power_LoadTest.py revision 21978453eaa14e284560915268cf9cb1b4604a48
1650be6d5f895abe5fd9fbca4cf242bdf92443c62Mike Truty# Copyright (c) 2012 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
521978453eaa14e284560915268cf9cb1b4604a48Todd Brochimport collections, logging, numpy, 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
92f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Brochfrom autotest_lib.client.cros import httpd, login, power_status, power_utils
103fa0580fde83c963b5f7f73636d5b9bb089f938cZdenek Behanfrom autotest_lib.client.cros import flimflam_test_path
1105c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Brochfrom autotest_lib.client.cros.audio import audio_helper
1202b5ce48af62ff6486a2423c0e0adea14e391a48Zdenek Behanimport flimflam
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',
217868162435adf9082b022a5ba6e00614c7c66381Simon Que    'tasks': '_tasks',
229d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda}
239d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
246a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
25e7c4cab13a8576a4f9de41b2dc1fb8c45c97424cEric Liclass power_LoadTest(cros_ui_test.UITest):
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',
5121978453eaa14e284560915268cf9cb1b4604a48Todd Broch                 scroll_by_pixels='600', test_low_batt_p=3,
529450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                 verbose=True, force_wifi=False, wifi_ap='', wifi_sec='none',
5305c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch                 wifi_pw='', tasks="", kblight_percent=10, volume_level=10,
5405c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch                 mic_gain=10):
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
652f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch        kblight_percent: percent brightness of keyboard backlight
6605c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch        volume_level: percent audio volume level
6705c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch        mic_gain: percent audio microphone gain level
6821978453eaa14e284560915268cf9cb1b4604a48Todd Broch        test_low_batt_p: percent battery at which test should stop
6921978453eaa14e284560915268cf9cb1b4604a48Todd Broch        sys_low_batt_p: percent battery at which power manager will
7021978453eaa14e284560915268cf9cb1b4604a48Todd Broch            shut-down the device
7121978453eaa14e284560915268cf9cb1b4604a48Todd Broch        sys_low_batt_s: seconds battery at which power manager will
7221978453eaa14e284560915268cf9cb1b4604a48Todd Broch            shut-down the device
739d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        """
74417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._loop_time = loop_time
75417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._loop_count = loop_count
76417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._mseconds = self._loop_time * 1000
779d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._verbose = verbose
7821978453eaa14e284560915268cf9cb1b4604a48Todd Broch
7921978453eaa14e284560915268cf9cb1b4604a48Todd Broch        self._sys_low_batt_p = 0.
8021978453eaa14e284560915268cf9cb1b4604a48Todd Broch        self._sys_low_batt_s = 0.
8121978453eaa14e284560915268cf9cb1b4604a48Todd Broch        self._test_low_batt_p = test_low_batt_p
829d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._should_scroll = should_scroll
839d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._should_scroll_up = should_scroll_up
849d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_loop = scroll_loop
859d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_interval_ms = scroll_interval_ms
869d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._scroll_by_pixels = scroll_by_pixels
87417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        self._tmp_keyvals = {}
88bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._power_status = power_status.get_status()
89b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        self._force_wifi = force_wifi
90b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        self._testServer = None
91ffd2a04887ca6c31a6c9501f4c0df8d418f4b055Simon Que        self._tasks = '\'' + tasks.replace(' ','') + '\''
92b312dcf7a07ffdfe5a9625bbb1b5b08e81158b39Jason Glasgow        self._backchannel = None
932f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch        self._kblight_percent = kblight_percent
9405c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch        self._volume_level = volume_level
9505c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch        self._mic_gain = mic_gain
9621978453eaa14e284560915268cf9cb1b4604a48Todd Broch        self._wait_time = 60
9721978453eaa14e284560915268cf9cb1b4604a48Todd Broch        self._stats = collections.defaultdict(list)
989d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
99cfa1ddf94edc7ac518a178415ec4a7c9a61a9dd6Todd Broch        self._power_status.assert_battery_state(percent_initial_charge_min)
1009450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis        # If force wifi enabled, convert eth0 to backchannel and connect to the
1019450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis        # specified WiFi AP.
102b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        if self._force_wifi:
1039450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis            # If backchannel is already running, don't run it again.
104b312dcf7a07ffdfe5a9625bbb1b5b08e81158b39Jason Glasgow            self._backchannel = backchannel.Backchannel()
105b312dcf7a07ffdfe5a9625bbb1b5b08e81158b39Jason Glasgow            if not self._backchannel.setup():
1069450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                raise error.TestError('Could not setup Backchannel network.')
1079450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis
108804448c0ab08762d4298716bb1a90831717e5ba7Julius Werner            if not flimflam.FlimFlam().ConnectService(retries=3,
1096e6be985c67de742de2d463ff8522355a3995f5dDale Curtis                                                      retry=True,
1109450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      service_type='wifi',
1119450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      ssid=wifi_ap,
1129450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      security=wifi_sec,
1139450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      passphrase=wifi_pw,
1149450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                                                      mode='managed')[0]:
1159450ad9bc6e5537d93f31bd53f161067fb13a1d5Dale Curtis                raise error.TestError('Could not connect to WiFi network.')
116278b5370c7d022768e0ab319ce7f439a877e4443Simon Que        else:
117278b5370c7d022768e0ab319ce7f439a877e4443Simon Que            # Find all wired ethernet interfaces.
118278b5370c7d022768e0ab319ce7f439a877e4443Simon Que            # TODO: combine this with code in network_DisableInterface, in a
119278b5370c7d022768e0ab319ce7f439a877e4443Simon Que            # common library somewhere.
120278b5370c7d022768e0ab319ce7f439a877e4443Simon Que            ifaces = [ nic.strip() for nic in os.listdir('/sys/class/net/')
121278b5370c7d022768e0ab319ce7f439a877e4443Simon Que                if ((not os.path.exists('/sys/class/net/' + nic + '/phy80211'))
122278b5370c7d022768e0ab319ce7f439a877e4443Simon Que                    and nic.find('eth') != -1) ]
123278b5370c7d022768e0ab319ce7f439a877e4443Simon Que            logging.debug(str(ifaces))
124278b5370c7d022768e0ab319ce7f439a877e4443Simon Que            for iface in ifaces:
125278b5370c7d022768e0ab319ce7f439a877e4443Simon Que              if check_network and backchannel.is_network_iface_running(iface):
126278b5370c7d022768e0ab319ce7f439a877e4443Simon Que                  raise error.TestError('Ethernet interface is active. ' + \
127278b5370c7d022768e0ab319ce7f439a877e4443Simon Que                                                'Please remove Ethernet cable')
1289d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
12905c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch        self._audio_helper = audio_helper.AudioHelper(None)
13005c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch
131d075074b8fc70d829912864f819345407295f35dSameer Nanda        # record the max backlight level
1324f99e9a29b81d14cc94eb711cdb4adb5e66872abSameer Nanda        cmd = 'backlight-tool --get_max_brightness'
133d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._max_backlight = int(utils.system_output(cmd).rstrip())
134d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._tmp_keyvals['level_backlight_max'] = self._max_backlight
1356a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
1369d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # fix up file perms for the power test extension so that chrome
1379d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        # can access it
138ce1407b29b32f8f8fb1121251e28f0861ecac6a8Sameer Nanda        os.system('chmod -R 755 %s' % self.bindir)
1399d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
1407bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        # write test parameters to the params.js file to be read by the test
1417bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        # extension.
1427bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        self._write_ext_params()
14306548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
1446a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        # setup a HTTP Server to listen for status updates from the power
1456a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        # test extension
146c4d8f4aab4e434fcb1a9fb33931768ffebfb8f1cEric Li        self._testServer = httpd.HTTPListener(8001, docroot=self.bindir)
1476a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        self._testServer.run()
1486a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
14987aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # initialize various interesting power related stats
150bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._usb_stats = power_status.USBSuspendStats()
151bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._cpufreq_stats = power_status.CPUFreqStats()
152bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        self._cpuidle_stats = power_status.CPUIdleStats()
153bec9d2222be708f7d03ab0d625f15dcb9c142ed3Julius Werner        self._cpupkg_stats = power_status.CPUPackageStats()
154c4133d233aa092c4cb9d6e399baaad4eaa16d187Julius Werner        self._disk_logger = power_status.DiskStateLogger()
155c4133d233aa092c4cb9d6e399baaad4eaa16d187Julius Werner        if os.path.exists('/dev/sda'):
156c4133d233aa092c4cb9d6e399baaad4eaa16d187Julius Werner            self._disk_logger.start()
157417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
1584ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner        self._power_status.refresh()
15921978453eaa14e284560915268cf9cb1b4604a48Todd Broch        (self._sys_low_batt_p, self._sys_low_batt_s) = \
16021978453eaa14e284560915268cf9cb1b4604a48Todd Broch            self._get_sys_low_batt_values()
16121978453eaa14e284560915268cf9cb1b4604a48Todd Broch        if self._sys_low_batt_p and (self._sys_low_batt_p >
16221978453eaa14e284560915268cf9cb1b4604a48Todd Broch                                     self._test_low_batt_p):
16321978453eaa14e284560915268cf9cb1b4604a48Todd Broch            logging.warn("test low battery threshold is below system ",
16421978453eaa14e284560915268cf9cb1b4604a48Todd Broch                         "low battery requirement.  Setting to %f",
16521978453eaa14e284560915268cf9cb1b4604a48Todd Broch                         self._sys_low_batt_p)
16621978453eaa14e284560915268cf9cb1b4604a48Todd Broch            self._test_low_batt_p = self._sys_low_batt_p
1674ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner
1689d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._ah_charge_start = self._power_status.battery[0].charge_now
1699d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        self._wh_energy_start = self._power_status.battery[0].energy
1709d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
171e7c4cab13a8576a4f9de41b2dc1fb8c45c97424cEric Li        # from cros_ui_test.UITest.initialize, sans authserver & local dns.
172d73c2565c6d2756c52c793808455fd8b685b910eScott James Remnant        cros_ui_test.UITest.initialize(self, creds)
17306548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
17406548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung    def run_once(self):
17506548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung
176417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        t0 = time.time()
177b55127d7cb78888e43f96a232feda409abcab1e9Nirnimesh        ext_path = os.path.join(os.path.dirname(__file__), 'extension.crx')
178417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
1792f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch        try:
1802f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch            kblight = power_utils.KbdBacklight()
1812f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch            kblight.set(self._kblight_percent)
1822f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch            self._tmp_keyvals['percent_kbd_backlight'] = kblight.get()
1832f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch        except power_utils.KbdBacklightException as e:
1842f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch            logging.info("Assuming no keyboard backlight due to :: %s", str(e))
1852f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch            kblight = None
1862f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch
187417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        for i in range(self._loop_count):
188417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            # the power test extension will report its status here
189417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            latch = self._testServer.add_wait_url('/status')
1906a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
191b55127d7cb78888e43f96a232feda409abcab1e9Nirnimesh            # Installing the extension will also fire it up.
192b55127d7cb78888e43f96a232feda409abcab1e9Nirnimesh            ext_id = self.pyauto.InstallExtension(ext_path)
193417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
194d075074b8fc70d829912864f819345407295f35dSameer Nanda            # stop powerd
195d075074b8fc70d829912864f819345407295f35dSameer Nanda            os.system('stop powerd')
196d075074b8fc70d829912864f819345407295f35dSameer Nanda
197d075074b8fc70d829912864f819345407295f35dSameer Nanda            # reset X settings since X gets restarted upon login
198d075074b8fc70d829912864f819345407295f35dSameer Nanda            self._do_xset()
199d075074b8fc70d829912864f819345407295f35dSameer Nanda
200d075074b8fc70d829912864f819345407295f35dSameer Nanda            # reset backlight level since powerd might've modified it
201d075074b8fc70d829912864f819345407295f35dSameer Nanda            # based on ambient light
202d075074b8fc70d829912864f819345407295f35dSameer Nanda            self._set_backlight_level()
203698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch            self._set_lightbar_level()
2042f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch            if kblight:
2052f156e8967fab4b4ffe38cd727aaeabf5e4080f6Todd Broch                kblight.set(self._kblight_percent)
20605c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch            self._audio_helper.set_volume_levels(self._volume_level,
20705c4b5d1b1417c4e38f184416b0d0ede23cd4e0aTodd Broch                                                 self._mic_gain)
208d075074b8fc70d829912864f819345407295f35dSameer Nanda
209417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            low_battery = self._do_wait(self._verbose, self._loop_time,
21006548eee3dafcf0fc9ee0dcd15eb607b901ad2c1Benson Leung                                        latch)
211417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
212417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if self._verbose:
213417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.debug('loop %d completed' % i)
214417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
215417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if low_battery:
216417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                logging.info('Exiting due to low battery')
217417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                break
2186a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
219b55127d7cb78888e43f96a232feda409abcab1e9Nirnimesh            if not self.pyauto.GetBrowserWindowCount():
220b55127d7cb78888e43f96a232feda409abcab1e9Nirnimesh                self.pyauto.OpenNewBrowserWindow(True)
221b55127d7cb78888e43f96a232feda409abcab1e9Nirnimesh            self.pyauto.UninstallExtensionById(ext_id)
222bc1c98747adc2bcb9c0a7d130a3188f2f424aaffNirnimesh
223417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        t1 = time.time()
22421978453eaa14e284560915268cf9cb1b4604a48Todd Broch        self._tmp_keyvals['minutes_battery_life_tested'] = (t1 - t0) / 60
2256a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
2266a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
2276a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda    def postprocess_iteration(self):
2284ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner        def _format_stats(keyvals, stats, name):
2294ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner            for state in stats:
2304ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner                keyvals['percent_%s_%s_time' % (name, state)] = stats[state]
2319d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
23221978453eaa14e284560915268cf9cb1b4604a48Todd Broch
23321978453eaa14e284560915268cf9cb1b4604a48Todd Broch        def _log_stats(prefix, stats):
23421978453eaa14e284560915268cf9cb1b4604a48Todd Broch            if not len(stats):
23521978453eaa14e284560915268cf9cb1b4604a48Todd Broch                return
23621978453eaa14e284560915268cf9cb1b4604a48Todd Broch            np = numpy.array(stats)
23721978453eaa14e284560915268cf9cb1b4604a48Todd Broch            logging.debug("%s samples: %d", prefix, len(np))
23821978453eaa14e284560915268cf9cb1b4604a48Todd Broch            logging.debug("%s mean:    %.2f", prefix, np.mean())
23921978453eaa14e284560915268cf9cb1b4604a48Todd Broch            logging.debug("%s stdev:   %.2f", prefix, np.std())
24021978453eaa14e284560915268cf9cb1b4604a48Todd Broch            logging.debug("%s max:     %.2f", prefix, np.max())
24121978453eaa14e284560915268cf9cb1b4604a48Todd Broch            logging.debug("%s min:     %.2f", prefix, np.min())
24221978453eaa14e284560915268cf9cb1b4604a48Todd Broch
24321978453eaa14e284560915268cf9cb1b4604a48Todd Broch
24421978453eaa14e284560915268cf9cb1b4604a48Todd Broch        def _log_per_loop_stats():
24521978453eaa14e284560915268cf9cb1b4604a48Todd Broch            samples_per_loop = self._loop_time / self._wait_time + 1
24621978453eaa14e284560915268cf9cb1b4604a48Todd Broch            for kname in self._stats:
24721978453eaa14e284560915268cf9cb1b4604a48Todd Broch                start_idx = 0
24821978453eaa14e284560915268cf9cb1b4604a48Todd Broch                loop = 1
24921978453eaa14e284560915268cf9cb1b4604a48Todd Broch                for end_idx in xrange(samples_per_loop, len(self._stats[kname]),
25021978453eaa14e284560915268cf9cb1b4604a48Todd Broch                                      samples_per_loop):
25121978453eaa14e284560915268cf9cb1b4604a48Todd Broch                    _log_stats("%s loop %d" % (kname, loop),
25221978453eaa14e284560915268cf9cb1b4604a48Todd Broch                               self._stats[kname][start_idx:end_idx])
25321978453eaa14e284560915268cf9cb1b4604a48Todd Broch                    loop += 1
25421978453eaa14e284560915268cf9cb1b4604a48Todd Broch                    start_idx = end_idx
25521978453eaa14e284560915268cf9cb1b4604a48Todd Broch
25621978453eaa14e284560915268cf9cb1b4604a48Todd Broch
25721978453eaa14e284560915268cf9cb1b4604a48Todd Broch        def _log_all_stats():
25821978453eaa14e284560915268cf9cb1b4604a48Todd Broch            for kname in self._stats:
25921978453eaa14e284560915268cf9cb1b4604a48Todd Broch                _log_stats(kname, self._stats[kname])
26021978453eaa14e284560915268cf9cb1b4604a48Todd Broch
26121978453eaa14e284560915268cf9cb1b4604a48Todd Broch
2624ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner        keyvals = {}
26387aced24632053d9df0a42842307abf165f60ad1Sameer Nanda
2644ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner        _format_stats(keyvals, self._usb_stats.refresh(), 'usb')
2654ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner        _format_stats(keyvals, self._cpufreq_stats.refresh(), 'cpufreq')
266bec9d2222be708f7d03ab0d625f15dcb9c142ed3Julius Werner        _format_stats(keyvals, self._cpupkg_stats.refresh(), 'cpupkg')
2674ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner        _format_stats(keyvals, self._cpuidle_stats.refresh(), 'cpuidle')
26821978453eaa14e284560915268cf9cb1b4604a48Todd Broch
26921978453eaa14e284560915268cf9cb1b4604a48Todd Broch        _log_all_stats()
27021978453eaa14e284560915268cf9cb1b4604a48Todd Broch        _log_per_loop_stats()
271c4133d233aa092c4cb9d6e399baaad4eaa16d187Julius Werner        if (self._disk_logger.get_error()):
272c4133d233aa092c4cb9d6e399baaad4eaa16d187Julius Werner            keyvals['disk_logging_error'] = str(self._disk_logger.get_error())
273c4133d233aa092c4cb9d6e399baaad4eaa16d187Julius Werner        else:
2744ae320f5b4afd9c047dfa446d76722100c03665bJulius Werner            _format_stats(keyvals, self._disk_logger.result(), 'disk')
275c4133d233aa092c4cb9d6e399baaad4eaa16d187Julius Werner
27687aced24632053d9df0a42842307abf165f60ad1Sameer Nanda        # record battery stats
27750fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['a_current_now'] = self._power_status.battery[0].current_now
2789d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_full'] = self._power_status.battery[0].charge_full
2796a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals['ah_charge_full_design'] = \
2809d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                             self._power_status.battery[0].charge_full_design
2819d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_start'] = self._ah_charge_start
2829d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['ah_charge_now'] = self._power_status.battery[0].charge_now
28350fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['ah_charge_used'] = keyvals['ah_charge_start'] - \
28450fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda                                    keyvals['ah_charge_now']
2859d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['wh_energy_start'] = self._wh_energy_start
2869d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['wh_energy_now'] = self._power_status.battery[0].energy
28750fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda        keyvals['wh_energy_used'] = keyvals['wh_energy_start'] - \
28850fb54165e35caebc1bd90d409fcba0fe0b01658Sameer Nanda                                    keyvals['wh_energy_now']
2896a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        keyvals['v_voltage_min_design'] = \
2909d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                             self._power_status.battery[0].voltage_min_design
29121978453eaa14e284560915268cf9cb1b4604a48Todd Broch        keyvals['wh_energy_full_design'] = \
29221978453eaa14e284560915268cf9cb1b4604a48Todd Broch                             self._power_status.battery[0].energy_full_design
2939d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        keyvals['v_voltage_now'] = self._power_status.battery[0].voltage_now
2949d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
295417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals.update(self._tmp_keyvals)
296417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
29721978453eaa14e284560915268cf9cb1b4604a48Todd Broch        keyvals['percent_sys_low_battery'] = self._sys_low_batt_p
29821978453eaa14e284560915268cf9cb1b4604a48Todd Broch        keyvals['seconds_sys_low_battery'] = self._sys_low_batt_s
29921978453eaa14e284560915268cf9cb1b4604a48Todd Broch        voltage_np = numpy.array(self._stats['v_voltage_now'])
30021978453eaa14e284560915268cf9cb1b4604a48Todd Broch        voltage_mean = voltage_np.mean()
30121978453eaa14e284560915268cf9cb1b4604a48Todd Broch        keyvals['v_voltage_mean'] = voltage_mean
30221978453eaa14e284560915268cf9cb1b4604a48Todd Broch        bat_life_scale = (keyvals['wh_energy_full_design'] /
30321978453eaa14e284560915268cf9cb1b4604a48Todd Broch                          (keyvals['ah_charge_used'] * voltage_mean)) * \
30421978453eaa14e284560915268cf9cb1b4604a48Todd Broch                          (100 - keyvals['percent_sys_low_battery'] / 100)
30521978453eaa14e284560915268cf9cb1b4604a48Todd Broch
30621978453eaa14e284560915268cf9cb1b4604a48Todd Broch        keyvals['minutes_battery_life'] = bat_life_scale * \
30721978453eaa14e284560915268cf9cb1b4604a48Todd Broch            keyvals['minutes_battery_life_tested']
30821978453eaa14e284560915268cf9cb1b4604a48Todd Broch        # In the case where sys_low_batt_s is non-zero subtract those minutes
30921978453eaa14e284560915268cf9cb1b4604a48Todd Broch        # from the final extrapolation.
31021978453eaa14e284560915268cf9cb1b4604a48Todd Broch        if self._sys_low_batt_s:
31121978453eaa14e284560915268cf9cb1b4604a48Todd Broch            keyvals['minutes_battery_life'] -= self._sys_low_batt_s / 60
31221978453eaa14e284560915268cf9cb1b4604a48Todd Broch
313417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals['a_current_rate'] = keyvals['ah_charge_used'] * 60 / \
314417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                                    keyvals['minutes_battery_life']
315417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        keyvals['w_energy_rate'] = keyvals['wh_energy_used'] * 60 / \
316417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                                   keyvals['minutes_battery_life']
317d8e41b7356a3067b7b7561f3a8fe8f12ff2731d6Simon Que        keyvals['mc_min_temp'] = self._power_status.min_temp
318d8e41b7356a3067b7b7561f3a8fe8f12ff2731d6Simon Que        keyvals['mc_max_temp'] = self._power_status.max_temp
3196a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda
3206a0746595cb21c52db2b4ef2e03ff1d73a75c1d0Sameer Nanda        self.write_perf_keyval(keyvals)
3219d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3229d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3239d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def cleanup(self):
324d075074b8fc70d829912864f819345407295f35dSameer Nanda        # re-enable powerd
3255aaf2314cf2bcdb9c89b42f3eb50e40cc76baf6bDavid James        os.system('start powerd')
326b5056ea955d1997ce7d28441656f6134b30a1a07Dale Curtis        # cleanup backchannel interface
327b312dcf7a07ffdfe5a9625bbb1b5b08e81158b39Jason Glasgow        if self._backchannel:
328b312dcf7a07ffdfe5a9625bbb1b5b08e81158b39Jason Glasgow            self._backchannel.teardown()
329b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis        if self._testServer:
330b7edff18c59e1caedc32f972551ec68b3620eea5Dale Curtis            self._testServer.stop()
3316cdaebad4a36d0ad917f9c1285910e66539d0d1aBenson Leung        super(power_LoadTest, self).cleanup()
3329d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3339d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3349d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda    def _write_ext_params(self):
3359d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        data = ''
3369d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        template= 'var %s = %s;\n'
3379d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        for k in params_dict:
3389d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            data += template % (k, getattr(self, params_dict[k]))
3399d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3407bcd700c40df1de04d8bf58e8f60f132df06b8e5Benson Leung        filename = os.path.join(self.bindir, 'params.js')
3419d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        utils.open_write_close(filename, data)
3429d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3439d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        logging.debug('filename ' + filename)
3449d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        logging.debug(data)
3459d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3469d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3472e56d3461849c3066023f0f6e9e9060523d72d30Mike Truty    def _do_wait(self, verbose, seconds, latch):
3489d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda        latched = False
349417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        low_battery = False
35021978453eaa14e284560915268cf9cb1b4604a48Todd Broch        total_time = seconds + self._wait_time
3512e56d3461849c3066023f0f6e9e9060523d72d30Mike Truty        elapsed_time = 0
3529d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3532e56d3461849c3066023f0f6e9e9060523d72d30Mike Truty        while elapsed_time < total_time:
35421978453eaa14e284560915268cf9cb1b4604a48Todd Broch            time.sleep(self._wait_time)
35521978453eaa14e284560915268cf9cb1b4604a48Todd Broch            elapsed_time += self._wait_time
3569d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
3579d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            self._power_status.refresh()
35821978453eaa14e284560915268cf9cb1b4604a48Todd Broch            charge_now = self._power_status.battery[0].charge_now
35921978453eaa14e284560915268cf9cb1b4604a48Todd Broch            energy_rate = self._power_status.battery[0].energy_rate
36021978453eaa14e284560915268cf9cb1b4604a48Todd Broch            voltage_now = self._power_status.battery[0].voltage_now
36121978453eaa14e284560915268cf9cb1b4604a48Todd Broch            self._stats['w_energy_rate'].append(energy_rate)
36221978453eaa14e284560915268cf9cb1b4604a48Todd Broch            self._stats['v_voltage_now'].append(voltage_now)
363417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if verbose:
36421978453eaa14e284560915268cf9cb1b4604a48Todd Broch                logging.debug('ah_charge_now %f', charge_now)
36521978453eaa14e284560915268cf9cb1b4604a48Todd Broch                logging.debug('w_energy_rate %f', energy_rate)
36621978453eaa14e284560915268cf9cb1b4604a48Todd Broch                logging.debug('v_voltage_now %f', voltage_now)
367417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
368cfa1ddf94edc7ac518a178415ec4a7c9a61a9dd6Todd Broch            low_battery = (self._power_status.percent_current_charge() <
36921978453eaa14e284560915268cf9cb1b4604a48Todd Broch                           self._test_low_batt_p)
370417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
371417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            latched = latch.is_set()
372417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda
373417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            if latched or low_battery:
3749d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda                break
3759d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
376417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        if latched:
377417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            # record chrome power extension stats
378417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            form_data = self._testServer.get_form_entries()
379417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            logging.debug(form_data)
380417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda            for e in form_data:
381417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                key = 'ext_' + e
382417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                if key in self._tmp_keyvals:
383417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    self._tmp_keyvals[key] += form_data[e]
384417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                else:
385417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda                    self._tmp_keyvals[key] = form_data[e]
386417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        else:
3879d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda            logging.debug("Didn't get status back from power extension")
3889d4bcb6d907ad23d947f65d3c764c8ee3848e7d3Sameer Nanda
389417da5be901b3e68131017e1a631bdd84835b1d2Sameer Nanda        return low_battery
390d075074b8fc70d829912864f819345407295f35dSameer Nanda
391d075074b8fc70d829912864f819345407295f35dSameer Nanda
392d075074b8fc70d829912864f819345407295f35dSameer Nanda    def _do_xset(self):
393d075074b8fc70d829912864f819345407295f35dSameer Nanda        XSET = 'LD_LIBRARY_PATH=/usr/local/lib xset'
394d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Disable X screen saver
39551d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s s 0 0' % XSET)
396d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Disable DPMS Standby/Suspend/Off
39751d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s dpms 0 0 0' % XSET)
398d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Force monitor on
39951d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s dpms force on' % XSET)
400d075074b8fc70d829912864f819345407295f35dSameer Nanda        # Save off X settings
40151d1939bf47960b6e65042402a900e0564aa6d3eEric Li        cros_ui.xsystem('%s q' % XSET)
402d075074b8fc70d829912864f819345407295f35dSameer Nanda
403d075074b8fc70d829912864f819345407295f35dSameer Nanda
404d075074b8fc70d829912864f819345407295f35dSameer Nanda    def _set_backlight_level(self):
405d075074b8fc70d829912864f819345407295f35dSameer Nanda        # set backlight level to 40% of max
406d075074b8fc70d829912864f819345407295f35dSameer Nanda        cmd = 'backlight-tool --set_brightness %d ' % (
407d075074b8fc70d829912864f819345407295f35dSameer Nanda              int(self._max_backlight * 0.4))
408d075074b8fc70d829912864f819345407295f35dSameer Nanda        os.system(cmd)
409d075074b8fc70d829912864f819345407295f35dSameer Nanda
410d075074b8fc70d829912864f819345407295f35dSameer Nanda        # record brightness level
411d075074b8fc70d829912864f819345407295f35dSameer Nanda        cmd = 'backlight-tool --get_brightness'
412d075074b8fc70d829912864f819345407295f35dSameer Nanda        level = int(utils.system_output(cmd).rstrip())
413d075074b8fc70d829912864f819345407295f35dSameer Nanda        logging.info('backlight level is %d' % level)
414d075074b8fc70d829912864f819345407295f35dSameer Nanda        self._tmp_keyvals['level_backlight_current'] = level
415698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch
416698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch
417698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch    def _set_lightbar_level(self, level='off'):
418698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        """Set lightbar level.
419698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch
420698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        Args:
421698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch          level: string value to set lightbar to.  See ectool for more details.
422698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        """
423698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        rv = utils.system('which ectool', ignore_status=True)
424698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        if rv:
425698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch            return
426698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        rv = utils.system('ectool lightbar %s' % level, ignore_status=True)
427698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        if rv:
428698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch            logging.info('Assuming no lightbar due to non-zero exit status')
429698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch        else:
430698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch            logging.info('Setting lightbar to %s', level)
431698956153242dfb51ebdaadef4317749c7fc4be0Todd Broch            self._tmp_keyvals['level_lightbar_current'] = level
43221978453eaa14e284560915268cf9cb1b4604a48Todd Broch
43321978453eaa14e284560915268cf9cb1b4604a48Todd Broch
43421978453eaa14e284560915268cf9cb1b4604a48Todd Broch    def _get_sys_low_batt_values(self):
43521978453eaa14e284560915268cf9cb1b4604a48Todd Broch        """Determine the low battery values for device and return.
43621978453eaa14e284560915268cf9cb1b4604a48Todd Broch
43721978453eaa14e284560915268cf9cb1b4604a48Todd Broch        2012/11/01: power manager (powerd.cc) parses parameters in filesystem
43821978453eaa14e284560915268cf9cb1b4604a48Todd Broch          and outputs a log message like:
43921978453eaa14e284560915268cf9cb1b4604a48Todd Broch
44021978453eaa14e284560915268cf9cb1b4604a48Todd Broch           [1101/173837:INFO:powerd.cc(258)] Using low battery time threshold
44121978453eaa14e284560915268cf9cb1b4604a48Todd Broch                     of 0 secs and using low battery percent threshold of 3.5
44221978453eaa14e284560915268cf9cb1b4604a48Todd Broch
44321978453eaa14e284560915268cf9cb1b4604a48Todd Broch           It currently checks to make sure that only one of these values is
44421978453eaa14e284560915268cf9cb1b4604a48Todd Broch           defined.
44521978453eaa14e284560915268cf9cb1b4604a48Todd Broch
44621978453eaa14e284560915268cf9cb1b4604a48Todd Broch        Returns:
44721978453eaa14e284560915268cf9cb1b4604a48Todd Broch          Tuple of (percent, seconds)
44821978453eaa14e284560915268cf9cb1b4604a48Todd Broch            percent: float of low battery percentage
44921978453eaa14e284560915268cf9cb1b4604a48Todd Broch            seconds: float of low battery seconds
45021978453eaa14e284560915268cf9cb1b4604a48Todd Broch
45121978453eaa14e284560915268cf9cb1b4604a48Todd Broch        """
45221978453eaa14e284560915268cf9cb1b4604a48Todd Broch        split_re = 'threshold of'
45321978453eaa14e284560915268cf9cb1b4604a48Todd Broch
45421978453eaa14e284560915268cf9cb1b4604a48Todd Broch        powerd_log = '/var/log/power_manager/powerd.LATEST'
45521978453eaa14e284560915268cf9cb1b4604a48Todd Broch        cmd = 'grep "low battery time" %s' % powerd_log
45621978453eaa14e284560915268cf9cb1b4604a48Todd Broch        line = utils.system_output(cmd)
45721978453eaa14e284560915268cf9cb1b4604a48Todd Broch        secs = float(line.split(split_re)[1].split()[0])
45821978453eaa14e284560915268cf9cb1b4604a48Todd Broch        percent = float(line.split(split_re)[2].split()[0])
45921978453eaa14e284560915268cf9cb1b4604a48Todd Broch        if secs and percent:
46021978453eaa14e284560915268cf9cb1b4604a48Todd Broch            raise error.TestError("Low battery percent and seconds " +
46121978453eaa14e284560915268cf9cb1b4604a48Todd Broch                                  "are non-zero.")
46221978453eaa14e284560915268cf9cb1b4604a48Todd Broch        return (percent, secs)
463