• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
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
17from __future__ import print_function
18
19import argparse
20import multiprocessing
21import sys
22
23import artifacts.artifact_targets as artifact_targets
24import artifacts.distribtest_targets as distribtest_targets
25import artifacts.package_targets as package_targets
26import python_utils.jobset as jobset
27import python_utils.report_utils as report_utils
28
29_TARGETS = []
30_TARGETS += artifact_targets.targets()
31_TARGETS += distribtest_targets.targets()
32_TARGETS += package_targets.targets()
33
34
35def _create_build_map():
36    """Maps task names and labels to list of tasks to be built."""
37    target_build_map = dict([(target.name, [target]) for target in _TARGETS])
38    if len(_TARGETS) > len(list(target_build_map.keys())):
39        raise Exception('Target names need to be unique')
40
41    label_build_map = {}
42    label_build_map['all'] = [t for t in _TARGETS]  # to build all targets
43    for target in _TARGETS:
44        for label in target.labels:
45            if label in label_build_map:
46                label_build_map[label].append(target)
47            else:
48                label_build_map[label] = [target]
49
50    if set(target_build_map.keys()).intersection(list(label_build_map.keys())):
51        raise Exception('Target names need to be distinct from label names')
52    return dict(list(target_build_map.items()) + list(label_build_map.items()))
53
54
55_BUILD_MAP = _create_build_map()
56
57argp = argparse.ArgumentParser(description='Runs build/test targets.')
58argp.add_argument('-b',
59                  '--build',
60                  choices=sorted(_BUILD_MAP.keys()),
61                  nargs='+',
62                  default=['all'],
63                  help='Target name or target label to build.')
64argp.add_argument('-f',
65                  '--filter',
66                  choices=sorted(_BUILD_MAP.keys()),
67                  nargs='+',
68                  default=[],
69                  help='Filter targets to build with AND semantics.')
70argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
71argp.add_argument('-x',
72                  '--xml_report',
73                  default='report_taskrunner_sponge_log.xml',
74                  type=str,
75                  help='Filename for the JUnit-compatible XML report')
76argp.add_argument('--dry_run',
77                  default=False,
78                  action='store_const',
79                  const=True,
80                  help='Only print what would be run.')
81argp.add_argument(
82    '--inner_jobs',
83    default=None,
84    type=int,
85    help=
86    'Number of parallel jobs to use by each target. Passed as build_jobspec(inner_jobs=N) to each target.'
87)
88
89args = argp.parse_args()
90
91# Figure out which targets to build
92targets = []
93for label in args.build:
94    targets += _BUILD_MAP[label]
95
96# Among targets selected by -b, filter out those that don't match the filter
97targets = [t for t in targets if all(f in t.labels for f in args.filter)]
98
99print('Will build %d targets:' % len(targets))
100for target in targets:
101    print('  %s, labels %s' % (target.name, target.labels))
102print()
103
104if args.dry_run:
105    print('--dry_run was used, exiting')
106    sys.exit(1)
107
108# Execute pre-build phase
109prebuild_jobs = []
110for target in targets:
111    prebuild_jobs += target.pre_build_jobspecs()
112if prebuild_jobs:
113    num_failures, _ = jobset.run(prebuild_jobs,
114                                 newline_on_success=True,
115                                 maxjobs=args.jobs)
116    if num_failures != 0:
117        jobset.message('FAILED', 'Pre-build phase failed.', do_newline=True)
118        sys.exit(1)
119
120build_jobs = []
121for target in targets:
122    build_jobs.append(target.build_jobspec(inner_jobs=args.inner_jobs))
123if not build_jobs:
124    print('Nothing to build.')
125    sys.exit(1)
126
127jobset.message('START', 'Building targets.', do_newline=True)
128num_failures, resultset = jobset.run(build_jobs,
129                                     newline_on_success=True,
130                                     maxjobs=args.jobs)
131report_utils.render_junit_xml_report(resultset,
132                                     args.xml_report,
133                                     suite_name='tasks')
134if num_failures == 0:
135    jobset.message('SUCCESS',
136                   'All targets built successfully.',
137                   do_newline=True)
138else:
139    jobset.message('FAILED', 'Failed to build targets.', do_newline=True)
140    sys.exit(1)
141