experiment_runner.py revision 4467f004e7f0854963bec90daff1879fbd9d2fec
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 15from experiment_status import ExperimentStatus 16from results_report import HTMLResultsReport 17from results_report import TextResultsReport 18 19 20class ExperimentRunner(object): 21 """ExperimentRunner Class.""" 22 23 STATUS_TIME_DELAY = 30 24 THREAD_MONITOR_DELAY = 2 25 26 def __init__(self, experiment): 27 self._experiment = experiment 28 self.l = logger.GetLogger() 29 self._ce = command_executer.GetCommandExecuter(self.l) 30 self._terminated = False 31 32 def _Run(self, experiment): 33 status = ExperimentStatus(experiment) 34 experiment.Run() 35 last_status_time = 0 36 try: 37 while not experiment.IsComplete(): 38 if last_status_time + self.STATUS_TIME_DELAY < time.time(): 39 last_status_time = time.time() 40 border = "==============================" 41 self.l.LogOutput(border) 42 self.l.LogOutput(status.GetProgressString()) 43 self.l.LogOutput(status.GetStatusString()) 44 logger.GetLogger().LogOutput(border) 45 time.sleep(self.THREAD_MONITOR_DELAY) 46 except KeyboardInterrupt: 47 self._terminated = True 48 self.l.LogError("Ctrl-c pressed. Cleaning up...") 49 experiment.Terminate() 50 51 def _PrintTable(self, experiment): 52 self.l.LogOutput(TextResultsReport(experiment).GetReport()) 53 54 def _Email(self, experiment): 55 # Only email by default if a new run was completed. 56 send_mail = False 57 for benchmark_run in experiment.benchmark_runs: 58 if not benchmark_run.cache_hit: 59 send_mail = True 60 break 61 if not send_mail and not experiment.email_to: 62 return 63 64 label_names = [] 65 for label in experiment.labels: 66 label_names.append(label.name) 67 subject = "%s: %s" % (experiment.name, " vs. ".join(label_names)) 68 69 text_report = TextResultsReport(experiment, True).GetReport() 70 text_report = "<pre style='font-size: 13px'>%s</pre>" % text_report 71 html_report = HTMLResultsReport(experiment).GetReport() 72 attachment = EmailSender.Attachment("report.html", html_report) 73 email_to = [getpass.getuser()] + experiment.email_to 74 EmailSender().SendEmail(email_to, 75 subject, 76 text_report, 77 attachments=[attachment], 78 msg_type="html") 79 80 def _StoreResults (self, experiment): 81 if self._terminated: 82 return 83 results_directory = experiment.results_directory 84 FileUtils().RmDir(results_directory) 85 FileUtils().MkDirP(results_directory) 86 self.l.LogOutput("Storing experiment file.") 87 experiment_file_path = os.path.join(results_directory, 88 "experiment.exp") 89 FileUtils().WriteFile(experiment_file_path, experiment.experiment_file) 90 91 self.l.LogOutput("Storing results report.") 92 results_table_path = os.path.join(results_directory, "results.html") 93 report = HTMLResultsReport(experiment).GetReport() 94 FileUtils().WriteFile(results_table_path, report) 95 96 self.l.LogOutput("Storing results of each benchmark run.") 97 for benchmark_run in experiment.benchmark_runs: 98 if benchmark_run.result: 99 benchmark_run_name = filter(str.isalnum, benchmark_run.name) 100 benchmark_run_path = os.path.join(results_directory, 101 benchmark_run_name) 102 benchmark_run.result.CopyResultsTo(benchmark_run_path) 103 benchmark_run.result.CleanUp() 104 105 def Run(self): 106 self._Run(self._experiment) 107 self._PrintTable(self._experiment) 108 if not self._terminated: 109 self._StoreResults(self._experiment) 110 self._Email(self._experiment) 111 112 113class MockExperimentRunner(ExperimentRunner): 114 """Mocked ExperimentRunner for testing.""" 115 116 def __init__(self, experiment): 117 super(MockExperimentRunner, self).__init__(experiment) 118 119 def _Run(self, experiment): 120 self.l.LogOutput("Would run the following experiment: '%s'." % 121 experiment.name) 122 123 def _PrintTable(self, experiment): 124 self.l.LogOutput("Would print the experiment table.") 125 126 def _Email(self, experiment): 127 self.l.LogOutput("Would send result email.") 128 129 def _StoreResults(self, experiment): 130 self.l.LogOutput("Would store the results.") 131