Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / web_perf / timeline_based_measurement_unittest.py
index 5893b8e..069c2f5 100644 (file)
 import os
 import unittest
 
-from telemetry import test
+from telemetry import benchmark
 from telemetry.core import wpr_modes
+from telemetry.page import page as page_module
+from telemetry.page import page_set
+from telemetry.results import page_test_results
 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.unittest import page_test_test_case
+from telemetry.value import scalar
 from telemetry.web_perf import timeline_based_measurement as tbm_module
+from telemetry.web_perf import timeline_interaction_record as tir_module
 from telemetry.web_perf.metrics import timeline_based_metric
 
 
-class TimelineBasedMetricsTests(unittest.TestCase):
+class FakeFastMetric(timeline_based_metric.TimelineBasedMetric):
 
-  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 AddResults(self, model, renderer_thread, interaction_records, results):
+    results.AddValue(scalar.ScalarValue(
+        results.current_page, 'FakeFastMetric', 'ms', 1))
+    results.AddValue(scalar.ScalarValue(
+        results.current_page, 'FastMetricRecords', 'count',
+        len(interaction_records)))
 
-  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)
+class FakeSmoothMetric(timeline_based_metric.TimelineBasedMetric):
 
-  def testAddResults(self):
-    results = page_measurement_results.PageMeasurementResults()
+  def AddResults(self, model, renderer_thread, interaction_records, results):
+    results.AddValue(scalar.ScalarValue(
+        results.current_page, 'FakeSmoothMetric', 'ms', 1))
+    results.AddValue(scalar.ScalarValue(
+        results.current_page, 'SmoothMetricRecords', 'count',
+        len(interaction_records)))
 
-    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):
 
-    class FakeLoadingMetric(timeline_based_metric.TimelineBasedMetric):
+  def AddResults(self, model, renderer_thread, interaction_records, results):
+    results.AddValue(scalar.ScalarValue(
+        results.current_page, 'FakeLoadingMetric', 'ms', 2))
+    results.AddValue(scalar.ScalarValue(
+        results.current_page, 'LoadingMetricRecords', 'count',
+        len(interaction_records)))
 
-      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
+def GetMetricFromMetricType(metric_type):
+  if metric_type == tir_module.IS_FAST:
+    return FakeFastMetric()
+  if metric_type == tir_module.IS_SMOOTH:
+    return FakeSmoothMetric()
+  if metric_type == tir_module.IS_RESPONSIVE:
+    return FakeLoadingMetric()
+  raise Exception('Unrecognized metric type: %s' % metric_type)
 
-    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()
+class TimelineBasedMetricTestData(object):
 
