11a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
21a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky# Use of this source code is governed by a BSD-style license that can be
31a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky# found in the LICENSE file.
41a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
5964a7dc21a2e74ef0ba01efc428cf9b01baa9b47Todd Brochimport logging
6964a7dc21a2e74ef0ba01efc428cf9b01baa9b47Todd Brochimport os
7964a7dc21a2e74ef0ba01efc428cf9b01baa9b47Todd Brochimport time
8964a7dc21a2e74ef0ba01efc428cf9b01baa9b47Todd Brochimport urllib
909e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky
10540af155fcd1016257478c22de8828b449d18085Puthikorn Voravootivatfrom autotest_lib.client.bin import site_utils, test, utils
111a739e719992caed23fdf9c35957417d21c80541Mark Koudritskyfrom autotest_lib.client.common_lib import error
1209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritskyfrom autotest_lib.client.common_lib.cros import chrome
131a739e719992caed23fdf9c35957417d21c80541Mark Koudritskyfrom autotest_lib.client.cros import backchannel
140ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch# pylint: disable=W0611
1509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritskyfrom autotest_lib.client.cros import flimflam_test_path  # Needed for flimflam
161a739e719992caed23fdf9c35957417d21c80541Mark Koudritskyfrom autotest_lib.client.cros import httpd
178f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Brochfrom autotest_lib.client.cros import power_rapl, power_status, power_utils
18b74d224b49cbc205d60b2238593695f3a79f964dRyan Harrisonfrom autotest_lib.client.cros import service_stopper
198753d83937751e6d2eb2646ea5af68979bb76312Ilja H. Friedelfrom autotest_lib.client.cros.graphics import graphics_utils
20440b4a856c75e6f947c6433f42545f865ce647c1Chris Masoneimport flimflam  # Requires flimflam_test_path to be imported first.
211a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
221a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritskyclass power_Consumption(test.test):
241a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    """Measure power consumption for different types of loads.
251a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
261a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    This test runs a series of different tasks like media playback, flash
271a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    animation, large file download etc. It measures and reports power
281a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    consumptions during each of those tasks.
291a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    """
301a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3109e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky    version = 2
321a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
331a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
349d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch    def initialize(self, ac_ok=False):
359d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch        """Initialize test.
369d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch
379d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch        Args:
389d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch            ac_ok: boolean to allow running on AC
399d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch        """
400dd8fb71470681de1a36d7fccc51454d843f35e8Mark Koudritsky        # Objects that need to be taken care of in cleanup() are initialized
410dd8fb71470681de1a36d7fccc51454d843f35e8Mark Koudritsky        # here to None. Otherwise we run the risk of AttributeError raised in
420dd8fb71470681de1a36d7fccc51454d843f35e8Mark Koudritsky        # cleanup() masking a real error that caused the test to fail during
430dd8fb71470681de1a36d7fccc51454d843f35e8Mark Koudritsky        # initialize() before those variables were assigned.
44af5de98643110a67a9f5c323dd56be3eb1e35448Todd Broch        self._backlight = None
459d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch        self._tmp_keyvals = {}
461a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
47d16f1daab3a354b637065b99dbc31809ce5674ddAlex Miller        self._services = service_stopper.ServiceStopper(
48d16f1daab3a354b637065b99dbc31809ce5674ddAlex Miller            service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
49d16f1daab3a354b637065b99dbc31809ce5674ddAlex Miller        self._services.stop_services()
50d16f1daab3a354b637065b99dbc31809ce5674ddAlex Miller
51d16f1daab3a354b637065b99dbc31809ce5674ddAlex Miller
521a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # Time to exclude from calculation after firing a task [seconds]
531a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._stabilization_seconds = 5
541a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._power_status = power_status.get_status()
559d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch        self._tmp_keyvals['b_on_ac'] = self._power_status.on_ac()
569d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch
579d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch        if not ac_ok:
589d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch            # Verify that we are running on battery and the battery is
599d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch            # sufficiently charged
609d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch            self._power_status.assert_battery_state(30)
611a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
62d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        # Find the battery capacity to report expected battery life in hours
63d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        batinfo = self._power_status.battery[0]
64d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        self.energy_full_design = batinfo.energy_full_design
6587230243479653137695efbd1d5a4e2de20a1133Daniel Kurtz        logging.info("energy_full_design = %0.3f Wh", self.energy_full_design)
66d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
67b8b5b462ef2ea1fd2c80a0ffbefffd4361f6092cMark Koudritsky        # Local data and web server settings. Tarballs with traditional names
68b8b5b462ef2ea1fd2c80a0ffbefffd4361f6092cMark Koudritsky        # like *.tgz don't get copied to the image by ebuilds (see
69b8b5b462ef2ea1fd2c80a0ffbefffd4361f6092cMark Koudritsky        # AUTOTEST_FILE_MASK in autotest-chrome ebuild).
70974858853d9218b023a79abc928b7f1c220bc293Mark Koudritsky        self._static_sub_dir = 'static_sites'
71974858853d9218b023a79abc928b7f1c220bc293Mark Koudritsky        utils.extract_tarball_to_dir(
72b8b5b462ef2ea1fd2c80a0ffbefffd4361f6092cMark Koudritsky                'static_sites.tgz.keep',
73974858853d9218b023a79abc928b7f1c220bc293Mark Koudritsky                os.path.join(self.bindir, self._static_sub_dir))
741a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._media_dir = '/home/chronos/user/Downloads/'
751a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._httpd_port = 8000
761a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._url_base = 'http://localhost:%s/' % self._httpd_port
771a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._test_server = httpd.HTTPListener(self._httpd_port,
781a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                                               docroot=self.bindir)
791a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
802ace7ae10114702d7b1be3d04e886da4182c0507Ravi Chandra Sadineni        # initialize various interesting power related stats
812ace7ae10114702d7b1be3d04e886da4182c0507Ravi Chandra Sadineni        self._statomatic = power_status.StatoMatic()
821a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._test_server.run()
831a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
842ace7ae10114702d7b1be3d04e886da4182c0507Ravi Chandra Sadineni
8509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        logging.info('initialize() finished')
861a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
871a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
881a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _download_test_data(self):
891a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Download audio and video files.
901a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
911a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        This is also used as payload for download test.
9213dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch
9313dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch        Note, can reach payload via browser at
9413dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch          https://console.developers.google.com/storage/chromeos-test-public/big_buck_bunny
9513dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch        Start with README
961a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """
971a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
9812af4ae8b29f4ff3809f0b961ea59217cc77e06aMark Koudritsky        repo = 'http://commondatastorage.googleapis.com/chromeos-test-public/'
9909e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        file_list = [repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.mp4', ]
100d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        if not self.short:
101d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            file_list += [
102d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.ogg',
1034922ad63220f45f8c1864cc39e9786d0a3e9bd9aTodd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.vp8.webm',
10413dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.vp9.webm',
105b6a1190bc58b63c4b849033d5132ba43477fe6a1Todd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.mp4',
106b6a1190bc58b63c4b849033d5132ba43477fe6a1Todd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.ogg',
1074922ad63220f45f8c1864cc39e9786d0a3e9bd9aTodd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.vp8.webm',
10813dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.vp9.webm',
109b6a1190bc58b63c4b849033d5132ba43477fe6a1Todd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.mp4',
110d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.ogg',
1114922ad63220f45f8c1864cc39e9786d0a3e9bd9aTodd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.vp8.webm',
11213dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.vp9.webm',
11309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky                repo + 'wikimedia/Greensleeves.ogg',
11409e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky                ]
1151a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1161a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for url in file_list:
1171a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            logging.info('Downloading %s', url)
1181a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            utils.unmap_url('', url, self._media_dir)
1191a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1201a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
12109e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky    def _toggle_fullscreen(self):
12209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        """Toggle full screen mode."""
12309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # Note: full screen mode toggled with F11 is different from clicking the
12409e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # full screen icon on video player controls. This needs improvement.
12509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # Bug: http://crbug.com/248939
1265780546bf60fa1b8e49528f3f4abac4796f3af6aIlja Friedel        graphics_utils.screen_toggle_fullscreen()
1271a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1281a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1291a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    # Below are a series of generic sub-test runners. They run a given task
1301a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    # and record the task name and start-end timestamps for future computation
1311a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    # of power consumption during the task.
132d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky    def _run_func(self, name, func, repeat=1, save_checkpoint=True):
1331a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Run a given python function as a sub-test."""
1341a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        start_time = time.time() + self._stabilization_seconds
1351a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for _ in xrange(repeat):
1361a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            ret = func()
137d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        if save_checkpoint:
138d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            self._plog.checkpoint(name, start_time)
1391a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        return ret
1401a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1411a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1421a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_sleep(self, name, seconds=60):
1431a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Just sleep and record it as a named sub-test"""
1441a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        start_time = time.time() + self._stabilization_seconds
1451a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        time.sleep(seconds)
14631535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        self._plog.checkpoint(name, start_time)
1471a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1481a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1491a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_cmd(self, name, cmd, repeat=1):
1501a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Run command in a shell as a sub-test"""
1511a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        start_time = time.time() + self._stabilization_seconds
1521a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for _ in xrange(repeat):
15309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            logging.info('Executing command: %s', cmd)
1541a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            exit_status = utils.system(cmd, ignore_status=True)
1551a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            if exit_status != 0:
1561a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                logging.error('run_cmd: the following command terminated with'
1571a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                                'a non zero exit status: %s', cmd)
15831535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        self._plog.checkpoint(name, start_time)
1591a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        return exit_status
1601a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1611a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
16209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky    def _run_until(self, name, predicate, timeout=60):
1631a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Probe the |predicate| function  and wait until it returns true.
1641a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        Record the waiting time as a sub-test
1651a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """
1661a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        start_time = time.time() + self._stabilization_seconds
1670f9f91b47342848b2e76e669f025a4c3bb8208e8Mark Koudritsky        utils.poll_for_condition(predicate, timeout=timeout)
16831535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        self._plog.checkpoint(name, start_time)
1691a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1701a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1711a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_url(self, name, url, duration):
1721a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Navigate to URL, sleep for some time and record it as a sub-test."""
17309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        logging.info('Navigating to %s', url)
17409e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        self._tab.Activate()
17509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        self._tab.Navigate(url)
1761a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._run_sleep(name, duration)
17709e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        tab_title = self._tab.EvaluateJavaScript('document.title')
1781a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        logging.info('Sub-test name: %s Tab title: %s.', name, tab_title)
1791a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1801a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1811a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_url_bg(self, name, url, duration):
1821a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Run a web site in background tab.
1831a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1841a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        Navigate to the given URL, open an empty tab to put the one with the
1851a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        URL in background, then sleep and record it as a sub-test.
1861a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
1871a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        Args:
1881a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            name: sub-test name.
1891a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            url: url to open in background tab.
1901a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            duration: number of seconds to sleep while taking measurements.
1911a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """
19209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        bg_tab = self._tab
19309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        bg_tab.Navigate(url)
1941a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # Let it load and settle
1951a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        time.sleep(self._stabilization_seconds / 2.)
19609e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        tab_title = bg_tab.EvaluateJavaScript('document.title')
1971a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        logging.info('App name: %s Tab title: %s.', name, tab_title)
19809e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # Open a new empty tab to cover the one with test payload.
1990ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch        fg_tab = self._browser.tabs.New()
20009e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        fg_tab.Activate()
2011a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._run_sleep(name, duration)
20209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        fg_tab.Close()
20309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        bg_tab.Activate()
2041a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2051a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2061a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_download(self):
2071a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Download over ethernet. Using video test data as payload."""
208d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
209d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        # For short run, the payload is too small to take measurement
2101a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._run_func('download_eth',
2111a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                       self._download_test_data ,
212d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                       repeat=self._repeats,
213d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                       save_checkpoint=not(self.short))
2141a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2151a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2161a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_webpages(self):
2171a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Runs a series of web pages as sub-tests."""
218974858853d9218b023a79abc928b7f1c220bc293Mark Koudritsky        data_url = self._url_base + self._static_sub_dir + '/'
2191a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
22009e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # URLs to be only tested in foreground tab.
22109e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # Can't use about:blank here - crbug.com/248945
22209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # but chrome://version is just as good for our needs.
22309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        urls = [('ChromeVer', 'chrome://version/')]
2241a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # URLs to be tested in both, background and foreground modes.
225d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        bg_urls = []
226d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
227d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        more_urls = [('BallsDHTML',
228d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                      data_url + 'balls/DHTMLBalls/dhtml.htm'),
2298e073c073dc804b4395852d3da26287a1e5bd586Mark Koudritsky                     # Disabling FlexBalls as experiment http://crbug.com/309403
2308e073c073dc804b4395852d3da26287a1e5bd586Mark Koudritsky                     # ('BallsFlex',
2318e073c073dc804b4395852d3da26287a1e5bd586Mark Koudritsky                     #  data_url + 'balls/FlexBalls/flexballs.html'),
2328e073c073dc804b4395852d3da26287a1e5bd586Mark Koudritsky                    ]
233d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
234d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        if self.short:
235d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            urls += more_urls
236d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        else:
237d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            bg_urls += more_urls
238d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            bg_urls += [('Parapluesch',
239d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                         'http://www.parapluesch.de/whiskystore/test.htm'),
240d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                         ('PosterCircle',
241d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                          'http://www.webkit.org'
24209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky                          '/blog-files/3d-transforms/poster-circle.html'), ]
2431a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2441a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for name, url in urls + bg_urls:
2451a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._run_url(name, url, duration=self._duration_secs)
2461a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2471a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for name, url in bg_urls:
2481a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._run_url_bg('bg_' + name, url, duration=self._duration_secs)
2491a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2501a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2511a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_v8(self):
2521a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Run the V8 benchmark suite as a sub-test.
2531a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2541a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        Fire it up and wait until it displays "Score".
2551a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """
2561a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2571a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        url = 'http://v8.googlecode.com/svn/data/benchmarks/v7/run.html'
25809e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        js = "document.getElementById('status').textContent"
25909e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        tab = self._tab
2601a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2611a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        def v8_func():
26209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            """To be passed as the callable to self._run_func()"""
26309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            tab.Navigate(url)
26409e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            # V8 test will usually take 17-25 seconds. Need some sleep here
26509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            # to let the V8 page load and create the 'status' div.
26609e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            is_done = lambda: tab.EvaluateJavaScript(js).startswith('Score')
26709e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            time.sleep(self._stabilization_seconds)
2680f9f91b47342848b2e76e669f025a4c3bb8208e8Mark Koudritsky            utils.poll_for_condition(is_done, timeout=60, desc='V8 score found')
2691a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2701a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._run_func('V8', v8_func, repeat=self._repeats)
2711a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
27209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # Write v8 score from the last run to log
27309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        score = tab.EvaluateJavaScript(js)
2741a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        score = score.strip().split()[1]
27509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        logging.info('V8 Score: %s', score)
2761a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2771a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
2781a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_video(self):
2791a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Run video and audio playback in the browser."""
2801a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
281c763a829e0e6a704ebec14c734dd3cd67188517fMark Koudritsky        # Note: for perf keyvals, key names are defined as VARCHAR(30) in the
282c763a829e0e6a704ebec14c734dd3cd67188517fMark Koudritsky        # results DB. Chars above 30 are truncated when saved to DB.
28309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        urls = [('vid400p_h264', 'big_buck_bunny_trailer_400p.mp4'), ]
284d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        fullscreen_urls = []
285d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        bg_urls = []
286d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
287d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        if not self.short:
288d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            urls += [
289d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                ('vid400p_ogg', 'big_buck_bunny_trailer_400p.ogg'),
2907fa532908adfbbf602c7dc2c00d420162df50ed6Todd Broch                ('vid400p_vp8', 'big_buck_bunny_trailer_400p.vp8.webm'),
29113dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                ('vid400p_vp9', 'big_buck_bunny_trailer_400p.vp9.webm'),
292b6a1190bc58b63c4b849033d5132ba43477fe6a1Todd Broch                ('vid720_h264', 'big_buck_bunny_trailer_720p.mp4'),
293b6a1190bc58b63c4b849033d5132ba43477fe6a1Todd Broch                ('vid720_ogg', 'big_buck_bunny_trailer_720p.ogg'),
2947fa532908adfbbf602c7dc2c00d420162df50ed6Todd Broch                ('vid720_vp8', 'big_buck_bunny_trailer_720p.vp8.webm'),
29513dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                ('vid720_vp9', 'big_buck_bunny_trailer_720p.vp9.webm'),
296b6a1190bc58b63c4b849033d5132ba43477fe6a1Todd Broch                ('vid1080_h264', 'big_buck_bunny_trailer_1080p.mp4'),
29709e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky                ('vid1080_ogg', 'big_buck_bunny_trailer_1080p.ogg'),
2987fa532908adfbbf602c7dc2c00d420162df50ed6Todd Broch                ('vid1080_vp8', 'big_buck_bunny_trailer_1080p.vp8.webm'),
29913dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                ('vid1080_vp9', 'big_buck_bunny_trailer_1080p.vp9.webm'),
300d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                ('audio', 'Greensleeves.ogg'),
301d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                ]
302d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
303d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            fullscreen_urls += [
3044922ad63220f45f8c1864cc39e9786d0a3e9bd9aTodd Broch                ('vid720_h264_fs', 'big_buck_bunny_trailer_720p.mp4'),
3057fa532908adfbbf602c7dc2c00d420162df50ed6Todd Broch                ('vid720_vp8_fs', 'big_buck_bunny_trailer_720p.vp8.webm'),
30613dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                ('vid720_vp9_fs', 'big_buck_bunny_trailer_720p.vp9.webm'),
3074922ad63220f45f8c1864cc39e9786d0a3e9bd9aTodd Broch                ('vid1080_h264_fs', 'big_buck_bunny_trailer_1080p.mp4'),
3087fa532908adfbbf602c7dc2c00d420162df50ed6Todd Broch                ('vid1080_vp8_fs', 'big_buck_bunny_trailer_1080p.vp8.webm'),
30913dab7b6221df48832aa516ec8583cd680ba23c7Todd Broch                ('vid1080_vp9_fs', 'big_buck_bunny_trailer_1080p.vp9.webm'),
310d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                ]
311d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
312d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            bg_urls += [
3133f5571f2e2b6f41824396a23265f952af1868876Todd Broch                ('bg_vid400p', 'big_buck_bunny_trailer_400p.vp8.webm'),
314d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                ]
3151a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3161a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # The video files are run from a file:// url. In order to work properly
3171a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # from an http:// url, some careful web server configuration is needed
3181a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        def full_url(filename):
3190ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            """Create a file:// url for the media file and verify it exists.
3200ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch
3210ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            @param filename: string
3220ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            """
3231a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            p = os.path.join(self._media_dir, filename)
3241a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            if not os.path.isfile(p):
3251a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                raise error.TestError('Media file %s is missing.', p)
3261a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            return 'file://' + p
3271a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3281a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        js_loop_enable = """ve = document.getElementsByTagName('video')[0];
3291a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                         ve.loop = true;
3301a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                         ve.play();
3311a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                         """
3321a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3331a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for name, url in urls:
33409e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            logging.info('Playing video %s', url)
33509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.Navigate(full_url(url))
33609e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.ExecuteJavaScript(js_loop_enable)
3371a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._run_sleep(name, self._duration_secs)
3381a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3391a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for name, url in fullscreen_urls:
34009e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._toggle_fullscreen()
34109e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.Navigate(full_url(url))
34209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.ExecuteJavaScript(js_loop_enable)
3431a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._run_sleep(name, self._duration_secs)
34409e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._toggle_fullscreen()
3451a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3461a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for name, url in bg_urls:
34709e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            logging.info('Playing video in background tab %s', url)
34809e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.Navigate(full_url(url))
34909e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.ExecuteJavaScript(js_loop_enable)
3500ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            fg_tab = self._browser.tabs.New()
3511a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._run_sleep(name, self._duration_secs)
35209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            fg_tab.Close()
35309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.Activate()
3541a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3551a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3561a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_sound(self):
3571a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Run non-UI sound test using 'speaker-test'."""
35809e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # For some reason speaker-test won't work on CrOS without a reasonable
35909e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # buffer size specified with -b.
36009e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # http://crbug.com/248955
36109e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        cmd = 'speaker-test -l %s -t sine -c 2 -b 16384' % (self._repeats * 6)
362c763a829e0e6a704ebec14c734dd3cd67188517fMark Koudritsky        self._run_cmd('speaker_test', cmd)
3631a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3641a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3651a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_lowlevel(self):
3661a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Low level system stuff"""
3671a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        mb = min(1024, 32 * self._repeats)
3681a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._run_cmd('memtester', '/usr/local/sbin/memtester %s 1' % mb)
3691a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3701a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # one rep of dd takes about 15 seconds
371540af155fcd1016257478c22de8828b449d18085Puthikorn Voravootivat        root_dev = site_utils.get_root_partition()
3721a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        cmd = 'dd if=%s of=/dev/null' % root_dev
37309e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        self._run_cmd('dd', cmd, repeat=2 * self._repeats)
3741a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3751a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3761a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_backchannel(self):
3771a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """WiFi sub-tests."""
3781a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3791a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        wifi_ap = 'GoogleGuest'
3808f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch        wifi_sec = 'none'
3811a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        wifi_pw = ''
3821a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3831a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        flim = flimflam.FlimFlam()
3841a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        conn = flim.ConnectService(retries=3,
3851a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                              retry=True,
3861a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                              service_type='wifi',
3871a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                              ssid=wifi_ap,
3881a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                              security=wifi_sec,
3891a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                              passphrase=wifi_pw,
3901a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                              mode='managed')
3911a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        if not conn[0]:
3921a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            logging.error("Could not connect to WiFi")
3931a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            return
3941a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
3951a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        logging.info('Starting Backchannel')
3961a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        with backchannel.Backchannel():
3971a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            # Wifi needs some time to recover after backchanel is activated
3981a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            # TODO (kamrik) remove this sleep, once backchannel handles this
3991a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            time.sleep(15)
4001a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4011a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            cmd = 'ping -c %s www.google.com' % (self._duration_secs)
4021a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._run_cmd('ping_wifi', cmd)
4031a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4041a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            # This URL must be visible from WiFi network used for test
4051a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            big_file_url = ('http://googleappengine.googlecode.com'
4061a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                            '/files/GoogleAppEngine-1.6.2.msi')
4071a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            cmd = 'curl %s > /dev/null' % big_file_url
4081a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._run_cmd('download_wifi', cmd, repeat=self._repeats)
4091a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4101a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4111a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_group_backlight(self):
4121a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """Vary backlight brightness and record power at each setting."""
4138f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch        for i in [100, 50, 0]:
4148f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch            self._backlight.set_percent(i)
4151a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            start_time = time.time() + self._stabilization_seconds
4161a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            time.sleep(30 * self._repeats)
41731535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch            self._plog.checkpoint('backlight_%03d' % i, start_time)
4188f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch        self._backlight.set_default()
4191a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4201a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4211a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _web_echo(self, msg):
4221a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """ Displays a message in the browser."""
4231a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        url = self._url_base + 'echo.html?'
4241a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        url += urllib.quote(msg)
42509e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        self._tab.Navigate(url)
4261a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4271a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4281a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def _run_test_groups(self, groups):
4291a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """ Run all the test groups.
4301a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4311a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        Args:
4321a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            groups: list of sub-test groups to run. Each sub-test group refers
4331a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky                to a _run_group_...() function.
4341a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        """
4351a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4361a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        for group in groups:
4371a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            logging.info('Running group %s', group)
4381a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            # The _web_echo here is important for some tests (esp. non UI)
4391a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            # it gets the previous web page replaced with an almost empty one.
44009e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            self._tab.Activate()
4411a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            self._web_echo('Running test %s' % group)
4421a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            test_func = getattr(self, '_run_group_%s' % group)
4431a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky            test_func()
4441a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4451a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
446d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky    def run_once(self, short=False, test_groups=None, reps=1):
4471a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # Some sub-tests have duration specified directly, _base_secs * reps
4481a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # is used in this case. Others complete whenever the underlying task
4491a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # completes, those are manually tuned to be roughly around
4501a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # reps * 30 seconds. Don't change _base_secs unless you also
4511a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # change the manual tuning in sub-tests
4521a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._base_secs = 30
45331535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        self._repeats = reps
4541a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self._duration_secs = self._base_secs * reps
4551a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
456d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        # Lists of default tests to run
457d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        UI_TESTS = ['backlight', 'download', 'webpages', 'video', 'v8']
458d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        NONUI_TESTS = ['backchannel', 'sound', 'lowlevel']
459d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        DEFAULT_TESTS = UI_TESTS + NONUI_TESTS
460d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        DEFAULT_SHORT_TESTS = ['download', 'webpages', 'video']
461d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
462d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        self.short = short
463d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        if test_groups is None:
464d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            if self.short:
465d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                test_groups = DEFAULT_SHORT_TESTS
466d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            else:
467d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky                test_groups = DEFAULT_TESTS
46809e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        logging.info('Test groups to run: %s', ', '.join(test_groups))
4691a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
470af5de98643110a67a9f5c323dd56be3eb1e35448Todd Broch        self._backlight = power_utils.Backlight()
4718f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch        self._backlight.set_default()
4720e53e639598c2e660a18d183370e1bfaa9dd0c07Todd Broch
4736047f146ba2dedf560c91cdfdce2a93cc7479382Todd Broch        measurements = \
474d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            [power_status.SystemPower(self._power_status.battery_path)]
4750e53e639598c2e660a18d183370e1bfaa9dd0c07Todd Broch        if power_utils.has_rapl_support():
4760e53e639598c2e660a18d183370e1bfaa9dd0c07Todd Broch            measurements += power_rapl.create_rapl()
47731535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        self._plog = power_status.PowerLogger(measurements)
47831535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        self._plog.start()
4791a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4800ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch        # Log in.
4810ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch        with chrome.Chrome() as cr:
4820ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            self._browser = cr.browser
4830ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            graphics_utils.screen_disable_energy_saving()
4840ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            # Most of the tests will be running in this tab.
4850ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            self._tab = cr.browser.tabs[0]
4860ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch
4870ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            # Verify that we have a functioning browser and local web server.
4880ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            self._tab.Activate()
4890ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            self._web_echo("Sanity_test")
4900ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            self._tab.WaitForDocumentReadyStateToBeComplete()
4911a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4920ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            # Video test must have the data from download test
4930ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            if ('video' in test_groups):
4940ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch                iv = test_groups.index('video')
4950ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch                if 'download' not in test_groups[:iv]:
4960ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch                    msg = '"download" test must run before "video".'
4970ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch                    raise error.TestError(msg)
4981a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
4990ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            # Run all the test groups
5000ac98a72887d9eba096caf2f24dffe68190374b2Todd Broch            self._run_test_groups(test_groups)
5011a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
5021a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # Wrap up
50331535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        keyvals = self._plog.calc()
5049d5a0ace586069861df87d35daf5f92eb9b77230Todd Broch        keyvals.update(self._tmp_keyvals)
5052ace7ae10114702d7b1be3d04e886da4182c0507Ravi Chandra Sadineni        keyvals.update(self._statomatic.publish())
506d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
50709e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        # Calculate expected battery life time with ChromeVer power draw
50809e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky        idle_name = 'ChromeVer_system_pwr'
509d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        if idle_name in keyvals:
510d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            hours_life = self.energy_full_design / keyvals[idle_name]
51109e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky            keyvals['hours_battery_ChromeVer'] = hours_life
512d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
513d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        # Calculate a weighted power draw and battery life time. The weights
514d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        # are intended to represent "typical" usage. Some video, some Flash ...
515d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        # and most of the time idle.
516d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        # see http://www.chromium.org/chromium-os/testing/power-testing
517d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        weights = {'vid400p_h264_system_pwr':0.1,
518222e0c008bdca66013531ee70f9eabd178228289Mark Koudritsky                   # TODO(chromium:309403) re-enable BallsFlex once Flash in
519222e0c008bdca66013531ee70f9eabd178228289Mark Koudritsky                   # test-lab understood and re-distribute back to 60/20/10/10.
520222e0c008bdca66013531ee70f9eabd178228289Mark Koudritsky                   # 'BallsFlex_system_pwr':0.1,
521222e0c008bdca66013531ee70f9eabd178228289Mark Koudritsky                   'BallsDHTML_system_pwr':0.3,
52209e78027653cc05218fa5bb5c4b8c71bf34bd1e4Mark Koudritsky                   }
523d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        weights[idle_name] = 1 - sum(weights.values())
524d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
525d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky        if set(weights).issubset(set(keyvals)):
5268f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch            p = sum(w * keyvals[k] for (k, w) in weights.items())
527d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            keyvals['w_Weighted_system_pwr'] = p
528d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky            keyvals['hours_battery_Weighted'] = self.energy_full_design / p
529d1e81b526b9ced543a73bb3abb1e87ae45b3eb57Mark Koudritsky
5301a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        self.write_perf_keyval(keyvals)
53131535be1477e9d098c2973e76aac2c4a8cc4864bTodd Broch        self._plog.save_results(self.resultsdir)
5321a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
5331a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
5341a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky    def cleanup(self):
5351a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        # cleanup() is run by common_lib/test.py
5364996a4edaa0d60da54c81c966af9e127cbceac94Todd Broch        try:
5374996a4edaa0d60da54c81c966af9e127cbceac94Todd Broch            self._test_server.stop()
5384996a4edaa0d60da54c81c966af9e127cbceac94Todd Broch        except AttributeError:
5394996a4edaa0d60da54c81c966af9e127cbceac94Todd Broch            logging.debug('test_server could not be stopped in cleanup')
5401a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
5418f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch        if self._backlight:
542af5de98643110a67a9f5c323dd56be3eb1e35448Todd Broch            self._backlight.restore()
5438f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch        if self._services:
5448f9bf6086f5b9f2ecd86f8a6e7a0ff045bebeb72Todd Broch            self._services.restore_services()
5451a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky
5461a739e719992caed23fdf9c35957417d21c80541Mark Koudritsky        super(power_Consumption, self).cleanup()
547