def testCacheHandled(self): cycler = self.SetUpCycler( ['--pageset-repeat=5', '--cold-load-percent=50'], True) url_name = 'http://fakepage.com' page = FakePage(url_name) tab = FakeTab() results = page_measurement_results.PageMeasurementResults() for i in range(5): cycler.WillNavigateToPage(page, tab) self.assertEqual( max(0, i - 2), tab.clear_cache_calls, 'Iteration %d tab.clear_cache_calls %d' % (i, tab.clear_cache_calls)) results.WillMeasurePage(page) cycler.MeasurePage(page, tab, results) values = results.page_specific_values_for_current_page results.DidMeasurePage() self.assertGreater(len(values), 2) self.assertEqual(values[0].page, page) chart_name = 'cold_times' if i == 0 or i > 2 else 'warm_times' self.assertEqual(values[0].name, '%s.page_load_time' % chart_name) self.assertEqual(values[0].units, 'ms') cycler.DidNavigateToPage(page, tab)
def RunPage(self, page, tab, results): # When recording, sleep to catch any resources that load post-onload. tab.WaitForDocumentReadyStateToBeComplete() if self.test: dummy_results = page_measurement_results.PageMeasurementResults() dummy_results.WillMeasurePage(page) self.test.MeasurePage(page, tab, dummy_results) dummy_results.DidMeasurePage() else: # TODO(tonyg): This should probably monitor resource timing for activity # and sleep until 2s since the last network event with some timeout like # 20s. We could wrap this up as WaitForNetworkIdle() and share with the # speed index metric. time.sleep(3) # Run the actions for all measurements. Reload the page between # actions. should_reload = False interactive = self.options and self.options.interactive for action_name in self._action_names: if not hasattr(page, action_name): continue if should_reload: self.RunNavigateSteps(page, tab) action_runner = action_runner_module.ActionRunner(page, tab, self) if interactive: action_runner.RunAction(interact.InteractAction()) else: self._RunMethod(page, action_name, action_runner) should_reload = True
def testColdWarm(self): cycler = self.SetUpCycler(['--pageset-repeat=3'], True) pages = [ FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com') ] tab = FakeTab() results = page_measurement_results.PageMeasurementResults() for i in range(3): for page in pages: cycler.WillNavigateToPage(page, tab) results.WillMeasurePage(page) cycler.MeasurePage(page, tab, results) values = results.page_specific_values_for_current_page results.DidMeasurePage() self.assertGreater(len(values), 2) self.assertEqual(values[0].page, page) chart_name = 'cold_times' if i == 0 or i > 1 else 'warm_times' self.assertEqual(values[0].name, '%s.page_load_time' % chart_name) self.assertEqual(values[0].units, 'ms') cycler.DidNavigateToPage(page, tab)
def PrepareResults(self, options): if hasattr(options, 'output_file') and options.output_file: output_stream = open(os.path.expanduser(options.output_file), 'w') else: output_stream = sys.stdout if not hasattr(options, 'output_format'): options.output_format = self.output_format_choices[0] if not hasattr(options, 'output_trace_tag'): options.output_trace_tag = '' if options.output_format == 'csv': return csv_page_measurement_results.CsvPageMeasurementResults( output_stream, self.results_are_the_same_on_every_page) elif options.output_format == 'block': return block_page_measurement_results.BlockPageMeasurementResults( output_stream) elif options.output_format == 'buildbot': return buildbot_page_measurement_results.BuildbotPageMeasurementResults( trace_tag=options.output_trace_tag) elif options.output_format == 'none': return page_measurement_results.PageMeasurementResults( trace_tag=options.output_trace_tag) else: # Should never be reached. The parser enforces the choices. raise Exception('Invalid --output-format "%s". Valid choices are: %s' % (options.output_format, ', '.join(self.output_format_choices)))
def testCacheHandled(self): cycler = self.setupCycler( ['--pageset-repeat=5', '--cold-load-percent=50']) # Mock out memory metrics; the real ones require a real browser. mock_memory_metric = MockMemoryMetric() mock_memory_module = simple_mock.MockObject() mock_memory_module.ExpectCall('MemoryMetric').WithArgs( simple_mock.DONT_CARE).WillReturn(mock_memory_metric) real_memory_module = page_cycler.memory try: page_cycler.memory = mock_memory_module cycler.DidStartBrowser(None) finally: page_cycler.memory = real_memory_module class FakePage(object): def __init__(self, url): self.url = url class FakeTab(object): def __init__(self): self.clear_cache_calls = 0 def ClearCache(self): self.clear_cache_calls += 1 def EvaluateJavaScript(self, _): return 1 def WaitForJavaScriptExpression(self, _, __): pass url_name = "http://fakepage.com" page = FakePage(url_name) tab = FakeTab() results = page_measurement_results.PageMeasurementResults() for i in range(5): cycler.WillNavigateToPage(page, tab) self.assertEqual( max(0, i - 2), tab.clear_cache_calls, "Iteration %d tab.clear_cache_calls %d" % (i, tab.clear_cache_calls)) num_results = len(results.page_results) results.WillMeasurePage(page) cycler.MeasurePage(page, tab, results) results.DidMeasurePage() self.assertEqual(num_results + 1, len(results.page_results)) result = results[-1] self.assertEqual(result.page, page) self.assertEqual(1, len(result.values)) self.assertEqual(result.values[0].trace_name, 'page_load_time') self.assertEqual(result.values[0].units, 'ms') self.assertEqual(result.values[0].chart_name, 'warm_times' if i < 3 else 'cold_times') cycler.DidNavigateToPage(page, tab)
def _PrepareAndRunPage(test, page_set, expectations, options, page, credentials_path, possible_browser, results, state): if options.wpr_mode != wpr_modes.WPR_RECORD: if page.archive_path and os.path.isfile(page.archive_path): possible_browser.options.wpr_mode = wpr_modes.WPR_REPLAY else: possible_browser.options.wpr_mode = wpr_modes.WPR_OFF results_for_current_run = results if state.first_page[page] and test.discard_first_result: # If discarding results, substitute a dummy object. results_for_current_run = page_measurement_results.PageMeasurementResults( ) results_for_current_run.StartTest(page) tries = 3 while tries: try: state.StartBrowser(test, page_set, page, possible_browser, credentials_path, page.archive_path) _WaitForThermalThrottlingIfNeeded(state.browser.platform) if options.profiler: state.StartProfiling(page, options) expectation = expectations.GetExpectationForPage( state.browser.platform, page) try: _RunPage(test, page, state.tab, expectation, results_for_current_run, options) _CheckThermalThrottling(state.browser.platform) except exceptions.TabCrashException: _LogStackTrace('Tab crashed: %s' % page.url, state.browser) state.StopBrowser() if options.profiler: state.StopProfiling() if test.NeedsBrowserRestartAfterEachRun(state.tab): state.StopBrowser() break except exceptions.BrowserGoneException: _LogStackTrace('Browser crashed', state.browser) logging.warning('Lost connection to browser. Retrying.') state.StopBrowser() tries -= 1 if not tries: logging.error('Lost connection to browser 3 times. Failing.') raise results_for_current_run.StopTest(page)
def PrepareResults(test, options): if not isinstance(test, page_measurement.PageMeasurement): # Sort of hacky. The default for non-Measurements should be "gtest." if options.output_format != 'none': options.output_format = 'gtest' if options.output_format == 'html' and not options.output_file: options.output_file = os.path.join(util.GetBaseDir(), 'results.html') if hasattr(options, 'output_file') and options.output_file: output_file = os.path.expanduser(options.output_file) open(output_file, 'a').close() # Create file if it doesn't exist. output_stream = open(output_file, 'r+') else: output_stream = sys.stdout if not hasattr(options, 'output_format'): options.output_format = _OUTPUT_FORMAT_CHOICES[0] if not hasattr(options, 'output_trace_tag'): options.output_trace_tag = '' if options.output_format == 'none': return page_measurement_results.PageMeasurementResults( output_stream, trace_tag=options.output_trace_tag) elif options.output_format == 'csv': return csv_page_measurement_results.CsvPageMeasurementResults( output_stream, test.results_are_the_same_on_every_page) elif options.output_format == 'block': return block_page_measurement_results.BlockPageMeasurementResults( output_stream) elif options.output_format == 'buildbot': return buildbot_page_measurement_results.BuildbotPageMeasurementResults( output_stream, trace_tag=options.output_trace_tag) elif options.output_format == 'gtest': return gtest_test_results.GTestTestResults(output_stream) elif options.output_format == 'html': return html_page_measurement_results.HtmlPageMeasurementResults( output_stream, test.__class__.__name__, options.reset_results, options.upload_results, options.browser_type, options.results_label, trace_tag=options.output_trace_tag) else: # Should never be reached. The parser enforces the choices. raise Exception( 'Invalid --output-format "%s". Valid choices are: %s' % (options.output_format, ', '.join(_OUTPUT_FORMAT_CHOICES)))
def testAddResults(self): results = page_measurement_results.PageMeasurementResults() class FakeSmoothMetric(timeline_based_metric.TimelineBasedMetric): def AddResults(self, model, renderer_thread, interaction_record, results): results.Add('FakeSmoothMetric', 'ms', 1) class FakeLoadingMetric(timeline_based_metric.TimelineBasedMetric): def AddResults(self, model, renderer_thread, interaction_record, results): assert interaction_record.logical_name == 'LogicalName2' results.Add('FakeLoadingMetric', 'ms', 2) def CreateMetricsForTimelineInteractionRecord(interaction): res = [] if interaction.is_smooth: res.append(FakeSmoothMetric()) if interaction.is_loading_resources: res.append(FakeLoadingMetric()) return res metric = tbm_module._TimelineBasedMetrics( # pylint: disable=W0212 self.model, self.renderer_thread, CreateMetricsForTimelineInteractionRecord) ps = page_set.PageSet.FromDict( { "description": "hello", "archive_path": "foo.wpr", "pages": [{ "url": "http://www.bar.com/" }] }, os.path.dirname(__file__)) 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)
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_loading_resources: 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)
def testResults(self): cycler = self.SetUpCycler([], True) pages = [ FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com') ] tab = FakeTab() results = page_measurement_results.PageMeasurementResults() for i in range(2): for page in pages: cycler.WillNavigateToPage(page, tab) results.WillMeasurePage(page) cycler.MeasurePage(page, tab, results) values = results.page_specific_values_for_current_page results.DidMeasurePage() self.assertEqual(4, len(values)) self.assertEqual(values[0].page, page) chart_name = 'cold_times' if i == 0 else 'warm_times' self.assertEqual(values[0].name, '%s.page_load_time' % chart_name) self.assertEqual(values[0].units, 'ms') for value, expected in zip(values[1:], ['gpu', 'renderer', 'browser']): self.assertEqual(value.page, page) self.assertEqual( value.name, 'cpu_utilization.cpu_utilization_%s' % expected) self.assertEqual(value.units, '%') cycler.DidNavigateToPage(page, tab)
def Run(self, options, page, tab, results): # When recording, sleep to catch any resources that load post-onload. tab.WaitForDocumentReadyStateToBeComplete() if self.test: dummy_results = page_measurement_results.PageMeasurementResults() dummy_results.WillMeasurePage(page) self.test.MeasurePage(page, tab, dummy_results) dummy_results.DidMeasurePage() else: # TODO(tonyg): This should probably monitor resource timing for activity # and sleep until 2s since the last network event with some timeout like # 20s. We could wrap this up as WaitForNetworkIdle() and share with the # speed index metric. time.sleep(3) # Run the actions for all measurements. Reload the page between # actions. should_reload = False for compound_action in self._CompoundActionsForPage(page, options): if should_reload: self.RunNavigateSteps(page, tab) self._RunCompoundAction(page, tab, compound_action) should_reload = True