def run_installed_tests_as_subprocess(app_dir_path, django_settings_module, python_exe_path=sys.executable, use_logger=None, read_config_file=True): """Run the installed mode tests as a separate subprocess, using the installed app's environment. A results file is used to communcate back the results of the validation. After the run is complete, an instance of ParsedJsonResults is returned """ logger.info(">> Validating application settings") app_dir_path = os.path.abspath(os.path.expanduser(app_dir_path)) if not os.path.exists(app_dir_path): raise TestSetupError("Django settings file validator: application directory '%s' does not exist" % app_dir_path) python_path_dir = find_python_module(django_settings_module, app_dir_path) if python_path_dir==None: raise TestSetupError("Django settings file validator: unable to find settings module %s under %s" % (django_settings_module, app_dir_path)) if use_logger == None: use_logger = logger python_path = get_python_path(python_path_dir, django_settings_module) use_logger.debug("Setting PYTHONPATH to %s" % python_path) # we create a temporary file that will contain the results tf = tempfile.NamedTemporaryFile(delete=False) tf.write("null") tf.close() script_file = os.path.dirname(os.path.abspath(__file__)) try: program_and_args = [python_exe_path, script_file, "-v", "validate-installed", app_dir_path, tf.name] if not read_config_file: program_and_args.append(django_settings_module) use_logger.debug(' '.join(program_and_args)) env = { "PYTHONPATH": python_path, "DJANGO_SETTINGS_MODULE": "%s" % \ get_deployed_settings_module(django_settings_module) } cwd = get_settings_file_directory(python_path_dir, django_settings_module) subproc = subprocess.Popen(program_and_args, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd) use_logger.debug("Started program %s, pid is %d" % (program_and_args[0], subproc.pid)) subproc.stdin.close() for line in subproc.stdout: use_logger.debug("[%d] %s" % (subproc.pid, line.rstrip())) subproc.wait() use_logger.debug("[%d] %s exited with return code %d" % (subproc.pid, program_and_args[0], subproc.returncode)) with open(tf.name, "rb") as f: json_obj = json.load(f) results = ParsedJsonResults(json_obj) return results finally: os.remove(tf.name)
def validate_installed_app(app_name, python_path_dir, known_apps, app_dir_path, django_settings_module, results): try: import_module(app_name) logger.debug("Application '%s' Ok." % app_name) except: (exc_typ, exc_val, exc_tb) = sys.exc_info() if exc_typ==ImportError and str(exc_val)==("No module named %s" % app_name): logger.debug("Unable to find module named %s" % app_name) if app_name in PACKAGES_FOR_KNOWN_APPS: pkgs = PACKAGES_FOR_KNOWN_APPS[app_name] if len(pkgs)>1: results.error("Django Application '%s' not found. Perhaps you wanted to include one of the following packages in your requirements.txt file: %s" % (app_name, pkgs)) else: results.error("Django Application '%s' not found. Perhaps you wanted to include the '%s' package in your requirements.txt file" % (app_name, pkgs[0])) else: pp_msg = "Your project was installed at %s. PYTHONPATH was set to %s." % (app_dir_path, get_python_path(python_path_dir, django_settings_module)) results.error("Django Application '%s' not found. If it is from an external package, add the associated package to the requirements.txt file. If the application is supposed to be a python module included with you project tree, check the value you provided for the settings module. %s" % (app_name, pp_msg)) else: # another exception occurred in import logger.exception("Exception when trying to import app %s" % app_name) results.warning("Django Application '%s' was found, but an error occurred when trying to import the application: %s(%s)" % (app_name, exc_typ.__name__, str(exc_val)))