OLD | NEW |
---|---|
(Empty) | |
1 # Copyright (c) 2013 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 | |
5 """PeaceKeeper benchmark suite. | |
6 | |
7 Peacekeeper measures browser's performance by testing its JavaScript | |
8 functionality. JavaScript is a widely used programming language used in the | |
9 creation of modern websites to provide features such as animation, navigation, | |
10 forms and other common requirements. By measuring a browser's ability to handle | |
11 commonly used JavaScript functions Peacekeeper can evaluate its performance. | |
12 Peacekeeper scores are measured in operations per second or rendered frames per | |
13 second depending on the test. Final Score is computed by calculating geometric | |
14 mean of individual tests scores. | |
15 """ | |
16 | |
17 import os | |
18 | |
19 from metrics import statistics | |
20 from telemetry import test | |
21 from telemetry.core import util | |
22 from telemetry.page import page_measurement | |
23 from telemetry.page import page_set | |
24 | |
25 | |
26 class PeaceKeeperMeasurement(page_measurement.PageMeasurement): | |
27 | |
28 def WillNavigateToPage(self, page, tab): | |
29 page.script_to_evaluate_on_commit = """ | |
30 var __results = {}; | |
31 var _done = false; | |
32 var __real_log = window.console.log; | |
33 var test_frame = null; | |
34 var benchmark = null; | |
35 window.console.log = function(msg) { | |
36 if (typeof(msg) == "string" && (msg.indexOf("benchmark")) == 0) { | |
37 test_frame = document.getElementById("testFrame"); | |
38 benchmark = test_frame.contentWindow.benchmark; | |
39 test_frame.contentWindow.onbeforeunload = {}; | |
40 if ((msg.indexOf("Submit ok.")) != -1) { | |
41 _done = true; | |
42 var __data = {}; | |
43 __results["test"] = benchmark.testObjectName; | |
44 __results["score"] = benchmark.test.result; | |
45 if (typeof(benchmark.test.unit) != "undefined") { | |
46 __results["unit"] = benchmark.test.unit; | |
47 } else { | |
48 __results["unit"] = benchmark.test.isFps ? "fps" : "ops"; | |
49 } | |
50 } | |
51 } | |
52 __real_log.apply(this, [msg]); | |
53 } | |
54 """ | |
55 | |
56 def MeasurePage(self, _, tab, results): | |
57 def _IsDone(): | |
58 res = tab.EvaluateJavaScript('_done') | |
59 return res | |
60 util.WaitFor(_IsDone, 600) | |
tonyg
2013/11/06 21:51:55
We have a new primitive now, tab.WaitForJavaScript
prasadv
2013/11/06 22:54:45
Done.
| |
61 result = tab.EvaluateJavaScript('__results') | |
62 | |
63 results.Add('Score', 'score', int(result['score']), result['test'], | |
64 'unimportant') | |
65 | |
66 def DidRunTest(self, browser, results): | |
67 # Calculate geometric mean as the total for the combined tests. | |
68 scores = [] | |
69 for result in results.page_results: | |
70 scores.append(result['Score'].output_value) | |
71 total = statistics.GeometricMean(scores) | |
72 results.AddSummary('Score', 'score', total, 'Total') | |
73 | |
74 | |
75 class PeaceKeeperBenchmark(test.Test): | |
76 """A base class for Peackeeper benchmarks.""" | |
77 test = PeaceKeeperMeasurement | |
78 | |
79 def CreatePageSet(self, options): | |
80 """Makes a PageSet for PeaceKeeper benchmarks.""" | |
81 # Subclasses are expected to define a class member called query_param. | |
82 if not hasattr(self, 'test_param'): | |
83 raise NotImplementedError('test_param not in PeaceKeeper benchmark.') | |
84 | |
85 # The docstring of benchmark classes may also be used as a description | |
86 # when 'run_benchmarks list' is run. | |
87 description = self.__doc__ or 'PeaceKeeper Benchmark' | |
88 test_urls = [] | |
89 for test_name in self.test_param: | |
90 test_urls.append( | |
91 {"url": ("http://peacekeeper.futuremark.com/run.action?debug=true&" | |
92 "repeat=false&forceSuiteName=%s&forceTestName=%s") % | |
tonyg
2013/11/06 21:51:55
Nice find! I'm glad you figured out a way to split
prasadv
2013/11/06 22:54:45
Done.
| |
93 (self.tag, test_name) | |
94 }) | |
95 | |
96 page_set_dict = { | |
97 'description': description, | |
98 'archive_data_file': '../page_sets/data/peacekeeper_%s.json' % self.tag, | |
99 'make_javascript_deterministic': False, | |
100 'pages': test_urls, | |
101 } | |
102 return page_set.PageSet.FromDict(page_set_dict, os.path.abspath(__file__)) | |
103 | |
104 | |
105 class PeaceKeeperRender(PeaceKeeperBenchmark): | |
106 """PeaceKeeper rendering benchmark suite. | |
107 | |
108 These tests measure your browser's ability to render and modify specific | |
109 elements used in typical web pages. Rendering tests manipulate the DOM tree in | |
110 real-time. The tests measure display updating speed (frames per seconds). | |
111 """ | |
112 tag = 'render' | |
113 test_param = ['renderGrid01', 'renderGrid02', 'renderGrid03', | |
114 'renderPhysics'] | |
115 | |
116 | |
117 class PeaceKeeperData(PeaceKeeperBenchmark): | |
118 """PeaceKeeper Data operations benchmark suite. | |
119 | |
120 These tests measure your browser's ability to add, remove and modify data | |
121 stored in an array. The Data suite consists of two tests: | |
122 1. arrayCombined: This test uses all features of the JavaScript Array object. | |
123 This is a technical test that is not based on profiled data. | |
124 The source data are different sized arrays of numbers. | |
125 2. arrayWeighted: This test is similar to 'arrayCombined', but the load is | |
126 balanced based on profiled data. The source data is a list of all the | |
127 countries in the world. | |
128 """ | |
129 | |
130 tag = 'array' | |
131 test_param = ['arrayCombined01', 'arrayWeighted'] | |
132 | |
133 | |
134 class PeaceKeeperDom(PeaceKeeperBenchmark): | |
135 """PeaceKeeper DOM operations benchmark suite. | |
136 | |
137 These tests emulate the methods used to create typical dynamic webpages. | |
138 The DOM tests are based on development experience and the capabilities of the | |
139 jQuery framework. | |
140 1. domGetElements: This test uses native DOM methods getElementById and | |
141 getElementsByName. The elements are not modified. | |
142 2. domDynamicCreationCreateElement: A common use of DOM is to dynamically | |
143 create content with JavaScript, this test measures creating objects | |
144 individually and then appending them to DOM. | |
145 3. domDynamicCreationInnerHTML: This test is similarl to the previous one, | |
146 but uses the innerHTML-method. | |
147 4. domJQueryAttributeFilters: This test does a DOM query with jQuery. | |
148 It searches elements with specific attributes. | |
149 5. domJQueryBasicFilters: This test uses filters to query elements from DOM. | |
150 6. domJQueryBasics: This test queries elements from DOM with basic methods. | |
151 It is similar to domGetElements, but uses jQuery rather than native methods. | |
152 7. domJQueryContentFilters: Query elements based on content. This does string | |
153 searching and these methods are assumed to be time consuming. | |
154 8. domJQueryHierarchy: Query elements based on hierarchy, such as getting | |
155 sibling, parent or child nodes from a DOM tree. | |
156 9. domQueryselector: QuerySelector, which allows JavaScript to search elements | |
157 from the DOM tree directly without the need to iterate the whole tree | |
158 through domGetElements. | |
159 """ | |
160 | |
161 tag = 'dom' | |
162 test_param = ['domGetElements', 'domDynamicCreationCreateElement', | |
tonyg
2013/11/06 21:51:55
Recommend one string per line just for readability
prasadv
2013/11/06 22:54:45
Done.
| |
163 'domDynamicCreationInnerHTML', 'domJQueryAttributeFilters', | |
164 'domJQueryBasicFilters', 'domJQueryBasics', | |
165 'domJQueryContentFilters', 'domJQueryHierarchy', | |
166 'domQueryselector'] | |
167 | |
168 | |
169 class PeaceKeeperTextParsing(PeaceKeeperBenchmark): | |
170 """PeaceKeeper Text Parsing benchmark suite. | |
171 | |
172 These tests measure your browser's performance in typical text manipulations | |
173 such as using a profanity filter for chats, browser detection and form | |
174 validation. | |
175 1. stringChat: This test removes swearing from artificial chat messages. | |
176 Test measures looping and string replace-method. | |
177 2. stringDetectBrowser: This test uses string indexOf-method to detect browser | |
178 and operating system. | |
179 3. stringFilter: This test filters a list of movies with a given keyword. | |
180 The behaviour is known as filtering select or continuous filter. It's used | |
181 to give real time suggestions while a user is filling input fields. | |
182 The test uses simple regular expressions. | |
183 4. stringValidateForm: This test uses complex regular expressions to validate | |
184 user input. | |
185 5. stringWeighted: This is an artificial test. Methods used and their | |
186 intensities are chosen based on profiled data. | |
187 """ | |
188 | |
189 tag = 'string' | |
190 test_param = ['stringChat', 'stringDetectBrowser', 'stringFilter', | |
191 'stringWeighted', 'stringValidateForm'] | |
192 | |
OLD | NEW |