[pypy-svn] r58320 - in pypy/build/testrunner: . test test/examples test/examples/normal

pedronis at codespeak.net pedronis at codespeak.net
Mon Sep 22 15:26:31 CEST 2008


Author: pedronis
Date: Mon Sep 22 15:26:29 2008
New Revision: 58320

Added:
   pypy/build/testrunner/   (props changed)
   pypy/build/testrunner/runner.py   (contents, props changed)
   pypy/build/testrunner/test/   (props changed)
   pypy/build/testrunner/test/examples/
   pypy/build/testrunner/test/examples/normal/
   pypy/build/testrunner/test/examples/normal/example.py   (contents, props changed)
   pypy/build/testrunner/test/examples/normal/example_importerror.py   (contents, props changed)
   pypy/build/testrunner/test/examples/normal/failingsetup.py   (contents, props changed)
   pypy/build/testrunner/test/examples/normal/failingsetup_tricky.py   (contents, props changed)
   pypy/build/testrunner/test/test_runner.py   (contents, props changed)
Log:
(iko, pedronis)

start working on a per-dir (parallel) test runner



Added: pypy/build/testrunner/runner.py
==============================================================================
--- (empty file)
+++ pypy/build/testrunner/runner.py	Mon Sep 22 15:26:29 2008
@@ -0,0 +1,64 @@
+import sys, os, signal
+import py
+from py.compat import subprocess
+
+
+def run(args, cwd, out):
+    f = out.open('w')
+    try:
+        return subprocess.call(args, cwd=str(cwd), stdout=f, stderr=f)
+    finally:
+        f.close()
+
+
+def getsignalname(n):
+    for name, value in signal.__dict__.items():
+        if value == n and name.startswith('SIG'):
+            return name
+    return 'signal %d' % (n,)
+
+def execute_test(cwd, test, out, logfname, interp=None, test_driver=None):
+    if interp is None:
+        interp = [os.path.abspath(sys.executable)]
+    if test_driver is None:
+        test_driver = [os.path.abspath(os.path.join('py', 'bin', 'py.test'))]
+
+    args = interp+test_driver
+    args += ['--resultlog=%s' % logfname, test]
+
+    args = map(str, args)
+
+    exitcode = run(args, cwd, out)
+    return exitcode
+
+
+
+def execute_tests(cwd, testdirs, logfile, out, test_driver=None):
+    sessdir = py.path.local.make_numbered_dir(prefix='usession-testrunner-', keep=4)
+    c = 0
+    failure = False
+    
+    for test in testdirs:
+        basename = py.path.local(test).purebasename
+        logfname = sessdir.join("%d-%s-pytest-log" % (c, basename))
+        one_output = sessdir.join("%d-%s-output" % (c, basename))
+        c += 1
+        exitcode = execute_test(cwd, test, one_output, logfname,
+                                test_driver=test_driver)
+        if c > 1:
+            out.write(79*'_'+'\n')
+        output = one_output.read()
+        out.write(output)
+        if logfname.check(file=1):
+            logdata = logfname.read()
+            logfile.write(logdata)
+        if exitcode:
+            failure = True
+            if exitcode != 1:
+                pass # xxx unexpected exit cases
+
+    return failure
+
+        
+        
+        

Added: pypy/build/testrunner/test/examples/normal/example.py
==============================================================================
--- (empty file)
+++ pypy/build/testrunner/test/examples/normal/example.py	Mon Sep 22 15:26:29 2008
@@ -0,0 +1,18 @@
+
+def test_one():
+    assert 1 == 10/10
+
+def test_two():
+    assert 2 == 3
+
+def test_three():
+    assert "hello" == "world"
+
+def test_many():
+    for i in range(100):
+        yield test_one,
+
+class TestStuff:
+
+    def test_final(self):
+        crash

Added: pypy/build/testrunner/test/examples/normal/example_importerror.py
==============================================================================
--- (empty file)
+++ pypy/build/testrunner/test/examples/normal/example_importerror.py	Mon Sep 22 15:26:29 2008
@@ -0,0 +1 @@
+print 1/0

