3 let assert = require('assert');
5 let BuildbotTriggerable = require('../tools/js/buildbot-triggerable.js').BuildbotTriggerable;
6 let MockData = require('./resources/mock-data.js');
7 let MockRemoteAPI = require('../unit-tests/resources/mock-remote-api.js').MockRemoteAPI;
8 let TestServer = require('./resources/test-server.js');
16 log(text) { this._logs.push(text); }
17 error(text) { this._logs.push(text); }
20 describe('BuildbotTriggerable', function () {
24 beforeEach(function () {
25 MockData.resetV3Models();
26 MockRemoteAPI.reset('http://build.webkit.org');
29 describe('syncOnce', function () {
30 it('should schedule the next build request when there are no pending builds', function (done) {
31 let db = TestServer.database();
33 db.connect().then(function () {
34 return MockData.addMockData(db, ['completed', 'running', 'pending', 'pending']);
36 return Manifest.fetch();
38 let config = MockData.mockTestSyncConfigWithSingleBuilder();
39 let logger = new MockLogger;
40 let slaveInfo = {name: 'sync-slave', password: 'password'};
41 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
42 syncPromise = triggerable.syncOnce();
43 syncPromise.catch(done);
44 return MockRemoteAPI.waitForRequest();
46 assert.equal(BuildRequest.all().length, 4);
47 assert.equal(BuildRequest.findById(700).status(), 'completed');
48 assert.equal(BuildRequest.findById(701).status(), 'running');
49 assert.equal(BuildRequest.findById(702).status(), 'pending');
50 assert.equal(BuildRequest.findById(703).status(), 'pending');
51 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
52 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
53 MockRemoteAPI.requests[0].resolve([]);
54 return MockRemoteAPI.waitForRequest();
56 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
57 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
58 MockRemoteAPI.requests[1].resolve({[-1]: MockData.runningBuild(), [-2]: MockData.finishedBuild()});
59 return MockRemoteAPI.waitForRequest();
61 assert.equal(MockRemoteAPI.requests[2].method, 'POST');
62 assert.equal(MockRemoteAPI.requests[2].url, '/builders/some-builder-1/force');
63 assert.deepEqual(MockRemoteAPI.requests[2].data, {'wk': '191622', 'os': '10.11 15A284', 'build-request-id': '702'});
64 MockRemoteAPI.requests[2].resolve('OK');
65 return MockRemoteAPI.waitForRequest();
67 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
68 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some-builder-1/pendingBuilds');
69 MockRemoteAPI.requests[3].resolve([MockData.pendingBuild()])
70 return MockRemoteAPI.waitForRequest();
72 assert.equal(MockRemoteAPI.requests[4].method, 'GET');
73 assert.equal(MockRemoteAPI.requests[4].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
74 MockRemoteAPI.requests[4].resolve({[-1]: MockData.runningBuild(), [-2]: MockData.finishedBuild()});
77 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithSingleBuilder().triggerableName);
79 assert.equal(BuildRequest.all().length, 4);
80 assert.equal(BuildRequest.findById(700).status(), 'completed');
81 assert.equal(BuildRequest.findById(701).status(), 'running');
82 assert.equal(BuildRequest.findById(702).status(), 'scheduled');
83 assert.equal(BuildRequest.findById(703).status(), 'pending');
88 it('should not schedule the next build request when there is a pending build', function (done) {
89 let db = TestServer.database();
91 db.connect().then(function () {
92 return MockData.addMockData(db, ['completed', 'running', 'pending', 'pending']);
94 return Manifest.fetch();
96 let config = MockData.mockTestSyncConfigWithSingleBuilder();
97 let logger = new MockLogger;
98 let slaveInfo = {name: 'sync-slave', password: 'password'};
99 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
100 syncPromise = triggerable.syncOnce();
101 syncPromise.catch(done);
102 return MockRemoteAPI.waitForRequest();
103 }).then(function () {
104 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
105 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
106 MockRemoteAPI.requests[0].resolve([MockData.pendingBuild()]);
107 return MockRemoteAPI.waitForRequest();
108 }).then(function () {
109 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
110 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
111 MockRemoteAPI.requests[1].resolve({[-1]: MockData.runningBuild(), [-2]: MockData.finishedBuild()});
112 return MockRemoteAPI.waitForRequest();
113 }).then(function () {
114 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
115 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/pendingBuilds');
116 MockRemoteAPI.requests[2].resolve([MockData.pendingBuild()])
117 return MockRemoteAPI.waitForRequest();
118 }).then(function () {
119 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
120 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
121 MockRemoteAPI.requests[3].resolve({[-1]: MockData.runningBuild(), [-2]: MockData.finishedBuild()});
123 }).then(function () {
124 assert.equal(BuildRequest.all().length, 4);
125 assert.equal(BuildRequest.findById(700).status(), 'completed');
126 assert.equal(BuildRequest.findById(701).status(), 'running');
127 assert.equal(BuildRequest.findById(702).status(), 'pending');
128 assert.equal(BuildRequest.findById(703).status(), 'pending');
129 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithSingleBuilder().triggerableName);
130 }).then(function () {
131 assert.equal(BuildRequest.all().length, 4);
132 assert.equal(BuildRequest.findById(700).status(), 'completed');
133 assert.equal(BuildRequest.findById(701).status(), 'running');
134 assert.equal(BuildRequest.findById(702).status(), 'scheduled');
135 assert.equal(BuildRequest.findById(703).status(), 'pending');
140 it('should schedule the build request on a builder without a pending build if it\'s the first request in the group', function (done) {
141 let db = TestServer.database();
143 db.connect().then(function () {
144 return MockData.addMockData(db, ['pending', 'pending', 'pending', 'pending']);
145 }).then(function () {
146 return Manifest.fetch();
147 }).then(function () {
148 let config = MockData.mockTestSyncConfigWithTwoBuilders();
149 let logger = new MockLogger;
150 let slaveInfo = {name: 'sync-slave', password: 'password'};
151 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
152 syncPromise = triggerable.syncOnce();
153 syncPromise.catch(done);
154 return MockRemoteAPI.waitForRequest();
155 }).then(function () {
156 assert.equal(MockRemoteAPI.requests.length, 2);
157 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
158 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
159 MockRemoteAPI.requests[0].resolve([MockData.pendingBuild({buildRequestId: 999})]);
160 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
161 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some%20builder%202/pendingBuilds');
162 MockRemoteAPI.requests[1].resolve([]);
163 return MockRemoteAPI.waitForRequest();
164 }).then(function () {
165 assert.equal(MockRemoteAPI.requests.length, 4);
166 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
167 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
168 MockRemoteAPI.requests[2].resolve({});
169 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
170 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
171 MockRemoteAPI.requests[3].resolve({});
172 return MockRemoteAPI.waitForRequest();
173 }).then(function () {
174 assert.equal(MockRemoteAPI.requests.length, 5);
175 assert.equal(MockRemoteAPI.requests[4].method, 'POST');
176 assert.equal(MockRemoteAPI.requests[4].url, '/builders/some%20builder%202/force');
177 assert.deepEqual(MockRemoteAPI.requests[4].data, {'wk': '191622', 'os': '10.11 15A284', 'build-request-id': '700'});
178 MockRemoteAPI.requests[4].resolve('OK');
179 return MockRemoteAPI.waitForRequest();
180 }).then(function () {
181 assert.equal(MockRemoteAPI.requests.length, 7);
182 assert.equal(MockRemoteAPI.requests[5].method, 'GET');
183 assert.equal(MockRemoteAPI.requests[5].url, '/json/builders/some-builder-1/pendingBuilds');
184 MockRemoteAPI.requests[5].resolve([MockData.pendingBuild({buildRequestId: 999})]);
185 assert.equal(MockRemoteAPI.requests[6].method, 'GET');
186 assert.equal(MockRemoteAPI.requests[6].url, '/json/builders/some%20builder%202/pendingBuilds');
187 MockRemoteAPI.requests[6].resolve([MockData.pendingBuild({builder: 'some builder 2', buildRequestId: 700})]);
188 return MockRemoteAPI.waitForRequest();
189 }).then(function () {
190 assert.equal(MockRemoteAPI.requests.length, 9);
191 assert.equal(MockRemoteAPI.requests[7].method, 'GET');
192 assert.equal(MockRemoteAPI.requests[7].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
193 MockRemoteAPI.requests[7].resolve({});
194 assert.equal(MockRemoteAPI.requests[8].method, 'GET');
195 assert.equal(MockRemoteAPI.requests[8].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
196 MockRemoteAPI.requests[8].resolve({});
198 }).then(function () {
199 assert.equal(BuildRequest.all().length, 4);
200 assert.equal(BuildRequest.findById(700).status(), 'pending');
201 assert.equal(BuildRequest.findById(700).statusUrl(), null);
202 assert.equal(BuildRequest.findById(701).status(), 'pending');
203 assert.equal(BuildRequest.findById(701).statusUrl(), null);
204 assert.equal(BuildRequest.findById(702).status(), 'pending');
205 assert.equal(BuildRequest.findById(702).statusUrl(), null);
206 assert.equal(BuildRequest.findById(703).status(), 'pending');
207 assert.equal(BuildRequest.findById(703).statusUrl(), null);
208 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
209 }).then(function () {
210 assert.equal(BuildRequest.all().length, 4);
211 assert.equal(BuildRequest.findById(700).status(), 'scheduled');
212 assert.equal(BuildRequest.findById(700).statusUrl(), 'http://build.webkit.org/builders/some%20builder%202/');
213 assert.equal(BuildRequest.findById(701).status(), 'pending');
214 assert.equal(BuildRequest.findById(701).statusUrl(), null);
215 assert.equal(BuildRequest.findById(702).status(), 'pending');
216 assert.equal(BuildRequest.findById(702).statusUrl(), null);
217 assert.equal(BuildRequest.findById(703).status(), 'pending');
218 assert.equal(BuildRequest.findById(703).statusUrl(), null);
223 it('should not schedule a build request on a different builder than the one the first build request is pending', function (done) {
224 let db = TestServer.database();
226 db.connect().then(function () {
227 return MockData.addMockData(db, ['pending', 'pending', 'pending', 'pending']);
228 }).then(function () {
229 return Manifest.fetch();
230 }).then(function () {
231 let config = MockData.mockTestSyncConfigWithTwoBuilders();
232 let logger = new MockLogger;
233 let slaveInfo = {name: 'sync-slave', password: 'password'};
234 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
235 syncPromise = triggerable.syncOnce();
236 syncPromise.catch(done);
237 return MockRemoteAPI.waitForRequest();
238 }).then(function () {
239 assert.equal(MockRemoteAPI.requests.length, 2);
240 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
241 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
242 MockRemoteAPI.requests[0].resolve([MockData.pendingBuild({buildRequestId: 700})]);
243 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
244 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some%20builder%202/pendingBuilds');
245 MockRemoteAPI.requests[1].resolve([]);
246 return MockRemoteAPI.waitForRequest();
247 }).then(function () {
248 assert.equal(MockRemoteAPI.requests.length, 4);
249 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
250 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
251 MockRemoteAPI.requests[2].resolve({});
252 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
253 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
254 MockRemoteAPI.requests[3].resolve({});
255 return MockRemoteAPI.waitForRequest();
256 }).then(function () {
257 assert.equal(MockRemoteAPI.requests.length, 6);
258 assert.equal(MockRemoteAPI.requests[4].method, 'GET');
259 assert.equal(MockRemoteAPI.requests[4].url, '/json/builders/some-builder-1/pendingBuilds');
260 MockRemoteAPI.requests[4].resolve([MockData.pendingBuild({buildRequestId: 700})]);
261 assert.equal(MockRemoteAPI.requests[5].method, 'GET');
262 assert.equal(MockRemoteAPI.requests[5].url, '/json/builders/some%20builder%202/pendingBuilds');
263 MockRemoteAPI.requests[5].resolve([]);
264 return MockRemoteAPI.waitForRequest();
265 }).then(function () {
266 assert.equal(MockRemoteAPI.requests.length, 8);
267 assert.equal(MockRemoteAPI.requests[6].method, 'GET');
268 assert.equal(MockRemoteAPI.requests[6].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
269 MockRemoteAPI.requests[6].resolve({});
270 assert.equal(MockRemoteAPI.requests[7].method, 'GET');
271 assert.equal(MockRemoteAPI.requests[7].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
272 MockRemoteAPI.requests[7].resolve({});
274 }).then(function () {
275 assert.equal(BuildRequest.all().length, 4);
276 assert.equal(BuildRequest.findById(700).status(), 'pending');
277 assert.equal(BuildRequest.findById(700).statusUrl(), null);
278 assert.equal(BuildRequest.findById(701).status(), 'pending');
279 assert.equal(BuildRequest.findById(701).statusUrl(), null);
280 assert.equal(BuildRequest.findById(702).status(), 'pending');
281 assert.equal(BuildRequest.findById(702).statusUrl(), null);
282 assert.equal(BuildRequest.findById(703).status(), 'pending');
283 assert.equal(BuildRequest.findById(703).statusUrl(), null);
284 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
285 }).then(function () {
286 assert.equal(BuildRequest.all().length, 4);
287 assert.equal(BuildRequest.findById(700).status(), 'scheduled');
288 assert.equal(BuildRequest.findById(700).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/');
289 assert.equal(BuildRequest.findById(701).status(), 'pending');
290 assert.equal(BuildRequest.findById(701).statusUrl(), null);
291 assert.equal(BuildRequest.findById(702).status(), 'pending');
292 assert.equal(BuildRequest.findById(702).statusUrl(), null);
293 assert.equal(BuildRequest.findById(703).status(), 'pending');
294 assert.equal(BuildRequest.findById(703).statusUrl(), null);
299 it('should update the status of a pending build and schedule a new build if the pending build had started running', function (done) {
300 let db = TestServer.database();
302 db.connect().then(function () {
303 return MockData.addMockData(db, ['pending', 'pending', 'pending', 'pending']);
304 }).then(function () {
305 return Manifest.fetch();
306 }).then(function () {
307 let config = MockData.mockTestSyncConfigWithTwoBuilders();
308 let logger = new MockLogger;
309 let slaveInfo = {name: 'sync-slave', password: 'password'};
310 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
311 syncPromise = triggerable.syncOnce();
312 syncPromise.catch(done);
313 return MockRemoteAPI.waitForRequest();
314 }).then(function () {
315 assert.equal(MockRemoteAPI.requests.length, 2);
316 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
317 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
318 MockRemoteAPI.requests[0].resolve([]);
319 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
320 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some%20builder%202/pendingBuilds');
321 MockRemoteAPI.requests[1].resolve([]);
322 return MockRemoteAPI.waitForRequest();
323 }).then(function () {
324 assert.equal(MockRemoteAPI.requests.length, 4);
325 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
326 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
327 MockRemoteAPI.requests[2].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
328 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
329 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
330 MockRemoteAPI.requests[3].resolve({});
331 return MockRemoteAPI.waitForRequest();
332 }).then(function () {
333 assert.equal(MockRemoteAPI.requests.length, 5);
334 assert.equal(MockRemoteAPI.requests[4].method, 'POST');
335 assert.equal(MockRemoteAPI.requests[4].url, '/builders/some-builder-1/force');
336 assert.deepEqual(MockRemoteAPI.requests[4].data, {'wk': '191622', 'os': '10.11 15A284', 'build-request-id': '702'});
337 MockRemoteAPI.requests[4].resolve('OK');
338 return MockRemoteAPI.waitForRequest();
339 }).then(function () {
340 assert.equal(MockRemoteAPI.requests.length, 7);
341 assert.equal(MockRemoteAPI.requests[5].method, 'GET');
342 assert.equal(MockRemoteAPI.requests[5].url, '/json/builders/some-builder-1/pendingBuilds');
343 MockRemoteAPI.requests[5].resolve([MockData.pendingBuild({buildRequestId: 702})]);
344 assert.equal(MockRemoteAPI.requests[6].method, 'GET');
345 assert.equal(MockRemoteAPI.requests[6].url, '/json/builders/some%20builder%202/pendingBuilds');
346 MockRemoteAPI.requests[6].resolve([]);
347 return MockRemoteAPI.waitForRequest();
348 }).then(function () {
349 assert.equal(MockRemoteAPI.requests.length, 9);
350 assert.equal(MockRemoteAPI.requests[7].method, 'GET');
351 assert.equal(MockRemoteAPI.requests[7].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
352 MockRemoteAPI.requests[7].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
353 assert.equal(MockRemoteAPI.requests[8].method, 'GET');
354 assert.equal(MockRemoteAPI.requests[8].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
355 MockRemoteAPI.requests[8].resolve({});
357 }).then(function () {
358 assert.equal(BuildRequest.all().length, 4);
359 assert.equal(BuildRequest.findById(700).status(), 'pending');
360 assert.equal(BuildRequest.findById(700).statusUrl(), null);
361 assert.equal(BuildRequest.findById(701).status(), 'pending');
362 assert.equal(BuildRequest.findById(701).statusUrl(), null);
363 assert.equal(BuildRequest.findById(702).status(), 'pending');
364 assert.equal(BuildRequest.findById(702).statusUrl(), null);
365 assert.equal(BuildRequest.findById(703).status(), 'pending');
366 assert.equal(BuildRequest.findById(703).statusUrl(), null);
367 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
368 }).then(function () {
369 assert.equal(BuildRequest.all().length, 4);
370 assert.equal(BuildRequest.findById(700).status(), 'failed');
371 assert.equal(BuildRequest.findById(700).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/builds/123');
372 assert.equal(BuildRequest.findById(701).status(), 'running');
373 assert.equal(BuildRequest.findById(701).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/builds/124');
374 assert.equal(BuildRequest.findById(702).status(), 'scheduled');
375 assert.equal(BuildRequest.findById(702).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/');
376 assert.equal(BuildRequest.findById(703).status(), 'pending');
377 assert.equal(BuildRequest.findById(703).statusUrl(), null);
382 it('should update the status of a scheduled build if the pending build had started running', function (done) {
383 let db = TestServer.database();
385 db.connect().then(function () {
386 return MockData.addMockData(db, ['scheduled', 'pending', 'pending', 'pending']);
387 }).then(function () {
388 return Manifest.fetch();
389 }).then(function () {
390 let config = MockData.mockTestSyncConfigWithSingleBuilder();
391 let logger = new MockLogger;
392 let slaveInfo = {name: 'sync-slave', password: 'password'};
393 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
394 syncPromise = triggerable.syncOnce();
395 syncPromise.catch(done);
396 return MockRemoteAPI.waitForRequest();
397 }).then(function () {
398 assert.equal(MockRemoteAPI.requests.length, 1);
399 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
400 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
401 MockRemoteAPI.requests[0].resolve([MockData.pendingBuild({buildRequestId: 700})]);
402 return MockRemoteAPI.waitForRequest();
403 }).then(function () {
404 assert.equal(MockRemoteAPI.requests.length, 2);
405 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
406 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
407 MockRemoteAPI.requests[1].resolve({});
408 return MockRemoteAPI.waitForRequest();
409 }).then(function () {
410 assert.equal(MockRemoteAPI.requests.length, 3);
411 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
412 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/pendingBuilds');
413 MockRemoteAPI.requests[2].resolve([]);
414 return MockRemoteAPI.waitForRequest();
415 }).then(function () {
416 assert.equal(MockRemoteAPI.requests.length, 4);
417 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
418 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
419 MockRemoteAPI.requests[3].resolve({[-1]: MockData.runningBuild({buildRequestId: 700})});
421 }).then(function () {
422 assert.equal(BuildRequest.all().length, 4);
423 assert.equal(BuildRequest.findById(700).status(), 'scheduled');
424 assert.equal(BuildRequest.findById(700).statusUrl(), null);
425 assert.equal(BuildRequest.findById(701).status(), 'pending');
426 assert.equal(BuildRequest.findById(701).statusUrl(), null);
427 assert.equal(BuildRequest.findById(702).status(), 'pending');
428 assert.equal(BuildRequest.findById(702).statusUrl(), null);
429 assert.equal(BuildRequest.findById(703).status(), 'pending');
430 assert.equal(BuildRequest.findById(703).statusUrl(), null);
431 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
432 }).then(function () {
433 assert.equal(BuildRequest.all().length, 4);
434 assert.equal(BuildRequest.findById(700).status(), 'running');
435 assert.equal(BuildRequest.findById(700).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/builds/124');
436 assert.equal(BuildRequest.findById(701).status(), 'pending');
437 assert.equal(BuildRequest.findById(701).statusUrl(), null);
438 assert.equal(BuildRequest.findById(702).status(), 'pending');
439 assert.equal(BuildRequest.findById(702).statusUrl(), null);
440 assert.equal(BuildRequest.findById(703).status(), 'pending');
441 assert.equal(BuildRequest.findById(703).statusUrl(), null);
446 it('should schedule a build request on a builder without pending builds if the request belongs to a new test group', function (done) {
447 let db = TestServer.database();
449 db.connect().then(function () {
451 MockData.addMockData(db, ['completed', 'pending', 'pending', 'pending']),
452 MockData.addAnotherMockTestGroup(db, ['pending', 'pending', 'pending', 'pending'])
454 }).then(function () {
455 return Manifest.fetch();
456 }).then(function () {
457 let config = MockData.mockTestSyncConfigWithTwoBuilders();
458 let logger = new MockLogger;
459 let slaveInfo = {name: 'sync-slave', password: 'password'};
460 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
461 syncPromise = triggerable.syncOnce();
462 syncPromise.catch(done);
463 return MockRemoteAPI.waitForRequest();
464 }).then(function () {
465 assert.equal(MockRemoteAPI.requests.length, 2);
466 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
467 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
468 MockRemoteAPI.requests[0].resolve([MockData.pendingBuild({buildRequestId: 702})]);
469 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
470 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some%20builder%202/pendingBuilds');
471 MockRemoteAPI.requests[1].resolve([]);
472 return MockRemoteAPI.waitForRequest();
473 }).then(function () {
474 assert.equal(MockRemoteAPI.requests.length, 4);
475 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
476 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
477 MockRemoteAPI.requests[2].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
478 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
479 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
480 MockRemoteAPI.requests[3].resolve({});
481 return MockRemoteAPI.waitForRequest();
482 }).then(function () {
483 assert.equal(MockRemoteAPI.requests.length, 5);
484 assert.equal(MockRemoteAPI.requests[4].method, 'POST');
485 assert.equal(MockRemoteAPI.requests[4].url, '/builders/some%20builder%202/force');
486 assert.deepEqual(MockRemoteAPI.requests[4].data, {'wk': '191622', 'os': '10.11 15A284', 'build-request-id': '710'});
487 MockRemoteAPI.requests[4].resolve('OK');
488 return MockRemoteAPI.waitForRequest();
489 }).then(function () {
490 assert.equal(MockRemoteAPI.requests.length, 7);
491 assert.equal(MockRemoteAPI.requests[5].method, 'GET');
492 assert.equal(MockRemoteAPI.requests[5].url, '/json/builders/some-builder-1/pendingBuilds');
493 MockRemoteAPI.requests[5].resolve([MockData.pendingBuild({buildRequestId: 702})]);
494 assert.equal(MockRemoteAPI.requests[6].method, 'GET');
495 assert.equal(MockRemoteAPI.requests[6].url, '/json/builders/some%20builder%202/pendingBuilds');
496 MockRemoteAPI.requests[6].resolve([MockData.pendingBuild({builder: 'some builder 2', buildRequestId: 710})]);
497 return MockRemoteAPI.waitForRequest();
498 }).then(function () {
499 assert.equal(MockRemoteAPI.requests.length, 9);
500 assert.equal(MockRemoteAPI.requests[7].method, 'GET');
501 assert.equal(MockRemoteAPI.requests[7].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
502 MockRemoteAPI.requests[7].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
503 assert.equal(MockRemoteAPI.requests[8].method, 'GET');
504 assert.equal(MockRemoteAPI.requests[8].url, '/json/builders/some%20builder%202/builds/?select=-1&select=-2');
505 MockRemoteAPI.requests[8].resolve({});
507 }).then(function () {
508 assert.equal(BuildRequest.all().length, 8);
509 assert.equal(BuildRequest.findById(700).status(), 'completed');
510 assert.equal(BuildRequest.findById(700).statusUrl(), null);
511 assert.equal(BuildRequest.findById(701).status(), 'pending');
512 assert.equal(BuildRequest.findById(701).statusUrl(), null);
513 assert.equal(BuildRequest.findById(702).status(), 'pending');
514 assert.equal(BuildRequest.findById(702).statusUrl(), null);
515 assert.equal(BuildRequest.findById(703).status(), 'pending');
516 assert.equal(BuildRequest.findById(703).statusUrl(), null);
517 assert.equal(BuildRequest.findById(710).status(), 'pending');
518 assert.equal(BuildRequest.findById(710).statusUrl(), null);
519 assert.equal(BuildRequest.findById(711).status(), 'pending');
520 assert.equal(BuildRequest.findById(711).statusUrl(), null);
521 assert.equal(BuildRequest.findById(712).status(), 'pending');
522 assert.equal(BuildRequest.findById(712).statusUrl(), null);
523 assert.equal(BuildRequest.findById(713).status(), 'pending');
524 assert.equal(BuildRequest.findById(713).statusUrl(), null);
525 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
526 }).then(function () {
527 assert.equal(BuildRequest.all().length, 8);
528 assert.equal(BuildRequest.findById(700).status(), 'completed');
529 assert.equal(BuildRequest.findById(700).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/builds/123');
530 assert.equal(BuildRequest.findById(701).status(), 'running');
531 assert.equal(BuildRequest.findById(701).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/builds/124');
532 assert.equal(BuildRequest.findById(702).status(), 'scheduled');
533 assert.equal(BuildRequest.findById(702).statusUrl(), 'http://build.webkit.org/builders/some-builder-1/');
534 assert.equal(BuildRequest.findById(703).status(), 'pending');
535 assert.equal(BuildRequest.findById(703).statusUrl(), null);
536 assert.equal(BuildRequest.findById(710).status(), 'scheduled');
537 assert.equal(BuildRequest.findById(710).statusUrl(), 'http://build.webkit.org/builders/some%20builder%202/');
538 assert.equal(BuildRequest.findById(711).status(), 'pending');
539 assert.equal(BuildRequest.findById(711).statusUrl(), null);
540 assert.equal(BuildRequest.findById(712).status(), 'pending');
541 assert.equal(BuildRequest.findById(712).statusUrl(), null);
542 assert.equal(BuildRequest.findById(713).status(), 'pending');
543 assert.equal(BuildRequest.findById(713).statusUrl(), null);
548 it('should update the status of a supposedly scheduled build that went missing', function (done) {
549 let db = TestServer.database();
551 db.connect().then(function () {
552 return MockData.addMockData(db, ['scheduled', 'pending', 'pending', 'pending']);
553 }).then(function () {
554 return Manifest.fetch();
555 }).then(function () {
556 let config = MockData.mockTestSyncConfigWithSingleBuilder();
557 let logger = new MockLogger;
558 let slaveInfo = {name: 'sync-slave', password: 'password'};
559 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
560 syncPromise = triggerable.syncOnce();
561 syncPromise.catch(done);
562 return MockRemoteAPI.waitForRequest();
563 }).then(function () {
564 assert.equal(MockRemoteAPI.requests.length, 1);
565 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
566 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
567 MockRemoteAPI.requests[0].resolve([]);
568 return MockRemoteAPI.waitForRequest();
569 }).then(function () {
570 assert.equal(MockRemoteAPI.requests.length, 2);
571 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
572 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
573 MockRemoteAPI.requests[1].resolve({});
574 return MockRemoteAPI.waitForRequest();
575 }).then(function () {
576 assert.equal(MockRemoteAPI.requests.length, 3);
577 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
578 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/pendingBuilds');
579 MockRemoteAPI.requests[2].resolve([]);
580 return MockRemoteAPI.waitForRequest();
581 }).then(function () {
582 assert.equal(MockRemoteAPI.requests.length, 4);
583 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
584 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
585 MockRemoteAPI.requests[3].resolve({});
587 }).then(function () {
588 assert.equal(BuildRequest.all().length, 4);
589 assert.equal(BuildRequest.findById(700).status(), 'scheduled');
590 assert.equal(BuildRequest.findById(701).status(), 'pending');
591 assert.equal(BuildRequest.findById(702).status(), 'pending');
592 assert.equal(BuildRequest.findById(703).status(), 'pending');
593 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
594 }).then(function () {
595 assert.equal(BuildRequest.all().length, 4);
596 assert.equal(BuildRequest.findById(700).status(), 'failed');
597 assert.equal(BuildRequest.findById(701).status(), 'pending');
598 assert.equal(BuildRequest.findById(702).status(), 'pending');
599 assert.equal(BuildRequest.findById(703).status(), 'pending');
604 it('should schedule a build request of an user created test group before ones created by automatic change detection', function (done) {
605 let db = TestServer.database();
607 db.connect().then(function () {
609 MockData.addMockData(db, ['pending', 'pending', 'pending', 'pending']),
610 MockData.addAnotherMockTestGroup(db, ['pending', 'pending', 'pending', 'pending'], 'rniwa'),
612 }).then(function () {
613 return Manifest.fetch();
614 }).then(function () {
615 let config = MockData.mockTestSyncConfigWithSingleBuilder();
616 let logger = new MockLogger;
617 let slaveInfo = {name: 'sync-slave', password: 'password'};
618 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
619 syncPromise = triggerable.syncOnce();
620 syncPromise.catch(done);
621 return MockRemoteAPI.waitForRequest();
622 }).then(function () {
623 assert.equal(MockRemoteAPI.requests.length, 1);
624 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
625 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
626 MockRemoteAPI.requests[0].resolve([]);
627 return MockRemoteAPI.waitForRequest();
628 }).then(function () {
629 assert.equal(MockRemoteAPI.requests.length, 2);
630 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
631 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
632 MockRemoteAPI.requests[1].resolve({});
633 return MockRemoteAPI.waitForRequest();
634 }).then(function () {
635 assert.equal(MockRemoteAPI.requests.length, 3);
636 assert.equal(MockRemoteAPI.requests[2].method, 'POST');
637 assert.equal(MockRemoteAPI.requests[2].url, '/builders/some-builder-1/force');
638 assert.deepEqual(MockRemoteAPI.requests[2].data, {'wk': '191622', 'os': '10.11 15A284', 'build-request-id': '710'});
639 MockRemoteAPI.requests[2].resolve('OK');