blob: d3b23003be42698e31d8fbd749055881ed2a8f0b [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)
169 cmd = "cd %s; tar -cvf %s %s/*; cp %s %s/." % (images_path,
170 tar_file_name,
171 test_path,
172 tar_file_name,
173 dest_dir)
174 if dry_run:
175 print "CMD: %s" % cmd
176 tar_ret = 0
177 else:
178 tar_ret = self._ce.RunCommand(cmd)
179 if tar_ret:
180 self._l.LogOutput("Error while creating/copying test tar file(%s)."
181 % tar_file_name)
182
183
184 def DoAll(self):
185 """
186 Main function inside ToolchainComparator class.
187
188 Launch trybot, get image names, create crosperf experiment file, run
189 crosperf, and copy images into seven-day report directories.
190 """
cmticece5ffa42015-02-12 15:18:43 -0800191 date_str = datetime.date.today()
192 description = "master_%s_%s_%s" % (USE_NEXT_GCC_PATCH, self._build, date_str)
cmtice46093e52014-12-09 14:59:16 -0800193 trybot_image = buildbot_utils.GetTrybotImage(self._chromeos_root,
194 self._build,
195 [ USE_NEXT_GCC_PATCH ],
196 description)
197
198 vanilla_image = self._ParseVanillaImage(trybot_image)
199
200 print ("trybot_image: %s" % trybot_image)
201 print ("vanilla_image: %s" % vanilla_image)
cmticed54f9802015-02-05 11:04:11 -0800202 if len(trybot_image) == 0:
203 self._l.LogError("Unable to find trybot_image for %s!" % description)
204 return 1
205 if len(vanilla_image) == 0:
206 self._l.LogError("Unable to find vanilla image for %s!" % description)
207 return 1
cmtice46093e52014-12-09 14:59:16 -0800208 if os.getlogin() == ROLE_ACCOUNT:
209 self._FinishSetup()
210
211 if not self._TestImages(trybot_image, vanilla_image):
212 # Only try to copy the image files if the test runs ran successfully.
213 self._CopyWeeklyReportFiles(trybot_image, vanilla_image)
214 return 0
215
216
217def Main(argv):
218 """The main function."""
219
220 # Common initializations
221 command_executer.InitCommandExecuter()
222 parser = optparse.OptionParser()
223 parser.add_option("--remote",
224 dest="remote",
225 help="Remote machines to run tests on.")
226 parser.add_option("--board",
227 dest="board",
228 default="x86-zgb",
229 help="The target board.")
230 parser.add_option("--chromeos_root",
231 dest="chromeos_root",
232 help="The chromeos root from which to run tests.")
233 parser.add_option("--weekday", default="",
234 dest="weekday",
235 help="The day of the week for which to run tests.")
236 options, _ = parser.parse_args(argv)
237 if not options.board:
238 print "Please give a board."
239 return 1
240 if not options.remote:
241 print "Please give at least one remote machine."
242 return 1
243 if not options.chromeos_root:
244 print "Please specify the ChromeOS root directory."
245 return 1
246
247 fc = ToolchainComparator(options.board, options.remote,
248 options.chromeos_root, options.weekday)
249 return fc.DoAll()
250
251
252if __name__ == "__main__":
253 retval = Main(sys.argv)
254 sys.exit(retval)