Modify rasterize_and_record for DisplayItemList recording.
[chromium-blink-merge.git] / tools / perf / measurements / task_execution_time_unittest.py
blobd8e366d4fbcbf7e6654a0bf93f5fdf53867b6a10
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.
5 from measurements import task_execution_time
6 from telemetry import decorators
7 from telemetry.core import wpr_modes
8 from telemetry.page import page as page_module
9 from telemetry.results import page_test_results
10 from telemetry.timeline import model as model_module
11 from telemetry.timeline import slice as slice_data
12 from telemetry.unittest_util import options_for_unittests
13 from telemetry.unittest_util import page_test_test_case
16 class TestTaskExecutionTimePage(page_module.Page):
18 def __init__(self, page_set, base_dir):
19 super(TestTaskExecutionTimePage, self).__init__(
20 'file://blank.html', page_set, base_dir)
22 def RunPageInteractions(self, action_runner):
23 interaction = action_runner.BeginGestureInteraction(
24 'ScrollAction', is_smooth=True)
25 action_runner.ScrollPage()
26 interaction.End()
29 class TaskExecutionTimeUnitTest(page_test_test_case.PageTestTestCase):
31 def setUp(self):
32 self._options = options_for_unittests.GetCopy()
33 self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
35 @decorators.Enabled('android')
36 def testSomeResultsReturnedFromDummyPage(self):
37 ps = self.CreateEmptyPageSet()
38 ps.AddUserStory(TestTaskExecutionTimePage(ps, ps.base_dir))
39 measurement = task_execution_time.TaskExecutionTime()
41 results = self.RunMeasurement(measurement, ps, options=self._options)
43 self.assertGreater(len(results.all_page_specific_values), 0)
45 @decorators.Enabled('android')
46 def testSlicesConformToRequiredNamingConventionsUsingDummyPage(self):
47 """This test ensures the presence of required keywords.
49 Some arbitrary keywords are required to generate the names of the top 10
50 tasks. The code has a weak dependancy on 'src_func', 'class' and 'line'
51 existing; if they exist in a slice's args they are used to generate a
52 name, if they don't exists the code falls back to using the name of the
53 slice, which is less clear.
55 If the code has been refactored and these keywords no longer exist
56 the code that relies on them in task_execution_time.py should be
57 updated to use the appropriate technique for assertaining this data
58 (and this test changed in the same way).
59 """
60 ps = self.CreateEmptyPageSet()
61 ps.AddUserStory(TestTaskExecutionTimePage(ps, ps.base_dir))
62 measurement = task_execution_time.TaskExecutionTime()
64 self.RunMeasurement(measurement, ps, options=self._options)
66 required_keywords = {'src_func': 0, 'class': 0, 'line': 0}
68 # Check all slices and count the uses of the required keywords.
69 for thread in measurement._renderer_process.threads.values():
70 for slice_info in thread.IterAllSlices():
71 _CheckSliceForKeywords(slice_info, required_keywords)
73 # Confirm that all required keywords have at least one instance.
74 for use_counts in required_keywords.values():
75 self.assertGreater(use_counts, 0)
77 def testMockedResults(self):
78 task_execution_time_metric = task_execution_time.TaskExecutionTime()
79 ps = self.CreateEmptyPageSet()
80 page = TestTaskExecutionTimePage(ps, ps.base_dir)
81 ps.AddUserStory(page)
83 # Get the name of a thread used by task_execution_time metric and set up
84 # some dummy execution data pretending to be from that thread & process.
85 first_thread_name = task_execution_time_metric._RENDERER_THREADS[0]
86 data = TaskExecutionTestData(first_thread_name)
87 task_execution_time_metric._renderer_process = data._renderer_process
89 # Pretend we're about to run the tests to silence lower level asserts.
90 data.results.WillRunPage(page)
91 data.AddSlice('fast', 0, 1)
92 data.AddSlice('medium', 0, 500)
93 data.AddSlice('slow', 0, 1000)
95 # Run the code we are testing.
96 task_execution_time_metric.ValidateAndMeasurePage(None, None, data.results)
98 # Confirm we get back 3 results that are correctly sorted and named.
99 self.assertEqual(len(data.results.all_page_specific_values), 3)
100 self.assertEqual(
101 data.results.all_page_specific_values[0].name,
102 'process 1:' + first_thread_name + ':slow')
103 self.assertEqual(
104 data.results.all_page_specific_values[1].name,
105 'process 1:' + first_thread_name + ':medium')
106 self.assertEqual(
107 data.results.all_page_specific_values[2].name,
108 'process 1:' + first_thread_name + ':fast')
109 self.assertEqual(data.results.all_page_specific_values[0].value, 1000)
110 self.assertEqual(data.results.all_page_specific_values[1].value, 500)
111 self.assertEqual(data.results.all_page_specific_values[2].value, 1)
113 def testIdleTasksAreReported(self):
114 task_execution_time_metric = task_execution_time.TaskExecutionTime()
115 ps = self.CreateEmptyPageSet()
116 page = TestTaskExecutionTimePage(ps, ps.base_dir)
117 ps.AddUserStory(page)
119 # Get the name of a thread used by task_execution_time metric and set up
120 # some dummy execution data pretending to be from that thread & process.
121 first_thread_name = task_execution_time_metric._RENDERER_THREADS[0]
122 data = TaskExecutionTestData(first_thread_name)
123 task_execution_time_metric._renderer_process = data._renderer_process
125 # Pretend we're about to run the tests to silence lower level asserts.
126 data.results.WillRunPage(page)
128 # Make a slice that looks like an idle task parent.
129 slice_start_time = 0
130 slice_duration = 1000
131 parent_slice = data.AddSlice(
132 task_execution_time_metric.IDLE_SECTION_TRIGGER,
133 slice_start_time,
134 slice_duration)
135 # Add a sub-slice, this should be reported back as occuring in idle time.
136 sub_slice = slice_data.Slice(
137 None,
138 'category',
139 'slow_sub_slice',
140 slice_start_time,
141 slice_duration)
142 parent_slice.sub_slices.append(sub_slice)
144 # Add a non-idle task.
145 data.AddSlice('not_idle', slice_start_time, slice_duration)
147 # Run the code we are testing.
148 task_execution_time_metric.ValidateAndMeasurePage(None, None, data.results)
150 # The 'slow_sub_slice' should be inside the Idle section and therefore
151 # removed from the results.
152 for result in data.results.all_page_specific_values:
153 if 'slow_sub_slice' in result.name:
154 self.fail('Tasks within idle section should not be reported')
156 # The 'not_idle' slice should not have the IDLE_SECTION added to its name
157 # and should exist.
158 for result in data.results.all_page_specific_values:
159 if 'not_idle' in result.name:
160 self.assertTrue(
161 task_execution_time_metric.IDLE_SECTION
162 not in result.name)
163 break
164 else:
165 self.fail('Task was incorrectly marked as Idle')
168 def _CheckSliceForKeywords(slice_info, required_keywords):
169 for argument in slice_info.args:
170 if argument in required_keywords:
171 required_keywords[argument] += 1
172 # recurse into our sub-slices.
173 for sub_slice in slice_info.sub_slices:
174 _CheckSliceForKeywords(sub_slice, required_keywords)
177 class TaskExecutionTestData(object):
179 def __init__(self, thread_name):
180 self._model = model_module.TimelineModel()
181 self._renderer_process = self._model.GetOrCreateProcess(1)
182 self._renderer_thread = self._renderer_process.GetOrCreateThread(2)
183 self._renderer_thread.name = thread_name
184 self._results = page_test_results.PageTestResults()
185 self._metric = None
186 self._ps = None
188 @property
189 def results(self):
190 return self._results
192 @property
193 def metric(self):
194 return self._metric
196 def AddSlice(self, name, timestamp, duration):
197 new_slice = slice_data.Slice(
198 None,
199 'category',
200 name,
201 timestamp,
202 duration,
203 timestamp,
204 duration,
206 self._renderer_thread.all_slices.append(new_slice)
207 return new_slice