1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import unittest
6
7from collections import namedtuple
8from telemetry.internal.results import page_test_results
9from telemetry.page import page
10from telemetry.web_perf.metrics import single_event
11from telemetry.web_perf import timeline_interaction_record
12
13TRACE_EVENT_NAME = 'FrameView::performLayout'
14METRIC_NAME = 'layout'
15FakeEventTuple = namedtuple(
16    'Event',
17    'start, end, name, duration, thread_duration, has_thread_timestamps')
18Interaction = timeline_interaction_record.TimelineInteractionRecord
19
20class SingleEventTestMetric(single_event._SingleEventMetric):
21  def __init__(self):
22    super(SingleEventTestMetric, self).__init__(TRACE_EVENT_NAME, METRIC_NAME)
23
24def GetSingleEventMetrics(events, interactions):
25  results = page_test_results.PageTestResults()
26  results.WillRunPage(page.Page('file://blank.html'))
27  SingleEventTestMetric()._AddResultsInternal(events, interactions, results)
28  return dict((value.name, value.values) for value in
29              results.current_page_run.values)
30
31def FakeEvent(start, end, name=TRACE_EVENT_NAME):
32  dur = end - start
33  return FakeEventTuple(start, end, name, dur, dur, True)
34
35
36class SingleEventMetricUnitTest(unittest.TestCase):
37  def testSingleEventMetric(self):
38    events = [FakeEvent(0, 1),
39              FakeEvent(9, 11),
40              FakeEventTuple(10, 13, TRACE_EVENT_NAME, 3, 0, False),
41              FakeEvent(20, 24),
42              FakeEvent(21, 26),
43              FakeEvent(29, 35),
44              FakeEvent(30, 37),
45              FakeEvent(40, 48),
46              FakeEvent(41, 50),
47              FakeEvent(10, 13, name='something'),
48              FakeEvent(20, 24, name='FrameView::something'),
49              FakeEvent(30, 37, name='SomeThing::performLayout'),
50              FakeEvent(40, 48, name='something else')]
51    interactions = [Interaction('interaction', 10, 20),
52                    Interaction('interaction', 30, 40)]
53
54    self.assertFalse(GetSingleEventMetrics(events, []))
55    self.assertFalse(GetSingleEventMetrics([], interactions))
56
57    # The first event starts before the first interaction, so it is ignored.
58    # The second event starts before the first interaction, so it is ignored.
59    # The third event starts during the first interaction, and its duration is
60    # 13 - 10 = 3.
61    # The fourth event starts during the first interaction, and its duration is
62    # 24 - 20 = 4.
63    # The fifth event starts between the two interactions, so it is ignored.
64    # The sixth event starts between the two interactions, so it is ignored.
65    # The seventh event starts during the second interaction, and its duration
66    # is 37 - 30 = 7.
67    # The eighth event starts during the second interaction, and its duration is
68    # 48 - 40 = 8.
69    # The ninth event starts after the last interaction, so it is ignored.
70    # The rest of the events have the wrong name, so they are ignored.
71    self.assertEqual({METRIC_NAME: [3, 4, 7, 8]}, GetSingleEventMetrics(
72        events, interactions))
73