blob: 5893b8ecf800e374fbbe724f12bc10efcf578f0b [file] [log] [blame]
# Copyright 2014 The Chromium 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 os
import unittest
from telemetry import test
from telemetry.core import wpr_modes
from telemetry.timeline import model as model_module
from telemetry.timeline import async_slice
from telemetry.page import page_measurement_unittest_base
from telemetry.page import page_set
from telemetry.page import page as page_module
# pylint: disable=W0401,W0614
from telemetry.page.actions.all_page_actions import *
from telemetry.results import page_measurement_results
from telemetry.unittest import options_for_unittests
from telemetry.web_perf import timeline_based_measurement as tbm_module
from telemetry.web_perf.metrics import timeline_based_metric
class TimelineBasedMetricsTests(unittest.TestCase):
def setUp(self):
model = model_module.TimelineModel()
renderer_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
renderer_thread.name = 'CrRendererMain'
# [ X ]
# [ Y ]
renderer_thread.BeginSlice('cat1', 'x.y', 10, 0)
renderer_thread.EndSlice(20, 20)
renderer_thread.async_slices.append(async_slice.AsyncSlice(
'cat', 'Interaction.LogicalName1/is_smooth',
timestamp=0, duration=20,
start_thread=renderer_thread, end_thread=renderer_thread,
thread_start=5, thread_duration=15))
renderer_thread.async_slices.append(async_slice.AsyncSlice(
'cat', 'Interaction.LogicalName2/is_responsive',
timestamp=25, duration=5,
start_thread=renderer_thread, end_thread=renderer_thread,
thread_start=25, thread_duration=5))
model.FinalizeImport()
self.model = model
self.renderer_thread = renderer_thread
def testFindTimelineInteractionRecords(self):
metric = tbm_module._TimelineBasedMetrics( # pylint: disable=W0212
self.model, self.renderer_thread, lambda _: [])
interactions = metric.FindTimelineInteractionRecords()
self.assertEquals(2, len(interactions))
self.assertTrue(interactions[0].is_smooth)
self.assertEquals(0, interactions[0].start)
self.assertEquals(20, interactions[0].end)
self.assertTrue(interactions[1].is_responsive)
self.assertEquals(25, interactions[1].start)
self.assertEquals(30, interactions[1].end)
def testAddResults(self):
results = page_measurement_results.PageMeasurementResults()
class FakeSmoothMetric(timeline_based_metric.TimelineBasedMetric):
def AddResults(self, model, renderer_thread,
interaction_records, results):
results.Add('FakeSmoothMetric', 'ms', 1)
class FakeLoadingMetric(timeline_based_metric.TimelineBasedMetric):
def AddResults(self, model, renderer_thread,
interaction_records, results):
for r in interaction_records:
assert r.logical_name == 'LogicalName2'
results.Add('FakeLoadingMetric', 'ms', 2)
def CreateMetricsForTimelineInteractionRecord(interaction):
res = []
if interaction.is_smooth:
res.append(FakeSmoothMetric())
if interaction.is_responsive:
res.append(FakeLoadingMetric())
return res
metric = tbm_module._TimelineBasedMetrics( # pylint: disable=W0212
self.model, self.renderer_thread,
CreateMetricsForTimelineInteractionRecord)
ps = page_set.PageSet(file_path=os.path.dirname(__file__))
ps.AddPageWithDefaultRunNavigate('http://www.bar.com/')
results.WillMeasurePage(ps.pages[0])
metric.AddResults(results)
results.DidMeasurePage()
v = results.FindAllPageSpecificValuesNamed('LogicalName1-FakeSmoothMetric')
self.assertEquals(len(v), 1)
v = results.FindAllPageSpecificValuesNamed('LogicalName2-FakeLoadingMetric')
self.assertEquals(len(v), 1)
class TestTimelinebasedMeasurementPage(page_module.Page):
def __init__(self, ps, base_dir):
super(TestTimelinebasedMeasurementPage, self).__init__(
'file://interaction_enabled_page.html', ps, base_dir)
def RunSmoothness(self, action_runner):
action_runner.Wait(2)
action_runner.TapElement('#drawer')
action_runner.Wait(1)
class TimelineBasedMeasurementTest(
page_measurement_unittest_base.PageMeasurementUnitTestBase):
def setUp(self):
self._options = options_for_unittests.GetCopy()
self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
# Disabled due to flakiness: crbug.com/368386
@test.Disabled
def testSmoothnessTimelineBasedMeasurementForSmoke(self):
ps = self.CreatePageSetFromFileInUnittestDataDir(
'interaction_enabled_page.html')
setattr(ps.pages[0], 'RunSmoothness', {
'action': 'wait', 'javascript': 'window.animationDone'})
measurement = tbm_module.TimelineBasedMeasurement()
results = self.RunMeasurement(measurement, ps,
options=self._options)
self.assertEquals(0, len(results.failures))
v = results.FindAllPageSpecificValuesNamed('CenterAnimation-jank')
self.assertEquals(len(v), 1)
v = results.FindAllPageSpecificValuesNamed('DrawerAnimation-jank')
self.assertEquals(len(v), 1)
# Disabled since mainthread_jank metric is not supported on windows platform.
@test.Disabled('win')
def testMainthreadJankTimelineBasedMeasurement(self):
ps = self.CreateEmptyPageSet()
ps.AddPage(TestTimelinebasedMeasurementPage(ps, ps.base_dir))
measurement = tbm_module.TimelineBasedMeasurement()
results = self.RunMeasurement(measurement, ps,
options=self._options)
self.assertEquals(0, len(results.failures))
# In interaction_enabled_page.html, we create a jank loop based on
# window.performance.now() (basically loop for x milliseconds).
# Since window.performance.now() uses wall-time
# instead of thread time, we set time to looping to 100ms in
# interaction_enabled_page.html and only assert the biggest jank > 50ms here
# to account for the fact that the browser may deschedule during the jank
# loop.
v = results.FindAllPageSpecificValuesNamed(
'JankThreadJSRun-responsive-biggest_jank_thread_time')
self.assertGreaterEqual(v[0].value, 50)
v = results.FindAllPageSpecificValuesNamed(
'JankThreadJSRun-responsive-total_big_jank_thread_time')
self.assertGreaterEqual(v[0].value, 50)