blob: b5f7ad19e24bb246ae7532466c0947206a795220 [file] [log] [blame]
# 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 = 0.1
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():
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'):
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]
})