OLD | NEW |
1 # Copyright 2016 Google Inc. | 1 # Copyright 2016 Google Inc. |
2 # | 2 # |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 import time | 6 import time |
7 | 7 |
8 class HardwareException(Exception): | 8 class Hardware: |
9 def __init__(self, message, sleeptime=60): | 9 """Locks down and monitors hardware for benchmarking. |
10 Exception.__init__(self, message) | |
11 self.sleeptime = sleeptime | |
12 | 10 |
13 class Hardware: | 11 This is a common base for classes that can control the specific hardware |
| 12 we are running on. Its purpose is to lock the hardware into a constant |
| 13 benchmarking mode for the duration of a 'with' block. e.g.: |
| 14 |
| 15 with hardware: |
| 16 run_benchmark() |
| 17 |
| 18 While benchmarking, the caller must call sanity_check() frequently to verify |
| 19 the hardware state has not changed. |
| 20 |
| 21 """ |
| 22 |
14 def __init__(self): | 23 def __init__(self): |
15 self.kick_in_time = 0 | 24 self.kick_in_time = 0 |
16 | 25 |
17 def __enter__(self): | 26 def __enter__(self): |
18 return self | 27 return self |
19 | 28 |
20 def __exit__(self, exception_type, exception_value, traceback): | 29 def __exit__(self, exception_type, exception_value, traceback): |
21 pass | 30 pass |
22 | 31 |
23 def sanity_check(self): | 32 def sanity_check(self): |
24 '''Raises a HardwareException if any hardware state is not as expected.''' | 33 """Raises a HardwareException if any hardware state is not as expected.""" |
25 pass | 34 pass |
26 | 35 |
27 def sleep(self, sleeptime): | 36 def sleep(self, sleeptime): |
28 '''Puts the hardware into a resting state for a fixed amount of time.''' | 37 """Puts the hardware into a resting state for a fixed amount of time.""" |
29 time.sleep(sleeptime) | 38 time.sleep(sleeptime) |
| 39 |
| 40 |
| 41 class HardwareException(Exception): |
| 42 """Gets thrown when certain hardware state is not what we expect. |
| 43 |
| 44 Generally this happens because of thermal conditions or other variables beyond |
| 45 our control, and the appropriate course of action is to take a short nap |
| 46 before resuming the benchmark. |
| 47 |
| 48 """ |
| 49 |
| 50 def __init__(self, message, sleeptime=60): |
| 51 Exception.__init__(self, message) |
| 52 self.sleeptime = sleeptime |
| 53 |
| 54 |
| 55 class Expectation: |
| 56 """Simple helper for checking the readings on hardware gauges.""" |
| 57 def __init__(self, value_type, min_value=None, max_value=None, |
| 58 exact_value=None, name=None, sleeptime=60): |
| 59 self.value_type = value_type |
| 60 self.min_value = min_value |
| 61 self.max_value = max_value |
| 62 self.exact_value = exact_value |
| 63 self.name = name |
| 64 self.sleeptime = sleeptime |
| 65 |
| 66 def check(self, stringvalue): |
| 67 typedvalue = self.value_type(stringvalue) |
| 68 if self.min_value is not None and typedvalue < self.min_value: |
| 69 raise HardwareException("%s is too low (%s, min=%s)" % |
| 70 (self.name, stringvalue, str(self.min_value)), |
| 71 sleeptime=self.sleeptime) |
| 72 if self.max_value is not None and typedvalue > self.max_value: |
| 73 raise HardwareException("%s is too high (%s, max=%s)" % |
| 74 (self.name, stringvalue, str(self.max_value)), |
| 75 sleeptime=self.sleeptime) |
| 76 if self.exact_value is not None and typedvalue != self.exact_value: |
| 77 raise HardwareException("unexpected %s (%s, expected=%s)" % |
| 78 (self.name, stringvalue, str(self.exact_value)), |
| 79 sleeptime=self.sleeptime) |
| 80 |
| 81 @staticmethod |
| 82 def check_all(expectations, stringvalues): |
| 83 if len(stringvalues) != len(expectations): |
| 84 raise Exception("unexpected reading from hardware gauges " |
| 85 "(expected %i values):\n%s" % |
| 86 (len(expectations), '\n'.join(stringvalues))) |
| 87 |
| 88 for value, expected in zip(stringvalues, expectations): |
| 89 expected.check(value) |
OLD | NEW |