diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2010-05-17 00:14:53 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2010-05-17 00:14:53 (GMT) |
commit | c2d095f4942408bbd85d934479ff049689b682cf (patch) | |
tree | 58f0740f2d50b6eebc3e15294880006fbbfd0c5a /Lib/test/test_os.py | |
parent | 304740635b6066d11850a36c46991fcea4cdb800 (diff) | |
download | cpython-c2d095f4942408bbd85d934479ff049689b682cf.zip cpython-c2d095f4942408bbd85d934479ff049689b682cf.tar.gz cpython-c2d095f4942408bbd85d934479ff049689b682cf.tar.bz2 |
test_os: cleanup test_internal_execvpe() and os._execvpe() mockup
* Replace os.defpath instead of os.get_exec_path() to test also
os.get_exec_path()
* Use contextlib.contextmanager, move the mockup outside the class, and
the mockup returns directly the call list object
* Use two different contexts for the two tests
* Use more revelant values and names
Diffstat (limited to 'Lib/test/test_os.py')
-rw-r--r-- | Lib/test/test_os.py | 101 |
1 files changed, 53 insertions, 48 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 3e958f2..49f9cbd 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -12,6 +12,7 @@ import subprocess import time import shutil from test import support +import contextlib # Detect whether we're on a Linux system that uses the (now outdated # and unmaintained) linuxthreads threading library. There's an issue @@ -623,6 +624,39 @@ class URandomTests(unittest.TestCase): except NotImplementedError: pass +@contextlib.contextmanager +def _execvpe_mockup(defpath=None): + """ + Stubs out execv and execve functions when used as context manager. + Records exec calls. The mock execv and execve functions always raise an + exception as they would normally never return. + """ + # A list of tuples containing (function name, first arg, args) + # of calls to execv or execve that have been made. + calls = [] + + def mock_execv(name, *args): + calls.append(('execv', name, args)) + raise RuntimeError("execv called") + + def mock_execve(name, *args): + calls.append(('execve', name, args)) + raise OSError(errno.ENOTDIR, "execve called") + + try: + orig_execv = os.execv + orig_execve = os.execve + orig_defpath = os.defpath + os.execv = mock_execv + os.execve = mock_execve + if defpath is not None: + os.defpath = defpath + yield calls + finally: + os.execv = orig_execv + os.execve = orig_execve + os.defpath = orig_defpath + class ExecTests(unittest.TestCase): @unittest.skipIf(USING_LINUXTHREADS, "avoid triggering a linuxthreads bug: see issue #4970") @@ -633,57 +667,28 @@ class ExecTests(unittest.TestCase): def test_execvpe_with_bad_arglist(self): self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) - class _stub_out_for_execvpe_test(object): - """ - Stubs out execv, execve and get_exec_path functions when - used as context manager. Records exec calls. The mock execv - and execve functions always raise an exception as they would - normally never return. - """ - def __init__(self): - # A list of tuples containing (function name, first arg, args) - # of calls to execv or execve that have been made. - self.calls = [] - def _mock_execv(self, name, *args): - self.calls.append(('execv', name, args)) - raise RuntimeError("execv called") - - def _mock_execve(self, name, *args): - self.calls.append(('execve', name, args)) - raise OSError(errno.ENOTDIR, "execve called") - - def _mock_get_exec_path(self, env=None): - return [os.sep+'p', os.sep+'pp'] - - def __enter__(self): - self.orig_execv = os.execv - self.orig_execve = os.execve - self.orig_get_exec_path = os.get_exec_path - os.execv = self._mock_execv - os.execve = self._mock_execve - os.get_exec_path = self._mock_get_exec_path - - def __exit__(self, type, value, tb): - os.execv = self.orig_execv - os.execve = self.orig_execve - os.get_exec_path = self.orig_get_exec_path - @unittest.skipUnless(hasattr(os, '_execvpe'), "No internal os._execvpe function to test.") def test_internal_execvpe(self): - exec_stubbed = self._stub_out_for_execvpe_test() - with exec_stubbed: - self.assertRaises(RuntimeError, os._execvpe, os.sep+'f', ['-a']) - self.assertEqual([('execv', os.sep+'f', (['-a'],))], - exec_stubbed.calls) - exec_stubbed.calls = [] - self.assertRaises(OSError, os._execvpe, 'f', ['-a'], - env={'spam': 'beans'}) - self.assertEqual([('execve', os.sep+'p'+os.sep+'f', - (['-a'], {'spam': 'beans'})), - ('execve', os.sep+'pp'+os.sep+'f', - (['-a'], {'spam': 'beans'}))], - exec_stubbed.calls) + program_path = os.sep+'absolutepath' + program = 'executable' + fullpath = os.path.join(program_path, program) + arguments = ['progname', 'arg1', 'arg2'] + env = {'spam': 'beans'} + + with _execvpe_mockup() as calls: + self.assertRaises(RuntimeError, os._execvpe, fullpath, arguments) + self.assertEqual(len(calls), 1) + self.assertEqual(calls[0], ('execv', fullpath, (arguments,))) + + with _execvpe_mockup(defpath=program_path) as calls: + self.assertRaises(OSError, os._execvpe, program, arguments, env=env) + self.assertEqual(len(calls), 1) + if os.name != "nt": + self.assertEqual(calls[0], ('execve', os.fsencode(fullpath), (arguments, env))) + else: + self.assertEqual(calls[0], ('execve', fullpath, (arguments, env))) + class Win32ErrorTests(unittest.TestCase): def test_rename(self): |