experiment_runner.py revision 42709763f709b0e08d4ed041e4374cb9dd5d6570
1#!/usr/bin/python 2 3# Copyright 2011 Google Inc. All Rights Reserved. 4 5"""The experiment runner module.""" 6import getpass 7import os 8import time 9 10from utils import command_executer 11from utils import logger 12from utils.email_sender import EmailSender 13from utils.file_utils import FileUtils 14 15import config 16from experiment_status import ExperimentStatus 17from results_report import HTMLResultsReport 18from results_report import TextResultsReport 19 20 21class ExperimentRunner(object): 22 """ExperimentRunner Class.""" 23 24 STATUS_TIME_DELAY = 30 25 THREAD_MONITOR_DELAY = 2 26 27 def __init__(self, experiment, logger=None, cmd_exec=None): 28 self._experiment = experiment 29 self.l = logger or logger.GetLogger(experiment.log_dir) 30 self._ce = cmd_exec or command_executer.GetCommandExecuter(self.l) 31 self._terminated = False 32 if experiment.log_level != "verbose": 33 self.STATUS_TIME_DELAY = 10 34 35 def _Run(self, experiment): 36 status = ExperimentStatus(experiment) 37 experiment.Run() 38 last_status_time = 0 39 last_status_string = "" 40 try: 41 if experiment.log_level != "verbose": 42 self.l.LogStartDots() 43 while not experiment.IsComplete(): 44 if last_status_time + self.STATUS_TIME_DELAY < time.time(): 45 last_status_time = time.time() 46 border = "==============================" 47 if experiment.log_level == "verbose": 48 self.l.LogOutput(border) 49 self.l.LogOutput(status.GetProgressString()) 50 self.l.LogOutput(status.GetStatusString()) 51 self.l.LogOutput(border) 52 else: 53 current_status_string = status.GetStatusString() 54 if (current_status_string != last_status_string): 55 self.l.LogEndDots() 56 self.l.LogOutput(border) 57 self.l.LogOutput(current_status_string) 58 self.l.LogOutput(border) 59 last_status_string = current_status_string 60 else: 61 self.l.LogAppendDot() 62 time.sleep(self.THREAD_MONITOR_DELAY) 63 except KeyboardInterrupt: 64 self._terminated = True 65 self.l.LogError("Ctrl-c pressed. Cleaning up...") 66 experiment.Terminate() 67 68 def _PrintTable(self, experiment): 69 self.l.LogOutput(TextResultsReport(experiment).GetReport()) 70 71 def _Email(self, experiment): 72 # Only email by default if a new run was completed. 73 send_mail = False 74 for benchmark_run in experiment.benchmark_runs: 75 if not benchmark_run.cache_hit: 76 send_mail = True 77 break 78 if (not send_mail and not experiment.email_to 79 or config.GetConfig("no_email")): 80 return 81 82 label_names = [] 83 for label in experiment.labels: 84 label_names.append(label.name) 85 subject = "%s: %s" % (experiment.name, " vs. ".join(label_names)) 86 87 text_report = TextResultsReport(experiment, True).GetReport() 88 text_report = "<pre style='font-size: 13px'>%s</pre>" % text_report 89 html_report = HTMLResultsReport(experiment).GetReport() 90 attachment = EmailSender.Attachment("report.html", html_report) 91 email_to = [getpass.getuser()] + experiment.email_to 92 EmailSender().SendEmail(email_to, 93 subject, 94 text_report, 95 attachments=[attachment], 96 msg_type="html") 97 98 def _StoreResults (self, experiment): 99 if self._terminated: 100 return 101 results_directory = experiment.results_directory 102 FileUtils().RmDir(results_directory) 103 FileUtils().MkDirP(results_directory) 104 self.l.LogOutput("Storing experiment file in %s." % results_directory) 105 experiment_file_path = os.path.join(results_directory, 106 "experiment.exp") 107 FileUtils().WriteFile(experiment_file_path, experiment.experiment_file) 108 109 self.l.LogOutput("Storing results report in %s." % results_directory) 110 results_table_path = os.path.join(results_directory, "results.html") 111 report = HTMLResultsReport(experiment).GetReport() 112 FileUtils().WriteFile(results_table_path, report) 113 114 self.l.LogOutput("Storing results of each benchmark run.") 115 for benchmark_run in experiment.benchmark_runs: 116 if benchmark_run.result: 117 benchmark_run_name = filter(str.isalnum, benchmark_run.name) 118 benchmark_run_path = os.path.join(results_directory, 119 benchmark_run_name) 120 benchmark_run.result.CopyResultsTo(benchmark_run_path) 121 benchmark_run.result.CleanUp(benchmark_run.benchmark.rm_chroot_tmp) 122 123 def Run(self): 124 self._Run(self._experiment) 125 self._PrintTable(self._experiment) 126 if not self._terminated: 127 self._StoreResults(self._experiment) 128 self._Email(self._experiment) 129 130 131class MockExperimentRunner(ExperimentRunner): 132 """Mocked ExperimentRunner for testing.""" 133 134 def __init__(self, experiment): 135 super(MockExperimentRunner, self).__init__(experiment) 136 137 def _Run(self, experiment): 138 self.l.LogOutput("Would run the following experiment: '%s'." % 139 experiment.name) 140 141 def _PrintTable(self, experiment): 142 self.l.LogOutput("Would print the experiment table.") 143 144 def _Email(self, experiment): 145 self.l.LogOutput("Would send result email.") 146 147 def _StoreResults(self, experiment): 148 self.l.LogOutput("Would store the results.") 149