• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4import time
5
6from autotest_lib.client.bin import test
7from autotest_lib.client.cros import service_stopper
8from autotest_lib.client.cros.power import power_dashboard
9from autotest_lib.client.cros.power import power_rapl
10from autotest_lib.client.cros.power import power_status
11from autotest_lib.client.cros.power import power_telemetry_utils
12from autotest_lib.client.cros.power import power_utils
13
14
15class power_Test(test.test):
16    """Optional base class power related tests."""
17    version = 1
18
19    def initialize(self, seconds_period=20., pdash_note=''):
20        """Perform necessary initialization prior to power test run.
21
22        @param seconds_period: float of probing interval in seconds.
23        @param pdash_note: note of the current run to send to power dashboard.
24
25        @var backlight: power_utils.Backlight object.
26        @var keyvals: dictionary of result keyvals.
27        @var status: power_status.SysStat object.
28
29        @var _checkpoint_logger: power_status.CheckpointLogger to track
30                                 checkpoint data.
31        @var _plog: power_status.PowerLogger object to monitor power.
32        @var _psr: power_utils.DisplayPanelSelfRefresh object to monitor PSR.
33        @var _services: service_stopper.ServiceStopper object.
34        @var _start_time: float of time in seconds since Epoch test started.
35        @var _stats: power_status.StatoMatic object.
36        @var _tlog: power_status.TempLogger object to monitor temperatures.
37        @var _clog: power_status.CPUStatsLogger object to monitor CPU(s)
38                    frequencies and c-states.
39        @var _meas_logs: list of power_status.MeasurementLoggers
40        """
41        super(power_Test, self).initialize()
42        self.backlight = power_utils.Backlight()
43        self.backlight.set_default()
44        self.keyvals = dict()
45        self.status = power_status.get_status()
46
47        self._checkpoint_logger = power_status.CheckpointLogger()
48
49        measurements = []
50        if not self.status.on_ac():
51            measurements.append(
52                power_status.SystemPower(self.status.battery_path))
53        if power_utils.has_powercap_support():
54            measurements += power_rapl.create_powercap()
55        elif power_utils.has_rapl_support():
56            measurements += power_rapl.create_rapl()
57        self._plog = power_status.PowerLogger(measurements,
58                seconds_period=seconds_period,
59                checkpoint_logger=self._checkpoint_logger)
60        self._psr = power_utils.DisplayPanelSelfRefresh()
61        self._services = service_stopper.ServiceStopper(
62                service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
63        self._services.stop_services()
64        self._stats = power_status.StatoMatic()
65
66        self._tlog = power_status.TempLogger([],
67                seconds_period=seconds_period,
68                checkpoint_logger=self._checkpoint_logger)
69        self._clog = power_status.CPUStatsLogger(seconds_period=seconds_period,
70                checkpoint_logger=self._checkpoint_logger)
71
72        self._meas_logs = [self._plog, self._tlog, self._clog]
73
74        self._pdash_note = pdash_note
75
76    def warmup(self, warmup_time=30):
77        """Warm up.
78
79        Wait between initialization and run_once for new settings to stabilize.
80
81        @param warmup_time: integer of seconds to warmup.
82        """
83        time.sleep(warmup_time)
84
85    def start_measurements(self):
86        """Start measurements."""
87        for log in self._meas_logs:
88            log.start()
89        self._start_time = time.time()
90        power_telemetry_utils.start_measurement()
91
92    def loop_sleep(self, loop, sleep_secs):
93        """Jitter free sleep.
94
95        @param loop: integer of loop (1st is zero).
96        @param sleep_secs: integer of desired sleep seconds.
97        """
98        next_time = self._start_time + (loop + 1) * sleep_secs
99        time.sleep(next_time - time.time())
100
101    def checkpoint_measurements(self, name, start_time=None):
102        """Checkpoint measurements.
103
104        @param name: string name of measurement being checkpointed.
105        @param start_time: float of time in seconds since Epoch that
106                measurements being checkpointed began.
107        """
108        if not start_time:
109            start_time = self._start_time
110        self.status.refresh()
111        self._checkpoint_logger.checkpoint(name, start_time)
112        self._psr.refresh()
113
114    def publish_keyvals(self):
115        """Publish power result keyvals."""
116        keyvals = self._stats.publish()
117        keyvals['level_backlight_max'] = self.backlight.get_max_level()
118        keyvals['level_backlight_current'] = self.backlight.get_level()
119
120        # record battery stats if not on AC
121        if self.status.on_ac():
122            keyvals['b_on_ac'] = 1
123        else:
124            keyvals['b_on_ac'] = 0
125
126        if self.status.battery:
127            keyvals['ah_charge_full'] = self.status.battery[0].charge_full
128            keyvals['ah_charge_full_design'] = \
129                                self.status.battery[0].charge_full_design
130            keyvals['ah_charge_now'] = self.status.battery[0].charge_now
131            keyvals['a_current_now'] = self.status.battery[0].current_now
132            keyvals['wh_energy'] = self.status.battery[0].energy
133            keyvals['w_energy_rate'] = self.status.battery[0].energy_rate
134            keyvals['v_voltage_min_design'] = \
135                                self.status.battery[0].voltage_min_design
136            keyvals['v_voltage_now'] = self.status.battery[0].voltage_now
137
138        for log in self._meas_logs:
139            keyvals.update(log.calc())
140        keyvals.update(self._psr.get_keyvals())
141
142        self.keyvals.update(keyvals)
143
144        core_keyvals = power_utils.get_core_keyvals(self.keyvals)
145        self.write_perf_keyval(core_keyvals)
146
147    def _publish_dashboard(self):
148        """Report results to chromeperf & power dashboard."""
149
150        self.publish_keyvals()
151
152        # publish power values
153        for key, values in self.keyvals.iteritems():
154            if key.endswith('pwr'):
155                self.output_perf_value(description=key, value=values, units='W',
156                                   higher_is_better=False, graph='power')
157
158        # publish temperature values
159        for key, values in self.keyvals.iteritems():
160            if key.endswith('temp'):
161                self.output_perf_value(description=key, value=values, units='C',
162                                   higher_is_better=False, graph='temperature')
163
164        # publish to power dashboard
165        pdash = power_dashboard.PowerLoggerDashboard(
166            self._plog, self.tagged_testname, self.resultsdir,
167            note=self._pdash_note)
168        pdash.upload()
169        cdash = power_dashboard.CPUStatsLoggerDashboard(
170            self._clog, self.tagged_testname, self.resultsdir,
171            note=self._pdash_note)
172        cdash.upload()
173        tdash = power_dashboard.TempLoggerDashboard(
174            self._tlog, self.tagged_testname, self.resultsdir,
175            note=self._pdash_note)
176        tdash.upload()
177
178    def _save_results(self):
179        """Save results of each logger in resultsdir."""
180        for log in self._meas_logs:
181            log.save_results(self.resultsdir)
182        self._checkpoint_logger.save_checkpoint_data(self.resultsdir)
183
184    def postprocess_iteration(self):
185        """Write keyval and send data to dashboard."""
186        power_telemetry_utils.end_measurement()
187        super(power_Test, self).postprocess_iteration()
188        self._publish_dashboard()
189        self._save_results()
190
191    def cleanup(self):
192        """Reverse setting change in initialization."""
193        if self.backlight:
194            self.backlight.restore()
195        self._services.restore_services()
196        super(power_Test, self).cleanup()
197