1#!/usr/bin/env vpython3 2 3# Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 4# 5# Use of this source code is governed by a BSD-style license 6# that can be found in the LICENSE file in the root of the source 7# tree. An additional intellectual property rights grant can be found 8# in the file PATENTS. All contributing project authors may 9# be found in the AUTHORS file in the root of the source tree. 10 11"""Tests for mb.py.""" 12 13import ast 14import os 15import re 16import sys 17import tempfile 18import unittest 19 20_SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) 21_SRC_DIR = os.path.dirname(os.path.dirname(_SCRIPT_DIR)) 22sys.path.insert(0, _SRC_DIR) 23 24from tools_webrtc.mb import mb 25 26 27class FakeMBW(mb.WebRTCMetaBuildWrapper): 28 def __init__(self, win32=False): 29 super().__init__() 30 31 # Override vars for test portability. 32 if win32: 33 self.chromium_src_dir = 'c:\\fake_src' 34 self.default_config = 'c:\\fake_src\\tools_webrtc\\mb\\mb_config.pyl' 35 self.default_isolate_map = ('c:\\fake_src\\testing\\buildbot\\' 36 'gn_isolate_map.pyl') 37 self.platform = 'win32' 38 self.executable = 'c:\\python\\vpython3.exe' 39 self.sep = '\\' 40 self.cwd = 'c:\\fake_src\\out\\Default' 41 else: 42 self.chromium_src_dir = '/fake_src' 43 self.default_config = '/fake_src/tools_webrtc/mb/mb_config.pyl' 44 self.default_isolate_map = '/fake_src/testing/buildbot/gn_isolate_map.pyl' 45 self.executable = '/usr/bin/vpython3' 46 self.platform = 'linux2' 47 self.sep = '/' 48 self.cwd = '/fake_src/out/Default' 49 50 self.files = {} 51 self.dirs = set() 52 self.calls = [] 53 self.cmds = [] 54 self.cross_compile = None 55 self.out = '' 56 self.err = '' 57 self.rmdirs = [] 58 59 def ExpandUser(self, path): 60 # pylint: disable=no-self-use 61 return '$HOME/%s' % path 62 63 def Exists(self, path): 64 abs_path = self._AbsPath(path) 65 return self.files.get(abs_path) is not None or abs_path in self.dirs 66 67 def ListDir(self, path): 68 dir_contents = [] 69 for f in list(self.files.keys()) + list(self.dirs): 70 head, _ = os.path.split(f) 71 if head == path: 72 dir_contents.append(f) 73 return dir_contents 74 75 def MaybeMakeDirectory(self, path): 76 abpath = self._AbsPath(path) 77 self.dirs.add(abpath) 78 79 def PathJoin(self, *comps): 80 return self.sep.join(comps) 81 82 def ReadFile(self, path): 83 try: 84 return self.files[self._AbsPath(path)] 85 except KeyError as e: 86 raise IOError('%s not found' % path) from e 87 88 def WriteFile(self, path, contents, force_verbose=False): 89 if self.args.dryrun or self.args.verbose or force_verbose: 90 self.Print('\nWriting """\\\n%s""" to %s.\n' % (contents, path)) 91 abpath = self._AbsPath(path) 92 self.files[abpath] = contents 93 94 def Call(self, cmd, env=None, capture_output=True, input=None): 95 # pylint: disable=redefined-builtin 96 del env 97 del capture_output 98 del input 99 self.calls.append(cmd) 100 if self.cmds: 101 return self.cmds.pop(0) 102 return 0, '', '' 103 104 def Print(self, *args, **kwargs): 105 sep = kwargs.get('sep', ' ') 106 end = kwargs.get('end', '\n') 107 f = kwargs.get('file', sys.stdout) 108 if f == sys.stderr: 109 self.err += sep.join(args) + end 110 else: 111 self.out += sep.join(args) + end 112 113 def TempDir(self): 114 tmp_dir = os.path.join(tempfile.gettempdir(), 'mb_test') 115 self.dirs.add(tmp_dir) 116 return tmp_dir 117 118 def TempFile(self, mode='w'): 119 del mode 120 return FakeFile(self.files) 121 122 def RemoveFile(self, path): 123 abpath = self._AbsPath(path) 124 self.files[abpath] = None 125 126 def RemoveDirectory(self, abs_path): 127 # Normalize the passed-in path to handle different working directories 128 # used during unit testing. 129 abs_path = self._AbsPath(abs_path) 130 self.rmdirs.append(abs_path) 131 files_to_delete = [f for f in self.files if f.startswith(abs_path)] 132 for f in files_to_delete: 133 self.files[f] = None 134 135 def _AbsPath(self, path): 136 if not ((self.platform == 'win32' and path.startswith('c:')) or 137 (self.platform != 'win32' and path.startswith('/'))): 138 path = self.PathJoin(self.cwd, path) 139 if self.sep == '\\': 140 return re.sub(r'\\+', r'\\', path) 141 return re.sub('/+', '/', path) 142 143 144class FakeFile: 145 # pylint: disable=invalid-name 146 def __init__(self, files): 147 self.name = '/tmp/file' 148 self.buf = '' 149 self.files = files 150 151 def write(self, contents): 152 self.buf += contents 153 154 def close(self): 155 self.files[self.name] = self.buf 156 157 158TEST_CONFIG = """\ 159{ 160 'builder_groups': { 161 'chromium': {}, 162 'fake_group': { 163 'fake_builder': 'rel_bot', 164 'fake_debug_builder': 'debug_goma', 165 'fake_args_bot': 'fake_args_bot', 166 'fake_multi_phase': { 'phase_1': 'phase_1', 'phase_2': 'phase_2'}, 167 'fake_android_bot': 'android_bot', 168 'fake_args_file': 'args_file_goma', 169 'fake_ios_error': 'ios_error', 170 }, 171 }, 172 'configs': { 173 'args_file_goma': ['fake_args_bot', 'goma'], 174 'fake_args_bot': ['fake_args_bot'], 175 'rel_bot': ['rel', 'goma', 'fake_feature1'], 176 'debug_goma': ['debug', 'goma'], 177 'phase_1': ['rel', 'phase_1'], 178 'phase_2': ['rel', 'phase_2'], 179 'android_bot': ['android'], 180 'ios_error': ['error'], 181 }, 182 'mixins': { 183 'error': { 184 'gn_args': 'error', 185 }, 186 'fake_args_bot': { 187 'args_file': '//build/args/bots/fake_group/fake_args_bot.gn', 188 }, 189 'fake_feature1': { 190 'gn_args': 'enable_doom_melon=true', 191 }, 192 'goma': { 193 'gn_args': 'use_goma=true', 194 }, 195 'phase_1': { 196 'gn_args': 'phase=1', 197 }, 198 'phase_2': { 199 'gn_args': 'phase=2', 200 }, 201 'rel': { 202 'gn_args': 'is_debug=false dcheck_always_on=false', 203 }, 204 'debug': { 205 'gn_args': 'is_debug=true', 206 }, 207 'android': { 208 'gn_args': 'target_os="android" dcheck_always_on=false', 209 } 210 }, 211} 212""" 213 214 215def CreateFakeMBW(files=None, win32=False): 216 mbw = FakeMBW(win32=win32) 217 mbw.files.setdefault(mbw.default_config, TEST_CONFIG) 218 mbw.files.setdefault( 219 mbw.ToAbsPath('//testing/buildbot/gn_isolate_map.pyl'), '''{ 220 "foo_unittests": { 221 "label": "//foo:foo_unittests", 222 "type": "console_test_launcher", 223 "args": [], 224 }, 225 }''') 226 mbw.files.setdefault( 227 mbw.ToAbsPath('//build/args/bots/fake_group/fake_args_bot.gn'), 228 'is_debug = false\ndcheck_always_on=false\n') 229 mbw.files.setdefault(mbw.ToAbsPath('//tools/mb/rts_banned_suites.json'), '{}') 230 if files: 231 for path, contents in list(files.items()): 232 mbw.files[path] = contents 233 if path.endswith('.runtime_deps'): 234 235 def FakeCall(cmd, env=None, capture_output=True, stdin=None): 236 # pylint: disable=cell-var-from-loop 237 del cmd 238 del env 239 del capture_output 240 del stdin 241 mbw.files[path] = contents 242 return 0, '', '' 243 244 # pylint: disable=invalid-name 245 mbw.Call = FakeCall 246 return mbw 247 248 249class UnitTest(unittest.TestCase): 250 # pylint: disable=invalid-name 251 def check(self, 252 args, 253 mbw=None, 254 files=None, 255 out=None, 256 err=None, 257 ret=None, 258 env=None): 259 if not mbw: 260 mbw = CreateFakeMBW(files) 261 262 try: 263 prev_env = os.environ.copy() 264 os.environ = env if env else prev_env 265 actual_ret = mbw.Main(args) 266 finally: 267 os.environ = prev_env 268 self.assertEqual( 269 actual_ret, ret, 270 "ret: %s, out: %s, err: %s" % (actual_ret, mbw.out, mbw.err)) 271 if out is not None: 272 self.assertEqual(mbw.out, out) 273 if err is not None: 274 self.assertEqual(mbw.err, err) 275 return mbw 276 277 def test_gen_swarming(self): 278 files = { 279 '/tmp/swarming_targets': 280 'foo_unittests\n', 281 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 282 ("{'foo_unittests': {" 283 " 'label': '//foo:foo_unittests'," 284 " 'type': 'raw'," 285 " 'args': []," 286 "}}\n"), 287 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 288 } 289 mbw = CreateFakeMBW(files) 290 self.check([ 291 'gen', '-c', 'debug_goma', '--swarming-targets-file', 292 '/tmp/swarming_targets', '//out/Default' 293 ], 294 mbw=mbw, 295 ret=0) 296 self.assertIn('/fake_src/out/Default/foo_unittests.isolate', mbw.files) 297 self.assertIn('/fake_src/out/Default/foo_unittests.isolated.gen.json', 298 mbw.files) 299 300 def test_gen_swarming_android(self): 301 test_files = { 302 '/tmp/swarming_targets': 303 'foo_unittests\n', 304 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 305 ("{'foo_unittests': {" 306 " 'label': '//foo:foo_unittests'," 307 " 'type': 'console_test_launcher'," 308 "}}\n"), 309 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 310 } 311 mbw = self.check([ 312 'gen', '-c', 'android_bot', '//out/Default', '--swarming-targets-file', 313 '/tmp/swarming_targets', '--isolate-map-file', 314 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 315 ], 316 files=test_files, 317 ret=0) 318 319 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 320 isolate_file_contents = ast.literal_eval(isolate_file) 321 files = isolate_file_contents['variables']['files'] 322 command = isolate_file_contents['variables']['command'] 323 324 self.assertEqual( 325 files, 326 ['../../.vpython3', '../../testing/test_env.py', 'foo_unittests']) 327 self.assertEqual(command, [ 328 'luci-auth', 329 'context', 330 '--', 331 'vpython3', 332 '../../build/android/test_wrapper/logdog_wrapper.py', 333 '--target', 334 'foo_unittests', 335 '--logdog-bin-cmd', 336 '../../.task_template_packages/logdog_butler', 337 '--logcat-output-file', 338 '${ISOLATED_OUTDIR}/logcats', 339 '--store-tombstones', 340 ]) 341 342 def test_gen_swarming_android_junit_test(self): 343 test_files = { 344 '/tmp/swarming_targets': 345 'foo_unittests\n', 346 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 347 ("{'foo_unittests': {" 348 " 'label': '//foo:foo_unittests'," 349 " 'type': 'junit_test'," 350 "}}\n"), 351 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 352 } 353 mbw = self.check([ 354 'gen', '-c', 'android_bot', '//out/Default', '--swarming-targets-file', 355 '/tmp/swarming_targets', '--isolate-map-file', 356 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 357 ], 358 files=test_files, 359 ret=0) 360 361 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 362 isolate_file_contents = ast.literal_eval(isolate_file) 363 files = isolate_file_contents['variables']['files'] 364 command = isolate_file_contents['variables']['command'] 365 366 self.assertEqual( 367 files, 368 ['../../.vpython3', '../../testing/test_env.py', 'foo_unittests']) 369 self.assertEqual(command, [ 370 'luci-auth', 371 'context', 372 '--', 373 'vpython3', 374 '../../build/android/test_wrapper/logdog_wrapper.py', 375 '--target', 376 'foo_unittests', 377 '--logdog-bin-cmd', 378 '../../.task_template_packages/logdog_butler', 379 '--logcat-output-file', 380 '${ISOLATED_OUTDIR}/logcats', 381 '--store-tombstones', 382 ]) 383 384 def test_gen_timeout(self): 385 test_files = { 386 '/tmp/swarming_targets': 387 'foo_unittests\n', 388 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 389 ("{'foo_unittests': {" 390 " 'label': '//foo:foo_unittests'," 391 " 'type': 'non_parallel_console_test_launcher'," 392 " 'timeout': 500," 393 "}}\n"), 394 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 395 } 396 mbw = self.check([ 397 'gen', '-c', 'debug_goma', '//out/Default', '--swarming-targets-file', 398 '/tmp/swarming_targets', '--isolate-map-file', 399 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 400 ], 401 files=test_files, 402 ret=0) 403 404 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 405 isolate_file_contents = ast.literal_eval(isolate_file) 406 files = isolate_file_contents['variables']['files'] 407 command = isolate_file_contents['variables']['command'] 408 409 self.assertEqual(files, [ 410 '../../.vpython3', 411 '../../testing/test_env.py', 412 '../../third_party/gtest-parallel/gtest-parallel', 413 '../../third_party/gtest-parallel/gtest_parallel.py', 414 '../../tools_webrtc/gtest-parallel-wrapper.py', 415 'foo_unittests', 416 ]) 417 self.assertEqual(command, [ 418 'vpython3', 419 '../../testing/test_env.py', 420 '../../tools_webrtc/gtest-parallel-wrapper.py', 421 '--output_dir=${ISOLATED_OUTDIR}/test_logs', 422 '--gtest_color=no', 423 '--timeout=500', 424 '--workers=1', 425 '--retry_failed=3', 426 './foo_unittests', 427 '--asan=0', 428 '--lsan=0', 429 '--msan=0', 430 '--tsan=0', 431 ]) 432 433 def test_gen_script(self): 434 test_files = { 435 '/tmp/swarming_targets': 436 'foo_unittests_script\n', 437 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 438 ("{'foo_unittests_script': {" 439 " 'label': '//foo:foo_unittests'," 440 " 'type': 'script'," 441 " 'script': '//foo/foo_unittests_script.py'," 442 "}}\n"), 443 '/fake_src/out/Default/foo_unittests_script.runtime_deps': 444 ("foo_unittests\n" 445 "foo_unittests_script.py\n"), 446 } 447 mbw = self.check([ 448 'gen', '-c', 'debug_goma', '//out/Default', '--swarming-targets-file', 449 '/tmp/swarming_targets', '--isolate-map-file', 450 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 451 ], 452 files=test_files, 453 ret=0) 454 455 isolate_file = ( 456 mbw.files['/fake_src/out/Default/foo_unittests_script.isolate']) 457 isolate_file_contents = ast.literal_eval(isolate_file) 458 files = isolate_file_contents['variables']['files'] 459 command = isolate_file_contents['variables']['command'] 460 461 self.assertEqual(files, [ 462 '../../.vpython3', 463 '../../testing/test_env.py', 464 'foo_unittests', 465 'foo_unittests_script.py', 466 ]) 467 self.assertEqual(command, [ 468 'vpython3', 469 '../../foo/foo_unittests_script.py', 470 ]) 471 472 def test_gen_raw(self): 473 test_files = { 474 '/tmp/swarming_targets': 475 'foo_unittests\n', 476 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 477 ("{'foo_unittests': {" 478 " 'label': '//foo:foo_unittests'," 479 " 'type': 'raw'," 480 "}}\n"), 481 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 482 } 483 mbw = self.check([ 484 'gen', '-c', 'debug_goma', '//out/Default', '--swarming-targets-file', 485 '/tmp/swarming_targets', '--isolate-map-file', 486 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 487 ], 488 files=test_files, 489 ret=0) 490 491 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 492 isolate_file_contents = ast.literal_eval(isolate_file) 493 files = isolate_file_contents['variables']['files'] 494 command = isolate_file_contents['variables']['command'] 495 496 self.assertEqual(files, [ 497 '../../.vpython3', 498 '../../testing/test_env.py', 499 'foo_unittests', 500 ]) 501 self.assertEqual(command, ['bin/run_foo_unittests']) 502 503 def test_gen_non_parallel_console_test_launcher(self): 504 test_files = { 505 '/tmp/swarming_targets': 506 'foo_unittests\n', 507 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 508 ("{'foo_unittests': {" 509 " 'label': '//foo:foo_unittests'," 510 " 'type': 'non_parallel_console_test_launcher'," 511 "}}\n"), 512 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 513 } 514 mbw = self.check([ 515 'gen', '-c', 'debug_goma', '//out/Default', '--swarming-targets-file', 516 '/tmp/swarming_targets', '--isolate-map-file', 517 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 518 ], 519 files=test_files, 520 ret=0) 521 522 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 523 isolate_file_contents = ast.literal_eval(isolate_file) 524 files = isolate_file_contents['variables']['files'] 525 command = isolate_file_contents['variables']['command'] 526 527 self.assertEqual(files, [ 528 '../../.vpython3', 529 '../../testing/test_env.py', 530 '../../third_party/gtest-parallel/gtest-parallel', 531 '../../third_party/gtest-parallel/gtest_parallel.py', 532 '../../tools_webrtc/gtest-parallel-wrapper.py', 533 'foo_unittests', 534 ]) 535 self.assertEqual(command, [ 536 'vpython3', 537 '../../testing/test_env.py', 538 '../../tools_webrtc/gtest-parallel-wrapper.py', 539 '--output_dir=${ISOLATED_OUTDIR}/test_logs', 540 '--gtest_color=no', 541 '--timeout=900', 542 '--workers=1', 543 '--retry_failed=3', 544 './foo_unittests', 545 '--asan=0', 546 '--lsan=0', 547 '--msan=0', 548 '--tsan=0', 549 ]) 550 551 def test_isolate_windowed_test_launcher_linux(self): 552 test_files = { 553 '/tmp/swarming_targets': 554 'foo_unittests\n', 555 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 556 ("{'foo_unittests': {" 557 " 'label': '//foo:foo_unittests'," 558 " 'type': 'windowed_test_launcher'," 559 "}}\n"), 560 '/fake_src/out/Default/foo_unittests.runtime_deps': 561 ("foo_unittests\n" 562 "some_resource_file\n"), 563 } 564 mbw = self.check([ 565 'gen', '-c', 'debug_goma', '//out/Default', '--swarming-targets-file', 566 '/tmp/swarming_targets', '--isolate-map-file', 567 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 568 ], 569 files=test_files, 570 ret=0) 571 572 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 573 isolate_file_contents = ast.literal_eval(isolate_file) 574 files = isolate_file_contents['variables']['files'] 575 command = isolate_file_contents['variables']['command'] 576 577 self.assertEqual(files, [ 578 '../../.vpython3', 579 '../../testing/test_env.py', 580 '../../testing/xvfb.py', 581 '../../third_party/gtest-parallel/gtest-parallel', 582 '../../third_party/gtest-parallel/gtest_parallel.py', 583 '../../tools_webrtc/gtest-parallel-wrapper.py', 584 'foo_unittests', 585 'some_resource_file', 586 ]) 587 self.assertEqual(command, [ 588 'vpython3', 589 '../../testing/xvfb.py', 590 '../../tools_webrtc/gtest-parallel-wrapper.py', 591 '--output_dir=${ISOLATED_OUTDIR}/test_logs', 592 '--gtest_color=no', 593 '--timeout=900', 594 '--retry_failed=3', 595 './foo_unittests', 596 '--asan=0', 597 '--lsan=0', 598 '--msan=0', 599 '--tsan=0', 600 ]) 601 602 def test_gen_windowed_test_launcher_win(self): 603 files = { 604 'c:\\fake_src\\out\\Default\\tmp\\swarming_targets': 605 'unittests\n', 606 'c:\\fake_src\\testing\\buildbot\\gn_isolate_map.pyl': 607 ("{'unittests': {" 608 " 'label': '//somewhere:unittests'," 609 " 'type': 'windowed_test_launcher'," 610 "}}\n"), 611 r'c:\fake_src\out\Default\unittests.exe.runtime_deps': 612 ("unittests.exe\n" 613 "some_dependency\n"), 614 } 615 mbw = CreateFakeMBW(files=files, win32=True) 616 self.check([ 617 'gen', '-c', 'debug_goma', '--swarming-targets-file', 618 'c:\\fake_src\\out\\Default\\tmp\\swarming_targets', 619 '--isolate-map-file', 620 'c:\\fake_src\\testing\\buildbot\\gn_isolate_map.pyl', '//out/Default' 621 ], 622 mbw=mbw, 623 ret=0) 624 625 isolate_file = mbw.files['c:\\fake_src\\out\\Default\\unittests.isolate'] 626 isolate_file_contents = ast.literal_eval(isolate_file) 627 files = isolate_file_contents['variables']['files'] 628 command = isolate_file_contents['variables']['command'] 629 630 self.assertEqual(files, [ 631 '../../.vpython3', 632 '../../testing/test_env.py', 633 '../../third_party/gtest-parallel/gtest-parallel', 634 '../../third_party/gtest-parallel/gtest_parallel.py', 635 '../../tools_webrtc/gtest-parallel-wrapper.py', 636 'some_dependency', 637 'unittests.exe', 638 ]) 639 self.assertEqual(command, [ 640 'vpython3', 641 '../../testing/test_env.py', 642 '../../tools_webrtc/gtest-parallel-wrapper.py', 643 '--output_dir=${ISOLATED_OUTDIR}/test_logs', 644 '--gtest_color=no', 645 '--timeout=900', 646 '--retry_failed=3', 647 r'.\unittests.exe', 648 '--asan=0', 649 '--lsan=0', 650 '--msan=0', 651 '--tsan=0', 652 ]) 653 654 def test_gen_console_test_launcher(self): 655 test_files = { 656 '/tmp/swarming_targets': 657 'foo_unittests\n', 658 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 659 ("{'foo_unittests': {" 660 " 'label': '//foo:foo_unittests'," 661 " 'type': 'console_test_launcher'," 662 "}}\n"), 663 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 664 } 665 mbw = self.check([ 666 'gen', '-c', 'debug_goma', '//out/Default', '--swarming-targets-file', 667 '/tmp/swarming_targets', '--isolate-map-file', 668 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 669 ], 670 files=test_files, 671 ret=0) 672 673 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 674 isolate_file_contents = ast.literal_eval(isolate_file) 675 files = isolate_file_contents['variables']['files'] 676 command = isolate_file_contents['variables']['command'] 677 678 self.assertEqual(files, [ 679 '../../.vpython3', 680 '../../testing/test_env.py', 681 '../../third_party/gtest-parallel/gtest-parallel', 682 '../../third_party/gtest-parallel/gtest_parallel.py', 683 '../../tools_webrtc/gtest-parallel-wrapper.py', 684 'foo_unittests', 685 ]) 686 self.assertEqual(command, [ 687 'vpython3', 688 '../../testing/test_env.py', 689 '../../tools_webrtc/gtest-parallel-wrapper.py', 690 '--output_dir=${ISOLATED_OUTDIR}/test_logs', 691 '--gtest_color=no', 692 '--timeout=900', 693 '--retry_failed=3', 694 './foo_unittests', 695 '--asan=0', 696 '--lsan=0', 697 '--msan=0', 698 '--tsan=0', 699 ]) 700 701 def test_isolate_test_launcher_with_webcam(self): 702 test_files = { 703 '/tmp/swarming_targets': 704 'foo_unittests\n', 705 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 706 ("{'foo_unittests': {" 707 " 'label': '//foo:foo_unittests'," 708 " 'type': 'console_test_launcher'," 709 " 'use_webcam': True," 710 "}}\n"), 711 '/fake_src/out/Default/foo_unittests.runtime_deps': 712 ("foo_unittests\n" 713 "some_resource_file\n"), 714 } 715 mbw = self.check([ 716 'gen', '-c', 'debug_goma', '//out/Default', '--swarming-targets-file', 717 '/tmp/swarming_targets', '--isolate-map-file', 718 '/fake_src/testing/buildbot/gn_isolate_map.pyl' 719 ], 720 files=test_files, 721 ret=0) 722 723 isolate_file = mbw.files['/fake_src/out/Default/foo_unittests.isolate'] 724 isolate_file_contents = ast.literal_eval(isolate_file) 725 files = isolate_file_contents['variables']['files'] 726 command = isolate_file_contents['variables']['command'] 727 728 self.assertEqual(files, [ 729 '../../.vpython3', 730 '../../testing/test_env.py', 731 '../../third_party/gtest-parallel/gtest-parallel', 732 '../../third_party/gtest-parallel/gtest_parallel.py', 733 '../../tools_webrtc/ensure_webcam_is_running.py', 734 '../../tools_webrtc/gtest-parallel-wrapper.py', 735 'foo_unittests', 736 'some_resource_file', 737 ]) 738 self.assertEqual(command, [ 739 'vpython3', 740 '../../tools_webrtc/ensure_webcam_is_running.py', 741 'vpython3', 742 '../../testing/test_env.py', 743 '../../tools_webrtc/gtest-parallel-wrapper.py', 744 '--output_dir=${ISOLATED_OUTDIR}/test_logs', 745 '--gtest_color=no', 746 '--timeout=900', 747 '--retry_failed=3', 748 './foo_unittests', 749 '--asan=0', 750 '--lsan=0', 751 '--msan=0', 752 '--tsan=0', 753 ]) 754 755 def test_isolate(self): 756 files = { 757 '/fake_src/out/Default/toolchain.ninja': 758 "", 759 '/fake_src/testing/buildbot/gn_isolate_map.pyl': 760 ("{'foo_unittests': {" 761 " 'label': '//foo:foo_unittests'," 762 " 'type': 'non_parallel_console_test_launcher'," 763 "}}\n"), 764 '/fake_src/out/Default/foo_unittests.runtime_deps': ("foo_unittests\n"), 765 } 766 self.check( 767 ['isolate', '-c', 'debug_goma', '//out/Default', 'foo_unittests'], 768 files=files, 769 ret=0) 770 771 # test running isolate on an existing build_dir 772 files['/fake_src/out/Default/args.gn'] = 'is_debug = true\n' 773 self.check(['isolate', '//out/Default', 'foo_unittests'], 774 files=files, 775 ret=0) 776 files['/fake_src/out/Default/mb_type'] = 'gn\n' 777 self.check(['isolate', '//out/Default', 'foo_unittests'], 778 files=files, 779 ret=0) 780 781if __name__ == '__main__': 782 unittest.main() 783