Add the support for perf try bots to sync-buildbot.js
[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                     acceptsRoots: true,
31                 }
32             },
33             types: {
34                 'some': {
35                     test: ['some test'],
36                     properties: {'test': 'some-test'},
37                 }
38             },
39             builders: {
40                 'builder-1': {
41                     builder: 'some tester',
42                     properties: {forcescheduler: 'force-ab-tests'},
43                 },
44                 'builder-2': {
45                     builder: 'some builder',
46                     properties: {forcescheduler: 'force-ab-builds'},
47                 },
48                 'builder-3': {
49                     builder: 'other builder',
50                     properties: {forcescheduler: 'force-ab-builds'},
51                 },
52             },
53             buildConfigurations: [
54                 {platforms: ['some platform'], builders: ['builder-2', 'builder-3']},
55             ],
56             testConfigurations: [
57                 {types: ['some'], platforms: ['some platform'], builders: ['builder-1']},
58             ],
59         };
60     return MockData.addMockConfiguration(TestServer.database()).then(() => {
61         return Manifest.fetch();
62     }).then(() => {
63         triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, {name: 'sync-slave', password: 'password'}, new MockLogger);
64         return triggerable.updateTriggerable();
65     }).then(() => Manifest.fetch()).then(() => {
66         return new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, {name: 'sync-slave', password: 'password'}, new MockLogger);
67     });
68 }
69
70 function createTestGroupWihPatch()
71 {
72     return TemporaryFile.makeTemporaryFile('patch.dat', 'patch file').then((patchFile) => {
73         return UploadedFile.uploadFile(patchFile);
74     }).then((patchFile) => {
75         const someTest = Test.findById(MockData.someTestId());
76         const webkit = Repository.findById(MockData.webkitRepositoryId());
77         const set1 = new CustomCommitSet;
78         set1.setRevisionForRepository(webkit, '191622', patchFile);
79         const set2 = new CustomCommitSet;
80         set2.setRevisionForRepository(webkit, '191622');
81         return TestGroup.createWithTask('custom task', Platform.findById(MockData.somePlatformId()), someTest, 'some group', 2, [set1, set2]);
82     }).then((task) => {
83         return TestGroup.findAllByTask(task.id())[0];
84     })
85 }
86
87 function uploadRoot(buildRequestId, buildNumber)
88 {
89     return TemporaryFile.makeTemporaryFile(`root${buildNumber}.dat`, `root for build ${buildNumber}`).then((rootFile) => {
90         return TestServer.remoteAPI().postFormData('/api/upload-root/', {
91             slaveName: 'sync-slave',
92             slavePassword: 'password',
93             builderName: 'some builder',
94             buildNumber: buildNumber,
95             buildTime: '2017-05-10T02:54:08.666',
96             buildRequest: buildRequestId,
97             rootFile,
98             repositoryList: '["WebKit"]',
99         });
100     });
101 }
102
103 describe('sync-buildbot', function () {
104     prepareServerTest(this);
105     TemporaryFile.inject();
106
107     beforeEach(() => {
108         MockRemoteAPI.reset('http://build.webkit.org');
109     });
110
111     function assertAndResolveRequest(request, method, url, contentToResolve)
112     {
113         assert.equal(request.method, method);
114         assert.equal(request.url, url);
115         request.resolve(contentToResolve);
116     }
117
118     it('should schedule a build to build a patch', () => {
119         const requests = MockRemoteAPI.requests;
120         let triggerable;
121         let taskId = null;
122         let syncPromise;
123         return createTriggerable().then((newTriggerable) => {
124             triggerable = newTriggerable;
125             return createTestGroupWihPatch();
126         }).then((testGroup) => {
127             taskId = testGroup.task().id();
128             const webkit = Repository.findById(MockData.webkitRepositoryId());
129             assert.equal(testGroup.buildRequests().length, 6);
130
131             const buildRequest = testGroup.buildRequests()[0];
132             assert(buildRequest.isBuild());
133             assert(!buildRequest.isTest());
134             assert.equal(buildRequest.statusLabel(), 'Waiting');
135             assert.equal(buildRequest.statusUrl(), null);
136             assert.equal(buildRequest.buildId(), null);
137
138             const commitSet = buildRequest.commitSet();
139             assert.equal(commitSet.revisionForRepository(webkit), '191622');
140             const webkitPatch = commitSet.patchForRepository(webkit);
141             assert(webkitPatch instanceof UploadedFile);
142             assert.equal(webkitPatch.filename(), 'patch.dat');
143             assert.equal(commitSet.rootForRepository(webkit), null);
144             assert.deepEqual(commitSet.allRootFiles(), []);
145
146             const otherBuildRequest = testGroup.buildRequests()[1];
147             assert(otherBuildRequest.isBuild());
148             assert(!otherBuildRequest.isTest());
149             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
150             assert.equal(otherBuildRequest.statusUrl(), null);
151             assert.equal(otherBuildRequest.buildId(), null);
152
153             const otherCommitSet = otherBuildRequest.commitSet();
154             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
155             assert.equal(otherCommitSet.patchForRepository(webkit), null);
156             assert.equal(otherCommitSet.rootForRepository(webkit), null);
157             assert.deepEqual(otherCommitSet.allRootFiles(), []);
158
159             syncPromise = triggerable.syncOnce();
160             return MockRemoteAPI.waitForRequest();
161         }).then(() => {
162             assert.equal(requests.length, 3);
163             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
164             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
165             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
166             return MockRemoteAPI.waitForRequest();
167         }).then(() => {
168             assert.equal(requests.length, 6);
169             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
170             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
171             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
172             return MockRemoteAPI.waitForRequest();
173         }).then(() => {
174             assert.equal(requests.length, 7);
175             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
176             assert.deepEqual(requests[6].data, {'wk': '191622', 'wk-patch': RemoteAPI.url('/api/uploaded-file/1'),
177                 'build-request-id': '1', 'forcescheduler': 'force-ab-builds'});
178             return MockRemoteAPI.waitForRequest();
179         }).then(() => {
180             assert.equal(requests.length, 10);
181             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
182             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
183                 [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
184             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
185             return MockRemoteAPI.waitForRequest();
186         }).then(() => {
187             assert.equal(requests.length, 13);
188             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
189             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
190                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
191             });
192             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
193             return syncPromise;
194         }).then(() => {
195             return TestGroup.fetchForTask(taskId, true);
196         }).then((testGroups) => {
197             assert.equal(testGroups.length, 1);
198             const testGroup = testGroups[0];
199             const webkit = Repository.findById(MockData.webkitRepositoryId());
200             assert.equal(testGroup.buildRequests().length, 6);
201
202             const buildRequest = testGroup.buildRequests()[0];
203             assert(buildRequest.isBuild());
204             assert(!buildRequest.isTest());
205             assert.equal(buildRequest.statusLabel(), 'Running');
206             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
207             assert.equal(buildRequest.buildId(), null);
208
209             const commitSet = buildRequest.commitSet();
210             assert.equal(commitSet.revisionForRepository(webkit), '191622');
211             const webkitPatch = commitSet.patchForRepository(webkit);
212             assert(webkitPatch instanceof UploadedFile);
213             assert.equal(webkitPatch.filename(), 'patch.dat');
214             assert.equal(commitSet.rootForRepository(webkit), null);
215             assert.deepEqual(commitSet.allRootFiles(), []);
216
217             const otherBuildRequest = testGroup.buildRequests()[1];
218             assert(otherBuildRequest.isBuild());
219             assert(!otherBuildRequest.isTest());
220             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
221             assert.equal(otherBuildRequest.statusUrl(), null);
222             assert.equal(otherBuildRequest.buildId(), null);
223
224             const otherCommitSet = otherBuildRequest.commitSet();
225             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
226             assert.equal(otherCommitSet.patchForRepository(webkit), null);
227             assert.equal(otherCommitSet.rootForRepository(webkit), null);
228             assert.deepEqual(otherCommitSet.allRootFiles(), []);
229
230             return uploadRoot(buildRequest.id(), 123);
231         }).then(() => {
232             return TestGroup.fetchForTask(taskId, true);
233         }).then((testGroups) => {
234             assert.equal(testGroups.length, 1);
235             const testGroup = testGroups[0];
236             const webkit = Repository.findById(MockData.webkitRepositoryId());
237             assert.equal(testGroup.buildRequests().length, 6);
238
239             const buildRequest = testGroup.buildRequests()[0];
240             assert(buildRequest.isBuild());
241             assert(!buildRequest.isTest());
242             assert.equal(buildRequest.statusLabel(), 'Completed');
243             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
244             assert.notEqual(buildRequest.buildId(), null);
245
246             const commitSet = buildRequest.commitSet();
247             assert.equal(commitSet.revisionForRepository(webkit), '191622');
248             const webkitPatch = commitSet.patchForRepository(webkit);
249             assert(webkitPatch instanceof UploadedFile);
250             assert.equal(webkitPatch.filename(), 'patch.dat');
251             const webkitRoot = commitSet.rootForRepository(webkit);
252             assert(webkitRoot instanceof UploadedFile);
253             assert.equal(webkitRoot.filename(), 'root123.dat');
254             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
255
256             const otherBuildRequest = testGroup.buildRequests()[1];
257             assert(otherBuildRequest.isBuild());
258             assert(!otherBuildRequest.isTest());
259             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
260             assert.equal(otherBuildRequest.statusUrl(), null);
261             assert.equal(otherBuildRequest.buildId(), null);
262
263             const otherCommitSet = otherBuildRequest.commitSet();
264             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
265             assert.equal(otherCommitSet.patchForRepository(webkit), null);
266             assert.equal(otherCommitSet.rootForRepository(webkit), null);
267             assert.deepEqual(otherCommitSet.allRootFiles(), []);
268
269             MockRemoteAPI.reset();
270             syncPromise = triggerable.syncOnce();
271             return MockRemoteAPI.waitForRequest();
272         }).then(() => {
273             assert.equal(requests.length, 3);
274             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
275             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
276             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
277             return MockRemoteAPI.waitForRequest();
278         }).then(() => {
279             assert.equal(requests.length, 6);
280             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
281             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
282                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
283             });
284             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
285             return MockRemoteAPI.waitForRequest();
286         }).then(() => {
287             assert.equal(requests.length, 7);
288             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
289             assert.deepEqual(requests[6].data, {'wk': '191622', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds'});
290             return MockRemoteAPI.waitForRequest();
291         }).then(() => {
292             assert.equal(requests.length, 10);
293             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
294             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
295             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
296             return MockRemoteAPI.waitForRequest();
297         }).then(() => {
298             assert.equal(requests.length, 13);
299             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
300             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
301                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
302                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
303             });
304             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
305             return syncPromise;
306         }).then(() => {
307             return TestGroup.fetchForTask(taskId, true);
308         }).then((testGroups) => {
309             assert.equal(testGroups.length, 1);
310             const testGroup = testGroups[0];
311             const webkit = Repository.findById(MockData.webkitRepositoryId());
312             assert.equal(testGroup.buildRequests().length, 6);
313
314             const buildRequest = testGroup.buildRequests()[0];
315             assert(buildRequest.isBuild());
316             assert(!buildRequest.isTest());
317             assert.equal(buildRequest.statusLabel(), 'Completed');
318             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
319             assert.notEqual(buildRequest.buildId(), null);
320
321             const commitSet = buildRequest.commitSet();
322             assert.equal(commitSet.revisionForRepository(webkit), '191622');
323             const webkitPatch = commitSet.patchForRepository(webkit);
324             assert(webkitPatch instanceof UploadedFile);
325             assert.equal(webkitPatch.filename(), 'patch.dat');
326             const webkitRoot = commitSet.rootForRepository(webkit);
327             assert(webkitRoot instanceof UploadedFile);
328             assert.equal(webkitRoot.filename(), 'root123.dat');
329             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
330
331             const otherBuildRequest = testGroup.buildRequests()[1];
332             assert(otherBuildRequest.isBuild());
333             assert(!otherBuildRequest.isTest());
334             assert.equal(otherBuildRequest.statusLabel(), 'Running');
335             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
336             assert.equal(otherBuildRequest.buildId(), null);
337
338             const otherCommitSet = otherBuildRequest.commitSet();
339             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
340             assert.equal(otherCommitSet.patchForRepository(webkit), null);
341             assert.equal(otherCommitSet.rootForRepository(webkit), null);
342             assert.deepEqual(otherCommitSet.allRootFiles(), []);
343
344             return uploadRoot(otherBuildRequest.id(), 124);
345         }).then(() => {
346             return TestGroup.fetchForTask(taskId, true);
347         }).then((testGroups) => {
348             assert.equal(testGroups.length, 1);
349             const testGroup = testGroups[0];
350             const webkit = Repository.findById(MockData.webkitRepositoryId());
351             assert.equal(testGroup.buildRequests().length, 6);
352
353             const buildRequest = testGroup.buildRequests()[0];
354             assert(buildRequest.isBuild());
355             assert(!buildRequest.isTest());
356             assert.equal(buildRequest.statusLabel(), 'Completed');
357             assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
358             assert.notEqual(buildRequest.buildId(), null);
359
360             const commitSet = buildRequest.commitSet();
361             assert.equal(commitSet.revisionForRepository(webkit), '191622');
362             const webkitPatch = commitSet.patchForRepository(webkit);
363             assert(webkitPatch instanceof UploadedFile);
364             assert.equal(webkitPatch.filename(), 'patch.dat');
365             const webkitRoot = commitSet.rootForRepository(webkit);
366             assert(webkitRoot instanceof UploadedFile);
367             assert.equal(webkitRoot.filename(), 'root123.dat');
368             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
369
370             const otherBuildRequest = testGroup.buildRequests()[1];
371             assert(otherBuildRequest.isBuild());
372             assert(!otherBuildRequest.isTest());
373             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
374             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
375             assert.notEqual(otherBuildRequest.buildId(), null);
376
377             const otherCommitSet = otherBuildRequest.commitSet();
378             assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
379             assert.equal(otherCommitSet.patchForRepository(webkit), null);
380             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
381             assert(otherWebkitRoot instanceof UploadedFile);
382             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
383             assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
384         });
385     });
386
387     it('should schedule a build to test after building a patch', () => {
388         const requests = MockRemoteAPI.requests;
389         let triggerable;
390         let taskId = null;
391         let syncPromise;
392         let firstRoot = null;
393         return createTriggerable().then((newTriggerable) => {
394             triggerable = newTriggerable;
395             return createTestGroupWihPatch();
396         }).then((testGroup) => {
397             taskId = testGroup.task().id();
398             const webkit = Repository.findById(MockData.webkitRepositoryId());
399             assert.equal(testGroup.buildRequests().length, 6);
400
401             const buildRequest = testGroup.buildRequests()[0];
402             assert.equal(buildRequest.id(), 1);
403             assert(buildRequest.isBuild());
404             assert(!buildRequest.isTest());
405             assert.equal(buildRequest.statusLabel(), 'Waiting');
406             assert.equal(buildRequest.buildId(), null);
407             assert.deepEqual(buildRequest.commitSet().allRootFiles(), []);
408
409             const otherBuildRequest = testGroup.buildRequests()[1];
410             assert.equal(otherBuildRequest.id(), 2);
411             assert(otherBuildRequest.isBuild());
412             assert(!otherBuildRequest.isTest());
413             assert.equal(buildRequest.statusLabel(), 'Waiting');
414             assert.equal(otherBuildRequest.buildId(), null);
415             assert.deepEqual(otherBuildRequest.commitSet().allRootFiles(), []);
416
417             return uploadRoot(1, 45);
418         }).then(() => {
419             return uploadRoot(2, 46);
420         }).then(() => {
421             return TestGroup.fetchForTask(taskId, true);
422         }).then((testGroups) => {
423             assert.equal(testGroups.length, 1);
424             const testGroup = testGroups[0];
425
426             const buildRequest = testGroup.buildRequests()[0];
427             assert(buildRequest.isBuild());
428             assert(!buildRequest.isTest());
429             assert.equal(buildRequest.statusLabel(), 'Completed');
430             assert.notEqual(buildRequest.buildId(), null);
431             const roots = buildRequest.commitSet().allRootFiles();
432             assert.equal(roots.length, 1);
433             firstRoot = roots[0];
434             assert.deepEqual(roots[0].filename(), 'root45.dat');
435
436             const otherBuildRequest = testGroup.buildRequests()[1];
437             assert(otherBuildRequest.isBuild());
438             assert(!otherBuildRequest.isTest());
439             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
440             assert.notEqual(otherBuildRequest.buildId(), null);
441             const otherRoots = otherBuildRequest.commitSet().allRootFiles();
442             assert.equal(otherRoots.length, 1);
443             assert.deepEqual(otherRoots[0].filename(), 'root46.dat');
444             syncPromise = triggerable.syncOnce();
445             return MockRemoteAPI.waitForRequest();
446         }).then(() => {
447             assert.equal(requests.length, 3);
448             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
449             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
450             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
451             return MockRemoteAPI.waitForRequest();
452         }).then(() => {
453             assert.equal(requests.length, 6);
454             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
455             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
456                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
457                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 2}),
458             });
459             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
460             return MockRemoteAPI.waitForRequest();
461         }).then(() => {
462             assert.equal(requests.length, 7);
463             assertAndResolveRequest(requests[6], 'POST', '/builders/some%20tester/force', 'OK');
464             assert.deepEqual(requests[6].data, {'test': 'some-test', 'wk': '191622', 'build-request-id': '3', 'forcescheduler': 'force-ab-tests',
465                 'roots': JSON.stringify([{url: firstRoot.url()}])});
466             return MockRemoteAPI.waitForRequest();
467         });
468     });
469
470     it('should not schedule a build to test while building a patch', () => {
471         const requests = MockRemoteAPI.requests;
472         let triggerable;
473         let taskId = null;
474         let syncPromise;
475         return createTriggerable().then((newTriggerable) => {
476             triggerable = newTriggerable;
477             return createTestGroupWihPatch();
478         }).then((testGroup) => {
479             taskId = testGroup.task().id();
480             assert.equal(testGroup.buildRequests().length, 6);
481
482             const buildRequest = testGroup.buildRequests()[0];
483             assert.equal(buildRequest.id(), 1);
484             assert(buildRequest.isBuild());
485             assert(!buildRequest.isTest());
486             assert.equal(buildRequest.statusLabel(), 'Waiting');
487             assert.equal(buildRequest.statusUrl(), null);
488             assert.equal(buildRequest.buildId(), null);
489
490             const otherBuildRequest = testGroup.buildRequests()[1];
491             assert.equal(otherBuildRequest.id(), 2);
492             assert(otherBuildRequest.isBuild());
493             assert(!otherBuildRequest.isTest());
494             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
495             assert.equal(otherBuildRequest.statusUrl(), null);
496             assert.equal(otherBuildRequest.buildId(), null);
497
498             syncPromise = triggerable.syncOnce();
499             return Promise.all([MockRemoteAPI.waitForRequest(), uploadRoot(1, 123)]);
500         }).then(() => {
501             assert.equal(requests.length, 3);
502             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
503             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
504             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
505             return MockRemoteAPI.waitForRequest();
506         }).then(() => {
507             assert.equal(requests.length, 6);
508             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
509             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
510                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
511                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
512             });
513             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
514             return MockRemoteAPI.waitForRequest();
515         }).then(() => {
516             assert.equal(requests.length, 9);
517             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
518             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
519             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
520             return MockRemoteAPI.waitForRequest();
521         }).then(() => {
522             assert.equal(requests.length, 12);
523             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
524             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
525                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2, buildNumber: 1002}),
526                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
527             });
528             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
529             return syncPromise;
530         }).then(() => {
531             return TestGroup.fetchForTask(taskId, true);
532         }).then((testGroups) => {
533             assert.equal(testGroups.length, 1);
534
535             const testGroup = testGroups[0];
536             const buildRequest = testGroup.buildRequests()[0];
537             assert.equal(buildRequest.id(), 1);
538             assert(buildRequest.isBuild());
539             assert(!buildRequest.isTest());
540             assert.equal(buildRequest.statusLabel(), 'Completed');
541             assert.equal(buildRequest.statusUrl(), null);
542             assert.notEqual(buildRequest.buildId(), null);
543
544             const otherBuildRequest = testGroup.buildRequests()[1];
545             assert.equal(otherBuildRequest.id(), 2);
546             assert(otherBuildRequest.isBuild());
547             assert(!otherBuildRequest.isTest());
548             assert.equal(otherBuildRequest.statusLabel(), 'Running');
549             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/1002');
550             assert.equal(otherBuildRequest.buildId(), null);
551         });
552     });
553
554     it('should cancel builds for testing when a build to build a patch fails', () => {
555         const requests = MockRemoteAPI.requests;
556         let triggerable;
557         let taskId = null;
558         let syncPromise;
559         return createTriggerable().then((newTriggerable) => {
560             triggerable = newTriggerable;
561             return createTestGroupWihPatch();
562         }).then((testGroup) => {
563             taskId = testGroup.task().id();
564             assert.equal(testGroup.buildRequests().length, 6);
565
566             const buildRequest = testGroup.buildRequests()[0];
567             assert.equal(buildRequest.id(), 1);
568             assert(buildRequest.isBuild());
569             assert(!buildRequest.isTest());
570             assert.equal(buildRequest.statusLabel(), 'Waiting');
571             assert.equal(buildRequest.statusUrl(), null);
572             assert.equal(buildRequest.buildId(), null);
573
574             const otherBuildRequest = testGroup.buildRequests()[1];
575             assert.equal(otherBuildRequest.id(), 2);
576             assert(otherBuildRequest.isBuild());
577             assert(!otherBuildRequest.isTest());
578             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
579             assert.equal(otherBuildRequest.statusUrl(), null);
580             assert.equal(otherBuildRequest.buildId(), null);
581
582             syncPromise = triggerable.syncOnce();
583             return MockRemoteAPI.waitForRequest();
584         }).then(() => {
585             assert.equal(requests.length, 3);
586             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
587             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
588             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
589             return MockRemoteAPI.waitForRequest();
590         }).then(() => {
591             assert.equal(requests.length, 6);
592             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
593             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
594             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
595                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
596             });
597             return MockRemoteAPI.waitForRequest();
598         }).then(() => {
599             assert.equal(requests.length, 9);
600             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
601             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
602             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
603             return MockRemoteAPI.waitForRequest();
604         }).then(() => {
605             assert.equal(requests.length, 12);
606             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
607             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
608             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
609                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
610             });
611             return syncPromise;
612         }).then(() => {
613             return TestGroup.fetchForTask(taskId, true);
614         }).then((testGroups) => {
615             assert.equal(testGroups.length, 1);
616
617             const buildReqeusts = testGroups[0].buildRequests();
618             assert(buildReqeusts[0].isBuild());
619             assert(!buildReqeusts[0].isTest());
620             assert.equal(buildReqeusts[0].statusLabel(), 'Failed');
621             assert.equal(buildReqeusts[0].statusUrl(), 'http://build.webkit.org/builders/other%20builder/builds/312');
622             assert.equal(buildReqeusts[0].buildId(), null);
623
624             assert(buildReqeusts[1].isBuild());
625             assert(!buildReqeusts[1].isTest());
626             assert.equal(buildReqeusts[1].statusLabel(), 'Failed');
627             assert.equal(buildReqeusts[1].statusUrl(), null);
628             assert.equal(buildReqeusts[1].buildId(), null);
629
630             function assertTestBuildHasFailed(request)
631             {
632                 assert(!request.isBuild());
633                 assert(request.isTest());
634                 assert.equal(request.statusLabel(), 'Failed');
635                 assert.equal(request.statusUrl(), null);
636                 assert.equal(request.buildId(), null);
637             }
638
639             assertTestBuildHasFailed(buildReqeusts[2]);
640             assertTestBuildHasFailed(buildReqeusts[3]);
641         });
642     });
643
644 });