Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """MB - the Meta-Build wrapper around GYP and GN | 6 """MB - the Meta-Build wrapper around GYP and GN |
| 7 | 7 |
| 8 MB is a wrapper script for GYP and GN that can be used to generate build files | 8 MB is a wrapper script for GYP and GN that can be used to generate build files |
| 9 for sets of canned configurations and analyze them. | 9 for sets of canned configurations and analyze them. |
| 10 """ | 10 """ |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 cmd = self.GNCmd('gen', path, vals['gn_args']) | 323 cmd = self.GNCmd('gen', path, vals['gn_args']) |
| 324 | 324 |
| 325 swarming_targets = [] | 325 swarming_targets = [] |
| 326 if self.args.swarming_targets_file: | 326 if self.args.swarming_targets_file: |
| 327 # We need GN to generate the list of runtime dependencies for | 327 # We need GN to generate the list of runtime dependencies for |
| 328 # the compile targets listed (one per line) in the file so | 328 # the compile targets listed (one per line) in the file so |
| 329 # we can run them via swarming. We use ninja_to_gn.pyl to convert | 329 # we can run them via swarming. We use ninja_to_gn.pyl to convert |
| 330 # the compile targets to the matching GN labels. | 330 # the compile targets to the matching GN labels. |
| 331 contents = self.ReadFile(self.args.swarming_targets_file) | 331 contents = self.ReadFile(self.args.swarming_targets_file) |
| 332 swarming_targets = contents.splitlines() | 332 swarming_targets = contents.splitlines() |
| 333 ninja_targets_to_labels = ast.literal_eval(self.ReadFile(os.path.join( | 333 gn_isolate_map = ast.literal_eval(self.ReadFile(os.path.join( |
| 334 self.chromium_src_dir, 'testing', 'buildbot', 'ninja_to_gn.pyl'))) | 334 self.chromium_src_dir, 'testing', 'buildbot', 'gn_isolate_map.pyl'))) |
| 335 gn_labels = [] | 335 gn_labels = [] |
| 336 for target in swarming_targets: | 336 for target in swarming_targets: |
| 337 if not target in ninja_targets_to_labels: | 337 if not target in gn_isolate_map: |
| 338 raise MBErr('test target "%s" not found in %s' % | 338 raise MBErr('test target "%s" not found in %s' % |
| 339 (target, '//testing/buildbot/ninja_to_gn.pyl')) | 339 (target, '//testing/buildbot/gn_isolate_map.pyl')) |
| 340 gn_labels.append(ninja_targets_to_labels[target]) | 340 gn_labels.append(gn_isolate_map[target]['label']) |
| 341 | 341 |
| 342 gn_runtime_deps_path = self.ToAbsPath(path, 'runtime_deps') | 342 gn_runtime_deps_path = self.ToAbsPath(path, 'runtime_deps') |
| 343 | 343 |
| 344 # Since GN hasn't run yet, the build directory may not even exist. | 344 # Since GN hasn't run yet, the build directory may not even exist. |
| 345 self.MaybeMakeDirectory(self.ToAbsPath(path)) | 345 self.MaybeMakeDirectory(self.ToAbsPath(path)) |
| 346 | 346 |
| 347 self.WriteFile(gn_runtime_deps_path, '\n'.join(gn_labels) + '\n') | 347 self.WriteFile(gn_runtime_deps_path, '\n'.join(gn_labels) + '\n') |
| 348 cmd.append('--runtime-deps-list-file=%s' % gn_runtime_deps_path) | 348 cmd.append('--runtime-deps-list-file=%s' % gn_runtime_deps_path) |
| 349 | 349 |
| 350 ret, _, _ = self.Run(cmd) | 350 ret, _, _ = self.Run(cmd) |
| 351 | 351 |
| 352 for target in swarming_targets: | 352 for target in swarming_targets: |
| 353 if sys.platform == 'win32': | 353 if sys.platform == 'win32': |
| 354 deps_path = self.ToAbsPath(path, target + '.exe.runtime_deps') | 354 deps_path = self.ToAbsPath(path, target + '.exe.runtime_deps') |
| 355 else: | 355 else: |
| 356 deps_path = self.ToAbsPath(path, target + '.runtime_deps') | 356 deps_path = self.ToAbsPath(path, target + '.runtime_deps') |
| 357 if not self.Exists(deps_path): | 357 if not self.Exists(deps_path): |
| 358 raise MBErr('did not generate %s' % deps_path) | 358 raise MBErr('did not generate %s' % deps_path) |
| 359 | 359 |
| 360 command, extra_files = self.GetIsolateCommand(target, vals) | 360 command, extra_files = self.GetIsolateCommand(target, vals, |
| 361 gn_isolate_map) | |
| 361 | 362 |
| 362 runtime_deps = self.ReadFile(deps_path).splitlines() | 363 runtime_deps = self.ReadFile(deps_path).splitlines() |
| 363 | 364 |
| 364 isolate_path = self.ToAbsPath(path, target + '.isolate') | 365 isolate_path = self.ToAbsPath(path, target + '.isolate') |
| 365 self.WriteFile(isolate_path, | 366 self.WriteFile(isolate_path, |
| 366 pprint.pformat({ | 367 pprint.pformat({ |
| 367 'variables': { | 368 'variables': { |
| 368 'command': command, | 369 'command': command, |
| 369 'files': sorted(runtime_deps + extra_files), | 370 'files': sorted(runtime_deps + extra_files), |
| 370 'read_only': 1, | 371 'read_only': 1, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 self.Print() | 454 self.Print() |
| 454 output_path = self.args.output_path[0] | 455 output_path = self.args.output_path[0] |
| 455 | 456 |
| 456 for target in inp['targets']: | 457 for target in inp['targets']: |
| 457 runtime_deps_path = self.ToAbsPath(build_path, target + '.runtime_deps') | 458 runtime_deps_path = self.ToAbsPath(build_path, target + '.runtime_deps') |
| 458 | 459 |
| 459 if not self.Exists(runtime_deps_path): | 460 if not self.Exists(runtime_deps_path): |
| 460 self.WriteFailureAndRaise('"%s" does not exist' % runtime_deps_path, | 461 self.WriteFailureAndRaise('"%s" does not exist' % runtime_deps_path, |
| 461 output_path) | 462 output_path) |
| 462 | 463 |
| 463 command, extra_files = self.GetIsolateCommand(target, vals) | 464 command, extra_files = self.GetIsolateCommand(target, vals, None) |
| 464 | 465 |
| 465 runtime_deps = self.ReadFile(runtime_deps_path).splitlines() | 466 runtime_deps = self.ReadFile(runtime_deps_path).splitlines() |
| 466 | 467 |
| 467 | 468 |
| 468 isolate_path = self.ToAbsPath(build_path, target + '.isolate') | 469 isolate_path = self.ToAbsPath(build_path, target + '.isolate') |
| 469 self.WriteFile(isolate_path, | 470 self.WriteFile(isolate_path, |
| 470 pprint.pformat({ | 471 pprint.pformat({ |
| 471 'variables': { | 472 'variables': { |
| 472 'command': command, | 473 'command': command, |
| 473 'files': sorted(runtime_deps + extra_files), | 474 'files': sorted(runtime_deps + extra_files), |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 484 self.ToSrcRelPath('%s/%s.isolate' % (build_path, target)), | 485 self.ToSrcRelPath('%s/%s.isolate' % (build_path, target)), |
| 485 ], | 486 ], |
| 486 'dir': self.chromium_src_dir, | 487 'dir': self.chromium_src_dir, |
| 487 'version': 1, | 488 'version': 1, |
| 488 }, | 489 }, |
| 489 isolate_path + 'd.gen.json', | 490 isolate_path + 'd.gen.json', |
| 490 ) | 491 ) |
| 491 | 492 |
| 492 return 0 | 493 return 0 |
| 493 | 494 |
| 494 def GetIsolateCommand(self, target, vals): | 495 def GetIsolateCommand(self, target, vals, gn_isolate_map): |
| 495 extra_files = [] | |
| 496 | |
| 497 # TODO(dpranke): We should probably pull this from | |
| 498 # the test list info in //testing/buildbot/*.json, | |
| 499 # and assert that the test has can_use_on_swarming_builders: True, | |
| 500 # but we hardcode it here for now. | |
| 501 test_type = {}.get(target, 'gtest_test') | |
| 502 | |
| 503 # This needs to mirror the settings in //build/config/ui.gni: | 496 # This needs to mirror the settings in //build/config/ui.gni: |
| 504 # use_x11 = is_linux && !use_ozone. | 497 # use_x11 = is_linux && !use_ozone. |
| 505 # TODO(dpranke): Figure out how to keep this in sync better. | 498 # TODO(dpranke): Figure out how to keep this in sync better. |
| 506 use_x11 = (sys.platform == 'linux2' and | 499 use_x11 = (sys.platform == 'linux2' and |
| 507 not 'target_os="android"' in vals['gn_args'] and | 500 not 'target_os="android"' in vals['gn_args'] and |
| 508 not 'use_ozone=true' in vals['gn_args']) | 501 not 'use_ozone=true' in vals['gn_args']) |
| 509 | 502 |
| 510 asan = 'is_asan=true' in vals['gn_args'] | 503 asan = 'is_asan=true' in vals['gn_args'] |
| 511 msan = 'is_msan=true' in vals['gn_args'] | 504 msan = 'is_msan=true' in vals['gn_args'] |
| 512 tsan = 'is_tsan=true' in vals['gn_args'] | 505 tsan = 'is_tsan=true' in vals['gn_args'] |
| 513 | 506 |
| 514 executable_suffix = '.exe' if sys.platform == 'win32' else '' | 507 executable_suffix = '.exe' if sys.platform == 'win32' else '' |
| 515 | 508 |
| 516 if test_type == 'gtest_test': | 509 test_type = gn_isolate_map[target]['type'] |
| 517 extra_files.append('../../testing/test_env.py') | 510 cmdline = [] |
| 511 extra_files = [] | |
| 518 | 512 |
| 519 if use_x11: | 513 if use_x11 and test_type == 'windowed_test_launcher': |
| 520 # TODO(dpranke): Figure out some way to figure out which | 514 extra_files = [ |
| 521 # test steps really need xvfb. | 515 'xdisplaycheck', |
| 522 extra_files.append('xdisplaycheck') | |
| 523 extra_files.append('../../testing/xvfb.py') | |
| 524 | |
| 525 cmdline = [ | |
| 526 '../../testing/xvfb.py', | 516 '../../testing/xvfb.py', |
| 527 '.', | 517 ] |
| 528 './' + str(target), | 518 cmdline = [ |
| 529 '--brave-new-test-launcher', | 519 '../../testing/xvfb.py', |
| 530 '--test-launcher-bot-mode', | 520 '.', |
| 531 '--asan=%d' % asan, | 521 './' + str(target), |
| 532 '--msan=%d' % msan, | 522 '--brave-new-test-launcher', |
| 533 '--tsan=%d' % tsan, | 523 '--test-launcher-bot-mode', |
| 534 ] | 524 '--asan=%d' % asan, |
| 535 else: | 525 '--msan=%d' % msan, |
| 536 cmdline = [ | 526 '--tsan=%d' % tsan, |
| 527 ] | |
| 528 elif test_type in ('windowed_test_launcher', 'console_test_launcher'): | |
|
M-A Ruel
2015/06/25 14:49:22
sort
| |
| 529 extra_files = [ | |
| 530 '../../testing/test_env.py' | |
| 531 ] | |
| 532 cmdline = [ | |
| 537 '../../testing/test_env.py', | 533 '../../testing/test_env.py', |
| 538 '.', | |
| 539 './' + str(target) + executable_suffix, | 534 './' + str(target) + executable_suffix, |
| 540 '--brave-new-test-launcher', | 535 '--brave-new-test-launcher', |
| 541 '--test-launcher-bot-mode', | 536 '--test-launcher-bot-mode', |
| 542 '--asan=%d' % asan, | 537 '--asan=%d' % asan, |
| 543 '--msan=%d' % msan, | 538 '--msan=%d' % msan, |
| 544 '--tsan=%d' % tsan, | 539 '--tsan=%d' % tsan, |
| 545 ] | 540 ] |
| 546 else: | 541 else: |
| 547 # TODO(dpranke): Handle script_tests and other types of swarmed tests. | 542 self.WriteFailureAndRaise('No command line for %s found (test type %s).' |
| 548 self.WriteFailureAndRaise('unknown test type "%s" for %s' % | 543 % (target, test_type), output_path=None) |
| 549 (test_type, target), output_path=None) | |
| 550 | |
| 551 | 544 |
| 552 return cmdline, extra_files | 545 return cmdline, extra_files |
| 553 | 546 |
| 554 def ToAbsPath(self, build_path, *comps): | 547 def ToAbsPath(self, build_path, *comps): |
| 555 return os.path.join(self.chromium_src_dir, | 548 return os.path.join(self.chromium_src_dir, |
| 556 self.ToSrcRelPath(build_path), | 549 self.ToSrcRelPath(build_path), |
| 557 *comps) | 550 *comps) |
| 558 | 551 |
| 559 def ToSrcRelPath(self, path): | 552 def ToSrcRelPath(self, path): |
| 560 """Returns a relative path from the top of the repo.""" | 553 """Returns a relative path from the top of the repo.""" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 | 773 |
| 781 if __name__ == '__main__': | 774 if __name__ == '__main__': |
| 782 try: | 775 try: |
| 783 sys.exit(main(sys.argv[1:])) | 776 sys.exit(main(sys.argv[1:])) |
| 784 except MBErr as e: | 777 except MBErr as e: |
| 785 print(e) | 778 print(e) |
| 786 sys.exit(1) | 779 sys.exit(1) |
| 787 except KeyboardInterrupt: | 780 except KeyboardInterrupt: |
| 788 print("interrupted, exiting", stream=sys.stderr) | 781 print("interrupted, exiting", stream=sys.stderr) |
| 789 sys.exit(130) | 782 sys.exit(130) |
| OLD | NEW |