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