bada57a1b654f70ee264df01b040e255bb7f9fb5
[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.initSyncers().then(() => 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.initSyncers().then(() => 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.dat'),
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.initSyncers().then(() => 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.initSyncers().then(() => 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         }).then(() => {
468             assert.equal(requests.length, 10);
469             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', [
470                 MockData.pendingBuild({builder: 'some tester', buildRequestId: 3}),
471             ]);
472             assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
473             assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
474             return MockRemoteAPI.waitForRequest();
475         }).then(() => {
476             assert.equal(requests.length, 13);
477             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
478             assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
479                 [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
480                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 2}),
481             });
482             assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
483             return syncPromise;
484         });
485     });
486
487     it('should not schedule a build to test while building a patch', () => {
488         const requests = MockRemoteAPI.requests;
489         let triggerable;
490         let taskId = null;
491         let syncPromise;
492         return createTriggerable().then((newTriggerable) => {
493             triggerable = newTriggerable;
494             return createTestGroupWihPatch();
495         }).then((testGroup) => {
496             taskId = testGroup.task().id();
497             assert.equal(testGroup.buildRequests().length, 6);
498
499             const buildRequest = testGroup.buildRequests()[0];
500             assert.equal(buildRequest.id(), 1);
501             assert(buildRequest.isBuild());
502             assert(!buildRequest.isTest());
503             assert.equal(buildRequest.statusLabel(), 'Waiting');
504             assert.equal(buildRequest.statusUrl(), null);
505             assert.equal(buildRequest.buildId(), null);
506
507             const otherBuildRequest = testGroup.buildRequests()[1];
508             assert.equal(otherBuildRequest.id(), 2);
509             assert(otherBuildRequest.isBuild());
510             assert(!otherBuildRequest.isTest());
511             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
512             assert.equal(otherBuildRequest.statusUrl(), null);
513             assert.equal(otherBuildRequest.buildId(), null);
514
515             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
516             return Promise.all([MockRemoteAPI.waitForRequest(), uploadRoot(1, 123)]);
517         }).then(() => {
518             assert.equal(requests.length, 3);
519             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
520             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
521             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
522             return MockRemoteAPI.waitForRequest();
523         }).then(() => {
524             assert.equal(requests.length, 6);
525             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
526             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
527                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
528                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
529             });
530             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
531             return MockRemoteAPI.waitForRequest();
532         }).then(() => {
533             assert.equal(requests.length, 9);
534             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
535             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
536             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
537             return MockRemoteAPI.waitForRequest();
538         }).then(() => {
539             assert.equal(requests.length, 12);
540             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
541             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
542                 [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2, buildNumber: 1002}),
543                 [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
544             });
545             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
546             return syncPromise;
547         }).then(() => {
548             return TestGroup.fetchForTask(taskId, true);
549         }).then((testGroups) => {
550             assert.equal(testGroups.length, 1);
551
552             const testGroup = testGroups[0];
553             const buildRequest = testGroup.buildRequests()[0];
554             assert.equal(buildRequest.id(), 1);
555             assert(buildRequest.isBuild());
556             assert(!buildRequest.isTest());
557             assert.equal(buildRequest.statusLabel(), 'Completed');
558             assert.equal(buildRequest.statusUrl(), null);
559             assert.notEqual(buildRequest.buildId(), null);
560
561             const otherBuildRequest = testGroup.buildRequests()[1];
562             assert.equal(otherBuildRequest.id(), 2);
563             assert(otherBuildRequest.isBuild());
564             assert(!otherBuildRequest.isTest());
565             assert.equal(otherBuildRequest.statusLabel(), 'Running');
566             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/1002');
567             assert.equal(otherBuildRequest.buildId(), null);
568         });
569     });
570
571     it('should cancel builds for testing when a build to build a patch fails', () => {
572         const requests = MockRemoteAPI.requests;
573         let triggerable;
574         let taskId = null;
575         let syncPromise;
576         return createTriggerable().then((newTriggerable) => {
577             triggerable = newTriggerable;
578             return createTestGroupWihPatch();
579         }).then((testGroup) => {
580             taskId = testGroup.task().id();
581             assert.equal(testGroup.buildRequests().length, 6);
582
583             const buildRequest = testGroup.buildRequests()[0];
584             assert.equal(buildRequest.id(), 1);
585             assert(buildRequest.isBuild());
586             assert(!buildRequest.isTest());
587             assert.equal(buildRequest.statusLabel(), 'Waiting');
588             assert.equal(buildRequest.statusUrl(), null);
589             assert.equal(buildRequest.buildId(), null);
590
591             const otherBuildRequest = testGroup.buildRequests()[1];
592             assert.equal(otherBuildRequest.id(), 2);
593             assert(otherBuildRequest.isBuild());
594             assert(!otherBuildRequest.isTest());
595             assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
596             assert.equal(otherBuildRequest.statusUrl(), null);
597             assert.equal(otherBuildRequest.buildId(), null);
598
599             syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
600             return MockRemoteAPI.waitForRequest();
601         }).then(() => {
602             assert.equal(requests.length, 3);
603             assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
604             assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
605             assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
606             return MockRemoteAPI.waitForRequest();
607         }).then(() => {
608             assert.equal(requests.length, 6);
609             assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
610             assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
611             assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
612                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
613             });
614             return MockRemoteAPI.waitForRequest();
615         }).then(() => {
616             assert.equal(requests.length, 9);
617             assertAndResolveRequest(requests[6], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
618             assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
619             assertAndResolveRequest(requests[8], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
620             return MockRemoteAPI.waitForRequest();
621         }).then(() => {
622             assert.equal(requests.length, 12);
623             assertAndResolveRequest(requests[9], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
624             assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
625             assertAndResolveRequest(requests[11], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {
626                 [-1]: MockData.finishedBuild({builder: 'other builder', buildRequestId: 1, buildNumber: 312}),
627             });
628             return syncPromise;
629         }).then(() => {
630             return TestGroup.fetchForTask(taskId, true);
631         }).then((testGroups) => {
632             assert.equal(testGroups.length, 1);
633
634             const buildReqeusts = testGroups[0].buildRequests();
635             assert(buildReqeusts[0].isBuild());
636             assert(!buildReqeusts[0].isTest());
637             assert.equal(buildReqeusts[0].statusLabel(), 'Failed');
638             assert.equal(buildReqeusts[0].statusUrl(), 'http://build.webkit.org/builders/other%20builder/builds/312');
639             assert.equal(buildReqeusts[0].buildId(), null);
640
641             assert(buildReqeusts[1].isBuild());
642             assert(!buildReqeusts[1].isTest());
643             assert.equal(buildReqeusts[1].statusLabel(), 'Failed');
644             assert.equal(buildReqeusts[1].statusUrl(), null);
645             assert.equal(buildReqeusts[1].buildId(), null);
646
647             function assertTestBuildHasFailed(request)
648             {
649                 assert(!request.isBuild());
650                 assert(request.isTest());
651                 assert.equal(request.statusLabel(), 'Failed');
652                 assert.equal(request.statusUrl(), null);
653                 assert.equal(request.buildId(), null);
654             }
655
656             assertTestBuildHasFailed(buildReqeusts[2]);
657             assertTestBuildHasFailed(buildReqeusts[3]);
658         });
659     });
660
661 });