summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2010-05-17 00:14:53 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2010-05-17 00:14:53 (GMT)
commitc2d095f4942408bbd85d934479ff049689b682cf (patch)
tree58f0740f2d50b6eebc3e15294880006fbbfd0c5a /Lib
parent304740635b6066d11850a36c46991fcea4cdb800 (diff)
downloadcpython-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')
-rw-r--r--Lib/test/test_os.py101
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):