Commits

Ronny Pfannschmidt committed 9ee1590

initial commit

Comments (0)

Files changed (6)

+.*\.egg-info
+\.tox
+\.cache
+dist
+build
+pytest_plugins = 'pytester'
+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)
+    return rep
+from setuptools import setup
+
+setup(
+    name='pytest-boxed',
+    version_from_scm=True,
+    license='GPLv2 or later',
+    author='holger krekel and contributors',
+    author_email='py-dev@codespeak.net,holger@merlinux.eu',
+    maintainer='Ronny Pfannschmidt',
+    maintainer_email='ronny.pfannschmidt@gmx.de',
+    url='http://bitbucket.org/RonnyPfannschmidt/pytest-boxed',
+    platforms=['linux', 'osx', 'posix'],
+    py_modules=['pytest_boxed'],
+    entry_points={'pytest11': ['boxed = pytest_boxed']},
+    install_requires=['pytest>=2.2'],
+    setup_requires=['hgdistver'],
+    classifiers=[
+        'Development Status :: 5 - Production/Stable',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: GNU General Public License (GPL)',
+        'Operating System :: POSIX',
+        'Operating System :: Microsoft :: Windows',
+        'Operating System :: MacOS :: MacOS X',
+        'Topic :: Software Development :: Testing',
+        'Topic :: Software Development :: Quality Assurance',
+        'Topic :: Utilities',
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 3',
+    ],
+)
+import py
+
+@py.test.mark.skipif("not hasattr(os, 'fork')")
+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*"
+    ])
+
+class TestOptionEffects:
+    def test_boxed_option_default(self, testdir):
+        tmpdir = testdir.tmpdir.ensure("subdir", dir=1)
+        config = testdir.parseconfig()
+        assert not config.option.boxed
+        py.test.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
+
+[tox]
+envlist=py26,py31,py27,py25,py24
+indexserver=
+    testrun = http://pypi.testrun.org
+    pypi = http://pypi.python.org/simple
+
+[testenv]
+changedir=testing
+deps=:testrun:pytest>=2.2.0.dev2
+commands= py.test --junitxml={envlogdir}/junit-{envname}.xml []
+
+#[testenv:py31]
+#deps=:pypi:pytest  # XXX needed because ClueRelease/pip broken
+#[testenv:py32]
+#deps=:pypi:pytest  # XXX needed because ClueRelease/pip broken
+
+[testenv:py26]
+deps=
+    :testrun:pytest
+    :pypi:pexpect
+
+[pytest]
+addopts = -rsfxX
+;; hello