blob: c78155ca9b16444365a346fc594052dcba426a39 [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__))
31
32
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
50
51 def _ParseVanillaImage(self, trybot_image):
52 """
53 Parse a trybot artifact name to get corresponding vanilla image.
54
55 This function takes an artifact name, such as
56 'trybot-daisy-release/R40-6394.0.0-b1389', and returns the
57 corresponding official build name, e.g. 'daisy-release/R40-6394.0.0'.
58 """
59 start_pos = trybot_image.find(self._build)
60 end_pos = trybot_image.rfind("-b")
61 vanilla_image = trybot_image[start_pos:end_pos]
62 return vanilla_image
63
64
65 def _FinishSetup(self):
66 """
67 Make sure testing_rsa file is properly set up.
68 """
69 # Fix protections on ssh key
70 command = ("chmod 600 /var/cache/chromeos-cache/distfiles/target"
71 "/chrome-src-internal/src/third_party/chromite/ssh_keys"
72 "/testing_rsa")
73 ret_val = self._ce.ChrootRunCommand(self._chromeos_root, command)
74 if ret_val:
75 raise Exception("chmod for testing_rsa failed")
76
77 def _TestImages(self, trybot_image, vanilla_image):
78 """
79 Create crosperf experiment file.
80
81 Given the names of the trybot and vanilla images, create the
82 appropriate crosperf experiment file and launch crosperf on it.
83 """
84 experiment_file_dir = os.path.join (self._chromeos_root, "..",
85 self._weekday)
86 experiment_file_name = "%s_toolchain_experiment.txt" % self._board
87 experiment_file = os.path.join (experiment_file_dir,
88 experiment_file_name)
89 experiment_header = """
90 board: %s
91 remote: %s
92 """ % (self._board, self._remotes)
93 experiment_tests = """
94 benchmark: all_perfv2 {
95 suite: telemetry_Crosperf
96 iterations: 3
97 }
98 """
99 with open(experiment_file, "w") as f:
100 print >> f, experiment_header
101 print >> f, experiment_tests
102
103 # Now add vanilla to test file.
104 official_image = """
105 vanilla_image {
106 chromeos_root: %s
107 build: %s
108 }
109 """ % (self._chromeos_root, vanilla_image)
110 print >> f, official_image
111
112 experiment_image = """
113 test_image {
114 chromeos_root: %s
115 build: %s
116 }
117 """ % (self._chromeos_root, trybot_image)
118 print >> f, experiment_image
119
120 crosperf = os.path.join(TOOLCHAIN_DIR,
121 "crosperf",
122 "crosperf")
123 command = "%s --email=c-compiler-chrome %s" % (crosperf, experiment_file)
124 ret = self._ce.RunCommand(command)
125 if ret:
126 raise Exception("Couldn't run crosperf!")
127 return ret
128
129
130 def _CopyWeeklyReportFiles(self, trybot_image, vanilla_image):
131 """
132 Put files in place for running seven-day reports.
133
134 Create tar files of the custom and official images and copy them
135 to the weekly reports directory, so they exist when the weekly report
136 gets generated. IMPORTANT NOTE: This function must run *after*
137 crosperf has been run; otherwise the vanilla images will not be there.
138 """
139
140 dry_run = False
141 if (os.getlogin() != ROLE_ACCOUNT):
142 self._l.LogOutput("Running this from non-role account; not copying "
143 "tar files for weekly reports.")
144 dry_run = True
145
146 images_path = os.path.join(os.path.realpath(self._chromeos_root),
147 "chroot/tmp")
148
149 data_dir = os.path.join(WEEKLY_REPORTS_ROOT, self._board)
150 dest_dir = os.path.join (data_dir, self._weekday)
151 if not os.path.exists(dest_dir):
152 os.makedirs(dest_dir)
153
154 # Make sure dest_dir is empty (clean out last week's data).
155 cmd = "cd %s; rm -Rf %s_*_image*" % (dest_dir, self._weekday)
156 if dry_run:
157 print "CMD: %s" % cmd
158 else:
159 self._ce.RunCommand(cmd)
160
161 # Now create new tar files and copy them over.
162 labels = [ "test", "vanilla" ]
163 for label_name in labels:
164 if label_name == "test":
165 test_path = trybot_image
166 else:
167 test_path = vanilla_image
168 tar_file_name = "%s_%s_image.tar" % (self._weekday, label_name)
Han Shenfe054f12015-02-18 15:00:13 -0800169 cmd = ("cd %s; tar -cvf %s %s/chromiumos_test_image.bin; "
170 "cp %s %s/.") % (images_path,
171 tar_file_name,
172 test_path,
173 tar_file_name,
174 dest_dir)
cmtice46093e52014-12-09 14:59:16 -0800175 if dry_run:
176 print "CMD: %s" % cmd
177 tar_ret = 0
178 else:
179 tar_ret = self._ce.RunCommand(cmd)
180 if tar_ret:
181 self._l.LogOutput("Error while creating/copying test tar file(%s)."
182 % tar_file_name)
183
184
185 def DoAll(self):
186 """
187 Main function inside ToolchainComparator class.
188
189 Launch trybot, get image names, create crosperf experiment file, run
190 crosperf, and copy images into seven-day report directories.
191 """
cmticece5ffa42015-02-12 15:18:43 -0800192 date_str = datetime.date.today()
Han Shenfe054f12015-02-18 15:00:13 -0800193 description = "master_%s_%s_%s" % (USE_NEXT_GCC_PATCH,
194 self._build,
195 date_str)
cmtice46093e52014-12-09 14:59:16 -0800196 trybot_image = buildbot_utils.GetTrybotImage(self._chromeos_root,
197 self._build,
198 [ USE_NEXT_GCC_PATCH ],
Luis Lozano8a68b2d2015-04-23 14:37:09 -0700199 description,
200 build_toolchain=True)
cmtice46093e52014-12-09 14:59:16 -0800201
202 vanilla_image = self._ParseVanillaImage(trybot_image)
203
204 print ("trybot_image: %s" % trybot_image)
205 print ("vanilla_image: %s" % vanilla_image)
cmticed54f9802015-02-05 11:04:11 -0800206 if len(trybot_image) == 0:
207 self._l.LogError("Unable to find trybot_image for %s!" % description)
208 return 1
209 if len(vanilla_image) == 0:
210 self._l.LogError("Unable to find vanilla image for %s!" % description)
211 return 1
cmtice46093e52014-12-09 14:59:16 -0800212 if os.getlogin() == ROLE_ACCOUNT:
213 self._FinishSetup()
214
215 if not self._TestImages(trybot_image, vanilla_image):
216 # Only try to copy the image files if the test runs ran successfully.
217 self._CopyWeeklyReportFiles(trybot_image, vanilla_image)
218 return 0
219
220
221def Main(argv):
222 """The main function."""
223
224 # Common initializations
225 command_executer.InitCommandExecuter()
226 parser = optparse.OptionParser()
227 parser.add_option("--remote",
228 dest="remote",
229 help="Remote machines to run tests on.")
230 parser.add_option("--board",
231 dest="board",
232 default="x86-zgb",
233 help="The target board.")
234 parser.add_option("--chromeos_root",
235 dest="chromeos_root",
236 help="The chromeos root from which to run tests.")
237 parser.add_option("--weekday", default="",
238 dest="weekday",
239 help="The day of the week for which to run tests.")
240 options, _ = parser.parse_args(argv)
241 if not options.board:
242 print "Please give a board."
243 return 1
244 if not options.remote:
245 print "Please give at least one remote machine."
246 return 1
247 if not options.chromeos_root:
248 print "Please specify the ChromeOS root directory."
249 return 1
250
251 fc = ToolchainComparator(options.board, options.remote,
252 options.chromeos_root, options.weekday)
253 return fc.DoAll()
254
255
256if __name__ == "__main__":
257 retval = Main(sys.argv)
258 sys.exit(retval)