experiment_runner.py revision f81680c018729fd4499e1e200d04b48c4b90127c
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): 28 self._experiment = experiment 29 self.l = logger.GetLogger(experiment.log_dir) 30 self._ce = command_executer.GetCommandExecuter(self.l) 31 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 62 if (not send_mail and not experiment.email_to 63 or config.GetConfig("no_email")): 64 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 71 text_report = TextResultsReport(experiment, True).GetReport() 72 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) 75 email_to = [getpass.getuser()] + experiment.email_to 76 EmailSender().SendEmail(email_to, 77 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: 100 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) 105 benchmark_run.result.CleanUp(benchmark_run.benchmark.rm_chroot_tmp) 106 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): 116 """Mocked ExperimentRunner for testing.""" 117 118 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.") 133