Example #1
0
 def __init__(self, config, testmon_data):
     self.testmon_data = testmon_data
     self.testmon = Testmon(config.project_dirs,
                            testmon_labels=testmon_options(config))
     self.collection_ignored = set()
     self.testmon_save = True
     self.config = config
Example #2
0
 def __init__(self, config, testmon_data):
     self.testmon_data = testmon_data
     self.testmon = Testmon(config.project_dirs,
                            testmon_labels=testmon_options(config))
     self.testmon_save = True
     self.config = config
     self.lastfailed = self.testmon_data.lastfailed
def track_it(testdir, func):
    testmon = Testmon(project_dirs=[testdir.tmpdir.strpath],
                      testmon_labels=set())
    testmon_data = TestmonData(testdir.tmpdir.strpath)
    testmon.start()
    func()
    testmon.stop_and_save(testmon_data, testdir.tmpdir.strpath, 'testnode')
    return testmon_data.node_data['testnode']
Example #4
0
def track_it(testdir, func):
    testmon = Testmon(project_dirs=[testdir.tmpdir.strpath],
                      testmon_labels=set())
    testmon_data = TestmonData(testdir.tmpdir.strpath)
    _result, coverage_data = testmon.track_dependencies(func, 'testnode')

    testmon_data.set_dependencies('testnode', coverage_data, testdir.tmpdir.strpath)
    return testmon_data.node_data['testnode']
def track_it(testdir, func):
    testmon = CoreTestmon(project_dirs=[testdir.tmpdir.strpath],
                          testmon_labels=set())
    testmon_data = CoreTestmonData(testdir.tmpdir.strpath)
    testmon_data.read_source()
    testmon.start()
    func()
    testmon.stop_and_save(testmon_data, testdir.tmpdir.strpath, 'testnode')
    return testmon_data._fetch_node_data()[0]['testnode']
Example #6
0
    def __init__(self, config, testmon_data):
        self.testmon_data = testmon_data
        self.testmon = Testmon(config.project_dirs, testmon_labels=testmon_options(config))

        self.collection_ignored = set()
        self.testmon_save = True
        self.config = config
        self.reports = defaultdict(lambda: {})
        self.selected, self.deselected = [], set()
        self.file_data = self.testmon_data.file_data()
        self.f_to_ignore = self.testmon_data.stable_files
        if self.config.getoption('tlf'):
            self.f_to_ignore -= self.testmon_data.f_last_failed
Example #7
0
    def test_subprocess_testmon(self):
        testmon = CoreTestmon("")
        testmon.setup_coverage(subprocess=True)

        path1 = self.make_file(
            "subprocesstest.py",
            """\
        a=1
        """,
        )
        self.run_command(f"python {path1}")
        assert testmon.sub_cov_file in "{}".format(
            os.listdir(os.path.join(os.getcwd(), ".tmontmp")))
        testmon.close()
def pytest_configure(config):
    coverage_stack = None

    plugin = None

    testmon_config = TestmonConfig()
    message, should_collect, should_select = testmon_config.header_collect_select(
        config, coverage_stack, cov_plugin=plugin)
    config.testmon_config = (message, should_collect, should_select)
    if should_select or should_collect:
        config.option.continue_on_collection_errors = True

        try:
            init_testmon_data(config)

            if should_select:
                config.pluginmanager.register(
                    TestmonSelect(config, config.testmon_data),
                    "TestmonSelect")

            if should_collect:
                config.pluginmanager.register(
                    TestmonCollect(
                        Testmon(
                            config.rootdir.strpath,
                            testmon_labels=testmon_options(config),
                            cov_plugin=plugin,
                        ),
                        config.testmon_data,
                    ),
                    "TestmonCollect",
                )
        except TestmonException as e:
            pytest.exit(str(e))
