github.com/apache/beam/sdks/v2@v2.48.2/python/apache_beam/utils/processes_test.py (about) 1 # 2 # Licensed to the Apache Software Foundation (ASF) under one or more 3 # contributor license agreements. See the NOTICE file distributed with 4 # this work for additional information regarding copyright ownership. 5 # The ASF licenses this file to You under the Apache License, Version 2.0 6 # (the "License"); you may not use this file except in compliance with 7 # the License. You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 """Unit tests for the processes module.""" 19 20 # pytype: skip-file 21 22 import subprocess 23 import unittest 24 25 import mock 26 27 from apache_beam.utils import processes 28 29 30 class Exec(unittest.TestCase): 31 def setUp(self): 32 pass 33 34 @mock.patch('apache_beam.utils.processes.subprocess') 35 def test_method_forwarding_not_windows(self, *unused_mocks): 36 # Test that the correct calls are being forwarded to the subprocess module 37 # when we are not on Windows. 38 processes.force_shell = False 39 40 processes.call(['subprocess', 'call'], shell=False, other_arg=True) 41 processes.subprocess.call.assert_called_once_with(['subprocess', 'call'], 42 shell=False, 43 other_arg=True) 44 45 processes.check_call(['subprocess', 'check_call'], 46 shell=False, 47 other_arg=True) 48 processes.subprocess.check_call.assert_called_once_with( 49 ['subprocess', 'check_call'], shell=False, other_arg=True) 50 51 processes.check_output(['subprocess', 'check_output'], shell=False) 52 processes.subprocess.check_output.assert_called_once_with( 53 ['subprocess', 'check_output'], shell=False) 54 55 processes.Popen(['subprocess', 'Popen'], shell=False, other_arg=True) 56 processes.subprocess.Popen.assert_called_once_with(['subprocess', 'Popen'], 57 shell=False, 58 other_arg=True) 59 60 @mock.patch('apache_beam.utils.processes.subprocess') 61 def test_method_forwarding_windows(self, *unused_mocks): 62 # Test that the correct calls are being forwarded to the subprocess module 63 # and that the shell=True flag is added when we are on Windows. 64 processes.force_shell = True 65 66 processes.call(['subprocess', 'call'], shell=False, other_arg=True) 67 processes.subprocess.call.assert_called_once_with(['subprocess', 'call'], 68 shell=True, 69 other_arg=True) 70 71 processes.check_call(['subprocess', 'check_call'], 72 shell=False, 73 other_arg=True) 74 processes.subprocess.check_call.assert_called_once_with( 75 ['subprocess', 'check_call'], shell=True, other_arg=True) 76 77 processes.check_output(['subprocess', 'check_output'], shell=False) 78 processes.subprocess.check_output.assert_called_once_with( 79 ['subprocess', 'check_output'], shell=True) 80 81 processes.Popen(['subprocess', 'Popen'], shell=False, other_arg=True) 82 processes.subprocess.Popen.assert_called_once_with(['subprocess', 'Popen'], 83 shell=True, 84 other_arg=True) 85 86 87 class TestErrorHandlingCheckCall(unittest.TestCase): 88 @classmethod 89 def setUpClass(cls): 90 cls.mock_get_patcher = mock.patch(\ 91 'apache_beam.utils.processes.subprocess.check_call') 92 cls.mock_get = cls.mock_get_patcher.start() 93 94 @classmethod 95 def tearDownClass(cls): 96 cls.mock_get_patcher.stop() 97 98 def test_oserror_check_call(self): 99 # Configure the mock to return a response with an OK status code. 100 self.mock_get.side_effect = OSError("Test OSError") 101 with self.assertRaises(RuntimeError): 102 processes.check_call(["lls"]) 103 104 def test_oserror_check_call_message(self): 105 # Configure the mock to return a response with an OK status code. 106 self.mock_get.side_effect = OSError() 107 cmd = ["lls"] 108 try: 109 processes.check_call(cmd) 110 except RuntimeError as error: 111 self.assertIn('Executable {} not found'.format(str(cmd)),\ 112 error.args[0]) 113 114 def test_check_call_pip_install_non_existing_package(self): 115 returncode = 1 116 package = "non-exsisting-package" 117 cmd = ['python', '-m', 'pip', 'download', '--dest', '/var',\ 118 '{}'.format(package),\ 119 '--no-deps', '--no-binary', ':all:'] 120 output = "Collecting {}".format(package) 121 self.mock_get.side_effect = subprocess.CalledProcessError(returncode,\ 122 cmd, output=output) 123 try: 124 output = processes.check_call(cmd) 125 self.fail( 126 "The test failed due to that\ 127 no error was raised when calling process.check_call") 128 except RuntimeError as error: 129 self.assertIn("Output from execution of subprocess: {}".format(output),\ 130 error.args[0]) 131 self.assertIn("Pip install failed for package: {}".format(package),\ 132 error.args[0]) 133 134 135 class TestErrorHandlingCheckOutput(unittest.TestCase): 136 @classmethod 137 def setUpClass(cls): 138 cls.mock_get_patcher = mock.patch(\ 139 'apache_beam.utils.processes.subprocess.check_output') 140 cls.mock_get = cls.mock_get_patcher.start() 141 142 @classmethod 143 def tearDownClass(cls): 144 cls.mock_get_patcher.stop() 145 146 def test_oserror_check_output_message(self): 147 self.mock_get.side_effect = OSError() 148 cmd = ["lls"] 149 try: 150 processes.check_output(cmd) 151 except RuntimeError as error: 152 self.assertIn('Executable {} not found'.format(str(cmd)),\ 153 error.args[0]) 154 155 def test_check_output_pip_install_non_existing_package(self): 156 returncode = 1 157 package = "non-exsisting-package" 158 cmd = ['python', '-m', 'pip', 'download', '--dest', '/var',\ 159 '{}'.format(package),\ 160 '--no-deps', '--no-binary', ':all:'] 161 output = "Collecting {}".format(package) 162 self.mock_get.side_effect = subprocess.CalledProcessError(returncode,\ 163 cmd, output=output) 164 try: 165 output = processes.check_output(cmd) 166 self.fail( 167 "The test failed due to that\ 168 no error was raised when calling process.check_call") 169 except RuntimeError as error: 170 self.assertIn("Output from execution of subprocess: {}".format(output),\ 171 error.args[0]) 172 self.assertIn("Pip install failed for package: {}".format(package),\ 173 error.args[0]) 174 175 176 class TestErrorHandlingCall(unittest.TestCase): 177 @classmethod 178 def setUpClass(cls): 179 cls.mock_get_patcher = mock.patch(\ 180 'apache_beam.utils.processes.subprocess.call') 181 cls.mock_get = cls.mock_get_patcher.start() 182 183 @classmethod 184 def tearDownClass(cls): 185 cls.mock_get_patcher.stop() 186 187 def test_oserror_check_output_message(self): 188 self.mock_get.side_effect = OSError() 189 cmd = ["lls"] 190 try: 191 processes.call(cmd) 192 except RuntimeError as error: 193 self.assertIn('Executable {} not found'.format(str(cmd)),\ 194 error.args[0]) 195 196 def test_check_output_pip_install_non_existing_package(self): 197 returncode = 1 198 package = "non-exsisting-package" 199 cmd = ['python', '-m', 'pip', 'download', '--dest', '/var',\ 200 '{}'.format(package),\ 201 '--no-deps', '--no-binary', ':all:'] 202 output = "Collecting {}".format(package) 203 self.mock_get.side_effect = subprocess.CalledProcessError(returncode,\ 204 cmd, output=output) 205 try: 206 output = processes.call(cmd) 207 self.fail( 208 "The test failed due to that\ 209 no error was raised when calling process.check_call") 210 except RuntimeError as error: 211 self.assertIn("Output from execution of subprocess: {}".format(output),\ 212 error.args[0]) 213 self.assertIn("Pip install failed for package: {}".format(package),\ 214 error.args[0]) 215 216 217 if __name__ == '__main__': 218 unittest.main()