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