1"""Unittests for test.support.script_helper. Who tests the test helper?""" 2 3import subprocess 4import sys 5import os 6from test.support import script_helper 7import unittest 8from unittest import mock 9 10 11class TestScriptHelper(unittest.TestCase): 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 72class TestScriptHelperEnvironment(unittest.TestCase): 73 """Code coverage for interpreter_requires_environment().""" 74 75 def setUp(self): 76 self.assertTrue( 77 hasattr(script_helper, '__cached_interp_requires_environment')) 78 # Reset the private cached state. 79 script_helper.__dict__['__cached_interp_requires_environment'] = None 80 81 def tearDown(self): 82 # Reset the private cached state. 83 script_helper.__dict__['__cached_interp_requires_environment'] = None 84 85 @mock.patch('subprocess.check_call') 86 def test_interpreter_requires_environment_true(self, mock_check_call): 87 with mock.patch.dict(os.environ): 88 os.environ.pop('PYTHONHOME', None) 89 mock_check_call.side_effect = subprocess.CalledProcessError('', '') 90 self.assertTrue(script_helper.interpreter_requires_environment()) 91 self.assertTrue(script_helper.interpreter_requires_environment()) 92 self.assertEqual(1, mock_check_call.call_count) 93 94 @mock.patch('subprocess.check_call') 95 def test_interpreter_requires_environment_false(self, mock_check_call): 96 with mock.patch.dict(os.environ): 97 os.environ.pop('PYTHONHOME', None) 98 # The mocked subprocess.check_call fakes a no-error process. 99 script_helper.interpreter_requires_environment() 100 self.assertFalse(script_helper.interpreter_requires_environment()) 101 self.assertEqual(1, mock_check_call.call_count) 102 103 @mock.patch('subprocess.check_call') 104 def test_interpreter_requires_environment_details(self, mock_check_call): 105 with mock.patch.dict(os.environ): 106 os.environ.pop('PYTHONHOME', None) 107 script_helper.interpreter_requires_environment() 108 self.assertFalse(script_helper.interpreter_requires_environment()) 109 self.assertFalse(script_helper.interpreter_requires_environment()) 110 self.assertEqual(1, mock_check_call.call_count) 111 check_call_command = mock_check_call.call_args[0][0] 112 self.assertEqual(sys.executable, check_call_command[0]) 113 self.assertIn('-E', check_call_command) 114 115 @mock.patch('subprocess.check_call') 116 def test_interpreter_requires_environment_with_pythonhome(self, mock_check_call): 117 with mock.patch.dict(os.environ): 118 os.environ['PYTHONHOME'] = 'MockedHome' 119 self.assertTrue(script_helper.interpreter_requires_environment()) 120 self.assertTrue(script_helper.interpreter_requires_environment()) 121 self.assertEqual(0, mock_check_call.call_count) 122 123 124if __name__ == '__main__': 125 unittest.main() 126