Summary page should show warnings when current or baseline data is missing.
[WebKit-https.git] / Websites / perf.webkit.org / unit-tests / measurement-set-tests.js
1 'use strict';
2
3 var assert = require('assert');
4
5 let MockRemoteAPI = require('./resources/mock-remote-api.js').MockRemoteAPI;
6 require('../tools/js/v3-models.js');
7 let MockModels = require('./resources/mock-v3-models.js').MockModels;
8
9 describe('MeasurementSet', function () {
10     MockModels.inject();
11     let requests = MockRemoteAPI.inject();
12
13     beforeEach(function () {
14         MeasurementSet._set = null;
15     });
16
17     describe('findSet', function () {
18         it('should create a new MeasurementSet for a new pair of platform and matric', function () {
19             assert.notEqual(MeasurementSet.findSet(1, 1, 3000), MeasurementSet.findSet(1, 2, 3000));
20             assert.notEqual(MeasurementSet.findSet(1, 1, 3000), MeasurementSet.findSet(2, 1, 3000));
21         });
22
23         it('should not create a new MeasurementSet when the same pair of platform and matric are requested', function () {
24             assert.equal(MeasurementSet.findSet(1, 1), MeasurementSet.findSet(1, 1));
25         });
26     });
27
28     describe('fetchBetween', function () {
29         it('should always request the cached primary cluster first', function () {
30             var set = MeasurementSet.findSet(1, 1, 3000);
31             set.fetchBetween(1000, 2000, function () { assert.notReached(); });
32             assert.equal(requests.length, 1);
33             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
34         });
35
36         it('should not request the cached primary cluster twice', function () {
37             var set = MeasurementSet.findSet(1, 1, 3000);
38             set.fetchBetween(1000, 2000, function () { assert.notReached(); });
39             assert.equal(requests.length, 1);
40             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
41             set.fetchBetween(2000, 3000, function () { assert.notReached(); });
42             assert.equal(requests.length, 1);
43         });
44
45         it('should invoke the callback when the up-to-date cached primary cluster is fetched and it matches the requested range', function (done) {
46             var set = MeasurementSet.findSet(1, 1, 3000);
47             var callCount = 0;
48             var promise = set.fetchBetween(2000, 3000, function () {
49                 callCount++;
50             });
51             assert.equal(requests.length, 1);
52             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
53
54             requests[0].resolve({
55                 'clusterStart': 1000,
56                 'clusterSize': 1000,
57                 'formatMap': [],
58                 'configurations': {current: []},
59                 'startTime': 2000,
60                 'endTime': 3000,
61                 'lastModified': 3000,
62                 'clusterCount': 2,
63                 'status': 'OK'});
64
65             promise.then(function () {
66                 assert.equal(callCount, 1);
67                 assert.equal(requests.length, 1);
68                 done();
69             }).catch(function (error) {
70                 done(error);
71             });
72         });
73
74         function waitForMeasurementSet()
75         {
76             return Promise.resolve().then(function () {
77                 return Promise.resolve();
78             }).then(function () {
79                 return Promise.resolve();
80             });
81         }
82
83         it('should invoke the callback and fetch a secondary cluster when the cached primary cluster is up-to-date and within in the requested range', function (done) {
84             var set = MeasurementSet.findSet(1, 1, 3000);
85             var callCount = 0;
86             var promise = set.fetchBetween(1000, 3000, function () {
87                 callCount++;
88             });
89             assert.equal(requests.length, 1);
90             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
91
92             requests[0].resolve({
93                 'clusterStart': 1000,
94                 'clusterSize': 1000,
95                 'formatMap': [],
96                 'configurations': {current: []},
97                 'startTime': 2000,
98                 'endTime': 3000,
99                 'lastModified': 3000,
100                 'clusterCount': 2,
101                 'status': 'OK'});
102
103             waitForMeasurementSet().then(function () {
104                 assert.equal(callCount, 1);
105                 assert.equal(requests.length, 2);
106                 assert.equal(requests[1].url, '../data/measurement-set-1-1-2000.json');
107                 done();
108             }).catch(function (error) {
109                 done(error);
110             });
111         });
112
113         it('should request additional secondary clusters as requested', function (done) {
114             var set = MeasurementSet.findSet(1, 1, 5000);
115             set.fetchBetween(2000, 3000, function () {
116                 assert.notReached();
117             });
118             assert.equal(requests.length, 1);
119             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
120
121             requests[0].resolve({
122                 'clusterStart': 1000,
123                 'clusterSize': 1000,
124                 'formatMap': [],
125                 'configurations': {current: []},
126                 'startTime': 4000,
127                 'endTime': 5000,
128                 'lastModified': 5000,
129                 'clusterCount': 3,
130                 'status': 'OK'});
131
132             var callCount = 0;
133             waitForMeasurementSet().then(function () {
134                 assert.equal(requests.length, 2);
135                 assert.equal(requests[1].url, '../data/measurement-set-1-1-3000.json');
136
137                 set.fetchBetween(0, 7000, function () { callCount++; });
138
139                 return waitForMeasurementSet();
140             }).then(function () {
141                 assert.equal(callCount, 1);
142                 assert.equal(requests.length, 4);
143                 assert.equal(requests[2].url, '../data/measurement-set-1-1-2000.json');
144                 assert.equal(requests[3].url, '../data/measurement-set-1-1-4000.json');
145
146                 done();
147             }).catch(function (error) {
148                 done(error);
149             });
150         });
151
152         it('should request secondary clusters which forms a superset of the requested range', function (done) {
153             var set = MeasurementSet.findSet(1, 1, 5000);
154             set.fetchBetween(2707, 4207, function () {
155                 assert.notReached();
156             });
157             assert.equal(requests.length, 1);
158             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
159
160             requests[0].resolve({
161                 'clusterStart': 1000,
162                 'clusterSize': 1000,
163                 'formatMap': [],
164                 'configurations': {current: []},
165                 'startTime': 4000,
166                 'endTime': 5000,
167                 'lastModified': 5000,
168                 'clusterCount': 3,
169                 'status': 'OK'});
170
171             waitForMeasurementSet().then(function () {
172                 assert.equal(requests.length, 3);
173                 assert.equal(requests[1].url, '../data/measurement-set-1-1-3000.json');
174                 assert.equal(requests[2].url, '../data/measurement-set-1-1-4000.json');
175                 done();
176             }).catch(function (error) {
177                 done(error);
178             });
179         });
180
181         it('should not request secondary clusters that are not requested', function (done) {
182             var set = MeasurementSet.findSet(1, 1, 5000);
183             set.fetchBetween(3200, 3700, function () {
184                 assert.notReached();
185             });
186             assert.equal(requests.length, 1);
187             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
188
189             requests[0].resolve({
190                 'clusterStart': 1000,
191                 'clusterSize': 1000,
192                 'formatMap': [],
193                 'configurations': {current: []},
194                 'startTime': 4000,
195                 'endTime': 5000,
196                 'lastModified': 5000,
197                 'clusterCount': 3,
198                 'status': 'OK'});
199
200             var callCount = 0;
201             waitForMeasurementSet().then(function () {
202                 assert.equal(requests.length, 2);
203                 assert.equal(requests[1].url, '../data/measurement-set-1-1-4000.json');
204                 set.fetchBetween(1207, 1293, function () { callCount++; });
205                 return waitForMeasurementSet();
206             }).then(function () {
207                 assert.equal(callCount, 0);
208                 assert.equal(requests.length, 3);
209                 assert.equal(requests[2].url, '../data/measurement-set-1-1-2000.json');
210                 set.fetchBetween(1964, 3401, function () { callCount++; });
211                 return waitForMeasurementSet();
212             }).then(function () {
213                 assert.equal(callCount, 0);
214                 assert.equal(requests.length, 4);
215                 assert.equal(requests[3].url, '../data/measurement-set-1-1-3000.json');
216                 done();
217             }).catch(function (error) {
218                 done(error);
219             });
220         });
221
222         it('should invoke the callback when the fetching of the primray cluster fails', function (done) {
223             var set = MeasurementSet.findSet(1, 1, 3000);
224             var callCount = 0;
225             set.fetchBetween(1000, 3000, function () {
226                 callCount++;
227             });
228             assert.equal(requests.length, 1);
229             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
230
231             requests[0].reject(500);
232
233             waitForMeasurementSet().then(function () {
234                 assert.equal(callCount, 1);
235                 assert.equal(requests.length, 1);
236                 done();
237             }).catch(function (error) {
238                 done(error);
239             });
240         });
241
242         it('should request the uncached primary cluster when the cached cluster is outdated', function (done) {
243             var set = MeasurementSet.findSet(1, 1, 3005);
244             var callCount = 0;
245             set.fetchBetween(1000, 2000, function () {
246                 callCount++;
247             });
248             assert.equal(requests.length, 1);
249             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
250
251             requests[0].resolve({
252                 'clusterStart': 1000,
253                 'clusterSize': 1000,
254                 'formatMap': [],
255                 'configurations': {current: []},
256                 'startTime': 2000,
257                 'endTime': 3000,
258                 'lastModified': 3000,
259                 'clusterCount': 2,
260                 'status': 'OK'});
261
262             Promise.resolve().then(function () {
263                 assert.equal(callCount, 0);
264                 assert.equal(requests.length, 2);
265                 assert.equal(requests[1].url, '../api/measurement-set?platform=1&metric=1');
266                 done();
267             }).catch(function (error) {
268                 done(error);
269             });
270         });
271
272         it('should request the uncached primary cluster when the cached cluster is 404', function (done) {
273             var set = MeasurementSet.findSet(1, 1, 3005);
274             var callCount = 0;
275             set.fetchBetween(1000, 2000, function () {
276                 callCount++;
277             });
278             assert.equal(requests.length, 1);
279             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
280
281             requests[0].reject(404);
282
283             waitForMeasurementSet().then(function () {
284                 assert.equal(callCount, 0);
285                 assert.equal(requests.length, 2);
286                 assert.equal(requests[1].url, '../api/measurement-set?platform=1&metric=1');
287                 done();
288             }).catch(function (error) {
289                 done(error);
290             });
291         });
292
293         it('should not request the primary cluster twice when multiple clients request it but should invoke all callbacks', function (done) {
294             var set = MeasurementSet.findSet(1, 1, 3000);
295             var callCount = 0;
296             set.fetchBetween(2000, 3000, function () {
297                 callCount++;
298             });
299             assert.equal(requests.length, 1);
300             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
301
302             var alternativeCallCount = 0;
303             set.fetchBetween(2000, 3000, function () {
304                 alternativeCallCount++;
305             });
306
307             requests[0].resolve({
308                 'clusterStart': 1000,
309                 'clusterSize': 1000,
310                 'formatMap': [],
311                 'configurations': {current: []},
312                 'startTime': 2000,
313                 'endTime': 3000,
314                 'lastModified': 3000,
315                 'clusterCount': 2,
316                 'status': 'OK'});
317
318             waitForMeasurementSet().then(function () {
319                 assert.equal(callCount, 1);
320                 assert.equal(alternativeCallCount, 1);
321                 assert.equal(requests.length, 1);
322                 done();
323             }).catch(function (error) {
324                 done(error);
325             });
326         });
327
328         it('should invoke callback for each secondary clusters that are fetched or rejected', function (done) {
329             var set = MeasurementSet.findSet(1, 1, 5000);
330             var callCountFor4000 = 0;
331             set.fetchBetween(3200, 3700, function () { callCountFor4000++; });
332             assert.equal(requests.length, 1);
333             assert.equal(requests[0].url, '../data/measurement-set-1-1.json');
334
335             requests[0].resolve({
336                 'clusterStart': 1000,
337                 'clusterSize': 1000,
338                 'formatMap': [],
339                 'configurations': {current: []},
340                 'startTime': 4000,
341                 'endTime': 5000,
342                 'lastModified': 5000,
343                 'clusterCount': 3,
344                 'status': 'OK'});
345
346             var callCountFor4000To5000 = 0;
347             var callCountFor2000 = 0;
348             var callCountFor2000To4000 = 0;
349             waitForMeasurementSet().then(function () {
350                 assert.equal(callCountFor4000, 0);
351                 assert.equal(requests.length, 2);
352                 assert.equal(requests[1].url, '../data/measurement-set-1-1-4000.json');
353
354                 set.fetchBetween(3708, 4800, function () { callCountFor4000To5000++; });
355                 return waitForMeasurementSet();
356             }).then(function () {
357                 assert.equal(callCountFor4000To5000, 1);
358                 assert.equal(requests.length, 2);
359
360                 set.fetchBetween(1207, 1293, function () { callCountFor2000++; });
361                 return waitForMeasurementSet();
362             }).then(function () {
363                 assert.equal(callCountFor2000, 0);
364                 assert.equal(requests.length, 3);
365                 assert.equal(requests[2].url, '../data/measurement-set-1-1-2000.json');
366
367                 requests[2].resolve({
368                     'formatMap': [],
369                     'configurations': {current: []},
370                     'startTime': 1000,
371                     'endTime': 2000,
372                     'lastModified': 5000,
373                     'status': 'OK'});
374                 return waitForMeasurementSet();
375             }).then(function () {
376                 assert.equal(requests.length, 3);
377                 assert.equal(callCountFor4000, 0);
378                 assert.equal(callCountFor4000To5000, 1);
379                 assert.equal(callCountFor2000, 1);
380
381                 set.fetchBetween(1964, 3401, function () { callCountFor2000To4000++; });
382                 return waitForMeasurementSet();
383             }).then(function () {
384                 assert.equal(callCountFor2000To4000, 1);
385                 assert.equal(requests.length, 4);
386                 assert.equal(requests[3].url, '../data/measurement-set-1-1-3000.json');
387
388                 requests[3].resolve({
389                     'formatMap': [],
390                     'configurations': {current: []},
391                     'startTime': 2000,
392                     'endTime': 3000,
393                     'lastModified': 5000,
394                     'status': 'OK'});
395                 return waitForMeasurementSet();
396             }).then(function () {
397                 assert.equal(callCountFor4000, 0);
398                 assert.equal(callCountFor4000To5000, 1);
399                 assert.equal(callCountFor2000, 1);
400                 assert.equal(callCountFor2000To4000, 2);
401                 assert.equal(requests.length, 4);
402
403                 requests[1].resolve({
404                     'formatMap': [],
405                     'configurations': {current: []},
406                     'startTime': 3000,
407                     'endTime': 4000,
408                     'lastModified': 5000,
409                     'status': 'OK'});
410                 return waitForMeasurementSet();
411             }).then(function () {
412                 assert.equal(callCountFor4000, 1);
413                 assert.equal(callCountFor4000To5000, 2);
414                 assert.equal(callCountFor2000, 1);
415                 assert.equal(callCountFor2000To4000, 3);
416                 assert.equal(requests.length, 4);
417
418                 done();
419             }).catch(function (error) {
420                 done(error);
421             })
422         });
423
424     });
425
426 });