Add support for builderNameToIDMap in BuildbotSyncer
[WebKit-https.git] / Websites / perf.webkit.org / server-tests / tools-sync-buildbot-integration-tests.js
1 'use strict';
2
3 const assert = require('assert');
4
5 require('../tools/js/v3-models.js');
6
7 const BuildbotTriggerable = require('../tools/js/buildbot-triggerable.js').BuildbotTriggerable;
8 const MockData = require('./resources/mock-data.js');
9 const MockLogger = require('./resources/mock-logger.js').MockLogger;
10 const MockRemoteAPI = require('../unit-tests/resources/mock-remote-api.js').MockRemoteAPI;
11 const TestServer = require('./resources/test-server.js');
12 const TemporaryFile = require('./resources/temporary-file.js').TemporaryFile;
13 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
14 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
15
16 const configWithOneTesterTwoBuilders = {
17     triggerableName: 'build-webkit',
18     lookbackCount: 2,
19     buildRequestArgument: 'build-request-id',
20     slaveName: 'sync-slave',
21     slavePassword: 'password',
22     repositoryGroups: {
23         'webkit': {
24             repositories: {'WebKit': {acceptsPatch: true}},
25             testProperties: {'wk': {'revision': 'WebKit'}, 'roots': {'roots': {}}},
26             buildProperties: {'wk': {'revision': 'WebKit'}, 'wk-patch': {'patch': 'WebKit'},
27                 'checkbox': {'ifRepositorySet': ['WebKit'], 'value': 'build-wk'},
28                 'owned-commits': {'ownedRevisions': 'WebKit'}},
29             acceptsRoots: true,
30         }
31     },
32     types: {
33         'some': {
34             test: ['some test'],
35             properties: {'test': 'some-test'},
36         }
37     },
38     builders: {
39         'builder-1': {
40             builder: 'some tester',
41             properties: {forcescheduler: 'force-ab-tests'},
42         },
43         'builder-2': {
44             builder: 'some builder',
45             properties: {forcescheduler: 'force-ab-builds'},
46         },
47         'builder-3': {
48             builder: 'other builder',
49             properties: {forcescheduler: 'force-ab-builds'},
50         },
51     },
52     buildConfigurations: [
53         {platforms: ['some platform'], builders: ['builder-2', 'builder-3']},
54     ],
55     testConfigurations: [
56         {types: ['some'], platforms: ['some platform'], builders: ['builder-1']},
57     ],
58 };
59
60 const configWithPlatformName = {
61     triggerableName: 'build-webkit',
62     lookbackCount: 2,
63     buildRequestArgument: 'build-request-id',
64     slaveName: 'sync-slave',
65     slavePassword: 'password',
66     platformArgument: 'platform-name',
67     repositoryGroups: {
68         'webkit': {
69             repositories: {'WebKit': {acceptsPatch: true}},
70             testProperties: {'wk': {'revision': 'WebKit'}, 'roots': {'roots': {}}},
71             buildProperties: {'wk': {'revision': 'WebKit'}, 'wk-patch': {'patch': 'WebKit'},
72                 'checkbox': {'ifRepositorySet': ['WebKit'], 'value': 'build-wk'},
73                 'owned-commits': {'ownedRevisions': 'WebKit'}},
74             acceptsRoots: true,
75         }
76     },
77     types: {
78         'some': {
79             test: ['some test'],
80             properties: {'test': 'some-test'},
81         }
82     },
83     builders: {
84         'builder-1': {
85             builder: 'some tester',
86             properties: {forcescheduler: 'force-ab-tests'},
87         },
88         'builder-2': {
89             builder: 'some builder',
90             properties: {forcescheduler: 'force-ab-builds'},
91         },
92         'builder-3': {
93             builder: 'other builder',
94             properties: {forcescheduler: 'force-ab-builds'},
95         },
96     },
97     buildConfigurations: [
98         {platforms: ['some platform'], builders: ['builder-2', 'builder-3']},
99     ],
100     testConfigurations: [
101         {types: ['some'], platforms: ['some platform'], builders: ['builder-1']},
102     ],
103 };
104
105 const configWithTwoTesters = {
106     triggerableName: 'build-webkit',
107     lookbackCount: 2,
108     buildRequestArgument: 'build-request-id',
109     slaveName: 'sync-slave',
110     slavePassword: 'password',
111     repositoryGroups: {
112         'webkit': {
113             repositories: {'WebKit': {acceptsPatch: true}},
114             testProperties: {'wk': {'revision': 'WebKit'}, 'roots': {'roots': {}}},
115             buildProperties: {'wk': {'revision': 'WebKit'}, 'wk-patch': {'patch': 'WebKit'},
116                 'checkbox': {'ifRepositorySet': ['WebKit'], 'value': 'build-wk'},
117                 'owned-commits': {'ownedRevisions': 'WebKit'}},
118             acceptsRoots: true,
119         }
120     },
121     types: {
122         'some': {
123             test: ['some test'],
124             properties: {'test': 'some-test'},
125         }
126     },
127     builders: {
128         'builder-1': {
129             builder: 'some tester',
130             properties: {forcescheduler: 'force-ab-tests'},
131         },
132         'builder-2': {
133             builder: 'another tester',
134             properties: {forcescheduler: 'force-ab-builds'},
135         },
136     },
137     testConfigurations: [
138         {types: ['some'], platforms: ['some platform'], builders: ['builder-1', 'builder-2']},
139     ]
140 };
141
142 function assertAndResolveRequest(request, method, url, contentToResolve)
143 {
144     assert.equal(request.method, method);
145     assert.equal(request.url, url);
146     request.resolve(contentToResolve);
147 }
148
149 function createTriggerable(config = configWithOneTesterTwoBuilders)
150 {
151     let triggerable;
152     return MockData.addMockConfiguration(TestServer.database()).then(() => {
153         return Manifest.fetch();
154     }).then(() => {
155         triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, {name: 'sync-slave', password: 'password'}, new MockLogger);
156         const syncPromise = triggerable.initSyncers().then(() => triggerable.updateTriggerable());
157         assertAndResolveRequest(MockRemoteAPI.requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
158         MockRemoteAPI.reset();
159         return syncPromise;
160     }).then(() => Manifest.fetch()).then(() => {
161         return new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, {name: 'sync-slave', password: 'password'}, new MockLogger);
162     });
163 }
164
165 function createTestGroup(task_name='custom task') {
166     const someTest = Test.findById(MockData.someTestId());
167     const webkit = Repository.findById(MockData.webkitRepositoryId());
168     const set1 = new CustomCommitSet;
169     set1.setRevisionForRepository(webkit, '191622');
170     const set2 = new CustomCommitSet;
171     set2.setRevisionForRepository(webkit, '192736');
172     return TestGroup.createWithTask('custom task', Platform.findById(MockData.somePlatformId()), someTest, 'some group', 2, [set1, set2]).then((task) => {
173         return TestGroup.findAllByTask(task.id())[0];
174     });
175 }
176
177 function createTestGroupWihPatch()
178 {
179     return TemporaryFile.makeTemporaryFile('patch.dat', 'patch file').then((patchFile) => {
180         return UploadedFile.uploadFile(patchFile);
181     }).then((patchFile) => {
182         const someTest = Test.findById(MockData.someTestId());
183         const webkit = Repository.findById(MockData.webkitRepositoryId());
184         const set1 = new CustomCommitSet;
185         set1.setRevisionForRepository(webkit, '191622', patchFile);
186         const set2 = new CustomCommitSet;
187         set2.setRevisionForRepository(webkit, '191622');
188         return TestGroup.createWithTask('custom task', Platform.findById(MockData.somePlatformId()), someTest, 'some group', 2, [set1, set2]);
189     }).then((task) => {
190         return TestGroup.findAllByTask(task.id())[0];
191     })
192 }
193
194 function createTestGroupWihOwnedCommit()
195 {
196     const someTest = Test.findById(MockData.someTestId());
197     const webkit = Repository.findById(MockData.webkitRepositoryId());
198     const ownedSJC = Repository.findById(MockData.ownedJSCRepositoryId());
199     const set1 = new CustomCommitSet;
200     set1.setRevisionForRepository(webkit, '191622');
201     set1.setRevisionForRepository(ownedSJC, 'owned-jsc-6161', null, '191622');
202     const set2 = new CustomCommitSet;
203     set2.setRevisionForRepository(webkit, '192736');
204     set2.setRevisionForRepository(ownedSJC, 'owned-jsc-9191', null, '192736');
205     return TestGroup.createWithTask('custom task', Platform.findById(MockData.somePlatformId()), someTest, 'some group', 2, [set1, set2]).then((task) => {
206         return TestGroup.findAllByTask(task.id())[0];
207     });
208 }
209
210 function uploadRoot(buildRequestId, buildNumber, repositoryList = ["WebKit"], buildTime = '2017-05-10T02:54:08.666')
211 {
212     return TemporaryFile.makeTemporaryFile(`root${buildNumber}.dat`, `root for build ${buildNumber} and repository list at ${buildTime}`).then((rootFile) => {
213         return TestServer.remoteAPI().postFormData('/api/upload-root/', {
214             slaveName: 'sync-slave',
215             slavePassword: 'password',
216             builderName: 'some builder',
217             buildNumber: buildNumber,
218             buildTime: buildTime,
219             buildRequest: buildRequestId,
220             rootFile,
221             repositoryList: JSON.stringify(repositoryList),
222         });
223     });
224 }
225
226 describe('sync-buildbot', function () {
227     prepareServerTest(this);
228     TemporaryFile.inject();
229
230     beforeEach(() => {
231         MockRemoteAPI.reset('http://build.webkit.org');
232     });
233
234
235     it('should not schedule on another builder if the build was scheduled on one builder before', () => {
236         const requests = MockRemoteAPI.requests;
237         let firstTestGroup;
238         let secondTestGroup;
239         let syncPromise;
240         let triggerable;
241         let taskId = null;
242         let anotherTaskId = null;
243         return createTriggerable(configWithTwoTesters).then((newTriggerable) => {
244             triggerable = newTriggerable;
245             return Promise.all([createTestGroup(), createTestGroup('another custom task')]);
246         }).then((testGroups) => {
247             firstTestGroup = testGroups[0];
248             secondTestGroup = testGroups[1];
249             taskId = firstTestGroup.task().id();
250             anotherTaskId = secondTestGroup.task().id();
251             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
252             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
253             MockRemoteAPI.reset();
254             return MockRemoteAPI.waitForRequest();
255         }).then(() => {
256             assert.equal(requests.length, 2);
257             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', [MockData.pendingBuild({builder: 'some tester', buildRequestId: 5})]);
258             assertAndResolveRequest(requests[1], 'GET', '/json/builders/another%20tester/pendingBuilds', []);
259             return MockRemoteAPI.waitForRequest();
260         }).then(() => {
261             assert.equal(requests.length, 4);
262             assertAndResolveRequest(requests[2], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {
263                 [-1]: MockData.runningBuild({builder: 'some tester', buildRequestId: 1})});
264             assertAndResolveRequest(requests[3], 'GET', '/json/builders/another%20tester/builds/?select=-1&select=-2', {});
265             return MockRemoteAPI.waitForRequest();
266         }).then(() => {
267             assert.equal(requests.length, 6);
268             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
269             assertAndResolveRequest(requests[5], 'GET', '/json/builders/another%20tester/pendingBuilds',[]);
270             return MockRemoteAPI.waitForRequest();
271         }).then(() => {
272             assert.equal(requests.length, 8);
273             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {
274                 [-1]: MockData.runningBuild({builder: 'some tester', buildRequestId: 5}),
275                 [-2]: MockData.finishedBuild({builder: 'some tester', buildRequestId: 1})
276             });
277             assertAndResolveRequest(requests[7], 'GET', '/json/builders/another%20tester/builds/?select=-1&select=-2', {});
278             return syncPromise;
279         }).then(() => {
280             return TestGroup.fetchForTask(taskId, true);
281         }).then((testGroups) => {
282             assert.equal(testGroups.length, 1);
283             const testGroup = testGroups[0];
284             const webkit = Repository.findById(MockData.webkitRepositoryId());
285
286             const buildRequest = testGroup.buildRequests()[0];
287             assert.equal(testGroup.buildRequests().length, 4);
288             assert(!buildRequest.isBuild());
289             assert(buildRequest.isTest());
290
291             const commitSet = buildRequest.commitSet();
292             assert.equal(commitSet.revisionForRepository(webkit), '191622');
293
294             const otherBuildRequest = testGroup.buildRequests()[1];
295             assert(!otherBuildRequest.isBuild());
296             assert(otherBuildRequest.isTest());
297
298             const otherCommitSet = otherBuildRequest.commitSet();
299             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
300
301             return TestGroup.fetchForTask(anotherTaskId, true);
302         }).then((testGroups) => {
303             assert.equal(testGroups.length, 1);
304             const testGroup = testGroups[0];
305             const webkit = Repository.findById(MockData.webkitRepositoryId());
306
307             const buildRequest = testGroup.buildRequests()[0];
308             assert.equal(testGroup.buildRequests().length, 4);
309             assert(!buildRequest.isBuild());
310             assert(buildRequest.isTest());
311
312             const commitSet = buildRequest.commitSet();
313             assert.equal(commitSet.revisionForRepository(webkit), '191622');
314
315             const otherBuildRequest = testGroup.buildRequests()[1];
316             assert(!otherBuildRequest.isBuild());
317             assert(otherBuildRequest.isTest());
318
319             const otherCommitSet = otherBuildRequest.commitSet();
320             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
321         });
322     });
323
324     it('should schedule a build to build a patch', () => {
325         const requests = MockRemoteAPI.requests;
326         let triggerable;
327         let taskId = null;
328         let syncPromise;
329         return createTriggerable().then((newTriggerable) => {
330             triggerable = newTriggerable;
331             return createTestGroupWihPatch();
332         }).then((testGroup) => {
333             taskId = testGroup.task().id();
334             const webkit = Repository.findById(MockData.webkitRepositoryId());
335             assert.equal(testGroup.buildRequests().length, 6);
336
337             const buildRequest = testGroup.buildRequests()[0];
338             assert(buildRequest.isBuild());
339             assert(!buildRequest.isTest());
340             assert.equal(buildRequest.statusLabel(), 'Waiting');
341             assert.equal(buildRequest.statusUrl(), null);
342             assert.equal(buildRequest.buildId(), null);
343
344             const commitSet = buildRequest.commitSet();
345             assert.equal(commitSet.revisionForRepository(webkit), '191622');
346             const webkitPatch = commitSet.patchForRepository(webkit);
347             assert(webkitPatch instanceof UploadedFile);
348             assert.equal(webkitPatch.filename(), 'patch.dat');
349             assert.equal(commitSet.rootForRepository(webkit), null);
350             assert.deepEqual(commitSet.allRootFiles(), []);
351
352             const otherBuildRequest = testGroup.buildRequests()[1];
353             assert(otherBuildRequest.isBuild());
354             assert(!otherBuildRequest.isTest());
355             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
356             assert.equal(otherBuildRequest.statusUrl(), null);
357             assert.equal(otherBuildRequest.buildId(), null);
358
359             const otherCommitSet = otherBuildRequest.commitSet();
360             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
361             assert.equal(otherCommitSet.patchForRepository(webkit), null);
362             assert.equal(otherCommitSet.rootForRepository(webkit), null);
363             assert.deepEqual(otherCommitSet.allRootFiles(), []);
364
365             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
366             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
367             MockRemoteAPI.reset();
368             return MockRemoteAPI.waitForRequest();
369         }).then(() => {
370             assert.equal(requests.length, 3);
371             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
372             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
373             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
374             return MockRemoteAPI.waitForRequest();
375         }).then(() => {
376             assert.equal(requests.length, 6);
377             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
378             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
379             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
380             return MockRemoteAPI.waitForRequest();
381         }).then(() => {
382             assert.equal(requests.length, 7);
383             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
384             assert.deepEqual(requests[6].data, {'wk': '191622', 'wk-patch': RemoteAPI.url('/api/uploaded-file/1.dat'),
385                 'build-request-id': '1', 'forcescheduler': 'force-ab-builds', 'checkbox': 'build-wk'});
386             return MockRemoteAPI.waitForRequest();
387         }).then(() => {
388             assert.equal(requests.length, 10);
389             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
390             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
391                 [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
392             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
393             return MockRemoteAPI.waitForRequest();
394         }).then(() => {
395             assert.equal(requests.length, 13);
396             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
397             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
398                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
399             });
400             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
401             return syncPromise;
402         }).then(() => {
403             return TestGroup.fetchForTask(taskId, true);
404         }).then((testGroups) => {
405             assert.equal(testGroups.length, 1);
406             const testGroup = testGroups[0];
407             const webkit = Repository.findById(MockData.webkitRepositoryId());
408             assert.equal(testGroup.buildRequests().length, 6);
409
410             const buildRequest = testGroup.buildRequests()[0];
411             assert(buildRequest.isBuild());
412             assert(!buildRequest.isTest());
413             assert.equal(buildRequest.statusLabel(), 'Running');
414             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
415             assert.equal(buildRequest.buildId(), null);
416
417             const commitSet = buildRequest.commitSet();
418             assert.equal(commitSet.revisionForRepository(webkit), '191622');
419             const webkitPatch = commitSet.patchForRepository(webkit);
420             assert(webkitPatch instanceof UploadedFile);
421             assert.equal(webkitPatch.filename(), 'patch.dat');
422             assert.equal(commitSet.rootForRepository(webkit), null);
423             assert.deepEqual(commitSet.allRootFiles(), []);
424
425             const otherBuildRequest = testGroup.buildRequests()[1];
426             assert(otherBuildRequest.isBuild());
427             assert(!otherBuildRequest.isTest());
428             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
429             assert.equal(otherBuildRequest.statusUrl(), null);
430             assert.equal(otherBuildRequest.buildId(), null);
431
432             const otherCommitSet = otherBuildRequest.commitSet();
433             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
434             assert.equal(otherCommitSet.patchForRepository(webkit), null);
435             assert.equal(otherCommitSet.rootForRepository(webkit), null);
436             assert.deepEqual(otherCommitSet.allRootFiles(), []);
437
438             return uploadRoot(buildRequest.id(), 123);
439         }).then(() => {
440             return TestGroup.fetchForTask(taskId, true);
441         }).then((testGroups) => {
442             assert.equal(testGroups.length, 1);
443             const testGroup = testGroups[0];
444             const webkit = Repository.findById(MockData.webkitRepositoryId());
445             assert.equal(testGroup.buildRequests().length, 6);
446
447             const buildRequest = testGroup.buildRequests()[0];
448             assert(buildRequest.isBuild());
449             assert(!buildRequest.isTest());
450             assert.equal(buildRequest.statusLabel(), 'Completed');
451             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
452             assert.notEqual(buildRequest.buildId(), null);
453
454             const commitSet = buildRequest.commitSet();
455             assert.equal(commitSet.revisionForRepository(webkit), '191622');
456             const webkitPatch = commitSet.patchForRepository(webkit);
457             assert(webkitPatch instanceof UploadedFile);
458             assert.equal(webkitPatch.filename(), 'patch.dat');
459             const webkitRoot = commitSet.rootForRepository(webkit);
460             assert(webkitRoot instanceof UploadedFile);
461             assert.equal(webkitRoot.filename(), 'root123.dat');
462             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
463
464             const otherBuildRequest = testGroup.buildRequests()[1];
465             assert(otherBuildRequest.isBuild());
466             assert(!otherBuildRequest.isTest());
467             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
468             assert.equal(otherBuildRequest.statusUrl(), null);
469             assert.equal(otherBuildRequest.buildId(), null);
470
471             const otherCommitSet = otherBuildRequest.commitSet();
472             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
473             assert.equal(otherCommitSet.patchForRepository(webkit), null);
474             assert.equal(otherCommitSet.rootForRepository(webkit), null);
475             assert.deepEqual(otherCommitSet.allRootFiles(), []);
476
477             MockRemoteAPI.reset();
478             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
479             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
480             MockRemoteAPI.reset();
481             return MockRemoteAPI.waitForRequest();
482         }).then(() => {
483             assert.equal(requests.length, 3);
484             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
485             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
486             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
487             return MockRemoteAPI.waitForRequest();
488         }).then(() => {
489             assert.equal(requests.length, 6);
490             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
491             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
492                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
493             });
494             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
495             return MockRemoteAPI.waitForRequest();
496         }).then(() => {
497             assert.equal(requests.length, 7);
498             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
499             assert.deepEqual(requests[6].data, {'wk': '191622', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds', 'checkbox': 'build-wk'});
500             return MockRemoteAPI.waitForRequest();
501         }).then(() => {
502             assert.equal(requests.length, 10);
503             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
504             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
505             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
506             return MockRemoteAPI.waitForRequest();
507         }).then(() => {
508             assert.equal(requests.length, 13);
509             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
510             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
511                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
512                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
513             });
514             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
515             return syncPromise;
516         }).then(() => {
517             return TestGroup.fetchForTask(taskId, true);
518         }).then((testGroups) => {
519             assert.equal(testGroups.length, 1);
520             const testGroup = testGroups[0];
521             const webkit = Repository.findById(MockData.webkitRepositoryId());
522             assert.equal(testGroup.buildRequests().length, 6);
523
524             const buildRequest = testGroup.buildRequests()[0];
525             assert(buildRequest.isBuild());
526             assert(!buildRequest.isTest());
527             assert.equal(buildRequest.statusLabel(), 'Completed');
528             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
529             assert.notEqual(buildRequest.buildId(), null);
530
531             const commitSet = buildRequest.commitSet();
532             assert.equal(commitSet.revisionForRepository(webkit), '191622');
533             const webkitPatch = commitSet.patchForRepository(webkit);
534             assert(webkitPatch instanceof UploadedFile);
535             assert.equal(webkitPatch.filename(), 'patch.dat');
536             const webkitRoot = commitSet.rootForRepository(webkit);
537             assert(webkitRoot instanceof UploadedFile);
538             assert.equal(webkitRoot.filename(), 'root123.dat');
539             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
540
541             const otherBuildRequest = testGroup.buildRequests()[1];
542             assert(otherBuildRequest.isBuild());
543             assert(!otherBuildRequest.isTest());
544             assert.equal(otherBuildRequest.statusLabel(), 'Running');
545             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
546             assert.equal(otherBuildRequest.buildId(), null);
547
548             const otherCommitSet = otherBuildRequest.commitSet();
549             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
550             assert.equal(otherCommitSet.patchForRepository(webkit), null);
551             assert.equal(otherCommitSet.rootForRepository(webkit), null);
552             assert.deepEqual(otherCommitSet.allRootFiles(), []);
553
554             return uploadRoot(otherBuildRequest.id(), 124);
555         }).then(() => {
556             return TestGroup.fetchForTask(taskId, true);
557         }).then((testGroups) => {
558             assert.equal(testGroups.length, 1);
559             const testGroup = testGroups[0];
560             const webkit = Repository.findById(MockData.webkitRepositoryId());
561             assert.equal(testGroup.buildRequests().length, 6);
562
563             const buildRequest = testGroup.buildRequests()[0];
564             assert(buildRequest.isBuild());
565             assert(!buildRequest.isTest());
566             assert.equal(buildRequest.statusLabel(), 'Completed');
567             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
568             assert.notEqual(buildRequest.buildId(), null);
569
570             const commitSet = buildRequest.commitSet();
571             assert.equal(commitSet.revisionForRepository(webkit), '191622');
572             const webkitPatch = commitSet.patchForRepository(webkit);
573             assert(webkitPatch instanceof UploadedFile);
574             assert.equal(webkitPatch.filename(), 'patch.dat');
575             const webkitRoot = commitSet.rootForRepository(webkit);
576             assert(webkitRoot instanceof UploadedFile);
577             assert.equal(webkitRoot.filename(), 'root123.dat');
578             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
579
580             const otherBuildRequest = testGroup.buildRequests()[1];
581             assert(otherBuildRequest.isBuild());
582             assert(!otherBuildRequest.isTest());
583             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
584             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
585             assert.notEqual(otherBuildRequest.buildId(), null);
586
587             const otherCommitSet = otherBuildRequest.commitSet();
588             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
589             assert.equal(otherCommitSet.patchForRepository(webkit), null);
590             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
591             assert(otherWebkitRoot instanceof UploadedFile);
592             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
593             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
594         });
595     });
596
597     it('should schedule a build with platform in build property', () => {
598         const requests = MockRemoteAPI.requests;
599         let triggerable;
600         let taskId = null;
601         let syncPromise;
602         return createTriggerable(configWithPlatformName).then((newTriggerable) => {
603             triggerable = newTriggerable;
604             return createTestGroupWihPatch();
605         }).then((testGroup) => {
606             taskId = testGroup.task().id();
607             const webkit = Repository.findById(MockData.webkitRepositoryId());
608             assert.equal(testGroup.buildRequests().length, 6);
609
610             const buildRequest = testGroup.buildRequests()[0];
611             assert(buildRequest.isBuild());
612             assert(!buildRequest.isTest());
613             assert.equal(buildRequest.statusLabel(), 'Waiting');
614             assert.equal(buildRequest.statusUrl(), null);
615             assert.equal(buildRequest.buildId(), null);
616
617             const commitSet = buildRequest.commitSet();
618             assert.equal(commitSet.revisionForRepository(webkit), '191622');
619             const webkitPatch = commitSet.patchForRepository(webkit);
620             assert(webkitPatch instanceof UploadedFile);
621             assert.equal(webkitPatch.filename(), 'patch.dat');
622             assert.equal(commitSet.rootForRepository(webkit), null);
623             assert.deepEqual(commitSet.allRootFiles(), []);
624
625             const otherBuildRequest = testGroup.buildRequests()[1];
626             assert(otherBuildRequest.isBuild());
627             assert(!otherBuildRequest.isTest());
628             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
629             assert.equal(otherBuildRequest.statusUrl(), null);
630             assert.equal(otherBuildRequest.buildId(), null);
631
632             const otherCommitSet = otherBuildRequest.commitSet();
633             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
634             assert.equal(otherCommitSet.patchForRepository(webkit), null);
635             assert.equal(otherCommitSet.rootForRepository(webkit), null);
636             assert.deepEqual(otherCommitSet.allRootFiles(), []);
637
638             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
639             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
640             MockRemoteAPI.reset();
641             return MockRemoteAPI.waitForRequest();
642         }).then(() => {
643             assert.equal(requests.length, 3);
644             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
645             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
646             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
647             return MockRemoteAPI.waitForRequest();
648         }).then(() => {
649             assert.equal(requests.length, 6);
650             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
651             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
652             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
653             return MockRemoteAPI.waitForRequest();
654         }).then(() => {
655             assert.equal(requests.length, 7);
656             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
657             assert.deepEqual(requests[6].data, {'wk': '191622', 'wk-patch': RemoteAPI.url('/api/uploaded-file/1.dat'),
658                 'build-request-id': '1', 'forcescheduler': 'force-ab-builds', 'checkbox': 'build-wk', 'platform-name': 'some platform'});
659             return MockRemoteAPI.waitForRequest();
660         }).then(() => {
661             assert.equal(requests.length, 10);
662             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
663             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
664                 [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
665             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
666             return MockRemoteAPI.waitForRequest();
667         }).then(() => {
668             assert.equal(requests.length, 13);
669             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
670             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
671                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
672             });
673             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
674             return syncPromise;
675         }).then(() => {
676             return TestGroup.fetchForTask(taskId, true);
677         }).then((testGroups) => {
678             assert.equal(testGroups.length, 1);
679             const testGroup = testGroups[0];
680             const webkit = Repository.findById(MockData.webkitRepositoryId());
681             assert.equal(testGroup.buildRequests().length, 6);
682
683             const buildRequest = testGroup.buildRequests()[0];
684             assert(buildRequest.isBuild());
685             assert(!buildRequest.isTest());
686             assert.equal(buildRequest.statusLabel(), 'Running');
687             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
688             assert.equal(buildRequest.buildId(), null);
689
690             const commitSet = buildRequest.commitSet();
691             assert.equal(commitSet.revisionForRepository(webkit), '191622');
692             const webkitPatch = commitSet.patchForRepository(webkit);
693             assert(webkitPatch instanceof UploadedFile);
694             assert.equal(webkitPatch.filename(), 'patch.dat');
695             assert.equal(commitSet.rootForRepository(webkit), null);
696             assert.deepEqual(commitSet.allRootFiles(), []);
697
698             const otherBuildRequest = testGroup.buildRequests()[1];
699             assert(otherBuildRequest.isBuild());
700             assert(!otherBuildRequest.isTest());
701             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
702             assert.equal(otherBuildRequest.statusUrl(), null);
703             assert.equal(otherBuildRequest.buildId(), null);
704
705             const otherCommitSet = otherBuildRequest.commitSet();
706             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
707             assert.equal(otherCommitSet.patchForRepository(webkit), null);
708             assert.equal(otherCommitSet.rootForRepository(webkit), null);
709             assert.deepEqual(otherCommitSet.allRootFiles(), []);
710
711             return uploadRoot(buildRequest.id(), 123);
712         }).then(() => {
713             return TestGroup.fetchForTask(taskId, true);
714         }).then((testGroups) => {
715             assert.equal(testGroups.length, 1);
716             const testGroup = testGroups[0];
717             const webkit = Repository.findById(MockData.webkitRepositoryId());
718             assert.equal(testGroup.buildRequests().length, 6);
719
720             const buildRequest = testGroup.buildRequests()[0];
721             assert(buildRequest.isBuild());
722             assert(!buildRequest.isTest());
723             assert.equal(buildRequest.statusLabel(), 'Completed');
724             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
725             assert.notEqual(buildRequest.buildId(), null);
726
727             const commitSet = buildRequest.commitSet();
728             assert.equal(commitSet.revisionForRepository(webkit), '191622');
729             const webkitPatch = commitSet.patchForRepository(webkit);
730             assert(webkitPatch instanceof UploadedFile);
731             assert.equal(webkitPatch.filename(), 'patch.dat');
732             const webkitRoot = commitSet.rootForRepository(webkit);
733             assert(webkitRoot instanceof UploadedFile);
734             assert.equal(webkitRoot.filename(), 'root123.dat');
735             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
736
737             const otherBuildRequest = testGroup.buildRequests()[1];
738             assert(otherBuildRequest.isBuild());
739             assert(!otherBuildRequest.isTest());
740             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
741             assert.equal(otherBuildRequest.statusUrl(), null);
742             assert.equal(otherBuildRequest.buildId(), null);
743
744             const otherCommitSet = otherBuildRequest.commitSet();
745             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
746             assert.equal(otherCommitSet.patchForRepository(webkit), null);
747             assert.equal(otherCommitSet.rootForRepository(webkit), null);
748             assert.deepEqual(otherCommitSet.allRootFiles(), []);
749
750             MockRemoteAPI.reset();
751             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
752             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
753             MockRemoteAPI.reset();
754             return MockRemoteAPI.waitForRequest();
755         }).then(() => {
756             assert.equal(requests.length, 3);
757             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
758             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
759             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
760             return MockRemoteAPI.waitForRequest();
761         }).then(() => {
762             assert.equal(requests.length, 6);
763             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
764             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
765                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
766             });
767             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
768             return MockRemoteAPI.waitForRequest();
769         }).then(() => {
770             assert.equal(requests.length, 7);
771             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
772             assert.deepEqual(requests[6].data, {'wk': '191622', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds', 'checkbox': 'build-wk', 'platform-name': 'some platform'});
773             return MockRemoteAPI.waitForRequest();
774         }).then(() => {
775             assert.equal(requests.length, 10);
776             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
777             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
778             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
779             return MockRemoteAPI.waitForRequest();
780         }).then(() => {
781             assert.equal(requests.length, 13);
782             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
783             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
784                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
785                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
786             });
787             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
788             return syncPromise;
789         }).then(() => {
790             return TestGroup.fetchForTask(taskId, true);
791         }).then((testGroups) => {
792             assert.equal(testGroups.length, 1);
793             const testGroup = testGroups[0];
794             const webkit = Repository.findById(MockData.webkitRepositoryId());
795             assert.equal(testGroup.buildRequests().length, 6);
796
797             const buildRequest = testGroup.buildRequests()[0];
798             assert(buildRequest.isBuild());
799             assert(!buildRequest.isTest());
800             assert.equal(buildRequest.statusLabel(), 'Completed');
801             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
802             assert.notEqual(buildRequest.buildId(), null);
803
804             const commitSet = buildRequest.commitSet();
805             assert.equal(commitSet.revisionForRepository(webkit), '191622');
806             const webkitPatch = commitSet.patchForRepository(webkit);
807             assert(webkitPatch instanceof UploadedFile);
808             assert.equal(webkitPatch.filename(), 'patch.dat');
809             const webkitRoot = commitSet.rootForRepository(webkit);
810             assert(webkitRoot instanceof UploadedFile);
811             assert.equal(webkitRoot.filename(), 'root123.dat');
812             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
813
814             const otherBuildRequest = testGroup.buildRequests()[1];
815             assert(otherBuildRequest.isBuild());
816             assert(!otherBuildRequest.isTest());
817             assert.equal(otherBuildRequest.statusLabel(), 'Running');
818             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
819             assert.equal(otherBuildRequest.buildId(), null);
820
821             const otherCommitSet = otherBuildRequest.commitSet();
822             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
823             assert.equal(otherCommitSet.patchForRepository(webkit), null);
824             assert.equal(otherCommitSet.rootForRepository(webkit), null);
825             assert.deepEqual(otherCommitSet.allRootFiles(), []);
826
827             return uploadRoot(otherBuildRequest.id(), 124);
828         }).then(() => {
829             return TestGroup.fetchForTask(taskId, true);
830         }).then((testGroups) => {
831             assert.equal(testGroups.length, 1);
832             const testGroup = testGroups[0];
833             const webkit = Repository.findById(MockData.webkitRepositoryId());
834             assert.equal(testGroup.buildRequests().length, 6);
835
836             const buildRequest = testGroup.buildRequests()[0];
837             assert(buildRequest.isBuild());
838             assert(!buildRequest.isTest());
839             assert.equal(buildRequest.statusLabel(), 'Completed');
840             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
841             assert.notEqual(buildRequest.buildId(), null);
842
843             const commitSet = buildRequest.commitSet();
844             assert.equal(commitSet.revisionForRepository(webkit), '191622');
845             const webkitPatch = commitSet.patchForRepository(webkit);
846             assert(webkitPatch instanceof UploadedFile);
847             assert.equal(webkitPatch.filename(), 'patch.dat');
848             const webkitRoot = commitSet.rootForRepository(webkit);
849             assert(webkitRoot instanceof UploadedFile);
850             assert.equal(webkitRoot.filename(), 'root123.dat');
851             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
852
853             const otherBuildRequest = testGroup.buildRequests()[1];
854             assert(otherBuildRequest.isBuild());
855             assert(!otherBuildRequest.isTest());
856             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
857             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
858             assert.notEqual(otherBuildRequest.buildId(), null);
859
860             const otherCommitSet = otherBuildRequest.commitSet();
861             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
862             assert.equal(otherCommitSet.patchForRepository(webkit), null);
863             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
864             assert(otherWebkitRoot instanceof UploadedFile);
865             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
866             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
867         });
868     });
869
870     it('should schedule a build to test after building a patch', () => {
871         const requests = MockRemoteAPI.requests;
872         let triggerable;
873         let taskId = null;
874         let syncPromise;
875         let firstRoot = null;
876         return createTriggerable().then((newTriggerable) => {
877             triggerable = newTriggerable;
878             return createTestGroupWihPatch();
879         }).then((testGroup) => {
880             taskId = testGroup.task().id();
881             const webkit = Repository.findById(MockData.webkitRepositoryId());
882             assert.equal(testGroup.buildRequests().length, 6);
883
884             const buildRequest = testGroup.buildRequests()[0];
885             assert.equal(buildRequest.id(), 1);
886             assert(buildRequest.isBuild());
887             assert(!buildRequest.isTest());
888             assert.equal(buildRequest.statusLabel(), 'Waiting');
889             assert.equal(buildRequest.buildId(), null);
890             assert.deepEqual(buildRequest.commitSet().allRootFiles(), []);
891
892             const otherBuildRequest = testGroup.buildRequests()[1];
893             assert.equal(otherBuildRequest.id(), 2);
894             assert(otherBuildRequest.isBuild());
895             assert(!otherBuildRequest.isTest());
896             assert.equal(buildRequest.statusLabel(), 'Waiting');
897             assert.equal(otherBuildRequest.buildId(), null);
898             assert.deepEqual(otherBuildRequest.commitSet().allRootFiles(), []);
899
900             return uploadRoot(1, 45);
901         }).then(() => {
902             return uploadRoot(2, 46);
903         }).then(() => {
904             return TestGroup.fetchForTask(taskId, true);
905         }).then((testGroups) => {
906             assert.equal(testGroups.length, 1);
907             const testGroup = testGroups[0];
908
909             const buildRequest = testGroup.buildRequests()[0];
910             assert(buildRequest.isBuild());
911             assert(!buildRequest.isTest());
912             assert.equal(buildRequest.statusLabel(), 'Completed');
913             assert.notEqual(buildRequest.buildId(), null);
914             const roots = buildRequest.commitSet().allRootFiles();
915             assert.equal(roots.length, 1);
916             firstRoot = roots[0];
917             assert.deepEqual(roots[0].filename(), 'root45.dat');
918
919             const otherBuildRequest = testGroup.buildRequests()[1];
920             assert(otherBuildRequest.isBuild());
921             assert(!otherBuildRequest.isTest());
922             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
923             assert.notEqual(otherBuildRequest.buildId(), null);
924             const otherRoots = otherBuildRequest.commitSet().allRootFiles();
925             assert.equal(otherRoots.length, 1);
926             assert.deepEqual(otherRoots[0].filename(), 'root46.dat');
927             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
928             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
929             MockRemoteAPI.reset();
930             return MockRemoteAPI.waitForRequest();
931         }).then(() => {
932             assert.equal(requests.length, 3);
933             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
934             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
935             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
936             return MockRemoteAPI.waitForRequest();
937         }).then(() => {
938             assert.equal(requests.length, 6);
939             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
940             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
941                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
942                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 2}),
943             });
944             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
945             return MockRemoteAPI.waitForRequest();
946         }).then(() => {
947             assert.equal(requests.length, 7);
948             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20tester/force', 'OK');
949             assert.deepEqual(requests[6].data, {'test': 'some-test', 'wk': '191622', 'build-request-id': '3', 'forcescheduler': 'force-ab-tests',
950                 'roots': JSON.stringify([{url: firstRoot.url()}])});
951             return MockRemoteAPI.waitForRequest();
952         }).then(() => {
953             assert.equal(requests.length, 10);
954             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', [
955                 MockData.pendingBuild({builder: 'some tester', buildRequestId: 3}),
956             ]);
957             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
958             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
959             return MockRemoteAPI.waitForRequest();
960         }).then(() => {
961             assert.equal(requests.length, 13);
962             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
963             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
964                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
965                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 2}),
966             });
967             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
968             return syncPromise;
969         });
970     });
971
972     it('should not schedule a build to test while building a patch', () => {
973         const requests = MockRemoteAPI.requests;
974         let triggerable;
975         let taskId = null;
976         let syncPromise;
977         return createTriggerable().then((newTriggerable) => {
978             triggerable = newTriggerable;
979             return createTestGroupWihPatch();
980         }).then((testGroup) => {
981             taskId = testGroup.task().id();
982             assert.equal(testGroup.buildRequests().length, 6);
983
984             const buildRequest = testGroup.buildRequests()[0];
985             assert.equal(buildRequest.id(), 1);
986             assert(buildRequest.isBuild());
987             assert(!buildRequest.isTest());
988             assert.equal(buildRequest.statusLabel(), 'Waiting');
989             assert.equal(buildRequest.statusUrl(), null);
990             assert.equal(buildRequest.buildId(), null);
991
992             const otherBuildRequest = testGroup.buildRequests()[1];
993             assert.equal(otherBuildRequest.id(), 2);
994             assert(otherBuildRequest.isBuild());
995             assert(!otherBuildRequest.isTest());
996             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
997             assert.equal(otherBuildRequest.statusUrl(), null);
998             assert.equal(otherBuildRequest.buildId(), null);
999
1000             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
1001             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
1002             MockRemoteAPI.reset();
1003             return Promise.all([MockRemoteAPI.waitForRequest(), uploadRoot(1, 123)]);
1004         }).then(() => {
1005             assert.equal(requests.length, 3);
1006             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1007             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1008             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1009             return MockRemoteAPI.waitForRequest();
1010         }).then(() => {
1011             assert.equal(requests.length, 6);
1012             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1013             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1014                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
1015                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
1016             });
1017             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1018             return MockRemoteAPI.waitForRequest();
1019         }).then(() => {
1020             assert.equal(requests.length, 9);
1021             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1022             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1023             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1024             return MockRemoteAPI.waitForRequest();
1025         }).then(() => {
1026             assert.equal(requests.length, 12);
1027             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1028             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1029                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2, buildNumber: 1002}),
1030                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
1031             });
1032             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1033             return syncPromise;
1034         }).then(() => {
1035             return TestGroup.fetchForTask(taskId, true);
1036         }).then((testGroups) => {
1037             assert.equal(testGroups.length, 1);
1038
1039             const testGroup = testGroups[0];
1040             const buildRequest = testGroup.buildRequests()[0];
1041             assert.equal(buildRequest.id(), 1);
1042             assert(buildRequest.isBuild());
1043             assert(!buildRequest.isTest());
1044             assert.equal(buildRequest.statusLabel(), 'Completed');
1045             assert.equal(buildRequest.statusUrl(), null);
1046             assert.notEqual(buildRequest.buildId(), null);
1047
1048             const otherBuildRequest = testGroup.buildRequests()[1];
1049             assert.equal(otherBuildRequest.id(), 2);
1050             assert(otherBuildRequest.isBuild());
1051             assert(!otherBuildRequest.isTest());
1052             assert.equal(otherBuildRequest.statusLabel(), 'Running');
1053             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/1002');
1054             assert.equal(otherBuildRequest.buildId(), null);
1055         });
1056     });
1057
1058     it('should cancel builds for testing when a build to build a patch fails', () => {
1059         const requests = MockRemoteAPI.requests;
1060         let triggerable;
1061         let taskId = null;
1062         let syncPromise;
1063         return createTriggerable().then((newTriggerable) => {
1064             triggerable = newTriggerable;
1065             return createTestGroupWihPatch();
1066         }).then((testGroup) => {
1067             taskId = testGroup.task().id();
1068             assert.equal(testGroup.buildRequests().length, 6);
1069
1070             const buildRequest = testGroup.buildRequests()[0];
1071             assert.equal(buildRequest.id(), 1);
1072             assert(buildRequest.isBuild());
1073             assert(!buildRequest.isTest());
1074             assert.equal(buildRequest.statusLabel(), 'Waiting');
1075             assert.equal(buildRequest.statusUrl(), null);
1076             assert.equal(buildRequest.buildId(), null);
1077
1078             const otherBuildRequest = testGroup.buildRequests()[1];
1079             assert.equal(otherBuildRequest.id(), 2);
1080             assert(otherBuildRequest.isBuild());
1081             assert(!otherBuildRequest.isTest());
1082             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1083             assert.equal(otherBuildRequest.statusUrl(), null);
1084             assert.equal(otherBuildRequest.buildId(), null);
1085
1086             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
1087             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
1088             MockRemoteAPI.reset();
1089             return MockRemoteAPI.waitForRequest();
1090         }).then(() => {
1091             assert.equal(requests.length, 3);
1092             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1093             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1094             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1095             return MockRemoteAPI.waitForRequest();
1096         }).then(() => {
1097             assert.equal(requests.length, 6);
1098             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1099             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
1100             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
1101                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
1102             });
1103             return MockRemoteAPI.waitForRequest();
1104         }).then(() => {
1105             assert.equal(requests.length, 9);
1106             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1107             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1108             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1109             return MockRemoteAPI.waitForRequest();
1110         }).then(() => {
1111             assert.equal(requests.length, 12);
1112             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1113             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
1114             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
1115                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
1116             });
1117             return syncPromise;
1118         }).then(() => {
1119             return TestGroup.fetchForTask(taskId, true);
1120         }).then((testGroups) => {
1121             assert.equal(testGroups.length, 1);
1122
1123             const buildReqeusts = testGroups[0].buildRequests();
1124             assert(buildReqeusts[0].isBuild());
1125             assert(!buildReqeusts[0].isTest());
1126             assert.equal(buildReqeusts[0].statusLabel(), 'Failed');
1127             assert.equal(buildReqeusts[0].statusUrl(), 'http://build.webkit.org/builders/other%20builder/builds/312');
1128             assert.equal(buildReqeusts[0].buildId(), null);
1129
1130             assert(buildReqeusts[1].isBuild());
1131             assert(!buildReqeusts[1].isTest());
1132             assert.equal(buildReqeusts[1].statusLabel(), 'Failed');
1133             assert.equal(buildReqeusts[1].statusUrl(), null);
1134             assert.equal(buildReqeusts[1].buildId(), null);
1135
1136             function assertTestBuildHasFailed(request)
1137             {
1138                 assert(!request.isBuild());
1139                 assert(request.isTest());
1140                 assert.equal(request.statusLabel(), 'Failed');
1141                 assert.equal(request.statusUrl(), null);
1142                 assert.equal(request.buildId(), null);
1143             }
1144
1145             assertTestBuildHasFailed(buildReqeusts[2]);
1146             assertTestBuildHasFailed(buildReqeusts[3]);
1147         });
1148     });
1149
1150     it('should schedule a build to build binary for owned commits', () => {
1151         const requests = MockRemoteAPI.requests;
1152         let triggerable;
1153         let taskId = null;
1154         let syncPromise;
1155         return createTriggerable().then((newTriggerable) => {
1156             triggerable = newTriggerable;
1157             return createTestGroupWihOwnedCommit();
1158         }).then((testGroup) => {
1159             taskId = testGroup.task().id();
1160             const webkit = Repository.findById(MockData.webkitRepositoryId());
1161             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1162             assert.equal(testGroup.buildRequests().length, 6);
1163
1164             const buildRequest = testGroup.buildRequests()[0];
1165             assert(buildRequest.isBuild());
1166             assert(!buildRequest.isTest());
1167             assert.equal(buildRequest.statusLabel(), 'Waiting');
1168             assert.equal(buildRequest.statusUrl(), null);
1169             assert.equal(buildRequest.buildId(), null);
1170
1171             const commitSet = buildRequest.commitSet();
1172             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1173             assert.equal(commitSet.patchForRepository(webkit), null);
1174             assert.equal(commitSet.rootForRepository(webkit), null);
1175             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1176             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1177             assert.deepEqual(commitSet.allRootFiles(), []);
1178
1179             const otherBuildRequest = testGroup.buildRequests()[1];
1180             assert(otherBuildRequest.isBuild());
1181             assert(!otherBuildRequest.isTest());
1182             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1183             assert.equal(otherBuildRequest.statusUrl(), null);
1184             assert.equal(otherBuildRequest.buildId(), null);
1185
1186             const otherCommitSet = otherBuildRequest.commitSet();
1187             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1188             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1189             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1190             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1191             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1192             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1193
1194             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
1195             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
1196             MockRemoteAPI.reset();
1197             return MockRemoteAPI.waitForRequest();
1198         }).then(() => {
1199             assert.equal(requests.length, 3);
1200             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1201             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1202             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1203             return MockRemoteAPI.waitForRequest();
1204         }).then(() => {
1205             assert.equal(requests.length, 6);
1206             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1207             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
1208             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1209             return MockRemoteAPI.waitForRequest();
1210         }).then(() => {
1211             assert.equal(requests.length, 7);
1212             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
1213             assert.deepEqual(requests[6].data, {'wk': '191622', 'build-request-id': '1', 'forcescheduler': 'force-ab-builds', 'owned-commits': `{"WebKit":[{"revision":"owned-jsc-6161","repository":"JavaScriptCore","ownerRevision":"191622"}]}`});
1214             return MockRemoteAPI.waitForRequest();
1215         }).then(() => {
1216             assert.equal(requests.length, 10);
1217             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1218             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
1219                 [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
1220             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1221             return MockRemoteAPI.waitForRequest();
1222         }).then(() => {
1223             assert.equal(requests.length, 13);
1224             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1225             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1226                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
1227             });
1228             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1229             return syncPromise;
1230         }).then(() => {
1231             return TestGroup.fetchForTask(taskId, true);
1232         }).then((testGroups) => {
1233             assert.equal(testGroups.length, 1);
1234             const testGroup = testGroups[0];
1235             const webkit = Repository.findById(MockData.webkitRepositoryId());
1236             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1237             assert.equal(testGroup.buildRequests().length, 6);
1238
1239             const buildRequest = testGroup.buildRequests()[0];
1240             assert(buildRequest.isBuild());
1241             assert(!buildRequest.isTest());
1242             assert.equal(buildRequest.statusLabel(), 'Running');
1243             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1244             assert.equal(buildRequest.buildId(), null);
1245
1246             const commitSet = buildRequest.commitSet();
1247             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1248             assert.equal(commitSet.patchForRepository(webkit), null);
1249             assert.equal(commitSet.rootForRepository(webkit), null);
1250             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1251             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1252             assert.deepEqual(commitSet.allRootFiles(), []);
1253
1254             const otherBuildRequest = testGroup.buildRequests()[1];
1255             assert(otherBuildRequest.isBuild());
1256             assert(!otherBuildRequest.isTest());
1257             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1258             assert.equal(otherBuildRequest.statusUrl(), null);
1259             assert.equal(otherBuildRequest.buildId(), null);
1260
1261             const otherCommitSet = otherBuildRequest.commitSet();
1262             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1263             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1264             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1265             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1266             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1267             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1268
1269             return uploadRoot(buildRequest.id(), 123).then(() => uploadRoot(buildRequest.id(), 123, [{ownerRepository: 'WebKit', ownedRepository: 'JavaScriptCore'}], '2017-05-10T02:54:09.666'));
1270         }).then(() => {
1271             return TestGroup.fetchForTask(taskId, true);
1272         }).then((testGroups) => {
1273             assert.equal(testGroups.length, 1);
1274             const testGroup = testGroups[0];
1275             const webkit = Repository.findById(MockData.webkitRepositoryId());
1276             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1277             assert.equal(testGroup.buildRequests().length, 6);
1278
1279             const buildRequest = testGroup.buildRequests()[0];
1280             assert(buildRequest.isBuild());
1281             assert(!buildRequest.isTest());
1282             assert.equal(buildRequest.statusLabel(), 'Completed');
1283             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1284             assert.notEqual(buildRequest.buildId(), null);
1285
1286             const commitSet = buildRequest.commitSet();
1287             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1288             assert.equal(commitSet.patchForRepository(webkit), null);
1289             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1290             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1291             const webkitRoot = commitSet.rootForRepository(webkit);
1292             assert(webkitRoot instanceof UploadedFile);
1293             assert.equal(webkitRoot.filename(), 'root123.dat');
1294             const jscRoot = commitSet.rootForRepository(ownedJSC);
1295             assert(jscRoot instanceof UploadedFile);
1296             assert.equal(jscRoot.filename(), 'root123.dat');
1297             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
1298
1299             const otherBuildRequest = testGroup.buildRequests()[1];
1300             assert(otherBuildRequest.isBuild());
1301             assert(!otherBuildRequest.isTest());
1302             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1303             assert.equal(otherBuildRequest.statusUrl(), null);
1304             assert.equal(otherBuildRequest.buildId(), null);
1305
1306             const otherCommitSet = otherBuildRequest.commitSet();
1307             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1308             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1309             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1310             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1311             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1312             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1313
1314             MockRemoteAPI.reset();
1315             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
1316             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
1317             MockRemoteAPI.reset();
1318             return MockRemoteAPI.waitForRequest();
1319         }).then(() => {
1320             assert.equal(requests.length, 3);
1321             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1322             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1323             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1324             return MockRemoteAPI.waitForRequest();
1325         }).then(() => {
1326             assert.equal(requests.length, 6);
1327             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1328             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1329                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
1330             });
1331             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1332             return MockRemoteAPI.waitForRequest();
1333         }).then(() => {
1334             assert.equal(requests.length, 7);
1335             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
1336             assert.deepEqual(requests[6].data, {'wk': '192736', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds', 'owned-commits': `{"WebKit":[{"revision":"owned-jsc-9191","repository":"JavaScriptCore","ownerRevision":"192736"}]}`});
1337             return MockRemoteAPI.waitForRequest();
1338         }).then(() => {
1339             assert.equal(requests.length, 10);
1340             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1341             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1342             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1343             return MockRemoteAPI.waitForRequest();
1344         }).then(() => {
1345             assert.equal(requests.length, 13);
1346             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1347             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1348                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
1349                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
1350             });
1351             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1352             return syncPromise;
1353         }).then(() => {
1354             return TestGroup.fetchForTask(taskId, true);
1355         }).then((testGroups) => {
1356             assert.equal(testGroups.length, 1);
1357             const testGroup = testGroups[0];
1358             const webkit = Repository.findById(MockData.webkitRepositoryId());
1359             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1360             assert.equal(testGroup.buildRequests().length, 6);
1361
1362             const buildRequest = testGroup.buildRequests()[0];
1363             assert(buildRequest.isBuild());
1364             assert(!buildRequest.isTest());
1365             assert.equal(buildRequest.statusLabel(), 'Completed');
1366             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1367             assert.notEqual(buildRequest.buildId(), null);
1368
1369             const commitSet = buildRequest.commitSet();
1370             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1371             assert.equal(commitSet.patchForRepository(webkit), null);
1372             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1373             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1374             const webkitRoot = commitSet.rootForRepository(webkit);
1375             assert(webkitRoot instanceof UploadedFile);
1376             assert.equal(webkitRoot.filename(), 'root123.dat');
1377             const jscRoot = commitSet.rootForRepository(ownedJSC);
1378             assert(jscRoot instanceof UploadedFile);
1379             assert.equal(jscRoot.filename(), 'root123.dat');
1380             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
1381
1382             const otherBuildRequest = testGroup.buildRequests()[1];
1383             assert(otherBuildRequest.isBuild());
1384             assert(!otherBuildRequest.isTest());
1385             assert.equal(otherBuildRequest.statusLabel(), 'Running');
1386             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1387             assert.equal(otherBuildRequest.buildId(), null);
1388
1389             const otherCommitSet = otherBuildRequest.commitSet();
1390             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1391             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1392             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1393             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1394             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1395             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1396
1397             return uploadRoot(otherBuildRequest.id(), 124).then(() => uploadRoot(otherBuildRequest.id(), 124, [{ownerRepository: 'WebKit', ownedRepository: 'JavaScriptCore'}], '2017-05-10T02:54:09.666'));
1398         }).then(() => {
1399             return TestGroup.fetchForTask(taskId, true);
1400         }).then((testGroups) => {
1401             assert.equal(testGroups.length, 1);
1402             const testGroup = testGroups[0];
1403             const webkit = Repository.findById(MockData.webkitRepositoryId());
1404             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1405             assert.equal(testGroup.buildRequests().length, 6);
1406
1407             const buildRequest = testGroup.buildRequests()[0];
1408             assert(buildRequest.isBuild());
1409             assert(!buildRequest.isTest());
1410             assert.equal(buildRequest.statusLabel(), 'Completed');
1411             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1412             assert.notEqual(buildRequest.buildId(), null);
1413
1414             const commitSet = buildRequest.commitSet();
1415             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1416             assert.equal(commitSet.patchForRepository(webkit), null);
1417             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1418             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1419             const webkitRoot = commitSet.rootForRepository(webkit);
1420             assert(webkitRoot instanceof UploadedFile);
1421             assert.equal(webkitRoot.filename(), 'root123.dat');
1422             const jscRoot = commitSet.rootForRepository(ownedJSC);
1423             assert(jscRoot instanceof UploadedFile);
1424             assert.equal(jscRoot.filename(), 'root123.dat');
1425             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
1426
1427             const otherBuildRequest = testGroup.buildRequests()[1];
1428             assert(otherBuildRequest.isBuild());
1429             assert(!otherBuildRequest.isTest());
1430             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
1431             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1432             assert.notEqual(otherBuildRequest.buildId(), null);
1433
1434             const otherCommitSet = otherBuildRequest.commitSet();
1435             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1436             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1437             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1438             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1439             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
1440             assert(otherWebkitRoot instanceof UploadedFile);
1441             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
1442             const otherJSCRoot = otherCommitSet.rootForRepository(ownedJSC);
1443             assert(otherJSCRoot instanceof UploadedFile);
1444             assert.equal(otherJSCRoot.filename(), 'root124.dat');
1445             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot, otherJSCRoot]);
1446         });
1447     });
1448
1449     it('should not update a build request to "completed" until all roots needed in the commit set are uploaded', () => {
1450         const requests = MockRemoteAPI.requests;
1451         let triggerable;
1452         let taskId = null;
1453         let syncPromise;
1454         return createTriggerable().then((newTriggerable) => {
1455             triggerable = newTriggerable;
1456             return createTestGroupWihOwnedCommit();
1457         }).then((testGroup) => {
1458             taskId = testGroup.task().id();
1459             const webkit = Repository.findById(MockData.webkitRepositoryId());
1460             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1461             assert.equal(testGroup.buildRequests().length, 6);
1462
1463             const buildRequest = testGroup.buildRequests()[0];
1464             assert(buildRequest.isBuild());
1465             assert(!buildRequest.isTest());
1466             assert.equal(buildRequest.statusLabel(), 'Waiting');
1467             assert.equal(buildRequest.statusUrl(), null);
1468             assert.equal(buildRequest.buildId(), null);
1469
1470             const commitSet = buildRequest.commitSet();
1471             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1472             assert.equal(commitSet.patchForRepository(webkit), null);
1473             assert.equal(commitSet.rootForRepository(webkit), null);
1474             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1475             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1476             assert.deepEqual(commitSet.allRootFiles(), []);
1477
1478             const otherBuildRequest = testGroup.buildRequests()[1];
1479             assert(otherBuildRequest.isBuild());
1480             assert(!otherBuildRequest.isTest());
1481             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1482             assert.equal(otherBuildRequest.statusUrl(), null);
1483             assert.equal(otherBuildRequest.buildId(), null);
1484
1485             const otherCommitSet = otherBuildRequest.commitSet();
1486             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1487             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1488             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1489             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1490             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1491             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1492
1493             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
1494             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
1495             MockRemoteAPI.reset();
1496             return MockRemoteAPI.waitForRequest();
1497         }).then(() => {
1498             assert.equal(requests.length, 3);
1499             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1500             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1501             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1502             return MockRemoteAPI.waitForRequest();
1503         }).then(() => {
1504             assert.equal(requests.length, 6);
1505             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1506             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
1507             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1508             return MockRemoteAPI.waitForRequest();
1509         }).then(() => {
1510             assert.equal(requests.length, 7);
1511             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
1512             assert.deepEqual(requests[6].data, {'wk': '191622', 'build-request-id': '1', 'forcescheduler': 'force-ab-builds', 'owned-commits': `{"WebKit":[{"revision":"owned-jsc-6161","repository":"JavaScriptCore","ownerRevision":"191622"}]}`});
1513             return MockRemoteAPI.waitForRequest();
1514         }).then(() => {
1515             assert.equal(requests.length, 10);
1516             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1517             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
1518                 [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
1519             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1520             return MockRemoteAPI.waitForRequest();
1521         }).then(() => {
1522             assert.equal(requests.length, 13);
1523             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1524             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1525                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
1526             });
1527             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1528             return syncPromise;
1529         }).then(() => {
1530             return TestGroup.fetchForTask(taskId, true);
1531         }).then((testGroups) => {
1532             assert.equal(testGroups.length, 1);
1533             const testGroup = testGroups[0];
1534             const webkit = Repository.findById(MockData.webkitRepositoryId());
1535             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1536             assert.equal(testGroup.buildRequests().length, 6);
1537
1538             const buildRequest = testGroup.buildRequests()[0];
1539             assert(buildRequest.isBuild());
1540             assert(!buildRequest.isTest());
1541             assert.equal(buildRequest.statusLabel(), 'Running');
1542             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1543             assert.equal(buildRequest.buildId(), null);
1544
1545             const commitSet = buildRequest.commitSet();
1546             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1547             assert.equal(commitSet.patchForRepository(webkit), null);
1548             assert.equal(commitSet.rootForRepository(webkit), null);
1549             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1550             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1551             assert.deepEqual(commitSet.allRootFiles(), []);
1552
1553             const otherBuildRequest = testGroup.buildRequests()[1];
1554             assert(otherBuildRequest.isBuild());
1555             assert(!otherBuildRequest.isTest());
1556             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1557             assert.equal(otherBuildRequest.statusUrl(), null);
1558             assert.equal(otherBuildRequest.buildId(), null);
1559
1560             const otherCommitSet = otherBuildRequest.commitSet();
1561             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1562             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1563             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1564             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1565             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1566             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1567
1568             return uploadRoot(buildRequest.id(), 123);
1569         }).then(() => {
1570             return TestGroup.fetchForTask(taskId, true);
1571         }).then((testGroups) => {
1572             assert.equal(testGroups.length, 1);
1573             const testGroup = testGroups[0];
1574             const webkit = Repository.findById(MockData.webkitRepositoryId());
1575             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1576             assert.equal(testGroup.buildRequests().length, 6);
1577
1578             const buildRequest = testGroup.buildRequests()[0];
1579             assert(buildRequest.isBuild());
1580             assert(!buildRequest.isTest());
1581             assert.equal(buildRequest.statusLabel(), 'Running');
1582             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1583             assert.equal(buildRequest.buildId(), null);
1584
1585             const commitSet = buildRequest.commitSet();
1586             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1587             assert.equal(commitSet.patchForRepository(webkit), null);
1588             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1589             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1590             const webkitRoot = commitSet.rootForRepository(webkit);
1591             assert(webkitRoot instanceof UploadedFile);
1592             assert.equal(webkitRoot.filename(), 'root123.dat');
1593             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
1594
1595             const otherBuildRequest = testGroup.buildRequests()[1];
1596             assert(otherBuildRequest.isBuild());
1597             assert(!otherBuildRequest.isTest());
1598             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1599             assert.equal(otherBuildRequest.statusUrl(), null);
1600             assert.equal(otherBuildRequest.buildId(), null);
1601
1602             const otherCommitSet = otherBuildRequest.commitSet();
1603             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1604             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1605             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1606             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1607             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1608             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1609             return uploadRoot(buildRequest.id(), 123, [{ownerRepository: 'WebKit', ownedRepository: 'JavaScriptCore'}], '2017-05-10T02:54:09.666');
1610         }).then(() => {
1611             return TestGroup.fetchForTask(taskId, true);
1612         }).then((testGroups) => {
1613             assert.equal(testGroups.length, 1);
1614             const testGroup = testGroups[0];
1615             const webkit = Repository.findById(MockData.webkitRepositoryId());
1616             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1617             assert.equal(testGroup.buildRequests().length, 6);
1618
1619             const buildRequest = testGroup.buildRequests()[0];
1620             assert(buildRequest.isBuild());
1621             assert(!buildRequest.isTest());
1622             assert.equal(buildRequest.statusLabel(), 'Completed');
1623             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1624             assert.notEqual(buildRequest.buildId(), null);
1625
1626             const commitSet = buildRequest.commitSet();
1627             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1628             assert.equal(commitSet.patchForRepository(webkit), null);
1629             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1630             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1631             const webkitRoot = commitSet.rootForRepository(webkit);
1632             assert(webkitRoot instanceof UploadedFile);
1633             assert.equal(webkitRoot.filename(), 'root123.dat');
1634             const jscRoot = commitSet.rootForRepository((ownedJSC));
1635             assert(jscRoot instanceof UploadedFile);
1636             assert.equal(jscRoot.filename(), 'root123.dat');
1637             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
1638
1639             const otherBuildRequest = testGroup.buildRequests()[1];
1640             assert(otherBuildRequest.isBuild());
1641             assert(!otherBuildRequest.isTest());
1642             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
1643             assert.equal(otherBuildRequest.statusUrl(), null);
1644             assert.equal(otherBuildRequest.buildId(), null);
1645
1646             const otherCommitSet = otherBuildRequest.commitSet();
1647             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1648             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1649             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1650             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1651             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1652             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1653
1654             MockRemoteAPI.reset();
1655             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
1656             assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURLDeprecated(), MockData.mockBuildbotBuildersDeprecated());
1657             MockRemoteAPI.reset();
1658             return MockRemoteAPI.waitForRequest();
1659         }).then(() => {
1660             assert.equal(requests.length, 3);
1661             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1662             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1663             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1664             return MockRemoteAPI.waitForRequest();
1665         }).then(() => {
1666             assert.equal(requests.length, 6);
1667             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1668             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1669                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
1670             });
1671             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1672             return MockRemoteAPI.waitForRequest();
1673         }).then(() => {
1674             assert.equal(requests.length, 7);
1675             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
1676             assert.deepEqual(requests[6].data, {'wk': '192736', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds', 'owned-commits': `{"WebKit":[{"revision":"owned-jsc-9191","repository":"JavaScriptCore","ownerRevision":"192736"}]}`});
1677             return MockRemoteAPI.waitForRequest();
1678         }).then(() => {
1679             assert.equal(requests.length, 10);
1680             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
1681             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
1682             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
1683             return MockRemoteAPI.waitForRequest();
1684         }).then(() => {
1685             assert.equal(requests.length, 13);
1686             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
1687             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
1688                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
1689                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
1690             });
1691             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
1692             return syncPromise;
1693         }).then(() => {
1694             return TestGroup.fetchForTask(taskId, true);
1695         }).then((testGroups) => {
1696             assert.equal(testGroups.length, 1);
1697             const testGroup = testGroups[0];
1698             const webkit = Repository.findById(MockData.webkitRepositoryId());
1699             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1700             assert.equal(testGroup.buildRequests().length, 6);
1701
1702             const buildRequest = testGroup.buildRequests()[0];
1703             assert(buildRequest.isBuild());
1704             assert(!buildRequest.isTest());
1705             assert.equal(buildRequest.statusLabel(), 'Completed');
1706             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1707             assert.notEqual(buildRequest.buildId(), null);
1708
1709             const commitSet = buildRequest.commitSet();
1710             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1711             assert.equal(commitSet.patchForRepository(webkit), null);
1712             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1713             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1714             const webkitRoot = commitSet.rootForRepository(webkit);
1715             assert(webkitRoot instanceof UploadedFile);
1716             assert.equal(webkitRoot.filename(), 'root123.dat');
1717             const jscRoot = commitSet.rootForRepository(ownedJSC);
1718             assert(jscRoot instanceof UploadedFile);
1719             assert.equal(jscRoot.filename(), 'root123.dat');
1720             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
1721
1722             const otherBuildRequest = testGroup.buildRequests()[1];
1723             assert(otherBuildRequest.isBuild());
1724             assert(!otherBuildRequest.isTest());
1725             assert.equal(otherBuildRequest.statusLabel(), 'Running');
1726             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1727             assert.equal(otherBuildRequest.buildId(), null);
1728
1729             const otherCommitSet = otherBuildRequest.commitSet();
1730             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1731             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1732             assert.equal(otherCommitSet.rootForRepository(webkit), null);
1733             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1734             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1735             assert.deepEqual(otherCommitSet.allRootFiles(), []);
1736
1737             return uploadRoot(otherBuildRequest.id(), 124);
1738         }).then(() => {
1739             return TestGroup.fetchForTask(taskId, true);
1740         }).then((testGroups) => {
1741             assert.equal(testGroups.length, 1);
1742             const testGroup = testGroups[0];
1743             const webkit = Repository.findById(MockData.webkitRepositoryId());
1744             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1745             assert.equal(testGroup.buildRequests().length, 6);
1746
1747             const buildRequest = testGroup.buildRequests()[0];
1748             assert(buildRequest.isBuild());
1749             assert(!buildRequest.isTest());
1750             assert.equal(buildRequest.statusLabel(), 'Completed');
1751             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1752             assert.notEqual(buildRequest.buildId(), null);
1753
1754             const commitSet = buildRequest.commitSet();
1755             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1756             assert.equal(commitSet.patchForRepository(webkit), null);
1757             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1758             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1759             const webkitRoot = commitSet.rootForRepository(webkit);
1760             assert(webkitRoot instanceof UploadedFile);
1761             assert.equal(webkitRoot.filename(), 'root123.dat');
1762             const jscRoot = commitSet.rootForRepository(ownedJSC);
1763             assert(jscRoot instanceof UploadedFile);
1764             assert.equal(jscRoot.filename(), 'root123.dat');
1765             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
1766
1767             const otherBuildRequest = testGroup.buildRequests()[1];
1768             assert(otherBuildRequest.isBuild());
1769             assert(!otherBuildRequest.isTest());
1770             assert.equal(otherBuildRequest.statusLabel(), 'Running');
1771             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1772             assert.equal(otherBuildRequest.buildId(), null);
1773
1774             const otherCommitSet = otherBuildRequest.commitSet();
1775             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1776             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1777             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1778             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1779             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
1780             assert(otherWebkitRoot instanceof UploadedFile);
1781             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
1782             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
1783             return uploadRoot(otherBuildRequest.id(), 124, [{ownerRepository: 'WebKit', ownedRepository: 'JavaScriptCore'}], '2017-05-10T02:54:09.666');
1784         }).then(() => {
1785             return TestGroup.fetchForTask(taskId, true);
1786         }).then((testGroups) => {
1787             assert.equal(testGroups.length, 1);
1788             const testGroup = testGroups[0];
1789             const webkit = Repository.findById(MockData.webkitRepositoryId());
1790             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
1791             assert.equal(testGroup.buildRequests().length, 6);
1792
1793             const buildRequest = testGroup.buildRequests()[0];
1794             assert(buildRequest.isBuild());
1795             assert(!buildRequest.isTest());
1796             assert.equal(buildRequest.statusLabel(), 'Completed');
1797             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1798             assert.notEqual(buildRequest.buildId(), null);
1799
1800             const commitSet = buildRequest.commitSet();
1801             assert.equal(commitSet.revisionForRepository(webkit), '191622');
1802             assert.equal(commitSet.patchForRepository(webkit), null);
1803             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
1804             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
1805             const webkitRoot = commitSet.rootForRepository(webkit);
1806             assert(webkitRoot instanceof UploadedFile);
1807             assert.equal(webkitRoot.filename(), 'root123.dat');
1808             const jscRoot = commitSet.rootForRepository(ownedJSC);
1809             assert(jscRoot instanceof UploadedFile);
1810             assert.equal(jscRoot.filename(), 'root123.dat');
1811             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
1812
1813             const otherBuildRequest = testGroup.buildRequests()[1];
1814             assert(otherBuildRequest.isBuild());
1815             assert(!otherBuildRequest.isTest());
1816             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
1817             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
1818             assert.notEqual(otherBuildRequest.buildId(), null);
1819
1820             const otherCommitSet = otherBuildRequest.commitSet();
1821             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
1822             assert.equal(otherCommitSet.patchForRepository(webkit), null);
1823             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
1824             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
1825             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
1826             assert(otherWebkitRoot instanceof UploadedFile);
1827             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
1828             const otherJSCRoot = otherCommitSet.rootForRepository(ownedJSC);
1829             assert(otherJSCRoot instanceof UploadedFile);
1830             assert.equal(otherJSCRoot.filename(), 'root124.dat');
1831             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot, otherJSCRoot]);
1832         });
1833     });
1834 });