| # Copyright 2015 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. |
| |
| from telemetry import decorators |
| from telemetry.internal.results import page_test_results |
| from telemetry.page import page as page_module |
| from telemetry.testing import options_for_unittests |
| from telemetry.testing import page_test_test_case |
| from telemetry.timeline import model as model_module |
| from telemetry.util import wpr_modes |
| |
| from measurements import v8_gc_times |
| |
| |
| class V8GCTimesTestPageHelper(object): |
| |
| def __init__(self, page_set): |
| self._page_set = page_set |
| self._model = model_module.TimelineModel() |
| self._renderer_process = self._model.GetOrCreateProcess(1) |
| self._renderer_thread = self._renderer_process.GetOrCreateThread(2) |
| self._renderer_thread.name = 'CrRendererMain' |
| |
| def AddEvent(self, category, name, thread_start, thread_duration, |
| args=None, wall_start=None, wall_duration=None): |
| wall_start = wall_start or thread_start |
| wall_duration = wall_duration or thread_duration |
| self._renderer_thread.BeginSlice(category, name, wall_start, thread_start, |
| args=args) |
| self._renderer_thread.EndSlice(wall_start + wall_duration, |
| thread_start + thread_duration) |
| |
| class MockV8GCTimesPage(page_module.Page): |
| |
| def __init__(self, page_set): |
| super(V8GCTimesTestPageHelper.MockV8GCTimesPage, self).__init__( |
| 'file://blank.html', page_set, page_set.base_dir, name='blank.html') |
| |
| def MeasureFakePage(self): |
| # Create a fake page and add it to the page set. |
| results = page_test_results.PageTestResults() |
| page = V8GCTimesTestPageHelper.MockV8GCTimesPage(self._page_set) |
| self._page_set.AddStory(page) |
| |
| # Pretend we're about to run the tests to silence lower level asserts. |
| results.WillRunPage(page) |
| |
| v8_gc_times_metric = v8_gc_times.V8GCTimes() |
| # pylint: disable=protected-access |
| v8_gc_times_metric._renderer_process = self._renderer_process |
| |
| # Finalize the timeline import. |
| self._model.FinalizeImport() |
| |
| # Measure the V8GCTimes metric and return the results |
| # pylint: disable=protected-access |
| v8_gc_times_metric._AddV8MetricsToResults(self._renderer_process, results) |
| results.DidRunPage(page) |
| return results |
| |
| |
| class V8GCTimesTests(page_test_test_case.PageTestTestCase): |
| |
| def setUp(self): |
| self._options = options_for_unittests.GetCopy() |
| self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF |
| |
| def testWithNoTraceEvents(self): |
| test_page_helper = V8GCTimesTestPageHelper( |
| self.CreateEmptyPageSet()) |
| |
| results = test_page_helper.MeasureFakePage() |
| self._AssertResultsEqual(_GetEmptyResults(), _ActualValues(results)) |
| |
| def testWithNoGarbageCollectionEvents(self): |
| test_page_helper = V8GCTimesTestPageHelper( |
| self.CreateEmptyPageSet()) |
| |
| test_page_helper.AddEvent( |
| 'toplevel', 'PostMessage', thread_start=0, thread_duration=14, |
| wall_start=5, wall_duration=35) |
| |
| results = test_page_helper.MeasureFakePage() |
| expected = _GetEmptyResults() |
| expected['duration'] = ('ms', 35) |
| expected['cpu_time'] = ('ms', 14) |
| |
| self._AssertResultsEqual(expected, _ActualValues(results)) |
| |
| def testWithGarbageCollectionEvents(self): |
| test_page_helper = V8GCTimesTestPageHelper( |
| self.CreateEmptyPageSet()) |
| |
| test_page_helper.AddEvent( |
| 'toplevel', 'PostMessage', thread_start=0, thread_duration=77, |
| wall_start=5, wall_duration=88) |
| test_page_helper.AddEvent('v8', 'V8.GCScavenger', 5, 4) |
| test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 3) |
| test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 23, 4) |
| test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 2) |
| test_page_helper.AddEvent('v8', 'V8.GCFinalizeMC', 38, 2) |
| test_page_helper.AddEvent('v8', 'V8.GCFinalizeMC', 42, 3) |
| test_page_helper.AddEvent('v8', 'V8.GCFinalizeMCReduceMemory', 46, 4) |
| test_page_helper.AddEvent('v8', 'V8.GCFinalizeMCReduceMemory', 51, 5) |
| test_page_helper.AddEvent('v8', 'V8.GCCompactor', 62, 4) |
| test_page_helper.AddEvent('v8', 'V8.GCCompactor', 72, 5) |
| |
| results = test_page_helper.MeasureFakePage() |
| expected = _GetEmptyResults() |
| expected['duration'] = ('ms', 88) |
| expected['cpu_time'] = ('ms', 77) |
| expected['v8_gc_incremental_marking'] = ('ms', 6.0) |
| expected['v8_gc_incremental_marking_average'] = ('ms', 3.0) |
| expected['v8_gc_incremental_marking_count'] = ('count', 2) |
| expected['v8_gc_incremental_marking_max'] = ('ms', 4.0) |
| expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 6.0) |
| expected['v8_gc_finalize_incremental'] = ('ms', 5.0) |
| expected['v8_gc_finalize_incremental_average'] = ('ms', 2.5) |
| expected['v8_gc_finalize_incremental_count'] = ('count', 2) |
| expected['v8_gc_finalize_incremental_max'] = ('ms', 3.0) |
| expected['v8_gc_finalize_incremental_outside_idle'] = ('ms', 5.0) |
| expected['v8_gc_finalize_incremental_reduce_memory'] = ('ms', 9.0) |
| expected['v8_gc_finalize_incremental_reduce_memory_average'] = ('ms', 4.5) |
| expected['v8_gc_finalize_incremental_reduce_memory_count'] = ('count', 2) |
| expected['v8_gc_finalize_incremental_reduce_memory_max'] = ('ms', 5.0) |
| expected['v8_gc_finalize_incremental_reduce_memory_outside_idle'] = ( |
| 'ms', 9.0) |
| expected['v8_gc_scavenger'] = ('ms', 7.0) |
| expected['v8_gc_scavenger_average'] = ('ms', 3.5) |
| expected['v8_gc_scavenger_count'] = ('count', 2) |
| expected['v8_gc_scavenger_max'] = ('ms', 4.0) |
| expected['v8_gc_scavenger_outside_idle'] = ('ms', 7.0) |
| expected['v8_gc_mark_compactor'] = ('ms', 9.0) |
| expected['v8_gc_mark_compactor_average'] = ('ms', 4.5) |
| expected['v8_gc_mark_compactor_count'] = ('count', 2) |
| expected['v8_gc_mark_compactor_max'] = ('ms', 5.0) |
| expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 9.0) |
| expected['v8_gc_total'] = ('ms', 36.0) |
| expected['v8_gc_total_outside_idle'] = ('ms', 36.0) |
| |
| self._AssertResultsEqual(expected, _ActualValues(results)) |
| |
| def testWithIdleTaskGarbageCollectionEvents(self): |
| test_page_helper = V8GCTimesTestPageHelper( |
| self.CreateEmptyPageSet()) |
| |
| test_page_helper.AddEvent( |
| 'toplevel', 'PostMessage', thread_start=0, thread_duration=57, |
| wall_start=5, wall_duration=68) |
| |
| test_page_helper.AddEvent('v8', 'V8.GCScavenger', 5, 4) |
| test_page_helper.AddEvent( |
| 'renderer.scheduler', 'SingleThreadIdleTaskRunner::RunTask', |
| 15, 4, {'allotted_time_ms': 12}) |
| test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 3) |
| |
| test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 23, 4) |
| test_page_helper.AddEvent( |
| 'renderer.scheduler', 'SingleThreadIdleTaskRunner::RunTask', |
| 34, 3, {'allotted_time_ms': 12}) |
| test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 2) |
| |
| test_page_helper.AddEvent('v8', 'V8.GCCompactor', 42, 4) |
| test_page_helper.AddEvent( |
| 'renderer.scheduler', 'SingleThreadIdleTaskRunner::RunTask', |
| 52, 6, {'allotted_time_ms': 12}) |
| test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 5) |
| |
| results = test_page_helper.MeasureFakePage() |
| expected = _GetEmptyResults() |
| expected['duration'] = ('ms', 68) |
| expected['cpu_time'] = ('ms', 57) |
| expected['v8_gc_incremental_marking'] = ('ms', 6.0) |
| expected['v8_gc_incremental_marking_average'] = ('ms', 3.0) |
| expected['v8_gc_incremental_marking_count'] = ('count', 2) |
| expected['v8_gc_incremental_marking_max'] = ('ms', 4.0) |
| expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 4.0) |
| expected['v8_gc_incremental_marking_percentage_idle'] = \ |
| ('idle%', 100 * 2 / 6.0) |
| expected['v8_gc_scavenger'] = ('ms', 7.0) |
| expected['v8_gc_scavenger_average'] = ('ms', 3.5) |
| expected['v8_gc_scavenger_count'] = ('count', 2) |
| expected['v8_gc_scavenger_max'] = ('ms', 4.0) |
| expected['v8_gc_scavenger_outside_idle'] = ('ms', 4.0) |
| expected['v8_gc_scavenger_percentage_idle'] = ('idle%', 100 * 3 / 7.0) |
| expected['v8_gc_mark_compactor'] = ('ms', 9.0) |
| expected['v8_gc_mark_compactor_average'] = ('ms', 4.5) |
| expected['v8_gc_mark_compactor_count'] = ('count', 2) |
| expected['v8_gc_mark_compactor_max'] = ('ms', 5.0) |
| expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 4.0) |
| expected['v8_gc_mark_compactor_percentage_idle'] = ('idle%', 100 * 5 / 9.0) |
| expected['v8_gc_total'] = ('ms', 22.0) |
| expected['v8_gc_total_outside_idle'] = ('ms', 12.0) |
| expected['v8_gc_total_percentage_idle'] = ('idle%', 100 * 10 / 22.0) |
| |
| self._AssertResultsEqual(expected, _ActualValues(results)) |
| |
| def testWithIdleTaskOverruns(self): |
| test_page_helper = V8GCTimesTestPageHelper( |
| self.CreateEmptyPageSet()) |
| |
| test_page_helper.AddEvent( |
| 'toplevel', 'PostMessage', thread_start=0, thread_duration=80, |
| wall_start=5, wall_duration=92) |
| |
| test_page_helper.AddEvent( |
| 'renderer.scheduler', 'SingleThreadIdleTaskRunner::RunTask', |
| 15, 15, {'allotted_time_ms': 8}) |
| test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 14) |
| |
| test_page_helper.AddEvent( |
| 'renderer.scheduler', 'SingleThreadIdleTaskRunner::RunTask', |
| 34, 15, {'allotted_time_ms': 6}) |
| test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 14) |
| |
| test_page_helper.AddEvent( |
| 'renderer.scheduler', 'SingleThreadIdleTaskRunner::RunTask', |
| 52, 23, {'allotted_time_ms': 9}) |
| test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 22) |
| |
| results = test_page_helper.MeasureFakePage() |
| expected = _GetEmptyResults() |
| expected['duration'] = ('ms', 92) |
| expected['cpu_time'] = ('ms', 80) |
| expected['v8_gc_incremental_marking'] = ('ms', 14.0) |
| expected['v8_gc_incremental_marking_average'] = ('ms', 14.0) |
| expected['v8_gc_incremental_marking_count'] = ('count', 1) |
| expected['v8_gc_incremental_marking_max'] = ('ms', 14.0) |
| expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 8.0) |
| expected['v8_gc_incremental_marking_idle_deadline_overrun'] = ('ms', 8.0) |
| expected['v8_gc_incremental_marking_percentage_idle'] = \ |
| ('idle%', 100 * 6 / 14.0) |
| expected['v8_gc_scavenger'] = ('ms', 14.0) |
| expected['v8_gc_scavenger_average'] = ('ms', 14.0) |
| expected['v8_gc_scavenger_count'] = ('count', 1) |
| expected['v8_gc_scavenger_max'] = ('ms', 14.0) |
| expected['v8_gc_scavenger_outside_idle'] = ('ms', 6.0) |
| expected['v8_gc_scavenger_idle_deadline_overrun'] = ('ms', 6.0) |
| expected['v8_gc_scavenger_percentage_idle'] = ('idle%', 100 * 8 / 14.0) |
| expected['v8_gc_mark_compactor'] = ('ms', 22.0) |
| expected['v8_gc_mark_compactor_average'] = ('ms', 22.0) |
| expected['v8_gc_mark_compactor_count'] = ('count', 1) |
| expected['v8_gc_mark_compactor_max'] = ('ms', 22.0) |
| expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 13.0) |
| expected['v8_gc_mark_compactor_idle_deadline_overrun'] = ('ms', 13.0) |
| expected['v8_gc_mark_compactor_percentage_idle'] = ('idle%', 100 * 9 / 22.0) |
| expected['v8_gc_total'] = ('ms', 50.0) |
| expected['v8_gc_total_outside_idle'] = ('ms', 27.0) |
| expected['v8_gc_total_idle_deadline_overrun'] = ('ms', 27.0) |
| expected['v8_gc_total_percentage_idle'] = ('idle%', 100 * 23 / 50.0) |
| |
| self._AssertResultsEqual(expected, _ActualValues(results)) |
| |
| def testWithIdleTaskWallDurationOverruns(self): |
| test_page_helper = V8GCTimesTestPageHelper( |
| self.CreateEmptyPageSet()) |
| |
| test_page_helper.AddEvent( |
| 'toplevel', 'PostMessage', thread_start=0, thread_duration=80, |
| wall_start=5, wall_duration=92) |
| |
| test_page_helper.AddEvent( |
| 'renderer.scheduler', 'SingleThreadIdleTaskRunner::RunTask', |
| 15, 15, {'allotted_time_ms': 8}) |
| test_page_helper.AddEvent( |
| 'v8', 'V8.GCScavenger', thread_start=15, thread_duration=4, |
| wall_start=15, wall_duration=14) |
| |
| results = test_page_helper.MeasureFakePage() |
| expected = _GetEmptyResults() |
| expected['duration'] = ('ms', 92) |
| expected['cpu_time'] = ('ms', 80) |
| expected['v8_gc_scavenger'] = ('ms', 4.0) |
| expected['v8_gc_scavenger_average'] = ('ms', 4.0) |
| expected['v8_gc_scavenger_count'] = ('count', 1) |
| expected['v8_gc_scavenger_max'] = ('ms', 4.0) |
| expected_outside_idle = 4.0 - (4.0 * 8 / 14) |
| expected['v8_gc_scavenger_outside_idle'] = ('ms', expected_outside_idle) |
| expected['v8_gc_scavenger_idle_deadline_overrun'] = ('ms', 6.0) |
| expected['v8_gc_scavenger_percentage_idle'] = \ |
| ('idle%', 100 * (4.0 - expected_outside_idle) / 4.0) |
| expected['v8_gc_total'] = expected['v8_gc_scavenger'] |
| expected['v8_gc_total_outside_idle'] = \ |
| expected['v8_gc_scavenger_outside_idle'] |
| expected['v8_gc_total_idle_deadline_overrun'] = \ |
| expected['v8_gc_scavenger_idle_deadline_overrun'] |
| expected['v8_gc_total_percentage_idle'] = \ |
| expected['v8_gc_scavenger_percentage_idle'] |
| |
| self._AssertResultsEqual(expected, _ActualValues(results)) |
| |
| def _AssertResultsEqual(self, expected, actual): |
| for key in expected.iterkeys(): |
| self.assertIn(key, actual.keys()) |
| self.assertEqual(expected[key], actual[key], |
| 'Result for [' + key + '] - expected ' + |
| str(expected[key]) + ' but got ' + str(actual[key])) |
| |
| @decorators.Disabled('win') # crbug.com/416502 |
| def testCleanUpTrace(self): |
| self.TestTracingCleanedUp(v8_gc_times.V8GCTimes, self._options) |
| |
| |
| def _ActualValues(results): |
| return dict(list( |
| (v.name, (v.units, v.value)) |
| for v in results.all_page_specific_values |
| )) |
| |
| |
| def _GetEmptyResults(): |
| return {'cpu_time': ('ms', 0.0), |
| 'duration': ('ms', 0.0), |
| 'v8_gc_incremental_marking': ('ms', 0.0), |
| 'v8_gc_incremental_marking_average': ('ms', 0.0), |
| 'v8_gc_incremental_marking_count': ('count', 0), |
| 'v8_gc_incremental_marking_max': ('ms', 0.0), |
| 'v8_gc_incremental_marking_idle_deadline_overrun': ('ms', 0.0), |
| 'v8_gc_incremental_marking_outside_idle': ('ms', 0.0), |
| 'v8_gc_incremental_marking_percentage_idle': ('idle%', 0.0), |
| 'v8_gc_finalize_incremental': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_average': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_count': ('count', 0), |
| 'v8_gc_finalize_incremental_max': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_idle_deadline_overrun': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_outside_idle': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_percentage_idle': ('idle%', 0.0), |
| 'v8_gc_finalize_incremental_reduce_memory': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_reduce_memory_average': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_reduce_memory_count': ('count', 0), |
| 'v8_gc_finalize_incremental_reduce_memory_max': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_reduce_memory_idle_deadline_overrun': |
| ('ms', 0.0), |
| 'v8_gc_finalize_incremental_reduce_memory_outside_idle': ('ms', 0.0), |
| 'v8_gc_finalize_incremental_reduce_memory_percentage_idle': |
| ('idle%', 0.0), |
| 'v8_gc_mark_compactor': ('ms', 0.0), |
| 'v8_gc_mark_compactor_average': ('ms', 0.0), |
| 'v8_gc_mark_compactor_count': ('count', 0), |
| 'v8_gc_mark_compactor_max': ('ms', 0.0), |
| 'v8_gc_mark_compactor_idle_deadline_overrun': ('ms', 0.0), |
| 'v8_gc_mark_compactor_outside_idle': ('ms', 0.0), |
| 'v8_gc_mark_compactor_percentage_idle': ('idle%', 0.0), |
| 'v8_gc_scavenger': ('ms', 0.0), |
| 'v8_gc_scavenger_average': ('ms', 0.0), |
| 'v8_gc_scavenger_count': ('count', 0), |
| 'v8_gc_scavenger_max': ('ms', 0.0), |
| 'v8_gc_scavenger_idle_deadline_overrun': ('ms', 0.0), |
| 'v8_gc_scavenger_outside_idle': ('ms', 0.0), |
| 'v8_gc_scavenger_percentage_idle': ('idle%', 0.0), |
| 'v8_gc_total': ('ms', 0.0), |
| 'v8_gc_total_idle_deadline_overrun': ('ms', 0.0), |
| 'v8_gc_total_outside_idle': ('ms', 0.0)} |