1 """Unittests for test.support.script_helper. Who tests the test helper?"""
2
3 import subprocess
4 import sys
5 import os
6 from test.support import script_helper, requires_subprocess
7 import unittest
8 from unittest import mock
9
10
11 class ESC[4;38;5;81mTestScriptHelper(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
12
13 def test_assert_python_ok(self):
14 t = script_helper.assert_python_ok('-c', 'import sys; sys.exit(0)')
15 self.assertEqual(0, t[0], 'return code was not 0')
16
17 def test_assert_python_failure(self):
18 # I didn't import the sys module so this child will fail.
19 rc, out, err = script_helper.assert_python_failure('-c', 'sys.exit(0)')
20 self.assertNotEqual(0, rc, 'return code should not be 0')
21
22 def test_assert_python_ok_raises(self):
23 # I didn't import the sys module so this child will fail.
24 with self.assertRaises(AssertionError) as error_context:
25 script_helper.assert_python_ok('-c', 'sys.exit(0)')
26 error_msg = str(error_context.exception)
27 self.assertIn('command line:', error_msg)
28 self.assertIn('sys.exit(0)', error_msg, msg='unexpected command line')
29
30 def test_assert_python_failure_raises(self):
31 with self.assertRaises(AssertionError) as error_context:
32 script_helper.assert_python_failure('-c', 'import sys; sys.exit(0)')
33 error_msg = str(error_context.exception)
34 self.assertIn('Process return code is 0\n', error_msg)
35 self.assertIn('import sys; sys.exit(0)', error_msg,
36 msg='unexpected command line.')
37
38 @mock.patch('subprocess.Popen')
39 def test_assert_python_isolated_when_env_not_required(self, mock_popen):
40 with mock.patch.object(script_helper,
41 'interpreter_requires_environment',
42 return_value=False) as mock_ire_func:
43 mock_popen.side_effect = RuntimeError('bail out of unittest')
44 try:
45 script_helper._assert_python(True, '-c', 'None')
46 except RuntimeError as err:
47 self.assertEqual('bail out of unittest', err.args[0])
48 self.assertEqual(1, mock_popen.call_count)
49 self.assertEqual(1, mock_ire_func.call_count)
50 popen_command = mock_popen.call_args[0][0]
51 self.assertEqual(sys.executable, popen_command[0])
52 self.assertIn('None', popen_command)
53 self.assertIn('-I', popen_command)
54 self.assertNotIn('-E', popen_command) # -I overrides this
55
56 @mock.patch('subprocess.Popen')
57 def test_assert_python_not_isolated_when_env_is_required(self, mock_popen):
58 """Ensure that -I is not passed when the environment is required."""
59 with mock.patch.object(script_helper,
60 'interpreter_requires_environment',
61 return_value=True) as mock_ire_func:
62 mock_popen.side_effect = RuntimeError('bail out of unittest')
63 try:
64 script_helper._assert_python(True, '-c', 'None')
65 except RuntimeError as err:
66 self.assertEqual('bail out of unittest', err.args[0])
67 popen_command = mock_popen.call_args[0][0]
68 self.assertNotIn('-I', popen_command)
69 self.assertNotIn('-E', popen_command)
70
71
72 @requires_subprocess()
73 class ESC[4;38;5;81mTestScriptHelperEnvironment(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
74 """Code coverage for interpreter_requires_environment()."""
75
76 def setUp(self):
77 self.assertTrue(
78 hasattr(script_helper, '__cached_interp_requires_environment'))
79 # Reset the private cached state.
80 script_helper.__dict__['__cached_interp_requires_environment'] = None
81
82 def tearDown(self):
83 # Reset the private cached state.
84 script_helper.__dict__['__cached_interp_requires_environment'] = None
85
86 @mock.patch('subprocess.check_call')
87 def test_interpreter_requires_environment_true(self, mock_check_call):
88 with mock.patch.dict(os.environ):
89 os.environ.pop('PYTHONHOME', None)
90 mock_check_call.side_effect = subprocess.CalledProcessError('', '')
91 self.assertTrue(script_helper.interpreter_requires_environment())
92 self.assertTrue(script_helper.interpreter_requires_environment())
93 self.assertEqual(1, mock_check_call.call_count)
94
95 @mock.patch('subprocess.check_call')
96 def test_interpreter_requires_environment_false(self, mock_check_call):
97 with mock.patch.dict(os.environ):
98 os.environ.pop('PYTHONHOME', None)
99 # The mocked subprocess.check_call fakes a no-error process.
100 script_helper.interpreter_requires_environment()
101 self.assertFalse(script_helper.interpreter_requires_environment())
102 self.assertEqual(1, mock_check_call.call_count)
103
104 @mock.patch('subprocess.check_call')
105 def test_interpreter_requires_environment_details(self, mock_check_call):
106 with mock.patch.dict(os.environ):
107 os.environ.pop('PYTHONHOME', None)
108 script_helper.interpreter_requires_environment()
109 self.assertFalse(script_helper.interpreter_requires_environment())
110 self.assertFalse(script_helper.interpreter_requires_environment())
111 self.assertEqual(1, mock_check_call.call_count)
112 check_call_command = mock_check_call.call_args[0][0]
113 self.assertEqual(sys.executable, check_call_command[0])
114 self.assertIn('-E', check_call_command)
115
116 @mock.patch('subprocess.check_call')
117 def test_interpreter_requires_environment_with_pythonhome(self, mock_check_call):
118 with mock.patch.dict(os.environ):
119 os.environ['PYTHONHOME'] = 'MockedHome'
120 self.assertTrue(script_helper.interpreter_requires_environment())
121 self.assertTrue(script_helper.interpreter_requires_environment())
122 self.assertEqual(0, mock_check_call.call_count)
123
124
125 if __name__ == '__main__':
126 unittest.main()