Example #9
0
def pytest_configure(config):
    coverage_stack = None

    testmon_config = TestmonConfig()
    message, should_collect, should_select = testmon_config.header_collect_select(
        config, coverage_stack
    )
    config.testmon_config = (message, should_collect, should_select)
    if should_select or should_collect:
        config.option.continue_on_collection_errors = True
        init_testmon_data(config)

        if should_select:
            config.pluginmanager.register(
                TestmonSelect(config, config.testmon_data), "TestmonSelect"
            )

        if should_collect:
            config.pluginmanager.register(
                TestmonCollect(
                    Testmon(
                        config.project_dirs, testmon_labels=testmon_options(config)
                    ),
                    config.testmon_data,
                ),
                "TestmonCollect",
            )
Example #10
0
def register_plugins(config, should_select, should_collect, cov_plugin):
    if should_select:
        config.pluginmanager.register(
            TestmonSelect(config, config.testmon_data), "TestmonSelect")

    if should_collect:
        config.pluginmanager.register(
            TestmonCollect(
                Testmon(
                    config.rootdir.strpath,
                    testmon_labels=testmon_options(config),
                    cov_plugin=cov_plugin,
                ),
                config.testmon_data,
            ),
            "TestmonCollect",
        )
Example #11
0
 def __init__(self, config, testmon_data):
     self.testmon_data = testmon_data
     self.testmon = Testmon(config.project_dirs, testmon_labels=testmon_options(config) )
     self.testmon_save = True
     self.config = config
     self.lastfailed = self.testmon_data.lastfailed
Example #12
0
class TestmonDeselect(object):
    def __init__(self, config, testmon_data):
        self.testmon_data = testmon_data
        self.testmon = Testmon(config.project_dirs, testmon_labels=testmon_options(config) )
        self.testmon_save = True
        self.config = config
        self.lastfailed = self.testmon_data.lastfailed

    def pytest_report_header(self, config):
        changed_files = ",".join([os.path.relpath(path, config.rootdir.strpath)
                                  for path
                                  in self.testmon_data.modules_cache])
        if changed_files=='' or len(changed_files)>100:
            changed_files = len(self.testmon_data.modules_cache)
        active_message = "testmon={}, changed files: {}, skipping collection of {} items".format(config.getoption('testmon'),
                                                              changed_files, sum(self.testmon_data.unaffected_paths.values()))
        if self.testmon_data.variant:
            return active_message + ", run variant: {}".format(self.testmon_data.variant)
        else:
            return active_message + "."

    def pytest_collection_modifyitems(self, session, config, items):
        selected, deselected = [], []
        self.testmon_data.collect_garbage(allnodeids=[item.nodeid for item in items])
        for item in items:
            if item.nodeid in self.lastfailed or self.testmon_data.test_should_run(item.nodeid):
                selected.append(item)
            else:
                deselected.append(item)
        items[:] = selected
        if deselected:
            config.hook.pytest_deselected(items=deselected)

    def pytest_runtest_protocol(self, __multicall__, item, nextitem):
        if self.config.getoption('testmon') == u'readonly':
            return __multicall__.execute()
        result, coverage_data = self.testmon.track_dependencies(__multicall__.execute, item.nodeid)
        self.testmon_data.set_dependencies(item.nodeid, coverage_data, item.config.rootdir.strpath)

        return result

    def pytest_runtest_logreport(self, report):
        if report.failed and "xfail" not in report.keywords:
            if report.nodeid not in self.lastfailed:
                self.lastfailed.append(report.nodeid)
        elif not report.failed:
            if report.when == "call":
                try:
                    if report.nodeid in self.lastfailed:
                        self.lastfailed.remove(report.nodeid)
                except KeyError:
                    pass

    def pytest_ignore_collect(self, path, config):
        strpath = path.strpath
        if strpath in self.testmon_data.unaffected_paths:
            config.hook.pytest_deselected(items=['1'] * self.testmon_data.unaffected_paths[strpath])
            return True

    def pytest_internalerror(self, excrepr, excinfo):
        self.testmon_save = False

    def pytest_keyboard_interrupt(self, excinfo):
        self.testmon_save = False

    def pytest_sessionfinish(self, session):
        if self.testmon_save:
            self.testmon_data.write_data()
        self.testmon.close()
