blob: 13596d2e29d64f5f2e72b3e6591962e00f818b09 [file] [log] [blame]
Yunlian Jiange84ea3d2016-12-12 11:07:40 -08001#!/usr/bin/env python2
Ting-Yuan Huange5819872016-12-15 14:22:26 -08002#
3# Copyright 2016 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
Yunlian Jiang14cf5962015-12-11 15:50:14 -08006"""Script for running nightly compiler tests on ChromeOS.
cmtice46093e52014-12-09 14:59:16 -08007
8This script launches a buildbot to build ChromeOS with the latest compiler on
9a particular board; then it finds and downloads the trybot image and the
10corresponding official image, and runs crosperf performance tests comparing
11the two. It then generates a report, emails it to the c-compiler-chrome, as
12well as copying the images into the seven-day reports directory.
13"""
14
15# Script to test different toolchains against ChromeOS benchmarks.
Yunlian Jiang14cf5962015-12-11 15:50:14 -080016
17from __future__ import print_function
18
Caroline Ticeeddb0632016-04-14 09:19:02 -070019import argparse
cmticece5ffa42015-02-12 15:18:43 -080020import datetime
cmtice46093e52014-12-09 14:59:16 -080021import os
Luis Lozanoc75fd052016-02-19 17:37:01 -080022import re
cmtice46093e52014-12-09 14:59:16 -080023import sys
24import time
cmtice46093e52014-12-09 14:59:16 -080025
Caroline Ticea8af9a72016-07-20 12:52:59 -070026from cros_utils import command_executer
27from cros_utils import logger
cmtice46093e52014-12-09 14:59:16 -080028
Caroline Ticea8af9a72016-07-20 12:52:59 -070029from cros_utils import buildbot_utils
cmtice46093e52014-12-09 14:59:16 -080030
Manoj Guptac4110352016-12-28 13:47:12 -080031# CL that uses LLVM-Next to build the images (includes chrome).
Manoj Gupta66682c72017-05-24 12:19:57 -070032USE_LLVM_NEXT_PATCH = '513590'
Manoj Guptac4110352016-12-28 13:47:12 -080033
Luis Lozanof2a3ef42015-12-15 13:49:30 -080034CROSTC_ROOT = '/usr/local/google/crostc'
35ROLE_ACCOUNT = 'mobiletc-prebuild'
cmtice46093e52014-12-09 14:59:16 -080036TOOLCHAIN_DIR = os.path.dirname(os.path.realpath(__file__))
Luis Lozanof2a3ef42015-12-15 13:49:30 -080037MAIL_PROGRAM = '~/var/bin/mail-sheriff'
Luis Lozanof2a3ef42015-12-15 13:49:30 -080038PENDING_ARCHIVES_DIR = os.path.join(CROSTC_ROOT, 'pending_archives')
39NIGHTLY_TESTS_DIR = os.path.join(CROSTC_ROOT, 'nightly_test_reports')
40
Ting-Yuan Huange5819872016-12-15 14:22:26 -080041IMAGE_DIR = '{board}-{image_type}'
42IMAGE_VERSION_STR = r'{chrome_version}-{tip}\.{branch}\.{branch_branch}'
43IMAGE_FS = IMAGE_DIR + '/' + IMAGE_VERSION_STR
Luis Lozanoc75fd052016-02-19 17:37:01 -080044TRYBOT_IMAGE_FS = 'trybot-' + IMAGE_FS + '-{build_id}'
45PFQ_IMAGE_FS = IMAGE_FS + '-rc1'
Manoj Guptaaee96b72016-10-24 13:43:28 -070046IMAGE_RE_GROUPS = {
47 'board': r'(?P<board>\S+)',
48 'image_type': r'(?P<image_type>\S+)',
49 'chrome_version': r'(?P<chrome_version>R\d+)',
50 'tip': r'(?P<tip>\d+)',
51 'branch': r'(?P<branch>\d+)',
52 'branch_branch': r'(?P<branch_branch>\d+)',
53 'build_id': r'(?P<build_id>b\d+)'
54}
Luis Lozanoc75fd052016-02-19 17:37:01 -080055TRYBOT_IMAGE_RE = TRYBOT_IMAGE_FS.format(**IMAGE_RE_GROUPS)
56
cmtice46093e52014-12-09 14:59:16 -080057
Yunlian Jiang14cf5962015-12-11 15:50:14 -080058class ToolchainComparator(object):
59 """Class for doing the nightly tests work."""
cmtice46093e52014-12-09 14:59:16 -080060
Luis Lozanof2a3ef42015-12-15 13:49:30 -080061 def __init__(self,
62 board,
63 remotes,
64 chromeos_root,
65 weekday,
66 patches,
67 noschedv2=False):
cmtice46093e52014-12-09 14:59:16 -080068 self._board = board
69 self._remotes = remotes
70 self._chromeos_root = chromeos_root
71 self._base_dir = os.getcwd()
72 self._ce = command_executer.GetCommandExecuter()
73 self._l = logger.GetLogger()
Luis Lozanof2a3ef42015-12-15 13:49:30 -080074 self._build = '%s-release' % board
Manoj Guptad575b8a2017-03-08 10:51:28 -080075 self._patches = patches.split(',') if patches else []
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070076 self._patches_string = '_'.join(str(p) for p in self._patches)
Han Shen43494292015-09-14 10:26:40 -070077 self._noschedv2 = noschedv2
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070078
cmtice46093e52014-12-09 14:59:16 -080079 if not weekday:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080080 self._weekday = time.strftime('%a')
cmtice46093e52014-12-09 14:59:16 -080081 else:
82 self._weekday = weekday
cmtice7f3190b2015-05-22 14:14:51 -070083 timestamp = datetime.datetime.strftime(datetime.datetime.now(),
Luis Lozanof2a3ef42015-12-15 13:49:30 -080084 '%Y-%m-%d_%H:%M:%S')
Manoj Guptaaee96b72016-10-24 13:43:28 -070085 self._reports_dir = os.path.join(
86 NIGHTLY_TESTS_DIR,
87 '%s.%s' % (timestamp, board),)
cmtice46093e52014-12-09 14:59:16 -080088
Luis Lozanoc75fd052016-02-19 17:37:01 -080089 def _GetVanillaImageName(self, trybot_image):
Ting-Yuan Huange5819872016-12-15 14:22:26 -080090 """Given a trybot artifact name, get latest vanilla image name.
cmtice46093e52014-12-09 14:59:16 -080091
Luis Lozano783954f2015-12-21 18:06:29 -080092 Args:
93 trybot_image: artifact name such as
94 'trybot-daisy-release/R40-6394.0.0-b1389'
95
96 Returns:
Ting-Yuan Huange5819872016-12-15 14:22:26 -080097 Latest official image name, e.g. 'daisy-release/R57-9089.0.0'.
cmtice46093e52014-12-09 14:59:16 -080098 """
Luis Lozanoc75fd052016-02-19 17:37:01 -080099 mo = re.search(TRYBOT_IMAGE_RE, trybot_image)
100 assert mo
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800101 dirname = IMAGE_DIR.replace('\\', '').format(**mo.groupdict())
Ting-Yuan Huang99d32c42017-04-24 20:34:43 -0700102 return buildbot_utils.GetLatestImage(self._chromeos_root, dirname)
cmtice46093e52014-12-09 14:59:16 -0800103
Luis Lozanoc75fd052016-02-19 17:37:01 -0800104 def _GetNonAFDOImageName(self, trybot_image):
105 """Given a trybot artifact name, get corresponding non-AFDO image name.
106
107 We get the non-AFDO image from the PFQ builders. This image
108 is not generated for all the boards and, the closest PFQ image
109 was the one build for the previous ChromeOS version (the chrome
110 used in the current version is the one validated in the previous
111 version).
112 The previous ChromeOS does not always exist either. So, we try
113 a couple of versions before.
Luis Lozano783954f2015-12-21 18:06:29 -0800114
115 Args:
116 trybot_image: artifact name such as
117 'trybot-daisy-release/R40-6394.0.0-b1389'
118
119 Returns:
120 Corresponding chrome PFQ image name, e.g.
Luis Lozanoc75fd052016-02-19 17:37:01 -0800121 'daisy-chrome-pfq/R40-6393.0.0-rc1'.
Luis Lozano783954f2015-12-21 18:06:29 -0800122 """
Luis Lozanoc75fd052016-02-19 17:37:01 -0800123 mo = re.search(TRYBOT_IMAGE_RE, trybot_image)
124 assert mo
125 image_dict = mo.groupdict()
126 image_dict['image_type'] = 'chrome-pfq'
127 for _ in xrange(2):
128 image_dict['tip'] = str(int(image_dict['tip']) - 1)
129 nonafdo_image = PFQ_IMAGE_FS.replace('\\', '').format(**image_dict)
130 if buildbot_utils.DoesImageExist(self._chromeos_root, nonafdo_image):
131 return nonafdo_image
132 return ''
Luis Lozano783954f2015-12-21 18:06:29 -0800133
cmtice46093e52014-12-09 14:59:16 -0800134 def _FinishSetup(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800135 """Make sure testing_rsa file is properly set up."""
cmtice46093e52014-12-09 14:59:16 -0800136 # Fix protections on ssh key
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800137 command = ('chmod 600 /var/cache/chromeos-cache/distfiles/target'
138 '/chrome-src-internal/src/third_party/chromite/ssh_keys'
139 '/testing_rsa')
cmtice46093e52014-12-09 14:59:16 -0800140 ret_val = self._ce.ChrootRunCommand(self._chromeos_root, command)
cmtice7f3190b2015-05-22 14:14:51 -0700141 if ret_val != 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800142 raise RuntimeError('chmod for testing_rsa failed')
cmtice46093e52014-12-09 14:59:16 -0800143
Luis Lozano783954f2015-12-21 18:06:29 -0800144 def _TestImages(self, trybot_image, vanilla_image, nonafdo_image):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800145 """Create crosperf experiment file.
cmtice46093e52014-12-09 14:59:16 -0800146
Luis Lozano783954f2015-12-21 18:06:29 -0800147 Given the names of the trybot, vanilla and non-AFDO images, create the
cmtice46093e52014-12-09 14:59:16 -0800148 appropriate crosperf experiment file and launch crosperf on it.
149 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800150 experiment_file_dir = os.path.join(self._chromeos_root, '..', self._weekday)
151 experiment_file_name = '%s_toolchain_experiment.txt' % self._board
Yunlian Jiang2f563562015-08-28 13:54:04 -0700152
Manoj Guptad575b8a2017-03-08 10:51:28 -0800153 compiler_string = 'llvm'
Manoj Guptac4110352016-12-28 13:47:12 -0800154 if USE_LLVM_NEXT_PATCH in self._patches_string:
155 experiment_file_name = '%s_llvm_next_experiment.txt' % self._board
156 compiler_string = 'llvm_next'
Yunlian Jiang2f563562015-08-28 13:54:04 -0700157
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800158 experiment_file = os.path.join(experiment_file_dir, experiment_file_name)
cmtice46093e52014-12-09 14:59:16 -0800159 experiment_header = """
160 board: %s
161 remote: %s
Luis Lozanoe1efeb82015-06-16 16:35:44 -0700162 retries: 1
cmtice46093e52014-12-09 14:59:16 -0800163 """ % (self._board, self._remotes)
164 experiment_tests = """
Luis Lozano1489d642015-12-08 10:08:19 -0800165 benchmark: all_toolchain_perf {
cmtice46093e52014-12-09 14:59:16 -0800166 suite: telemetry_Crosperf
Ting-Yuan Huang83323642017-02-17 12:20:02 -0800167 iterations: 0
Manoj Gupta5a516382017-08-23 12:27:54 -0700168 run_local: False
cmtice46093e52014-12-09 14:59:16 -0800169 }
Caroline Ticee82513b2016-10-27 12:45:15 -0700170
171 benchmark: page_cycler_v2.typical_25 {
172 suite: telemetry_Crosperf
Ting-Yuan Huang83323642017-02-17 12:20:02 -0800173 iterations: 0
Caroline Ticee82513b2016-10-27 12:45:15 -0700174 run_local: False
175 retries: 0
176 }
cmtice46093e52014-12-09 14:59:16 -0800177 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800178
179 with open(experiment_file, 'w') as f:
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800180 f.write(experiment_header)
181 f.write(experiment_tests)
cmtice46093e52014-12-09 14:59:16 -0800182
183 # Now add vanilla to test file.
184 official_image = """
185 vanilla_image {
186 chromeos_root: %s
187 build: %s
Yunlian Jiang8c18be12017-03-20 16:52:33 -0700188 compiler: llvm
cmtice46093e52014-12-09 14:59:16 -0800189 }
190 """ % (self._chromeos_root, vanilla_image)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800191 f.write(official_image)
cmtice46093e52014-12-09 14:59:16 -0800192
Luis Lozano783954f2015-12-21 18:06:29 -0800193 # Now add non-AFDO image to test file.
Luis Lozano439f2b72016-01-08 11:56:02 -0800194 if nonafdo_image:
195 official_nonafdo_image = """
Luis Lozano783954f2015-12-21 18:06:29 -0800196 nonafdo_image {
197 chromeos_root: %s
198 build: %s
Yunlian Jiang8c18be12017-03-20 16:52:33 -0700199 compiler: llvm
Luis Lozano783954f2015-12-21 18:06:29 -0800200 }
201 """ % (self._chromeos_root, nonafdo_image)
Luis Lozano439f2b72016-01-08 11:56:02 -0800202 f.write(official_nonafdo_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800203
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800204 label_string = '%s_trybot_image' % compiler_string
Caroline Tice80eab982015-11-04 14:03:14 -0800205
Manoj Gupta3594db82017-01-31 11:48:57 -0800206 # Reuse autotest files from vanilla image for trybot images
207 autotest_files = os.path.join('/tmp', vanilla_image, 'autotest_files')
cmtice46093e52014-12-09 14:59:16 -0800208 experiment_image = """
Caroline Tice80eab982015-11-04 14:03:14 -0800209 %s {
cmtice46093e52014-12-09 14:59:16 -0800210 chromeos_root: %s
211 build: %s
Manoj Gupta3594db82017-01-31 11:48:57 -0800212 autotest_path: %s
Caroline Ticeddde5052015-09-23 09:43:35 -0700213 compiler: %s
cmtice46093e52014-12-09 14:59:16 -0800214 }
Caroline Tice80eab982015-11-04 14:03:14 -0800215 """ % (label_string, self._chromeos_root, trybot_image,
Manoj Gupta3594db82017-01-31 11:48:57 -0800216 autotest_files, compiler_string)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800217 f.write(experiment_image)
cmtice46093e52014-12-09 14:59:16 -0800218
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800219 crosperf = os.path.join(TOOLCHAIN_DIR, 'crosperf', 'crosperf')
Han Shen43494292015-09-14 10:26:40 -0700220 noschedv2_opts = '--noschedv2' if self._noschedv2 else ''
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800221 command = ('{crosperf} --no_email=True --results_dir={r_dir} '
222 '--json_report=True {noschedv2_opts} {exp_file}').format(
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800223 crosperf=crosperf,
224 r_dir=self._reports_dir,
225 noschedv2_opts=noschedv2_opts,
226 exp_file=experiment_file)
cmticeaa700b02015-06-12 13:26:47 -0700227
cmtice46093e52014-12-09 14:59:16 -0800228 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700229 if ret != 0:
Manoj Guptaaee96b72016-10-24 13:43:28 -0700230 raise RuntimeError('Crosperf execution error!')
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700231 else:
232 # Copy json report to pending archives directory.
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800233 command = 'cp %s/*.json %s/.' % (self._reports_dir, PENDING_ARCHIVES_DIR)
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700234 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700235 return
cmtice46093e52014-12-09 14:59:16 -0800236
cmtice7f3190b2015-05-22 14:14:51 -0700237 def _SendEmail(self):
238 """Find email message generated by crosperf and send it."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800239 filename = os.path.join(self._reports_dir, 'msg_body.html')
cmtice7f3190b2015-05-22 14:14:51 -0700240 if (os.path.exists(filename) and
241 os.path.exists(os.path.expanduser(MAIL_PROGRAM))):
Manoj Guptad575b8a2017-03-08 10:51:28 -0800242 email_title = 'buildbot llvm test results'
Manoj Guptac4110352016-12-28 13:47:12 -0800243 if USE_LLVM_NEXT_PATCH in self._patches_string:
244 email_title = 'buildbot llvm_next test results'
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800245 command = ('cat %s | %s -s "%s, %s" -team -html' %
246 (filename, MAIL_PROGRAM, email_title, self._board))
cmtice7f3190b2015-05-22 14:14:51 -0700247 self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800248
249 def DoAll(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800250 """Main function inside ToolchainComparator class.
cmtice46093e52014-12-09 14:59:16 -0800251
252 Launch trybot, get image names, create crosperf experiment file, run
253 crosperf, and copy images into seven-day report directories.
254 """
cmticece5ffa42015-02-12 15:18:43 -0800255 date_str = datetime.date.today()
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800256 description = 'master_%s_%s_%s' % (self._patches_string, self._build,
Han Shenfe054f12015-02-18 15:00:13 -0800257 date_str)
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800258 build_id, trybot_image = buildbot_utils.GetTrybotImage(
Manoj Guptaaee96b72016-10-24 13:43:28 -0700259 self._chromeos_root,
260 self._build,
261 self._patches,
262 description,
Ting-Yuan Huang0da40e02017-08-18 16:55:02 -0700263 tryjob_flags=['--notests'],
Manoj Guptaaee96b72016-10-24 13:43:28 -0700264 build_toolchain=True)
cmtice46093e52014-12-09 14:59:16 -0800265
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800266 print('trybot_url: \
Manoj Guptac4110352016-12-28 13:47:12 -0800267 https://uberchromegw.corp.google.com/i/chromiumos.tryserver/builders/release/builds/%s'
268 % build_id)
cmticed54f9802015-02-05 11:04:11 -0800269 if len(trybot_image) == 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800270 self._l.LogError('Unable to find trybot_image for %s!' % description)
Luis Lozano7f20acb2015-11-04 17:15:08 -0800271 return 1
Luis Lozano783954f2015-12-21 18:06:29 -0800272
Luis Lozanoc75fd052016-02-19 17:37:01 -0800273 vanilla_image = self._GetVanillaImageName(trybot_image)
274 nonafdo_image = self._GetNonAFDOImageName(trybot_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800275
276 print('trybot_image: %s' % trybot_image)
277 print('vanilla_image: %s' % vanilla_image)
278 print('nonafdo_image: %s' % nonafdo_image)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800279
cmtice46093e52014-12-09 14:59:16 -0800280 if os.getlogin() == ROLE_ACCOUNT:
281 self._FinishSetup()
282
Luis Lozano783954f2015-12-21 18:06:29 -0800283 self._TestImages(trybot_image, vanilla_image, nonafdo_image)
cmtice7f3190b2015-05-22 14:14:51 -0700284 self._SendEmail()
cmtice46093e52014-12-09 14:59:16 -0800285 return 0
286
287
288def Main(argv):
289 """The main function."""
290
291 # Common initializations
292 command_executer.InitCommandExecuter()
Caroline Ticeeddb0632016-04-14 09:19:02 -0700293 parser = argparse.ArgumentParser()
Manoj Guptaaee96b72016-10-24 13:43:28 -0700294 parser.add_argument(
295 '--remote', dest='remote', help='Remote machines to run tests on.')
296 parser.add_argument(
297 '--board', dest='board', default='x86-zgb', help='The target board.')
298 parser.add_argument(
299 '--chromeos_root',
300 dest='chromeos_root',
301 help='The chromeos root from which to run tests.')
302 parser.add_argument(
303 '--weekday',
304 default='',
305 dest='weekday',
306 help='The day of the week for which to run tests.')
307 parser.add_argument(
308 '--patch',
309 dest='patches',
310 help='The patches to use for the testing, '
311 "seprate the patch numbers with ',' "
312 'for more than one patches.')
313 parser.add_argument(
314 '--noschedv2',
315 dest='noschedv2',
316 action='store_true',
317 default=False,
318 help='Pass --noschedv2 to crosperf.')
Han Shen36413122015-08-28 11:05:40 -0700319
Caroline Ticeeddb0632016-04-14 09:19:02 -0700320 options = parser.parse_args(argv[1:])
cmtice46093e52014-12-09 14:59:16 -0800321 if not options.board:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800322 print('Please give a board.')
cmtice46093e52014-12-09 14:59:16 -0800323 return 1
324 if not options.remote:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800325 print('Please give at least one remote machine.')
cmtice46093e52014-12-09 14:59:16 -0800326 return 1
327 if not options.chromeos_root:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800328 print('Please specify the ChromeOS root directory.')
cmtice46093e52014-12-09 14:59:16 -0800329 return 1
Yunlian Jiange52838c2015-08-20 14:32:37 -0700330
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800331 fc = ToolchainComparator(options.board, options.remote, options.chromeos_root,
Manoj Guptad575b8a2017-03-08 10:51:28 -0800332 options.weekday, options.patches, options.noschedv2)
cmtice46093e52014-12-09 14:59:16 -0800333 return fc.DoAll()
334
335
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800336if __name__ == '__main__':
cmtice46093e52014-12-09 14:59:16 -0800337 retval = Main(sys.argv)
338 sys.exit(retval)