[Python-checkins] r81247 - python/branches/py3k/Lib/test/test_os.py

victor.stinner python-checkins at python.org
Mon May 17 02:14:53 CEST 2010


Author: victor.stinner
Date: Mon May 17 02:14:53 2010
New Revision: 81247

Log:
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


Modified:
   python/branches/py3k/Lib/test/test_os.py

Modified: python/branches/py3k/Lib/test/test_os.py
==============================================================================
--- python/branches/py3k/Lib/test/test_os.py	(original)
+++ python/branches/py3k/Lib/test/test_os.py	Mon May 17 02:14:53 2010
@@ -12,6 +12,7 @@
 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 @@
         except NotImplementedError:
             pass
 
+ at 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 @@
     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):


More information about the Python-checkins mailing list