experiment.py revision 5c09fc2966ac49263ce7154c2905f2a86aeda297
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"""The experiment setting module."""
8
9import os
10import time
11
12from utils import logger
13from utils import misc
14
15from benchmark_run import BenchmarkRun
16from machine_manager import MachineManager
17from machine_manager import MockMachineManager
18import test_flag
19
20
21class Experiment(object):
22  """Class representing an Experiment to be run."""
23
24  def __init__(self, name, remote, working_directory,
25               chromeos_root, cache_conditions, labels, benchmarks,
26               experiment_file, email_to, acquire_timeout, log_dir,
27               log_level, share_cache, results_directory, locks_directory):
28    self.name = name
29    self.working_directory = working_directory
30    self.remote = remote
31    self.chromeos_root = chromeos_root
32    self.cache_conditions = cache_conditions
33    self.experiment_file = experiment_file
34    self.email_to = email_to
35    if not results_directory:
36      self.results_directory = os.path.join(self.working_directory,
37                                            self.name + "_results")
38    else:
39      self.results_directory = misc.CanonicalizePath(results_directory)
40    self.log_dir = log_dir
41    self.log_level = log_level
42    self.labels = labels
43    self.benchmarks = benchmarks
44    self.num_complete = 0
45    self.num_run_complete = 0
46    self.share_cache = share_cache
47
48    # We need one chromeos_root to run the benchmarks in, but it doesn't
49    # matter where it is, unless the ABIs are different.
50    if not chromeos_root:
51      for label in self.labels:
52        if label.chromeos_root:
53          chromeos_root = label.chromeos_root
54    if not chromeos_root:
55      raise Exception("No chromeos_root given and could not determine one from "
56                      "the image path.")
57
58    if test_flag.GetTestMode():
59      self.machine_manager = MockMachineManager(chromeos_root, acquire_timeout,
60                                                log_level)
61    else:
62      self.machine_manager = MachineManager(chromeos_root, acquire_timeout,
63                                            log_level, locks_directory)
64    self.l = logger.GetLogger(log_dir)
65
66    for machine in remote:
67      self.machine_manager.AddMachine(machine)
68    for label in labels:
69      self.machine_manager.ComputeCommonCheckSum(label)
70      self.machine_manager.ComputeCommonCheckSumString(label)
71
72    self.start_time = None
73    self.benchmark_runs = self._GenerateBenchmarkRuns()
74
75  def _GenerateBenchmarkRuns(self):
76    """Generate benchmark runs from labels and benchmark defintions."""
77    benchmark_runs = []
78    for label in self.labels:
79      for benchmark in self.benchmarks:
80        for iteration in range(1, benchmark.iterations + 1):
81
82          benchmark_run_name = "%s: %s (%s)" % (label.name, benchmark.name,
83                                                iteration)
84          full_name = "%s_%s_%s" % (label.name, benchmark.name, iteration)
85          logger_to_use = logger.Logger(self.log_dir,
86                                        "run.%s" % (full_name),
87                                        True)
88          benchmark_run = BenchmarkRun(benchmark_run_name,
89                                       benchmark,
90                                       label,
91                                       iteration,
92                                       self.cache_conditions,
93                                       self.machine_manager,
94                                       logger_to_use,
95                                       self.log_level,
96                                       self.share_cache)
97
98          benchmark_runs.append(benchmark_run)
99    return benchmark_runs
100
101  def Build(self):
102    pass
103
104  def Terminate(self):
105    for t in self.benchmark_runs:
106      if t.isAlive():
107        self.l.LogError("Terminating run: '%s'." % t.name)
108        t.Terminate()
109
110  def IsComplete(self):
111    if self.active_threads:
112      for t in self.active_threads:
113        if t.isAlive():
114          t.join(0)
115        if not t.isAlive():
116          self.num_complete += 1
117          if not t.cache_hit:
118            self.num_run_complete += 1
119          self.active_threads.remove(t)
120      return False
121    return True
122
123  def Run(self):
124    self.start_time = time.time()
125    self.active_threads = []
126    for benchmark_run in self.benchmark_runs:
127      # Set threads to daemon so program exits when ctrl-c is pressed.
128      benchmark_run.daemon = True
129      benchmark_run.start()
130      self.active_threads.append(benchmark_run)
131
132  def SetCacheConditions(self, cache_conditions):
133    for benchmark_run in self.benchmark_runs:
134      benchmark_run.SetCacheConditions(cache_conditions)
135
136  def Cleanup(self):
137    self.machine_manager.Cleanup()
138