From ad3e45590f6d9460945caf74819ed8e7b4d06897 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 1 Sep 2015 23:10:47 +0200 Subject: [PATCH 1/8] remove the boxed plugin code --- setup.py | 1 - testing/test_boxed.py | 58 ----------------------------------------- xdist/boxed.py | 60 ------------------------------------------- 3 files changed, 119 deletions(-) delete mode 100644 testing/test_boxed.py delete mode 100644 xdist/boxed.py diff --git a/setup.py b/setup.py index 64bb5f27..9876aebc 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,6 @@ 'pytest11': [ 'xdist = xdist.plugin', 'xdist.looponfail = xdist.looponfail', - 'xdist.boxed = xdist.boxed', ], }, zip_safe=False, diff --git a/testing/test_boxed.py b/testing/test_boxed.py deleted file mode 100644 index d624a95c..00000000 --- a/testing/test_boxed.py +++ /dev/null @@ -1,58 +0,0 @@ -import pytest -import os - -needsfork = pytest.mark.skipif(not hasattr(os, "fork"), - reason="os.fork required") - - -@needsfork -def test_functional_boxed(testdir): - p1 = testdir.makepyfile(""" - import os - def test_function(): - os.kill(os.getpid(), 15) - """) - result = testdir.runpytest(p1, "--boxed") - result.stdout.fnmatch_lines([ - "*CRASHED*", - "*1 failed*" - ]) - - -@needsfork -@pytest.mark.parametrize("capmode", [ - "no", - pytest.mark.xfail("sys", reason="capture cleanup needed"), - pytest.mark.xfail("fd", reason="capture cleanup needed")]) -def test_functional_boxed_capturing(testdir, capmode): - p1 = testdir.makepyfile(""" - import os - import sys - def test_function(): - sys.stdout.write("hello\\n") - sys.stderr.write("world\\n") - os.kill(os.getpid(), 15) - """) - result = testdir.runpytest(p1, "--boxed", "--capture=%s" % capmode) - result.stdout.fnmatch_lines(""" - *CRASHED* - *stdout* - hello - *stderr* - world - *1 failed* - """) - - -class TestOptionEffects: - def test_boxed_option_default(self, testdir): - tmpdir = testdir.tmpdir.ensure("subdir", dir=1) - config = testdir.parseconfig() - assert not config.option.boxed - pytest.importorskip("execnet") - config = testdir.parseconfig('-d', tmpdir) - assert not config.option.boxed - - def test_is_not_boxed_by_default(self, testdir): - config = testdir.parseconfig(testdir.tmpdir) - assert not config.option.boxed diff --git a/xdist/boxed.py b/xdist/boxed.py deleted file mode 100644 index 009a1129..00000000 --- a/xdist/boxed.py +++ /dev/null @@ -1,60 +0,0 @@ - -import py - - -def pytest_addoption(parser): - group = parser.getgroup("xdist", "distributed and subprocess testing") - group.addoption( - '--boxed', - action="store_true", dest="boxed", default=False, - help="box each test run in a separate process (unix)") - - -def pytest_runtest_protocol(item): - if item.config.getvalue("boxed"): - reports = forked_run_report(item) - for rep in reports: - item.ihook.pytest_runtest_logreport(report=rep) - return True - - -def forked_run_report(item): - # for now, we run setup/teardown in the subprocess - # XXX optionally allow sharing of setup/teardown - from _pytest.runner import runtestprotocol - EXITSTATUS_TESTEXIT = 4 - import marshal - from xdist.remote import serialize_report - from xdist.slavemanage import unserialize_report - - def runforked(): - try: - reports = runtestprotocol(item, log=False) - except KeyboardInterrupt: - py.std.os._exit(EXITSTATUS_TESTEXIT) - return marshal.dumps([serialize_report(x) for x in reports]) - - ff = py.process.ForkedFunc(runforked) - result = ff.waitfinish() - if result.retval is not None: - report_dumps = marshal.loads(result.retval) - return [unserialize_report("testreport", x) for x in report_dumps] - else: - if result.exitstatus == EXITSTATUS_TESTEXIT: - py.test.exit("forked test item %s raised Exit" % (item,)) - return [report_process_crash(item, result)] - - -def report_process_crash(item, result): - path, lineno = item._getfslineno() - info = ("%s:%s: running the test CRASHED with signal %d" % - (path, lineno, result.signal)) - from _pytest import runner - call = runner.CallInfo(lambda: 0/0, "???") - call.excinfo = info - rep = runner.pytest_runtest_makereport(item, call) - if result.out: - rep.sections.append(("captured stdout", result.out)) - if result.err: - rep.sections.append(("captured stderr", result.err)) - return rep From 3f96e1b97fe4d82dc605d41e9cac6b428606cb20 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 1 Sep 2015 23:18:48 +0200 Subject: [PATCH 2/8] remove boxed from example -n1 is sufficient and quicker to run --- example/boxed.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/example/boxed.txt b/example/boxed.txt index 00cec2fb..a3a3daee 100644 --- a/example/boxed.txt +++ b/example/boxed.txt @@ -14,19 +14,19 @@ to run each test in a controlled subprocess. Here is a basic example:: @pytest.mark.parametrize("arg", range(50)) def test_func(arg): time.sleep(0.05) # each tests takes a while - if arg % 19 == 0: + if arg % 19 == 0: os.kill(os.getpid(), 15) If you run this with:: - $ py.test --boxed + $ py.test -n1 =========================== test session starts ============================ platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev8 plugins: xdist, bugzilla, cache, oejskit, cli, pep8, cov collecting ... collected 50 items - + test_module.py f..................f..................f........... - + ================================= FAILURES ================================= _______________________________ test_func[0] _______________________________ /home/hpk/tmp/doc-exec-420/test_module.py:6: running the test CRASHED with signal 15 @@ -40,13 +40,13 @@ You'll see that a couple of tests are reported as crashing, indicated by lower-case ``f`` and the respective failure summary. You can also use the xdist-provided parallelization feature to speed up your testing:: - $ py.test --boxed -n3 + $ py.test -n3 =========================== test session starts ============================ platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev8 plugins: xdist, bugzilla, cache, oejskit, cli, pep8, cov gw0 I / gw1 I / gw2 I gw0 [50] / gw1 [50] / gw2 [50] - + scheduling tests via LoadScheduling ..f...............f..................f............ ================================= FAILURES ================================= From 56d62c2d37232194ca8554659a60e2381484935c Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 1 Sep 2015 23:22:43 +0200 Subject: [PATCH 3/8] remove boxed from readme --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index b2060749..61bee8b7 100644 --- a/README.rst +++ b/README.rst @@ -22,8 +22,6 @@ test execution modes: those for a combined test run. This allows to speed up development or to use special resources of `remote machines`_. -* ``--boxed``: (not available on Windows) run each test in a boxed_ - subprocess to survive ``SEGFAULTS`` or otherwise dying processes * ``--looponfail``: run your tests repeatedly in a subprocess. After each run py.test waits until a file in your project changes and then re-runs From 5db31f1ee7301700ae9c73b92d4c9d07fe01339a Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Fri, 4 Aug 2017 21:31:01 +0200 Subject: [PATCH 4/8] add support for --boxed by aliasing to --forked of pytest-foked --- setup.py | 2 +- xdist/plugin.py | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 9876aebc..7f8b0573 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages -install_requires = ['execnet>=1.1', 'pytest>=3.0.0'] +install_requires = ['execnet>=1.1', 'pytest>=3.0.0', 'pytest-forked'] if version_info < (2, 7): install_requires.append('ordereddict') diff --git a/xdist/plugin.py b/xdist/plugin.py index 47a9b54f..1e41bb4b 100644 --- a/xdist/plugin.py +++ b/xdist/plugin.py @@ -26,10 +26,10 @@ def pytest_addoption(parser): help="shortcut for '--dist=load --tx=NUM*popen', " "you can use 'auto' here for auto detection CPUs number on " "host system") - group._addoption('--max-slave-restart', action="store", default=None, + group.addoption('--max-slave-restart', action="store", default=None, help="maximum number of slaves that can be restarted " "when crashed (set to zero to disable this feature)") - group._addoption( + group.addoption( '--dist', metavar="distmode", action="store", choices=['each', 'load', 'loadscope', 'no'], dest="dist", default="no", @@ -40,7 +40,7 @@ def pytest_addoption(parser): "loadscope: load balance by sending pending groups of tests in" " the same scope to any available environment.\n\n" "(default) no: run tests inprocess, don't distribute.")) - group._addoption( + group.addoption( '--tx', dest="tx", action="append", default=[], metavar="xspec", help=("add a test execution environment. some examples: " @@ -57,6 +57,9 @@ def pytest_addoption(parser): '--rsyncignore', action="append", default=[], metavar="GLOB", help="add expression for ignores when rsyncing to remote tx nodes.") + group.addoption( + "--boxed", action="store_true", + help="backward compatibility alias for pytest-forked --forked") parser.addini( 'rsyncdirs', 'list of (relative) paths to be rsynced for' ' remote distributed testing.', type="pathlist") @@ -67,6 +70,7 @@ def pytest_addoption(parser): "looponfailroots", type="pathlist", help="directories to check for changes", default=[py.path.local()]) + # ------------------------------------------------------------------------- # distributed testing hooks # ------------------------------------------------------------------------- @@ -93,6 +97,8 @@ def pytest_configure(config): config.pluginmanager.register(session, "dsession") tr = config.pluginmanager.getplugin("terminalreporter") tr.showfspath = False + if config.getoption("boxed"): + config.option.forked = True @pytest.mark.tryfirst From 7f20416a7000e9dd766a8b4f04325ffaeaa7be75 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Fri, 4 Aug 2017 21:32:44 +0200 Subject: [PATCH 5/8] changelog entry --- changelog/1.removal | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/1.removal diff --git a/changelog/1.removal b/changelog/1.removal new file mode 100644 index 00000000..14abf388 --- /dev/null +++ b/changelog/1.removal @@ -0,0 +1 @@ +remove the implementation of "boxed" and use pytest-forked for providing ``--boxed`` \ No newline at end of file From 060e7b85ad2320bddc1319eb6d21f3a52f5c50ce Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Fri, 4 Aug 2017 23:24:09 +0200 Subject: [PATCH 6/8] include brunos review suggestions for changes --- changelog/1.removal | 2 +- example/boxed.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/changelog/1.removal b/changelog/1.removal index 14abf388..57e70ba5 100644 --- a/changelog/1.removal +++ b/changelog/1.removal @@ -1 +1 @@ -remove the implementation of "boxed" and use pytest-forked for providing ``--boxed`` \ No newline at end of file +``--boxed`` functionality has been moved to a separate plugin, `pytest-forked `_. This release now depends on `` pytest-forked`` and provides ``--boxed`` as a backward compatibility option. \ No newline at end of file diff --git a/example/boxed.txt b/example/boxed.txt index a3a3daee..b5c577d3 100644 --- a/example/boxed.txt +++ b/example/boxed.txt @@ -1,3 +1,9 @@ +.. note:: + + Since 2.0, the actual implementation of the ``--boxed`` option has been moved to a + separate plugin, `pytest-forked `_ + which can be installed independently. The ``--boxed`` command-line options remains + for backward compatibility reasons. If your testing involves C or C++ libraries you might have to deal From f856cb74f466fa067112c79dc11c3a7455ec243c Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Sat, 5 Aug 2017 08:28:30 +0200 Subject: [PATCH 7/8] fix linting issue --- xdist/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xdist/plugin.py b/xdist/plugin.py index 1e41bb4b..17c9e194 100644 --- a/xdist/plugin.py +++ b/xdist/plugin.py @@ -27,8 +27,8 @@ def pytest_addoption(parser): "you can use 'auto' here for auto detection CPUs number on " "host system") group.addoption('--max-slave-restart', action="store", default=None, - help="maximum number of slaves that can be restarted " - "when crashed (set to zero to disable this feature)") + help="maximum number of slaves that can be restarted " + "when crashed (set to zero to disable this feature)") group.addoption( '--dist', metavar="distmode", action="store", choices=['each', 'load', 'loadscope', 'no'], From c454d410a1c76f7533e6275e47812da9ab98eec3 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Sat, 5 Aug 2017 09:33:10 +0200 Subject: [PATCH 8/8] fix version number --- example/boxed.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/boxed.txt b/example/boxed.txt index b5c577d3..1c83e630 100644 --- a/example/boxed.txt +++ b/example/boxed.txt @@ -1,6 +1,6 @@ .. note:: - Since 2.0, the actual implementation of the ``--boxed`` option has been moved to a + Since 1.19.0, the actual implementation of the ``--boxed`` option has been moved to a separate plugin, `pytest-forked `_ which can be installed independently. The ``--boxed`` command-line options remains for backward compatibility reasons.