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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 cmd = self.GNCmd('gen', path, vals['gn_args']) | 329 cmd = self.GNCmd('gen', path, vals['gn_args']) |
330 | 330 |
331 swarming_targets = [] | 331 swarming_targets = [] |
332 if self.args.swarming_targets_file: | 332 if self.args.swarming_targets_file: |
333 # We need GN to generate the list of runtime dependencies for | 333 # We need GN to generate the list of runtime dependencies for |
334 # the compile targets listed (one per line) in the file so | 334 # the compile targets listed (one per line) in the file so |
335 # we can run them via swarming. We use ninja_to_gn.pyl to convert | 335 # we can run them via swarming. We use ninja_to_gn.pyl to convert |
336 # the compile targets to the matching GN labels. | 336 # the compile targets to the matching GN labels. |
337 contents = self.ReadFile(self.args.swarming_targets_file) | 337 contents = self.ReadFile(self.args.swarming_targets_file) |
338 swarming_targets = contents.splitlines() | 338 swarming_targets = contents.splitlines() |
339 ninja_targets_to_labels = ast.literal_eval(self.ReadFile(os.path.join( | 339 gn_isolate_map = ast.literal_eval(self.ReadFile(os.path.join( |
340 self.chromium_src_dir, 'testing', 'buildbot', 'ninja_to_gn.pyl'))) | 340 self.chromium_src_dir, 'testing', 'buildbot', 'gn_isolate_map.pyl'))) |
341 gn_labels = [] | 341 gn_labels = [] |
342 for target in swarming_targets: | 342 for target in swarming_targets: |
343 if not target in ninja_targets_to_labels: | 343 if not target in gn_isolate_map: |
344 raise MBErr('test target "%s" not found in %s' % | 344 raise MBErr('test target "%s" not found in %s' % |
345 (target, '//testing/buildbot/ninja_to_gn.pyl')) | 345 (target, '//testing/buildbot/gn_isolate_map.pyl')) |
346 gn_labels.append(ninja_targets_to_labels[target]) | 346 gn_labels.append(gn_isolate_map[target]['label']) |
347 | 347 |
348 gn_runtime_deps_path = self.ToAbsPath(path, 'runtime_deps') | 348 gn_runtime_deps_path = self.ToAbsPath(path, 'runtime_deps') |
349 | 349 |
350 # Since GN hasn't run yet, the build directory may not even exist. | 350 # Since GN hasn't run yet, the build directory may not even exist. |
351 self.MaybeMakeDirectory(self.ToAbsPath(path)) | 351 self.MaybeMakeDirectory(self.ToAbsPath(path)) |
352 | 352 |
353 self.WriteFile(gn_runtime_deps_path, '\n'.join(gn_labels) + '\n') | 353 self.WriteFile(gn_runtime_deps_path, '\n'.join(gn_labels) + '\n') |
354 cmd.append('--runtime-deps-list-file=%s' % gn_runtime_deps_path) | 354 cmd.append('--runtime-deps-list-file=%s' % gn_runtime_deps_path) |
355 | 355 |
356 ret, _, _ = self.Run(cmd) | 356 ret, _, _ = self.Run(cmd) |
357 | 357 |
358 for target in swarming_targets: | 358 for target in swarming_targets: |
359 if sys.platform == 'win32': | 359 if sys.platform == 'win32': |
360 deps_path = self.ToAbsPath(path, target + '.exe.runtime_deps') | 360 deps_path = self.ToAbsPath(path, target + '.exe.runtime_deps') |
361 else: | 361 else: |
362 deps_path = self.ToAbsPath(path, target + '.runtime_deps') | 362 deps_path = self.ToAbsPath(path, target + '.runtime_deps') |
363 if not self.Exists(deps_path): | 363 if not self.Exists(deps_path): |
364 raise MBErr('did not generate %s' % deps_path) | 364 raise MBErr('did not generate %s' % deps_path) |
365 | 365 |
366 command, extra_files = self.GetIsolateCommand(target, vals) | 366 command, extra_files = self.GetIsolateCommand(target, vals, |
367 gn_isolate_map) | |
367 | 368 |
368 runtime_deps = self.ReadFile(deps_path).splitlines() | 369 runtime_deps = self.ReadFile(deps_path).splitlines() |
369 | 370 |
370 isolate_path = self.ToAbsPath(path, target + '.isolate') | 371 isolate_path = self.ToAbsPath(path, target + '.isolate') |
371 self.WriteFile(isolate_path, | 372 self.WriteFile(isolate_path, |
372 pprint.pformat({ | 373 pprint.pformat({ |
373 'variables': { | 374 'variables': { |
374 'command': command, | 375 'command': command, |
375 'files': sorted(runtime_deps + extra_files), | 376 'files': sorted(runtime_deps + extra_files), |
376 } | 377 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
441 ret, _, _ = self.Run(cmd) | 442 ret, _, _ = self.Run(cmd) |
442 if not ret and self.args.verbose: | 443 if not ret and self.args.verbose: |
443 outp = json.loads(self.ReadFile(self.args.output_path[0])) | 444 outp = json.loads(self.ReadFile(self.args.output_path[0])) |
444 self.Print() | 445 self.Print() |
445 self.Print('analyze output:') | 446 self.Print('analyze output:') |
446 self.PrintJSON(outp) | 447 self.PrintJSON(outp) |
447 self.Print() | 448 self.Print() |
448 | 449 |
449 return ret | 450 return ret |
450 | 451 |
451 def GetIsolateCommand(self, target, vals): | 452 def RunGNIsolate(self, vals): |
452 extra_files = [] | 453 build_path = self.args.path[0] |
454 inp = self.ReadInputJSON(['targets']) | |
455 if self.args.verbose: | |
456 self.Print() | |
457 self.Print('isolate input:') | |
458 self.PrintJSON(inp) | |
459 self.Print() | |
460 output_path = self.args.output_path[0] | |
453 | 461 |
454 # TODO(dpranke): We should probably pull this from | 462 for target in inp['targets']: |
455 # the test list info in //testing/buildbot/*.json, | 463 runtime_deps_path = self.ToAbsPath(build_path, target + '.runtime_deps') |
456 # and assert that the test has can_use_on_swarming_builders: True, | |
457 # but we hardcode it here for now. | |
458 test_type = {}.get(target, 'gtest_test') | |
459 | 464 |
465 if not self.Exists(runtime_deps_path): | |
466 self.WriteFailureAndRaise('"%s" does not exist' % runtime_deps_path, | |
467 output_path) | |
468 | |
469 command, extra_files = self.GetIsolateCommand(target, vals, None) | |
470 | |
471 runtime_deps = self.ReadFile(runtime_deps_path).splitlines() | |
472 | |
473 | |
474 isolate_path = self.ToAbsPath(build_path, target + '.isolate') | |
475 self.WriteFile(isolate_path, | |
476 pprint.pformat({ | |
477 'variables': { | |
478 'command': command, | |
479 'files': sorted(runtime_deps + extra_files), | |
480 'read_only': 1, | |
M-A Ruel
2015/07/22 18:22:42
Not needed
| |
481 } | |
482 }) + '\n') | |
483 | |
484 self.WriteJSON( | |
485 { | |
486 'args': [ | |
487 '--isolated', | |
488 self.ToSrcRelPath('%s/%s.isolated' % (build_path, target)), | |
489 '--isolate', | |
490 self.ToSrcRelPath('%s/%s.isolate' % (build_path, target)), | |
491 ], | |
492 'dir': self.chromium_src_dir, | |
493 'version': 1, | |
494 }, | |
495 isolate_path + 'd.gen.json', | |
496 ) | |
497 | |
498 return 0 | |
499 | |
500 def GetIsolateCommand(self, target, vals, gn_isolate_map): | |
460 # This needs to mirror the settings in //build/config/ui.gni: | 501 # This needs to mirror the settings in //build/config/ui.gni: |
461 # use_x11 = is_linux && !use_ozone. | 502 # use_x11 = is_linux && !use_ozone. |
462 # TODO(dpranke): Figure out how to keep this in sync better. | 503 # TODO(dpranke): Figure out how to keep this in sync better. |
463 use_x11 = (sys.platform == 'linux2' and | 504 use_x11 = (sys.platform == 'linux2' and |
464 not 'target_os="android"' in vals['gn_args'] and | 505 not 'target_os="android"' in vals['gn_args'] and |
465 not 'use_ozone=true' in vals['gn_args']) | 506 not 'use_ozone=true' in vals['gn_args']) |
466 | 507 |
467 asan = 'is_asan=true' in vals['gn_args'] | 508 asan = 'is_asan=true' in vals['gn_args'] |
468 msan = 'is_msan=true' in vals['gn_args'] | 509 msan = 'is_msan=true' in vals['gn_args'] |
469 tsan = 'is_tsan=true' in vals['gn_args'] | 510 tsan = 'is_tsan=true' in vals['gn_args'] |
470 | 511 |
471 executable_suffix = '.exe' if sys.platform == 'win32' else '' | 512 executable_suffix = '.exe' if sys.platform == 'win32' else '' |
472 | 513 |
473 if test_type == 'gtest_test': | 514 test_type = gn_isolate_map[target]['type'] |
474 extra_files.append('../../testing/test_env.py') | 515 cmdline = [] |
516 extra_files = [] | |
475 | 517 |
476 if use_x11: | 518 if use_x11 and test_type == 'windowed_test_launcher': |
477 # TODO(dpranke): Figure out some way to figure out which | 519 extra_files = [ |
478 # test steps really need xvfb. | 520 'xdisplaycheck', |
479 extra_files.append('xdisplaycheck') | 521 '../../testing/test_env.py', |
480 extra_files.append('../../testing/xvfb.py') | |
481 | |
482 cmdline = [ | |
483 '../../testing/xvfb.py', | 522 '../../testing/xvfb.py', |
484 '.', | 523 ] |
485 './' + str(target), | 524 cmdline = [ |
486 '--brave-new-test-launcher', | 525 '../../testing/xvfb.py', |
487 '--test-launcher-bot-mode', | 526 '.', |
488 '--asan=%d' % asan, | 527 './' + str(target), |
489 '--msan=%d' % msan, | 528 '--brave-new-test-launcher', |
490 '--tsan=%d' % tsan, | 529 '--test-launcher-bot-mode', |
491 ] | 530 '--asan=%d' % asan, |
492 else: | 531 '--msan=%d' % msan, |
493 cmdline = [ | 532 '--tsan=%d' % tsan, |
533 ] | |
534 elif test_type in ('windowed_test_launcher', 'console_test_launcher'): | |
535 extra_files = [ | |
536 '../../testing/test_env.py' | |
537 ] | |
538 cmdline = [ | |
494 '../../testing/test_env.py', | 539 '../../testing/test_env.py', |
495 '.', | |
496 './' + str(target) + executable_suffix, | 540 './' + str(target) + executable_suffix, |
497 '--brave-new-test-launcher', | 541 '--brave-new-test-launcher', |
498 '--test-launcher-bot-mode', | 542 '--test-launcher-bot-mode', |
499 '--asan=%d' % asan, | 543 '--asan=%d' % asan, |
500 '--msan=%d' % msan, | 544 '--msan=%d' % msan, |
501 '--tsan=%d' % tsan, | 545 '--tsan=%d' % tsan, |
502 ] | 546 ] |
547 elif test_type in ('raw'): | |
548 extra_files = [] | |
549 cmdline = [ | |
550 './' + str(target) + executable_suffix, | |
551 ] + gn_isolate_map[target].get('args') | |
552 | |
503 else: | 553 else: |
504 # TODO(dpranke): Handle script_tests and other types of swarmed tests. | 554 self.WriteFailureAndRaise('No command line for %s found (test type %s).' |
505 self.WriteFailureAndRaise('unknown test type "%s" for %s' % | 555 % (target, test_type), output_path=None) |
506 (test_type, target), output_path=None) | |
507 | |
508 | 556 |
509 return cmdline, extra_files | 557 return cmdline, extra_files |
510 | 558 |
511 def ToAbsPath(self, build_path, *comps): | 559 def ToAbsPath(self, build_path, *comps): |
512 return os.path.join(self.chromium_src_dir, | 560 return os.path.join(self.chromium_src_dir, |
513 self.ToSrcRelPath(build_path), | 561 self.ToSrcRelPath(build_path), |
514 *comps) | 562 *comps) |
515 | 563 |
516 def ToSrcRelPath(self, path): | 564 def ToSrcRelPath(self, path): |
517 """Returns a relative path from the top of the repo.""" | 565 """Returns a relative path from the top of the repo.""" |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
737 | 785 |
738 if __name__ == '__main__': | 786 if __name__ == '__main__': |
739 try: | 787 try: |
740 sys.exit(main(sys.argv[1:])) | 788 sys.exit(main(sys.argv[1:])) |
741 except MBErr as e: | 789 except MBErr as e: |
742 print(e) | 790 print(e) |
743 sys.exit(1) | 791 sys.exit(1) |
744 except KeyboardInterrupt: | 792 except KeyboardInterrupt: |
745 print("interrupted, exiting", stream=sys.stderr) | 793 print("interrupted, exiting", stream=sys.stderr) |
746 sys.exit(130) | 794 sys.exit(130) |
OLD | NEW |