#!/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, 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.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) else: self.machine_manager = MachineManager(chromeos_root, acquire_timeout) 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.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()