test_toolchains.py revision a6255d058ecf1fe6e9983bb5acf7bec5213c1317
1#!/usr/bin/python 2 3# Script to test different toolchains against ChromeOS benchmarks. 4import optparse 5import os 6import sys 7import build_chromeos 8import setup_chromeos 9from utils import command_executer 10from utils import misc 11from utils import logger 12 13 14class GCCConfig(object): 15 def __init__(self, githash): 16 self.githash = githash 17 18 19class ToolchainConfig: 20 def __init__(self, gcc_config=None, binutils_config=None): 21 self.gcc_config = gcc_config 22 23 24class ChromeOSCheckout(object): 25 def __init__(self, board, chromeos_root): 26 self._board = board 27 self._chromeos_root = chromeos_root 28 self._ce = command_executer.GetCommandExecuter() 29 self._l = logger.GetLogger() 30 31 def _DeleteChroot(self): 32 command = "cd %s; cros_sdk --delete" % self._chromeos_root 33 return self._ce.RunCommand(command) 34 35 def _DeleteCcahe(self): 36 # crosbug.com/34956 37 command = "sudo rm -rf %s" % os.path.join(self._chromeos_root, ".cache") 38 return self._ce.RunCommand(command) 39 40 def _BuildAndImage(self, label=""): 41 if (not label or 42 not misc.DoesLabelExist(self._chromeos_root, self._board, label)): 43 build_chromeos_args = [build_chromeos.__file__, 44 "--chromeos_root=%s" % self._chromeos_root, 45 "--board=%s" % self._board, 46 "--rebuild"] 47 if self._public: 48 build_chromeos_args.append("--env=USE=-chrome_internal") 49 if label == "vanilla": 50 build_chromeos_args.append("--vanilla_image") 51 ret = build_chromeos.Main(build_chromeos_args) 52 if ret: 53 raise Exception("Couldn't build ChromeOS!") 54 if label: 55 misc.LabelLatestImage(self._chromeos_root, self._board, label) 56 return label 57 58 def _SetupBoard(self, env_dict): 59 env_string = misc.GetEnvStringFromDict(env_dict) 60 command = ("%s %s" % 61 (env_string, 62 misc.GetSetupBoardCommand(self._board, 63 usepkg=False))) 64 ret = self._ce.ChrootRunCommand(self._chromeos_root, 65 command) 66 assert ret == 0, "Could not setup board with new toolchain." 67 68 def _UnInstallToolchain(self): 69 command = ("sudo CLEAN_DELAY=0 emerge -C cross-%s/gcc" % 70 misc.GetCtargetFromBoard(self._board, 71 self._chromeos_root)) 72 ret = self._ce.ChrootRunCommand(self._chromeos_root, 73 command) 74 if ret: 75 raise Exception("Couldn't uninstall the toolchain!") 76 77 def _CheckoutChromeOS(self): 78 # TODO(asharif): Setup a fixed ChromeOS version (quarterly snapshot). 79 if not os.path.exists(self._chromeos_root): 80 setup_chromeos_args = [setup_chromeos.__file__, 81 "--dir=%s" % self._chromeos_root] 82 if self._public: 83 setup_chromeos_args.append("--public") 84 ret = setup_chromeos.Main(setup_chromeos_args) 85 if ret: 86 raise Exception("Couldn't run setup_chromeos!") 87 88 89 def _BuildToolchain(self, config): 90 self._UnInstallToolchain() 91 self._SetupBoard({"USE": "git_gcc", 92 "GCC_GITHASH": config.gcc_config.githash, 93 "EMERGE_DEFAULT_OPTS": "--exclude=gcc"}) 94 95 96class ToolchainComparator(ChromeOSCheckout): 97 def __init__(self, board, remotes, configs, clean, public, force_mismatch): 98 self._board = board 99 self._remotes = remotes 100 self._chromeos_root = "chromeos" 101 self._configs = configs 102 self._clean = clean 103 self._public = public 104 self._force_mismatch = force_mismatch 105 self._ce = command_executer.GetCommandExecuter() 106 self._l = logger.GetLogger() 107 ChromeOSCheckout.__init__(self, board, self._chromeos_root) 108 109 110 def _FinishSetup(self): 111 # Get correct .boto file 112 current_dir = os.getcwd() 113 src = "/home/mobiletc-prebuild/.boto" 114 dest = os.path.join(current_dir, self._chromeos_root, 115 "src/private-overlays/chromeos-overlay/" 116 "googlestorage_account.boto") 117 # Copy the file to the correct place 118 copy_cmd = "cp %s %s" % (src, dest) 119 retval = self._ce.RunCommand(copy_cmd) 120 if retval: 121 raise Exception("Couldn't copy .boto file for google storage.") 122 123 # Fix protections on ssh key 124 command = ("chmod 600 /var/cache/chromeos-cache/distfiles/target" 125 "/chrome-src-internal/src/third_party/chromite/ssh_keys" 126 "/testing_rsa") 127 retval = self._ce.ChrootRunCommand(self._chromeos_root, command) 128 if retval: 129 raise Exception("chmod for testing_rsa failed") 130 131 def _TestLabels(self, labels): 132 experiment_file = "toolchain_experiment.txt" 133 image_args = "" 134 if self._force_mismatch: 135 image_args = "--force-mismatch" 136 experiment_header = """ 137 board: %s 138 remote: %s 139 """ % (self._board, self._remotes) 140 experiment_tests = """ 141 benchmark: all_perfv2 { 142 suite: telemetry_Crosperf 143 iterations: 1 144 } 145 """ 146 with open(experiment_file, "w") as f: 147 print >>f, experiment_header 148 print >>f, experiment_tests 149 for label in labels: 150 # TODO(asharif): Fix crosperf so it accepts labels with symbols 151 crosperf_label = label 152 crosperf_label = crosperf_label.replace("-", "minus") 153 crosperf_label = crosperf_label.replace("+", "plus") 154 crosperf_label = crosperf_label.replace(".", "") 155 experiment_image = """ 156 %s { 157 chromeos_image: %s 158 image_args: %s 159 } 160 """ % (crosperf_label, 161 os.path.join(misc.GetImageDir(self._chromeos_root, self._board), 162 label, 163 "chromiumos_test_image.bin"), 164 image_args) 165 print >>f, experiment_image 166 crosperf = os.path.join(os.path.dirname(__file__), 167 "crosperf", 168 "crosperf") 169 command = "%s --email=c-compiler-chrome %s" % (crosperf, experiment_file) 170 ret = self._ce.RunCommand(command) 171 if ret: 172 raise Exception("Couldn't run crosperf!") 173 174 def DoAll(self): 175 self._CheckoutChromeOS() 176 labels = [] 177 vanilla_label = self._BuildAndImage("vanilla") 178 labels.append(vanilla_label) 179 for config in self._configs: 180 label = misc.GetFilenameFromString(config.gcc_config.githash) 181 if (not misc.DoesLabelExist(self._chromeos_root, 182 self._board, 183 label)): 184 self._BuildToolchain(config) 185 label = self._BuildAndImage(label) 186 labels.append(label) 187 self._FinishSetup() 188 self._TestLabels(labels) 189 if self._clean: 190 ret = self._DeleteChroot() 191 if ret: return ret 192 ret = self._DeleteCcahe() 193 if ret: return ret 194 return 0 195 196 197def Main(argv): 198 """The main function.""" 199 # Common initializations 200### command_executer.InitCommandExecuter(True) 201 command_executer.InitCommandExecuter() 202 parser = optparse.OptionParser() 203 parser.add_option("--remote", 204 dest="remote", 205 help="Remote machines to run tests on.") 206 parser.add_option("--board", 207 dest="board", 208 default="x86-zgb", 209 help="The target board.") 210 parser.add_option("--githashes", 211 dest="githashes", 212 default="master", 213 help="The gcc githashes to test.") 214 parser.add_option("--clean", 215 dest="clean", 216 default=False, 217 action="store_true", 218 help="Clean the chroot after testing.") 219 parser.add_option("--public", 220 dest="public", 221 default=False, 222 action="store_true", 223 help="Use the public checkout/build.") 224 parser.add_option("--force-mismatch", 225 dest="force_mismatch", 226 default="", 227 help="Force the image regardless of board mismatch") 228 options, _ = parser.parse_args(argv) 229 if not options.board: 230 print "Please give a board." 231 return 1 232 if not options.remote: 233 print "Please give at least one remote machine." 234 return 1 235 toolchain_configs = [] 236 for githash in options.githashes.split(","): 237 gcc_config = GCCConfig(githash=githash) 238 toolchain_config = ToolchainConfig(gcc_config=gcc_config) 239 toolchain_configs.append(toolchain_config) 240 fc = ToolchainComparator(options.board, options.remote, toolchain_configs, 241 options.clean, options.public, 242 options.force_mismatch) 243 return fc.DoAll() 244 245 246if __name__ == "__main__": 247 retval = Main(sys.argv) 248 sys.exit(retval) 249