Example #13
0
class TestmonDeselect(object):
    def __init__(self, config, testmon_data):
        self.testmon_data = testmon_data
        self.testmon = Testmon(config.project_dirs,
                               testmon_labels=testmon_options(config))
        self.collection_ignored = set()
        self.testmon_save = True
        self.config = config

    def pytest_report_header(self, config):
        changed_files = ",".join(self.testmon_data.source_tree.changed_files)
        if changed_files == '' or len(changed_files) > 100:
            changed_files = len(self.testmon_data.source_tree.changed_files)
        active_message = "testmon={}, changed files: {}, skipping collection of {} items".format(
            config.getoption('testmon'), changed_files,
            len(self.testmon_data.unaffected_nodeids))
        if self.testmon_data.variant:
            return active_message + ", run variant: {}".format(
                self.testmon_data.variant)
        else:
            return active_message + "."

    def report_if_failed(self, nodeid):
        if nodeid in self.testmon_data.fail_reports:
            for report in self.testmon_data.fail_reports[nodeid]:
                test_report = unserialize_report('testreport', report)
                self.config.hook.pytest_runtest_logreport(report=test_report)

    def pytest_collection_modifyitems(self, session, config, items):
        removed_nodeids = set(
            self.testmon_data.node_data) - self.collection_ignored - set(
                [item.nodeid for item in items])
        if removed_nodeids:
            self.testmon_data.collect_garbage(removed_nodeids)

        selected, deselected = [], []
        for item in items:
            assert item.nodeid not in self.collection_ignored
            if self.testmon_data.test_should_run(item.nodeid):
                selected.append(item)
            else:
                self.report_if_failed(item.nodeid)
                deselected.append(item)
        for nodeid in self.collection_ignored:
            self.report_if_failed(nodeid)
        items[:] = selected
        if deselected:
            config.hook.pytest_deselected(items=deselected)

    @pytest.mark.hookwrapper
    def pytest_runtest_protocol(self, item, nextitem):
        if self.config.getoption('testmon') == u'readonly':
            yield

        self.testmon.start()
        result = yield
        if result.excinfo and issubclass(result.excinfo[0], KeyboardInterrupt):
            self.testmon.stop()
        else:
            self.testmon.stop_and_save(self.testmon_data,
                                       item.config.rootdir.strpath,
                                       item.nodeid,
                                       self.testmon_data.reports[item.nodeid])
            del self.testmon_data.reports[item.nodeid]

    def pytest_runtest_logreport(self, report):
        self.testmon_data.reports[report.nodeid].append(
            serialize_report(report))

    class FakeItemFromTestmon(object):
        def __init__(self, config):
            self.config = config

    def pytest_ignore_collect(self, path, config):
        strpath = os.path.relpath(path.strpath, config.rootdir.strpath)
        if strpath in self.testmon_data.unaffected_files:
            if os.path.split(strpath)[1].startswith('test_'):
                for nodeid in self.testmon_data.file_data()[strpath]:
                    self.collection_ignored.add(nodeid)
                config.hook.pytest_deselected(
                    items=([self.FakeItemFromTestmon(config)] *
                           len(self.testmon_data.file_data()[strpath])))
            return True

    def pytest_internalerror(self, excrepr, excinfo):
        self.testmon_save = False

    def pytest_keyboard_interrupt(self, excinfo):
        self.testmon_save = False

    def pytest_sessionfinish(self, session):
        if self.testmon_save:
            self.testmon_data.write_data()
        self.testmon.close()
Example #14
0
from testmon.testmon_core import get_variant_inifile, Testmon


ancestor = get_common_ancestor(sys.argv[1:])
rootdir, inifile, inicfg = getcfg(
    [ancestor], ["pytest.ini", "tox.ini", "setup.cfg"])
