summaryrefslogtreecommitdiff
path: root/functional_tests
diff options
context:
space:
mode:
authorkumar <kumar.mcmillan@gmail.com>2011-11-11 11:53:23 -0600
committerkumar <kumar.mcmillan@gmail.com>2011-11-11 11:53:23 -0600
commit38a976ccaeef112f988058ebbac7833f7bcecfa1 (patch)
treefa2f8546e4923a5a197ced166b6ffb0a8efbeff0 /functional_tests
parentc3a9d056a88ffd05330d702192434dae7b23e385 (diff)
parent0f3ff413655950a3de8507f41575aec025e4b234 (diff)
downloadnose-38a976ccaeef112f988058ebbac7833f7bcecfa1.tar.gz
Merged
Diffstat (limited to 'functional_tests')
-rw-r--r--functional_tests/test_multiprocessing/__init__.py28
-rw-r--r--functional_tests/test_multiprocessing/support/class.py14
-rw-r--r--functional_tests/test_multiprocessing/support/concurrent_shared/__init__.py6
-rw-r--r--functional_tests/test_multiprocessing/support/concurrent_shared/test.py11
-rw-r--r--functional_tests/test_multiprocessing/support/fake_nosetest.py14
-rw-r--r--functional_tests/test_multiprocessing/support/keyboardinterrupt.py29
-rw-r--r--functional_tests/test_multiprocessing/support/keyboardinterrupt_twice.py34
-rw-r--r--functional_tests/test_multiprocessing/support/timeout.py6
-rw-r--r--functional_tests/test_multiprocessing/test_class.py13
-rw-r--r--functional_tests/test_multiprocessing/test_concurrent_shared.py13
-rw-r--r--functional_tests/test_multiprocessing/test_keyboardinterrupt.py84
-rw-r--r--functional_tests/test_multiprocessing/test_nameerror.py26
-rw-r--r--functional_tests/test_multiprocessing/test_process_timeout.py30
13 files changed, 263 insertions, 45 deletions
diff --git a/functional_tests/test_multiprocessing/__init__.py b/functional_tests/test_multiprocessing/__init__.py
new file mode 100644
index 0000000..2a52efd
--- /dev/null
+++ b/functional_tests/test_multiprocessing/__init__.py
@@ -0,0 +1,28 @@
+import os
+from unittest import TestCase
+
+from nose.plugins import PluginTester
+from nose.plugins.skip import SkipTest
+from nose.plugins.multiprocess import MultiProcess
+
+support = os.path.join(os.path.dirname(__file__), 'support')
+
+def setup():
+ try:
+ import multiprocessing
+ if 'active' in MultiProcess.status:
+ raise SkipTest("Multiprocess plugin is active. Skipping tests of "
+ "plugin itself.")
+ except ImportError:
+ raise SkipTest("multiprocessing module not available")
+
+class MPTestBase(PluginTester, TestCase):
+ processes = 1
+ activate = '--processes=1'
+ plugins = [MultiProcess()]
+ suitepath = os.path.join(support, 'timeout.py')
+
+ def __init__(self, *args, **kwargs):
+ self.activate = '--processes=%d' % self.processes
+ PluginTester.__init__(self)
+ TestCase.__init__(self, *args, **kwargs)
diff --git a/functional_tests/test_multiprocessing/support/class.py b/functional_tests/test_multiprocessing/support/class.py
new file mode 100644
index 0000000..905bcdf
--- /dev/null
+++ b/functional_tests/test_multiprocessing/support/class.py
@@ -0,0 +1,14 @@
+class TestFunctionalTest(object):
+ counter = 0
+ @classmethod
+ def setup_class(cls):
+ cls.counter += 1
+ @classmethod
+ def teardown_class(cls):
+ cls.counter -= 1
+ def _run(self):
+ assert self.counter==1
+ def test1(self):
+ self._run()
+ def test2(self):
+ self._run()
diff --git a/functional_tests/test_multiprocessing/support/concurrent_shared/__init__.py b/functional_tests/test_multiprocessing/support/concurrent_shared/__init__.py
new file mode 100644
index 0000000..c557001
--- /dev/null
+++ b/functional_tests/test_multiprocessing/support/concurrent_shared/__init__.py
@@ -0,0 +1,6 @@
+counter=[0]
+_multiprocess_shared_ = True
+def setup_package():
+ counter[0] += 1
+def teardown_package():
+ counter[0] -= 1
diff --git a/functional_tests/test_multiprocessing/support/concurrent_shared/test.py b/functional_tests/test_multiprocessing/support/concurrent_shared/test.py
new file mode 100644
index 0000000..5bc21f6
--- /dev/null
+++ b/functional_tests/test_multiprocessing/support/concurrent_shared/test.py
@@ -0,0 +1,11 @@
+#from . import counter
+from time import sleep
+#_multiprocess_can_split_ = True
+class Test1(object):
+ def test1(self):
+ sleep(1)
+ pass
+class Test2(object):
+ def test2(self):
+ sleep(1)
+ pass
diff --git a/functional_tests/test_multiprocessing/support/fake_nosetest.py b/functional_tests/test_multiprocessing/support/fake_nosetest.py
new file mode 100644
index 0000000..f5a6289
--- /dev/null
+++ b/functional_tests/test_multiprocessing/support/fake_nosetest.py
@@ -0,0 +1,14 @@
+import os
+import sys
+
+import nose
+from nose.plugins.multiprocess import MultiProcess
+from nose.config import Config
+from nose.plugins.manager import PluginManager
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print "USAGE: %s TEST_FILE LOG_FILE" % sys.argv[0]
+ sys.exit(1)
+ os.environ['NOSE_MP_LOG']=sys.argv[2]
+ nose.main(defaultTest=sys.argv[1], argv=[sys.argv[0],'--processes=1','-v'], config=Config(plugins=PluginManager(plugins=[MultiProcess()])))
diff --git a/functional_tests/test_multiprocessing/support/keyboardinterrupt.py b/functional_tests/test_multiprocessing/support/keyboardinterrupt.py
new file mode 100644
index 0000000..2c36d95
--- /dev/null
+++ b/functional_tests/test_multiprocessing/support/keyboardinterrupt.py
@@ -0,0 +1,29 @@
+import os
+
+from tempfile import mktemp
+from time import sleep
+
+if 'NOSE_MP_LOG' not in os.environ:
+ raise Exception('Environment variable NOSE_MP_LOG is not set')
+
+logfile = os.environ['NOSE_MP_LOG']
+
+def log(w):
+ f = open(logfile, 'a')
+ f.write(w+"\n")
+ f.close()
+#make sure all tests in this file are dispatched to the same subprocess
+def setup():
+ log('setup')
+
+def test_timeout():
+ log('test_timeout')
+ sleep(2)
+ log('test_timeout_finished')
+
+# check timeout will not prevent remaining tests dispatched to the same subprocess to continue to run
+def test_pass():
+ log('test_pass')
+
+def teardown():
+ log('teardown')
diff --git a/functional_tests/test_multiprocessing/support/keyboardinterrupt_twice.py b/functional_tests/test_multiprocessing/support/keyboardinterrupt_twice.py
new file mode 100644
index 0000000..3932bbd
--- /dev/null
+++ b/functional_tests/test_multiprocessing/support/keyboardinterrupt_twice.py
@@ -0,0 +1,34 @@
+import os
+
+from tempfile import mktemp
+from time import sleep
+
+if 'NOSE_MP_LOG' not in os.environ:
+ raise Exception('Environment variable NOSE_MP_LOG is not set')
+
+logfile = os.environ['NOSE_MP_LOG']
+
+def log(w):
+ f = open(logfile, 'a')
+ f.write(w+"\n")
+ f.close()
+#make sure all tests in this file are dispatched to the same subprocess
+def setup():
+ '''global logfile
+ logfile = mktemp()
+ print "tempfile is:",logfile'''
+ log('setup')
+
+def test_timeout():
+ log('test_timeout')
+ sleep(2)
+ log('test_timeout_finished')
+
+# check timeout will not prevent remaining tests dispatched to the same subprocess to continue to run
+def test_pass():
+ log('test_pass')
+
+def teardown():
+ log('teardown')
+ sleep(10)
+ log('teardown_finished')
diff --git a/functional_tests/test_multiprocessing/support/timeout.py b/functional_tests/test_multiprocessing/support/timeout.py
index 52dce12..480c859 100644
--- a/functional_tests/test_multiprocessing/support/timeout.py
+++ b/functional_tests/test_multiprocessing/support/timeout.py
@@ -1,6 +1,12 @@
+#make sure all tests in this file are dispatched to the same subprocess
+def setup():
+ pass
def test_timeout():
"this test *should* fail when process-timeout=1"
from time import sleep
sleep(2)
+# check timeout will not prevent remaining tests dispatched to the same subprocess to continue to run
+def test_pass():
+ pass
diff --git a/functional_tests/test_multiprocessing/test_class.py b/functional_tests/test_multiprocessing/test_class.py
new file mode 100644
index 0000000..d92710d
--- /dev/null
+++ b/functional_tests/test_multiprocessing/test_class.py
@@ -0,0 +1,13 @@
+import os
+
+from test_multiprocessing import MPTestBase
+
+
+#test case for #462
+class TestClassFixture(MPTestBase):
+ suitepath = os.path.join(os.path.dirname(__file__), 'support', 'class.py')
+
+ def runTest(self):
+ assert str(self.output).strip().endswith('OK')
+ assert 'Ran 2 tests' in self.output
+
diff --git a/functional_tests/test_multiprocessing/test_concurrent_shared.py b/functional_tests/test_multiprocessing/test_concurrent_shared.py
new file mode 100644
index 0000000..2552c2b
--- /dev/null
+++ b/functional_tests/test_multiprocessing/test_concurrent_shared.py
@@ -0,0 +1,13 @@
+import os
+
+from test_multiprocessing import MPTestBase
+
+class TestConcurrentShared(MPTestBase):
+ processes = 2
+ suitepath = os.path.join(os.path.dirname(__file__), 'support',
+ 'concurrent_shared')
+
+ def runTest(self):
+ assert 'Ran 2 tests in 1.' in self.output, "make sure two tests use 1.x seconds (no more than 2 seconsd)"
+ assert str(self.output).strip().endswith('OK')
+
diff --git a/functional_tests/test_multiprocessing/test_keyboardinterrupt.py b/functional_tests/test_multiprocessing/test_keyboardinterrupt.py
new file mode 100644
index 0000000..8f07e54
--- /dev/null
+++ b/functional_tests/test_multiprocessing/test_keyboardinterrupt.py
@@ -0,0 +1,84 @@
+from subprocess import Popen,PIPE
+import os
+import sys
+from time import sleep
+import signal
+
+import nose
+
+support = os.path.join(os.path.dirname(__file__), 'support')
+
+PYTHONPATH = os.environ['PYTHONPATH'] if 'PYTHONPATH' in os.environ else ''
+def setup():
+ nose_parent_dir = os.path.normpath(os.path.join(os.path.abspath(os.path.dirname(nose.__file__)),'..'))
+ paths = [nose_parent_dir]
+ if PYTHONPATH:
+ paths.append(PYTHONPATH)
+ os.environ['PYTHONPATH'] = os.pathsep.join(paths)
+def teardown():
+ if PYTHONPATH:
+ os.environ['PYTHONPATH'] = PYTHONPATH
+ else:
+ del os.environ['PYTHONPATH']
+
+runner = os.path.join(support, 'fake_nosetest.py')
+def keyboardinterrupt(case):
+ #os.setsid would create a process group so signals sent to the
+ #parent process will propogates to all children processes
+ from tempfile import mktemp
+ logfile = mktemp()
+ process = Popen([sys.executable,runner,os.path.join(support,case),logfile], preexec_fn=os.setsid, stdout=PIPE, stderr=PIPE, bufsize=-1)
+
+ #wait until logfile is created:
+ retry=100
+ while not os.path.exists(logfile):
+ sleep(0.1)
+ retry -= 1
+ if not retry:
+ raise Exception('Timeout while waiting for log file to be created by fake_nosetest.py')
+
+ os.killpg(process.pid, signal.SIGINT)
+ return process, logfile
+
+def get_log_content(logfile):
+ '''prefix = 'tempfile is: '
+ if not stdout.startswith(prefix):
+ raise Exception('stdout does not contain tmp file name: '+stdout)
+ logfile = stdout[len(prefix):].strip() #remove trailing new line char'''
+ f = open(logfile)
+ content = f.read()
+ f.close()
+ os.remove(logfile)
+ return content
+
+def test_keyboardinterrupt():
+ process, logfile = keyboardinterrupt('keyboardinterrupt.py')
+ stdout, stderr = [s.decode('utf-8') for s in process.communicate(None)]
+ print stderr
+ log = get_log_content(logfile)
+ assert 'setup' in log
+ assert 'test_timeout' in log
+ assert 'test_timeout_finished' not in log
+ assert 'test_pass' not in log
+ assert 'teardown' in log
+ assert 'Ran 0 tests' in stderr
+ assert 'KeyboardInterrupt' in stderr
+ assert 'FAILED (errors=1)' in stderr
+ assert 'ERROR: Worker 0 keyboard interrupt, failing current test '+os.path.join(support,'keyboardinterrupt.py') in stderr
+
+
+def test_keyboardinterrupt_twice():
+ process, logfile = keyboardinterrupt('keyboardinterrupt_twice.py')
+ sleep(0.5)
+ os.killpg(process.pid, signal.SIGINT)
+ stdout, stderr = [s.decode('utf-8') for s in process.communicate(None)]
+ log = get_log_content(logfile)
+ assert 'setup' in log
+ assert 'test_timeout' in log
+ assert 'test_timeout_finished' not in log
+ assert 'test_pass' not in log
+ assert 'teardown' in log
+ assert 'teardown_finished' not in log
+ assert 'Ran 0 tests' in stderr
+ assert 'KeyboardInterrupt' in stderr
+ assert 'FAILED (errors=1)' in stderr
diff --git a/functional_tests/test_multiprocessing/test_nameerror.py b/functional_tests/test_multiprocessing/test_nameerror.py
index f73d02b..5e58226 100644
--- a/functional_tests/test_multiprocessing/test_nameerror.py
+++ b/functional_tests/test_multiprocessing/test_nameerror.py
@@ -1,28 +1,10 @@
import os
-import unittest
-from nose.plugins import PluginTester
-from nose.plugins.skip import SkipTest
-from nose.plugins.multiprocess import MultiProcess
+from test_multiprocessing import support, MPTestBase
-
-support = os.path.join(os.path.dirname(__file__), 'support')
-
-
-def setup():
- try:
- import multiprocessing
- if 'active' in MultiProcess.status:
- raise SkipTest("Multiprocess plugin is active. Skipping tests of "
- "plugin itself.")
- except ImportError:
- raise SkipTest("multiprocessing module not available")
-
-
-class TestMPNameError(PluginTester, unittest.TestCase):
- activate = '--processes=2'
- plugins = [MultiProcess()]
- suitepath = os.path.join(support, 'nameerror.py')
+class TestMPNameError(MPTestBase):
+ processes = 2
+ suitepath = os.path.join(os.path.dirname(__file__), 'support', 'nameerror.py')
def runTest(self):
print str(self.output)
diff --git a/functional_tests/test_multiprocessing/test_process_timeout.py b/functional_tests/test_multiprocessing/test_process_timeout.py
index 535ecdb..6b858f8 100644
--- a/functional_tests/test_multiprocessing/test_process_timeout.py
+++ b/functional_tests/test_multiprocessing/test_process_timeout.py
@@ -1,37 +1,21 @@
import os
-import unittest
-from nose.plugins import PluginTester
-from nose.plugins.skip import SkipTest
-from nose.plugins.multiprocess import MultiProcess
+from test_multiprocessing import MPTestBase
-support = os.path.join(os.path.dirname(__file__), 'support')
-
-
-def setup():
- try:
- import multiprocessing
- if 'active' in MultiProcess.status:
- raise SkipTest("Multiprocess plugin is active. Skipping tests of "
- "plugin itself.")
- except ImportError:
- raise SkipTest("multiprocessing module not available")
-
-
-
-class TestMPTimeout(PluginTester, unittest.TestCase):
- activate = '--processes=2'
+class TestMPTimeout(MPTestBase):
args = ['--process-timeout=1']
- plugins = [MultiProcess()]
- suitepath = os.path.join(support, 'timeout.py')
+ suitepath = os.path.join(os.path.dirname(__file__), 'support', 'timeout.py')
def runTest(self):
assert "TimedOutException: 'timeout.test_timeout'" in self.output
-
+ assert "Ran 2 tests in" in self.output
+ assert "FAILED (errors=1)" in self.output
class TestMPTimeoutPass(TestMPTimeout):
args = ['--process-timeout=3']
def runTest(self):
assert "TimedOutException: 'timeout.test_timeout'" not in self.output
+ assert "Ran 2 tests in" in self.output
assert str(self.output).strip().endswith('OK')
+