Added: pypy/build/testrunner/test/examples/normal/failingsetup.py
==============================================================================
--- (empty file)
+++ pypy/build/testrunner/test/examples/normal/failingsetup.py	Mon Sep 22 15:26:29 2008
@@ -0,0 +1,6 @@
+
+def setup_module(mod):
+    raise RuntimeError
+
+def test_bar(self):
+    assert True

Added: pypy/build/testrunner/test/examples/normal/failingsetup_tricky.py
==============================================================================
--- (empty file)
+++ pypy/build/testrunner/test/examples/normal/failingsetup_tricky.py	Mon Sep 22 15:26:29 2008
@@ -0,0 +1,6 @@
+
+def setup_module(mod):
+    raise RuntimeError
+
+def test_goo(self):
+    yield (lambda: None)

Added: pypy/build/testrunner/test/test_runner.py
==============================================================================
--- (empty file)
+++ pypy/build/testrunner/test/test_runner.py	Mon Sep 22 15:26:29 2008
@@ -0,0 +1,97 @@
+import py, sys, os, signal, cStringIO
+
+import runner
+
+
+class TestExecuteTest(object):
+
+    def setup_class(cls):
+        cls.real_run = (runner.run,)
+        cls.called = []
+        cls.exitcode = [0]
+        
+        def fake_run(args, cwd, out):
+            cls.called = (args, cwd, out)
+            return cls.exitcode[0]
+        runner.run = fake_run
+
+    def teardown_class(cls):
+        runner.run = cls.real_run[0]
+
+    def test_basic(self):
+        res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE')
+
+        expected = [os.path.abspath(sys.executable),
+                    os.path.abspath(os.path.join('py', 'bin', 'py.test')),
+                    '--resultlog=LOGFILE',
+                    'test_one']
+
+        assert self.called == (expected, '/wd', 'out')
+        assert res == 0
+
+
+    def test_explicit(self):
+        res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE',
+                                  interp=['INTERP', 'IARG'],
+                                  test_driver=['driver', 'darg'])
+
+        expected = ['INTERP', 'IARG', 
+                    'driver', 'darg',
+                    '--resultlog=LOGFILE',
+                    'test_one']
+
+        assert self.called == (expected, '/wd', 'out')        
+        assert res == 0
+    
+
+    def test_error(self):
+        self.exitcode[:] = [1]
+        res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE')
+        assert res == 1
+
+
+        self.exitcode[:] = [-signal.SIGSEGV]
+        res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE')
+        assert res == -signal.SIGSEGV
+
+
+class TestRunner(object):
+
+
+    def setup_class(cls):
+        cls.udir = py.path.local.make_numbered_dir(prefix='usession-runner-',
+                                              keep=3)
+        cls.udir.join('test_normal').ensure(dir=1)
+        for p in py.path.local(__file__).dirpath(
+            'examples', 'normal').listdir("*.py"):
+            p.copy(cls.udir.join('test_normal', 'test_'+p.basename))
+
+    def teardown_class(cls):
+        pass
+
+    def test_one_dir(self):
+        test_driver = [py.path.local(py.__file__).dirpath('bin', 'py.test')]
+
+        log = cStringIO.StringIO()
+        out = cStringIO.StringIO()
+        
+        res = runner.execute_tests(self.udir, ['test_normal'], log, out,
+                                   test_driver=test_driver)
+
+        assert res
+
+        assert out.getvalue()
+
+        log_lines = log.getvalue().splitlines()
+
+        assert log_lines[0] == ". test_normal/test_example.py:test_one"
+        nfailures = 0
+        noutcomes = 0
+        for line in log_lines:
+            if line[0] != ' ':
+                noutcomes += 1
+                if line[0] != '.':
+                    nfailures += 1
+
+        assert noutcomes == 107
+        assert nfailures == 6



More information about the Pypy-commit mailing list