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