task_runner.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #!/usr/bin/env python
  2. # Copyright 2016 gRPC authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. """Runs selected gRPC test/build tasks."""
  16. from __future__ import print_function
  17. import argparse
  18. import multiprocessing
  19. import sys
  20. import artifacts.artifact_targets as artifact_targets
  21. import artifacts.distribtest_targets as distribtest_targets
  22. import artifacts.package_targets as package_targets
  23. import python_utils.jobset as jobset
  24. import python_utils.report_utils as report_utils
  25. _TARGETS = []
  26. _TARGETS += artifact_targets.targets()
  27. _TARGETS += distribtest_targets.targets()
  28. _TARGETS += package_targets.targets()
  29. def _create_build_map():
  30. """Maps task names and labels to list of tasks to be built."""
  31. target_build_map = dict([(target.name, [target]) for target in _TARGETS])
  32. if len(_TARGETS) > len(list(target_build_map.keys())):
  33. raise Exception('Target names need to be unique')
  34. label_build_map = {}
  35. label_build_map['all'] = [t for t in _TARGETS] # to build all targets
  36. for target in _TARGETS:
  37. for label in target.labels:
  38. if label in label_build_map:
  39. label_build_map[label].append(target)
  40. else:
  41. label_build_map[label] = [target]
  42. if set(target_build_map.keys()).intersection(list(label_build_map.keys())):
  43. raise Exception('Target names need to be distinct from label names')
  44. return dict(list(target_build_map.items()) + list(label_build_map.items()))
  45. _BUILD_MAP = _create_build_map()
  46. argp = argparse.ArgumentParser(description='Runs build/test targets.')
  47. argp.add_argument('-b',
  48. '--build',
  49. choices=sorted(_BUILD_MAP.keys()),
  50. nargs='+',
  51. default=['all'],
  52. help='Target name or target label to build.')
  53. argp.add_argument('-f',
  54. '--filter',
  55. choices=sorted(_BUILD_MAP.keys()),
  56. nargs='+',
  57. default=[],
  58. help='Filter targets to build with AND semantics.')
  59. argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
  60. argp.add_argument('-x',
  61. '--xml_report',
  62. default='report_taskrunner_sponge_log.xml',
  63. type=str,
  64. help='Filename for the JUnit-compatible XML report')
  65. argp.add_argument('--dry_run',
  66. default=False,
  67. action='store_const',
  68. const=True,
  69. help='Only print what would be run.')
  70. argp.add_argument(
  71. '--inner_jobs',
  72. default=None,
  73. type=int,
  74. help=
  75. 'Number of parallel jobs to use by each target. Passed as build_jobspec(inner_jobs=N) to each target.'
  76. )
  77. args = argp.parse_args()
  78. # Figure out which targets to build
  79. targets = []
  80. for label in args.build:
  81. targets += _BUILD_MAP[label]
  82. # Among targets selected by -b, filter out those that don't match the filter
  83. targets = [t for t in targets if all(f in t.labels for f in args.filter)]
  84. print('Will build %d targets:' % len(targets))
  85. for target in targets:
  86. print(' %s, labels %s' % (target.name, target.labels))
  87. print()
  88. if args.dry_run:
  89. print('--dry_run was used, exiting')
  90. sys.exit(1)
  91. # Execute pre-build phase
  92. prebuild_jobs = []
  93. for target in targets:
  94. prebuild_jobs += target.pre_build_jobspecs()
  95. if prebuild_jobs:
  96. num_failures, _ = jobset.run(prebuild_jobs,
  97. newline_on_success=True,
  98. maxjobs=args.jobs)
  99. if num_failures != 0:
  100. jobset.message('FAILED', 'Pre-build phase failed.', do_newline=True)
  101. sys.exit(1)
  102. build_jobs = []
  103. for target in targets:
  104. build_jobs.append(target.build_jobspec(inner_jobs=args.inner_jobs))
  105. if not build_jobs:
  106. print('Nothing to build.')
  107. sys.exit(1)
  108. jobset.message('START', 'Building targets.', do_newline=True)
  109. num_failures, resultset = jobset.run(build_jobs,
  110. newline_on_success=True,
  111. maxjobs=args.jobs)
  112. report_utils.render_junit_xml_report(resultset,
  113. args.xml_report,
  114. suite_name='tasks')
  115. if num_failures == 0:
  116. jobset.message('SUCCESS',
  117. 'All targets built successfully.',
  118. do_newline=True)
  119. else:
  120. jobset.message('FAILED', 'Failed to build targets.', do_newline=True)
  121. sys.exit(1)