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