blob: c6371318c956e650287e88e22a745728db975aac [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""The experiment setting module."""
import os
import time
from utils import logger
from utils import misc
from benchmark_run import BenchmarkRun
from machine_manager import MachineManager
from machine_manager import MockMachineManager
import test_flag
class Experiment(object):
"""Class representing an Experiment to be run."""
def __init__(self, name, remote, working_directory,
chromeos_root, cache_conditions, labels, benchmarks,
experiment_file, email_to, acquire_timeout, log_dir,
log_level, share_users, results_directory):
self.name = name
self.working_directory = working_directory
self.remote = remote
self.chromeos_root = chromeos_root
self.cache_conditions = cache_conditions
self.experiment_file = experiment_file
self.email_to = email_to
if not results_directory:
self.results_directory = os.path.join(self.working_directory,
self.name + "_results")
else:
self.results_directory = misc.CanonicalizePath(results_directory)
self.log_dir = log_dir
self.log_level = log_level
self.labels = labels
self.benchmarks = benchmarks
self.num_complete = 0
self.num_run_complete = 0
self.share_users = share_users
# We need one chromeos_root to run the benchmarks in, but it doesn't
# matter where it is, unless the ABIs are different.
if not chromeos_root:
for label in self.labels:
if label.chromeos_root:
chromeos_root = label.chromeos_root
if not chromeos_root:
raise Exception("No chromeos_root given and could not determine one from "
"the image path.")
if test_flag.GetTestMode():
self.machine_manager = MockMachineManager(chromeos_root, acquire_timeout,
log_level)
else:
self.machine_manager = MachineManager(chromeos_root, acquire_timeout,
log_level)
self.l = logger.GetLogger(log_dir)
for machine in remote:
self.machine_manager.AddMachine(machine)
for label in labels:
self.machine_manager.ComputeCommonCheckSum(label)
self.machine_manager.ComputeCommonCheckSumString(label)
self.start_time = None
self.benchmark_runs = self._GenerateBenchmarkRuns()
def _GenerateBenchmarkRuns(self):
"""Generate benchmark runs from labels and benchmark defintions."""
benchmark_runs = []
for label in self.labels:
for benchmark in self.benchmarks:
for iteration in range(1, benchmark.iterations + 1):
benchmark_run_name = "%s: %s (%s)" % (label.name, benchmark.name,
iteration)
full_name = "%s_%s_%s" % (label.name, benchmark.name, iteration)
logger_to_use = logger.Logger(self.log_dir,
"run.%s" % (full_name),
True)
benchmark_run = BenchmarkRun(benchmark_run_name,
benchmark,
label,
iteration,
self.cache_conditions,
self.machine_manager,
logger_to_use,
self.log_level,
self.share_users)
benchmark_runs.append(benchmark_run)
return benchmark_runs
def Build(self):
pass
def Terminate(self):
for t in self.benchmark_runs:
if t.isAlive():
self.l.LogError("Terminating run: '%s'." % t.name)
t.Terminate()
def IsComplete(self):
if self.active_threads:
for t in self.active_threads:
if t.isAlive():
t.join(0)
if not t.isAlive():
self.num_complete += 1
if not t.cache_hit:
self.num_run_complete += 1
self.active_threads.remove(t)
return False
return True
def Run(self):
self.start_time = time.time()
self.active_threads = []
for benchmark_run in self.benchmark_runs:
# Set threads to daemon so program exits when ctrl-c is pressed.
benchmark_run.daemon = True
benchmark_run.start()
self.active_threads.append(benchmark_run)
def SetCacheConditions(self, cache_conditions):
for benchmark_run in self.benchmark_runs:
benchmark_run.SetCacheConditions(cache_conditions)
def Cleanup(self):
self.machine_manager.Cleanup()