REGRESSION(r230960): Browser tests under TimeSeriesChart fetchMeasurementSets all...
[WebKit-https.git] / Websites / perf.webkit.org / unit-tests / commit-set-range-bisector-tests.js
1 'use strict';
2
3 const assert = require('assert');
4
5 require('../tools/js/v3-models.js');
6 const BrowserPrivilegedAPI = require('../public/v3/privileged-api.js').PrivilegedAPI;
7 const MockModels = require('./resources/mock-v3-models.js').MockModels;
8 const MockRemoteAPI = require('./resources/mock-remote-api.js').MockRemoteAPI;
9
10 describe('CommitSetRangeBisector', () => {
11
12     function makeCommit(id, repository, revision, time, order)
13     {
14         return CommitLog.ensureSingleton(id, {
15             repository,
16             revision,
17             ownsCommits: false,
18             time,
19             order
20         });
21     }
22
23     function sortedCommitSets()
24     {
25         return [
26             CommitSet.ensureSingleton(1, {
27                 revisionItems: [
28                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
29                     { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false }
30                 ],
31                 customRoots: []}),
32             CommitSet.ensureSingleton(2, {
33                 revisionItems: [
34                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
35                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }
36                 ],
37                 customRoots: []}),
38             CommitSet.ensureSingleton(3, {
39                 revisionItems: [
40                     { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false },
41                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }
42                 ],
43                 customRoots: []}),
44             CommitSet.ensureSingleton(4, {
45                 revisionItems: [
46                     { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false },
47                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }
48                 ],
49                 customRoots: []}),
50             CommitSet.ensureSingleton(5, {
51                 revisionItems: [
52                     { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false },
53                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }
54                 ],
55                 customRoots: []}),
56         ];
57     }
58
59     function sortedCommitSetsWithoutTimeOrOrder()
60     {
61         return [
62             CommitSet.ensureSingleton(6, {
63                 revisionItems: [
64                     { commit: makeCommit(101, MockModels.webkit, 'webkit-commit-101', 0), requiresBuild: false },
65                     { commit: makeCommit(111, MockModels.osx, 'osx-commit-111', 0), requiresBuild: false }
66                 ],
67                 customRoots: []}),
68             CommitSet.ensureSingleton(7, {
69                 revisionItems: [
70                     { commit: makeCommit(101, MockModels.webkit, 'webkit-commit-101', 0), requiresBuild: false },
71                     { commit: makeCommit(112, MockModels.osx, 'osx-commit-112', 0), requiresBuild: false }
72                 ],
73                 customRoots: []}),
74             CommitSet.ensureSingleton(8, {
75                 revisionItems: [
76                     { commit: makeCommit(102, MockModels.webkit, 'webkit-commit-102', 0), requiresBuild: false },
77                     { commit: makeCommit(112, MockModels.osx, 'osx-commit-112', 0), requiresBuild: false }
78                 ],
79                 customRoots: []}),
80             CommitSet.ensureSingleton(9, {
81                 revisionItems: [
82                     { commit: makeCommit(103, MockModels.webkit, 'webkit-commit-103', 0), requiresBuild: false },
83                     { commit: makeCommit(113, MockModels.osx, 'osx-commit-113', 0), requiresBuild: false }
84                 ],
85                 customRoots: []}),
86             CommitSet.ensureSingleton(10, {
87                 revisionItems: [
88                     { commit: makeCommit(106, MockModels.webkit, 'webkit-commit-106', 0), requiresBuild: false },
89                     { commit: makeCommit(113, MockModels.osx, 'osx-commit-113', 0), requiresBuild: false }
90                 ],
91                 customRoots: []}),
92         ];
93     }
94
95     function commitSetsWithSomeCommitsOnlyHaveOrder()
96     {
97         return [
98             CommitSet.ensureSingleton(11, {
99                 revisionItems: [
100                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
101                     { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false },
102                     { commit: makeCommit(201, MockModels.ownerRepository, 'owner-commit-1', 0, 1), requiresBuild: false }
103                 ],
104                 customRoots: []}),
105             CommitSet.ensureSingleton(12, {
106                 revisionItems: [
107                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
108                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false },
109                     { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false }
110                 ],
111                 customRoots: []}),
112             CommitSet.ensureSingleton(13, {
113                 revisionItems: [
114                     { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false },
115                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false },
116                     { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false }
117                 ],
118                 customRoots: []}),
119             CommitSet.ensureSingleton(14, {
120                 revisionItems: [
121                     { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false },
122                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false },
123                     { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false }
124                 ],
125                 customRoots: []}),
126             CommitSet.ensureSingleton(15, {
127                 revisionItems: [
128                     { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false },
129                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false },
130                     { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false }
131                 ],
132                 customRoots: []}),
133             CommitSet.ensureSingleton(16, {
134                 revisionItems: [
135                     { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false },
136                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false },
137                     { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false }
138                 ],
139                 customRoots: []}),
140         ];
141     }
142
143     function commitSetsWithSomeHaveOwnedCommits()
144     {
145         return [
146             CommitSet.ensureSingleton(11, {
147                 revisionItems: [
148                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
149                     { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false },
150                     { commit: makeCommit(201, MockModels.ownerRepository, 'owner-commit-1', 0, 1), requiresBuild: false },
151                 ],
152                 customRoots: []}),
153             CommitSet.ensureSingleton(12, {
154                 revisionItems: [
155                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
156                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false },
157                     { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false }
158                 ],
159                 customRoots: []}),
160             CommitSet.ensureSingleton(13, {
161                 revisionItems: [
162                     { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false },
163                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false },
164                     { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false }
165                 ],
166                 customRoots: []}),
167             CommitSet.ensureSingleton(14, {
168                 revisionItems: [
169                     { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false },
170                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false },
171                     { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false },
172                     { commit: makeCommit(302, MockModels.ownedRepository, 'owned-commit-2', 0, 2), requiresBuild: false }
173                 ],
174                 customRoots: []}),
175             CommitSet.ensureSingleton(15, {
176                 revisionItems: [
177                     { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false },
178                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false },
179                     { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false }
180                 ],
181                 customRoots: []}),
182             CommitSet.ensureSingleton(16, {
183                 revisionItems: [
184                     { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false },
185                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false },
186                     { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false }
187                 ],
188                 customRoots: []}),
189         ];
190     }
191
192     function commitSetsWithSomeCommitsNotMonotonicallyIncrease()
193     {
194         return [
195             CommitSet.ensureSingleton(17, {
196                 revisionItems: [
197                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
198                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 0, 2), requiresBuild: false }
199                 ],
200                 customRoots: []}),
201             CommitSet.ensureSingleton(18, {
202                 revisionItems: [
203                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false },
204                     { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 0, 1), requiresBuild: false }
205                 ],
206                 customRoots: []}),
207             CommitSet.ensureSingleton(19, {
208                 revisionItems: [
209                     { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false },
210                     { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 0, 1), requiresBuild: false }
211                 ],
212                 customRoots: []}),
213             CommitSet.ensureSingleton(20, {
214                 revisionItems: [
215                     { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false },
216                     { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 0, 2), requiresBuild: false }
217                 ],
218                 customRoots: []}),
219             CommitSet.ensureSingleton(21, {
220                 revisionItems: [
221                     { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false },
222                     { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 0, 3), requiresBuild: false }
223                 ],
224                 customRoots: []}),
225             CommitSet.ensureSingleton(22, {
226                 revisionItems: [
227                     { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false },
228                     { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 0, 1), requiresBuild: false }
229                 ],
230                 customRoots: []}),
231         ];
232     }
233
234     function createRoot()
235     {
236         return UploadedFile.ensureSingleton(456, {'createdAt': new Date('2017-05-01T21:03:27Z'), 'filename': 'root.dat', 'extension': '.dat', 'author': 'some user',
237             size: 16452234, sha256: '03eed7a8494ab8794c44b7d4308e55448fc56f4d6c175809ba968f78f656d58d'});
238     }
239
240     function commitSetWithRoot()
241     {
242         return CommitSet.ensureSingleton(15, {
243             revisionItems: [{ commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false }],
244             customRoots: [createRoot()]
245         });
246     }
247
248     function commitSet()
249     {
250         return CommitSet.ensureSingleton(16, {
251             revisionItems: [{ commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false }],
252             customRoots: []
253         });
254     }
255
256     function commitSetsWithNoCommonRepository() {
257         return [
258             CommitSet.ensureSingleton(1, {
259                 revisionItems: [
260                     { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false },
261                     { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false }
262                 ],
263                 customRoots: []}),
264             CommitSet.ensureSingleton(2, {
265                 revisionItems: [
266                     { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false },
267                     { commit: makeCommit(31, MockModels.ios, 'ios-commit-1', 1), requiresBuild: false },
268                 ],
269                 customRoots: []})
270         ];
271     }
272
273     describe('commitSetClosestToMiddleOfAllCommits', () => {
274         MockModels.inject();
275         const requests = MockRemoteAPI.inject(null, BrowserPrivilegedAPI);
276
277         it('should return "null" if no common repository found', async () => {
278             const middleCommitSet = await CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits(commitSetsWithNoCommonRepository().splice(0, 2));
279             assert.equal(middleCommitSet, null);
280         });
281
282         it('should return "null" to bisect commit set with root', async () => {
283             const middleCommitSet = await CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([commitSet(), commitSetWithRoot()], [commitSet(), commitSetWithRoot()]);
284             assert.equal(middleCommitSet, null);
285         });
286
287         it('should return "null" if no repository with time or order is found', async () => {
288             const allCommitSets = sortedCommitSetsWithoutTimeOrOrder();
289             const startCommitSet = allCommitSets[0];
290             const endCommitSet = allCommitSets[allCommitSets.length - 1];
291             const middleCommitSet = await CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets);
292             assert.equal(middleCommitSet, null);
293         });
294
295         it('should throw exception when failed to fetch commit log', async () => {
296             const allCommitSets = sortedCommitSets();
297             const startCommitSet = allCommitSets[0];
298             const endCommitSet = allCommitSets[allCommitSets.length - 1];
299             const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets);
300             const rejectReason = '404';
301             requests[0].reject(rejectReason);
302             let exceptionRaised = false;
303             try {
304                 await promise;
305             } catch (error) {
306                 exceptionRaised = true;
307                 assert.equal(error, rejectReason);
308             }
309             assert.ok(exceptionRaised);
310         });
311
312         it('should return "null" if no commit set is found other than the commit sets that define the range', async () => {
313             const allCommitSets = sortedCommitSets();
314             const startCommitSet = allCommitSets[0];
315             const endCommitSet = allCommitSets[allCommitSets.length - 1];
316             const webkitId = MockModels.webkit.id();
317             const osxId = MockModels.osx.id();
318             const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], [startCommitSet, endCommitSet]);
319             assert.equal(requests.length, 2);
320             assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3');
321             assert.equal(requests[1].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6');
322             requests[0].resolve({
323                 'commits': [
324                     {
325                         repository: osxId,
326                         id: 12,
327                         revision: 'osx-commit-2',
328                         ownsCommits: false,
329                         time: 21
330                     },
331                     {
332                         repository: osxId,
333                         id: 13,
334                         revision: 'osx-commit-3',
335                         ownsCommits: false,
336                         time: 31
337                     }
338                 ]
339             });
340             requests[1].resolve({
341                 'commits': [
342                     {
343                         repository: webkitId,
344                         id: 2,
345                         revision: 'webkit-commit-2',
346                         ownsCommits: false,
347                         time: 20
348                     },
349                     {
350                         repository: webkitId,
351                         id: 3,
352                         revision: 'webkit-commit-3',
353                         ownsCommits: false,
354                         time: 30
355                     },
356                     {
357                         repository: webkitId,
358                         id: 4,
359                         revision: 'webkit-commit-4',
360                         ownsCommits: false,
361                         time: 40
362                     },
363                     {
364                         repository: webkitId,
365                         id: 5,
366                         revision: 'webkit-commit-5',
367                         ownsCommits: false,
368                         time: 50
369                     },
370                     {
371                         repository: webkitId,
372                         id: 6,
373                         revision: 'webkit-commit-6',
374                         ownsCommits: false,
375                         time: 60
376                     },
377                 ]
378             });
379
380             assert.equal(await promise, null);
381         });
382
383         it('should return bisecting commit set point closest to the middle of revision range', async () => {
384             const allCommitSets = sortedCommitSets();
385             const startCommitSet = allCommitSets[0];
386             const endCommitSet = allCommitSets[allCommitSets.length - 1];
387             const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets);
388             assert.equal(requests.length, 2);
389             const osxFetchRequest = requests.find((fetch_request) => fetch_request.url === '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3');
390             const webkitFetchRequest = requests.find((fetch_request) => fetch_request.url === '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6');
391             const webkitId = MockModels.webkit.id();
392             const osxId = MockModels.osx.id();
393             webkitFetchRequest.resolve({
394                 'commits': [
395                     {
396                         repository: webkitId,
397                         id: 2,
398                         revision: 'webkit-commit-2',
399                         ownsCommits: false,
400                         time: 20
401                     },
402                     {
403                         repository: webkitId,
404                         id: 3,
405                         revision: 'webkit-commit-3',
406                         ownsCommits: false,
407                         time: 30
408                     },
409                     {
410                         repository: webkitId,
411                         id: 4,
412                         revision: 'webkit-commit-4',
413                         ownsCommits: false,
414                         time: 40
415                     },
416                     {
417                         repository: webkitId,
418                         id: 5,
419                         revision: 'webkit-commit-5',
420                         ownsCommits: false,
421                         time: 50
422                     },
423                     {
424                         repository: webkitId,
425                         id: 6,
426                         revision: 'webkit-commit-6',
427                         ownsCommits: false,
428                         time: 60
429                     },
430                 ]
431             });
432             osxFetchRequest.resolve({
433                 'commits': [
434                     {
435                         repository: osxId,
436                         id: 12,
437                         revision: 'osx-commit-2',
438                         ownsCommits: false,
439                         time: 21
440                     },
441                     {
442                         repository: osxId,
443                         id: 13,
444                         revision: 'osx-commit-3',
445                         ownsCommits: false,
446                         time: 31
447                     }
448                 ]
449             });
450
451             assert.equal(await promise, allCommitSets[3]);
452         });
453
454         it('should return same bisection point even when two commit sets from original commit set have reverse order', async () => {
455             const allCommitSets = sortedCommitSets();
456             const startCommitSet = allCommitSets[0];
457             const endCommitSet = allCommitSets[allCommitSets.length - 1];
458             const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([endCommitSet, startCommitSet], allCommitSets);
459             const webkitId = MockModels.webkit.id();
460             const osxId = MockModels.osx.id();
461             requests[0].resolve({
462                 'commits': [
463                     {
464                         repository: webkitId,
465                         id: 2,
466                         revision: 'webkit-commit-2',
467                         ownsCommits: false,
468                         time: 20
469                     },
470                     {
471                         repository: webkitId,
472                         id: 3,
473                         revision: 'webkit-commit-3',
474                         ownsCommits: false,
475                         time: 30
476                     },
477                     {
478                         repository: webkitId,
479                         id: 4,
480                         revision: 'webkit-commit-4',
481                         ownsCommits: false,
482                         time: 40
483                     },
484                     {
485                         repository: webkitId,
486                         id: 5,
487                         revision: 'webkit-commit-5',
488                         ownsCommits: false,
489                         time: 50
490                     },
491                     {
492                         repository: webkitId,
493                         id: 6,
494                         revision: 'webkit-commit-6',
495                         ownsCommits: false,
496                         time: 60
497                     },
498                 ]
499             });
500             requests[1].resolve({
501                 'commits': [
502                     {
503                         repository: osxId,
504                         id: 12,
505                         revision: 'osx-commit-2',
506                         ownsCommits: false,
507                         time: 21
508                     },
509                     {
510                         repository: osxId,
511                         id: 13,
512                         revision: 'osx-commit-3',
513                         ownsCommits: false,
514                         time: 31
515                     }
516                 ]
517             });
518
519             assert.equal(await promise, allCommitSets[3]);
520         });
521
522         it('should use commits with order as fallback when multiple commit sets found for the commit that is closest to the middle of commits with time', async () => {
523             const allCommitSets = commitSetsWithSomeCommitsOnlyHaveOrder();
524             const startCommitSet = allCommitSets[0];
525             const endCommitSet = allCommitSets[allCommitSets.length - 1];
526             const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets);
527             const webkitId = MockModels.webkit.id();
528             const osxId = MockModels.osx.id();
529             const ownerRepositoryId = MockModels.ownerRepository.id();
530
531             assert.equal(requests.length, 3);
532             assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3');
533             assert.equal(requests[1].url, '/api/commits/111/?precedingRevision=owner-commit-1&lastRevision=owner-commit-3');
534             assert.equal(requests[2].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6');
535
536             requests[0].resolve({
537                 'commits': [
538                     {
539                         repository: osxId,
540                         id: 12,
541                         revision: 'osx-commit-2',
542                         ownsCommits: false,
543                         time: 21
544                     },
545                     {
546                         repository: osxId,
547                         id: 13,
548                         revision: 'osx-commit-3',
549                         ownsCommits: false,
550                         time: 31
551                     }
552                 ]
553             });
554
555             requests[1].resolve({
556                 'commits': [
557                     {
558                         repository: ownerRepositoryId,
559                         id: 202,
560                         revision: 'owner-commit-2',
561                         ownsCommits: false,
562                         time: 0,
563                         order: 2
564                     },
565                     {
566                         repository: ownerRepositoryId,
567                         id: 203,
568                         revision: 'owner-commit-3',
569                         ownsCommits: false,
570                         time: 0,
571                         order: 3
572                     }
573                 ]
574             });
575
576             requests[2].resolve({
577                 'commits': [
578                     {
579                         repository: webkitId,
580                         id: 2,
581                         revision: 'webkit-commit-2',
582                         ownsCommits: false,
583                         time: 20
584                     },
585                     {
586                         repository: webkitId,
587                         id: 3,
588                         revision: 'webkit-commit-3',
589                         ownsCommits: false,
590                         time: 30
591                     },
592                     {
593                         repository: webkitId,
594                         id: 4,
595                         revision: 'webkit-commit-4',
596                         ownsCommits: false,
597                         time: 40
598                     },
599                     {
600                         repository: webkitId,
601                         id: 5,
602                         revision: 'webkit-commit-5',
603                         ownsCommits: false,
604                         time: 50
605                     },
606                     {
607                         repository: webkitId,
608                         id: 6,
609                         revision: 'webkit-commit-6',
610                         ownsCommits: false,
611                         time: 60
612                     },
613                 ]
614             });
615             assert.equal(await promise, allCommitSets[3]);
616         });
617
618         it('should filter out commit set with owned commit', async () => {
619             const allCommitSets = commitSetsWithSomeHaveOwnedCommits();
620             const startCommitSet = allCommitSets[0];
621             const endCommitSet = allCommitSets[allCommitSets.length - 1];
622             const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets);
623             const webkitId = MockModels.webkit.id();
624             const osxId = MockModels.osx.id();
625             const ownerRepositoryId = MockModels.ownerRepository.id();
626
627             assert.equal(requests.length, 3);
628             assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3');
629             assert.equal(requests[1].url, '/api/commits/111/?precedingRevision=owner-commit-1&lastRevision=owner-commit-3');
630             assert.equal(requests[2].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6');
631
632             requests[0].resolve({
633                 'commits': [
634                     {
635                         repository: osxId,
636                         id: 12,
637                         revision: 'osx-commit-2',
638                         ownsCommits: false,
639                         time: 21
640                     },
641                     {
642                         repository: osxId,
643                         id: 13,
644                         revision: 'osx-commit-3',
645                         ownsCommits: false,
646                         time: 31
647                     }
648                 ]
649             });
650
651             requests[1].resolve({
652                 'commits': [
653                     {
654                         repository: ownerRepositoryId,
655                         id: 202,
656                         revision: 'owner-commit-2',
657                         ownsCommits: true,
658                         time: 0,
659                         order: 2
660                     },
661                     {
662                         repository: ownerRepositoryId,
663                         id: 203,
664                         revision: 'owner-commit-3',
665                         ownsCommits: true,
666                         time: 0,
667                         order: 3
668                     }
669                 ]
670             });
671
672             requests[2].resolve({
673                 'commits': [
674                     {
675                         repository: webkitId,
676                         id: 2,
677                         revision: 'webkit-commit-2',
678                         ownsCommits: false,
679                         time: 20
680                     },
681                     {
682                         repository: webkitId,
683                         id: 3,
684                         revision: 'webkit-commit-3',
685                         ownsCommits: false,
686                         time: 30
687                     },
688                     {
689                         repository: webkitId,
690                         id: 4,
691                         revision: 'webkit-commit-4',
692                         ownsCommits: false,
693                         time: 40
694                     },
695                     {
696                         repository: webkitId,
697                         id: 5,
698                         revision: 'webkit-commit-5',
699                         ownsCommits: false,
700                         time: 50
701                     },
702                     {
703                         repository: webkitId,
704                         id: 6,
705                         revision: 'webkit-commit-6',
706                         ownsCommits: false,
707                         time: 60
708                     },
709                 ]
710             });
711             assert.equal(await promise, allCommitSets[4]);
712         });
713
714         it('should still work even some commits do not monotonically increasing', async () => {
715             const allCommitSets = commitSetsWithSomeCommitsNotMonotonicallyIncrease();
716             const startCommitSet = allCommitSets[0];
717             const endCommitSet = allCommitSets[allCommitSets.length - 1];
718             const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets);
719             const webkitId = MockModels.webkit.id();
720             const osxId = MockModels.osx.id();
721
722             assert.equal(requests.length, 2);
723             assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-2');
724             assert.equal(requests[1].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6');
725
726             requests[0].resolve({
727                 'commits': [
728                     {
729                         repository: osxId,
730                         id: 12,
731                         revision: 'osx-commit-2',
732                         ownsCommits: false,
733                         time: 0,
734                         order: 2
735                     }
736                 ]
737             });
738             requests[1].resolve({
739                 'commits': [
740                     {
741                         repository: webkitId,
742                         id: 2,
743                         revision: 'webkit-commit-2',
744                         ownsCommits: false,
745                         time: 20
746                     },
747                     {
748                         repository: webkitId,
749                         id: 3,
750                         revision: 'webkit-commit-3',
751                         ownsCommits: false,
752                         time: 30
753                     },
754                     {
755                         repository: webkitId,
756                         id: 4,
757                         revision: 'webkit-commit-4',
758                         ownsCommits: false,
759                         time: 40
760                     },
761                     {
762                         repository: webkitId,
763                         id: 5,
764                         revision: 'webkit-commit-5',
765                         ownsCommits: false,
766                         time: 50
767                     },
768                     {
769                         repository: webkitId,
770                         id: 6,
771                         revision: 'webkit-commit-6',
772                         ownsCommits: false,
773                         time: 60
774                     },
775                 ]
776             });
777
778             assert.equal(await promise, allCommitSets[3]);
779         });
780     });
781 });