Simplify the test harness
[WebKit-https.git] / PerformanceTests / Animometer / resources / debug-runner / benchmark-runner.js
1 function BenchmarkRunnerState(suites)
2 {
3     this._suites = suites;
4     this._suiteIndex = -1;
5     this._testIndex = 0;
6     this.next();
7 }
8
9 BenchmarkRunnerState.prototype = {
10     currentSuite: function()
11     {
12         return this._suites[this._suiteIndex];
13     },
14
15     currentTest: function()
16     {
17         var suite = this.currentSuite();
18         return suite ? suite.tests[this._testIndex] : null;
19     },
20
21     isFirstTest: function()
22     {
23         return !this._testIndex;
24     },
25
26     next: function()
27     {
28         this._testIndex++;
29
30         var suite = this._suites[this._suiteIndex];
31         if (suite && this._testIndex < suite.tests.length)
32             return;
33
34         this._testIndex = 0;
35         do {
36             this._suiteIndex++;
37         } while (this._suiteIndex < this._suites.length && this._suites[this._suiteIndex].disabled);
38     },
39
40     prepareCurrentTest: function(runner, frame)
41     {
42         var test = this.currentTest();
43         var promise = new SimplePromise;
44
45         frame.onload = function() {
46             promise.resolve();
47         };
48
49         frame.src = "tests/" + test.url;
50         return promise;
51     }
52 };
53
54 function BenchmarkRunner(suites, frameContainer, client)
55 {
56     this._suites = suites;
57     this._client = client;
58     this._frameContainer = frameContainer;
59 }
60
61 BenchmarkRunner.prototype = {
62     _appendFrame: function()
63     {
64         var frame = document.createElement("iframe");
65         frame.setAttribute("scrolling", "no");
66
67         this._frameContainer.insertBefore(frame, this._frameContainer.firstChild);
68         this._frame = frame;
69         return frame;
70     },
71
72     _removeFrame: function()
73     {
74         if (this._frame) {
75             this._frame.parentNode.removeChild(this._frame);
76             this._frame = null;
77         }
78     },
79
80     _runBenchmarkAndRecordResults: function(state)
81     {
82         var promise = new SimplePromise;
83         var suite = state.currentSuite();
84         var test = state.currentTest();
85
86         if (this._client && this._client.willRunTest)
87             this._client.willRunTest(suite, test);
88
89         var contentWindow = this._frame.contentWindow;
90         var self = this;
91
92         var options = { complexity: test.complexity };
93         Utilities.extendObject(options, this._client.options);
94         Utilities.extendObject(options, contentWindow.Utilities.parseParameters());
95
96         var benchmark = new contentWindow.benchmarkClass(options);
97         benchmark.run().then(function(sampler) {
98             var samplers = self._suitesSamplers[suite.name] || {};
99             samplers[test.name] = sampler.toJSON(true, true);
100             self._suitesSamplers[suite.name] = samplers;
101
102             if (self._client && self._client.didRunTest)
103                 self._client.didRunTest(suite, test);
104
105             state.next();
106             if (state.currentSuite() != suite)
107                 self._removeFrame();
108             promise.resolve(state);
109         });
110
111         return promise;
112     },
113
114     step: function(state)
115     {
116         if (!state) {
117             state = new BenchmarkRunnerState(this._suites);
118             this._suitesSamplers = {};
119         }
120
121         var suite = state.currentSuite();
122         if (!suite) {
123             this._finalize();
124             var promise = new SimplePromise;
125             promise.resolve();
126             return promise;
127         }
128
129         if (state.isFirstTest()) {
130             this._appendFrame();
131         }
132
133         return state.prepareCurrentTest(this, this._frame).then(function(prepareReturnValue) {
134             return this._runBenchmarkAndRecordResults(state);
135         }.bind(this));
136     },
137
138     runAllSteps: function(startingState)
139     {
140         var nextCallee = this.runAllSteps.bind(this);
141         this.step(startingState).then(function(nextState) {
142             if (nextState)
143                 nextCallee(nextState);
144         });
145     },
146
147     runMultipleIterations: function()
148     {
149         var self = this;
150         var currentIteration = 0;
151
152         this._runNextIteration = function() {
153             currentIteration++;
154             if (currentIteration < self._client.iterationCount)
155                 self.runAllSteps();
156             else if (this._client && this._client.didFinishLastIteration)
157                 self._client.didFinishLastIteration();
158         }
159
160         if (this._client && this._client.willStartFirstIteration)
161             this._client.willStartFirstIteration();
162
163         this.runAllSteps();
164     },
165
166     _finalize: function()
167     {
168         this._removeFrame();
169
170         if (this._client && this._client.didRunSuites)
171             this._client.didRunSuites(this._suitesSamplers);
172
173         if (this._runNextIteration)
174             this._runNextIteration();
175     }
176 };