power_LoadTest.py revision ffd2a04887ca6c31a6c9501f4c0df8d418f4b055
17bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
26a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda# Use of this source code is governed by a BSD-style license that can be
36a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda# found in the LICENSE file.
46a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
53fa0580fde83c963b5f7f73636d5b9bb089f938cZdenek Behanimport logging, os, shutil, time
6b910a9da27688211de1a80121ae75146b09e80a4Eric Lifrom autotest_lib.client.bin import utils
7bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Lifrom autotest_lib.client.common_lib import error
8b910a9da27688211de1a80121ae75146b09e80a4Eric Lifrom autotest_lib.client.cros import backchannel, cros_ui, cros_ui_test
9bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Lifrom autotest_lib.client.cros import httpd, login, power_status
103fa0580fde83c963b5f7f73636d5b9bb089f938cZdenek Behanfrom autotest_lib.client.cros import flimflam_test_path
1102b5ce48af62ff6486a2423c0e0adea14e391a48Zdenek Behanimport flimflam
129450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
139d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nandaparams_dict = {
149d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'test_time_ms': '_mseconds',
159d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'should_scroll': '_should_scroll',
169d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'should_scroll_up': '_should_scroll_up',
179d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'scroll_loop': '_scroll_loop',
189d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'scroll_interval_ms': '_scroll_interval_ms',
199d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'scroll_by_pixels': '_scroll_by_pixels',
207868162435adf9082b022a5ba6e00614c7c66381Simon Que    'tasks': '_tasks',
219d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda}
229d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
236a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
24e7c4cab13a8576a4f9de41b2dc1fb8c45c97424cEric Liclass power_LoadTest(cros_ui_test.UITest):
25b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis    auto_login = False
2606548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    version = 2
2750fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda
28e7c4cab13a8576a4f9de41b2dc1fb8c45c97424cEric Li
29b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis    def start_authserver(self):
30b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        """
31b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        Override cros_ui_test.UITest's start_authserver.
32b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        Do not use auth server and local dns for our test. We need to be
33b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        able to reach the web.
34b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        """
35b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        pass
36b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis
37b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis
3806548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def ensure_login_complete(self):
3906548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        """
40e7c4cab13a8576a4f9de41b2dc1fb8c45c97424cEric Li        Override cros_ui_test.UITest's ensure_login_complete.
4106548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        Do not use auth server and local dns for our test. We need to be
4206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        able to reach the web.
4306548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        """
4406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        pass
4550fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda
46e7c4cab13a8576a4f9de41b2dc1fb8c45c97424cEric Li
4706548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def initialize(self, creds='$default', percent_initial_charge_min=None,
484f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 check_network=True, loop_time=3600, loop_count=1,
494f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 should_scroll='true', should_scroll_up='true',
504f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 scroll_loop='false', scroll_interval_ms='10000',
514f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 scroll_by_pixels='600', low_battery_threshold=3,
529450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                 verbose=True, force_wifi=False, wifi_ap='', wifi_sec='none',
537868162435adf9082b022a5ba6e00614c7c66381Simon Que                 wifi_pw='', tasks=""):
5406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
559d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        """
569d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        percent_initial_charge_min: min battery charge at start of test
579d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        check_network: check that Ethernet interface is not running
58417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        loop_count: number of times to loop the test for
59417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        loop_time: length of time to run the test for in each loop
609d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        should_scroll: should the extension scroll pages
619d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        should_scroll_up: should scroll in up direction
629d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        scroll_loop: continue scrolling indefinitely
639d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        scroll_interval_ms: how often to scoll
649d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        scroll_by_pixels: number of pixels to scroll each time
659d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        """
66417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._loop_time = loop_time
67417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._loop_count = loop_count
68417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._mseconds = self._loop_time * 1000
699d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._verbose = verbose
70417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._low_battery_threshold = low_battery_threshold
719d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._should_scroll = should_scroll
729d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._should_scroll_up = should_scroll_up
739d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_loop = scroll_loop
749d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_interval_ms = scroll_interval_ms
759d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_by_pixels = scroll_by_pixels
76417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._tmp_keyvals = {}
77bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._power_status = power_status.get_status()
78dfc0199adabc92a7311df0f00629afb171495de9Benson Leung        self._json_path = None
79b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        self._force_wifi = force_wifi
80b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        self._testServer = None
81ffd2a04887ca6c31a6c9501f4c0df8d418f4b055Simon Que        self._tasks = '\'' + tasks.replace(' ','') + '\''
829d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
839d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # verify that initial conditions are met:
84ce1407b29b32f8f8fb1121251e28f0861ecac6a8Sameer Nanda        if self._power_status.linepower[0].online:
8577962639bc65f67634d4a2761c40d39a2be6a0daKen Mixter            raise error.TestError(
869d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                'Running on AC power. Please remove AC power cable')
879d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
8831d58c10977e075e0b7235be608ecab52bc9509eDarin Petkov        percent_initial_charge = self._percent_current_charge()
8931d58c10977e075e0b7235be608ecab52bc9509eDarin Petkov        if percent_initial_charge_min and percent_initial_charge < \
909d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                                          percent_initial_charge_min:
919d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            raise error.TestError('Initial charge (%f) less than min (%f)'
929d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                      % (percent_initial_charge, percent_initial_charge_min))
936a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
949450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis        # If force wifi enabled, convert eth0 to backchannel and connect to the
959450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis        # specified WiFi AP.
96b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        if self._force_wifi:
979450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # If backchannel is already running, don't run it again.
98b910a9da27688211de1a80121ae75146b09e80a4Eric Li            if not backchannel.setup():
999450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                raise error.TestError('Could not setup Backchannel network.')
1009450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
1019450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # Note: FlimFlam is flaky after Backchannel setup sometimes. It may
1029450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # take several tries for WiFi to connect. More experimentation with
1039450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # the retry settings here may be necessary if this becomes a source
1049450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # of test flakiness in the future.
1056e6be985c67de742de2d463ff8522355a3995f5dDale Curtis            if not flimflam.FlimFlam().ConnectService(retries=3,
1066e6be985c67de742de2d463ff8522355a3995f5dDale Curtis                                                      retry=True,
1079450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      service_type='wifi',
1089450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      ssid=wifi_ap,
1099450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      security=wifi_sec,
1109450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      passphrase=wifi_pw,
1119450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      mode='managed')[0]:
1129450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                raise error.TestError('Could not connect to WiFi network.')
1139450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
114b910a9da27688211de1a80121ae75146b09e80a4Eric Li        if check_network and backchannel.is_network_iface_running('eth0'):
11577962639bc65f67634d4a2761c40d39a2be6a0daKen Mixter            raise error.TestError(
1169d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                'Ethernet interface is active. Please remove Ethernet cable')
1179d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
118d075074b8fc70d829912864f819345407295f35dSameer Nanda        # record the max backlight level
1194f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda        cmd = 'backlight-tool --get_max_brightness'
120d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._max_backlight = int(utils.system_output(cmd).rstrip())
121d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._tmp_keyvals['level_backlight_max'] = self._max_backlight
1226a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1239d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # fix up file perms for the power test extension so that chrome
1249d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # can access it
125ce1407b29b32f8f8fb1121251e28f0861ecac6a8Sameer Nanda        os.system('chmod -R 755 %s' % self.bindir)
1269d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
1277bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        # write test parameters to the params.js file to be read by the test
1287bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        # extension.
1297bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        self._write_ext_params()
13006548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
13106548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # copy external_extensions.json to known location
13206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        self._json_path = os.path.join(self.bindir, '..')
13306548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        shutil.copy(os.path.join(self.bindir, 'external_extensions.json'),
13406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung                                 self._json_path)
1356a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1366a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        # setup a HTTP Server to listen for status updates from the power
1376a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        # test extension
138c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        self._testServer = httpd.HTTPListener(8001, docroot=self.bindir)
1396a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        self._testServer.run()
1406a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
14187aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # initialize various interesting power related stats
142bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._usb_stats = power_status.USBSuspendStats()
143bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._cpufreq_stats = power_status.CPUFreqStats()
144bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._cpuidle_stats = power_status.CPUIdleStats()
14587aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
1466a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
14787aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._usb_stats.refresh()
14887aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._cpufreq_stats.refresh()
14987aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._cpuidle_stats.refresh()
1509d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._power_status.refresh()
151417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
1529d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._ah_charge_start = self._power_status.battery[0].charge_now
1539d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._wh_energy_start = self._power_status.battery[0].energy
1549d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
155e7c4cab13a8576a4f9de41b2dc1fb8c45c97424cEric Li        # from cros_ui_test.UITest.initialize, sans authserver & local dns.
156b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        cros_ui_test.UITest.initialize(self, creds)
15706548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
15806548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def run_once(self):
15906548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
160417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        t0 = time.time()
161417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
162417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        for i in range(self._loop_count):
163417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            # the power test extension will report its status here
164417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            latch = self._testServer.add_wait_url('/status')
1656a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
16606548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung            # the act of logging in will launch chrome with external extension.
167d79bea0a1d57d37e3f72648c7f9ddbe34dec3e73Thieu Le            # NOTE: self.login() will log out the current session if it's
168d79bea0a1d57d37e3f72648c7f9ddbe34dec3e73Thieu Le            # currently logged in.
169b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis            self.login()
170417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
171d075074b8fc70d829912864f819345407295f35dSameer Nanda            # stop powerd
172d075074b8fc70d829912864f819345407295f35dSameer Nanda            os.system('stop powerd')
173d075074b8fc70d829912864f819345407295f35dSameer Nanda
174d075074b8fc70d829912864f819345407295f35dSameer Nanda            # reset X settings since X gets restarted upon login
175d075074b8fc70d829912864f819345407295f35dSameer Nanda            self._do_xset()
176d075074b8fc70d829912864f819345407295f35dSameer Nanda
177d075074b8fc70d829912864f819345407295f35dSameer Nanda            # reset backlight level since powerd might've modified it
178d075074b8fc70d829912864f819345407295f35dSameer Nanda            # based on ambient light
179d075074b8fc70d829912864f819345407295f35dSameer Nanda            self._set_backlight_level()
180d075074b8fc70d829912864f819345407295f35dSameer Nanda
181417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            low_battery = self._do_wait(self._verbose, self._loop_time,
18206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung                                        latch)
183417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
184417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if self._verbose:
185417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.debug('loop %d completed' % i)
186417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
187417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if low_battery:
188417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.info('Exiting due to low battery')
189417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                break
1906a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
191417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        t1 = time.time()
192417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._tmp_keyvals['minutes_battery_life'] = (t1 - t0) / 60
1936a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1946a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1956a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda    def postprocess_iteration(self):
1966a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals = {}
1979d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
19887aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # refresh power related statistics
19987aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        usb_stats = self._usb_stats.refresh()
20087aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        cpufreq_stats = self._cpufreq_stats.refresh()
20187aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        cpuidle_stats = self._cpuidle_stats.refresh()
20287aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
20387aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record percent time USB devices were not in suspended state
20487aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        keyvals['percent_usb_active'] = usb_stats
20587aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
20687aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record percent time spent in each CPU C-state
20787aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        for state in cpuidle_stats:
20887aced24632053d9df0a42842307abf165f60ad1Sameer Nanda            keyvals['percent_cpuidle_%s_time' % state] = cpuidle_stats[state]
20987aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
21087aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record percent time spent at each CPU frequency
21187aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        for freq in cpufreq_stats:
21287aced24632053d9df0a42842307abf165f60ad1Sameer Nanda            keyvals['percent_cpufreq_%s_time' % freq] = cpufreq_stats[freq]
21387aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
21487aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record battery stats
21550fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['a_current_now'] = self._power_status.battery[0].current_now
2169d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_full'] = self._power_status.battery[0].charge_full
2176a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals['ah_charge_full_design'] = \
2189d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                             self._power_status.battery[0].charge_full_design
2199d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_start'] = self._ah_charge_start
2209d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_now'] = self._power_status.battery[0].charge_now
22150fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['ah_charge_used'] = keyvals['ah_charge_start'] - \
22250fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda                                    keyvals['ah_charge_now']
2239d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['wh_energy_start'] = self._wh_energy_start
2249d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['wh_energy_now'] = self._power_status.battery[0].energy
22550fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['wh_energy_used'] = keyvals['wh_energy_start'] - \
22650fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda                                    keyvals['wh_energy_now']
2276a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals['v_voltage_min_design'] = \
2289d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                             self._power_status.battery[0].voltage_min_design
2299d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['v_voltage_now'] = self._power_status.battery[0].voltage_now
2309d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
231417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals.update(self._tmp_keyvals)
232417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
233417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals['a_current_rate'] = keyvals['ah_charge_used'] * 60 / \
234417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                                    keyvals['minutes_battery_life']
235417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals['w_energy_rate'] = keyvals['wh_energy_used'] * 60 / \
236417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                                   keyvals['minutes_battery_life']
2376a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
2386a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        self.write_perf_keyval(keyvals)
2399d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2409d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2419d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def cleanup(self):
24206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # remove json file after test to stop external extension launch.
243dfc0199adabc92a7311df0f00629afb171495de9Benson Leung        if self._json_path:
244dfc0199adabc92a7311df0f00629afb171495de9Benson Leung            jsonfile = os.path.join(self._json_path, 'external_extensions.json')
245dfc0199adabc92a7311df0f00629afb171495de9Benson Leung            if os.path.exists(jsonfile):
246dfc0199adabc92a7311df0f00629afb171495de9Benson Leung                os.system('rm -f %s' % jsonfile)
247d075074b8fc70d829912864f819345407295f35dSameer Nanda        # re-enable powerd
2485aaf2314cf2bcdb9c89b42f3eb50e40cc76baf6bDavid James        os.system('start powerd')
249c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        if login.logged_in():
250c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li            login.attempt_logout()
251b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        # cleanup backchannel interface
252b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        if self._force_wifi:
253b910a9da27688211de1a80121ae75146b09e80a4Eric Li            backchannel.teardown()
254b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        if self._testServer:
255b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis            self._testServer.stop()
2569d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2579d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def _percent_current_charge(self):
2589d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        return self._power_status.battery[0].charge_now * 100 / \
2599d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda               self._power_status.battery[0].charge_full_design
2609d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2619d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2629d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def _write_ext_params(self):
2639d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        data = ''
2649d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        template= 'var %s = %s;\n'
2659d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        for k in params_dict:
2669d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            data += template % (k, getattr(self, params_dict[k]))
2679d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2687bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        filename = os.path.join(self.bindir, 'params.js')
2699d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        utils.open_write_close(filename, data)
2709d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2719d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        logging.debug('filename ' + filename)
2729d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        logging.debug(data)
2739d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2749d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
27506548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def _do_wait(self, verbose, seconds, latch):
2769d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        latched = False
277417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        low_battery = False
278417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        total_time = seconds + 60
2799d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        elapsed_time = 0
280417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        wait_time = 60
2819d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2829d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        while elapsed_time < total_time:
2839d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            time.sleep(wait_time)
2849d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            elapsed_time += wait_time
2859d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2869d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            self._power_status.refresh()
287417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if verbose:
288417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.debug('ah_charge_now %f' \
289417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    % self._power_status.battery[0].charge_now)
290417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.debug('w_energy_rate %f' \
291417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    % self._power_status.battery[0].energy_rate)
292417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
293417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            low_battery = (self._percent_current_charge() <
294417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                           self._low_battery_threshold)
295417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
296417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            latched = latch.is_set()
297417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
298417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if latched or low_battery:
2999d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                break
3009d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
301417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        if latched:
302417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            # record chrome power extension stats
303417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            form_data = self._testServer.get_form_entries()
304417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            logging.debug(form_data)
305417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            for e in form_data:
306417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                key = 'ext_' + e
307417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                if key in self._tmp_keyvals:
308417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    self._tmp_keyvals[key] += form_data[e]
309417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                else:
310417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    self._tmp_keyvals[key] = form_data[e]
311417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        else:
3129d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            logging.debug("Didn't get status back from power extension")
3139d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
314417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        return low_battery
315d075074b8fc70d829912864f819345407295f35dSameer Nanda
316d075074b8fc70d829912864f819345407295f35dSameer Nanda
317d075074b8fc70d829912864f819345407295f35dSameer Nanda    def _do_xset(self):
318d075074b8fc70d829912864f819345407295f35dSameer Nanda        XSET = 'LD_LIBRARY_PATH=/usr/local/lib xset'
319d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Disable X screen saver
32051d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s s 0 0' % XSET)
321d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Disable DPMS Standby/Suspend/Off
32251d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s dpms 0 0 0' % XSET)
323d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Force monitor on
32451d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s dpms force on' % XSET)
325d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Save off X settings
32651d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s q' % XSET)
327d075074b8fc70d829912864f819345407295f35dSameer Nanda
328d075074b8fc70d829912864f819345407295f35dSameer Nanda
329d075074b8fc70d829912864f819345407295f35dSameer Nanda    def _set_backlight_level(self):
330d075074b8fc70d829912864f819345407295f35dSameer Nanda        # set backlight level to 40% of max
331d075074b8fc70d829912864f819345407295f35dSameer Nanda        cmd = 'backlight-tool --set_brightness %d ' % (
332d075074b8fc70d829912864f819345407295f35dSameer Nanda              int(self._max_backlight * 0.4))
333d075074b8fc70d829912864f819345407295f35dSameer Nanda        os.system(cmd)
334d075074b8fc70d829912864f819345407295f35dSameer Nanda
335d075074b8fc70d829912864f819345407295f35dSameer Nanda        # record brightness level
336d075074b8fc70d829912864f819345407295f35dSameer Nanda        cmd = 'backlight-tool --get_brightness'
337d075074b8fc70d829912864f819345407295f35dSameer Nanda        level = int(utils.system_output(cmd).rstrip())
338d075074b8fc70d829912864f819345407295f35dSameer Nanda        logging.info('backlight level is %d' % level)
339d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._tmp_keyvals['level_backlight_current'] = level
340