blob: 03b7bff54ab6cb49a08b81fb7a2dc83fe3c279f3 [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.
6
Yunlian Jiang14cf5962015-12-11 15:50:14 -08007"""Script for running nightly compiler tests on ChromeOS.
cmtice46093e52014-12-09 14:59:16 -08008
9This script launches a buildbot to build ChromeOS with the latest compiler on
10a particular board; then it finds and downloads the trybot image and the
11corresponding official image, and runs crosperf performance tests comparing
12the two. It then generates a report, emails it to the c-compiler-chrome, as
13well as copying the images into the seven-day reports directory.
14"""
15
16# Script to test different toolchains against ChromeOS benchmarks.
Yunlian Jiang14cf5962015-12-11 15:50:14 -080017
18from __future__ import print_function
19
Caroline Ticeeddb0632016-04-14 09:19:02 -070020import argparse
cmticece5ffa42015-02-12 15:18:43 -080021import datetime
cmtice46093e52014-12-09 14:59:16 -080022import os
Luis Lozanoc75fd052016-02-19 17:37:01 -080023import re
cmtice46093e52014-12-09 14:59:16 -080024import sys
25import time
cmtice46093e52014-12-09 14:59:16 -080026
Caroline Ticea8af9a72016-07-20 12:52:59 -070027from cros_utils import command_executer
28from cros_utils import logger
cmtice46093e52014-12-09 14:59:16 -080029
Caroline Ticea8af9a72016-07-20 12:52:59 -070030from cros_utils import buildbot_utils
cmtice46093e52014-12-09 14:59:16 -080031
32# CL that updated GCC ebuilds to use 'next_gcc'.
Luis Lozanof2a3ef42015-12-15 13:49:30 -080033USE_NEXT_GCC_PATCH = '230260'
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070034
Yunlian Jiang2f563562015-08-28 13:54:04 -070035# CL that uses LLVM to build the peppy image.
Luis Lozanof2a3ef42015-12-15 13:49:30 -080036USE_LLVM_PATCH = '295217'
Yunlian Jiang2f563562015-08-28 13:54:04 -070037
Luis Lozanof2a3ef42015-12-15 13:49:30 -080038CROSTC_ROOT = '/usr/local/google/crostc'
39ROLE_ACCOUNT = 'mobiletc-prebuild'
cmtice46093e52014-12-09 14:59:16 -080040TOOLCHAIN_DIR = os.path.dirname(os.path.realpath(__file__))
Luis Lozanof2a3ef42015-12-15 13:49:30 -080041MAIL_PROGRAM = '~/var/bin/mail-sheriff'
Luis Lozanof2a3ef42015-12-15 13:49:30 -080042PENDING_ARCHIVES_DIR = os.path.join(CROSTC_ROOT, 'pending_archives')
43NIGHTLY_TESTS_DIR = os.path.join(CROSTC_ROOT, 'nightly_test_reports')
44
Ting-Yuan Huange5819872016-12-15 14:22:26 -080045IMAGE_DIR = '{board}-{image_type}'
46IMAGE_VERSION_STR = r'{chrome_version}-{tip}\.{branch}\.{branch_branch}'
47IMAGE_FS = IMAGE_DIR + '/' + IMAGE_VERSION_STR
Luis Lozanoc75fd052016-02-19 17:37:01 -080048TRYBOT_IMAGE_FS = 'trybot-' + IMAGE_FS + '-{build_id}'
49PFQ_IMAGE_FS = IMAGE_FS + '-rc1'
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
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()
Luis Lozanof2a3ef42015-12-15 13:49:30 -080078 self._build = '%s-release' % board
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070079 self._patches = patches.split(',')
80 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,
91 '%s.%s' % (timestamp, board),)
cmtice46093e52014-12-09 14:59:16 -080092
Luis Lozanoc75fd052016-02-19 17:37:01 -080093 def _GetVanillaImageName(self, trybot_image):
Ting-Yuan Huange5819872016-12-15 14:22:26 -080094 """Given a trybot artifact name, get latest vanilla image name.
cmtice46093e52014-12-09 14:59:16 -080095
Luis Lozano783954f2015-12-21 18:06:29 -080096 Args:
97 trybot_image: artifact name such as
98 'trybot-daisy-release/R40-6394.0.0-b1389'
99
100 Returns:
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800101 Latest official image name, e.g. 'daisy-release/R57-9089.0.0'.
cmtice46093e52014-12-09 14:59:16 -0800102 """
Luis Lozanoc75fd052016-02-19 17:37:01 -0800103 mo = re.search(TRYBOT_IMAGE_RE, trybot_image)
104 assert mo
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800105 dirname = IMAGE_DIR.replace('\\', '').format(**mo.groupdict())
106 version = buildbot_utils.GetGSContent(self._chromeos_root,
107 dirname + '/LATEST-master')
108 return dirname + '/' + version
cmtice46093e52014-12-09 14:59:16 -0800109
Luis Lozanoc75fd052016-02-19 17:37:01 -0800110 def _GetNonAFDOImageName(self, trybot_image):
111 """Given a trybot artifact name, get corresponding non-AFDO image name.
112
113 We get the non-AFDO image from the PFQ builders. This image
114 is not generated for all the boards and, the closest PFQ image
115 was the one build for the previous ChromeOS version (the chrome
116 used in the current version is the one validated in the previous
117 version).
118 The previous ChromeOS does not always exist either. So, we try
119 a couple of versions before.
Luis Lozano783954f2015-12-21 18:06:29 -0800120
121 Args:
122 trybot_image: artifact name such as
123 'trybot-daisy-release/R40-6394.0.0-b1389'
124
125 Returns:
126 Corresponding chrome PFQ image name, e.g.
Luis Lozanoc75fd052016-02-19 17:37:01 -0800127 'daisy-chrome-pfq/R40-6393.0.0-rc1'.
Luis Lozano783954f2015-12-21 18:06:29 -0800128 """
Luis Lozanoc75fd052016-02-19 17:37:01 -0800129 mo = re.search(TRYBOT_IMAGE_RE, trybot_image)
130 assert mo
131 image_dict = mo.groupdict()
132 image_dict['image_type'] = 'chrome-pfq'
133 for _ in xrange(2):
134 image_dict['tip'] = str(int(image_dict['tip']) - 1)
135 nonafdo_image = PFQ_IMAGE_FS.replace('\\', '').format(**image_dict)
136 if buildbot_utils.DoesImageExist(self._chromeos_root, nonafdo_image):
137 return nonafdo_image
138 return ''
Luis Lozano783954f2015-12-21 18:06:29 -0800139
cmtice46093e52014-12-09 14:59:16 -0800140 def _FinishSetup(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800141 """Make sure testing_rsa file is properly set up."""
cmtice46093e52014-12-09 14:59:16 -0800142 # Fix protections on ssh key
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800143 command = ('chmod 600 /var/cache/chromeos-cache/distfiles/target'
144 '/chrome-src-internal/src/third_party/chromite/ssh_keys'
145 '/testing_rsa')
cmtice46093e52014-12-09 14:59:16 -0800146 ret_val = self._ce.ChrootRunCommand(self._chromeos_root, command)
cmtice7f3190b2015-05-22 14:14:51 -0700147 if ret_val != 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800148 raise RuntimeError('chmod for testing_rsa failed')
cmtice46093e52014-12-09 14:59:16 -0800149
Luis Lozano783954f2015-12-21 18:06:29 -0800150 def _TestImages(self, trybot_image, vanilla_image, nonafdo_image):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800151 """Create crosperf experiment file.
cmtice46093e52014-12-09 14:59:16 -0800152
Luis Lozano783954f2015-12-21 18:06:29 -0800153 Given the names of the trybot, vanilla and non-AFDO images, create the
cmtice46093e52014-12-09 14:59:16 -0800154 appropriate crosperf experiment file and launch crosperf on it.
155 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800156 experiment_file_dir = os.path.join(self._chromeos_root, '..', self._weekday)
157 experiment_file_name = '%s_toolchain_experiment.txt' % self._board
Yunlian Jiang2f563562015-08-28 13:54:04 -0700158
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800159 compiler_string = 'gcc'
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800160 if USE_LLVM_PATCH in self._patches_string:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800161 experiment_file_name = '%s_llvm_experiment.txt' % self._board
162 compiler_string = 'llvm'
Yunlian Jiang2f563562015-08-28 13:54:04 -0700163
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800164 experiment_file = os.path.join(experiment_file_dir, experiment_file_name)
cmtice46093e52014-12-09 14:59:16 -0800165 experiment_header = """
166 board: %s
167 remote: %s
Luis Lozanoe1efeb82015-06-16 16:35:44 -0700168 retries: 1
cmtice46093e52014-12-09 14:59:16 -0800169 """ % (self._board, self._remotes)
170 experiment_tests = """
Luis Lozano1489d642015-12-08 10:08:19 -0800171 benchmark: all_toolchain_perf {
cmtice46093e52014-12-09 14:59:16 -0800172 suite: telemetry_Crosperf
173 iterations: 3
174 }
Caroline Ticee82513b2016-10-27 12:45:15 -0700175
176 benchmark: page_cycler_v2.typical_25 {
177 suite: telemetry_Crosperf
178 iterations: 2
179 run_local: False
180 retries: 0
181 }
cmtice46093e52014-12-09 14:59:16 -0800182 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800183
184 with open(experiment_file, 'w') as f:
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800185 f.write(experiment_header)
186 f.write(experiment_tests)
cmtice46093e52014-12-09 14:59:16 -0800187
188 # Now add vanilla to test file.
189 official_image = """
190 vanilla_image {
191 chromeos_root: %s
192 build: %s
Caroline Ticeddde5052015-09-23 09:43:35 -0700193 compiler: gcc
cmtice46093e52014-12-09 14:59:16 -0800194 }
195 """ % (self._chromeos_root, vanilla_image)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800196 f.write(official_image)
cmtice46093e52014-12-09 14:59:16 -0800197
Luis Lozano783954f2015-12-21 18:06:29 -0800198 # Now add non-AFDO image to test file.
Luis Lozano439f2b72016-01-08 11:56:02 -0800199 if nonafdo_image:
200 official_nonafdo_image = """
Luis Lozano783954f2015-12-21 18:06:29 -0800201 nonafdo_image {
202 chromeos_root: %s
203 build: %s
204 compiler: gcc
205 }
206 """ % (self._chromeos_root, nonafdo_image)
Luis Lozano439f2b72016-01-08 11:56:02 -0800207 f.write(official_nonafdo_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800208
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800209 label_string = '%s_trybot_image' % compiler_string
Caroline Tice80eab982015-11-04 14:03:14 -0800210 if USE_NEXT_GCC_PATCH in self._patches:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800211 label_string = 'gcc_next_trybot_image'
Caroline Tice80eab982015-11-04 14:03:14 -0800212
cmtice46093e52014-12-09 14:59:16 -0800213 experiment_image = """
Caroline Tice80eab982015-11-04 14:03:14 -0800214 %s {
cmtice46093e52014-12-09 14:59:16 -0800215 chromeos_root: %s
216 build: %s
Caroline Ticeddde5052015-09-23 09:43:35 -0700217 compiler: %s
cmtice46093e52014-12-09 14:59:16 -0800218 }
Caroline Tice80eab982015-11-04 14:03:14 -0800219 """ % (label_string, self._chromeos_root, trybot_image,
220 compiler_string)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800221 f.write(experiment_image)
cmtice46093e52014-12-09 14:59:16 -0800222
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800223 crosperf = os.path.join(TOOLCHAIN_DIR, 'crosperf', 'crosperf')
Han Shen43494292015-09-14 10:26:40 -0700224 noschedv2_opts = '--noschedv2' if self._noschedv2 else ''
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800225 command = ('{crosperf} --no_email=True --results_dir={r_dir} '
226 '--json_report=True {noschedv2_opts} {exp_file}').format(
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800227 crosperf=crosperf,
228 r_dir=self._reports_dir,
229 noschedv2_opts=noschedv2_opts,
230 exp_file=experiment_file)
cmticeaa700b02015-06-12 13:26:47 -0700231
cmtice46093e52014-12-09 14:59:16 -0800232 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700233 if ret != 0:
Manoj Guptaaee96b72016-10-24 13:43:28 -0700234 raise RuntimeError('Crosperf execution error!')
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700235 else:
236 # Copy json report to pending archives directory.
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800237 command = 'cp %s/*.json %s/.' % (self._reports_dir, PENDING_ARCHIVES_DIR)
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700238 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700239 return
cmtice46093e52014-12-09 14:59:16 -0800240
cmtice7f3190b2015-05-22 14:14:51 -0700241 def _SendEmail(self):
242 """Find email message generated by crosperf and send it."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800243 filename = os.path.join(self._reports_dir, 'msg_body.html')
cmtice7f3190b2015-05-22 14:14:51 -0700244 if (os.path.exists(filename) and
245 os.path.exists(os.path.expanduser(MAIL_PROGRAM))):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800246 email_title = 'buildbot test results'
Yunlian Jiang2f563562015-08-28 13:54:04 -0700247 if self._patches_string == USE_LLVM_PATCH:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800248 email_title = 'buildbot llvm test results'
249 command = ('cat %s | %s -s "%s, %s" -team -html' %
250 (filename, MAIL_PROGRAM, email_title, self._board))
cmtice7f3190b2015-05-22 14:14:51 -0700251 self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800252
253 def DoAll(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800254 """Main function inside ToolchainComparator class.
cmtice46093e52014-12-09 14:59:16 -0800255
256 Launch trybot, get image names, create crosperf experiment file, run
257 crosperf, and copy images into seven-day report directories.
258 """
cmticece5ffa42015-02-12 15:18:43 -0800259 date_str = datetime.date.today()
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800260 description = 'master_%s_%s_%s' % (self._patches_string, self._build,
Han Shenfe054f12015-02-18 15:00:13 -0800261 date_str)
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800262 build_id, trybot_image = buildbot_utils.GetTrybotImage(
Manoj Guptaaee96b72016-10-24 13:43:28 -0700263 self._chromeos_root,
264 self._build,
265 self._patches,
266 description,
267 other_flags=['--notests'],
268 build_toolchain=True)
cmtice46093e52014-12-09 14:59:16 -0800269
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800270 print('trybot_url: \
271 https://uberchromegw.corp.google.com/i/chromiumos.tryserver/builders/release/builds/%s' \
272 % build_id)
cmticed54f9802015-02-05 11:04:11 -0800273 if len(trybot_image) == 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800274 self._l.LogError('Unable to find trybot_image for %s!' % description)
Luis Lozano7f20acb2015-11-04 17:15:08 -0800275 return 1
Luis Lozano783954f2015-12-21 18:06:29 -0800276
Luis Lozanoc75fd052016-02-19 17:37:01 -0800277 vanilla_image = self._GetVanillaImageName(trybot_image)
278 nonafdo_image = self._GetNonAFDOImageName(trybot_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800279
280 print('trybot_image: %s' % trybot_image)
281 print('vanilla_image: %s' % vanilla_image)
282 print('nonafdo_image: %s' % nonafdo_image)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800283
cmtice46093e52014-12-09 14:59:16 -0800284 if os.getlogin() == ROLE_ACCOUNT:
285 self._FinishSetup()
286
Luis Lozano783954f2015-12-21 18:06:29 -0800287 self._TestImages(trybot_image, vanilla_image, nonafdo_image)
cmtice7f3190b2015-05-22 14:14:51 -0700288 self._SendEmail()
cmtice46093e52014-12-09 14:59:16 -0800289 return 0
290
291
292def Main(argv):
293 """The main function."""
294
295 # Common initializations
296 command_executer.InitCommandExecuter()
Caroline Ticeeddb0632016-04-14 09:19:02 -0700297 parser = argparse.ArgumentParser()
Manoj Guptaaee96b72016-10-24 13:43:28 -0700298 parser.add_argument(
299 '--remote', dest='remote', help='Remote machines to run tests on.')
300 parser.add_argument(
301 '--board', dest='board', default='x86-zgb', help='The target board.')
302 parser.add_argument(
303 '--chromeos_root',
304 dest='chromeos_root',
305 help='The chromeos root from which to run tests.')
306 parser.add_argument(
307 '--weekday',
308 default='',
309 dest='weekday',
310 help='The day of the week for which to run tests.')
311 parser.add_argument(
312 '--patch',
313 dest='patches',
314 help='The patches to use for the testing, '
315 "seprate the patch numbers with ',' "
316 'for more than one patches.')
317 parser.add_argument(
318 '--noschedv2',
319 dest='noschedv2',
320 action='store_true',
321 default=False,
322 help='Pass --noschedv2 to crosperf.')
Han Shen36413122015-08-28 11:05:40 -0700323
Caroline Ticeeddb0632016-04-14 09:19:02 -0700324 options = parser.parse_args(argv[1:])
cmtice46093e52014-12-09 14:59:16 -0800325 if not options.board:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800326 print('Please give a board.')
cmtice46093e52014-12-09 14:59:16 -0800327 return 1
328 if not options.remote:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800329 print('Please give at least one remote machine.')
cmtice46093e52014-12-09 14:59:16 -0800330 return 1
331 if not options.chromeos_root:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800332 print('Please specify the ChromeOS root directory.')
cmtice46093e52014-12-09 14:59:16 -0800333 return 1
Yunlian Jiang76259e62015-08-21 08:44:31 -0700334 if options.patches:
Yunlian Jiang3c6e4672015-08-24 15:58:22 -0700335 patches = options.patches
336 else:
337 patches = USE_NEXT_GCC_PATCH
Yunlian Jiange52838c2015-08-20 14:32:37 -0700338
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800339 fc = ToolchainComparator(options.board, options.remote, options.chromeos_root,
340 options.weekday, patches, options.noschedv2)
cmtice46093e52014-12-09 14:59:16 -0800341 return fc.DoAll()
342
343
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800344if __name__ == '__main__':
cmtice46093e52014-12-09 14:59:16 -0800345 retval = Main(sys.argv)
346 sys.exit(retval)