if rootdir is None:
    for rootdir in ancestor.parts(reverse=True):
        if rootdir.join("setup.py").exists():
            break
    else:
        rootdir = ancestor

variant = get_variant_inifile(inifile)

testmon = Testmon([str(rootdir)], variant=variant )
testmon.read_fs()


node_files = testmon.modules_test_counts().keys()

changed_files = []
for node_file in node_files:
    if testmon.old_mtimes.get(node_file) != testmon.mtimes.get(node_file):
        changed_files.append(node_file)
print "Changed files:%s " % changed_files

print rootdir, inifile, inicfg


Example #15
0
class TestmonDeselect(object):
    def __init__(self, config, testmon_data):
        self.testmon_data = testmon_data
        self.testmon = Testmon(config.project_dirs,
                               testmon_labels=testmon_options(config))
        self.testmon_save = True
        self.config = config
        self.lastfailed = self.testmon_data.lastfailed

    def pytest_report_header(self, config):
        changed_files = ",".join([
            os.path.relpath(path, config.rootdir.strpath)
            for path in self.testmon_data.modules_cache
        ])
        if changed_files == '' or len(changed_files) > 100:
            changed_files = len(self.testmon_data.modules_cache)
        active_message = "testmon={}, changed files: {}, skipping collection of {} items".format(
            config.getoption('testmon'), changed_files,
            sum(self.testmon_data.unaffected_paths.values()))
        if self.testmon_data.variant:
            return active_message + ", run variant: {}".format(
                self.testmon_data.variant)
        else:
            return active_message + "."

    def pytest_collection_modifyitems(self, session, config, items):
        selected, deselected = [], []
        self.testmon_data.collect_garbage(
            allnodeids=[item.nodeid for item in items])
        for item in items:
            if item.nodeid in self.lastfailed or self.testmon_data.test_should_run(
                    item.nodeid):
                selected.append(item)
            else:
                deselected.append(item)
        items[:] = selected
        if deselected:
            config.hook.pytest_deselected(items=deselected)

    @pytest.mark.hookwrapper
    def pytest_runtest_protocol(self, item, nextitem):
        if self.config.getoption('testmon') == u'readonly':
            yield

        self.testmon.start()
        result = yield
        # NOTE: pytest-watch also sends KeyboardInterrupt when changes are
        # detected.  This should still save the collected data up until then.
        if result.excinfo and issubclass(result.excinfo[0], KeyboardInterrupt):
            self.testmon.stop()
        else:
            self.testmon.stop_and_save(self.testmon_data,
                                       item.config.rootdir.strpath,
                                       item.nodeid)

    def pytest_runtest_logreport(self, report):
        if report.failed and "xfail" not in report.keywords:
            if report.nodeid not in self.lastfailed:
                self.lastfailed.append(report.nodeid)
        elif not report.failed:
            if report.when == "call":
                try:
                    if report.nodeid in self.lastfailed:
                        self.lastfailed.remove(report.nodeid)
                except KeyError:
                    pass

    class FakeItemFromTestmon(object):
        def __init__(self, config):
            self.config = config

    def pytest_ignore_collect(self, path, config):
        strpath = path.strpath
        if strpath in self.testmon_data.unaffected_paths:
            config.hook.pytest_deselected(
                items=([self.FakeItemFromTestmon(config)] *
                       self.testmon_data.unaffected_paths[strpath]))
            return True

    def pytest_internalerror(self, excrepr, excinfo):
        self.testmon_save = False

    def pytest_sessionfinish(self, session):
        if self.testmon_save:
            self.testmon_data.write_data()
        self.testmon.close()

    def pytest_terminal_summary(self, terminalreporter, exitstatus=None):
        if (not self.testmon_save
                and terminalreporter.config.getvalue('verbose')):
            terminalreporter.line('testmon: not saving data')
from testmon.testmon_core import get_variant_inifile, Testmon


