def __exec_python_cmd(cmd, env=None, capture_stdout=True): """ Executes an externally spawned Python interpreter. If capture_stdout is set to True, returns anything that was emitted in the standard output as a single string. Otherwise, returns the exit code. """ # 'PyInstaller.config' cannot be imported as other top-level modules. from PyInstaller.config import CONF if env is None: env = {} # Update environment. Defaults to 'os.environ' pp_env = copy.deepcopy(os.environ) pp_env.update(env) # Prepend PYTHONPATH with pathex # Some functions use some PyInstaller code in subprocess so add # PyInstaller HOMEPATH to sys.path too. pp = os.pathsep.join(CONF['pathex'] + [HOMEPATH]) # PYTHONPATH might be already defined in the 'env' argument or in # the original 'os.environ'. Prepend it. if 'PYTHONPATH' in pp_env: pp = os.pathsep.join([pp_env.get('PYTHONPATH'), pp]) pp_env['PYTHONPATH'] = pp if capture_stdout: txt = compat.exec_python(*cmd, env=pp_env) return txt.strip() else: return compat.exec_python_rc(*cmd, env=pp_env)
def test_collect_submod_egg(self, tmpdir, monkeypatch): # Copy files to a tmpdir for egg building. dest_path = tmpdir.join('hookutils_package') shutil.copytree(TEST_MOD_PATH, dest_path.strpath) monkeypatch.chdir(dest_path) # Create an egg from the test package. For debug, show the output of # the egg build. print(exec_python('setup.py', 'bdist_egg')) # Obtain the name of the egg, which depends on the Python version. dist_path = dest_path.join('dist') fl = os.listdir(dist_path.strpath) assert len(fl) == 1 egg_name = fl[0] assert egg_name.endswith('.egg') # Add the egg to Python's path. pth = dist_path.join(egg_name).strpath monkeypatch.setattr('PyInstaller.config.CONF', {'pathex': [pth]}) monkeypatch.syspath_prepend(pth) # Verify its contents. ml = collect_submodules(TEST_MOD) self.test_collect_submod_all_included(ml)
def test_exec_command_subprocess_wrong_encoding_reports_nicely(capsys): # Ensure a nice error message is printed if decoding the output of the # subprocess fails. # Actually `exec_python()` is used for running the progam, so we can use a # small Python script. prog = ("""import sys; sys.stdout.buffer.write(b'dfadfadf\\xa0:::::')""") with pytest.raises(UnicodeDecodeError): res = compat.exec_python('-c', prog) out, err = capsys.readouterr() assert 'bytes around the offending' in err
def test_logs(self): """ Compare log files (now used only by multipackage test_name). Return True if .toc files match or when .toc patters are not defined. """ logsfn = glob.glob(self.test_file + '.toc') # Other main scripts do not start with 'test_'. logsfn += glob.glob(self.test_file.split('_', 1)[1] + '_?.toc') for logfn in logsfn: self._msg("EXECUTING MATCHING " + logfn) tmpname = os.path.splitext(logfn)[0] prog = self._find_exepath(tmpname) if prog is None: prog = self._find_exepath(tmpname, os.path.join('dist', self.test_file)) if _virtual_env_: fname_list = compat.exec_command('pyi-archive_viewer', '-b', '-r', prog) else: fname_list = compat.exec_python( os.path.join(HOMEPATH, 'utils', 'archive_viewer.py'), '-b', '-r', prog) # Fix line-endings so eval() does not fail. fname_list = fname_list.replace('\r\n', '\n').replace('\n\r', '\n') fname_list = eval(fname_list) pattern_list = eval(open(logfn, 'rU').read()) # Alphabetical order of patterns. pattern_list.sort() count = 0 for pattern in pattern_list: found = False for fname in fname_list: if re.match(pattern, fname): count += 1 found = True self._plain_msg('MATCH: %s --> %s' % (pattern, fname)) break if not found: self._plain_msg('MISSING: %s' % pattern) # Not all modules matched. # Stop comparing other .toc files and fail the test. if count < len(pattern_list): return False return True
def test_logs(self): """ Compare log files (now used only by multipackage test_name). Return True if .toc files match or when .toc patters are not defined. """ logsfn = glob.glob(self.test_file + '.toc') # Other main scripts do not start with 'test_'. logsfn += glob.glob(self.test_file.split('_', 1)[1] + '_?.toc') for logfn in logsfn: self._msg("EXECUTING MATCHING " + logfn) tmpname = os.path.splitext(logfn)[0] prog = self._find_exepath(tmpname) if prog is None: prog = self._find_exepath(tmpname, os.path.join('dist', self.test_file)) if _virtual_env_: fname_list = compat.exec_command( 'pyi-archive_viewer', '-b', '-r', prog) else: fname_list = compat.exec_python( os.path.join(HOMEPATH, 'utils', 'archive_viewer.py'), '-b', '-r', prog) # Fix line-endings so eval() does not fail. fname_list = fname_list.replace('\r\n', '\n').replace('\n\r', '\n') fname_list = eval(fname_list) pattern_list = eval(open(logfn, 'rU').read()) # Alphabetical order of patterns. pattern_list.sort() count = 0 for pattern in pattern_list: found = False for fname in fname_list: if re.match(pattern, fname): count += 1 found = True self._plain_msg('MATCH: %s --> %s' % (pattern, fname)) break if not found: self._plain_msg('MISSING: %s' % pattern) # Not all modules matched. # Stop comparing other .toc files and fail the test. if count < len(pattern_list): return False return True
def test_logs(self): """ Compare log files (now used only by multipackage test_name). Return True if .toc files match or when .toc patters are not defined. """ logsfn = glob.glob(self.test_file + '.toc') # other main scritps do not start with 'test_' logsfn += glob.glob(self.test_file.split('_', 1)[1] + '_?.toc') for logfn in logsfn: self._msg("EXECUTING MATCHING", logfn) tmpname = os.path.splitext(logfn)[0] prog = self._find_exepath(tmpname) if prog is None: prog = self._find_exepath(tmpname, os.path.join('dist', self.test_file)) fname_list = compat.exec_python( os.path.join(HOMEPATH, 'utils', 'ArchiveViewer.py'), '-b', '-r', prog) # fix line-endings so eval() does not fail fname_list = fname_list.replace('\r\n', '\n').replace('\n\r', '\n') fname_list = eval(fname_list) pattern_list = eval(open(logfn, 'rU').read()) count = 0 for pattern in pattern_list: found = False for fname in fname_list: if re.match(pattern, fname): count += 1 found = True self._plain_msg('MATCH: %s --> %s' % (pattern, fname)) break if not found: self._plain_msg('MISSING: %s' % pattern) return not count < len(pattern_list) return True
def __exec_python_cmd(cmd): """ Executes an externally spawned Python interpreter and returns anything that was emitted in the standard output as a single string. """ # Prepend PYTHONPATH with pathex pp = os.pathsep.join(PyInstaller.__pathex__) old_pp = compat.getenv('PYTHONPATH') if old_pp: pp = os.pathsep.join([pp, old_pp]) compat.setenv("PYTHONPATH", pp) try: try: txt = compat.exec_python(*cmd) except OSError, e: raise SystemExit("Execution failed: %s" % e) finally: if old_pp is not None: compat.setenv("PYTHONPATH", old_pp) else: compat.unsetenv("PYTHONPATH") return txt.strip()
def __exec_python_cmd(cmd): """ Executes an externally spawned Python interpreter and returns anything that was emitted in the standard output as a single string. """ # Prepend PYTHONPATH with pathex pp = os.pathsep.join(PyInstaller.__pathex__) old_pp = compat.getenv('PYTHONPATH') if old_pp: pp = os.pathsep.join([old_pp, pp]) compat.setenv("PYTHONPATH", pp) try: try: txt = compat.exec_python(*cmd) except OSError, e: raise SystemExit("Execution failed: %s" % e) finally: if old_pp is not None: compat.setenv("PYTHONPATH", old_pp) else: compat.unsetenv("PYTHONPATH") return txt.strip()
def __get_test_package_path(package_type, tmpdir, monkeypatch): # Same test package, in two different formats: source package or # zipped egg (built on-the-fly) src_path = os.path.join(_MODULES_DIR, 'pyi_pkg_resources_provider', 'package') # Source package if package_type == 'pkg': return src_path # Copy files to a tmpdir for building the egg. dest_path = tmpdir.join('src') shutil.copytree(src_path, dest_path.strpath) monkeypatch.chdir(dest_path) # Create an egg from the test package. For debug, show the output of # the egg build. print(exec_python('setup.py', 'bdist_egg')) # Obtain the name of the egg, which depends on the Python version. dist_path = dest_path.join('dist') files = os.listdir(dist_path.strpath) assert len(files) == 1 egg_name = files[0] assert egg_name.endswith('.egg') # Return the full path to the egg file return dist_path.join(egg_name).strpath
def runtests(alltests, filters=None, run_executable=1, verbose=False): # Use path separator '/' even on windows for test names. if is_win: alltests = [x.replace('\\', '/') for x in alltests] info = "Executing PyInstaller tests in: %s" % os.getcwd() print "*" * min(80, len(info)) print info print "*" * min(80, len(info)) OPTS = ['--skip-configure', '--debug'] build_python = open('basic/python_exe.build', 'w') build_python.write(sys.executable + "\n") build_python.write('debug=%s' % __debug__ + '\n') build_python.close() if not filters: tests = alltests else: tests = [] for part in filters: tests += [t for t in alltests if part in t and t not in tests] tests = [(len(x), x) for x in tests] tests.sort() counter = {"passed": [], "failed": [], "skipped": []} # run configure phase only once compat.exec_python_rc(os.path.join(HOMEPATH, 'utils', 'Configure.py')) # execute tests testbasedir = os.getcwdu() for _, test in tests: test = os.path.splitext(test)[0] if not os.path.exists(test + '.py'): _msg("Testfile not found:", test + '.py', short=1) counter["failed"].append(test) continue testdir, testfile = os.path.split(test) if not testdir: testdir = '.' elif not os.path.exists(testdir): os.makedirs(testdir) os.chdir(testdir) # go to testdir if test in MIN_VERSION_OR_OS and not MIN_VERSION_OR_OS[test]: counter["skipped"].append(test) os.chdir(testbasedir) # go back from testdir continue if test in DEPENDENCIES: failed = False for mod in DEPENDENCIES[test]: res = compat.exec_python_rc('-c', "import %s" % mod) if res != 0: failed = True break if failed: if verbose: print "Skipping test because module %s is missing" % mod counter["skipped"].append(test) os.chdir(testbasedir) # go back from testdir continue _msg("BUILDING TEST", test) # use pyinstaller.py for building tests testfile_spec = testfile + '.spec' if not os.path.exists(testfile + '.spec'): # .spec file does not exist and it has to be generated # for main script testfile_spec = testfile + '.py' res = compat.exec_python_rc(os.path.join(HOMEPATH, 'pyinstaller.py'), testfile_spec, *OPTS) if res == 0 and run_executable: files = glob.glob(os.path.join('dist', testfile + '*')) for exe in files: exe = os.path.splitext(exe)[0] res_tmp = test_exe(exe[5:], testdir) res = res or res_tmp # compare log files (now used only by multipackage tests) logsfn = glob.glob(testfile + '.toc') # other main scritps do not start with 'test_' logsfn += glob.glob(testfile.split('_', 1)[1] + '_?.toc') for logfn in logsfn: _msg("EXECUTING MATCHING", logfn) tmpname = os.path.splitext(logfn)[0] prog = find_exepath(tmpname) if prog is None: prog = find_exepath(tmpname, os.path.join('dist', testfile)) fname_list = compat.exec_python( os.path.join(HOMEPATH, 'utils', 'ArchiveViewer.py'), '-b', '-r', prog) fname_list = eval(fname_list) pattern_list = eval(open(logfn, 'rU').read()) count = 0 for pattern in pattern_list: found = False for fname in fname_list: if re.match(pattern, fname): count += 1 found = True if verbose: print "MATCH: %s --> %s" % (pattern, fname) break if not found: if verbose: print "MISSING: %s" % pattern if count < len(pattern_list): res = 1 print "Matching FAILED!" else: print "Matching SUCCESS!" if res == 0: _msg("FINISHING TEST", test, short=1) counter["passed"].append(test) else: _msg("TEST", test, "FAILED", short=1, sep="!!") counter["failed"].append(test) os.chdir(testbasedir) # go back from testdir pprint.pprint(counter)