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