blob: 9f88ed0147fe92f2dc33ced5d5a2a60f29d3de42 [file] [log] [blame]
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08001#!/usr/bin/python
2
Yunlian Jiang00cc30e2013-03-28 13:23:57 -07003# 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.
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08006
Ahmad Sharif4467f002012-12-20 12:09:49 -08007"""The experiment setting module."""
8
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08009import os
10import time
Ahmad Sharif4467f002012-12-20 12:09:49 -080011
cmticee5bc63b2015-05-27 16:59:37 -070012import afe_lock_machine
13
Ahmad Sharif4467f002012-12-20 12:09:49 -080014from utils import logger
Yunlian Jiang00cc30e2013-03-28 13:23:57 -070015from utils import misc
Ahmad Sharif4467f002012-12-20 12:09:49 -080016
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080017from benchmark_run import BenchmarkRun
18from machine_manager import MachineManager
Ahmad Sharif4467f002012-12-20 12:09:49 -080019from machine_manager import MockMachineManager
Ahmad Sharif4467f002012-12-20 12:09:49 -080020import test_flag
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080021
22
23class Experiment(object):
24 """Class representing an Experiment to be run."""
25
Luis Lozanof81680c2013-03-15 14:44:13 -070026 def __init__(self, name, remote, working_directory,
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080027 chromeos_root, cache_conditions, labels, benchmarks,
Luis Lozanof81680c2013-03-15 14:44:13 -070028 experiment_file, email_to, acquire_timeout, log_dir,
cmtice5c09fc22015-04-22 09:25:53 -070029 log_level, share_cache, results_directory, locks_directory):
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080030 self.name = name
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080031 self.working_directory = working_directory
32 self.remote = remote
33 self.chromeos_root = chromeos_root
34 self.cache_conditions = cache_conditions
35 self.experiment_file = experiment_file
Ahmad Shariff395c262012-10-09 17:48:09 -070036 self.email_to = email_to
Yunlian Jiang00cc30e2013-03-28 13:23:57 -070037 if not results_directory:
38 self.results_directory = os.path.join(self.working_directory,
39 self.name + "_results")
40 else:
41 self.results_directory = misc.CanonicalizePath(results_directory)
Luis Lozanof81680c2013-03-15 14:44:13 -070042 self.log_dir = log_dir
cmtice13909242014-03-11 13:38:07 -070043 self.log_level = log_level
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080044 self.labels = labels
45 self.benchmarks = benchmarks
46 self.num_complete = 0
Ahmad Sharif4467f002012-12-20 12:09:49 -080047 self.num_run_complete = 0
cmtice1a224362014-10-16 15:49:56 -070048 self.share_cache = share_cache
cmtice517dc982015-06-12 12:22:32 -070049 # If locks_directory (self.lock_dir) not blank, we will use the file
50 # locking mechanism; if it is blank then we will use the AFE server
51 # locking mechanism.
52 self.locks_dir = locks_directory
cmticef3eb8032015-07-27 13:55:52 -070053 self.locked_machines = []
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080054
55 # We need one chromeos_root to run the benchmarks in, but it doesn't
56 # matter where it is, unless the ABIs are different.
57 if not chromeos_root:
58 for label in self.labels:
59 if label.chromeos_root:
60 chromeos_root = label.chromeos_root
61 if not chromeos_root:
62 raise Exception("No chromeos_root given and could not determine one from "
63 "the image path.")
64
Ahmad Sharif4467f002012-12-20 12:09:49 -080065 if test_flag.GetTestMode():
cmtice13909242014-03-11 13:38:07 -070066 self.machine_manager = MockMachineManager(chromeos_root, acquire_timeout,
cmticed96e4572015-05-19 16:19:25 -070067 log_level, locks_directory)
Ahmad Sharif4467f002012-12-20 12:09:49 -080068 else:
cmtice13909242014-03-11 13:38:07 -070069 self.machine_manager = MachineManager(chromeos_root, acquire_timeout,
cmtice517dc982015-06-12 12:22:32 -070070 log_level, locks_directory)
Luis Lozanof81680c2013-03-15 14:44:13 -070071 self.l = logger.GetLogger(log_dir)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080072
73 for machine in remote:
74 self.machine_manager.AddMachine(machine)
Ahmad Sharif4467f002012-12-20 12:09:49 -080075 for label in labels:
76 self.machine_manager.ComputeCommonCheckSum(label)
77 self.machine_manager.ComputeCommonCheckSumString(label)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080078
79 self.start_time = None
80 self.benchmark_runs = self._GenerateBenchmarkRuns()
81
82 def _GenerateBenchmarkRuns(self):
83 """Generate benchmark runs from labels and benchmark defintions."""
84 benchmark_runs = []
85 for label in self.labels:
86 for benchmark in self.benchmarks:
87 for iteration in range(1, benchmark.iterations + 1):
88
89 benchmark_run_name = "%s: %s (%s)" % (label.name, benchmark.name,
90 iteration)
91 full_name = "%s_%s_%s" % (label.name, benchmark.name, iteration)
Luis Lozanof81680c2013-03-15 14:44:13 -070092 logger_to_use = logger.Logger(self.log_dir,
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080093 "run.%s" % (full_name),
cmtice77892942014-03-18 13:47:17 -070094 True)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080095 benchmark_run = BenchmarkRun(benchmark_run_name,
Ahmad Sharif4467f002012-12-20 12:09:49 -080096 benchmark,
97 label,
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080098 iteration,
99 self.cache_conditions,
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800100 self.machine_manager,
Luis Lozanof81680c2013-03-15 14:44:13 -0700101 logger_to_use,
cmtice13909242014-03-11 13:38:07 -0700102 self.log_level,
cmtice1a224362014-10-16 15:49:56 -0700103 self.share_cache)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800104
105 benchmark_runs.append(benchmark_run)
106 return benchmark_runs
107
108 def Build(self):
109 pass
110
111 def Terminate(self):
112 for t in self.benchmark_runs:
113 if t.isAlive():
114 self.l.LogError("Terminating run: '%s'." % t.name)
115 t.Terminate()
116
117 def IsComplete(self):
118 if self.active_threads:
119 for t in self.active_threads:
120 if t.isAlive():
121 t.join(0)
122 if not t.isAlive():
123 self.num_complete += 1
Ahmad Sharif4467f002012-12-20 12:09:49 -0800124 if not t.cache_hit:
125 self.num_run_complete += 1
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800126 self.active_threads.remove(t)
127 return False
128 return True
129
130 def Run(self):
131 self.start_time = time.time()
132 self.active_threads = []
133 for benchmark_run in self.benchmark_runs:
134 # Set threads to daemon so program exits when ctrl-c is pressed.
135 benchmark_run.daemon = True
136 benchmark_run.start()
137 self.active_threads.append(benchmark_run)
138
139 def SetCacheConditions(self, cache_conditions):
140 for benchmark_run in self.benchmark_runs:
141 benchmark_run.SetCacheConditions(cache_conditions)
142
143 def Cleanup(self):
cmticee5bc63b2015-05-27 16:59:37 -0700144 """Make sure all machines are unlocked."""
cmtice517dc982015-06-12 12:22:32 -0700145 if self.locks_dir:
146 # We are using the file locks mechanism, so call machine_manager.Cleanup
147 # to unlock everything.
148 self.machine_manager.Cleanup()
149 else:
cmticef3eb8032015-07-27 13:55:52 -0700150 all_machines = self.locked_machines
151 if not all_machines:
152 return
153
154 # If we locked any machines earlier, make sure we unlock them now.
cmtice517dc982015-06-12 12:22:32 -0700155 lock_mgr = afe_lock_machine.AFELockManager(all_machines, "",
156 self.labels[0].chromeos_root,
157 None)
158 machine_states = lock_mgr.GetMachineStates("unlock")
159 for k, state in machine_states.iteritems():
160 if state["locked"]:
161 lock_mgr.UpdateLockInAFE(False, k)