blob: 9212ba56b7adf274c3e0b10d765dc79920404a9b [file] [log] [blame]
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08001#!/usr/bin/python
2
3# Copyright 2011 Google Inc. All Rights Reserved.
4
Ahmad Sharif4467f002012-12-20 12:09:49 -08005"""The experiment runner module."""
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08006import getpass
7import os
8import time
Ahmad Sharif4467f002012-12-20 12:09:49 -08009
Ahmad Shariffd356fb2012-05-07 12:02:16 -070010from utils import command_executer
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080011from utils import logger
12from utils.email_sender import EmailSender
13from utils.file_utils import FileUtils
14
Luis Lozanof81680c2013-03-15 14:44:13 -070015import config
Ahmad Sharif4467f002012-12-20 12:09:49 -080016from experiment_status import ExperimentStatus
17from results_report import HTMLResultsReport
18from results_report import TextResultsReport
19
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080020
21class ExperimentRunner(object):
Ahmad Sharif4467f002012-12-20 12:09:49 -080022 """ExperimentRunner Class."""
23
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080024 STATUS_TIME_DELAY = 30
25 THREAD_MONITOR_DELAY = 2
26
27 def __init__(self, experiment):
28 self._experiment = experiment
Luis Lozanof81680c2013-03-15 14:44:13 -070029 self.l = logger.GetLogger(experiment.log_dir)
Ahmad Shariffd356fb2012-05-07 12:02:16 -070030 self._ce = command_executer.GetCommandExecuter(self.l)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080031 self._terminated = False
32
33 def _Run(self, experiment):
34 status = ExperimentStatus(experiment)
35 experiment.Run()
36 last_status_time = 0
37 try:
38 while not experiment.IsComplete():
39 if last_status_time + self.STATUS_TIME_DELAY < time.time():
40 last_status_time = time.time()
41 border = "=============================="
42 self.l.LogOutput(border)
43 self.l.LogOutput(status.GetProgressString())
44 self.l.LogOutput(status.GetStatusString())
45 logger.GetLogger().LogOutput(border)
46 time.sleep(self.THREAD_MONITOR_DELAY)
47 except KeyboardInterrupt:
48 self._terminated = True
49 self.l.LogError("Ctrl-c pressed. Cleaning up...")
50 experiment.Terminate()
51
52 def _PrintTable(self, experiment):
53 self.l.LogOutput(TextResultsReport(experiment).GetReport())
54
55 def _Email(self, experiment):
56 # Only email by default if a new run was completed.
57 send_mail = False
58 for benchmark_run in experiment.benchmark_runs:
59 if not benchmark_run.cache_hit:
60 send_mail = True
61 break
Luis Lozanof81680c2013-03-15 14:44:13 -070062 if (not send_mail and not experiment.email_to
63 or config.GetConfig("no_email")):
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080064 return
65
66 label_names = []
67 for label in experiment.labels:
68 label_names.append(label.name)
69 subject = "%s: %s" % (experiment.name, " vs. ".join(label_names))
70
Ahmad Shariff395c262012-10-09 17:48:09 -070071 text_report = TextResultsReport(experiment, True).GetReport()
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080072 text_report = "<pre style='font-size: 13px'>%s</pre>" % text_report
73 html_report = HTMLResultsReport(experiment).GetReport()
74 attachment = EmailSender.Attachment("report.html", html_report)
Ahmad Shariff395c262012-10-09 17:48:09 -070075 email_to = [getpass.getuser()] + experiment.email_to
76 EmailSender().SendEmail(email_to,
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080077 subject,
78 text_report,
79 attachments=[attachment],
80 msg_type="html")
81
82 def _StoreResults (self, experiment):
83 if self._terminated:
84 return
85 results_directory = experiment.results_directory
86 FileUtils().RmDir(results_directory)
87 FileUtils().MkDirP(results_directory)
88 self.l.LogOutput("Storing experiment file.")
89 experiment_file_path = os.path.join(results_directory,
90 "experiment.exp")
91 FileUtils().WriteFile(experiment_file_path, experiment.experiment_file)
92
93 self.l.LogOutput("Storing results report.")
94 results_table_path = os.path.join(results_directory, "results.html")
95 report = HTMLResultsReport(experiment).GetReport()
96 FileUtils().WriteFile(results_table_path, report)
97
98 self.l.LogOutput("Storing results of each benchmark run.")
99 for benchmark_run in experiment.benchmark_runs:
Ahmad Shariff395c262012-10-09 17:48:09 -0700100 if benchmark_run.result:
101 benchmark_run_name = filter(str.isalnum, benchmark_run.name)
102 benchmark_run_path = os.path.join(results_directory,
103 benchmark_run_name)
104 benchmark_run.result.CopyResultsTo(benchmark_run_path)
Luis Lozanof81680c2013-03-15 14:44:13 -0700105 benchmark_run.result.CleanUp(benchmark_run.benchmark.rm_chroot_tmp)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800106
107 def Run(self):
108 self._Run(self._experiment)
109 self._PrintTable(self._experiment)
110 if not self._terminated:
111 self._StoreResults(self._experiment)
112 self._Email(self._experiment)
113
114
115class MockExperimentRunner(ExperimentRunner):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800116 """Mocked ExperimentRunner for testing."""
117
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800118 def __init__(self, experiment):
119 super(MockExperimentRunner, self).__init__(experiment)
120
121 def _Run(self, experiment):
122 self.l.LogOutput("Would run the following experiment: '%s'." %
123 experiment.name)
124
125 def _PrintTable(self, experiment):
126 self.l.LogOutput("Would print the experiment table.")
127
128 def _Email(self, experiment):
129 self.l.LogOutput("Would send result email.")
130
131 def _StoreResults(self, experiment):
132 self.l.LogOutput("Would store the results.")