ancestor = get_common_ancestor(sys.argv[1:])
rootdir, inifile, inicfg = getcfg(
    [ancestor], ["pytest.ini", "tox.ini", "setup.cfg"])
if rootdir is None:
    for rootdir in ancestor.parts(reverse=True):
        if rootdir.join("setup.py").exists():
            break
    else:
        rootdir = ancestor

variant = get_variant_inifile(inifile)

testmon = Testmon([str(rootdir)], variant=variant )
testmon.read_fs()


node_files = testmon.file_data().keys()

changed_files = []
for node_file in node_files:
    if testmon.old_mtimes.get(node_file) != testmon.mtimes.get(node_file):
        changed_files.append(node_file)
print "Changed files:%s " % changed_files

print rootdir, inifile, inicfg


Example #17
0
class TestmonDeselect(object):
    def __init__(self, config, testmon_data):
        self.testmon_data = testmon_data
        self.testmon = Testmon(config.project_dirs,
                               testmon_labels=testmon_options(config))

        self.collection_ignored = set()
        self.testmon_save = True
        self.config = config
        self.reports = defaultdict(lambda: {})
        self.selected, self.deselected = [], set()
        self.file_data = self.testmon_data.file_data()
        self.f_to_ignore = self.testmon_data.stable_files
        if self.config.getoption('tlf'):
            self.f_to_ignore -= self.testmon_data.f_last_failed

    def test_should_run(self, nodeid):
        if self.config.getoption('tlf'):
            if nodeid in self.testmon_data.fail_reports:
                return True
        if nodeid in self.testmon_data.stable_nodeids:
            return False
        else:
            return True

    def report_if_failed(self, nodeid):
        node_reports = self.testmon_data.fail_reports.get(nodeid, {})
        for phase in ('setup', 'call', 'teardown'):
            if phase in node_reports:
                test_report = runner.TestReport(**node_reports[phase])
                self.config.hook.pytest_runtest_logreport(report=test_report)

    def pytest_report_header(self, config):
        changed_files = ",".join(self.testmon_data.source_tree.changed_files)
        if changed_files == '' or len(changed_files) > 100:
            changed_files = len(self.testmon_data.source_tree.changed_files)
        active_message = "testmon={}, changed files: {}, skipping collection of {} files".format(
            config.getoption('testmon'), changed_files,
            len(self.testmon_data.stable_files))
        if self.testmon_data.variant:
            return active_message + ", run variant: {}".format(
                self.testmon_data.variant)
        else:
            return active_message + "."

    def pytest_ignore_collect(self, path, config):
        strpath = os.path.relpath(path.strpath, config.rootdir.strpath)
        if strpath in (self.f_to_ignore):
            self.collection_ignored.update(self.testmon_data.f_tests[strpath])
            return True

    @pytest.mark.trylast
    def pytest_collection_modifyitems(self, session, config, items):
        self.testmon_data.collect_garbage(retain=self.collection_ignored.union(
            set([item.nodeid for item in items])))

        for item in items:
            assert item.nodeid not in self.collection_ignored, (
                item.nodeid, self.collection_ignored)

        for item in items:
            if self.test_should_run(item.nodeid):
                self.selected.append(item)
            else:
                self.deselected.add(item.nodeid)
        items[:] = self.selected

        session.config.hook.pytest_deselected(
            items=([self.FakeItemFromTestmon(session.config)] *
                   len(self.collection_ignored.union(self.deselected))))

    def pytest_runtestloop(self, session):
        ignored_deselected = self.collection_ignored.union(self.deselected)
        for nodeid in ignored_deselected:
            self.report_if_failed(nodeid)

    @pytest.mark.hookwrapper
    def pytest_runtest_protocol(self, item, nextitem):
        if self.config.getoption('testmon') == u'readonly':
            yield
        else:
            self.testmon.start()
            result = yield
            if result.excinfo and issubclass(result.excinfo[0],
                                             KeyboardInterrupt):
                self.testmon.stop()
            else:
                self.testmon.stop_and_save(self.testmon_data,
                                           item.config.rootdir.strpath,
                                           item.nodeid,
                                           self.reports[item.nodeid])

    def pytest_runtest_logreport(self, report):
        assert report.when not in self.reports, \
            "{} {} {}".format(report.nodeid, report.when, self.reports)
        self.reports[report.nodeid][report.when] = serialize_report(report)

    class FakeItemFromTestmon(object):
        def __init__(self, config):
            self.config = config

    def pytest_internalerror(self, excrepr, excinfo):
        self.testmon_save = False

    def pytest_keyboard_interrupt(self, excinfo):
        self.testmon_save = False

    def pytest_sessionfinish(self, session):
        if self.testmon_save:
            self.testmon_data.write_data()
        self.testmon.close()
