Update syncing script to be able to build binary for commit set with owned commits.
[WebKit.git] / Websites / perf.webkit.org / server-tests / tools-sync-buildbot-integration-tests.js
1 'use strict';
2
3 const assert = require('assert');
4
5 require('../tools/js/v3-models.js');
6
7 const BuildbotTriggerable = require('../tools/js/buildbot-triggerable.js').BuildbotTriggerable;
8 const MockData = require('./resources/mock-data.js');
9 const MockLogger = require('./resources/mock-logger.js').MockLogger;
10 const MockRemoteAPI = require('../unit-tests/resources/mock-remote-api.js').MockRemoteAPI;
11 const TestServer = require('./resources/test-server.js');
12 const TemporaryFile = require('./resources/temporary-file.js').TemporaryFile;
13 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
14 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
15
16 function createTriggerable()
17 {
18     let triggerable;
19     const config = {
20             triggerableName: 'build-webkit',
21             lookbackCount: 2,
22             buildRequestArgument: 'build-request-id',
23             slaveName: 'sync-slave',
24             slavePassword: 'password',
25             repositoryGroups: {
26                 'webkit': {
27                     repositories: {'WebKit': {acceptsPatch: true}},
28                     testProperties: {'wk': {'revision': 'WebKit'}, 'roots': {'roots': {}}},
29                     buildProperties: {'wk': {'revision': 'WebKit'}, 'wk-patch': {'patch': 'WebKit'},
30                         'checkbox': {'ifRepositorySet': ['WebKit'], 'value': 'build-wk'},
31                         'owned-commits': {'ownedRevisions': 'WebKit'}},
32                     acceptsRoots: true,
33                 }
34             },
35             types: {
36                 'some': {
37                     test: ['some test'],
38                     properties: {'test': 'some-test'},
39                 }
40             },
41             builders: {
42                 'builder-1': {
43                     builder: 'some tester',
44                     properties: {forcescheduler: 'force-ab-tests'},
45                 },
46                 'builder-2': {
47                     builder: 'some builder',
48                     properties: {forcescheduler: 'force-ab-builds'},
49                 },
50                 'builder-3': {
51                     builder: 'other builder',
52                     properties: {forcescheduler: 'force-ab-builds'},
53                 },
54             },
55             buildConfigurations: [
56                 {platforms: ['some platform'], builders: ['builder-2', 'builder-3']},
57             ],
58             testConfigurations: [
59                 {types: ['some'], platforms: ['some platform'], builders: ['builder-1']},
60             ],
61         };
62     return MockData.addMockConfiguration(TestServer.database()).then(() => {
63         return Manifest.fetch();
64     }).then(() => {
65         triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, {name: 'sync-slave', password: 'password'}, new MockLogger);
66         return triggerable.initSyncers().then(() => triggerable.updateTriggerable());
67     }).then(() => Manifest.fetch()).then(() => {
68         return new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, {name: 'sync-slave', password: 'password'}, new MockLogger);
69     });
70 }
71
72 function createTestGroupWihPatch()
73 {
74     return TemporaryFile.makeTemporaryFile('patch.dat', 'patch file').then((patchFile) => {
75         return UploadedFile.uploadFile(patchFile);
76     }).then((patchFile) => {
77         const someTest = Test.findById(MockData.someTestId());
78         const webkit = Repository.findById(MockData.webkitRepositoryId());
79         const set1 = new CustomCommitSet;
80         set1.setRevisionForRepository(webkit, '191622', patchFile);
81         const set2 = new CustomCommitSet;
82         set2.setRevisionForRepository(webkit, '191622');
83         return TestGroup.createWithTask('custom task', Platform.findById(MockData.somePlatformId()), someTest, 'some group', 2, [set1, set2]);
84     }).then((task) => {
85         return TestGroup.findAllByTask(task.id())[0];
86     })
87 }
88
89 function createTestGroupWihOwnedCommit()
90 {
91     const someTest = Test.findById(MockData.someTestId());
92     const webkit = Repository.findById(MockData.webkitRepositoryId());
93     const ownedSJC = Repository.findById(MockData.ownedJSCRepositoryId());
94     const set1 = new CustomCommitSet;
95     set1.setRevisionForRepository(webkit, '191622');
96     set1.setRevisionForRepository(ownedSJC, 'owned-jsc-6161', null, '191622');
97     const set2 = new CustomCommitSet;
98     set2.setRevisionForRepository(webkit, '192736');
99     set2.setRevisionForRepository(ownedSJC, 'owned-jsc-9191', null, '192736');
100     return TestGroup.createWithTask('custom task', Platform.findById(MockData.somePlatformId()), someTest, 'some group', 2, [set1, set2]).then((task) => {
101         return TestGroup.findAllByTask(task.id())[0];
102     });
103 }
104
105 function uploadRoot(buildRequestId, buildNumber)
106 {
107     return TemporaryFile.makeTemporaryFile(`root${buildNumber}.dat`, `root for build ${buildNumber}`).then((rootFile) => {
108         return TestServer.remoteAPI().postFormData('/api/upload-root/', {
109             slaveName: 'sync-slave',
110             slavePassword: 'password',
111             builderName: 'some builder',
112             buildNumber: buildNumber,
113             buildTime: '2017-05-10T02:54:08.666',
114             buildRequest: buildRequestId,
115             rootFile,
116             repositoryList: '["WebKit"]',
117         });
118     });
119 }
120
121 describe('sync-buildbot', function () {
122     prepareServerTest(this);
123     TemporaryFile.inject();
124
125     beforeEach(() => {
126         MockRemoteAPI.reset('http://build.webkit.org');
127     });
128
129     function assertAndResolveRequest(request, method, url, contentToResolve)
130     {
131         assert.equal(request.method, method);
132         assert.equal(request.url, url);
133         request.resolve(contentToResolve);
134     }
135
136     it('should schedule a build to build a patch', () => {
137         const requests = MockRemoteAPI.requests;
138         let triggerable;
139         let taskId = null;
140         let syncPromise;
141         return createTriggerable().then((newTriggerable) => {
142             triggerable = newTriggerable;
143             return createTestGroupWihPatch();
144         }).then((testGroup) => {
145             taskId = testGroup.task().id();
146             const webkit = Repository.findById(MockData.webkitRepositoryId());
147             assert.equal(testGroup.buildRequests().length, 6);
148
149             const buildRequest = testGroup.buildRequests()[0];
150             assert(buildRequest.isBuild());
151             assert(!buildRequest.isTest());
152             assert.equal(buildRequest.statusLabel(), 'Waiting');
153             assert.equal(buildRequest.statusUrl(), null);
154             assert.equal(buildRequest.buildId(), null);
155
156             const commitSet = buildRequest.commitSet();
157             assert.equal(commitSet.revisionForRepository(webkit), '191622');
158             const webkitPatch = commitSet.patchForRepository(webkit);
159             assert(webkitPatch instanceof UploadedFile);
160             assert.equal(webkitPatch.filename(), 'patch.dat');
161             assert.equal(commitSet.rootForRepository(webkit), null);
162             assert.deepEqual(commitSet.allRootFiles(), []);
163
164             const otherBuildRequest = testGroup.buildRequests()[1];
165             assert(otherBuildRequest.isBuild());
166             assert(!otherBuildRequest.isTest());
167             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
168             assert.equal(otherBuildRequest.statusUrl(), null);
169             assert.equal(otherBuildRequest.buildId(), null);
170
171             const otherCommitSet = otherBuildRequest.commitSet();
172             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
173             assert.equal(otherCommitSet.patchForRepository(webkit), null);
174             assert.equal(otherCommitSet.rootForRepository(webkit), null);
175             assert.deepEqual(otherCommitSet.allRootFiles(), []);
176
177             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
178             return MockRemoteAPI.waitForRequest();
179         }).then(() => {
180             assert.equal(requests.length, 3);
181             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
182             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
183             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
184             return MockRemoteAPI.waitForRequest();
185         }).then(() => {
186             assert.equal(requests.length, 6);
187             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
188             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
189             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
190             return MockRemoteAPI.waitForRequest();
191         }).then(() => {
192             assert.equal(requests.length, 7);
193             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
194             assert.deepEqual(requests[6].data, {'wk': '191622', 'wk-patch': RemoteAPI.url('/api/uploaded-file/1.dat'),
195                 'build-request-id': '1', 'forcescheduler': 'force-ab-builds', 'checkbox': 'build-wk'});
196             return MockRemoteAPI.waitForRequest();
197         }).then(() => {
198             assert.equal(requests.length, 10);
199             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
200             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
201                 [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
202             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
203             return MockRemoteAPI.waitForRequest();
204         }).then(() => {
205             assert.equal(requests.length, 13);
206             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
207             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
208                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
209             });
210             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
211             return syncPromise;
212         }).then(() => {
213             return TestGroup.fetchForTask(taskId, true);
214         }).then((testGroups) => {
215             assert.equal(testGroups.length, 1);
216             const testGroup = testGroups[0];
217             const webkit = Repository.findById(MockData.webkitRepositoryId());
218             assert.equal(testGroup.buildRequests().length, 6);
219
220             const buildRequest = testGroup.buildRequests()[0];
221             assert(buildRequest.isBuild());
222             assert(!buildRequest.isTest());
223             assert.equal(buildRequest.statusLabel(), 'Running');
224             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
225             assert.equal(buildRequest.buildId(), null);
226
227             const commitSet = buildRequest.commitSet();
228             assert.equal(commitSet.revisionForRepository(webkit), '191622');
229             const webkitPatch = commitSet.patchForRepository(webkit);
230             assert(webkitPatch instanceof UploadedFile);
231             assert.equal(webkitPatch.filename(), 'patch.dat');
232             assert.equal(commitSet.rootForRepository(webkit), null);
233             assert.deepEqual(commitSet.allRootFiles(), []);
234
235             const otherBuildRequest = testGroup.buildRequests()[1];
236             assert(otherBuildRequest.isBuild());
237             assert(!otherBuildRequest.isTest());
238             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
239             assert.equal(otherBuildRequest.statusUrl(), null);
240             assert.equal(otherBuildRequest.buildId(), null);
241
242             const otherCommitSet = otherBuildRequest.commitSet();
243             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
244             assert.equal(otherCommitSet.patchForRepository(webkit), null);
245             assert.equal(otherCommitSet.rootForRepository(webkit), null);
246             assert.deepEqual(otherCommitSet.allRootFiles(), []);
247
248             return uploadRoot(buildRequest.id(), 123);
249         }).then(() => {
250             return TestGroup.fetchForTask(taskId, true);
251         }).then((testGroups) => {
252             assert.equal(testGroups.length, 1);
253             const testGroup = testGroups[0];
254             const webkit = Repository.findById(MockData.webkitRepositoryId());
255             assert.equal(testGroup.buildRequests().length, 6);
256
257             const buildRequest = testGroup.buildRequests()[0];
258             assert(buildRequest.isBuild());
259             assert(!buildRequest.isTest());
260             assert.equal(buildRequest.statusLabel(), 'Completed');
261             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
262             assert.notEqual(buildRequest.buildId(), null);
263
264             const commitSet = buildRequest.commitSet();
265             assert.equal(commitSet.revisionForRepository(webkit), '191622');
266             const webkitPatch = commitSet.patchForRepository(webkit);
267             assert(webkitPatch instanceof UploadedFile);
268             assert.equal(webkitPatch.filename(), 'patch.dat');
269             const webkitRoot = commitSet.rootForRepository(webkit);
270             assert(webkitRoot instanceof UploadedFile);
271             assert.equal(webkitRoot.filename(), 'root123.dat');
272             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
273
274             const otherBuildRequest = testGroup.buildRequests()[1];
275             assert(otherBuildRequest.isBuild());
276             assert(!otherBuildRequest.isTest());
277             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
278             assert.equal(otherBuildRequest.statusUrl(), null);
279             assert.equal(otherBuildRequest.buildId(), null);
280
281             const otherCommitSet = otherBuildRequest.commitSet();
282             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
283             assert.equal(otherCommitSet.patchForRepository(webkit), null);
284             assert.equal(otherCommitSet.rootForRepository(webkit), null);
285             assert.deepEqual(otherCommitSet.allRootFiles(), []);
286
287             MockRemoteAPI.reset();
288             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
289             return MockRemoteAPI.waitForRequest();
290         }).then(() => {
291             assert.equal(requests.length, 3);
292             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
293             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
294             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
295             return MockRemoteAPI.waitForRequest();
296         }).then(() => {
297             assert.equal(requests.length, 6);
298             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
299             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
300                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
301             });
302             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
303             return MockRemoteAPI.waitForRequest();
304         }).then(() => {
305             assert.equal(requests.length, 7);
306             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
307             assert.deepEqual(requests[6].data, {'wk': '191622', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds', 'checkbox': 'build-wk'});
308             return MockRemoteAPI.waitForRequest();
309         }).then(() => {
310             assert.equal(requests.length, 10);
311             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
312             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
313             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
314             return MockRemoteAPI.waitForRequest();
315         }).then(() => {
316             assert.equal(requests.length, 13);
317             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
318             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
319                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
320                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
321             });
322             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
323             return syncPromise;
324         }).then(() => {
325             return TestGroup.fetchForTask(taskId, true);
326         }).then((testGroups) => {
327             assert.equal(testGroups.length, 1);
328             const testGroup = testGroups[0];
329             const webkit = Repository.findById(MockData.webkitRepositoryId());
330             assert.equal(testGroup.buildRequests().length, 6);
331
332             const buildRequest = testGroup.buildRequests()[0];
333             assert(buildRequest.isBuild());
334             assert(!buildRequest.isTest());
335             assert.equal(buildRequest.statusLabel(), 'Completed');
336             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
337             assert.notEqual(buildRequest.buildId(), null);
338
339             const commitSet = buildRequest.commitSet();
340             assert.equal(commitSet.revisionForRepository(webkit), '191622');
341             const webkitPatch = commitSet.patchForRepository(webkit);
342             assert(webkitPatch instanceof UploadedFile);
343             assert.equal(webkitPatch.filename(), 'patch.dat');
344             const webkitRoot = commitSet.rootForRepository(webkit);
345             assert(webkitRoot instanceof UploadedFile);
346             assert.equal(webkitRoot.filename(), 'root123.dat');
347             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
348
349             const otherBuildRequest = testGroup.buildRequests()[1];
350             assert(otherBuildRequest.isBuild());
351             assert(!otherBuildRequest.isTest());
352             assert.equal(otherBuildRequest.statusLabel(), 'Running');
353             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
354             assert.equal(otherBuildRequest.buildId(), null);
355
356             const otherCommitSet = otherBuildRequest.commitSet();
357             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
358             assert.equal(otherCommitSet.patchForRepository(webkit), null);
359             assert.equal(otherCommitSet.rootForRepository(webkit), null);
360             assert.deepEqual(otherCommitSet.allRootFiles(), []);
361
362             return uploadRoot(otherBuildRequest.id(), 124);
363         }).then(() => {
364             return TestGroup.fetchForTask(taskId, true);
365         }).then((testGroups) => {
366             assert.equal(testGroups.length, 1);
367             const testGroup = testGroups[0];
368             const webkit = Repository.findById(MockData.webkitRepositoryId());
369             assert.equal(testGroup.buildRequests().length, 6);
370
371             const buildRequest = testGroup.buildRequests()[0];
372             assert(buildRequest.isBuild());
373             assert(!buildRequest.isTest());
374             assert.equal(buildRequest.statusLabel(), 'Completed');
375             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
376             assert.notEqual(buildRequest.buildId(), null);
377
378             const commitSet = buildRequest.commitSet();
379             assert.equal(commitSet.revisionForRepository(webkit), '191622');
380             const webkitPatch = commitSet.patchForRepository(webkit);
381             assert(webkitPatch instanceof UploadedFile);
382             assert.equal(webkitPatch.filename(), 'patch.dat');
383             const webkitRoot = commitSet.rootForRepository(webkit);
384             assert(webkitRoot instanceof UploadedFile);
385             assert.equal(webkitRoot.filename(), 'root123.dat');
386             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
387
388             const otherBuildRequest = testGroup.buildRequests()[1];
389             assert(otherBuildRequest.isBuild());
390             assert(!otherBuildRequest.isTest());
391             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
392             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
393             assert.notEqual(otherBuildRequest.buildId(), null);
394
395             const otherCommitSet = otherBuildRequest.commitSet();
396             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
397             assert.equal(otherCommitSet.patchForRepository(webkit), null);
398             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
399             assert(otherWebkitRoot instanceof UploadedFile);
400             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
401             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
402         });
403     });
404
405     it('should schedule a build to test after building a patch', () => {
406         const requests = MockRemoteAPI.requests;
407         let triggerable;
408         let taskId = null;
409         let syncPromise;
410         let firstRoot = null;
411         return createTriggerable().then((newTriggerable) => {
412             triggerable = newTriggerable;
413             return createTestGroupWihPatch();
414         }).then((testGroup) => {
415             taskId = testGroup.task().id();
416             const webkit = Repository.findById(MockData.webkitRepositoryId());
417             assert.equal(testGroup.buildRequests().length, 6);
418
419             const buildRequest = testGroup.buildRequests()[0];
420             assert.equal(buildRequest.id(), 1);
421             assert(buildRequest.isBuild());
422             assert(!buildRequest.isTest());
423             assert.equal(buildRequest.statusLabel(), 'Waiting');
424             assert.equal(buildRequest.buildId(), null);
425             assert.deepEqual(buildRequest.commitSet().allRootFiles(), []);
426
427             const otherBuildRequest = testGroup.buildRequests()[1];
428             assert.equal(otherBuildRequest.id(), 2);
429             assert(otherBuildRequest.isBuild());
430             assert(!otherBuildRequest.isTest());
431             assert.equal(buildRequest.statusLabel(), 'Waiting');
432             assert.equal(otherBuildRequest.buildId(), null);
433             assert.deepEqual(otherBuildRequest.commitSet().allRootFiles(), []);
434
435             return uploadRoot(1, 45);
436         }).then(() => {
437             return uploadRoot(2, 46);
438         }).then(() => {
439             return TestGroup.fetchForTask(taskId, true);
440         }).then((testGroups) => {
441             assert.equal(testGroups.length, 1);
442             const testGroup = testGroups[0];
443
444             const buildRequest = testGroup.buildRequests()[0];
445             assert(buildRequest.isBuild());
446             assert(!buildRequest.isTest());
447             assert.equal(buildRequest.statusLabel(), 'Completed');
448             assert.notEqual(buildRequest.buildId(), null);
449             const roots = buildRequest.commitSet().allRootFiles();
450             assert.equal(roots.length, 1);
451             firstRoot = roots[0];
452             assert.deepEqual(roots[0].filename(), 'root45.dat');
453
454             const otherBuildRequest = testGroup.buildRequests()[1];
455             assert(otherBuildRequest.isBuild());
456             assert(!otherBuildRequest.isTest());
457             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
458             assert.notEqual(otherBuildRequest.buildId(), null);
459             const otherRoots = otherBuildRequest.commitSet().allRootFiles();
460             assert.equal(otherRoots.length, 1);
461             assert.deepEqual(otherRoots[0].filename(), 'root46.dat');
462             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
463             return MockRemoteAPI.waitForRequest();
464         }).then(() => {
465             assert.equal(requests.length, 3);
466             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
467             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
468             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
469             return MockRemoteAPI.waitForRequest();
470         }).then(() => {
471             assert.equal(requests.length, 6);
472             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
473             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
474                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
475                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 2}),
476             });
477             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
478             return MockRemoteAPI.waitForRequest();
479         }).then(() => {
480             assert.equal(requests.length, 7);
481             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20tester/force', 'OK');
482             assert.deepEqual(requests[6].data, {'test': 'some-test', 'wk': '191622', 'build-request-id': '3', 'forcescheduler': 'force-ab-tests',
483                 'roots': JSON.stringify([{url: firstRoot.url()}])});
484             return MockRemoteAPI.waitForRequest();
485         }).then(() => {
486             assert.equal(requests.length, 10);
487             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', [
488                 MockData.pendingBuild({builder: 'some tester', buildRequestId: 3}),
489             ]);
490             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
491             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
492             return MockRemoteAPI.waitForRequest();
493         }).then(() => {
494             assert.equal(requests.length, 13);
495             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
496             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
497                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
498                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 2}),
499             });
500             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
501             return syncPromise;
502         });
503     });
504
505     it('should not schedule a build to test while building a patch', () => {
506         const requests = MockRemoteAPI.requests;
507         let triggerable;
508         let taskId = null;
509         let syncPromise;
510         return createTriggerable().then((newTriggerable) => {
511             triggerable = newTriggerable;
512             return createTestGroupWihPatch();
513         }).then((testGroup) => {
514             taskId = testGroup.task().id();
515             assert.equal(testGroup.buildRequests().length, 6);
516
517             const buildRequest = testGroup.buildRequests()[0];
518             assert.equal(buildRequest.id(), 1);
519             assert(buildRequest.isBuild());
520             assert(!buildRequest.isTest());
521             assert.equal(buildRequest.statusLabel(), 'Waiting');
522             assert.equal(buildRequest.statusUrl(), null);
523             assert.equal(buildRequest.buildId(), null);
524
525             const otherBuildRequest = testGroup.buildRequests()[1];
526             assert.equal(otherBuildRequest.id(), 2);
527             assert(otherBuildRequest.isBuild());
528             assert(!otherBuildRequest.isTest());
529             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
530             assert.equal(otherBuildRequest.statusUrl(), null);
531             assert.equal(otherBuildRequest.buildId(), null);
532
533             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
534             return Promise.all([MockRemoteAPI.waitForRequest(), uploadRoot(1, 123)]);
535         }).then(() => {
536             assert.equal(requests.length, 3);
537             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
538             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
539             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
540             return MockRemoteAPI.waitForRequest();
541         }).then(() => {
542             assert.equal(requests.length, 6);
543             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
544             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
545                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
546                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
547             });
548             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
549             return MockRemoteAPI.waitForRequest();
550         }).then(() => {
551             assert.equal(requests.length, 9);
552             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
553             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
554             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
555             return MockRemoteAPI.waitForRequest();
556         }).then(() => {
557             assert.equal(requests.length, 12);
558             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
559             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
560                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2, buildNumber: 1002}),
561                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
562             });
563             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
564             return syncPromise;
565         }).then(() => {
566             return TestGroup.fetchForTask(taskId, true);
567         }).then((testGroups) => {
568             assert.equal(testGroups.length, 1);
569
570             const testGroup = testGroups[0];
571             const buildRequest = testGroup.buildRequests()[0];
572             assert.equal(buildRequest.id(), 1);
573             assert(buildRequest.isBuild());
574             assert(!buildRequest.isTest());
575             assert.equal(buildRequest.statusLabel(), 'Completed');
576             assert.equal(buildRequest.statusUrl(), null);
577             assert.notEqual(buildRequest.buildId(), null);
578
579             const otherBuildRequest = testGroup.buildRequests()[1];
580             assert.equal(otherBuildRequest.id(), 2);
581             assert(otherBuildRequest.isBuild());
582             assert(!otherBuildRequest.isTest());
583             assert.equal(otherBuildRequest.statusLabel(), 'Running');
584             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/1002');
585             assert.equal(otherBuildRequest.buildId(), null);
586         });
587     });
588
589     it('should cancel builds for testing when a build to build a patch fails', () => {
590         const requests = MockRemoteAPI.requests;
591         let triggerable;
592         let taskId = null;
593         let syncPromise;
594         return createTriggerable().then((newTriggerable) => {
595             triggerable = newTriggerable;
596             return createTestGroupWihPatch();
597         }).then((testGroup) => {
598             taskId = testGroup.task().id();
599             assert.equal(testGroup.buildRequests().length, 6);
600
601             const buildRequest = testGroup.buildRequests()[0];
602             assert.equal(buildRequest.id(), 1);
603             assert(buildRequest.isBuild());
604             assert(!buildRequest.isTest());
605             assert.equal(buildRequest.statusLabel(), 'Waiting');
606             assert.equal(buildRequest.statusUrl(), null);
607             assert.equal(buildRequest.buildId(), null);
608
609             const otherBuildRequest = testGroup.buildRequests()[1];
610             assert.equal(otherBuildRequest.id(), 2);
611             assert(otherBuildRequest.isBuild());
612             assert(!otherBuildRequest.isTest());
613             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
614             assert.equal(otherBuildRequest.statusUrl(), null);
615             assert.equal(otherBuildRequest.buildId(), null);
616
617             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
618             return MockRemoteAPI.waitForRequest();
619         }).then(() => {
620             assert.equal(requests.length, 3);
621             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
622             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
623             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
624             return MockRemoteAPI.waitForRequest();
625         }).then(() => {
626             assert.equal(requests.length, 6);
627             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
628             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
629             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
630                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
631             });
632             return MockRemoteAPI.waitForRequest();
633         }).then(() => {
634             assert.equal(requests.length, 9);
635             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
636             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
637             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
638             return MockRemoteAPI.waitForRequest();
639         }).then(() => {
640             assert.equal(requests.length, 12);
641             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
642             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
643             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
644                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
645             });
646             return syncPromise;
647         }).then(() => {
648             return TestGroup.fetchForTask(taskId, true);
649         }).then((testGroups) => {
650             assert.equal(testGroups.length, 1);
651
652             const buildReqeusts = testGroups[0].buildRequests();
653             assert(buildReqeusts[0].isBuild());
654             assert(!buildReqeusts[0].isTest());
655             assert.equal(buildReqeusts[0].statusLabel(), 'Failed');
656             assert.equal(buildReqeusts[0].statusUrl(), 'http://build.webkit.org/builders/other%20builder/builds/312');
657             assert.equal(buildReqeusts[0].buildId(), null);
658
659             assert(buildReqeusts[1].isBuild());
660             assert(!buildReqeusts[1].isTest());
661             assert.equal(buildReqeusts[1].statusLabel(), 'Failed');
662             assert.equal(buildReqeusts[1].statusUrl(), null);
663             assert.equal(buildReqeusts[1].buildId(), null);
664
665             function assertTestBuildHasFailed(request)
666             {
667                 assert(!request.isBuild());
668                 assert(request.isTest());
669                 assert.equal(request.statusLabel(), 'Failed');
670                 assert.equal(request.statusUrl(), null);
671                 assert.equal(request.buildId(), null);
672             }
673
674             assertTestBuildHasFailed(buildReqeusts[2]);
675             assertTestBuildHasFailed(buildReqeusts[3]);
676         });
677     });
678
679     it('should schedule a build to build binary for owned commits', () => {
680         const requests = MockRemoteAPI.requests;
681         let triggerable;
682         let taskId = null;
683         let syncPromise;
684         return createTriggerable().then((newTriggerable) => {
685             triggerable = newTriggerable;
686             return createTestGroupWihOwnedCommit();
687         }).then((testGroup) => {
688             taskId = testGroup.task().id();
689             const webkit = Repository.findById(MockData.webkitRepositoryId());
690             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
691             assert.equal(testGroup.buildRequests().length, 6);
692
693             const buildRequest = testGroup.buildRequests()[0];
694             assert(buildRequest.isBuild());
695             assert(!buildRequest.isTest());
696             assert.equal(buildRequest.statusLabel(), 'Waiting');
697             assert.equal(buildRequest.statusUrl(), null);
698             assert.equal(buildRequest.buildId(), null);
699
700             const commitSet = buildRequest.commitSet();
701             assert.equal(commitSet.revisionForRepository(webkit), '191622');
702             assert.equal(commitSet.patchForRepository(webkit), null);
703             assert.equal(commitSet.rootForRepository(webkit), null);
704             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
705             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
706             assert.deepEqual(commitSet.allRootFiles(), []);
707
708             const otherBuildRequest = testGroup.buildRequests()[1];
709             assert(otherBuildRequest.isBuild());
710             assert(!otherBuildRequest.isTest());
711             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
712             assert.equal(otherBuildRequest.statusUrl(), null);
713             assert.equal(otherBuildRequest.buildId(), null);
714
715             const otherCommitSet = otherBuildRequest.commitSet();
716             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
717             assert.equal(otherCommitSet.patchForRepository(webkit), null);
718             assert.equal(otherCommitSet.rootForRepository(webkit), null);
719             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
720             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
721             assert.deepEqual(otherCommitSet.allRootFiles(), []);
722
723             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
724             return MockRemoteAPI.waitForRequest();
725         }).then(() => {
726             assert.equal(requests.length, 3);
727             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
728             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
729             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
730             return MockRemoteAPI.waitForRequest();
731         }).then(() => {
732             assert.equal(requests.length, 6);
733             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
734             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
735             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
736             return MockRemoteAPI.waitForRequest();
737         }).then(() => {
738             assert.equal(requests.length, 7);
739             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
740             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"}]}`});
741             return MockRemoteAPI.waitForRequest();
742         }).then(() => {
743             assert.equal(requests.length, 10);
744             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
745             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
746                 [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
747             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
748             return MockRemoteAPI.waitForRequest();
749         }).then(() => {
750             assert.equal(requests.length, 13);
751             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
752             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
753                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
754             });
755             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
756             return syncPromise;
757         }).then(() => {
758             return TestGroup.fetchForTask(taskId, true);
759         }).then((testGroups) => {
760             assert.equal(testGroups.length, 1);
761             const testGroup = testGroups[0];
762             const webkit = Repository.findById(MockData.webkitRepositoryId());
763             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
764             assert.equal(testGroup.buildRequests().length, 6);
765
766             const buildRequest = testGroup.buildRequests()[0];
767             assert(buildRequest.isBuild());
768             assert(!buildRequest.isTest());
769             assert.equal(buildRequest.statusLabel(), 'Running');
770             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
771             assert.equal(buildRequest.buildId(), null);
772
773             const commitSet = buildRequest.commitSet();
774             assert.equal(commitSet.revisionForRepository(webkit), '191622');
775             assert.equal(commitSet.patchForRepository(webkit), null);
776             assert.equal(commitSet.rootForRepository(webkit), null);
777             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
778             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
779             assert.deepEqual(commitSet.allRootFiles(), []);
780
781             const otherBuildRequest = testGroup.buildRequests()[1];
782             assert(otherBuildRequest.isBuild());
783             assert(!otherBuildRequest.isTest());
784             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
785             assert.equal(otherBuildRequest.statusUrl(), null);
786             assert.equal(otherBuildRequest.buildId(), null);
787
788             const otherCommitSet = otherBuildRequest.commitSet();
789             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
790             assert.equal(otherCommitSet.patchForRepository(webkit), null);
791             assert.equal(otherCommitSet.rootForRepository(webkit), null);
792             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
793             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
794             assert.deepEqual(otherCommitSet.allRootFiles(), []);
795
796             return uploadRoot(buildRequest.id(), 123);
797         }).then(() => {
798             return TestGroup.fetchForTask(taskId, true);
799         }).then((testGroups) => {
800             assert.equal(testGroups.length, 1);
801             const testGroup = testGroups[0];
802             const webkit = Repository.findById(MockData.webkitRepositoryId());
803             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
804             assert.equal(testGroup.buildRequests().length, 6);
805
806             const buildRequest = testGroup.buildRequests()[0];
807             assert(buildRequest.isBuild());
808             assert(!buildRequest.isTest());
809             assert.equal(buildRequest.statusLabel(), 'Completed');
810             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
811             assert.notEqual(buildRequest.buildId(), null);
812
813             const commitSet = buildRequest.commitSet();
814             assert.equal(commitSet.revisionForRepository(webkit), '191622');
815             assert.equal(commitSet.patchForRepository(webkit), null);
816             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
817             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
818             const webkitRoot = commitSet.rootForRepository(webkit);
819             assert(webkitRoot instanceof UploadedFile);
820             assert.equal(webkitRoot.filename(), 'root123.dat');
821             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
822
823             const otherBuildRequest = testGroup.buildRequests()[1];
824             assert(otherBuildRequest.isBuild());
825             assert(!otherBuildRequest.isTest());
826             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
827             assert.equal(otherBuildRequest.statusUrl(), null);
828             assert.equal(otherBuildRequest.buildId(), null);
829
830             const otherCommitSet = otherBuildRequest.commitSet();
831             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
832             assert.equal(otherCommitSet.patchForRepository(webkit), null);
833             assert.equal(otherCommitSet.rootForRepository(webkit), null);
834             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
835             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
836             assert.deepEqual(otherCommitSet.allRootFiles(), []);
837
838             MockRemoteAPI.reset();
839             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
840             return MockRemoteAPI.waitForRequest();
841         }).then(() => {
842             assert.equal(requests.length, 3);
843             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
844             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
845             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
846             return MockRemoteAPI.waitForRequest();
847         }).then(() => {
848             assert.equal(requests.length, 6);
849             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
850             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
851                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
852             });
853             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
854             return MockRemoteAPI.waitForRequest();
855         }).then(() => {
856             assert.equal(requests.length, 7);
857             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
858             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"}]}`});
859             return MockRemoteAPI.waitForRequest();
860         }).then(() => {
861             assert.equal(requests.length, 10);
862             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
863             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
864             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
865             return MockRemoteAPI.waitForRequest();
866         }).then(() => {
867             assert.equal(requests.length, 13);
868             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
869             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
870                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
871                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
872             });
873             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
874             return syncPromise;
875         }).then(() => {
876             return TestGroup.fetchForTask(taskId, true);
877         }).then((testGroups) => {
878             assert.equal(testGroups.length, 1);
879             const testGroup = testGroups[0];
880             const webkit = Repository.findById(MockData.webkitRepositoryId());
881             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
882             assert.equal(testGroup.buildRequests().length, 6);
883
884             const buildRequest = testGroup.buildRequests()[0];
885             assert(buildRequest.isBuild());
886             assert(!buildRequest.isTest());
887             assert.equal(buildRequest.statusLabel(), 'Completed');
888             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
889             assert.notEqual(buildRequest.buildId(), null);
890
891             const commitSet = buildRequest.commitSet();
892             assert.equal(commitSet.revisionForRepository(webkit), '191622');
893             assert.equal(commitSet.patchForRepository(webkit), null);
894             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
895             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
896             const webkitRoot = commitSet.rootForRepository(webkit);
897             assert(webkitRoot instanceof UploadedFile);
898             assert.equal(webkitRoot.filename(), 'root123.dat');
899             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
900
901             const otherBuildRequest = testGroup.buildRequests()[1];
902             assert(otherBuildRequest.isBuild());
903             assert(!otherBuildRequest.isTest());
904             assert.equal(otherBuildRequest.statusLabel(), 'Running');
905             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
906             assert.equal(otherBuildRequest.buildId(), null);
907
908             const otherCommitSet = otherBuildRequest.commitSet();
909             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
910             assert.equal(otherCommitSet.patchForRepository(webkit), null);
911             assert.equal(otherCommitSet.rootForRepository(webkit), null);
912             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
913             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
914             assert.deepEqual(otherCommitSet.allRootFiles(), []);
915
916             return uploadRoot(otherBuildRequest.id(), 124);
917         }).then(() => {
918             return TestGroup.fetchForTask(taskId, true);
919         }).then((testGroups) => {
920             assert.equal(testGroups.length, 1);
921             const testGroup = testGroups[0];
922             const webkit = Repository.findById(MockData.webkitRepositoryId());
923             const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
924             assert.equal(testGroup.buildRequests().length, 6);
925
926             const buildRequest = testGroup.buildRequests()[0];
927             assert(buildRequest.isBuild());
928             assert(!buildRequest.isTest());
929             assert.equal(buildRequest.statusLabel(), 'Completed');
930             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
931             assert.notEqual(buildRequest.buildId(), null);
932
933             const commitSet = buildRequest.commitSet();
934             assert.equal(commitSet.revisionForRepository(webkit), '191622');
935             assert.equal(commitSet.patchForRepository(webkit), null);
936             assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
937             assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
938             const webkitRoot = commitSet.rootForRepository(webkit);
939             assert(webkitRoot instanceof UploadedFile);
940             assert.equal(webkitRoot.filename(), 'root123.dat');
941             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
942
943             const otherBuildRequest = testGroup.buildRequests()[1];
944             assert(otherBuildRequest.isBuild());
945             assert(!otherBuildRequest.isTest());
946             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
947             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
948             assert.notEqual(otherBuildRequest.buildId(), null);
949
950             const otherCommitSet = otherBuildRequest.commitSet();
951             assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
952             assert.equal(otherCommitSet.patchForRepository(webkit), null);
953             assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
954             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
955             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
956             assert(otherWebkitRoot instanceof UploadedFile);
957             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
958             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
959         });
960     });
961 });