-    v = results.FindAllPageSpecificValuesNamed('LogicalName1-FakeSmoothMetric')
-    self.assertEquals(len(v), 1)
-    v = results.FindAllPageSpecificValuesNamed('LogicalName2-FakeLoadingMetric')
-    self.assertEquals(len(v), 1)
+  def __init__(self):
+    self._model = model_module.TimelineModel()
+    renderer_process = self._model.GetOrCreateProcess(1)
+    self._renderer_thread = renderer_process.GetOrCreateThread(2)
+    self._renderer_thread.name = 'CrRendererMain'
+    self._results = page_test_results.PageTestResults()
+    self._metric = None
+    self._ps = None
+
+  @property
+  def results(self):
+    return self._results
+
+  @property
+  def metric(self):
+    return self._metric
+
+  def AddInteraction(self, marker='', ts=0, duration=5):
+    self._renderer_thread.async_slices.append(async_slice.AsyncSlice(
+        'category', marker, timestamp=ts, duration=duration,
+        start_thread=self._renderer_thread, end_thread=self._renderer_thread,
+        thread_start=ts, thread_duration=duration))
+
+  def FinalizeImport(self):
+    self._model.FinalizeImport()
+    self._metric = tbm_module._TimelineBasedMetrics(  # pylint: disable=W0212
+        self._model, self._renderer_thread, GetMetricFromMetricType)
+    self._ps = page_set.PageSet(file_path=os.path.dirname(__file__))
+    self._ps.AddPageWithDefaultRunNavigate('http://www.bar.com/')
+    self._results.WillRunPage(self._ps.pages[0])
+
+  def AddResults(self):
+    self._metric.AddResults(self._results)
+    self._results.DidRunPage(self._ps.pages[0])
+
+
+class TimelineBasedMetricsTests(unittest.TestCase):
+
+  def testFindTimelineInteractionRecords(self):
+    d = TimelineBasedMetricTestData()
+    d.AddInteraction(ts=0, duration=20,
+                     marker='Interaction.LogicalName1/is_smooth')
+    d.AddInteraction(ts=25, duration=5,
+                     marker='Interaction.LogicalName2/is_responsive')
+    d.AddInteraction(ts=50, duration=15,
+                     marker='Interaction.LogicalName3/is_fast')
+    d.FinalizeImport()
+    interactions = d.metric.FindTimelineInteractionRecords()
+    self.assertEquals(3, 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)
+
+    self.assertTrue(interactions[2].is_fast)
+    self.assertEquals(50, interactions[2].start)
+    self.assertEquals(65, interactions[2].end)
+
+  def testAddResults(self):
+    d = TimelineBasedMetricTestData()
+    d.AddInteraction(ts=0, duration=20,
+                     marker='Interaction.LogicalName1/is_smooth')
+    d.AddInteraction(ts=25, duration=5,
+                     marker='Interaction.LogicalName2/is_responsive')
+    d.AddInteraction(ts=50, duration=15,
+                     marker='Interaction.LogicalName3/is_fast')
+    d.FinalizeImport()
+    d.AddResults()
+    self.assertEquals(1, len(d.results.FindAllPageSpecificValuesNamed(
+        'LogicalName1-FakeSmoothMetric')))
+    self.assertEquals(1, len(d.results.FindAllPageSpecificValuesNamed(
+        'LogicalName2-FakeLoadingMetric')))
+    self.assertEquals(1, len(d.results.FindAllPageSpecificValuesNamed(
+        'LogicalName3-FakeFastMetric')))
+
+  def testNoInteractions(self):
+    d = TimelineBasedMetricTestData()
+    d.FinalizeImport()
+    self.assertRaises(tbm_module.InvalidInteractions, d.AddResults)
+
+  def testDuplicateUnrepeatableInteractions(self):
+    d = TimelineBasedMetricTestData()
+    d.AddInteraction(ts=10, duration=5,
+                     marker='Interaction.LogicalName/is_smooth')
+    d.AddInteraction(ts=20, duration=5,
+                     marker='Interaction.LogicalName/is_smooth')
+    d.FinalizeImport()
+    self.assertRaises(tbm_module.InvalidInteractions, d.AddResults)
+
+  def testDuplicateRepeatableInteractions(self):
+    d = TimelineBasedMetricTestData()
+    d.AddInteraction(ts=10, duration=5,
+                     marker='Interaction.LogicalName/is_smooth,repeatable')
+    d.AddInteraction(ts=20, duration=5,
+                     marker='Interaction.LogicalName/is_smooth,repeatable')
+    d.FinalizeImport()
+    d.AddResults()
+    self.assertEquals(1, len(d.results.pages_that_succeeded))
+
+  def testDuplicateRepeatableInteractionsWithDifferentMetrics(self):
+    d = TimelineBasedMetricTestData()
+
+    responsive_marker = 'Interaction.LogicalName/is_responsive,repeatable'
+    d.AddInteraction(ts=10, duration=5, marker=responsive_marker)
+    smooth_marker = 'Interaction.LogicalName/is_smooth,repeatable'
+    d.AddInteraction(ts=20, duration=5, marker=smooth_marker)
+    d.FinalizeImport()
+    self.assertRaises(tbm_module.InvalidInteractions, d.AddResults)
 
 
 class TestTimelinebasedMeasurementPage(page_module.Page):
 
-  def __init__(self, ps, base_dir):
+  def __init__(self, ps, base_dir, trigger_animation=False,
+               trigger_jank=False):
     super(TestTimelinebasedMeasurementPage, self).__init__(
         'file://interaction_enabled_page.html', ps, base_dir)
+    self._trigger_animation = trigger_animation
+    self._trigger_jank = trigger_jank
 
   def RunSmoothness(self, action_runner):
-    action_runner.Wait(2)
-    action_runner.TapElement('#drawer')
-    action_runner.Wait(1)
+    if self._trigger_animation:
+      action_runner.TapElement('#animating-button')
+      action_runner.WaitForJavaScriptCondition('window.animationDone')
+    if self._trigger_jank:
+      action_runner.TapElement('#jank-button')
+      action_runner.WaitForJavaScriptCondition('window.jankScriptDone')
 
 
-class TimelineBasedMeasurementTest(
-    page_measurement_unittest_base.PageMeasurementUnitTestBase):
+class TimelineBasedMeasurementTest(page_test_test_case.PageTestTestCase):
 
   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'})
+    ps = self.CreateEmptyPageSet()
+    ps.AddPage(TestTimelinebasedMeasurementPage(
+        ps, ps.base_dir, trigger_animation=True))
+
     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)
@@ -137,10 +215,11 @@ class TimelineBasedMeasurementTest(
     self.assertEquals(len(v), 1)
 
   # Disabled since mainthread_jank metric is not supported on windows platform.
-  @test.Disabled('win')
+  @benchmark.Disabled('win')
   def testMainthreadJankTimelineBasedMeasurement(self):
     ps = self.CreateEmptyPageSet()
-    ps.AddPage(TestTimelinebasedMeasurementPage(ps, ps.base_dir))
+    ps.AddPage(TestTimelinebasedMeasurementPage(
+        ps, ps.base_dir, trigger_jank=True))
 
     measurement = tbm_module.TimelineBasedMeasurement()
     results = self.RunMeasurement(measurement, ps,