power_LoadTest.py revision c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1c
16a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda# Copyright (c) 2010 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
59450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtisimport logging, os, shutil, sys, time
6c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Lifrom autotest_lib.client.bin import site_backchannel, utils
7c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Lifrom autotest_lib.client.common_lib import error, site_power_status
8c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Lifrom autotest_lib.client.cros import httpd, login, ui, ui_test
96a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
109450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtissys.path.append(os.environ.get('SYSROOT', '') + '/usr/local/lib/flimflam/test')
119450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtisimport flimflam
129450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
139450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
149d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nandaparams_dict = {
159d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'test_time_ms': '_mseconds',
169d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'should_scroll': '_should_scroll',
179d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'should_scroll_up': '_should_scroll_up',
189d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'scroll_loop': '_scroll_loop',
199d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'scroll_interval_ms': '_scroll_interval_ms',
209d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    'scroll_by_pixels': '_scroll_by_pixels',
219d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda}
229d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
236a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
24cb6a91adb049e9d5fe42a9adc4e570a988203e65Eric Liclass power_LoadTest(ui_test.UITest):
2506548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    version = 2
2650fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda
2706548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def ensure_login_complete(self):
2806548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        """
29cb6a91adb049e9d5fe42a9adc4e570a988203e65Eric Li        Override ui_test.UITest's ensure_login_complete.
3006548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        Do not use auth server and local dns for our test. We need to be
3106548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        able to reach the web.
3206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        """
3306548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        pass
3450fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda
3506548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def initialize(self, creds='$default', percent_initial_charge_min=None,
364f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 check_network=True, loop_time=3600, loop_count=1,
374f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 should_scroll='true', should_scroll_up='true',
384f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 scroll_loop='false', scroll_interval_ms='10000',
394f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda                 scroll_by_pixels='600', low_battery_threshold=3,
409450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                 verbose=True, force_wifi=False, wifi_ap='', wifi_sec='none',
419450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                 wifi_pw=''):
4206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
439d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        """
449d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        percent_initial_charge_min: min battery charge at start of test
459d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        check_network: check that Ethernet interface is not running
46417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        loop_count: number of times to loop the test for
47417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        loop_time: length of time to run the test for in each loop
489d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        should_scroll: should the extension scroll pages
499d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        should_scroll_up: should scroll in up direction
509d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        scroll_loop: continue scrolling indefinitely
519d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        scroll_interval_ms: how often to scoll
529d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        scroll_by_pixels: number of pixels to scroll each time
539d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        """
54417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._loop_time = loop_time
55417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._loop_count = loop_count
56417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._mseconds = self._loop_time * 1000
579d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._verbose = verbose
58417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._low_battery_threshold = low_battery_threshold
599d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._should_scroll = should_scroll
609d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._should_scroll_up = should_scroll_up
619d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_loop = scroll_loop
629d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_interval_ms = scroll_interval_ms
639d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_by_pixels = scroll_by_pixels
64417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._tmp_keyvals = {}
659d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._power_status = site_power_status.get_status()
66dfc0199adabc92a7311df0f00629afb171495de9Benson Leung        self._json_path = None
67b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        self._force_wifi = force_wifi
689d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
699d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # verify that initial conditions are met:
70ce1407b29b32f8f8fb1121251e28f0861ecac6a8Sameer Nanda        if self._power_status.linepower[0].online:
7177962639bc65f67634d4a2761c40d39a2be6a0daKen Mixter            raise error.TestError(
729d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                'Running on AC power. Please remove AC power cable')
739d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
7431d58c10977e075e0b7235be608ecab52bc9509eDarin Petkov        percent_initial_charge = self._percent_current_charge()
7531d58c10977e075e0b7235be608ecab52bc9509eDarin Petkov        if percent_initial_charge_min and percent_initial_charge < \
769d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                                          percent_initial_charge_min:
779d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            raise error.TestError('Initial charge (%f) less than min (%f)'
789d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                      % (percent_initial_charge, percent_initial_charge_min))
796a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
809450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis        # If force wifi enabled, convert eth0 to backchannel and connect to the
819450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis        # specified WiFi AP.
82b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        if self._force_wifi:
839450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # If backchannel is already running, don't run it again.
849450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            if not site_backchannel.setup():
859450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                raise error.TestError('Could not setup Backchannel network.')
869450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
879450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # Note: FlimFlam is flaky after Backchannel setup sometimes. It may
889450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # take several tries for WiFi to connect. More experimentation with
899450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # the retry settings here may be necessary if this becomes a source
909450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # of test flakiness in the future.
919450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            if not flimflam.FlimFlam().ConnectService(retry=True,
929450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      service_type='wifi',
939450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      ssid=wifi_ap,
949450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      security=wifi_sec,
959450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      passphrase=wifi_pw,
969450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      mode='managed')[0]:
979450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                raise error.TestError('Could not connect to WiFi network.')
989450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
999450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis        if check_network and site_backchannel.is_network_iface_running('eth0'):
10077962639bc65f67634d4a2761c40d39a2be6a0daKen Mixter            raise error.TestError(
1019d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                'Ethernet interface is active. Please remove Ethernet cable')
1029d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
103d075074b8fc70d829912864f819345407295f35dSameer Nanda        # record the max backlight level
1044f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda        cmd = 'backlight-tool --get_max_brightness'
105d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._max_backlight = int(utils.system_output(cmd).rstrip())
106d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._tmp_keyvals['level_backlight_max'] = self._max_backlight
1076a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1089d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # fix up file perms for the power test extension so that chrome
1099d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # can access it
110ce1407b29b32f8f8fb1121251e28f0861ecac6a8Sameer Nanda        os.system('chmod -R 755 %s' % self.bindir)
1119d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
11206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # TODO (bleung) :
11306548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # The new external extension packed crx means we can't pass params by
11406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # modifying params.js
11506548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # Possible solution :
11606548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # - modify extension to not start until we poke it from the browser.
11706548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        #       then pass through URL.
11806548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
1199d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # write test parameters to the power extension's params.js file
12006548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # self._ext_path = os.path.join(self.bindir, 'extension')
12106548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # self._write_ext_params()
12206548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
12306548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # copy external_extensions.json to known location
12406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        self._json_path = os.path.join(self.bindir, '..')
12506548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        shutil.copy(os.path.join(self.bindir, 'external_extensions.json'),
12606548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung                                 self._json_path)
1276a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1286a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        # setup a HTTP Server to listen for status updates from the power
1296a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        # test extension
130c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        self._testServer = httpd.HTTPListener(8001, docroot=self.bindir)
1316a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        self._testServer.run()
1326a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
13387aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # initialize various interesting power related stats
13487aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._usb_stats = site_power_status.USBSuspendStats()
13587aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._cpufreq_stats = site_power_status.CPUFreqStats()
13687aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._cpuidle_stats = site_power_status.CPUIdleStats()
13787aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
1386a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
13987aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._usb_stats.refresh()
14087aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._cpufreq_stats.refresh()
14187aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        self._cpuidle_stats.refresh()
1429d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._power_status.refresh()
143417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
1449d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._ah_charge_start = self._power_status.battery[0].charge_now
1459d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._wh_energy_start = self._power_status.battery[0].energy
1469d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
147cb6a91adb049e9d5fe42a9adc4e570a988203e65Eric Li        # from ui_test.UITest.initialize, sans authserver & local dns.
14806548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        (self.username, self.password) = self._UITest__resolve_creds(creds)
14906548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
15006548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def run_once(self):
15106548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
152417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        t0 = time.time()
153417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
154417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        for i in range(self._loop_count):
155417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            # the power test extension will report its status here
156417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            latch = self._testServer.add_wait_url('/status')
1576a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
15806548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung            # the act of logging in will launch chrome with external extension.
159d79bea0a1d57d37e3f72648c7f9ddbe34dec3e73Thieu Le            # NOTE: self.login() will log out the current session if it's
160d79bea0a1d57d37e3f72648c7f9ddbe34dec3e73Thieu Le            # currently logged in.
16106548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung            self.login(self.username, self.password)
162417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
163d075074b8fc70d829912864f819345407295f35dSameer Nanda            # stop powerd
164d075074b8fc70d829912864f819345407295f35dSameer Nanda            os.system('stop powerd')
165d075074b8fc70d829912864f819345407295f35dSameer Nanda
166d075074b8fc70d829912864f819345407295f35dSameer Nanda            # reset X settings since X gets restarted upon login
167d075074b8fc70d829912864f819345407295f35dSameer Nanda            self._do_xset()
168d075074b8fc70d829912864f819345407295f35dSameer Nanda
169d075074b8fc70d829912864f819345407295f35dSameer Nanda            # reset backlight level since powerd might've modified it
170d075074b8fc70d829912864f819345407295f35dSameer Nanda            # based on ambient light
171d075074b8fc70d829912864f819345407295f35dSameer Nanda            self._set_backlight_level()
172d075074b8fc70d829912864f819345407295f35dSameer Nanda
173417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            low_battery = self._do_wait(self._verbose, self._loop_time,
17406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung                                        latch)
175417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
176417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if self._verbose:
177417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.debug('loop %d completed' % i)
178417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
179417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if low_battery:
180417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.info('Exiting due to low battery')
181417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                break
1826a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
183417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        t1 = time.time()
184417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._tmp_keyvals['minutes_battery_life'] = (t1 - t0) / 60
1856a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1866a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1876a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda    def postprocess_iteration(self):
1886a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals = {}
1899d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
19087aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # refresh power related statistics
19187aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        usb_stats = self._usb_stats.refresh()
19287aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        cpufreq_stats = self._cpufreq_stats.refresh()
19387aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        cpuidle_stats = self._cpuidle_stats.refresh()
19487aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
19587aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record percent time USB devices were not in suspended state
19687aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        keyvals['percent_usb_active'] = usb_stats
19787aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
19887aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record percent time spent in each CPU C-state
19987aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        for state in cpuidle_stats:
20087aced24632053d9df0a42842307abf165f60ad1Sameer Nanda            keyvals['percent_cpuidle_%s_time' % state] = cpuidle_stats[state]
20187aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
20287aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record percent time spent at each CPU frequency
20387aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        for freq in cpufreq_stats:
20487aced24632053d9df0a42842307abf165f60ad1Sameer Nanda            keyvals['percent_cpufreq_%s_time' % freq] = cpufreq_stats[freq]
20587aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
20687aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record battery stats
20750fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['a_current_now'] = self._power_status.battery[0].current_now
2089d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_full'] = self._power_status.battery[0].charge_full
2096a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals['ah_charge_full_design'] = \
2109d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                             self._power_status.battery[0].charge_full_design
2119d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_start'] = self._ah_charge_start
2129d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_now'] = self._power_status.battery[0].charge_now
21350fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['ah_charge_used'] = keyvals['ah_charge_start'] - \
21450fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda                                    keyvals['ah_charge_now']
2159d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['wh_energy_start'] = self._wh_energy_start
2169d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['wh_energy_now'] = self._power_status.battery[0].energy
21750fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['wh_energy_used'] = keyvals['wh_energy_start'] - \
21850fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda                                    keyvals['wh_energy_now']
2196a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals['v_voltage_min_design'] = \
2209d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                             self._power_status.battery[0].voltage_min_design
2219d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['v_voltage_now'] = self._power_status.battery[0].voltage_now
2229d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
223417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals.update(self._tmp_keyvals)
224417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
225417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals['a_current_rate'] = keyvals['ah_charge_used'] * 60 / \
226417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                                    keyvals['minutes_battery_life']
227417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals['w_energy_rate'] = keyvals['wh_energy_used'] * 60 / \
228417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                                   keyvals['minutes_battery_life']
2296a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
2306a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        self.write_perf_keyval(keyvals)
2319d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2329d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2339d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def cleanup(self):
23406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung        # remove json file after test to stop external extension launch.
235dfc0199adabc92a7311df0f00629afb171495de9Benson Leung        if self._json_path:
236dfc0199adabc92a7311df0f00629afb171495de9Benson Leung            jsonfile = os.path.join(self._json_path, 'external_extensions.json')
237dfc0199adabc92a7311df0f00629afb171495de9Benson Leung            if os.path.exists(jsonfile):
238dfc0199adabc92a7311df0f00629afb171495de9Benson Leung                os.system('rm -f %s' % jsonfile)
239d075074b8fc70d829912864f819345407295f35dSameer Nanda        # re-enable powerd
2405aaf2314cf2bcdb9c89b42f3eb50e40cc76baf6bDavid James        os.system('start powerd')
241c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        if login.logged_in():
242c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li            login.attempt_logout()
243b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        # cleanup backchannel interface
244b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        if self._force_wifi:
245b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis            site_backchannel.teardown()
2469d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2479d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2489d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def _percent_current_charge(self):
2499d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        return self._power_status.battery[0].charge_now * 100 / \
2509d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda               self._power_status.battery[0].charge_full_design
2519d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2529d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2539d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def _write_ext_params(self):
2549d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        data = ''
2559d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        template= 'var %s = %s;\n'
2569d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        for k in params_dict:
2579d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            data += template % (k, getattr(self, params_dict[k]))
2589d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2599d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        filename = os.path.join(self._ext_path, 'params.js')
2609d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        utils.open_write_close(filename, data)
2619d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2629d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        logging.debug('filename ' + filename)
2639d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        logging.debug(data)
2649d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2659d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
26606548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def _do_wait(self, verbose, seconds, latch):
2679d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        latched = False
268417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        low_battery = False
269417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        total_time = seconds + 60
2709d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        elapsed_time = 0
271417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        wait_time = 60
2729d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2739d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        while elapsed_time < total_time:
2749d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            time.sleep(wait_time)
2759d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            elapsed_time += wait_time
2769d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
2779d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            self._power_status.refresh()
278417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if verbose:
279417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.debug('ah_charge_now %f' \
280417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    % self._power_status.battery[0].charge_now)
281417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.debug('w_energy_rate %f' \
282417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    % self._power_status.battery[0].energy_rate)
283417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
284417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            low_battery = (self._percent_current_charge() <
285417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                           self._low_battery_threshold)
286417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
287417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            latched = latch.is_set()
288417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
289417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if latched or low_battery:
2909d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                break
2919d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
292417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        if latched:
293417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            # record chrome power extension stats
294417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            form_data = self._testServer.get_form_entries()
295417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            logging.debug(form_data)
296417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            for e in form_data:
297417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                key = 'ext_' + e
298417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                if key in self._tmp_keyvals:
299417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    self._tmp_keyvals[key] += form_data[e]
300417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                else:
301417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    self._tmp_keyvals[key] = form_data[e]
302417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        else:
3039d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            logging.debug("Didn't get status back from power extension")
3049d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
305417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        return low_battery
306d075074b8fc70d829912864f819345407295f35dSameer Nanda
307d075074b8fc70d829912864f819345407295f35dSameer Nanda
308d075074b8fc70d829912864f819345407295f35dSameer Nanda    def _do_xset(self):
309d075074b8fc70d829912864f819345407295f35dSameer Nanda        XSET = 'LD_LIBRARY_PATH=/usr/local/lib xset'
310d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Disable X screen saver
311c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        ui.xsystem('%s s 0 0' % XSET)
312d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Disable DPMS Standby/Suspend/Off
313c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        ui.xsystem('%s dpms 0 0 0' % XSET)
314d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Force monitor on
315c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        ui.xsystem('%s dpms force on' % XSET)
316d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Save off X settings
317c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        ui.xsystem('%s q' % XSET)
318d075074b8fc70d829912864f819345407295f35dSameer Nanda
319d075074b8fc70d829912864f819345407295f35dSameer Nanda
320d075074b8fc70d829912864f819345407295f35dSameer Nanda    def _set_backlight_level(self):
321d075074b8fc70d829912864f819345407295f35dSameer Nanda        # set backlight level to 40% of max
322d075074b8fc70d829912864f819345407295f35dSameer Nanda        cmd = 'backlight-tool --set_brightness %d ' % (
323d075074b8fc70d829912864f819345407295f35dSameer Nanda              int(self._max_backlight * 0.4))
324d075074b8fc70d829912864f819345407295f35dSameer Nanda        os.system(cmd)
325d075074b8fc70d829912864f819345407295f35dSameer Nanda
326d075074b8fc70d829912864f819345407295f35dSameer Nanda        # record brightness level
327d075074b8fc70d829912864f819345407295f35dSameer Nanda        cmd = 'backlight-tool --get_brightness'
328d075074b8fc70d829912864f819345407295f35dSameer Nanda        level = int(utils.system_output(cmd).rstrip())
329d075074b8fc70d829912864f819345407295f35dSameer Nanda        logging.info('backlight level is %d' % level)
330d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._tmp_keyvals['level_backlight_current'] = level
331