blob: e3ca31965a6dc75a08da3131d1709170c0cb9ce5 [file] [log] [blame]
Yunlian Jiange84ea3d2016-12-12 11:07:40 -08001#!/usr/bin/env python2
Tiancong Wangd0348132019-03-07 11:22:48 -08002# -*- coding: utf-8 -*-
Ting-Yuan Huange5819872016-12-15 14:22:26 -08003#
4# Copyright 2016 The Chromium OS Authors. All rights reserved.
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
Denis Nikitin265c2962019-08-01 19:52:49 -07007
Yunlian Jiang14cf5962015-12-11 15:50:14 -08008"""Script for running nightly compiler tests on ChromeOS.
cmtice46093e52014-12-09 14:59:16 -08009
10This script launches a buildbot to build ChromeOS with the latest compiler on
11a particular board; then it finds and downloads the trybot image and the
12corresponding official image, and runs crosperf performance tests comparing
13the two. It then generates a report, emails it to the c-compiler-chrome, as
14well as copying the images into the seven-day reports directory.
15"""
16
17# Script to test different toolchains against ChromeOS benchmarks.
Yunlian Jiang14cf5962015-12-11 15:50:14 -080018
19from __future__ import print_function
20
Caroline Ticeeddb0632016-04-14 09:19:02 -070021import argparse
cmticece5ffa42015-02-12 15:18:43 -080022import datetime
cmtice46093e52014-12-09 14:59:16 -080023import os
Luis Lozanoc75fd052016-02-19 17:37:01 -080024import re
cmtice46093e52014-12-09 14:59:16 -080025import sys
26import time
cmtice46093e52014-12-09 14:59:16 -080027
Caroline Ticea8af9a72016-07-20 12:52:59 -070028from cros_utils import command_executer
29from cros_utils import logger
cmtice46093e52014-12-09 14:59:16 -080030
Caroline Ticea8af9a72016-07-20 12:52:59 -070031from cros_utils import buildbot_utils
cmtice46093e52014-12-09 14:59:16 -080032
Manoj Guptac4110352016-12-28 13:47:12 -080033# CL that uses LLVM-Next to build the images (includes chrome).
Manoj Gupta66682c72017-05-24 12:19:57 -070034USE_LLVM_NEXT_PATCH = '513590'
Manoj Guptac4110352016-12-28 13:47:12 -080035
Luis Lozanof2a3ef42015-12-15 13:49:30 -080036CROSTC_ROOT = '/usr/local/google/crostc'
37ROLE_ACCOUNT = 'mobiletc-prebuild'
cmtice46093e52014-12-09 14:59:16 -080038TOOLCHAIN_DIR = os.path.dirname(os.path.realpath(__file__))
Luis Lozanof2a3ef42015-12-15 13:49:30 -080039MAIL_PROGRAM = '~/var/bin/mail-sheriff'
Luis Lozanof2a3ef42015-12-15 13:49:30 -080040PENDING_ARCHIVES_DIR = os.path.join(CROSTC_ROOT, 'pending_archives')
41NIGHTLY_TESTS_DIR = os.path.join(CROSTC_ROOT, 'nightly_test_reports')
42
Ting-Yuan Huange5819872016-12-15 14:22:26 -080043IMAGE_DIR = '{board}-{image_type}'
44IMAGE_VERSION_STR = r'{chrome_version}-{tip}\.{branch}\.{branch_branch}'
45IMAGE_FS = IMAGE_DIR + '/' + IMAGE_VERSION_STR
Ting-Yuan Huang112d5622018-03-26 13:49:42 -070046TRYBOT_IMAGE_FS = IMAGE_FS + '-{build_id}'
Luis Lozanoc75fd052016-02-19 17:37:01 -080047PFQ_IMAGE_FS = IMAGE_FS + '-rc1'
Manoj Guptaaee96b72016-10-24 13:43:28 -070048IMAGE_RE_GROUPS = {
49 'board': r'(?P<board>\S+)',
50 'image_type': r'(?P<image_type>\S+)',
51 'chrome_version': r'(?P<chrome_version>R\d+)',
52 'tip': r'(?P<tip>\d+)',
53 'branch': r'(?P<branch>\d+)',
54 'branch_branch': r'(?P<branch_branch>\d+)',
55 'build_id': r'(?P<build_id>b\d+)'
56}
Luis Lozanoc75fd052016-02-19 17:37:01 -080057TRYBOT_IMAGE_RE = TRYBOT_IMAGE_FS.format(**IMAGE_RE_GROUPS)
58
Tiancong Wang03234662019-10-30 10:16:38 -070059TELEMETRY_AQUARIUM_UNSUPPORTED = ['bob', 'elm', 'veyron_minnie']
60
cmtice46093e52014-12-09 14:59:16 -080061
Yunlian Jiang14cf5962015-12-11 15:50:14 -080062class ToolchainComparator(object):
63 """Class for doing the nightly tests work."""
cmtice46093e52014-12-09 14:59:16 -080064
Luis Lozanof2a3ef42015-12-15 13:49:30 -080065 def __init__(self,
66 board,
67 remotes,
68 chromeos_root,
69 weekday,
70 patches,
71 noschedv2=False):
cmtice46093e52014-12-09 14:59:16 -080072 self._board = board
73 self._remotes = remotes
74 self._chromeos_root = chromeos_root
75 self._base_dir = os.getcwd()
76 self._ce = command_executer.GetCommandExecuter()
77 self._l = logger.GetLogger()
Yunlian Jiang73580dd2017-11-21 04:48:40 -080078 self._build = '%s-release-tryjob' % board
Manoj Guptad575b8a2017-03-08 10:51:28 -080079 self._patches = patches.split(',') if patches else []
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070080 self._patches_string = '_'.join(str(p) for p in self._patches)
Han Shen43494292015-09-14 10:26:40 -070081 self._noschedv2 = noschedv2
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070082
cmtice46093e52014-12-09 14:59:16 -080083 if not weekday:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080084 self._weekday = time.strftime('%a')
cmtice46093e52014-12-09 14:59:16 -080085 else:
86 self._weekday = weekday
cmtice7f3190b2015-05-22 14:14:51 -070087 timestamp = datetime.datetime.strftime(datetime.datetime.now(),
Luis Lozanof2a3ef42015-12-15 13:49:30 -080088 '%Y-%m-%d_%H:%M:%S')
Manoj Guptaaee96b72016-10-24 13:43:28 -070089 self._reports_dir = os.path.join(
90 NIGHTLY_TESTS_DIR,
Caroline Tice9c4003a2017-11-07 16:37:33 -080091 '%s.%s' % (timestamp, board),
92 )
cmtice46093e52014-12-09 14:59:16 -080093
Luis Lozanoc75fd052016-02-19 17:37:01 -080094 def _GetVanillaImageName(self, trybot_image):
Ting-Yuan Huange5819872016-12-15 14:22:26 -080095 """Given a trybot artifact name, get latest vanilla image name.
cmtice46093e52014-12-09 14:59:16 -080096
Luis Lozano783954f2015-12-21 18:06:29 -080097 Args:
98 trybot_image: artifact name such as
Caroline Tice219e3b72018-12-18 15:54:49 -080099 'daisy-release-tryjob/R40-6394.0.0-b1389'
Luis Lozano783954f2015-12-21 18:06:29 -0800100
101 Returns:
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800102 Latest official image name, e.g. 'daisy-release/R57-9089.0.0'.
cmtice46093e52014-12-09 14:59:16 -0800103 """
Yunlian Jiang2e0ad052017-11-22 14:06:45 -0800104 # We need to filter out -tryjob in the trybot_image.
105 trybot = re.sub('-tryjob', '', trybot_image)
106 mo = re.search(TRYBOT_IMAGE_RE, trybot)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800107 assert mo
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800108 dirname = IMAGE_DIR.replace('\\', '').format(**mo.groupdict())
Ting-Yuan Huang99d32c42017-04-24 20:34:43 -0700109 return buildbot_utils.GetLatestImage(self._chromeos_root, dirname)
cmtice46093e52014-12-09 14:59:16 -0800110
Luis Lozanoc75fd052016-02-19 17:37:01 -0800111 def _GetNonAFDOImageName(self, trybot_image):
112 """Given a trybot artifact name, get corresponding non-AFDO image name.
113
114 We get the non-AFDO image from the PFQ builders. This image
115 is not generated for all the boards and, the closest PFQ image
116 was the one build for the previous ChromeOS version (the chrome
117 used in the current version is the one validated in the previous
118 version).
119 The previous ChromeOS does not always exist either. So, we try
120 a couple of versions before.
Luis Lozano783954f2015-12-21 18:06:29 -0800121
122 Args:
123 trybot_image: artifact name such as
Caroline Tice219e3b72018-12-18 15:54:49 -0800124 'daisy-release-tryjob/R40-6394.0.0-b1389'
Luis Lozano783954f2015-12-21 18:06:29 -0800125
126 Returns:
127 Corresponding chrome PFQ image name, e.g.
Luis Lozanoc75fd052016-02-19 17:37:01 -0800128 'daisy-chrome-pfq/R40-6393.0.0-rc1'.
Luis Lozano783954f2015-12-21 18:06:29 -0800129 """
Yunlian Jiang2e0ad052017-11-22 14:06:45 -0800130 trybot = re.sub('-tryjob', '', trybot_image)
131 mo = re.search(TRYBOT_IMAGE_RE, trybot)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800132 assert mo
133 image_dict = mo.groupdict()
134 image_dict['image_type'] = 'chrome-pfq'
George Burgess IV9a6dae82019-07-24 23:20:57 -0700135 for _ in range(2):
Luis Lozanoc75fd052016-02-19 17:37:01 -0800136 image_dict['tip'] = str(int(image_dict['tip']) - 1)
137 nonafdo_image = PFQ_IMAGE_FS.replace('\\', '').format(**image_dict)
138 if buildbot_utils.DoesImageExist(self._chromeos_root, nonafdo_image):
139 return nonafdo_image
140 return ''
Luis Lozano783954f2015-12-21 18:06:29 -0800141
Luis Lozano783954f2015-12-21 18:06:29 -0800142 def _TestImages(self, trybot_image, vanilla_image, nonafdo_image):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800143 """Create crosperf experiment file.
cmtice46093e52014-12-09 14:59:16 -0800144
Luis Lozano783954f2015-12-21 18:06:29 -0800145 Given the names of the trybot, vanilla and non-AFDO images, create the
cmtice46093e52014-12-09 14:59:16 -0800146 appropriate crosperf experiment file and launch crosperf on it.
147 """
Caroline Ticead16df92019-08-02 11:09:25 -0700148 experiment_file_dir = os.path.join(CROSTC_ROOT, self._weekday)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800149 experiment_file_name = '%s_toolchain_experiment.txt' % self._board
Yunlian Jiang2f563562015-08-28 13:54:04 -0700150
Manoj Guptad575b8a2017-03-08 10:51:28 -0800151 compiler_string = 'llvm'
Manoj Guptac4110352016-12-28 13:47:12 -0800152 if USE_LLVM_NEXT_PATCH in self._patches_string:
153 experiment_file_name = '%s_llvm_next_experiment.txt' % self._board
154 compiler_string = 'llvm_next'
Yunlian Jiang2f563562015-08-28 13:54:04 -0700155
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800156 experiment_file = os.path.join(experiment_file_dir, experiment_file_name)
cmtice46093e52014-12-09 14:59:16 -0800157 experiment_header = """
158 board: %s
159 remote: %s
Luis Lozanoe1efeb82015-06-16 16:35:44 -0700160 retries: 1
Denis Nikitind7cded22019-09-12 13:38:50 -0700161 cooldown_temp: 40
162 cooldown_time: 10
Denis Nikitin858e1452019-09-16 15:30:05 -0700163 cpu_freq_pct: 95
Denis Nikitin30a061f2019-09-27 09:04:31 -0700164 top_interval: 1
cmtice46093e52014-12-09 14:59:16 -0800165 """ % (self._board, self._remotes)
166 experiment_tests = """
Luis Lozano1489d642015-12-08 10:08:19 -0800167 benchmark: all_toolchain_perf {
cmtice46093e52014-12-09 14:59:16 -0800168 suite: telemetry_Crosperf
Tiancong Wangd0348132019-03-07 11:22:48 -0800169 iterations: 5
Manoj Gupta5a516382017-08-23 12:27:54 -0700170 run_local: False
cmtice46093e52014-12-09 14:59:16 -0800171 }
Caroline Ticee82513b2016-10-27 12:45:15 -0700172
Caroline Tice219e3b72018-12-18 15:54:49 -0800173 benchmark: loading.desktop {
Caroline Ticee82513b2016-10-27 12:45:15 -0700174 suite: telemetry_Crosperf
Caroline Tice219e3b72018-12-18 15:54:49 -0800175 test_args: --story-tag-filter=typical
176 iterations: 3
Caroline Ticee82513b2016-10-27 12:45:15 -0700177 run_local: False
178 retries: 0
179 }
Tiancong Wang03234662019-10-30 10:16:38 -0700180 """
181 telemetry_aquarium_tests = """
Tiancong Wangd8bf2812019-08-30 11:34:05 -0700182 benchmark: rendering.desktop {
183 run_local: False
184 suite: telemetry_Crosperf
185 test_args: --story-filter=aquarium$
186 iterations: 5
187 }
188
189 benchmark: rendering.desktop {
190 run_local: False
191 suite: telemetry_Crosperf
192 test_args: --story-filter=aquarium_20k$
193 iterations: 3
194 }
cmtice46093e52014-12-09 14:59:16 -0800195 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800196
197 with open(experiment_file, 'w') as f:
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800198 f.write(experiment_header)
199 f.write(experiment_tests)
cmtice46093e52014-12-09 14:59:16 -0800200
Tiancong Wang03234662019-10-30 10:16:38 -0700201 if self.board not in TELEMETRY_AQUARIUM_UNSUPPORTED:
202 f.write(telemetry_aquarium_tests)
203
cmtice46093e52014-12-09 14:59:16 -0800204 # Now add vanilla to test file.
Yunlian Jiangfceaba32018-06-06 09:08:44 -0700205 official_image = """
cmtice46093e52014-12-09 14:59:16 -0800206 vanilla_image {
207 chromeos_root: %s
208 build: %s
Yunlian Jiang8c18be12017-03-20 16:52:33 -0700209 compiler: llvm
cmtice46093e52014-12-09 14:59:16 -0800210 }
211 """ % (self._chromeos_root, vanilla_image)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800212 f.write(official_image)
cmtice46093e52014-12-09 14:59:16 -0800213
Luis Lozano783954f2015-12-21 18:06:29 -0800214 # Now add non-AFDO image to test file.
Luis Lozano439f2b72016-01-08 11:56:02 -0800215 if nonafdo_image:
Yunlian Jiangfceaba32018-06-06 09:08:44 -0700216 official_nonafdo_image = """
Luis Lozano783954f2015-12-21 18:06:29 -0800217 nonafdo_image {
218 chromeos_root: %s
219 build: %s
Yunlian Jiang8c18be12017-03-20 16:52:33 -0700220 compiler: llvm
Luis Lozano783954f2015-12-21 18:06:29 -0800221 }
222 """ % (self._chromeos_root, nonafdo_image)
Luis Lozano439f2b72016-01-08 11:56:02 -0800223 f.write(official_nonafdo_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800224
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800225 label_string = '%s_trybot_image' % compiler_string
Caroline Tice80eab982015-11-04 14:03:14 -0800226
Manoj Gupta3594db82017-01-31 11:48:57 -0800227 # Reuse autotest files from vanilla image for trybot images
228 autotest_files = os.path.join('/tmp', vanilla_image, 'autotest_files')
Yunlian Jiangfceaba32018-06-06 09:08:44 -0700229 experiment_image = """
Caroline Tice80eab982015-11-04 14:03:14 -0800230 %s {
cmtice46093e52014-12-09 14:59:16 -0800231 chromeos_root: %s
232 build: %s
Manoj Gupta3594db82017-01-31 11:48:57 -0800233 autotest_path: %s
Caroline Ticeddde5052015-09-23 09:43:35 -0700234 compiler: %s
cmtice46093e52014-12-09 14:59:16 -0800235 }
Caroline Tice80eab982015-11-04 14:03:14 -0800236 """ % (label_string, self._chromeos_root, trybot_image,
Manoj Gupta3594db82017-01-31 11:48:57 -0800237 autotest_files, compiler_string)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800238 f.write(experiment_image)
cmtice46093e52014-12-09 14:59:16 -0800239
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800240 crosperf = os.path.join(TOOLCHAIN_DIR, 'crosperf', 'crosperf')
Han Shen43494292015-09-14 10:26:40 -0700241 noschedv2_opts = '--noschedv2' if self._noschedv2 else ''
Denis Nikitin265c2962019-08-01 19:52:49 -0700242 command = ('{crosperf} --no_email=True --results_dir={r_dir} --no_hwp '
Ting-Yuan Huangb1afe3f2018-08-16 21:03:50 +0000243 '--json_report=True {noschedv2_opts} {exp_file}').format(
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800244 crosperf=crosperf,
245 r_dir=self._reports_dir,
246 noschedv2_opts=noschedv2_opts,
247 exp_file=experiment_file)
cmticeaa700b02015-06-12 13:26:47 -0700248
cmtice46093e52014-12-09 14:59:16 -0800249 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700250 if ret != 0:
Manoj Guptaaee96b72016-10-24 13:43:28 -0700251 raise RuntimeError('Crosperf execution error!')
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700252 else:
253 # Copy json report to pending archives directory.
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800254 command = 'cp %s/*.json %s/.' % (self._reports_dir, PENDING_ARCHIVES_DIR)
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700255 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700256 return
cmtice46093e52014-12-09 14:59:16 -0800257
cmtice7f3190b2015-05-22 14:14:51 -0700258 def _SendEmail(self):
259 """Find email message generated by crosperf and send it."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800260 filename = os.path.join(self._reports_dir, 'msg_body.html')
cmtice7f3190b2015-05-22 14:14:51 -0700261 if (os.path.exists(filename) and
262 os.path.exists(os.path.expanduser(MAIL_PROGRAM))):
Manoj Guptad575b8a2017-03-08 10:51:28 -0800263 email_title = 'buildbot llvm test results'
Manoj Guptac4110352016-12-28 13:47:12 -0800264 if USE_LLVM_NEXT_PATCH in self._patches_string:
265 email_title = 'buildbot llvm_next test results'
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800266 command = ('cat %s | %s -s "%s, %s" -team -html' %
267 (filename, MAIL_PROGRAM, email_title, self._board))
cmtice7f3190b2015-05-22 14:14:51 -0700268 self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800269
Ting-Yuan Huang6a9a98a2018-03-07 17:35:13 -0800270 def DoAll(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800271 """Main function inside ToolchainComparator class.
cmtice46093e52014-12-09 14:59:16 -0800272
273 Launch trybot, get image names, create crosperf experiment file, run
274 crosperf, and copy images into seven-day report directories.
275 """
Ting-Yuan Huang6a9a98a2018-03-07 17:35:13 -0800276 buildbucket_id, trybot_image = buildbot_utils.GetTrybotImage(
277 self._chromeos_root,
278 self._build,
279 self._patches,
Jian Cai9d576402019-06-17 20:49:35 +0000280 tryjob_flags=['--notests'],
Ting-Yuan Huang6a9a98a2018-03-07 17:35:13 -0800281 build_toolchain=True)
cmtice46093e52014-12-09 14:59:16 -0800282
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800283 print('trybot_url: \
Ting-Yuan Huang6a9a98a2018-03-07 17:35:13 -0800284 http://cros-goldeneye/chromeos/healthmonitoring/buildDetails?buildbucketId=%s'
285 % buildbucket_id)
Tiancong Wang03234662019-10-30 10:16:38 -0700286 if not trybot_image:
Caroline Ticeefb79902018-04-18 11:23:01 -0700287 self._l.LogError('Unable to find trybot_image!')
Yunlian Jiangcdd19072017-09-29 10:15:56 -0700288 return 2
Luis Lozano783954f2015-12-21 18:06:29 -0800289
Luis Lozanoc75fd052016-02-19 17:37:01 -0800290 vanilla_image = self._GetVanillaImageName(trybot_image)
291 nonafdo_image = self._GetNonAFDOImageName(trybot_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800292
293 print('trybot_image: %s' % trybot_image)
294 print('vanilla_image: %s' % vanilla_image)
295 print('nonafdo_image: %s' % nonafdo_image)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800296
Luis Lozano783954f2015-12-21 18:06:29 -0800297 self._TestImages(trybot_image, vanilla_image, nonafdo_image)
cmtice7f3190b2015-05-22 14:14:51 -0700298 self._SendEmail()
cmtice46093e52014-12-09 14:59:16 -0800299 return 0
300
301
302def Main(argv):
303 """The main function."""
304
305 # Common initializations
306 command_executer.InitCommandExecuter()
Caroline Ticeeddb0632016-04-14 09:19:02 -0700307 parser = argparse.ArgumentParser()
Manoj Guptaaee96b72016-10-24 13:43:28 -0700308 parser.add_argument(
309 '--remote', dest='remote', help='Remote machines to run tests on.')
310 parser.add_argument(
311 '--board', dest='board', default='x86-zgb', help='The target board.')
312 parser.add_argument(
313 '--chromeos_root',
314 dest='chromeos_root',
315 help='The chromeos root from which to run tests.')
316 parser.add_argument(
317 '--weekday',
318 default='',
319 dest='weekday',
320 help='The day of the week for which to run tests.')
321 parser.add_argument(
322 '--patch',
323 dest='patches',
324 help='The patches to use for the testing, '
325 "seprate the patch numbers with ',' "
326 'for more than one patches.')
327 parser.add_argument(
328 '--noschedv2',
329 dest='noschedv2',
330 action='store_true',
331 default=False,
332 help='Pass --noschedv2 to crosperf.')
Han Shen36413122015-08-28 11:05:40 -0700333
Caroline Ticeeddb0632016-04-14 09:19:02 -0700334 options = parser.parse_args(argv[1:])
cmtice46093e52014-12-09 14:59:16 -0800335 if not options.board:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800336 print('Please give a board.')
cmtice46093e52014-12-09 14:59:16 -0800337 return 1
338 if not options.remote:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800339 print('Please give at least one remote machine.')
cmtice46093e52014-12-09 14:59:16 -0800340 return 1
341 if not options.chromeos_root:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800342 print('Please specify the ChromeOS root directory.')
cmtice46093e52014-12-09 14:59:16 -0800343 return 1
Yunlian Jiange52838c2015-08-20 14:32:37 -0700344
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800345 fc = ToolchainComparator(options.board, options.remote, options.chromeos_root,
Manoj Guptad575b8a2017-03-08 10:51:28 -0800346 options.weekday, options.patches, options.noschedv2)
Ting-Yuan Huang6a9a98a2018-03-07 17:35:13 -0800347 return fc.DoAll()
cmtice46093e52014-12-09 14:59:16 -0800348
349
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800350if __name__ == '__main__':
cmtice46093e52014-12-09 14:59:16 -0800351 retval = Main(sys.argv)
352 sys.exit(retval)