buildbot_test_toolchains.py revision 776d528ff8fa7e66d6abf96a735050c70f950a2b
1#!/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. 13import datetime 14import 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 """ 191 date_str = datetime.date.today() 192 description = "master_%s_%s_%s" % (USE_NEXT_GCC_PATCH, self._build, date_str) 193 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) 202 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 208 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) 255