| # Copyright 2014 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. | 
 |  | 
 | """Apple's Speedometer performance benchmark. | 
 |  | 
 | Speedometer measures simulated user interactions in web applications. | 
 |  | 
 | The current benchmark uses TodoMVC to simulate user actions for adding, | 
 | completing, and removing to-do items. Speedometer repeats the same actions using | 
 | DOM APIs - a core set of web platform APIs used extensively in web applications- | 
 | as well as six popular JavaScript frameworks: Ember.js, Backbone.js, jQuery, | 
 | AngularJS, React, and Flight. Many of these frameworks are used on the most | 
 | popular websites in the world, such as Facebook and Twitter. The performance of | 
 | these types of operations depends on the speed of the DOM APIs, the JavaScript | 
 | engine, CSS style resolution, layout, and other technologies. | 
 | """ | 
 |  | 
 | import os | 
 |  | 
 | from core import perf_benchmark | 
 |  | 
 | from benchmarks import v8_helper | 
 |  | 
 | from telemetry import benchmark | 
 | from telemetry import page as page_module | 
 | from telemetry.page import legacy_page_test | 
 | from telemetry import story | 
 | from telemetry.value import list_of_scalar_values | 
 |  | 
 | from metrics import keychain_metric | 
 |  | 
 |  | 
 | class SpeedometerMeasurement(legacy_page_test.LegacyPageTest): | 
 |   enabled_suites = [ | 
 |       'VanillaJS-TodoMVC', | 
 |       'EmberJS-TodoMVC', | 
 |       'BackboneJS-TodoMVC', | 
 |       'jQuery-TodoMVC', | 
 |       'AngularJS-TodoMVC', | 
 |       'React-TodoMVC', | 
 |       'FlightJS-TodoMVC' | 
 |   ] | 
 |  | 
 |   def __init__(self): | 
 |     super(SpeedometerMeasurement, self).__init__() | 
 |  | 
 |   def CustomizeBrowserOptions(self, options): | 
 |     keychain_metric.KeychainMetric.CustomizeBrowserOptions(options) | 
 |  | 
 |   def ValidateAndMeasurePage(self, page, tab, results): | 
 |     tab.WaitForDocumentReadyStateToBeComplete() | 
 |     iterationCount = 10 | 
 |     # A single iteration on android takes ~75 seconds, the benchmark times out | 
 |     # when running for 10 iterations. | 
 |     if tab.browser.platform.GetOSName() == 'android': | 
 |       iterationCount = 3 | 
 |  | 
 |     tab.ExecuteJavaScript(""" | 
 |         // Store all the results in the benchmarkClient | 
 |         benchmarkClient._measuredValues = [] | 
 |         benchmarkClient.didRunSuites = function(measuredValues) { | 
 |           benchmarkClient._measuredValues.push(measuredValues); | 
 |           benchmarkClient._timeValues.push(measuredValues.total); | 
 |         }; | 
 |         benchmarkClient.iterationCount = %d; | 
 |         startTest(); | 
 |         """ % iterationCount) | 
 |     tab.WaitForJavaScriptExpression( | 
 |         'benchmarkClient._finishedTestCount == benchmarkClient.testsCount', 600) | 
 |     results.AddValue(list_of_scalar_values.ListOfScalarValues( | 
 |         page, 'Total', 'ms', | 
 |         tab.EvaluateJavaScript('benchmarkClient._timeValues'), important=True)) | 
 |  | 
 |     # Extract the timings for each suite | 
 |     for suite_name in self.enabled_suites: | 
 |       results.AddValue(list_of_scalar_values.ListOfScalarValues( | 
 |           page, suite_name, 'ms', | 
 |           tab.EvaluateJavaScript(""" | 
 |               var suite_times = []; | 
 |               for(var i = 0; i < benchmarkClient.iterationCount; i++) { | 
 |                 suite_times.push( | 
 |                     benchmarkClient._measuredValues[i].tests['%s'].total); | 
 |               }; | 
 |               suite_times; | 
 |               """ % suite_name), important=False)) | 
 |     keychain_metric.KeychainMetric().AddResults(tab, results) | 
 |  | 
 |  | 
 | class Speedometer(perf_benchmark.PerfBenchmark): | 
 |   test = SpeedometerMeasurement | 
 |  | 
 |   @classmethod | 
 |   def Name(cls): | 
 |     return 'speedometer' | 
 |  | 
 |   def CreateStorySet(self, options): | 
 |     ps = story.StorySet( | 
 |         base_dir=os.path.dirname(os.path.abspath(__file__)), | 
 |         archive_data_file='../page_sets/data/speedometer.json', | 
 |         cloud_storage_bucket=story.PUBLIC_BUCKET) | 
 |     ps.AddStory(page_module.Page( | 
 |         'http://browserbench.org/Speedometer/', ps, ps.base_dir, | 
 |         make_javascript_deterministic=False)) | 
 |     return ps | 
 |  | 
 |  | 
 | @benchmark.Disabled('reference')  # crbug.com/579546 | 
 | class SpeedometerIgnition(Speedometer): | 
 |   def SetExtraBrowserOptions(self, options): | 
 |     super(SpeedometerIgnition, self).SetExtraBrowserOptions(options) | 
 |     v8_helper.EnableIgnition(options) | 
 |  | 
 |   @classmethod | 
 |   def Name(cls): | 
 |     return 'speedometer-ignition' |