experiment_factory.py revision b47bff4d3336c5fe5593a95963c0f3dc20a02f68
1#!/usr/bin/python 2 3# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""A module to generate experments.""" 8 9import os 10import re 11import socket 12 13from benchmark import Benchmark 14import config 15from experiment import Experiment 16from label import Label 17from label import MockLabel 18from results_cache import CacheConditions 19import test_flag 20 21 22class ExperimentFactory(object): 23 """Factory class for building an Experiment, given an ExperimentFile as input. 24 25 This factory is currently hardcoded to produce an experiment for running 26 ChromeOS benchmarks, but the idea is that in the future, other types 27 of experiments could be produced. 28 """ 29 30 def GetExperiment(self, experiment_file, working_directory, log_dir): 31 """Construct an experiment from an experiment file.""" 32 global_settings = experiment_file.GetGlobalSettings() 33 experiment_name = global_settings.GetField("name") 34 remote = global_settings.GetField("remote") 35 # This is used to remove the ",' from the remote if user 36 # add them to the remote string. 37 new_remote = [] 38 for i in remote: 39 c = re.sub('["\']', '', i) 40 new_remote.append(c) 41 remote = new_remote 42 chromeos_root = global_settings.GetField("chromeos_root") 43 rm_chroot_tmp = global_settings.GetField("rm_chroot_tmp") 44 key_results_only = global_settings.GetField("key_results_only") 45 acquire_timeout= global_settings.GetField("acquire_timeout") 46 cache_dir = global_settings.GetField("cache_dir") 47 config.AddConfig("no_email", global_settings.GetField("no_email")) 48 share_users = global_settings.GetField("share_users") 49 results_dir = global_settings.GetField("results_dir") 50 chrome_src = global_settings.GetField("chrome_src") 51 use_test_that = global_settings.GetField("use_test_that") 52 # Default cache hit conditions. The image checksum in the cache and the 53 # computed checksum of the image must match. Also a cache file must exist. 54 cache_conditions = [CacheConditions.CACHE_FILE_EXISTS, 55 CacheConditions.CHECKSUMS_MATCH] 56 if global_settings.GetField("rerun_if_failed"): 57 cache_conditions.append(CacheConditions.RUN_SUCCEEDED) 58 if global_settings.GetField("rerun"): 59 cache_conditions.append(CacheConditions.FALSE) 60 if global_settings.GetField("same_machine"): 61 cache_conditions.append(CacheConditions.SAME_MACHINE_MATCH) 62 if global_settings.GetField("same_specs"): 63 cache_conditions.append(CacheConditions.MACHINES_MATCH) 64 65 # Construct benchmarks. 66 benchmarks = [] 67 all_benchmark_settings = experiment_file.GetSettings("benchmark") 68 for benchmark_settings in all_benchmark_settings: 69 benchmark_name = benchmark_settings.name 70 test_name = benchmark_settings.GetField("test_name") 71 if not test_name: 72 test_name = benchmark_name 73 test_args = benchmark_settings.GetField("test_args") 74 iterations = benchmark_settings.GetField("iterations") 75 outlier_range = benchmark_settings.GetField("outlier_range") 76 perf_args = benchmark_settings.GetField("perf_args") 77 rm_chroot_tmp = benchmark_settings.GetField("rm_chroot_tmp") 78 key_results_only = benchmark_settings.GetField("key_results_only") 79 suite = benchmark_settings.GetField("suite") 80 use_test_that = benchmark_settings.GetField("use_test_that") 81 82 benchmark = Benchmark(benchmark_name, test_name, test_args, 83 iterations, outlier_range, 84 key_results_only, rm_chroot_tmp, 85 perf_args, suite, use_test_that) 86 benchmarks.append(benchmark) 87 88 # Construct labels. 89 labels = [] 90 all_label_settings = experiment_file.GetSettings("label") 91 all_remote = list(remote) 92 for label_settings in all_label_settings: 93 label_name = label_settings.name 94 image = label_settings.GetField("chromeos_image") 95 chromeos_root = label_settings.GetField("chromeos_root") 96 board = label_settings.GetField("board") 97 my_remote = label_settings.GetField("remote") 98 new_remote = [] 99 for i in my_remote: 100 c = re.sub('["\']', '', i) 101 new_remote.append(c) 102 my_remote = new_remote 103 104 image_md5sum = label_settings.GetField("md5sum") 105 cache_dir = label_settings.GetField("cache_dir") 106 chrome_src = label_settings.GetField("chrome_src") 107 108 # TODO(yunlian): We should consolidate code in machine_manager.py 109 # to derermine whether we are running from within google or not 110 if ("corp.google.com" in socket.gethostname() and 111 (not my_remote 112 or my_remote == remote 113 and global_settings.GetField("board") != board)): 114 my_remote = self.GetDefaultRemotes(board) 115 if global_settings.GetField("same_machine") and len(my_remote) > 1: 116 raise Exception("Only one remote is allowed when same_machine " 117 "is turned on") 118 all_remote += my_remote 119 image_args = label_settings.GetField("image_args") 120 if test_flag.GetTestMode(): 121 label = MockLabel(label_name, image, chromeos_root, board, my_remote, 122 image_args, image_md5sum, cache_dir, chrome_src) 123 else: 124 label = Label(label_name, image, chromeos_root, board, my_remote, 125 image_args, image_md5sum, cache_dir, chrome_src) 126 labels.append(label) 127 128 email = global_settings.GetField("email") 129 all_remote = list(set(all_remote)) 130 experiment = Experiment(experiment_name, all_remote, 131 working_directory, chromeos_root, 132 cache_conditions, labels, benchmarks, 133 experiment_file.Canonicalize(), 134 email, acquire_timeout, log_dir, share_users, 135 results_dir) 136 137 return experiment 138 139 def GetDefaultRemotes(self, board): 140 default_remotes_file = os.path.join(os.path.dirname(__file__), 141 "default_remotes") 142 try: 143 with open(default_remotes_file) as f: 144 for line in f: 145 key, v = line.split(":") 146 if key.strip() == board: 147 remotes = v.strip().split(" ") 148 if remotes: 149 return remotes 150 else: 151 raise Exception("There is not remote for {0}".format(board)) 152 except IOError: 153 raise Exception("IOError while reading file {0}" 154 .format(default_remotes_file)) 155 else: 156 raise Exception("There is not remote for {0}".format(board)) 157 158 159 160