blob: 55b84fbf88f7fec6b72c140c230329801a4a313b [file] [log] [blame]
# Copyright 2021 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
import time
import os
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros.audio import alsa_utils
from autotest_lib.client.cros.audio import cras_utils
from autotest_lib.client.cros.graphics import graphics_utils
from autotest_lib.client.cros.power import power_test
from autotest_lib.client.cros.video import helper_logger
URL = "https://www.youtube.com/watch?v=zqLEO5tIuYs"
class video_YouTubePlaybackStress(power_test.power_Test):
version = 1
PLAYING_STATE = 'playing'
# Time in seconds to sample for frame drops
_SAMPLE_TIME = 10
DROPPED_FRAMES_PERCENT_THRESHOLD = 10
def cleanup(self):
if not self.success:
graphics_utils.take_screenshot(os.path.join(self.debugdir),
'chrome')
if self.cr:
self.cr.close()
super(video_YouTubePlaybackStress, self).cleanup()
def initialize_test(self, player_page):
"""Initializes the test.
@param player_page: The URL (string) of the YouTube player page to test.
"""
self.tab = self.cr.browser.tabs[0]
self.tab.Navigate(player_page)
self.tab.WaitForDocumentReadyStateToBeComplete()
utils.poll_for_condition(
condition=self.player_is_ready,
exception=error.TestError('Failed to load the Youtube player'))
with open(
os.path.join(os.path.dirname(__file__),
'files/video_YouTubePageCommon.js')) as f:
js = f.read()
if not self.tab.EvaluateJavaScript(js):
raise error.TestError('YouTube page failed to load.')
logging.info('Loaded accompanying .js script.')
def player_is_ready(self):
"""Simple wrapper to check if the player is ready
@returns: Returns whether the player is ready."""
return self.tab.EvaluateJavaScript('typeof player != "undefined"')
def get_player_state(self):
"""Simple wrapper to get the JS player state.
@returns: The state of the player (string).
"""
return self.tab.EvaluateJavaScript('window.__getVideoState();')
def get_current_time(self):
"""
Simple wrapper to get the JS player current time
@returns: Returns current time.
"""
return self.tab.EvaluateJavaScript('window.__getCurrentTime();')
def get_frames_statistics(self):
"""Simple wrapper to get a dictionary of raw video frame states
@returns: Dict of droppedFrameCount (int), decodedFrameCount (int), and
droppedFramesPercentage (float).
"""
return self.tab.EvaluateJavaScript('window.__getFramesStatistics();')
def get_dropped_frames_percentage(self):
"""Simple wrapper to get the percentage of dropped frames.
@returns: Drop frame percentage (float).
"""
return self.get_frames_statistics()['droppedFramesPercentage']
def perform_frame_drop_test(self):
"""Test to check if there are too many dropped frames.
"""
utils.poll_for_condition(
condition=lambda: self.get_player_state() == self.PLAYING_STATE,
exception=error.TestError('Current player state is %s. Expected '
'player state is %s' % (
self.get_player_state(),
self.PLAYING_STATE)))
old_time = self.get_current_time()
utils.poll_for_condition(
condition=lambda: self.get_current_time() > old_time,
exception=error.TestError('Video is not played until timeout'))
dropped_frames_percentage = self.get_dropped_frames_percentage()
if dropped_frames_percentage > self.DROPPED_FRAMES_PERCENT_THRESHOLD:
raise error.TestError(
'perform_frame_drop_test failed due to too many dropped '
'frames (%f%%)' % (dropped_frames_percentage))
@helper_logger.video_log_wrapper
def run_once(self, test_duration=10,
output_node="INTERNAL_SPEAKER"):
self.cr = chrome.Chrome(
extra_browser_args=helper_logger.chrome_vmodule_flag())
self.initialize_test(URL)
device_name = cras_utils.get_selected_output_device_name()
device_type = cras_utils.get_selected_output_device_type()
self.start_measurements()
start_time = time.time()
logging.info("Playing and verifying youtube audio")
while (time.time() - start_time) <= test_duration:
logging.info("Peform framedrop test")
self.perform_frame_drop_test()
alsa_utils.check_audio_stream_at_selected_device(device_name,
device_type)
time.sleep(self._SAMPLE_TIME)