diff --git a/py/doc/test.txt b/py/doc/test.txt index 6bf42a041..3c4a95ed3 100644 --- a/py/doc/test.txt +++ b/py/doc/test.txt @@ -461,8 +461,8 @@ experimental options Run browser (implies --startserver). -``--box`` - Use boxing: run each test in an external process. Very useful for testing +``--boxed`` + Use boxed tests: run each test in an external process. Very useful for testing things that occasionally segfault (since normally the segfault then would stop the whole test process). @@ -553,7 +553,7 @@ The options that you need to specify in that conftest.py file are: * `dist_rsync_ignore` - a list of relative locations to ignore for rsyncing * `dist_remotepython` - the remote python executable to run. * `dist_nicelevel` - process priority of remote nodes. -* `dist_boxing` - will run each single test in a separate process +* `dist_boxed` - will run each single test in a separate process (allowing to survive segfaults for example) * `dist_taskspernode` - Maximum number of tasks being queued to remote nodes @@ -563,7 +563,7 @@ Sample configuration:: dist_rsync_roots = ['../pypy', '../py'] dist_remotepython = 'python2.4' dist_nicelevel = 10 - dist_boxing = True + dist_boxed = False dist_maxwait = 100 dist_taskspernode = 10 diff --git a/py/path/local/testing/test_local.py b/py/path/local/testing/test_local.py index 469cb14d4..d0af16022 100644 --- a/py/path/local/testing/test_local.py +++ b/py/path/local/testing/test_local.py @@ -261,8 +261,8 @@ class TestExecution(LocalSetup): assert not numdir.new(ext=str(i-3)).check() def test_locked_make_numbered_dir(self): - if py.test.config.is_boxed(): - py.test.skip("Fails under boxing") + if py.test.config.option.boxed: + py.test.skip("Fails when run as boxed tests") root = self.tmpdir for i in range(10): numdir = local.make_numbered_dir(prefix='base.', rootdir=root, diff --git a/py/test/config.py b/py/test/config.py index 9b869e6a7..08ac4057e 100644 --- a/py/test/config.py +++ b/py/test/config.py @@ -156,13 +156,13 @@ class Config(object): if self.option.dist: name = 'RSession' else: - optnames = 'startserver runbrowser apigen restreport boxing'.split() + optnames = 'startserver runbrowser apigen restreport boxed'.split() for opt in optnames: if getattr(self.option, opt, False): name = 'LSession' break else: - if self.getvalue('dist_boxing'): + if self.getvalue('dist_boxed'): name = 'LSession' if self.option.looponfailing: name = 'RemoteTerminalSession' @@ -170,10 +170,6 @@ class Config(object): name = 'RemoteTerminalSession' return name - def is_boxed(self): - # XXX probably not a good idea to have this special function ... - return self.option.boxing or self.getvalue("dist_boxing") - def _reparse(self, args): """ this is used from tests that want to re-invoke parse(). """ #assert args # XXX should not be empty diff --git a/py/test/defaultconftest.py b/py/test/defaultconftest.py index bf3a5f617..dff3aab8c 100644 --- a/py/test/defaultconftest.py +++ b/py/test/defaultconftest.py @@ -19,7 +19,7 @@ additionalinfo = None # whole pkgdir will be rsynced dist_remotepython = "python" dist_taskspernode = 15 -dist_boxing = False +dist_boxed = False if hasattr(py.std.os, 'nice'): dist_nicelevel = py.std.os.nice(0) # nice py.test works else: @@ -87,9 +87,9 @@ def adddefaultoptions(config): action="store_true", dest="runbrowser", default=False, help="run browser (implies --startserver)." ), - Option('', '--box', - action="store_true", dest="boxing", - help="use boxing (running each test in external process)"), + Option('', '--boxed', + action="store_true", dest="boxed", default=False, + help="box each test run in a separate process"), Option('', '--rest', action='store_true', dest="restreport", default=False, help="restructured text output reporting."), diff --git a/py/test/rsession/rsession.py b/py/test/rsession/rsession.py index ef8df2ed7..e4ce5f422 100644 --- a/py/test/rsession/rsession.py +++ b/py/test/rsession/rsession.py @@ -30,6 +30,8 @@ class AbstractSession(Session): if option.nocapture: print "Cannot use nocapture with distributed testing" sys.exit(1) + if self.config.getvalue("dist_boxed"): + option.boxed = True super(AbstractSession, self).fixoptions() def init_reporter(self, reporter, hosts, reporter_class, arg=""): @@ -240,9 +242,8 @@ class LSession(AbstractSession): module_name=pkgname) self.tracer = Tracer(self.docstorage) return apigen_runner + elif self.config.option.boxed: + return box_runner else: - if (self.config.getvalue('dist_boxing') or self.config.option.boxing)\ - and not self.config.option.nocapture: - return box_runner return plain_runner diff --git a/py/test/testing/test_collect.py b/py/test/testing/test_collect.py index 1c082d3af..5d17768ec 100644 --- a/py/test/testing/test_collect.py +++ b/py/test/testing/test_collect.py @@ -7,6 +7,10 @@ def setup_module(mod): mod.datadir = setupdatadir() mod.tmpdir = py.test.ensuretemp('test_collect') +def skipboxed(): + if py.test.config.option.boxed: + py.test.skip("test does not work with boxed tests") + def test_failing_import_execfile(): dest = datadir / 'failingimport.py' col = py.test.collect.Module(dest) @@ -267,8 +271,7 @@ def test_custom_NONpython_collection_from_conftest(): assert len(l) == 1 def test_order_of_execution_generator_same_codeline(): - if py.test.config.is_boxed(): - py.test.skip("Does not work with boxing") + skipboxed() test_list = [] expected_list = range(6) @@ -286,8 +289,7 @@ def test_order_of_execution_generator_same_codeline(): def test_order_of_execution_generator_different_codeline(): - if py.test.config.is_boxed(): - py.test.skip("Does not work with boxing") + skipboxed() test_list = [] expected_list = range(3) diff --git a/py/test/testing/test_config.py b/py/test/testing/test_config.py index 8ea115780..21d24eb50 100644 --- a/py/test/testing/test_config.py +++ b/py/test/testing/test_config.py @@ -207,7 +207,7 @@ class TestSessionAndOptions: assert config._getsessionname() == 'RSession' def test_implied_lsession(self): - optnames = 'startserver runbrowser apigen=x rest box'.split() + optnames = 'startserver runbrowser apigen=x rest boxed'.split() for x in optnames: config = py.test.config._reparse([self.tmpdir, '--%s' % x]) assert config._getsessionname() == 'LSession' @@ -240,22 +240,30 @@ class TestSessionAndOptions: session = config.initsession() assert session.config is config - def test_boxing_options(self): - # XXX config.is_boxed() is probably not a good idea - tmpdir = self.tmpdir + def test_boxed_option_including_implied_from_conftest(self): + self.tmpdir.join("conftest.py").write("dist_hosts=[]") + tmpdir = self.tmpdir.ensure("subdir", dir=1) config = py.test.config._reparse([tmpdir]) - assert not config.option.boxing - assert not config.is_boxed() + config.initsession() + assert not config.option.boxed + config = py.test.config._reparse(['--dist', tmpdir]) + config.initsession() + assert not config.option.boxed - #tmpdir.join("conftest.py").write("dist_boxing=True\n") - #config = py.test.config._reparse([tmpdir]) - #assert config.is_boxed() - - tmpdir.join("conftest.py").write("dist_boxing=False\n") - config = py.test.config._reparse([tmpdir]) - assert not config.is_boxed() + tmpdir.join("conftest.py").write(py.code.Source(""" + dist_hosts = [] + dist_boxed = True + """)) + config = py.test.config._reparse(['--dist', tmpdir]) + config.initsession() + assert config.option.boxed + tmpdir.join("conftest.py").write(py.code.Source(""" + dist_boxed = False + """)) config = py.test.config._reparse([tmpdir, '--box']) - assert config.is_boxed() + assert config.option.boxed + config.initsession() + assert config.option.boxed def test_getvalue_pathlist(self): tmpdir = self.tmpdir diff --git a/py/test/testing/test_session.py b/py/test/testing/test_session.py index 6ff27c88a..5e3a39f81 100644 --- a/py/test/testing/test_session.py +++ b/py/test/testing/test_session.py @@ -50,6 +50,10 @@ def runfiletest(opts): l = session.getitemoutcomepairs(Passed) assert not l +def test_is_not_boxed_by_default(): + config = py.test.config._reparse([datadir]) + assert not config.option.boxed + class TestKeywordSelection: def test_select_simple(self): for keyword in ['test_one', 'est_on']: