diff --git a/py/test/config.py b/py/test/config.py index 7e0572778..709482591 100644 --- a/py/test/config.py +++ b/py/test/config.py @@ -63,6 +63,12 @@ class Config(object): elif not opt.type and opt.action in ("store_true", "store_false"): val = eval(val) opt.default = val + else: + name = "pytest_option_" + opt.dest + try: + opt.default = self._conftest.rget(name) + except (ValueError, KeyError): + pass if not hasattr(self.option, opt.dest): setattr(self.option, opt.dest, opt.default) diff --git a/py/test/dsession/dsession.py b/py/test/dsession/dsession.py index 0958dcf62..177544117 100644 --- a/py/test/dsession/dsession.py +++ b/py/test/dsession/dsession.py @@ -60,16 +60,12 @@ class DSession(Session): if config.option.numprocesses: return try: - config.getvalue('dist_hosts') + config.getvalue('hosts') except KeyError: - print "Don't know where to distribute tests to. You may want" - print "to specify either a number of local processes to start" - print "with '--numprocesses=NUM' or specify 'dist_hosts' in a local" - print "conftest.py file, for example:" - print - print " dist_hosts = ['localhost'] * 4 # for 3 processors" - print " dist_hosts = ['you@remote.com', '...'] # for testing on ssh accounts" - print " # with your remote ssh accounts" + print "Please specify hosts for distribution of tests:" + print "cmdline: --hosts=host1,host2,..." + print "conftest.py: pytest_option_hosts=['host1','host2',]" + print "environment: PYTEST_OPTION_HOSTS=host1,host2,host3" print print "see also: http://codespeak.net/py/current/doc/test.html#automated-distributed-testing" raise SystemExit diff --git a/py/test/dsession/hostmanage.py b/py/test/dsession/hostmanage.py index 5778b6cb5..8d1d77bc3 100644 --- a/py/test/dsession/hostmanage.py +++ b/py/test/dsession/hostmanage.py @@ -6,7 +6,7 @@ from py.__.test import event def getconfighosts(config): if config.option.numprocesses: - hosts = ['localhost'] * config.option.numprocesses + hosts = ['popen'] * config.option.numprocesses else: hosts = config.option.hosts if not hosts: diff --git a/py/test/dsession/testing/test_dsession.py b/py/test/dsession/testing/test_dsession.py index a6dc8a25e..da6abf779 100644 --- a/py/test/dsession/testing/test_dsession.py +++ b/py/test/dsession/testing/test_dsession.py @@ -300,17 +300,17 @@ class TestDSession: remaining = session.filteritems(items) assert remaining == [] - evname, ev = evrec.events[-1] - assert evname == "deselected" - assert ev.items == items + event = evrec.events[-1] + assert event.name == "deselected" + assert event.args[0].items == items modcol._config.option.keyword = "test_fail" remaining = session.filteritems(items) assert remaining == [items[0]] - evname, ev = evrec.events[-1] - assert evname == "deselected" - assert ev.items == [items[1]] + event = evrec.events[-1] + assert event.name == "deselected" + assert event.args[0].items == [items[1]] def test_hostdown_shutdown_after_completion(self, testdir): item = testdir.getitem("def test_func(): pass") diff --git a/py/test/plugin/pytest_pytester.py b/py/test/plugin/pytest_pytester.py index a1235a784..953a5d7e3 100644 --- a/py/test/plugin/pytest_pytester.py +++ b/py/test/plugin/pytest_pytester.py @@ -236,6 +236,11 @@ class TmpTestdir: def runpytest(self, *args): return self.runpybin("py.test", *args) +class Event: + def __init__(self, name, args, kwargs): + self.name = name + self.args = args + self.kwargs = kwargs class EventRecorder(object): def __init__(self, pyplugins, debug=False): # True): @@ -249,26 +254,27 @@ class EventRecorder(object): return if self.debug: print "[event: %s]: %s **%s" %(name, ", ".join(map(str, args)), kwargs,) - self.events.append((name,) + tuple(args)) + self.events.append(Event(name, args, kwargs)) def get(self, cls): l = [] - for name, value in self.events: + for event in self.events: + value = event.args[0] if isinstance(value, cls): l.append(value) return l def getnamed(self, *names): l = [] - for evname, event in self.events: - if evname in names: - l.append(event) + for event in self.events: + if event.name in names: + l.append(event.args[0]) return l def getfirstnamed(self, name): - for evname, event in self.events: - if evname == name: - return event + for event in self.events: + if event.name == name: + return event.args[0] def getfailures(self, names='itemtestreport collectionreport'): l = [] diff --git a/py/test/testing/acceptance_test.py b/py/test/testing/acceptance_test.py index 7f82c9a08..fbb7d61ff 100644 --- a/py/test/testing/acceptance_test.py +++ b/py/test/testing/acceptance_test.py @@ -252,6 +252,31 @@ class TestPyTest: ]) assert result.ret == 1 + def test_dist_testing_conftest_specified(self, testdir): + p1 = testdir.makepyfile(""" + import py + def test_fail0(): + assert 0 + def test_fail1(): + raise ValueError() + def test_ok(): + pass + def test_skip(): + py.test.skip("hello") + """, + ) + testdir.makeconftest(""" + pytest_option_hosts='popen,popen,popen' + """) + result = testdir.runpytest(p1, '-d') + result.stdout.fnmatch_lines([ + "HOSTUP: popen*Python*", + #"HOSTUP: localhost*Python*", + #"HOSTUP: localhost*Python*", + "*2 failed, 1 passed, 1 skipped*", + ]) + assert result.ret == 1 + def test_dist_tests_with_crash(self, testdir): if not hasattr(py.std.os, 'kill'): py.test.skip("no os.kill") diff --git a/py/test/testing/test_config.py b/py/test/testing/test_config.py index 83e306e59..a9004f2f2 100644 --- a/py/test/testing/test_config.py +++ b/py/test/testing/test_config.py @@ -40,6 +40,12 @@ class TestConfigCmdlineParsing: group.addoption("--option4", action="store", type="int") assert group.options[3].default == ("NO", "DEFAULT") + def test_parser_addoption_default_conftest(self, testdir, monkeypatch): + import os + testdir.makeconftest("pytest_option_verbose=True") + config = testdir.parseconfig() + assert config.option.verbose + def test_config_cmdline_options_only_lowercase(self, testdir): testdir.makepyfile(conftest=""" import py