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