blob: 7072c634da18d1eacb700381052caf9d6fcc9bb2 [file] [log] [blame]
cmtice46093e52014-12-09 14:59:16 -08001#!/usr/bin/python
2"""
3Script for running nightly compiler tests on ChromeOS.
4
5This script launches a buildbot to build ChromeOS with the latest compiler on
6a particular board; then it finds and downloads the trybot image and the
7corresponding official image, and runs crosperf performance tests comparing
8the two. It then generates a report, emails it to the c-compiler-chrome, as
9well as copying the images into the seven-day reports directory.
10"""
11
12# Script to test different toolchains against ChromeOS benchmarks.
cmticece5ffa42015-02-12 15:18:43 -080013import datetime
cmtice46093e52014-12-09 14:59:16 -080014import optparse
15import os
16import sys
17import time
18import urllib2
19
20from utils import command_executer
21from utils import logger
22
23from utils import buildbot_utils
24
25# CL that updated GCC ebuilds to use 'next_gcc'.
26USE_NEXT_GCC_PATCH ="230260"
27
28WEEKLY_REPORTS_ROOT = "/usr/local/google/crostc/weekly_test_data"
29ROLE_ACCOUNT = "mobiletc-prebuild"
30TOOLCHAIN_DIR = os.path.dirname(os.path.realpath(__file__))
cmtice7f3190b2015-05-22 14:14:51 -070031MAIL_PROGRAM = "~/var/bin/mail-sheriff"
cmtice46093e52014-12-09 14:59:16 -080032
33class ToolchainComparator():
34 """
35 Class for doing the nightly tests work.
36 """
37
38 def __init__(self, board, remotes, chromeos_root, weekday):
39 self._board = board
40 self._remotes = remotes
41 self._chromeos_root = chromeos_root
42 self._base_dir = os.getcwd()
43 self._ce = command_executer.GetCommandExecuter()
44 self._l = logger.GetLogger()
45 self._build = "%s-release" % board
46 if not weekday:
47 self._weekday = time.strftime("%a")
48 else:
49 self._weekday = weekday
cmtice7f3190b2015-05-22 14:14:51 -070050 timestamp = datetime.datetime.strftime(datetime.datetime.now(),
51 "%Y-%m-%d_%H:%M:%S")
52 self._reports_dir = os.path.join(
53 os.path.expanduser("~/nightly_test_reports"),
54 "%s.%s" % (timestamp, board),
55 )
cmtice46093e52014-12-09 14:59:16 -080056
57 def _ParseVanillaImage(self, trybot_image):
58 """
59 Parse a trybot artifact name to get corresponding vanilla image.
60
61 This function takes an artifact name, such as
62 'trybot-daisy-release/R40-6394.0.0-b1389', and returns the
63 corresponding official build name, e.g. 'daisy-release/R40-6394.0.0'.
64 """
65 start_pos = trybot_image.find(self._build)
66 end_pos = trybot_image.rfind("-b")
67 vanilla_image = trybot_image[start_pos:end_pos]
68 return vanilla_image
69
cmtice46093e52014-12-09 14:59:16 -080070 def _FinishSetup(self):
71 """
72 Make sure testing_rsa file is properly set up.
73 """
74 # Fix protections on ssh key
75 command = ("chmod 600 /var/cache/chromeos-cache/distfiles/target"
76 "/chrome-src-internal/src/third_party/chromite/ssh_keys"
77 "/testing_rsa")
78 ret_val = self._ce.ChrootRunCommand(self._chromeos_root, command)
cmtice7f3190b2015-05-22 14:14:51 -070079 if ret_val != 0:
80 raise RuntimeError("chmod for testing_rsa failed")
cmtice46093e52014-12-09 14:59:16 -080081
82 def _TestImages(self, trybot_image, vanilla_image):
83 """
84 Create crosperf experiment file.
85
86 Given the names of the trybot and vanilla images, create the
87 appropriate crosperf experiment file and launch crosperf on it.
88 """
89 experiment_file_dir = os.path.join (self._chromeos_root, "..",
90 self._weekday)
91 experiment_file_name = "%s_toolchain_experiment.txt" % self._board
92 experiment_file = os.path.join (experiment_file_dir,
93 experiment_file_name)
94 experiment_header = """
95 board: %s
96 remote: %s
97 """ % (self._board, self._remotes)
98 experiment_tests = """
99 benchmark: all_perfv2 {
100 suite: telemetry_Crosperf
101 iterations: 3
102 }
103 """
104 with open(experiment_file, "w") as f:
105 print >> f, experiment_header
106 print >> f, experiment_tests
107
108 # Now add vanilla to test file.
109 official_image = """
110 vanilla_image {
111 chromeos_root: %s
112 build: %s
113 }
114 """ % (self._chromeos_root, vanilla_image)
115 print >> f, official_image
116
117 experiment_image = """
118 test_image {
119 chromeos_root: %s
120 build: %s
121 }
122 """ % (self._chromeos_root, trybot_image)
123 print >> f, experiment_image
124
125 crosperf = os.path.join(TOOLCHAIN_DIR,
126 "crosperf",
127 "crosperf")
cmtice7f3190b2015-05-22 14:14:51 -0700128 command = ("%s --no_email=True --results_dir=%s %s" % (crosperf,
129 self._reports_dir,
130 experiment_file))
cmtice46093e52014-12-09 14:59:16 -0800131 ret = self._ce.RunCommand(command)
cmtice7f3190b2015-05-22 14:14:51 -0700132 if ret != 0:
133 raise RuntimeError("Couldn't run crosperf!")
134 return
cmtice46093e52014-12-09 14:59:16 -0800135
136 def _CopyWeeklyReportFiles(self, trybot_image, vanilla_image):
137 """
138 Put files in place for running seven-day reports.
139
140 Create tar files of the custom and official images and copy them
141 to the weekly reports directory, so they exist when the weekly report
142 gets generated. IMPORTANT NOTE: This function must run *after*
143 crosperf has been run; otherwise the vanilla images will not be there.
144 """
145
146 dry_run = False
147 if (os.getlogin() != ROLE_ACCOUNT):
148 self._l.LogOutput("Running this from non-role account; not copying "
149 "tar files for weekly reports.")
150 dry_run = True
151
152 images_path = os.path.join(os.path.realpath(self._chromeos_root),
153 "chroot/tmp")
154
155 data_dir = os.path.join(WEEKLY_REPORTS_ROOT, self._board)
156 dest_dir = os.path.join (data_dir, self._weekday)
157 if not os.path.exists(dest_dir):
158 os.makedirs(dest_dir)
159
160 # Make sure dest_dir is empty (clean out last week's data).
161 cmd = "cd %s; rm -Rf %s_*_image*" % (dest_dir, self._weekday)
162 if dry_run:
163 print "CMD: %s" % cmd
164 else:
165 self._ce.RunCommand(cmd)
166
167 # Now create new tar files and copy them over.
168 labels = [ "test", "vanilla" ]
169 for label_name in labels:
170 if label_name == "test":
171 test_path = trybot_image
172 else:
173 test_path = vanilla_image
174 tar_file_name = "%s_%s_image.tar" % (self._weekday, label_name)
Han Shenfe054f12015-02-18 15:00:13 -0800175 cmd = ("cd %s; tar -cvf %s %s/chromiumos_test_image.bin; "
176 "cp %s %s/.") % (images_path,
177 tar_file_name,
178 test_path,
179 tar_file_name,
180 dest_dir)
cmtice46093e52014-12-09 14:59:16 -0800181 if dry_run:
182 print "CMD: %s" % cmd
183 tar_ret = 0
184 else:
185 tar_ret = self._ce.RunCommand(cmd)
186 if tar_ret:
187 self._l.LogOutput("Error while creating/copying test tar file(%s)."
188 % tar_file_name)
189
cmtice7f3190b2015-05-22 14:14:51 -0700190 def _SendEmail(self):
191 """Find email message generated by crosperf and send it."""
192 filename = os.path.join(self._reports_dir,
193 "msg_body.html")
194 if (os.path.exists(filename) and
195 os.path.exists(os.path.expanduser(MAIL_PROGRAM))):
196 command = ('cat %s | %s -s "buildbot test results, %s" -team -html'
197 % (filename, MAIL_PROGRAM, self._board))
198 self._ce.RunCommand(command)
cmtice46093e52014-12-09 14:59:16 -0800199
200 def DoAll(self):
201 """
202 Main function inside ToolchainComparator class.
203
204 Launch trybot, get image names, create crosperf experiment file, run
205 crosperf, and copy images into seven-day report directories.
206 """
cmticece5ffa42015-02-12 15:18:43 -0800207 date_str = datetime.date.today()
Han Shenfe054f12015-02-18 15:00:13 -0800208 description = "master_%s_%s_%s" % (USE_NEXT_GCC_PATCH,
209 self._build,
210 date_str)
cmtice46093e52014-12-09 14:59:16 -0800211 trybot_image = buildbot_utils.GetTrybotImage(self._chromeos_root,
212 self._build,
213 [ USE_NEXT_GCC_PATCH ],
Luis Lozano8a68b2d2015-04-23 14:37:09 -0700214 description,
215 build_toolchain=True)
cmtice46093e52014-12-09 14:59:16 -0800216
217 vanilla_image = self._ParseVanillaImage(trybot_image)
218
219 print ("trybot_image: %s" % trybot_image)
220 print ("vanilla_image: %s" % vanilla_image)
cmticed54f9802015-02-05 11:04:11 -0800221 if len(trybot_image) == 0:
222 self._l.LogError("Unable to find trybot_image for %s!" % description)
223 return 1
224 if len(vanilla_image) == 0:
225 self._l.LogError("Unable to find vanilla image for %s!" % description)
226 return 1
cmtice46093e52014-12-09 14:59:16 -0800227 if os.getlogin() == ROLE_ACCOUNT:
228 self._FinishSetup()
229
cmtice7f3190b2015-05-22 14:14:51 -0700230 self._TestImages(trybot_image, vanilla_image)
231 self._SendEmail()
232 # Only try to copy the image files if the test runs ran successfully.
233 self._CopyWeeklyReportFiles(trybot_image, vanilla_image)
cmtice46093e52014-12-09 14:59:16 -0800234 return 0
235
236
237def Main(argv):
238 """The main function."""
239
240 # Common initializations
241 command_executer.InitCommandExecuter()
242 parser = optparse.OptionParser()
243 parser.add_option("--remote",
244 dest="remote",
245 help="Remote machines to run tests on.")
246 parser.add_option("--board",
247 dest="board",
248 default="x86-zgb",
249 help="The target board.")
250 parser.add_option("--chromeos_root",
251 dest="chromeos_root",
252 help="The chromeos root from which to run tests.")
253 parser.add_option("--weekday", default="",
254 dest="weekday",
255 help="The day of the week for which to run tests.")
256 options, _ = parser.parse_args(argv)
257 if not options.board:
258 print "Please give a board."
259 return 1
260 if not options.remote:
261 print "Please give at least one remote machine."
262 return 1
263 if not options.chromeos_root:
264 print "Please specify the ChromeOS root directory."
265 return 1
266
267 fc = ToolchainComparator(options.board, options.remote,
268 options.chromeos_root, options.weekday)
269 return fc.DoAll()
270
271
272if __name__ == "__main__":
273 retval = Main(sys.argv)
274 sys.exit(retval)