1*760c253cSXin Li# -*- coding: utf-8 -*- 2*760c253cSXin Li# Copyright 2013 The ChromiumOS Authors 3*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be 4*760c253cSXin Li# found in the LICENSE file. 5*760c253cSXin Li 6*760c253cSXin Li"""A module to generate experiments.""" 7*760c253cSXin Li 8*760c253cSXin Li 9*760c253cSXin Liimport os 10*760c253cSXin Liimport re 11*760c253cSXin Liimport socket 12*760c253cSXin Liimport sys 13*760c253cSXin Li 14*760c253cSXin Lifrom benchmark import Benchmark 15*760c253cSXin Lifrom cros_utils import command_executer 16*760c253cSXin Lifrom cros_utils import logger 17*760c253cSXin Lifrom experiment import Experiment 18*760c253cSXin Liimport file_lock_machine 19*760c253cSXin Lifrom label import Label 20*760c253cSXin Lifrom label import MockLabel 21*760c253cSXin Lifrom results_cache import CacheConditions 22*760c253cSXin Liimport test_flag 23*760c253cSXin Li 24*760c253cSXin Liimport config 25*760c253cSXin Li 26*760c253cSXin Li 27*760c253cSXin Li# Users may want to run Telemetry tests either individually, or in 28*760c253cSXin Li# specified sets. Here we define sets of tests that users may want 29*760c253cSXin Li# to run together. 30*760c253cSXin Li 31*760c253cSXin Litelemetry_toolchain_perf_tests = [ 32*760c253cSXin Li "octane", 33*760c253cSXin Li "speedometer", 34*760c253cSXin Li "speedometer2", 35*760c253cSXin Li "jetstream2", 36*760c253cSXin Li] 37*760c253cSXin Ligraphics_perf_tests = [ 38*760c253cSXin Li "graphics_GLBench", 39*760c253cSXin Li "graphics_GLMark2", 40*760c253cSXin Li "graphics_SanAngeles", 41*760c253cSXin Li "graphics_WebGLAquarium", 42*760c253cSXin Li "graphics_WebGLPerformance", 43*760c253cSXin Li] 44*760c253cSXin Li# TODO: disable rendering.desktop by default as the benchmark is 45*760c253cSXin Li# currently in a bad state 46*760c253cSXin Litelemetry_crosbolt_perf_tests = [ 47*760c253cSXin Li "octane", 48*760c253cSXin Li "speedometer2", 49*760c253cSXin Li "jetstream2", 50*760c253cSXin Li "loading.desktop", 51*760c253cSXin Li # 'rendering.desktop', 52*760c253cSXin Li] 53*760c253cSXin Li 54*760c253cSXin Licrosbolt_perf_tests = [ 55*760c253cSXin Li "graphics_WebGLAquarium", 56*760c253cSXin Li "tast.video.PlaybackPerfVP91080P30FPS", 57*760c253cSXin Li] 58*760c253cSXin Li 59*760c253cSXin Lidso_list = [ 60*760c253cSXin Li "all", 61*760c253cSXin Li "chrome", 62*760c253cSXin Li "kallsyms", 63*760c253cSXin Li] 64*760c253cSXin Li 65*760c253cSXin Li 66*760c253cSXin Liclass ExperimentFactory(object): 67*760c253cSXin Li """Factory class for building an Experiment, given an ExperimentFile as input. 68*760c253cSXin Li 69*760c253cSXin Li This factory is currently hardcoded to produce an experiment for running 70*760c253cSXin Li ChromeOS benchmarks, but the idea is that in the future, other types 71*760c253cSXin Li of experiments could be produced. 72*760c253cSXin Li """ 73*760c253cSXin Li 74*760c253cSXin Li def AppendBenchmarkSet( 75*760c253cSXin Li self, 76*760c253cSXin Li benchmarks, 77*760c253cSXin Li benchmark_list, 78*760c253cSXin Li test_args, 79*760c253cSXin Li iterations, 80*760c253cSXin Li rm_chroot_tmp, 81*760c253cSXin Li perf_args, 82*760c253cSXin Li suite, 83*760c253cSXin Li show_all_results, 84*760c253cSXin Li retries, 85*760c253cSXin Li run_local, 86*760c253cSXin Li cwp_dso, 87*760c253cSXin Li weight, 88*760c253cSXin Li ): 89*760c253cSXin Li """Add all the tests in a set to the benchmarks list.""" 90*760c253cSXin Li for test_name in benchmark_list: 91*760c253cSXin Li telemetry_benchmark = Benchmark( 92*760c253cSXin Li test_name, 93*760c253cSXin Li test_name, 94*760c253cSXin Li test_args, 95*760c253cSXin Li iterations, 96*760c253cSXin Li rm_chroot_tmp, 97*760c253cSXin Li perf_args, 98*760c253cSXin Li suite, 99*760c253cSXin Li show_all_results, 100*760c253cSXin Li retries, 101*760c253cSXin Li run_local, 102*760c253cSXin Li cwp_dso, 103*760c253cSXin Li weight, 104*760c253cSXin Li ) 105*760c253cSXin Li benchmarks.append(telemetry_benchmark) 106*760c253cSXin Li 107*760c253cSXin Li def GetExperiment(self, experiment_file, working_directory, log_dir): 108*760c253cSXin Li """Construct an experiment from an experiment file.""" 109*760c253cSXin Li global_settings = experiment_file.GetGlobalSettings() 110*760c253cSXin Li experiment_name = global_settings.GetField("name") 111*760c253cSXin Li board = global_settings.GetField("board") 112*760c253cSXin Li chromeos_root = global_settings.GetField("chromeos_root") 113*760c253cSXin Li log_level = global_settings.GetField("logging_level") 114*760c253cSXin Li if log_level not in ("quiet", "average", "verbose"): 115*760c253cSXin Li log_level = "verbose" 116*760c253cSXin Li 117*760c253cSXin Li crosfleet = global_settings.GetField("crosfleet") 118*760c253cSXin Li no_lock = bool(global_settings.GetField("no_lock")) 119*760c253cSXin Li # Check whether crosfleet tool is installed correctly for crosfleet mode. 120*760c253cSXin Li if crosfleet and not self.CheckCrosfleetTool(chromeos_root, log_level): 121*760c253cSXin Li sys.exit(0) 122*760c253cSXin Li 123*760c253cSXin Li remote = global_settings.GetField("remote") 124*760c253cSXin Li # This is used to remove the ",' from the remote if user 125*760c253cSXin Li # add them to the remote string. 126*760c253cSXin Li new_remote = [] 127*760c253cSXin Li if remote: 128*760c253cSXin Li for i in remote: 129*760c253cSXin Li c = re.sub("[\"']", "", i) 130*760c253cSXin Li new_remote.append(c) 131*760c253cSXin Li remote = new_remote 132*760c253cSXin Li rm_chroot_tmp = global_settings.GetField("rm_chroot_tmp") 133*760c253cSXin Li perf_args = global_settings.GetField("perf_args") 134*760c253cSXin Li download_debug = global_settings.GetField("download_debug") 135*760c253cSXin Li # Do not download debug symbols when perf_args is not specified. 136*760c253cSXin Li if not perf_args and download_debug: 137*760c253cSXin Li download_debug = False 138*760c253cSXin Li acquire_timeout = global_settings.GetField("acquire_timeout") 139*760c253cSXin Li cache_dir = global_settings.GetField("cache_dir") 140*760c253cSXin Li cache_only = global_settings.GetField("cache_only") 141*760c253cSXin Li config.AddConfig("no_email", global_settings.GetField("no_email")) 142*760c253cSXin Li share_cache = global_settings.GetField("share_cache") 143*760c253cSXin Li results_dir = global_settings.GetField("results_dir") 144*760c253cSXin Li compress_results = global_settings.GetField("compress_results") 145*760c253cSXin Li # Warn user that option use_file_locks is deprecated. 146*760c253cSXin Li use_file_locks = global_settings.GetField("use_file_locks") 147*760c253cSXin Li if use_file_locks: 148*760c253cSXin Li l = logger.GetLogger() 149*760c253cSXin Li l.LogWarning( 150*760c253cSXin Li "Option use_file_locks is deprecated, please remove it " 151*760c253cSXin Li "from your experiment settings." 152*760c253cSXin Li ) 153*760c253cSXin Li locks_dir = global_settings.GetField("locks_dir") 154*760c253cSXin Li # If not specified, set the locks dir to the default locks dir in 155*760c253cSXin Li # file_lock_machine. 156*760c253cSXin Li if not locks_dir: 157*760c253cSXin Li locks_dir = file_lock_machine.Machine.LOCKS_DIR 158*760c253cSXin Li if not os.path.exists(locks_dir): 159*760c253cSXin Li raise RuntimeError( 160*760c253cSXin Li "Cannot access default lock directory. " 161*760c253cSXin Li "Please run prodaccess or specify a local directory" 162*760c253cSXin Li ) 163*760c253cSXin Li chrome_src = global_settings.GetField("chrome_src") 164*760c253cSXin Li show_all_results = global_settings.GetField("show_all_results") 165*760c253cSXin Li cwp_dso = global_settings.GetField("cwp_dso") 166*760c253cSXin Li if cwp_dso and not cwp_dso in dso_list: 167*760c253cSXin Li raise RuntimeError("The DSO specified is not supported") 168*760c253cSXin Li ignore_min_max = global_settings.GetField("ignore_min_max") 169*760c253cSXin Li dut_config = { 170*760c253cSXin Li "enable_aslr": global_settings.GetField("enable_aslr"), 171*760c253cSXin Li "intel_pstate": global_settings.GetField("intel_pstate"), 172*760c253cSXin Li "cooldown_time": global_settings.GetField("cooldown_time"), 173*760c253cSXin Li "cooldown_temp": global_settings.GetField("cooldown_temp"), 174*760c253cSXin Li "governor": global_settings.GetField("governor"), 175*760c253cSXin Li "cpu_usage": global_settings.GetField("cpu_usage"), 176*760c253cSXin Li "cpu_freq_pct": global_settings.GetField("cpu_freq_pct"), 177*760c253cSXin Li "turbostat": global_settings.GetField("turbostat"), 178*760c253cSXin Li "top_interval": global_settings.GetField("top_interval"), 179*760c253cSXin Li } 180*760c253cSXin Li keep_stateful = global_settings.GetField("keep_stateful") 181*760c253cSXin Li 182*760c253cSXin Li # Default cache hit conditions. The image checksum in the cache and the 183*760c253cSXin Li # computed checksum of the image must match. Also a cache file must exist. 184*760c253cSXin Li cache_conditions = [ 185*760c253cSXin Li CacheConditions.CACHE_FILE_EXISTS, 186*760c253cSXin Li CacheConditions.CHECKSUMS_MATCH, 187*760c253cSXin Li ] 188*760c253cSXin Li if global_settings.GetField("rerun_if_failed"): 189*760c253cSXin Li cache_conditions.append(CacheConditions.RUN_SUCCEEDED) 190*760c253cSXin Li if global_settings.GetField("rerun") or global_settings.GetField( 191*760c253cSXin Li "ignore_cache" 192*760c253cSXin Li ): 193*760c253cSXin Li cache_conditions.append(CacheConditions.FALSE) 194*760c253cSXin Li if global_settings.GetField("same_machine"): 195*760c253cSXin Li cache_conditions.append(CacheConditions.SAME_MACHINE_MATCH) 196*760c253cSXin Li if global_settings.GetField("same_specs"): 197*760c253cSXin Li cache_conditions.append(CacheConditions.MACHINES_MATCH) 198*760c253cSXin Li 199*760c253cSXin Li # Construct benchmarks. 200*760c253cSXin Li # Some fields are common with global settings. The values are 201*760c253cSXin Li # inherited and/or merged with the global settings values. 202*760c253cSXin Li benchmarks = [] 203*760c253cSXin Li all_benchmark_settings = experiment_file.GetSettings("benchmark") 204*760c253cSXin Li 205*760c253cSXin Li # Check if there is duplicated benchmark name 206*760c253cSXin Li benchmark_names = {} 207*760c253cSXin Li # Check if in cwp_dso mode, all benchmarks should have same iterations 208*760c253cSXin Li cwp_dso_iterations = 0 209*760c253cSXin Li 210*760c253cSXin Li for benchmark_settings in all_benchmark_settings: 211*760c253cSXin Li benchmark_name = benchmark_settings.name 212*760c253cSXin Li test_name = benchmark_settings.GetField("test_name") 213*760c253cSXin Li if not test_name: 214*760c253cSXin Li test_name = benchmark_name 215*760c253cSXin Li test_args = benchmark_settings.GetField("test_args") 216*760c253cSXin Li 217*760c253cSXin Li # Rename benchmark name if 'story-filter' or 'story-tag-filter' specified 218*760c253cSXin Li # in test_args. Make sure these two tags only appear once. 219*760c253cSXin Li story_count = 0 220*760c253cSXin Li for arg in test_args.split(): 221*760c253cSXin Li if "--story-filter=" in arg or "--story-tag-filter=" in arg: 222*760c253cSXin Li story_count += 1 223*760c253cSXin Li if story_count > 1: 224*760c253cSXin Li raise RuntimeError( 225*760c253cSXin Li "Only one story or story-tag filter allowed in " 226*760c253cSXin Li "a single benchmark run" 227*760c253cSXin Li ) 228*760c253cSXin Li # Rename benchmark name with an extension of 'story'-option 229*760c253cSXin Li benchmark_name = "%s@@%s" % ( 230*760c253cSXin Li benchmark_name, 231*760c253cSXin Li arg.split("=")[-1], 232*760c253cSXin Li ) 233*760c253cSXin Li 234*760c253cSXin Li # Check for duplicated benchmark name after renaming 235*760c253cSXin Li if not benchmark_name in benchmark_names: 236*760c253cSXin Li benchmark_names[benchmark_name] = True 237*760c253cSXin Li else: 238*760c253cSXin Li raise SyntaxError( 239*760c253cSXin Li "Duplicate benchmark name: '%s'." % benchmark_name 240*760c253cSXin Li ) 241*760c253cSXin Li 242*760c253cSXin Li iterations = benchmark_settings.GetField("iterations") 243*760c253cSXin Li if cwp_dso: 244*760c253cSXin Li if cwp_dso_iterations not in (0, iterations): 245*760c253cSXin Li raise RuntimeError( 246*760c253cSXin Li "Iterations of each benchmark run are not the " "same" 247*760c253cSXin Li ) 248*760c253cSXin Li cwp_dso_iterations = iterations 249*760c253cSXin Li 250*760c253cSXin Li suite = benchmark_settings.GetField("suite") 251*760c253cSXin Li retries = benchmark_settings.GetField("retries") 252*760c253cSXin Li run_local = benchmark_settings.GetField("run_local") 253*760c253cSXin Li weight = benchmark_settings.GetField("weight") 254*760c253cSXin Li if weight: 255*760c253cSXin Li if not cwp_dso: 256*760c253cSXin Li raise RuntimeError( 257*760c253cSXin Li "Weight can only be set when DSO specified" 258*760c253cSXin Li ) 259*760c253cSXin Li if suite != "telemetry_Crosperf": 260*760c253cSXin Li raise RuntimeError( 261*760c253cSXin Li "CWP approximation weight only works with " 262*760c253cSXin Li "telemetry_Crosperf suite" 263*760c253cSXin Li ) 264*760c253cSXin Li if run_local: 265*760c253cSXin Li raise RuntimeError( 266*760c253cSXin Li "run_local must be set to False to use CWP " 267*760c253cSXin Li "approximation" 268*760c253cSXin Li ) 269*760c253cSXin Li if weight < 0: 270*760c253cSXin Li raise RuntimeError("Weight should be a float >=0") 271*760c253cSXin Li elif cwp_dso: 272*760c253cSXin Li raise RuntimeError( 273*760c253cSXin Li "With DSO specified, each benchmark should have a " "weight" 274*760c253cSXin Li ) 275*760c253cSXin Li 276*760c253cSXin Li if suite == "telemetry_Crosperf": 277*760c253cSXin Li if test_name == "all_crosbolt_perf": 278*760c253cSXin Li self.AppendBenchmarkSet( 279*760c253cSXin Li benchmarks, 280*760c253cSXin Li telemetry_crosbolt_perf_tests, 281*760c253cSXin Li test_args, 282*760c253cSXin Li iterations, 283*760c253cSXin Li rm_chroot_tmp, 284*760c253cSXin Li perf_args, 285*760c253cSXin Li "telemetry_Crosperf", 286*760c253cSXin Li show_all_results, 287*760c253cSXin Li retries, 288*760c253cSXin Li run_local, 289*760c253cSXin Li cwp_dso, 290*760c253cSXin Li weight, 291*760c253cSXin Li ) 292*760c253cSXin Li self.AppendBenchmarkSet( 293*760c253cSXin Li benchmarks, 294*760c253cSXin Li crosbolt_perf_tests, 295*760c253cSXin Li "", 296*760c253cSXin Li iterations, 297*760c253cSXin Li rm_chroot_tmp, 298*760c253cSXin Li perf_args, 299*760c253cSXin Li "", 300*760c253cSXin Li show_all_results, 301*760c253cSXin Li retries, 302*760c253cSXin Li run_local=False, 303*760c253cSXin Li cwp_dso=cwp_dso, 304*760c253cSXin Li weight=weight, 305*760c253cSXin Li ) 306*760c253cSXin Li elif test_name == "all_toolchain_perf": 307*760c253cSXin Li self.AppendBenchmarkSet( 308*760c253cSXin Li benchmarks, 309*760c253cSXin Li telemetry_toolchain_perf_tests, 310*760c253cSXin Li test_args, 311*760c253cSXin Li iterations, 312*760c253cSXin Li rm_chroot_tmp, 313*760c253cSXin Li perf_args, 314*760c253cSXin Li suite, 315*760c253cSXin Li show_all_results, 316*760c253cSXin Li retries, 317*760c253cSXin Li run_local, 318*760c253cSXin Li cwp_dso, 319*760c253cSXin Li weight, 320*760c253cSXin Li ) 321*760c253cSXin Li # Add non-telemetry toolchain-perf benchmarks: 322*760c253cSXin Li 323*760c253cSXin Li # TODO: crbug.com/1057755 Do not enable graphics_WebGLAquarium until 324*760c253cSXin Li # it gets fixed. 325*760c253cSXin Li # 326*760c253cSXin Li # benchmarks.append( 327*760c253cSXin Li # Benchmark( 328*760c253cSXin Li # 'graphics_WebGLAquarium', 329*760c253cSXin Li # 'graphics_WebGLAquarium', 330*760c253cSXin Li # '', 331*760c253cSXin Li # iterations, 332*760c253cSXin Li # rm_chroot_tmp, 333*760c253cSXin Li # perf_args, 334*760c253cSXin Li # 'crosperf_Wrapper', # Use client wrapper in Autotest 335*760c253cSXin Li # show_all_results, 336*760c253cSXin Li # retries, 337*760c253cSXin Li # run_local=False, 338*760c253cSXin Li # cwp_dso=cwp_dso, 339*760c253cSXin Li # weight=weight)) 340*760c253cSXin Li else: 341*760c253cSXin Li benchmark = Benchmark( 342*760c253cSXin Li benchmark_name, 343*760c253cSXin Li test_name, 344*760c253cSXin Li test_args, 345*760c253cSXin Li iterations, 346*760c253cSXin Li rm_chroot_tmp, 347*760c253cSXin Li perf_args, 348*760c253cSXin Li suite, 349*760c253cSXin Li show_all_results, 350*760c253cSXin Li retries, 351*760c253cSXin Li run_local, 352*760c253cSXin Li cwp_dso, 353*760c253cSXin Li weight, 354*760c253cSXin Li ) 355*760c253cSXin Li benchmarks.append(benchmark) 356*760c253cSXin Li else: 357*760c253cSXin Li if test_name == "all_graphics_perf": 358*760c253cSXin Li self.AppendBenchmarkSet( 359*760c253cSXin Li benchmarks, 360*760c253cSXin Li graphics_perf_tests, 361*760c253cSXin Li "", 362*760c253cSXin Li iterations, 363*760c253cSXin Li rm_chroot_tmp, 364*760c253cSXin Li perf_args, 365*760c253cSXin Li "", 366*760c253cSXin Li show_all_results, 367*760c253cSXin Li retries, 368*760c253cSXin Li run_local=False, 369*760c253cSXin Li cwp_dso=cwp_dso, 370*760c253cSXin Li weight=weight, 371*760c253cSXin Li ) 372*760c253cSXin Li else: 373*760c253cSXin Li # Add the single benchmark. 374*760c253cSXin Li benchmark = Benchmark( 375*760c253cSXin Li benchmark_name, 376*760c253cSXin Li test_name, 377*760c253cSXin Li test_args, 378*760c253cSXin Li iterations, 379*760c253cSXin Li rm_chroot_tmp, 380*760c253cSXin Li perf_args, 381*760c253cSXin Li suite, 382*760c253cSXin Li show_all_results, 383*760c253cSXin Li retries, 384*760c253cSXin Li run_local=False, 385*760c253cSXin Li cwp_dso=cwp_dso, 386*760c253cSXin Li weight=weight, 387*760c253cSXin Li ) 388*760c253cSXin Li benchmarks.append(benchmark) 389*760c253cSXin Li 390*760c253cSXin Li if not benchmarks: 391*760c253cSXin Li raise RuntimeError("No benchmarks specified") 392*760c253cSXin Li 393*760c253cSXin Li # Construct labels. 394*760c253cSXin Li # Some fields are common with global settings. The values are 395*760c253cSXin Li # inherited and/or merged with the global settings values. 396*760c253cSXin Li labels = [] 397*760c253cSXin Li all_label_settings = experiment_file.GetSettings("label") 398*760c253cSXin Li all_remote = list(remote) 399*760c253cSXin Li for label_settings in all_label_settings: 400*760c253cSXin Li label_name = label_settings.name 401*760c253cSXin Li image = label_settings.GetField("chromeos_image") 402*760c253cSXin Li build = label_settings.GetField("build") 403*760c253cSXin Li autotest_path = label_settings.GetField("autotest_path") 404*760c253cSXin Li debug_path = label_settings.GetField("debug_path") 405*760c253cSXin Li chromeos_root = label_settings.GetField("chromeos_root") 406*760c253cSXin Li my_remote = label_settings.GetField("remote") 407*760c253cSXin Li compiler = label_settings.GetField("compiler") 408*760c253cSXin Li new_remote = [] 409*760c253cSXin Li if my_remote: 410*760c253cSXin Li for i in my_remote: 411*760c253cSXin Li c = re.sub("[\"']", "", i) 412*760c253cSXin Li new_remote.append(c) 413*760c253cSXin Li my_remote = new_remote 414*760c253cSXin Li 415*760c253cSXin Li if image: 416*760c253cSXin Li if crosfleet: 417*760c253cSXin Li raise RuntimeError( 418*760c253cSXin Li "In crosfleet mode, local image should not be used." 419*760c253cSXin Li ) 420*760c253cSXin Li if build: 421*760c253cSXin Li raise RuntimeError( 422*760c253cSXin Li "Image path and build are provided at the same " 423*760c253cSXin Li "time, please use only one of them." 424*760c253cSXin Li ) 425*760c253cSXin Li else: 426*760c253cSXin Li if not build: 427*760c253cSXin Li raise RuntimeError("Can not have empty 'build' field!") 428*760c253cSXin Li image, autotest_path, debug_path = label_settings.GetXbuddyPath( 429*760c253cSXin Li build, 430*760c253cSXin Li autotest_path, 431*760c253cSXin Li debug_path, 432*760c253cSXin Li board, 433*760c253cSXin Li chromeos_root, 434*760c253cSXin Li log_level, 435*760c253cSXin Li download_debug, 436*760c253cSXin Li ) 437*760c253cSXin Li 438*760c253cSXin Li cache_dir = label_settings.GetField("cache_dir") 439*760c253cSXin Li chrome_src = label_settings.GetField("chrome_src") 440*760c253cSXin Li 441*760c253cSXin Li # TODO(yunlian): We should consolidate code in machine_manager.py 442*760c253cSXin Li # to derermine whether we are running from within google or not 443*760c253cSXin Li if ( 444*760c253cSXin Li "corp.google.com" in socket.gethostname() 445*760c253cSXin Li and not my_remote 446*760c253cSXin Li and not crosfleet 447*760c253cSXin Li ): 448*760c253cSXin Li my_remote = self.GetDefaultRemotes(board) 449*760c253cSXin Li if global_settings.GetField("same_machine") and len(my_remote) > 1: 450*760c253cSXin Li raise RuntimeError( 451*760c253cSXin Li "Only one remote is allowed when same_machine " 452*760c253cSXin Li "is turned on" 453*760c253cSXin Li ) 454*760c253cSXin Li all_remote += my_remote 455*760c253cSXin Li image_args = label_settings.GetField("image_args") 456*760c253cSXin Li if test_flag.GetTestMode(): 457*760c253cSXin Li # pylint: disable=too-many-function-args 458*760c253cSXin Li label = MockLabel( 459*760c253cSXin Li label_name, 460*760c253cSXin Li build, 461*760c253cSXin Li image, 462*760c253cSXin Li autotest_path, 463*760c253cSXin Li debug_path, 464*760c253cSXin Li chromeos_root, 465*760c253cSXin Li board, 466*760c253cSXin Li my_remote, 467*760c253cSXin Li image_args, 468*760c253cSXin Li cache_dir, 469*760c253cSXin Li cache_only, 470*760c253cSXin Li log_level, 471*760c253cSXin Li compiler, 472*760c253cSXin Li crosfleet, 473*760c253cSXin Li chrome_src, 474*760c253cSXin Li ) 475*760c253cSXin Li else: 476*760c253cSXin Li label = Label( 477*760c253cSXin Li label_name, 478*760c253cSXin Li build, 479*760c253cSXin Li image, 480*760c253cSXin Li autotest_path, 481*760c253cSXin Li debug_path, 482*760c253cSXin Li chromeos_root, 483*760c253cSXin Li board, 484*760c253cSXin Li my_remote, 485*760c253cSXin Li image_args, 486*760c253cSXin Li cache_dir, 487*760c253cSXin Li cache_only, 488*760c253cSXin Li log_level, 489*760c253cSXin Li compiler, 490*760c253cSXin Li crosfleet, 491*760c253cSXin Li chrome_src, 492*760c253cSXin Li ) 493*760c253cSXin Li labels.append(label) 494*760c253cSXin Li 495*760c253cSXin Li if not labels: 496*760c253cSXin Li raise RuntimeError("No labels specified") 497*760c253cSXin Li 498*760c253cSXin Li email = global_settings.GetField("email") 499*760c253cSXin Li all_remote += list(set(my_remote)) 500*760c253cSXin Li all_remote = list(set(all_remote)) 501*760c253cSXin Li if crosfleet: 502*760c253cSXin Li for remote in all_remote: 503*760c253cSXin Li self.CheckRemotesInCrosfleet(remote) 504*760c253cSXin Li experiment = Experiment( 505*760c253cSXin Li experiment_name, 506*760c253cSXin Li all_remote, 507*760c253cSXin Li working_directory, 508*760c253cSXin Li chromeos_root, 509*760c253cSXin Li cache_conditions, 510*760c253cSXin Li labels, 511*760c253cSXin Li benchmarks, 512*760c253cSXin Li experiment_file.Canonicalize(), 513*760c253cSXin Li email, 514*760c253cSXin Li acquire_timeout, 515*760c253cSXin Li log_dir, 516*760c253cSXin Li log_level, 517*760c253cSXin Li share_cache, 518*760c253cSXin Li results_dir, 519*760c253cSXin Li compress_results, 520*760c253cSXin Li locks_dir, 521*760c253cSXin Li cwp_dso, 522*760c253cSXin Li ignore_min_max, 523*760c253cSXin Li crosfleet, 524*760c253cSXin Li dut_config, 525*760c253cSXin Li keep_stateful, 526*760c253cSXin Li no_lock=no_lock, 527*760c253cSXin Li ) 528*760c253cSXin Li 529*760c253cSXin Li return experiment 530*760c253cSXin Li 531*760c253cSXin Li def GetDefaultRemotes(self, board): 532*760c253cSXin Li default_remotes_file = os.path.join( 533*760c253cSXin Li os.path.dirname(__file__), "default_remotes" 534*760c253cSXin Li ) 535*760c253cSXin Li try: 536*760c253cSXin Li with open(default_remotes_file, encoding="utf-8") as f: 537*760c253cSXin Li for line in f: 538*760c253cSXin Li key, v = line.split(":") 539*760c253cSXin Li if key.strip() == board: 540*760c253cSXin Li remotes = v.strip().split() 541*760c253cSXin Li if remotes: 542*760c253cSXin Li return remotes 543*760c253cSXin Li else: 544*760c253cSXin Li raise RuntimeError( 545*760c253cSXin Li f"There is no remote for {board}" 546*760c253cSXin Li ) 547*760c253cSXin Li except IOError: 548*760c253cSXin Li # TODO: rethrow instead of throwing different exception. 549*760c253cSXin Li raise RuntimeError( 550*760c253cSXin Li f"IOError while reading file {default_remotes_file}" 551*760c253cSXin Li ) 552*760c253cSXin Li else: 553*760c253cSXin Li raise RuntimeError(f"There is no remote for {board}") 554*760c253cSXin Li 555*760c253cSXin Li def CheckRemotesInCrosfleet(self, remote): 556*760c253cSXin Li # TODO: (AI:zhizhouy) need to check whether a remote is a local or lab 557*760c253cSXin Li # machine. If not lab machine, raise an error. 558*760c253cSXin Li pass 559*760c253cSXin Li 560*760c253cSXin Li def CheckCrosfleetTool(self, chromeos_root, log_level): 561*760c253cSXin Li CROSFLEET_PATH = "crosfleet" 562*760c253cSXin Li if os.path.exists(CROSFLEET_PATH): 563*760c253cSXin Li return True 564*760c253cSXin Li l = logger.GetLogger() 565*760c253cSXin Li l.LogOutput("Crosfleet tool not installed, trying to install it.") 566*760c253cSXin Li ce = command_executer.GetCommandExecuter(l, log_level=log_level) 567*760c253cSXin Li setup_lab_tools = os.path.join( 568*760c253cSXin Li chromeos_root, "chromeos-admin", "lab-tools", "setup_lab_tools" 569*760c253cSXin Li ) 570*760c253cSXin Li cmd = "%s" % setup_lab_tools 571*760c253cSXin Li status = ce.RunCommand(cmd) 572*760c253cSXin Li if status != 0: 573*760c253cSXin Li raise RuntimeError( 574*760c253cSXin Li "Crosfleet tool not installed correctly, please try to " 575*760c253cSXin Li "manually install it from %s" % setup_lab_tools 576*760c253cSXin Li ) 577*760c253cSXin Li l.LogOutput( 578*760c253cSXin Li "Crosfleet is installed at %s, please login before first use. " 579*760c253cSXin Li 'Login by running "crosfleet login" and follow instructions.' 580*760c253cSXin Li % CROSFLEET_PATH 581*760c253cSXin Li ) 582*760c253cSXin Li return False 583