buildbot_test_toolchains.py revision fe054f1eac0d0d739b74dee6bd45805af86568a2
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/chromiumos_test_image.bin; " 170 "cp %s %s/.") % (images_path, 171 tar_file_name, 172 test_path, 173 tar_file_name, 174 dest_dir) 175 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 """ 192 date_str = datetime.date.today() 193 description = "master_%s_%s_%s" % (USE_NEXT_GCC_PATCH, 194 self._build, 195 date_str) 196 trybot_image = buildbot_utils.GetTrybotImage(self._chromeos_root, 197 self._build, 198 [ USE_NEXT_GCC_PATCH ], 199 description) 200 201 vanilla_image = self._ParseVanillaImage(trybot_image) 202 203 print ("trybot_image: %s" % trybot_image) 204 print ("vanilla_image: %s" % vanilla_image) 205 if len(trybot_image) == 0: 206 self._l.LogError("Unable to find trybot_image for %s!" % description) 207 return 1 208 if len(vanilla_image) == 0: 209 self._l.LogError("Unable to find vanilla image for %s!" % description) 210 return 1 211 if os.getlogin() == ROLE_ACCOUNT: 212 self._FinishSetup() 213 214 if not self._TestImages(trybot_image, vanilla_image): 215 # Only try to copy the image files if the test runs ran successfully. 216 self._CopyWeeklyReportFiles(trybot_image, vanilla_image) 217 return 0 218 219 220def Main(argv): 221 """The main function.""" 222 223 # Common initializations 224 command_executer.InitCommandExecuter() 225 parser = optparse.OptionParser() 226 parser.add_option("--remote", 227 dest="remote", 228 help="Remote machines to run tests on.") 229 parser.add_option("--board", 230 dest="board", 231 default="x86-zgb", 232 help="The target board.") 233 parser.add_option("--chromeos_root", 234 dest="chromeos_root", 235 help="The chromeos root from which to run tests.") 236 parser.add_option("--weekday", default="", 237 dest="weekday", 238 help="The day of the week for which to run tests.") 239 options, _ = parser.parse_args(argv) 240 if not options.board: 241 print "Please give a board." 242 return 1 243 if not options.remote: 244 print "Please give at least one remote machine." 245 return 1 246 if not options.chromeos_root: 247 print "Please specify the ChromeOS root directory." 248 return 1 249 250 fc = ToolchainComparator(options.board, options.remote, 251 options.chromeos_root, options.weekday) 252 return fc.DoAll() 253 254 255if __name__ == "__main__": 256 retval = Main(sys.argv) 257 sys.exit(retval) 258