blob: 0fcd0c61a823b78da7430a80d635cf5119f8a628 [file] [log] [blame]
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08001#!/usr/bin/python
2
Yunlian Jiange5b673f2013-05-23 11:42:53 -07003# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08006
7import datetime
8import os
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08009import threading
10import time
11import traceback
Ahmad Shariffd356fb2012-05-07 12:02:16 -070012
Ahmad Sharif4467f002012-12-20 12:09:49 -080013from utils import command_executer
14from utils import timeline
15
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070016from suite_runner import SuiteRunner
Ahmad Shariff395c262012-10-09 17:48:09 -070017from results_cache import Result
18from results_cache import ResultsCache
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070019from results_cache import TelemetryResult
20
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080021
22STATUS_FAILED = "FAILED"
23STATUS_SUCCEEDED = "SUCCEEDED"
24STATUS_IMAGING = "IMAGING"
25STATUS_RUNNING = "RUNNING"
26STATUS_WAITING = "WAITING"
27STATUS_PENDING = "PENDING"
28
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080029class BenchmarkRun(threading.Thread):
Ahmad Sharif4467f002012-12-20 12:09:49 -080030 def __init__(self, name, benchmark,
31 label,
32 iteration,
33 cache_conditions,
Ahmad Shariffd356fb2012-05-07 12:02:16 -070034 machine_manager,
Luis Lozanof81680c2013-03-15 14:44:13 -070035 logger_to_use,
36 share_users):
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080037 threading.Thread.__init__(self)
38 self.name = name
39 self._logger = logger_to_use
Ahmad Sharif4467f002012-12-20 12:09:49 -080040 self.benchmark = benchmark
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080041 self.iteration = iteration
Ahmad Sharif4467f002012-12-20 12:09:49 -080042 self.label = label
Ahmad Shariffd356fb2012-05-07 12:02:16 -070043 self.result = None
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080044 self.terminated = False
45 self.retval = None
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080046 self.run_completed = False
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080047 self.machine_manager = machine_manager
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070048 self.suite_runner = SuiteRunner(self._logger)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080049 self.machine = None
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080050 self.cache_conditions = cache_conditions
51 self.runs_complete = 0
52 self.cache_hit = False
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080053 self.failure_reason = ""
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070054 self.test_args = "%s %s" % (benchmark.test_args,
Ahmad Sharif4467f002012-12-20 12:09:49 -080055 self._GetExtraAutotestArgs())
Ahmad Sharif92ab7af2012-03-01 18:03:46 -080056 self._ce = command_executer.GetCommandExecuter(self._logger)
Ahmad Sharif4467f002012-12-20 12:09:49 -080057 self.timeline = timeline.Timeline()
58 self.timeline.Record(STATUS_PENDING)
Luis Lozanof81680c2013-03-15 14:44:13 -070059 self.share_users = share_users
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080060
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070061 def ReadCache(self):
62 # Just use the first machine for running the cached version,
63 # without locking it.
64 self.cache = ResultsCache()
65 self.cache.Init(self.label.chromeos_image,
66 self.label.chromeos_root,
67 self.benchmark.test_name,
68 self.iteration,
69 self.test_args,
70 self.machine_manager,
71 self.label.board,
72 self.cache_conditions,
73 self._logger,
74 self.label,
75 self.share_users,
76 self.benchmark.suite
77 )
78
79 self.result = self.cache.ReadResult()
80 self.cache_hit = (self.result is not None)
81
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080082 def run(self):
83 try:
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070084 self.ReadCache()
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080085
Ahmad Shariffd356fb2012-05-07 12:02:16 -070086 if self.result:
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080087 self._logger.LogOutput("%s: Cache hit." % self.name)
Ahmad Sharif4467f002012-12-20 12:09:49 -080088 self._logger.LogOutput(self.result.out, print_to_console=False)
89 self._logger.LogError(self.result.err, print_to_console=False)
90
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080091 else:
92 self._logger.LogOutput("%s: No cache hit." % self.name)
Ahmad Sharif4467f002012-12-20 12:09:49 -080093 self.timeline.Record(STATUS_WAITING)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080094 # Try to acquire a machine now.
95 self.machine = self.AcquireMachine()
Ahmad Shariffd356fb2012-05-07 12:02:16 -070096 self.result = self.RunTest(self.machine)
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070097
98 self.cache.remote = self.machine.name
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070099 self.cache.StoreResult(self.result)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800100
101 if self.terminated:
102 return
103
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700104 if not self.result.retval:
Ahmad Sharif4467f002012-12-20 12:09:49 -0800105 self.timeline.Record(STATUS_SUCCEEDED)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800106 else:
Ahmad Sharif4467f002012-12-20 12:09:49 -0800107 if self.timeline.GetLastEvent() != STATUS_FAILED:
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700108 self.failure_reason = "Return value of test suite was non-zero."
Ahmad Sharif4467f002012-12-20 12:09:49 -0800109 self.timeline.Record(STATUS_FAILED)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800110
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800111 except Exception, e:
112 self._logger.LogError("Benchmark run: '%s' failed: %s" % (self.name, e))
113 traceback.print_exc()
Ahmad Sharif4467f002012-12-20 12:09:49 -0800114 if self.timeline.GetLastEvent() != STATUS_FAILED:
115 self.timeline.Record(STATUS_FAILED)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800116 self.failure_reason = str(e)
117 finally:
118 if self.machine:
Yunlian Jiange5b673f2013-05-23 11:42:53 -0700119 if not self.machine.IsReachable():
120 self._logger.LogOutput("Machine % is not reachable, removing it."
121 % self.machine.name)
122 self.machine_manager.RemoveMachine(self.machine.name)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800123 self._logger.LogOutput("Releasing machine: %s" % self.machine.name)
124 self.machine_manager.ReleaseMachine(self.machine)
125 self._logger.LogOutput("Released machine: %s" % self.machine.name)
126
127 def Terminate(self):
128 self.terminated = True
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700129 self.suite_runner.Terminate()
Ahmad Sharif4467f002012-12-20 12:09:49 -0800130 if self.timeline.GetLastEvent() != STATUS_FAILED:
131 self.timeline.Record(STATUS_FAILED)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800132 self.failure_reason = "Thread terminated."
133
134 def AcquireMachine(self):
135 while True:
136 if self.terminated:
137 raise Exception("Thread terminated while trying to acquire machine.")
Ahmad Sharif4467f002012-12-20 12:09:49 -0800138 machine = self.machine_manager.AcquireMachine(self.label.chromeos_image,
139 self.label)
140
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800141 if machine:
142 self._logger.LogOutput("%s: Machine %s acquired at %s" %
143 (self.name,
144 machine.name,
145 datetime.datetime.now()))
146 break
147 else:
148 sleep_duration = 10
149 time.sleep(sleep_duration)
150 return machine
151
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700152 def _GetExtraAutotestArgs(self):
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700153 if self.benchmark.perf_args and self.benchmark.suite == "telemetry":
154 self._logger.LogError("Telemetry benchmark does not support profiler.")
155
Ahmad Sharif4467f002012-12-20 12:09:49 -0800156 if self.benchmark.perf_args:
157 perf_args_list = self.benchmark.perf_args.split(" ")
Ahmad Shariff395c262012-10-09 17:48:09 -0700158 perf_args_list = [perf_args_list[0]] + ["-a"] + perf_args_list[1:]
159 perf_args = " ".join(perf_args_list)
160 if not perf_args_list[0] in ["record", "stat"]:
161 raise Exception("perf_args must start with either record or stat")
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700162 extra_test_args = ["--profiler=custom_perf",
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700163 ("--profiler_args='perf_options=\"%s\"'" %
164 perf_args)]
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700165 return " ".join(extra_test_args)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700166 else:
167 return ""
168
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800169 def RunTest(self, machine):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800170 self.timeline.Record(STATUS_IMAGING)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800171 self.machine_manager.ImageMachine(machine,
Ahmad Sharif4467f002012-12-20 12:09:49 -0800172 self.label)
173 self.timeline.Record(STATUS_RUNNING)
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700174 [retval, out, err] = self.suite_runner.Run(machine.name,
175 self.label,
176 self.benchmark,
177 self.test_args)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800178 self.run_completed = True
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700179 return Result.CreateFromRun(self._logger,
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700180 self.label,
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700181 out,
182 err,
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700183 retval,
184 self.benchmark.suite)
Ahmad Sharif92ab7af2012-03-01 18:03:46 -0800185
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800186 def SetCacheConditions(self, cache_conditions):
187 self.cache_conditions = cache_conditions
Ahmad Sharif4467f002012-12-20 12:09:49 -0800188
189
190class MockBenchmarkRun(BenchmarkRun):
191 """Inherited from BenchmarkRun, just overide RunTest for testing."""
192
193 def RunTest(self, machine):
194 """Remove Result.CreateFromRun for testing."""
195 self.timeline.Record(STATUS_IMAGING)
196 self.machine_manager.ImageMachine(machine,
197 self.label)
198 self.timeline.Record(STATUS_RUNNING)
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700199 [retval, out, err] = self.suite_runner.Run(machine.name,
Ahmad Sharif4467f002012-12-20 12:09:49 -0800200 self.label.chromeos_root,
201 self.label.board,
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700202 self.benchmark.test_name,
203 self.test_args)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800204 self.run_completed = True
205 rr = Result("Results placed in /tmp/test", "", 0)
206 rr.out = out
207 rr.err = err
208 rr.retval = retval
209 return rr
210