Example #18
0
class TestmonDeselect(object):
    def __init__(self, config, testmon_data):
        self.testmon_data = testmon_data
        self.testmon = Testmon(config.project_dirs, testmon_labels=testmon_options(config))
        self.testmon_save = True
        self.config = config
        self.lastfailed = self.testmon_data.lastfailed

    def pytest_report_header(self, config):
        changed_files = ",".join([os.path.relpath(path, config.rootdir.strpath)
                                  for path
                                  in self.testmon_data.modules_cache])
        if changed_files == '' or len(changed_files) > 100:
            changed_files = len(self.testmon_data.modules_cache)
        active_message = "testmon={}, changed files: {}, skipping collection of {} items".format(
            config.getoption('testmon'),
            changed_files, sum(self.testmon_data.unaffected_paths.values()))
        if self.testmon_data.variant:
            return active_message + ", run variant: {}".format(self.testmon_data.variant)
        else:
            return active_message + "."

    def pytest_collection_modifyitems(self, session, config, items):
        selected, deselected = [], []
        self.testmon_data.collect_garbage(allnodeids=[item.nodeid for item in items])
        for item in items:
            if item.nodeid in self.lastfailed or self.testmon_data.test_should_run(item.nodeid):
                selected.append(item)
            else:
                deselected.append(item)
        items[:] = selected
        if deselected:
            config.hook.pytest_deselected(items=deselected)

    @pytest.mark.hookwrapper
    def pytest_runtest_protocol(self, item, nextitem):
        if self.config.getoption('testmon') == u'readonly':
            yield

        self.testmon.start()
        result = yield
        # NOTE: pytest-watch also sends KeyboardInterrupt when changes are
        # detected.  This should still save the collected data up until then.
        if result.excinfo and issubclass(result.excinfo[0], KeyboardInterrupt):
            self.testmon.stop()
        else:
            self.testmon.stop_and_save(self.testmon_data, item.config.rootdir.strpath, item.nodeid)

    def pytest_runtest_logreport(self, report):
        if report.failed and "xfail" not in report.keywords:
            if report.nodeid not in self.lastfailed:
                self.lastfailed.append(report.nodeid)
        elif not report.failed:
            if report.when == "call":
                try:
                    if report.nodeid in self.lastfailed:
                        self.lastfailed.remove(report.nodeid)
                except KeyError:
                    pass

    class FakeItemFromTestmon(object):
        def __init__(self, config):
            self.config = config

    def pytest_ignore_collect(self, path, config):
        strpath = path.strpath
        if strpath in self.testmon_data.unaffected_paths:
            config.hook.pytest_deselected(
                items=([self.FakeItemFromTestmon(config)] *
                       self.testmon_data.unaffected_paths[strpath]))
            return True

    def pytest_internalerror(self, excrepr, excinfo):
        self.testmon_save = False

    def pytest_sessionfinish(self, session):
        if self.testmon_save:
            self.testmon_data.write_data()
        self.testmon.close()

    def pytest_terminal_summary(self, terminalreporter, exitstatus=None):
        if (not self.testmon_save and
                terminalreporter.config.getvalue('verbose')):
            terminalreporter.line('testmon: not saving data')