Exemplo n.º 1
0
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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
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()
Exemplo n.º 11
0
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()
Exemplo n.º 12
0
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
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
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)