blob: 898e874cc8a516cb07f9f73bc6d646e2ff3a407b [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
178 iterations: 3
179 }
Caroline Ticee82513b2016-10-27 12:45:15 -0700180
181 benchmark: page_cycler_v2.typical_25 {
182 suite: telemetry_Crosperf
183 iterations: 2
184 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
cmtice46093e52014-12-09 14:59:16 -0800218 experiment_image = """
Caroline Tice80eab982015-11-04 14:03:14 -0800219 %s {
cmtice46093e52014-12-09 14:59:16 -0800220 chromeos_root: %s
221 build: %s
Caroline Ticeddde5052015-09-23 09:43:35 -0700222 compiler: %s
cmtice46093e52014-12-09 14:59:16 -0800223 }
Caroline Tice80eab982015-11-04 14:03:14 -0800224 """ % (label_string, self._chromeos_root, trybot_image,
225 compiler_string)
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800226 f.write(experiment_image)
cmtice46093e52014-12-09 14:59:16 -0800227
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800228 crosperf = os.path.join(TOOLCHAIN_DIR, 'crosperf', 'crosperf')
Han Shen43494292015-09-14 10:26:40 -0700229 noschedv2_opts = '--noschedv2' if self._noschedv2 else ''
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800230 command = ('{crosperf} --no_email=True --results_dir={r_dir} '
231 '--json_report=True {noschedv2_opts} {exp_file}').format(
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800232 crosperf=crosperf,
233 r_dir=self._reports_dir,
234 noschedv2_opts=noschedv2_opts,
235 exp_file=experiment_file)
cmticeaa700b02015-06-12 13:26:47 -0700236
cmtice46093e52014-12-09 14:59:16 -0800237 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700238 if ret != 0:
Manoj Guptaaee96b72016-10-24 13:43:28 -0700239 raise RuntimeError('Crosperf execution error!')
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700240 else:
241 # Copy json report to pending archives directory.
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800242 command = 'cp %s/*.json %s/.' % (self._reports_dir, PENDING_ARCHIVES_DIR)
Caroline Ticeebbc3da2015-09-03 10:27:20 -0700243 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700244 return
cmtice46093e52014-12-09 14:59:16 -0800245
cmtice7f3190b2015-05-22 14:14:51 -0700246 def _SendEmail(self):
247 """Find email message generated by crosperf and send it."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800248 filename = os.path.join(self._reports_dir, 'msg_body.html')
cmtice7f3190b2015-05-22 14:14:51 -0700249 if (os.path.exists(filename) and
250 os.path.exists(os.path.expanduser(MAIL_PROGRAM))):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800251 email_title = 'buildbot test results'
Manoj Guptac4110352016-12-28 13:47:12 -0800252 if USE_LLVM_NEXT_PATCH in self._patches_string:
253 email_title = 'buildbot llvm_next test results'
254 elif USE_LLVM_PATCH in self._patches_string:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800255 email_title = 'buildbot llvm test results'
256 command = ('cat %s | %s -s "%s, %s" -team -html' %
257 (filename, MAIL_PROGRAM, email_title, self._board))
cmtice7f3190b2015-05-22 14:14:51 -0700258 self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800259
260 def DoAll(self):
Yunlian Jiang14cf5962015-12-11 15:50:14 -0800261 """Main function inside ToolchainComparator class.
cmtice46093e52014-12-09 14:59:16 -0800262
263 Launch trybot, get image names, create crosperf experiment file, run
264 crosperf, and copy images into seven-day report directories.
265 """
cmticece5ffa42015-02-12 15:18:43 -0800266 date_str = datetime.date.today()
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800267 description = 'master_%s_%s_%s' % (self._patches_string, self._build,
Han Shenfe054f12015-02-18 15:00:13 -0800268 date_str)
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800269 build_id, trybot_image = buildbot_utils.GetTrybotImage(
Manoj Guptaaee96b72016-10-24 13:43:28 -0700270 self._chromeos_root,
271 self._build,
272 self._patches,
273 description,
274 other_flags=['--notests'],
275 build_toolchain=True)
cmtice46093e52014-12-09 14:59:16 -0800276
Yunlian Jiange84ea3d2016-12-12 11:07:40 -0800277 print('trybot_url: \
Manoj Guptac4110352016-12-28 13:47:12 -0800278 https://uberchromegw.corp.google.com/i/chromiumos.tryserver/builders/release/builds/%s'
279 % build_id)
cmticed54f9802015-02-05 11:04:11 -0800280 if len(trybot_image) == 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800281 self._l.LogError('Unable to find trybot_image for %s!' % description)
Luis Lozano7f20acb2015-11-04 17:15:08 -0800282 return 1
Luis Lozano783954f2015-12-21 18:06:29 -0800283
Luis Lozanoc75fd052016-02-19 17:37:01 -0800284 vanilla_image = self._GetVanillaImageName(trybot_image)
285 nonafdo_image = self._GetNonAFDOImageName(trybot_image)
Luis Lozano783954f2015-12-21 18:06:29 -0800286
287 print('trybot_image: %s' % trybot_image)
288 print('vanilla_image: %s' % vanilla_image)
289 print('nonafdo_image: %s' % nonafdo_image)
Luis Lozanoc75fd052016-02-19 17:37:01 -0800290
cmtice46093e52014-12-09 14:59:16 -0800291 if os.getlogin() == ROLE_ACCOUNT:
292 self._FinishSetup()
293
Luis Lozano783954f2015-12-21 18:06:29 -0800294 self._TestImages(trybot_image, vanilla_image, nonafdo_image)
cmtice7f3190b2015-05-22 14:14:51 -0700295 self._SendEmail()
cmtice46093e52014-12-09 14:59:16 -0800296 return 0
297
298
299def Main(argv):
300 """The main function."""
301
302 # Common initializations
303 command_executer.InitCommandExecuter()
Caroline Ticeeddb0632016-04-14 09:19:02 -0700304 parser = argparse.ArgumentParser()
Manoj Guptaaee96b72016-10-24 13:43:28 -0700305 parser.add_argument(
306 '--remote', dest='remote', help='Remote machines to run tests on.')
307 parser.add_argument(
308 '--board', dest='board', default='x86-zgb', help='The target board.')
309 parser.add_argument(
310 '--chromeos_root',
311 dest='chromeos_root',
312 help='The chromeos root from which to run tests.')
313 parser.add_argument(
314 '--weekday',
315 default='',
316 dest='weekday',
317 help='The day of the week for which to run tests.')
318 parser.add_argument(
319 '--patch',
320 dest='patches',
321 help='The patches to use for the testing, '
322 "seprate the patch numbers with ',' "
323 'for more than one patches.')
324 parser.add_argument(
325 '--noschedv2',
326 dest='noschedv2',
327 action='store_true',
328 default=False,
329 help='Pass --noschedv2 to crosperf.')
Han Shen36413122015-08-28 11:05:40 -0700330
Caroline Ticeeddb0632016-04-14 09:19:02 -0700331 options = parser.parse_args(argv[1:])
cmtice46093e52014-12-09 14:59:16 -0800332 if not options.board:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800333 print('Please give a board.')
cmtice46093e52014-12-09 14:59:16 -0800334 return 1
335 if not options.remote:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800336 print('Please give at least one remote machine.')
cmtice46093e52014-12-09 14:59:16 -0800337 return 1
338 if not options.chromeos_root:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800339 print('Please specify the ChromeOS root directory.')
cmtice46093e52014-12-09 14:59:16 -0800340 return 1
Yunlian Jiang76259e62015-08-21 08:44:31 -0700341 if options.patches:
Yunlian Jiang3c6e4672015-08-24 15:58:22 -0700342 patches = options.patches
343 else:
344 patches = USE_NEXT_GCC_PATCH
Yunlian Jiange52838c2015-08-20 14:32:37 -0700345
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800346 fc = ToolchainComparator(options.board, options.remote, options.chromeos_root,
347 options.weekday, patches, options.noschedv2)
cmtice46093e52014-12-09 14:59:16 -0800348 return fc.DoAll()
349
350
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800351if __name__ == '__main__':
cmtice46093e52014-12-09 14:59:16 -0800352 retval = Main(sys.argv)
353 sys.exit(retval)