blob: 1e8b33ac1311199c839024fd11a19ea4bdb30071 [file] [log] [blame]
Zhizhou Yang81d651f2020-02-10 16:51:20 -08001#!/usr/bin/env python3
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
zhizhouy9258b052020-04-15 17:33:46 -070025import shutil
cmtice46093e52014-12-09 14:59:16 -080026import sys
27import time
cmtice46093e52014-12-09 14:59:16 -080028
Caroline Ticea8af9a72016-07-20 12:52:59 -070029from cros_utils import command_executer
30from cros_utils import logger
cmtice46093e52014-12-09 14:59:16 -080031
Caroline Ticea8af9a72016-07-20 12:52:59 -070032from cros_utils import buildbot_utils
cmtice46093e52014-12-09 14:59:16 -080033
Manoj Guptac4110352016-12-28 13:47:12 -080034# CL that uses LLVM-Next to build the images (includes chrome).
Manoj Gupta66682c72017-05-24 12:19:57 -070035USE_LLVM_NEXT_PATCH = '513590'
Manoj Guptac4110352016-12-28 13:47:12 -080036
Luis Lozanof2a3ef42015-12-15 13:49:30 -080037CROSTC_ROOT = '/usr/local/google/crostc'
Luis Lozanobe756e02020-02-07 10:54:08 -080038NIGHTLY_TESTS_DIR = os.path.join(CROSTC_ROOT, 'nightly-tests')
Luis Lozanof2a3ef42015-12-15 13:49:30 -080039ROLE_ACCOUNT = 'mobiletc-prebuild'
cmtice46093e52014-12-09 14:59:16 -080040TOOLCHAIN_DIR = os.path.dirname(os.path.realpath(__file__))
zhizhouy9258b052020-04-15 17:33:46 -070041TMP_TOOLCHAIN_TEST = '/tmp/toolchain-tests'
Luis Lozanof2a3ef42015-12-15 13:49:30 -080042MAIL_PROGRAM = '~/var/bin/mail-sheriff'
Luis Lozanof2a3ef42015-12-15 13:49:30 -080043PENDING_ARCHIVES_DIR = os.path.join(CROSTC_ROOT, 'pending_archives')
Luis Lozanob02958e2020-02-10 02:12:18 -080044NIGHTLY_TESTS_RESULTS = os.path.join(CROSTC_ROOT, 'nightly_test_reports')
Luis Lozanof2a3ef42015-12-15 13:49:30 -080045
Ting-Yuan Huange5819872016-12-15 14:22:26 -080046IMAGE_DIR = '{board}-{image_type}'
47IMAGE_VERSION_STR = r'{chrome_version}-{tip}\.{branch}\.{branch_branch}'
48IMAGE_FS = IMAGE_DIR + '/' + IMAGE_VERSION_STR
Ting-Yuan Huang112d5622018-03-26 13:49:42 -070049TRYBOT_IMAGE_FS = IMAGE_FS + '-{build_id}'
Manoj Guptaaee96b72016-10-24 13:43:28 -070050IMAGE_RE_GROUPS = {
51 'board': r'(?P<board>\S+)',
52 'image_type': r'(?P<image_type>\S+)',
53 'chrome_version': r'(?P<chrome_version>R\d+)',
54 'tip': r'(?P<tip>\d+)',
55 'branch': r'(?P<branch>\d+)',
56 'branch_branch': r'(?P<branch_branch>\d+)',
57 'build_id': r'(?P<build_id>b\d+)'
58}
Luis Lozanoc75fd052016-02-19 17:37:01 -080059TRYBOT_IMAGE_RE = TRYBOT_IMAGE_FS.format(**IMAGE_RE_GROUPS)
60
zhizhouy9258b052020-04-15 17:33:46 -070061RECIPE_IMAGE_FS = IMAGE_FS + '-{build_id}-{buildbucket_id}'
62RECIPE_IMAGE_RE_GROUPS = {
63 'board': r'(?P<board>\S+)',
64 'image_type': r'(?P<image_type>\S+)',
65 'chrome_version': r'(?P<chrome_version>R\d+)',
66 'tip': r'(?P<tip>\d+)',
67 'branch': r'(?P<branch>\d+)',
68 'branch_branch': r'(?P<branch_branch>\d+)',
69 'build_id': r'(?P<build_id>\d+)',
70 'buildbucket_id': r'(?P<buildbucket_id>\d+)'
71}
72RECIPE_IMAGE_RE = RECIPE_IMAGE_FS.format(**RECIPE_IMAGE_RE_GROUPS)
73
Tiancong Wang03234662019-10-30 10:16:38 -070074TELEMETRY_AQUARIUM_UNSUPPORTED = ['bob', 'elm', 'veyron_minnie']
75
cmtice46093e52014-12-09 14:59:16 -080076
Yunlian Jiang14cf5962015-12-11 15:50:14 -080077class ToolchainComparator(object):
78 """Class for doing the nightly tests work."""
cmtice46093e52014-12-09 14:59:16 -080079
Luis Lozanof2a3ef42015-12-15 13:49:30 -080080 def __init__(self,
81 board,
82 remotes,
83 chromeos_root,
84 weekday,
85 patches,
zhizhouy9258b052020-04-15 17:33:46 -070086 recipe=False,
87 test=False,
Luis Lozanof2a3ef42015-12-15 13:49:30 -080088 noschedv2=False):
cmtice46093e52014-12-09 14:59:16 -080089 self._board = board
90 self._remotes = remotes
91 self._chromeos_root = chromeos_root
92 self._base_dir = os.getcwd()
93 self._ce = command_executer.GetCommandExecuter()
94 self._l = logger.GetLogger()
Yunlian Jiang73580dd2017-11-21 04:48:40 -080095 self._build = '%s-release-tryjob' % board
Manoj Guptad575b8a2017-03-08 10:51:28 -080096 self._patches = patches.split(',') if patches else []
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070097 self._patches_string = '_'.join(str(p) for p in self._patches)
zhizhouy9258b052020-04-15 17:33:46 -070098 self._recipe = recipe
99 self._test = test
Han Shen43494292015-09-14 10:26:40 -0700100 self._noschedv2 = noschedv2
Yunlian Jiang3c6e4672015-08-24 15:58:22 -0700101
cmtice46093e52014-12-09 14:59:16 -0800102 if not weekday:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800103 self._weekday = time.strftime('%a')
cmtice46093e52014-12-09 14:59:16 -0800104 else:
105 self._weekday = weekday
zhizhouyd8fcbf52020-04-06 16:47:20 -0700106 self._date = datetime.date.today().strftime('%Y/%m/%d')
107 timestamp = datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
Manoj Guptaaee96b72016-10-24 13:43:28 -0700108 self._reports_dir = os.path.join(
zhizhouy9258b052020-04-15 17:33:46 -0700109 TMP_TOOLCHAIN_TEST if self._test else NIGHTLY_TESTS_RESULTS,
Caroline Tice9c4003a2017-11-07 16:37:33 -0800110 '%s.%s' % (timestamp, board),
111 )
cmtice46093e52014-12-09 14:59:16 -0800112
Luis Lozanoc75fd052016-02-19 17:37:01 -0800113 def _GetVanillaImageName(self, trybot_image):
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800114 """Given a trybot artifact name, get latest vanilla image name.
cmtice46093e52014-12-09 14:59:16 -0800115
Luis Lozano783954f2015-12-21 18:06:29 -0800116 Args:
117 trybot_image: artifact name such as
Caroline Tice219e3b72018-12-18 15:54:49 -0800118 'daisy-release-tryjob/R40-6394.0.0-b1389'
zhizhouy9258b052020-04-15 17:33:46 -0700119 for recipe images, name is in this format:
120 'lulu-llvm-next-nightly/R84-13037.0.0-31011-8883172717979984032/'
Luis Lozano783954f2015-12-21 18:06:29 -0800121
122 Returns:
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800123 Latest official image name, e.g. 'daisy-release/R57-9089.0.0'.
cmtice46093e52014-12-09 14:59:16 -0800124 """
Yunlian Jiang2e0ad052017-11-22 14:06:45 -0800125 # We need to filter out -tryjob in the trybot_image.
zhizhouy9258b052020-04-15 17:33:46 -0700126 if self._recipe:
127 trybot = re.sub('-llvm-next-nightly', '-release', trybot_image)
128 mo = re.search(RECIPE_IMAGE_RE, trybot)
129 else:
130 trybot = re.sub('-tryjob', '', trybot_image)
131 mo = re.search(TRYBOT_IMAGE_RE, trybot)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800132 assert mo
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800133 dirname = IMAGE_DIR.replace('\\', '').format(**mo.groupdict())
Ting-Yuan Huang99d32c42017-04-24 20:34:43 -0700134 return buildbot_utils.GetLatestImage(self._chromeos_root, dirname)
cmtice46093e52014-12-09 14:59:16 -0800135
zhizhouy9258b052020-04-15 17:33:46 -0700136 def _TestImages(self, trybot_image, vanilla_image):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800137 """Create crosperf experiment file.
cmtice46093e52014-12-09 14:59:16 -0800138
Luis Lozano783954f2015-12-21 18:06:29 -0800139 Given the names of the trybot, vanilla and non-AFDO images, create the
cmtice46093e52014-12-09 14:59:16 -0800140 appropriate crosperf experiment file and launch crosperf on it.
141 """
zhizhouy9258b052020-04-15 17:33:46 -0700142 if self._test:
143 experiment_file_dir = TMP_TOOLCHAIN_TEST
144 else:
145 experiment_file_dir = os.path.join(NIGHTLY_TESTS_DIR, self._weekday)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800146 experiment_file_name = '%s_toolchain_experiment.txt' % self._board
Yunlian Jiang2f563562015-08-28 13:54:04 -0700147
Manoj Guptad575b8a2017-03-08 10:51:28 -0800148 compiler_string = 'llvm'
Manoj Guptac4110352016-12-28 13:47:12 -0800149 if USE_LLVM_NEXT_PATCH in self._patches_string:
150 experiment_file_name = '%s_llvm_next_experiment.txt' % self._board
151 compiler_string = 'llvm_next'
Yunlian Jiang2f563562015-08-28 13:54:04 -0700152
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800153 experiment_file = os.path.join(experiment_file_dir, experiment_file_name)
cmtice46093e52014-12-09 14:59:16 -0800154 experiment_header = """
155 board: %s
156 remote: %s
Luis Lozanoe1efeb82015-06-16 16:35:44 -0700157 retries: 1
Denis Nikitind7cded22019-09-12 13:38:50 -0700158 cooldown_temp: 40
159 cooldown_time: 10
Denis Nikitin858e1452019-09-16 15:30:05 -0700160 cpu_freq_pct: 95
Denis Nikitin30a061f2019-09-27 09:04:31 -0700161 top_interval: 1
cmtice46093e52014-12-09 14:59:16 -0800162 """ % (self._board, self._remotes)
163 experiment_tests = """
Luis Lozano1489d642015-12-08 10:08:19 -0800164 benchmark: all_toolchain_perf {
cmtice46093e52014-12-09 14:59:16 -0800165 suite: telemetry_Crosperf
Tiancong Wangd0348132019-03-07 11:22:48 -0800166 iterations: 5
Manoj Gupta5a516382017-08-23 12:27:54 -0700167 run_local: False
cmtice46093e52014-12-09 14:59:16 -0800168 }
Caroline Ticee82513b2016-10-27 12:45:15 -0700169
Caroline Tice219e3b72018-12-18 15:54:49 -0800170 benchmark: loading.desktop {
Caroline Ticee82513b2016-10-27 12:45:15 -0700171 suite: telemetry_Crosperf
Caroline Tice219e3b72018-12-18 15:54:49 -0800172 test_args: --story-tag-filter=typical
173 iterations: 3
Caroline Ticee82513b2016-10-27 12:45:15 -0700174 run_local: False
175 retries: 0
176 }
Tiancong Wang03234662019-10-30 10:16:38 -0700177 """
178 telemetry_aquarium_tests = """
Tiancong Wangd8bf2812019-08-30 11:34:05 -0700179 benchmark: rendering.desktop {
180 run_local: False
181 suite: telemetry_Crosperf
182 test_args: --story-filter=aquarium$
183 iterations: 5
184 }
185
186 benchmark: rendering.desktop {
187 run_local: False
188 suite: telemetry_Crosperf
189 test_args: --story-filter=aquarium_20k$
190 iterations: 3
191 }
cmtice46093e52014-12-09 14:59:16 -0800192 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800193
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800194 with open(experiment_file, 'w', encoding='utf-8') as f:
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800195 f.write(experiment_header)
196 f.write(experiment_tests)
cmtice46093e52014-12-09 14:59:16 -0800197
Tiancong Wang011c5712019-11-01 10:33:34 -0700198 if self._board not in TELEMETRY_AQUARIUM_UNSUPPORTED:
Tiancong Wang03234662019-10-30 10:16:38 -0700199 f.write(telemetry_aquarium_tests)
200
cmtice46093e52014-12-09 14:59:16 -0800201 # Now add vanilla to test file.
Yunlian Jiangfceaba32018-06-06 09:08:44 -0700202 official_image = """
Zhizhou Yangcbc6a9d2020-02-13 15:51:36 -0800203 vanilla_image {
204 chromeos_root: %s
205 build: %s
206 compiler: llvm
207 }
208 """ % (self._chromeos_root, vanilla_image)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800209 f.write(official_image)
cmtice46093e52014-12-09 14:59:16 -0800210
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800211 label_string = '%s_trybot_image' % compiler_string
Caroline Tice80eab982015-11-04 14:03:14 -0800212
Manoj Gupta3594db82017-01-31 11:48:57 -0800213 # Reuse autotest files from vanilla image for trybot images
214 autotest_files = os.path.join('/tmp', vanilla_image, 'autotest_files')
Yunlian Jiangfceaba32018-06-06 09:08:44 -0700215 experiment_image = """
Zhizhou Yangcbc6a9d2020-02-13 15:51:36 -0800216 %s {
217 chromeos_root: %s
218 build: %s
219 autotest_path: %s
220 compiler: %s
221 }
222 """ % (label_string, self._chromeos_root, trybot_image, autotest_files,
223 compiler_string)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800224 f.write(experiment_image)
cmtice46093e52014-12-09 14:59:16 -0800225
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800226 crosperf = os.path.join(TOOLCHAIN_DIR, 'crosperf', 'crosperf')
Han Shen43494292015-09-14 10:26:40 -0700227 noschedv2_opts = '--noschedv2' if self._noschedv2 else ''
zhizhouy9258b052020-04-15 17:33:46 -0700228 command = ('{crosperf} --no_email={no_email} --results_dir={r_dir} '
zhizhouyeb6e55f2020-03-24 12:09:20 -0700229 '--intel_pstate=no_hwp --logging_level=verbose '
Ting-Yuan Huangb1afe3f2018-08-16 21:03:50 +0000230 '--json_report=True {noschedv2_opts} {exp_file}').format(
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800231 crosperf=crosperf,
zhizhouy9258b052020-04-15 17:33:46 -0700232 no_email=not self._test,
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800233 r_dir=self._reports_dir,
234 noschedv2_opts=noschedv2_opts,
235 exp_file=experiment_file)
cmticeaa700b02015-06-12 13:26:47 -0700236
zhizhouyd8fcbf52020-04-06 16:47:20 -0700237 return self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800238
cmtice7f3190b2015-05-22 14:14:51 -0700239 def _SendEmail(self):
240 """Find email message generated by crosperf and send it."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800241 filename = os.path.join(self._reports_dir, 'msg_body.html')
cmtice7f3190b2015-05-22 14:14:51 -0700242 if (os.path.exists(filename) and
243 os.path.exists(os.path.expanduser(MAIL_PROGRAM))):
Manoj Guptad575b8a2017-03-08 10:51:28 -0800244 email_title = 'buildbot llvm test results'
Manoj Guptac4110352016-12-28 13:47:12 -0800245 if USE_LLVM_NEXT_PATCH in self._patches_string:
246 email_title = 'buildbot llvm_next test results'
zhizhouyd8fcbf52020-04-06 16:47:20 -0700247 command = ('cat %s | %s -s "%s, %s %s" -team -html' %
248 (filename, MAIL_PROGRAM, email_title, self._board, self._date))
cmtice7f3190b2015-05-22 14:14:51 -0700249 self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800250
zhizhouyd8fcbf52020-04-06 16:47:20 -0700251 def _CopyJson(self):
252 # Copy json report to pending archives directory.
253 command = 'cp %s/*.json %s/.' % (self._reports_dir, PENDING_ARCHIVES_DIR)
254 ret = self._ce.RunCommand(command)
255 # Failing to access json report means that crosperf terminated or all tests
256 # failed, raise an error.
257 if ret != 0:
258 raise RuntimeError(
259 'Crosperf failed to run tests, cannot copy json report!')
260
Ting-Yuan Huang6a9a98a2018-03-07 17:35:13 -0800261 def DoAll(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800262 """Main function inside ToolchainComparator class.
cmtice46093e52014-12-09 14:59:16 -0800263
264 Launch trybot, get image names, create crosperf experiment file, run
265 crosperf, and copy images into seven-day report directories.
266 """
zhizhouy9258b052020-04-15 17:33:46 -0700267 if self._recipe:
268 print('Using recipe buckets to get latest image.')
269 trybot_image = buildbot_utils.GetLatestRecipeImage(
270 self._chromeos_root, '%s-llvm-next-nightly' % self._board)
271 else:
272 # Launch tryjob and wait to get image location.
273 buildbucket_id, trybot_image = buildbot_utils.GetTrybotImage(
274 self._chromeos_root,
275 self._build,
276 self._patches,
277 tryjob_flags=['--notests'],
278 build_toolchain=True)
279 print('trybot_url: \
280 http://cros-goldeneye/chromeos/healthmonitoring/buildDetails?buildbucketId=%s'
281 % buildbucket_id)
cmtice46093e52014-12-09 14:59:16 -0800282
Tiancong Wang03234662019-10-30 10:16:38 -0700283 if not trybot_image:
Caroline Ticeefb79902018-04-18 11:23:01 -0700284 self._l.LogError('Unable to find trybot_image!')
Yunlian Jiangcdd19072017-09-29 10:15:56 -0700285 return 2
Luis Lozano783954f2015-12-21 18:06:29 -0800286
Luis Lozanoc75fd052016-02-19 17:37:01 -0800287 vanilla_image = self._GetVanillaImageName(trybot_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800288
289 print('trybot_image: %s' % trybot_image)
290 print('vanilla_image: %s' % vanilla_image)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800291
zhizhouy9258b052020-04-15 17:33:46 -0700292 ret = self._TestImages(trybot_image, vanilla_image)
zhizhouyd8fcbf52020-04-06 16:47:20 -0700293 # Always try to send report email as crosperf will generate report when
294 # tests partially succeeded.
zhizhouy9258b052020-04-15 17:33:46 -0700295 if not self._test:
296 self._SendEmail()
297 self._CopyJson()
zhizhouyd8fcbf52020-04-06 16:47:20 -0700298 # Non-zero ret here means crosperf tests partially failed, raise error here
299 # so that toolchain summary report can catch it.
300 if ret != 0:
301 raise RuntimeError('Crosperf tests partially failed!')
302
cmtice46093e52014-12-09 14:59:16 -0800303 return 0
304
305
306def Main(argv):
307 """The main function."""
308
309 # Common initializations
310 command_executer.InitCommandExecuter()
Caroline Ticeeddb0632016-04-14 09:19:02 -0700311 parser = argparse.ArgumentParser()
Manoj Guptaaee96b72016-10-24 13:43:28 -0700312 parser.add_argument(
313 '--remote', dest='remote', help='Remote machines to run tests on.')
314 parser.add_argument(
315 '--board', dest='board', default='x86-zgb', help='The target board.')
316 parser.add_argument(
317 '--chromeos_root',
318 dest='chromeos_root',
319 help='The chromeos root from which to run tests.')
320 parser.add_argument(
321 '--weekday',
322 default='',
323 dest='weekday',
324 help='The day of the week for which to run tests.')
325 parser.add_argument(
326 '--patch',
327 dest='patches',
328 help='The patches to use for the testing, '
329 "seprate the patch numbers with ',' "
330 'for more than one patches.')
331 parser.add_argument(
332 '--noschedv2',
333 dest='noschedv2',
334 action='store_true',
335 default=False,
336 help='Pass --noschedv2 to crosperf.')
zhizhouy9258b052020-04-15 17:33:46 -0700337 parser.add_argument(
338 '--recipe',
339 dest='recipe',
340 default=True,
341 help='Use images generated from recipe rather than'
342 'launching tryjob to get images.')
343 parser.add_argument(
344 '--test',
345 dest='test',
346 default=False,
347 help='Test this script on local desktop, '
348 'disabling mobiletc checking and email sending.'
349 'Artifacts stored in /tmp/toolchain-tests')
Han Shen36413122015-08-28 11:05:40 -0700350
Caroline Ticeeddb0632016-04-14 09:19:02 -0700351 options = parser.parse_args(argv[1:])
cmtice46093e52014-12-09 14:59:16 -0800352 if not options.board:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800353 print('Please give a board.')
cmtice46093e52014-12-09 14:59:16 -0800354 return 1
355 if not options.remote:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800356 print('Please give at least one remote machine.')
cmtice46093e52014-12-09 14:59:16 -0800357 return 1
358 if not options.chromeos_root:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800359 print('Please specify the ChromeOS root directory.')
cmtice46093e52014-12-09 14:59:16 -0800360 return 1
zhizhouy9258b052020-04-15 17:33:46 -0700361 if options.test:
362 print('Cleaning local test directory for this script.')
363 if os.path.exists(TMP_TOOLCHAIN_TEST):
364 shutil.rmtree(TMP_TOOLCHAIN_TEST)
365 os.mkdir(TMP_TOOLCHAIN_TEST)
Yunlian Jiange52838c2015-08-20 14:32:37 -0700366
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800367 fc = ToolchainComparator(options.board, options.remote, options.chromeos_root,
zhizhouy9258b052020-04-15 17:33:46 -0700368 options.weekday, options.patches, options.recipe,
369 options.test, options.noschedv2)
Ting-Yuan Huang6a9a98a2018-03-07 17:35:13 -0800370 return fc.DoAll()
cmtice46093e52014-12-09 14:59:16 -0800371
372
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800373if __name__ == '__main__':
cmtice46093e52014-12-09 14:59:16 -0800374 retval = Main(sys.argv)
375 sys.exit(retval)