154 lines
6.3 KiB
Python
154 lines
6.3 KiB
Python
# Copyright 2018 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import logging, time
|
|
|
|
from autotest_lib.client.bin import utils
|
|
from autotest_lib.client.common_lib.cros import chrome
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.client.cros import service_stopper
|
|
from autotest_lib.client.cros.graphics import graphics_utils
|
|
from autotest_lib.client.cros.power import power_rapl
|
|
from autotest_lib.client.cros.power import power_status
|
|
from autotest_lib.client.cros.power import power_utils
|
|
|
|
TEST_NAME_AND_FLAGS = [
|
|
['hw_overlays_hw_decode', ['']],
|
|
['no_overlays_hw_decode', ['--enable-hardware-overlays=']],
|
|
['hw_overlays_sw_decode', ['--disable-accelerated-video-decode']],
|
|
[
|
|
'no_overlays_sw_decode',
|
|
['--disable-accelerated-video-decode', '--enable-hardware-overlays=']
|
|
]
|
|
]
|
|
# Amount of time to wait for the URL to load and the video to start playing.
|
|
PREAMBLE_DURATION_SECONDS = 8
|
|
# Amount of time to let the video play while measuring power consumption.
|
|
MEASUREMENT_DURATION_SECONDS = 12
|
|
|
|
# Time in seconds to wait for cpu idle until giveup.
|
|
IDLE_CPU_WAIT_TIMEOUT_SECONDS = 60.0
|
|
# Maximum percent of cpu usage considered as idle.
|
|
IDLE_CPU_LOAD_PERCENTAGE = 2.5
|
|
|
|
GRAPH_NAME = 'power_consumption'
|
|
|
|
|
|
class graphics_VideoRenderingPower(graphics_utils.GraphicsTest):
|
|
"""This test renders on screen for a short while a video from a given
|
|
|
|
(controlled) URL while measuring the power consumption of the different SoC
|
|
domains.
|
|
"""
|
|
version = 1
|
|
_backlight = None
|
|
_service_stopper = None
|
|
_power_status = None
|
|
|
|
def initialize(self):
|
|
super(graphics_VideoRenderingPower, self).initialize()
|
|
|
|
self._backlight = power_utils.Backlight()
|
|
self._backlight.set_default()
|
|
|
|
self._service_stopper = service_stopper.ServiceStopper(
|
|
service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
|
|
self._service_stopper.stop_services()
|
|
|
|
self._power_status = power_status.get_status()
|
|
|
|
def cleanup(self):
|
|
if self._backlight:
|
|
self._backlight.restore()
|
|
if self._service_stopper:
|
|
self._service_stopper.restore_services()
|
|
super(graphics_VideoRenderingPower, self).cleanup()
|
|
|
|
@graphics_utils.GraphicsTest.failure_report_decorator(
|
|
'graphics_VideoRenderingPower')
|
|
def run_once(self, video_url, video_short_name):
|
|
"""Runs the graphics_VideoRenderingPower test.
|
|
|
|
@param video_url: URL with autoplay video inside. It's assumed that
|
|
there's just one <video> in the HTML, and that it fits in the
|
|
viewport.
|
|
@param video_short_name: short string describing the video; itt will be
|
|
presented as part of the dashboard entry name.
|
|
"""
|
|
|
|
# TODO(mcasas): Extend this test to non-Intel platforms.
|
|
if not power_utils.has_rapl_support():
|
|
logging.warning('This board has no RAPL power measurement support, '
|
|
'skipping test.')
|
|
return
|
|
|
|
rapl = []
|
|
if power_utils.has_battery():
|
|
# Sometimes, the DUT is supposed to have a battery but we may not
|
|
# detect one. This is a symptom of a bad battery (b/145144707).
|
|
if self._power_status.battery_path is None:
|
|
raise error.TestFail('No battery found in this DUT (this is a '
|
|
'symptom of a bad battery).')
|
|
rapl.append(
|
|
power_status.SystemPower(self._power_status.battery_path))
|
|
else:
|
|
logging.warning('This board has no battery.')
|
|
rapl += power_rapl.create_rapl()
|
|
|
|
for test_name_and_flags in TEST_NAME_AND_FLAGS:
|
|
logging.info('Test case: %s', test_name_and_flags[0])
|
|
# Launch Chrome with the appropriate flag combination.
|
|
with chrome.Chrome(
|
|
extra_browser_args=test_name_and_flags[1],
|
|
init_network_controller=True) as cr:
|
|
|
|
if not utils.wait_for_idle_cpu(IDLE_CPU_WAIT_TIMEOUT_SECONDS,
|
|
IDLE_CPU_LOAD_PERCENTAGE):
|
|
raise error.TestFail('Failed: Could not get idle CPU.')
|
|
if not utils.wait_for_cool_machine():
|
|
raise error.TestFail('Failed: Could not get cold machine.')
|
|
|
|
tab = cr.browser.tabs[0]
|
|
tab.Navigate(video_url)
|
|
tab.WaitForDocumentReadyStateToBeComplete()
|
|
tab.EvaluateJavaScript(
|
|
'document.'
|
|
'getElementsByTagName(\'video\')[0].scrollIntoView(true)')
|
|
|
|
# Disabling hardware overlays is difficult because the flag is
|
|
# already in the browser. Instead, scroll a bit down to make the
|
|
# video bleed out of the viewport.
|
|
if '--enable-hardware-overlays=' in test_name_and_flags[1]:
|
|
tab.EvaluateJavaScript('window.scrollBy(0, 1)')
|
|
|
|
power_logger = power_status.PowerLogger(rapl)
|
|
power_logger.start()
|
|
time.sleep(PREAMBLE_DURATION_SECONDS)
|
|
|
|
start_time = time.time()
|
|
time.sleep(MEASUREMENT_DURATION_SECONDS)
|
|
power_logger.checkpoint('result', start_time)
|
|
|
|
measurements = power_logger.calc()
|
|
logging.debug(measurements)
|
|
|
|
for category in sorted(measurements):
|
|
if category.endswith('_pwr_avg'):
|
|
description = '%s_%s_%s' % (
|
|
video_short_name, test_name_and_flags[0], category)
|
|
self.output_perf_value(
|
|
description=description,
|
|
value=measurements[category],
|
|
units='W',
|
|
higher_is_better=False,
|
|
graph=GRAPH_NAME)
|
|
|
|
if category.endswith('_pwr_avg'):
|
|
# write_perf_keyval() wants units (W) first in lowercase.
|
|
description = '%s_%s_%s' % (
|
|
video_short_name, test_name_and_flags[0], category)
|
|
self.write_perf_keyval({
|
|
'w_' + description: measurements[category]
|
|
})
|