File size: 5,960 Bytes
1d777c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""Unittests for test.support.script_helper.  Who tests the test helper?"""

import subprocess
import sys
import os
from test.support import script_helper, requires_subprocess
import unittest
from unittest import mock


class TestScriptHelper(unittest.TestCase):

    def test_assert_python_ok(self):
        t = script_helper.assert_python_ok('-c', 'import sys; sys.exit(0)')
        self.assertEqual(0, t[0], 'return code was not 0')

    def test_assert_python_failure(self):
        # I didn't import the sys module so this child will fail.
        rc, out, err = script_helper.assert_python_failure('-c', 'sys.exit(0)')
        self.assertNotEqual(0, rc, 'return code should not be 0')

    def test_assert_python_ok_raises(self):
        # I didn't import the sys module so this child will fail.
        with self.assertRaises(AssertionError) as error_context:
            script_helper.assert_python_ok('-c', 'sys.exit(0)')
        error_msg = str(error_context.exception)
        self.assertIn('command line:', error_msg)
        self.assertIn('sys.exit(0)', error_msg, msg='unexpected command line')

    def test_assert_python_failure_raises(self):
        with self.assertRaises(AssertionError) as error_context:
            script_helper.assert_python_failure('-c', 'import sys; sys.exit(0)')
        error_msg = str(error_context.exception)
        self.assertIn('Process return code is 0\n', error_msg)
        self.assertIn('import sys; sys.exit(0)', error_msg,
                      msg='unexpected command line.')

    @mock.patch('subprocess.Popen')
    def test_assert_python_isolated_when_env_not_required(self, mock_popen):
        with mock.patch.object(script_helper,
                               'interpreter_requires_environment',
                               return_value=False) as mock_ire_func:
            mock_popen.side_effect = RuntimeError('bail out of unittest')
            try:
                script_helper._assert_python(True, '-c', 'None')
            except RuntimeError as err:
                self.assertEqual('bail out of unittest', err.args[0])
            self.assertEqual(1, mock_popen.call_count)
            self.assertEqual(1, mock_ire_func.call_count)
            popen_command = mock_popen.call_args[0][0]
            self.assertEqual(sys.executable, popen_command[0])
            self.assertIn('None', popen_command)
            self.assertIn('-I', popen_command)
            self.assertNotIn('-E', popen_command)  # -I overrides this

    @mock.patch('subprocess.Popen')
    def test_assert_python_not_isolated_when_env_is_required(self, mock_popen):
        """Ensure that -I is not passed when the environment is required."""
        with mock.patch.object(script_helper,
                               'interpreter_requires_environment',
                               return_value=True) as mock_ire_func:
            mock_popen.side_effect = RuntimeError('bail out of unittest')
            try:
                script_helper._assert_python(True, '-c', 'None')
            except RuntimeError as err:
                self.assertEqual('bail out of unittest', err.args[0])
            popen_command = mock_popen.call_args[0][0]
            self.assertNotIn('-I', popen_command)
            self.assertNotIn('-E', popen_command)


@requires_subprocess()
class TestScriptHelperEnvironment(unittest.TestCase):
    """Code coverage for interpreter_requires_environment()."""

    def setUp(self):
        self.assertTrue(
            hasattr(script_helper, '__cached_interp_requires_environment'))
        # Reset the private cached state.
        script_helper.__dict__['__cached_interp_requires_environment'] = None

    def tearDown(self):
        # Reset the private cached state.
        script_helper.__dict__['__cached_interp_requires_environment'] = None

    @mock.patch('subprocess.check_call')
    def test_interpreter_requires_environment_true(self, mock_check_call):
        with mock.patch.dict(os.environ):
            os.environ.pop('PYTHONHOME', None)
            mock_check_call.side_effect = subprocess.CalledProcessError('', '')
            self.assertTrue(script_helper.interpreter_requires_environment())
            self.assertTrue(script_helper.interpreter_requires_environment())
            self.assertEqual(1, mock_check_call.call_count)

    @mock.patch('subprocess.check_call')
    def test_interpreter_requires_environment_false(self, mock_check_call):
        with mock.patch.dict(os.environ):
            os.environ.pop('PYTHONHOME', None)
            # The mocked subprocess.check_call fakes a no-error process.
            script_helper.interpreter_requires_environment()
            self.assertFalse(script_helper.interpreter_requires_environment())
            self.assertEqual(1, mock_check_call.call_count)

    @mock.patch('subprocess.check_call')
    def test_interpreter_requires_environment_details(self, mock_check_call):
        with mock.patch.dict(os.environ):
            os.environ.pop('PYTHONHOME', None)
            script_helper.interpreter_requires_environment()
            self.assertFalse(script_helper.interpreter_requires_environment())
            self.assertFalse(script_helper.interpreter_requires_environment())
            self.assertEqual(1, mock_check_call.call_count)
            check_call_command = mock_check_call.call_args[0][0]
            self.assertEqual(sys.executable, check_call_command[0])
            self.assertIn('-E', check_call_command)

    @mock.patch('subprocess.check_call')
    def test_interpreter_requires_environment_with_pythonhome(self, mock_check_call):
        with mock.patch.dict(os.environ):
            os.environ['PYTHONHOME'] = 'MockedHome'
            self.assertTrue(script_helper.interpreter_requires_environment())
            self.assertTrue(script_helper.interpreter_requires_environment())
            self.assertEqual(0, mock_check_call.call_count)


if __name__ == '__main__':
    unittest.main()