| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2013 The LUCI Authors. All rights reserved. | 2 # Copyright 2013 The LUCI Authors. All rights reserved. |
| 3 # Use of this source code is governed by the Apache v2.0 license that can be | 3 # Use of this source code is governed by the Apache v2.0 license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 # pylint: disable=R0201 | 6 # pylint: disable=R0201 |
| 7 | 7 |
| 8 import StringIO | 8 import StringIO |
| 9 import base64 | 9 import base64 |
| 10 import functools | 10 import functools |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 ] | 169 ] |
| 170 ret = run_isolated.main(cmd) | 170 ret = run_isolated.main(cmd) |
| 171 self.assertEqual(0, ret) | 171 self.assertEqual(0, ret) |
| 172 self.assertEqual( | 172 self.assertEqual( |
| 173 [ | 173 [ |
| 174 ([self.temp_join(u'foo.exe'), u'cmd w/ space', '--extraargs', 'bar'], | 174 ([self.temp_join(u'foo.exe'), u'cmd w/ space', '--extraargs', 'bar'], |
| 175 {'detached': True}), | 175 {'detached': True}), |
| 176 ], | 176 ], |
| 177 self.popen_calls) | 177 self.popen_calls) |
| 178 | 178 |
| 179 def _run_tha_test(self, isolated_hash, files): | 179 def _run_tha_test(self, isolated_hash=None, files=None, command=None): |
| 180 files = files or {} |
| 180 make_tree_call = [] | 181 make_tree_call = [] |
| 181 def add(i, _): | 182 def add(i, _): |
| 182 make_tree_call.append(i) | 183 make_tree_call.append(i) |
| 183 for i in ('make_tree_read_only', 'make_tree_files_read_only', | 184 for i in ('make_tree_read_only', 'make_tree_files_read_only', |
| 184 'make_tree_deleteable', 'make_tree_writeable'): | 185 'make_tree_deleteable', 'make_tree_writeable'): |
| 185 self.mock(file_path, i, functools.partial(add, i)) | 186 self.mock(file_path, i, functools.partial(add, i)) |
| 186 | 187 |
| 187 ret = run_isolated.run_tha_test( | 188 ret = run_isolated.run_tha_test( |
| 189 command, |
| 188 isolated_hash, | 190 isolated_hash, |
| 189 StorageFake(files), | 191 StorageFake(files), |
| 190 isolateserver.MemoryCache(), | 192 isolateserver.MemoryCache(), |
| 191 False, | 193 False, |
| 192 None, | 194 None, |
| 193 None, | 195 None, |
| 194 None, | 196 None, |
| 195 None, | 197 None, |
| 196 []) | 198 None) |
| 197 self.assertEqual(0, ret) | 199 self.assertEqual(0, ret) |
| 198 return make_tree_call | 200 return make_tree_call |
| 199 | 201 |
| 200 def test_run_tha_test_naked(self): | 202 def test_run_tha_test_naked(self): |
| 201 isolated = json_dumps({'command': ['invalid', 'command']}) | 203 isolated = json_dumps({'command': ['invalid', 'command']}) |
| 202 isolated_hash = isolateserver_mock.hash_content(isolated) | 204 isolated_hash = isolateserver_mock.hash_content(isolated) |
| 203 files = {isolated_hash:isolated} | 205 files = {isolated_hash:isolated} |
| 204 make_tree_call = self._run_tha_test(isolated_hash, files) | 206 make_tree_call = self._run_tha_test(isolated_hash, files) |
| 205 self.assertEqual( | 207 self.assertEqual( |
| 206 [ | 208 [ |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 [ | 268 [ |
| 267 'make_tree_read_only', 'make_tree_deleteable', 'make_tree_deleteable', | 269 'make_tree_read_only', 'make_tree_deleteable', 'make_tree_deleteable', |
| 268 'make_tree_deleteable', | 270 'make_tree_deleteable', |
| 269 ], | 271 ], |
| 270 make_tree_call) | 272 make_tree_call) |
| 271 self.assertEqual(1, len(self.popen_calls)) | 273 self.assertEqual(1, len(self.popen_calls)) |
| 272 self.assertEqual( | 274 self.assertEqual( |
| 273 [([self.temp_join(u'invalid'), u'command'], {'detached': True})], | 275 [([self.temp_join(u'invalid'), u'command'], {'detached': True})], |
| 274 self.popen_calls) | 276 self.popen_calls) |
| 275 | 277 |
| 278 def mock_popen_with_oserr(self): |
| 279 def r(self, args, **kwargs): |
| 280 old_init(self, args, **kwargs) |
| 281 raise OSError('Unknown') |
| 282 old_init = self.mock(subprocess42.Popen, '__init__', r) |
| 283 |
| 276 def test_main_naked(self): | 284 def test_main_naked(self): |
| 285 self.mock_popen_with_oserr() |
| 277 self.mock(on_error, 'report', lambda _: None) | 286 self.mock(on_error, 'report', lambda _: None) |
| 278 # The most naked .isolated file that can exist. | 287 # The most naked .isolated file that can exist. |
| 279 self.mock(tools, 'disable_buffering', lambda: None) | 288 self.mock(tools, 'disable_buffering', lambda: None) |
| 280 isolated = json_dumps({'command': ['invalid', 'command']}) | 289 isolated = json_dumps({'command': ['invalid', 'command']}) |
| 281 isolated_hash = isolateserver_mock.hash_content(isolated) | 290 isolated_hash = isolateserver_mock.hash_content(isolated) |
| 282 def get_storage(_isolate_server, _namespace): | 291 def get_storage(_isolate_server, _namespace): |
| 283 return StorageFake({isolated_hash:isolated}) | 292 return StorageFake({isolated_hash:isolated}) |
| 284 self.mock(isolateserver, 'get_storage', get_storage) | 293 self.mock(isolateserver, 'get_storage', get_storage) |
| 285 | 294 |
| 286 def r(self, args, **kwargs): | |
| 287 old_init(self, args, **kwargs) | |
| 288 raise OSError('Unknown') | |
| 289 old_init = self.mock(subprocess42.Popen, '__init__', r) | |
| 290 | |
| 291 cmd = [ | 295 cmd = [ |
| 292 '--no-log', | 296 '--no-log', |
| 293 '--isolated', isolated_hash, | 297 '--isolated', isolated_hash, |
| 294 '--cache', self.tempdir, | 298 '--cache', self.tempdir, |
| 295 '--isolate-server', 'https://localhost', | 299 '--isolate-server', 'https://localhost', |
| 296 ] | 300 ] |
| 297 ret = run_isolated.main(cmd) | 301 ret = run_isolated.main(cmd) |
| 298 self.assertEqual(1, ret) | 302 self.assertEqual(1, ret) |
| 299 self.assertEqual(1, len(self.popen_calls)) | 303 self.assertEqual(1, len(self.popen_calls)) |
| 300 self.assertEqual( | 304 self.assertEqual( |
| 301 [([self.temp_join(u'invalid'), u'command'], {'detached': True})], | 305 [([self.temp_join(u'invalid'), u'command'], {'detached': True})], |
| 302 self.popen_calls) | 306 self.popen_calls) |
| 303 | 307 |
| 308 def test_main_naked_without_isolated(self): |
| 309 self.mock_popen_with_oserr() |
| 310 cmd = [ |
| 311 '--no-log', |
| 312 '/bin/echo', |
| 313 'hello', |
| 314 'world', |
| 315 ] |
| 316 ret = run_isolated.main(cmd) |
| 317 self.assertEqual(1, ret) |
| 318 self.assertEqual(1, len(self.popen_calls)) |
| 319 self.assertEqual( |
| 320 [([u'/bin/echo', u'hello', u'world'], {'detached': True})], |
| 321 self.popen_calls) |
| 322 |
| 304 def test_modified_cwd(self): | 323 def test_modified_cwd(self): |
| 305 isolated = json_dumps({ | 324 isolated = json_dumps({ |
| 306 'command': ['../out/some.exe', 'arg'], | 325 'command': ['../out/some.exe', 'arg'], |
| 307 'relative_cwd': 'some', | 326 'relative_cwd': 'some', |
| 308 }) | 327 }) |
| 309 isolated_hash = isolateserver_mock.hash_content(isolated) | 328 isolated_hash = isolateserver_mock.hash_content(isolated) |
| 310 files = {isolated_hash:isolated} | 329 files = {isolated_hash:isolated} |
| 311 _ = self._run_tha_test(isolated_hash, files) | 330 _ = self._run_tha_test(isolated_hash, files) |
| 312 self.assertEqual(1, len(self.popen_calls)) | 331 self.assertEqual(1, len(self.popen_calls)) |
| 313 self.assertEqual( | 332 self.assertEqual( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 324 _ = self._run_tha_test(isolated_hash, files) | 343 _ = self._run_tha_test(isolated_hash, files) |
| 325 self.assertEqual(1, len(self.popen_calls)) | 344 self.assertEqual(1, len(self.popen_calls)) |
| 326 # Injects sys.executable. | 345 # Injects sys.executable. |
| 327 self.assertEqual( | 346 self.assertEqual( |
| 328 [ | 347 [ |
| 329 ([sys.executable, os.path.join(u'..', 'out', 'cmd.py'), u'arg'], | 348 ([sys.executable, os.path.join(u'..', 'out', 'cmd.py'), u'arg'], |
| 330 {'detached': True}), | 349 {'detached': True}), |
| 331 ], | 350 ], |
| 332 self.popen_calls) | 351 self.popen_calls) |
| 333 | 352 |
| 353 def test_run_tha_test_non_isolated(self): |
| 354 _ = self._run_tha_test(command=['/bin/echo', 'hello', 'world']) |
| 355 self.assertEqual( |
| 356 [([u'/bin/echo', u'hello', u'world'], {'detached': True})], |
| 357 self.popen_calls) |
| 358 |
| 334 | 359 |
| 335 class RunIsolatedTestRun(RunIsolatedTestBase): | 360 class RunIsolatedTestRun(RunIsolatedTestBase): |
| 336 def test_output(self): | 361 def test_output(self): |
| 337 # Starts a full isolate server mock and have run_tha_test() uploads results | 362 # Starts a full isolate server mock and have run_tha_test() uploads results |
| 338 # back after the task completed. | 363 # back after the task completed. |
| 339 server = isolateserver_mock.MockIsolateServer() | 364 server = isolateserver_mock.MockIsolateServer() |
| 340 try: | 365 try: |
| 341 script = ( | 366 script = ( |
| 342 'import sys\n' | 367 'import sys\n' |
| 343 'open(sys.argv[1], "w").write("bar")\n') | 368 'open(sys.argv[1], "w").write("bar")\n') |
| (...skipping 13 matching lines...) Expand all Loading... |
| 357 if sys.platform == 'win32': | 382 if sys.platform == 'win32': |
| 358 isolated['files']['cmd.py'].pop('m') | 383 isolated['files']['cmd.py'].pop('m') |
| 359 isolated_data = json_dumps(isolated) | 384 isolated_data = json_dumps(isolated) |
| 360 isolated_hash = isolateserver_mock.hash_content(isolated_data) | 385 isolated_hash = isolateserver_mock.hash_content(isolated_data) |
| 361 server.add_content('default-store', script) | 386 server.add_content('default-store', script) |
| 362 server.add_content('default-store', isolated_data) | 387 server.add_content('default-store', isolated_data) |
| 363 store = isolateserver.get_storage(server.url, 'default-store') | 388 store = isolateserver.get_storage(server.url, 'default-store') |
| 364 | 389 |
| 365 self.mock(sys, 'stdout', StringIO.StringIO()) | 390 self.mock(sys, 'stdout', StringIO.StringIO()) |
| 366 ret = run_isolated.run_tha_test( | 391 ret = run_isolated.run_tha_test( |
| 392 None, |
| 367 isolated_hash, | 393 isolated_hash, |
| 368 store, | 394 store, |
| 369 isolateserver.MemoryCache(), | 395 isolateserver.MemoryCache(), |
| 370 False, | 396 False, |
| 371 None, | 397 None, |
| 372 None, | 398 None, |
| 373 None, | 399 None, |
| 374 None, | 400 None, |
| 375 []) | 401 []) |
| 376 self.assertEqual(0, ret) | 402 self.assertEqual(0, ret) |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 self.assertEqual(expected, actual) | 542 self.assertEqual(expected, actual) |
| 517 | 543 |
| 518 | 544 |
| 519 if __name__ == '__main__': | 545 if __name__ == '__main__': |
| 520 fix_encoding.fix_encoding() | 546 fix_encoding.fix_encoding() |
| 521 if '-v' in sys.argv: | 547 if '-v' in sys.argv: |
| 522 unittest.TestCase.maxDiff = None | 548 unittest.TestCase.maxDiff = None |
| 523 logging.basicConfig( | 549 logging.basicConfig( |
| 524 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR) | 550 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR) |
| 525 unittest.main() | 551 unittest.main() |
| OLD | NEW |