blob: 028d7f1a2c637f78dc248178c1b85f1ca9dd2f13 [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
31# CL that updated GCC ebuilds to use 'next_gcc'.
Luis Lozanof2a3ef42015-12-15 13:49:30 -080032USE_NEXT_GCC_PATCH = '230260'
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070033
Yunlian Jiang2f563562015-08-28 13:54:04 -070034# CL that uses LLVM to build the peppy image.
Luis Lozanof2a3ef42015-12-15 13:49:30 -080035USE_LLVM_PATCH = '295217'
Yunlian Jiang2f563562015-08-28 13:54:04 -070036
Manoj Guptac4110352016-12-28 13:47:12 -080037# CL that uses LLVM-Next to build the images (includes chrome).
38USE_LLVM_NEXT_PATCH = '424123'
39
Luis Lozanof2a3ef42015-12-15 13:49:30 -080040CROSTC_ROOT = '/usr/local/google/crostc'
41ROLE_ACCOUNT = 'mobiletc-prebuild'
cmtice46093e52014-12-09 14:59:16 -080042TOOLCHAIN_DIR = os.path.dirname(os.path.realpath(__file__))
Luis Lozanof2a3ef42015-12-15 13:49:30 -080043MAIL_PROGRAM = '~/var/bin/mail-sheriff'
Luis Lozanof2a3ef42015-12-15 13:49:30 -080044PENDING_ARCHIVES_DIR = os.path.join(CROSTC_ROOT, 'pending_archives')
45NIGHTLY_TESTS_DIR = os.path.join(CROSTC_ROOT, 'nightly_test_reports')
46
Ting-Yuan Huange5819872016-12-15 14:22:26 -080047IMAGE_DIR = '{board}-{image_type}'
48IMAGE_VERSION_STR = r'{chrome_version}-{tip}\.{branch}\.{branch_branch}'
49IMAGE_FS = IMAGE_DIR + '/' + IMAGE_VERSION_STR
Luis Lozanoc75fd052016-02-19 17:37:01 -080050TRYBOT_IMAGE_FS = 'trybot-' + IMAGE_FS + '-{build_id}'
51PFQ_IMAGE_FS = IMAGE_FS + '-rc1'
Manoj Guptaaee96b72016-10-24 13:43:28 -070052IMAGE_RE_GROUPS = {
53 'board': r'(?P<board>\S+)',
54 'image_type': r'(?P<image_type>\S+)',
55 'chrome_version': r'(?P<chrome_version>R\d+)',
56 'tip': r'(?P<tip>\d+)',
57 'branch': r'(?P<branch>\d+)',
58 'branch_branch': r'(?P<branch_branch>\d+)',
59 'build_id': r'(?P<build_id>b\d+)'
60}
Luis Lozanoc75fd052016-02-19 17:37:01 -080061TRYBOT_IMAGE_RE = TRYBOT_IMAGE_FS.format(**IMAGE_RE_GROUPS)
62
cmtice46093e52014-12-09 14:59:16 -080063
Yunlian Jiang14cf5962015-12-11 15:50:14 -080064class ToolchainComparator(object):
65 """Class for doing the nightly tests work."""
cmtice46093e52014-12-09 14:59:16 -080066
Luis Lozanof2a3ef42015-12-15 13:49:30 -080067 def __init__(self,
68 board,
69 remotes,
70 chromeos_root,
71 weekday,
72 patches,
73 noschedv2=False):
cmtice46093e52014-12-09 14:59:16 -080074 self._board = board
75 self._remotes = remotes
76 self._chromeos_root = chromeos_root
77 self._base_dir = os.getcwd()
78 self._ce = command_executer.GetCommandExecuter()
79 self._l = logger.GetLogger()
Luis Lozanof2a3ef42015-12-15 13:49:30 -080080 self._build = '%s-release' % board
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070081 self._patches = patches.split(',')
82 self._patches_string = '_'.join(str(p) for p in self._patches)
Han Shen43494292015-09-14 10:26:40 -070083 self._noschedv2 = noschedv2
Yunlian Jiang3c6e4672015-08-24 15:58:22 -070084
cmtice46093e52014-12-09 14:59:16 -080085 if not weekday:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080086 self._weekday = time.strftime('%a')
cmtice46093e52014-12-09 14:59:16 -080087 else:
88 self._weekday = weekday
cmtice7f3190b2015-05-22 14:14:51 -070089 timestamp = datetime.datetime.strftime(datetime.datetime.now(),
Luis Lozanof2a3ef42015-12-15 13:49:30 -080090 '%Y-%m-%d_%H:%M:%S')
Manoj Guptaaee96b72016-10-24 13:43:28 -070091 self._reports_dir = os.path.join(
92 NIGHTLY_TESTS_DIR,
93 '%s.%s' % (timestamp, board),)
cmtice46093e52014-12-09 14:59:16 -080094
Luis Lozanoc75fd052016-02-19 17:37:01 -080095 def _GetVanillaImageName(self, trybot_image):
Ting-Yuan Huange5819872016-12-15 14:22:26 -080096 """Given a trybot artifact name, get latest vanilla image name.
cmtice46093e52014-12-09 14:59:16 -080097
Luis Lozano783954f2015-12-21 18:06:29 -080098 Args:
99 trybot_image: artifact name such as
100 'trybot-daisy-release/R40-6394.0.0-b1389'
101
102 Returns:
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800103 Latest official image name, e.g. 'daisy-release/R57-9089.0.0'.
cmtice46093e52014-12-09 14:59:16 -0800104 """
Luis Lozanoc75fd052016-02-19 17:37:01 -0800105 mo = re.search(TRYBOT_IMAGE_RE, trybot_image)
106 assert mo
Ting-Yuan Huange5819872016-12-15 14:22:26 -0800107 dirname = IMAGE_DIR.replace('\\', '').format(**mo.groupdict())
108 version = buildbot_utils.GetGSContent(self._chromeos_root,
109 dirname + '/LATEST-master')
110 return dirname + '/' + version
cmtice46093e52014-12-09 14:59:16 -0800111
Luis Lozanoc75fd052016-02-19 17:37:01 -0800112 def _GetNonAFDOImageName(self, trybot_image):
113 """Given a trybot artifact name, get corresponding non-AFDO image name.
114
115 We get the non-AFDO image from the PFQ builders. This image
116 is not generated for all the boards and, the closest PFQ image
117 was the one build for the previous ChromeOS version (the chrome
118 used in the current version is the one validated in the previous
119 version).
120 The previous ChromeOS does not always exist either. So, we try
121 a couple of versions before.
Luis Lozano783954f2015-12-21 18:06:29 -0800122
123 Args:
124 trybot_image: artifact name such as
125 'trybot-daisy-release/R40-6394.0.0-b1389'
126
127 Returns:
128 Corresponding chrome PFQ image name, e.g.
Luis Lozanoc75fd052016-02-19 17:37:01 -0800129 'daisy-chrome-pfq/R40-6393.0.0-rc1'.
Luis Lozano783954f2015-12-21 18:06:29 -0800130 """
Luis Lozanoc75fd052016-02-19 17:37:01 -0800131 mo = re.search(TRYBOT_IMAGE_RE, trybot_image)
132 assert mo
133 image_dict = mo.groupdict()
134 image_dict['image_type'] = 'chrome-pfq'
135 for _ in xrange(2):
136 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
cmtice46093e52014-12-09 14:59:16 -0800142 def _FinishSetup(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800143 """Make sure testing_rsa file is properly set up."""
cmtice46093e52014-12-09 14:59:16 -0800144 # Fix protections on ssh key
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800145 command = ('chmod 600 /var/cache/chromeos-cache/distfiles/target'
146 '/chrome-src-internal/src/third_party/chromite/ssh_keys'
147 '/testing_rsa')
cmtice46093e52014-12-09 14:59:16 -0800148 ret_val = self._ce.ChrootRunCommand(self._chromeos_root, command)
cmtice7f3190b2015-05-22 14:14:51 -0700149 if ret_val != 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800150 raise RuntimeError('chmod for testing_rsa failed')
cmtice46093e52014-12-09 14:59:16 -0800151
Luis Lozano783954f2015-12-21 18:06:29 -0800152 def _TestImages(self, trybot_image, vanilla_image, nonafdo_image):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800153 """Create crosperf experiment file.
cmtice46093e52014-12-09 14:59:16 -0800154
Luis Lozano783954f2015-12-21 18:06:29 -0800155 Given the names of the trybot, vanilla and non-AFDO images, create the
cmtice46093e52014-12-09 14:59:16 -0800156 appropriate crosperf experiment file and launch crosperf on it.
157 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800158 experiment_file_dir = os.path.join(self._chromeos_root, '..', self._weekday)
159 experiment_file_name = '%s_toolchain_experiment.txt' % self._board
Yunlian Jiang2f563562015-08-28 13:54:04 -0700160
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800161 compiler_string = 'gcc'
Manoj Guptac4110352016-12-28 13:47:12 -0800162 if USE_LLVM_NEXT_PATCH in self._patches_string:
163 experiment_file_name = '%s_llvm_next_experiment.txt' % self._board
164 compiler_string = 'llvm_next'
165 elif USE_LLVM_PATCH in self._patches_string:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800166 experiment_file_name = '%s_llvm_experiment.txt' % self._board
167 compiler_string = 'llvm'
Yunlian Jiang2f563562015-08-28 13:54:04 -0700168
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800169 experiment_file = os.path.join(experiment_file_dir, experiment_file_name)
cmtice46093e52014-12-09 14:59:16 -0800170 experiment_header = """
171 board: %s
172 remote: %s
Luis Lozanoe1efeb82015-06-16 16:35:44 -0700173 retries: 1
cmtice46093e52014-12-09 14:59:16 -0800174 """ % (self._board, self._remotes)
175 experiment_tests = """
Luis Lozano1489d642015-12-08 10:08:19 -0800176 benchmark: all_toolchain_perf {
cmtice46093e52014-12-09 14:59:16 -0800177 suite: telemetry_Crosperf
Ting-Yuan Huang83323642017-02-17 12:20:02 -0800178 iterations: 0
cmtice46093e52014-12-09 14:59:16 -0800179 }
Caroline Ticee82513b2016-10-27 12:45:15 -0700180
181 benchmark: page_cycler_v2.typical_25 {
182 suite: telemetry_Crosperf
Ting-Yuan Huang83323642017-02-17 12:20:02 -0800183 iterations: 0
Caroline Ticee82513b2016-10-27 12:45:15 -0700184 run_local: False
185 retries: 0
186 }
cmtice46093e52014-12-09 14:59:16 -0800187 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800188
189 with open(experiment_file, 'w') as f:
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800190 f.write(experiment_header)
191 f.write(experiment_tests)
cmtice46093e52014-12-09 14:59:16 -0800192
193 # Now add vanilla to test file.
194 official_image = """
195 vanilla_image {
196 chromeos_root: %s
197 build: %s
Caroline Ticeddde5052015-09-23 09:43:35 -0700198 compiler: gcc
cmtice46093e52014-12-09 14:59:16 -0800199 }
200 """ % (self._chromeos_root, vanilla_image)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800201 f.write(official_image)
cmtice46093e52014-12-09 14:59:16 -0800202
Luis Lozano783954f2015-12-21 18:06:29 -0800203 # Now add non-AFDO image to test file.
Luis Lozano439f2b72016-01-08 11:56:02 -0800204 if nonafdo_image:
205 official_nonafdo_image = """
Luis Lozano783954f2015-12-21 18:06:29 -0800206 nonafdo_image {
207 chromeos_root: %s
208 build: %s
209 compiler: gcc
210 }
211 """ % (self._chromeos_root, nonafdo_image)
Luis Lozano439f2b72016-01-08 11:56:02 -0800212 f.write(official_nonafdo_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800213
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800214 label_string = '%s_trybot_image' % compiler_string
Caroline Tice80eab982015-11-04 14:03:14 -0800215 if USE_NEXT_GCC_PATCH in self._patches:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800216 label_string = 'gcc_next_trybot_image'
Caroline Tice80eab982015-11-04 14:03:14 -0800217
Manoj Gupta3594db82017-01-31 11:48:57 -0800218 # Reuse autotest files from vanilla image for trybot images
219 autotest_files = os.path.join('/tmp', vanilla_image, 'autotest_files')
cmtice46093e52014-12-09 14:59:16 -0800220 experiment_image = """
Caroline Tice80eab982015-11-04 14:03:14 -0800221 %s {
cmtice46093e52014-12-09 14:59:16 -0800222 chromeos_root: %s
223 build: %s
Manoj Gupta3594db82017-01-31 11:48:57 -0800224 autotest_path: %s
Caroline Ticeddde5052015-09-23 09:43:35 -0700225 compiler: %s
cmtice46093e52014-12-09 14:59:16 -0800226 }
Caroline Tice80eab982015-11-04 14:03:14 -0800227 """ % (label_string, self._chromeos_root, trybot_image,
Manoj Gupta3594db82017-01-31 11:48:57 -0800228 autotest_files, compiler_string)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800229 f.write(experiment_image)
cmtice46093e52014-12-09 14:59:16 -0800230
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800231 crosperf = os.path.join(TOOLCHAIN_DIR, 'crosperf', 'crosperf')
Han Shen43494292015-09-14 10:26:40 -0700232 noschedv2_opts = '--noschedv2' if self._noschedv2 else ''
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800233 command = ('{crosperf} --no_email=True --results_dir={r_dir} '
234 '--json_report=True {noschedv2_opts} {exp_file}').format(
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800235 crosperf=crosperf,
236 r_dir=self._reports_dir,
237 noschedv2_opts=noschedv2_opts,
238 exp_file=experiment_file)
cmticeaa700b02015-06-12 13:26:47 -0700239
cmtice46093e52014-12-09 14:59:16 -0800240 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700241 if ret != 0:
Manoj Guptaaee96b72016-10-24 13:43:28 -0700242 raise RuntimeError('Crosperf execution error!')
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700243 else:
244 # Copy json report to pending archives directory.
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800245 command = 'cp %s/*.json %s/.' % (self._reports_dir, PENDING_ARCHIVES_DIR)
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700246 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700247 return
cmtice46093e52014-12-09 14:59:16 -0800248
cmtice7f3190b2015-05-22 14:14:51 -0700249 def _SendEmail(self):
250 """Find email message generated by crosperf and send it."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800251 filename = os.path.join(self._reports_dir, 'msg_body.html')
cmtice7f3190b2015-05-22 14:14:51 -0700252 if (os.path.exists(filename) and
253 os.path.exists(os.path.expanduser(MAIL_PROGRAM))):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800254 email_title = 'buildbot test results'
Manoj Guptac4110352016-12-28 13:47:12 -0800255 if USE_LLVM_NEXT_PATCH in self._patches_string:
256 email_title = 'buildbot llvm_next test results'
257 elif USE_LLVM_PATCH in self._patches_string:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800258 email_title = 'buildbot llvm test results'
259 command = ('cat %s | %s -s "%s, %s" -team -html' %
260 (filename, MAIL_PROGRAM, email_title, self._board))
cmtice7f3190b2015-05-22 14:14:51 -0700261 self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800262
263 def DoAll(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800264 """Main function inside ToolchainComparator class.
cmtice46093e52014-12-09 14:59:16 -0800265
266 Launch trybot, get image names, create crosperf experiment file, run
267 crosperf, and copy images into seven-day report directories.
268 """
cmticece5ffa42015-02-12 15:18:43 -0800269 date_str = datetime.date.today()
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800270 description = 'master_%s_%s_%s' % (self._patches_string, self._build,
Han Shenfe054f12015-02-18 15:00:13 -0800271 date_str)
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800272 build_id, trybot_image = buildbot_utils.GetTrybotImage(
Manoj Guptaaee96b72016-10-24 13:43:28 -0700273 self._chromeos_root,
274 self._build,
275 self._patches,
276 description,
277 other_flags=['--notests'],
278 build_toolchain=True)
cmtice46093e52014-12-09 14:59:16 -0800279
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800280 print('trybot_url: \
Manoj Guptac4110352016-12-28 13:47:12 -0800281 https://uberchromegw.corp.google.com/i/chromiumos.tryserver/builders/release/builds/%s'
282 % build_id)
cmticed54f9802015-02-05 11:04:11 -0800283 if len(trybot_image) == 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800284 self._l.LogError('Unable to find trybot_image for %s!' % description)
Luis Lozano7f20acb2015-11-04 17:15:08 -0800285 return 1
Luis Lozano783954f2015-12-21 18:06:29 -0800286
Luis Lozanoc75fd052016-02-19 17:37:01 -0800287 vanilla_image = self._GetVanillaImageName(trybot_image)
288 nonafdo_image = self._GetNonAFDOImageName(trybot_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800289
290 print('trybot_image: %s' % trybot_image)
291 print('vanilla_image: %s' % vanilla_image)
292 print('nonafdo_image: %s' % nonafdo_image)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800293
cmtice46093e52014-12-09 14:59:16 -0800294 if os.getlogin() == ROLE_ACCOUNT:
295 self._FinishSetup()
296
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 Jiang76259e62015-08-21 08:44:31 -0700344 if options.patches:
Yunlian Jiang3c6e4672015-08-24 15:58:22 -0700345 patches = options.patches
346 else:
347 patches = USE_NEXT_GCC_PATCH
Yunlian Jiange52838c2015-08-20 14:32:37 -0700348
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800349 fc = ToolchainComparator(options.board, options.remote, options.chromeos_root,
350 options.weekday, patches, options.noschedv2)
cmtice46093e52014-12-09 14:59:16 -0800351 return fc.DoAll()
352
353
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800354if __name__ == '__main__':
cmtice46093e52014-12-09 14:59:16 -0800355 retval = Main(sys.argv)
356 sys.exit(retval)