New buildbot syncing scripts that supports multiple builders and slaves
[WebKit-https.git] / Websites / perf.webkit.org / server-tests / tools-buildbot-triggerable-tests.js
1 'use strict';
2
3 let assert = require('assert');
4
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');
9
10 class MockLogger {
11     constructor()
12     {
13         this._logs = [];
14     }
15
16     log(text) { this._logs.push(text); }
17     error(text) { this._logs.push(text); }
18 }
19
20 describe('BuildbotTriggerable', function () {
21     this.timeout(10000);
22     TestServer.inject();
23
24     beforeEach(function () {
25         MockData.resetV3Models();
26         MockRemoteAPI.reset('http://build.webkit.org');
27     });
28
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();
32             let syncPromise;
33             db.connect().then(function () {
34                 return MockData.addMockData(db, ['completed', 'running', 'pending', 'pending']);
35             }).then(function () {
36                 return Manifest.fetch();
37             }).then(function () {
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();
45             }).then(function () {
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();
55             }).then(function () {
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();
60             }).then(function () {
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();
66             }).then(function () {
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();
71             }).then(function () {
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()});
75                 return syncPromise;
76             }).then(function () {
77                 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithSingleBuilder().triggerableName);
78             }).then(function () {
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');
84                 done();
85             }).catch(done);
86         });
87
88         it('should not schedule the next build request when there is a pending build', function (done) {
89             let db = TestServer.database();
90             let syncPromise;
91             db.connect().then(function () {
92                 return MockData.addMockData(db, ['completed', 'running', 'pending', 'pending']);
93             }).then(function () {
94                 return Manifest.fetch();
95             }).then(function () {
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()});
122                 return syncPromise;
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');
136                 done();
137             }).catch(done);
138         });
139
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();
142             let syncPromise;
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-builder-2/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-builder-2/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-builder-2/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-builder-2/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-builder-2/builds/?select=-1&select=-2');
196                 MockRemoteAPI.requests[8].resolve({});
197                 return syncPromise;
198             }).then(function () {
199                 assert.equal(BuildRequest.all().length, 4);
200                 assert.equal(BuildRequest.findById(700).status(), 'pending');
201                 assert.equal(BuildRequest.findById(701).status(), 'pending');
202                 assert.equal(BuildRequest.findById(702).status(), 'pending');
203                 assert.equal(BuildRequest.findById(703).status(), 'pending');
204                 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
205             }).then(function () {
206                 assert.equal(BuildRequest.all().length, 4);
207                 assert.equal(BuildRequest.findById(700).status(), 'scheduled');
208                 assert.equal(BuildRequest.findById(701).status(), 'pending');
209                 assert.equal(BuildRequest.findById(702).status(), 'pending');
210                 assert.equal(BuildRequest.findById(703).status(), 'pending');
211                 done();
212             }).catch(done);
213         });
214
215         it('should not schedule a build request on a different builder than the one the first build request is pending', function (done) {
216             let db = TestServer.database();
217             let syncPromise;
218             db.connect().then(function () {
219                 return MockData.addMockData(db, ['pending', 'pending', 'pending', 'pending']);
220             }).then(function () {
221                 return Manifest.fetch();
222             }).then(function () {
223                 let config = MockData.mockTestSyncConfigWithTwoBuilders();
224                 let logger = new MockLogger;
225                 let slaveInfo = {name: 'sync-slave', password: 'password'};
226                 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
227                 syncPromise = triggerable.syncOnce();
228                 syncPromise.catch(done);
229                 return MockRemoteAPI.waitForRequest();
230             }).then(function () {
231                 assert.equal(MockRemoteAPI.requests.length, 2);
232                 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
233                 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
234                 MockRemoteAPI.requests[0].resolve([MockData.pendingBuild({buildRequestId: 700})]);
235                 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
236                 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-2/pendingBuilds');
237                 MockRemoteAPI.requests[1].resolve([]);
238                 return MockRemoteAPI.waitForRequest();
239             }).then(function () {
240                 assert.equal(MockRemoteAPI.requests.length, 4);
241                 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
242                 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
243                 MockRemoteAPI.requests[2].resolve({});
244                 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
245                 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some-builder-2/builds/?select=-1&select=-2');
246                 MockRemoteAPI.requests[3].resolve({});
247                 return MockRemoteAPI.waitForRequest();
248             }).then(function () {
249                 assert.equal(MockRemoteAPI.requests.length, 6);
250                 assert.equal(MockRemoteAPI.requests[4].method, 'GET');
251                 assert.equal(MockRemoteAPI.requests[4].url, '/json/builders/some-builder-1/pendingBuilds');
252                 MockRemoteAPI.requests[4].resolve([MockData.pendingBuild({buildRequestId: 700})]);
253                 assert.equal(MockRemoteAPI.requests[5].method, 'GET');
254                 assert.equal(MockRemoteAPI.requests[5].url, '/json/builders/some-builder-2/pendingBuilds');
255                 MockRemoteAPI.requests[5].resolve([]);
256                 return MockRemoteAPI.waitForRequest();
257             }).then(function () {
258                 assert.equal(MockRemoteAPI.requests.length, 8);
259                 assert.equal(MockRemoteAPI.requests[6].method, 'GET');
260                 assert.equal(MockRemoteAPI.requests[6].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
261                 MockRemoteAPI.requests[6].resolve({});
262                 assert.equal(MockRemoteAPI.requests[7].method, 'GET');
263                 assert.equal(MockRemoteAPI.requests[7].url, '/json/builders/some-builder-2/builds/?select=-1&select=-2');
264                 MockRemoteAPI.requests[7].resolve({});
265                 return syncPromise;
266             }).then(function () {
267                 assert.equal(BuildRequest.all().length, 4);
268                 assert.equal(BuildRequest.findById(700).status(), 'pending');
269                 assert.equal(BuildRequest.findById(701).status(), 'pending');
270                 assert.equal(BuildRequest.findById(702).status(), 'pending');
271                 assert.equal(BuildRequest.findById(703).status(), 'pending');
272                 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
273             }).then(function () {
274                 assert.equal(BuildRequest.all().length, 4);
275                 assert.equal(BuildRequest.findById(700).status(), 'scheduled');
276                 assert.equal(BuildRequest.findById(701).status(), 'pending');
277                 assert.equal(BuildRequest.findById(702).status(), 'pending');
278                 assert.equal(BuildRequest.findById(703).status(), 'pending');
279                 done();
280             }).catch(done);
281         });
282
283         it('should update the status of a pending build and schedule a new build if the pending build had started running', function (done) {
284             let db = TestServer.database();
285             let syncPromise;
286             db.connect().then(function () {
287                 return MockData.addMockData(db, ['pending', 'pending', 'pending', 'pending']);
288             }).then(function () {
289                 return Manifest.fetch();
290             }).then(function () {
291                 let config = MockData.mockTestSyncConfigWithTwoBuilders();
292                 let logger = new MockLogger;
293                 let slaveInfo = {name: 'sync-slave', password: 'password'};
294                 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
295                 syncPromise = triggerable.syncOnce();
296                 syncPromise.catch(done);
297                 return MockRemoteAPI.waitForRequest();
298             }).then(function () {
299                 assert.equal(MockRemoteAPI.requests.length, 2);
300                 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
301                 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
302                 MockRemoteAPI.requests[0].resolve([]);
303                 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
304                 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-2/pendingBuilds');
305                 MockRemoteAPI.requests[1].resolve([]);
306                 return MockRemoteAPI.waitForRequest();
307             }).then(function () {
308                 assert.equal(MockRemoteAPI.requests.length, 4);
309                 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
310                 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
311                 MockRemoteAPI.requests[2].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
312                 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
313                 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some-builder-2/builds/?select=-1&select=-2');
314                 MockRemoteAPI.requests[3].resolve({});
315                 return MockRemoteAPI.waitForRequest();
316             }).then(function () {
317                 assert.equal(MockRemoteAPI.requests.length, 5);
318                 assert.equal(MockRemoteAPI.requests[4].method, 'POST');
319                 assert.equal(MockRemoteAPI.requests[4].url, '/builders/some-builder-1/force');
320                 assert.deepEqual(MockRemoteAPI.requests[4].data, {'wk': '191622', 'os': '10.11 15A284', 'build-request-id': '702'});
321                 MockRemoteAPI.requests[4].resolve('OK');
322                 return MockRemoteAPI.waitForRequest();
323             }).then(function () {
324                 assert.equal(MockRemoteAPI.requests.length, 7);
325                 assert.equal(MockRemoteAPI.requests[5].method, 'GET');
326                 assert.equal(MockRemoteAPI.requests[5].url, '/json/builders/some-builder-1/pendingBuilds');
327                 MockRemoteAPI.requests[5].resolve([MockData.pendingBuild({buildRequestId: 702})]);
328                 assert.equal(MockRemoteAPI.requests[6].method, 'GET');
329                 assert.equal(MockRemoteAPI.requests[6].url, '/json/builders/some-builder-2/pendingBuilds');
330                 MockRemoteAPI.requests[6].resolve([]);
331                 return MockRemoteAPI.waitForRequest();
332             }).then(function () {
333                 assert.equal(MockRemoteAPI.requests.length, 9);
334                 assert.equal(MockRemoteAPI.requests[7].method, 'GET');
335                 assert.equal(MockRemoteAPI.requests[7].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
336                 MockRemoteAPI.requests[7].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
337                 assert.equal(MockRemoteAPI.requests[8].method, 'GET');
338                 assert.equal(MockRemoteAPI.requests[8].url, '/json/builders/some-builder-2/builds/?select=-1&select=-2');
339                 MockRemoteAPI.requests[8].resolve({});
340                 return syncPromise;
341             }).then(function () {
342                 assert.equal(BuildRequest.all().length, 4);
343                 assert.equal(BuildRequest.findById(700).status(), 'pending');
344                 assert.equal(BuildRequest.findById(701).status(), 'pending');
345                 assert.equal(BuildRequest.findById(702).status(), 'pending');
346                 assert.equal(BuildRequest.findById(703).status(), 'pending');
347                 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
348             }).then(function () {
349                 assert.equal(BuildRequest.all().length, 4);
350                 assert.equal(BuildRequest.findById(700).status(), 'failed');
351                 assert.equal(BuildRequest.findById(701).status(), 'running');
352                 assert.equal(BuildRequest.findById(702).status(), 'scheduled');
353                 assert.equal(BuildRequest.findById(703).status(), 'pending');
354                 done();
355             }).catch(done);
356         });
357
358         it('should schedule a build request on a builder without pending builds if the request belongs to a new test group', function (done) {
359             let db = TestServer.database();
360             let syncPromise;
361             db.connect().then(function () {
362                 return Promise.all([
363                     MockData.addMockData(db, ['completed', 'pending', 'pending', 'pending']),
364                     MockData.addAnotherMockTestGroup(db, ['pending', 'pending', 'pending', 'pending'])
365                 ]);
366             }).then(function () {
367                 return Manifest.fetch();
368             }).then(function () {
369                 let config = MockData.mockTestSyncConfigWithTwoBuilders();
370                 let logger = new MockLogger;
371                 let slaveInfo = {name: 'sync-slave', password: 'password'};
372                 let triggerable = new BuildbotTriggerable(config, TestServer.remoteAPI(), MockRemoteAPI, slaveInfo, logger);
373                 syncPromise = triggerable.syncOnce();
374                 syncPromise.catch(done);
375                 return MockRemoteAPI.waitForRequest();
376             }).then(function () {
377                 assert.equal(MockRemoteAPI.requests.length, 2);
378                 assert.equal(MockRemoteAPI.requests[0].method, 'GET');
379                 assert.equal(MockRemoteAPI.requests[0].url, '/json/builders/some-builder-1/pendingBuilds');
380                 MockRemoteAPI.requests[0].resolve([MockData.pendingBuild({buildRequestId: 702})]);
381                 assert.equal(MockRemoteAPI.requests[1].method, 'GET');
382                 assert.equal(MockRemoteAPI.requests[1].url, '/json/builders/some-builder-2/pendingBuilds');
383                 MockRemoteAPI.requests[1].resolve([]);
384                 return MockRemoteAPI.waitForRequest();
385             }).then(function () {
386                 assert.equal(MockRemoteAPI.requests.length, 4);
387                 assert.equal(MockRemoteAPI.requests[2].method, 'GET');
388                 assert.equal(MockRemoteAPI.requests[2].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
389                 MockRemoteAPI.requests[2].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
390                 assert.equal(MockRemoteAPI.requests[3].method, 'GET');
391                 assert.equal(MockRemoteAPI.requests[3].url, '/json/builders/some-builder-2/builds/?select=-1&select=-2');
392                 MockRemoteAPI.requests[3].resolve({});
393                 return MockRemoteAPI.waitForRequest();
394             }).then(function () {
395                 assert.equal(MockRemoteAPI.requests.length, 5);
396                 assert.equal(MockRemoteAPI.requests[4].method, 'POST');
397                 assert.equal(MockRemoteAPI.requests[4].url, '/builders/some-builder-2/force');
398                 assert.deepEqual(MockRemoteAPI.requests[4].data, {'wk': '191622', 'os': '10.11 15A284', 'build-request-id': '710'});
399                 MockRemoteAPI.requests[4].resolve('OK');
400                 return MockRemoteAPI.waitForRequest();
401             }).then(function () {
402                 assert.equal(MockRemoteAPI.requests.length, 7);
403                 assert.equal(MockRemoteAPI.requests[5].method, 'GET');
404                 assert.equal(MockRemoteAPI.requests[5].url, '/json/builders/some-builder-1/pendingBuilds');
405                 MockRemoteAPI.requests[5].resolve([MockData.pendingBuild({buildRequestId: 702})]);
406                 assert.equal(MockRemoteAPI.requests[6].method, 'GET');
407                 assert.equal(MockRemoteAPI.requests[6].url, '/json/builders/some-builder-2/pendingBuilds');
408                 MockRemoteAPI.requests[6].resolve([MockData.pendingBuild({builder: 'some-builder-2', buildRequestId: 710})]);
409                 return MockRemoteAPI.waitForRequest();
410             }).then(function () {
411                 assert.equal(MockRemoteAPI.requests.length, 9);
412                 assert.equal(MockRemoteAPI.requests[7].method, 'GET');
413                 assert.equal(MockRemoteAPI.requests[7].url, '/json/builders/some-builder-1/builds/?select=-1&select=-2');
414                 MockRemoteAPI.requests[7].resolve({[-1]: MockData.runningBuild({buildRequestId: 701}), [-2]: MockData.finishedBuild({buildRequestId: 700})});
415                 assert.equal(MockRemoteAPI.requests[8].method, 'GET');
416                 assert.equal(MockRemoteAPI.requests[8].url, '/json/builders/some-builder-2/builds/?select=-1&select=-2');
417                 MockRemoteAPI.requests[8].resolve({});
418                 return syncPromise;
419             }).then(function () {
420                 assert.equal(BuildRequest.all().length, 8);
421                 assert.equal(BuildRequest.findById(700).status(), 'completed');
422                 assert.equal(BuildRequest.findById(701).status(), 'pending');
423                 assert.equal(BuildRequest.findById(702).status(), 'pending');
424                 assert.equal(BuildRequest.findById(703).status(), 'pending');
425                 assert.equal(BuildRequest.findById(710).status(), 'pending');
426                 assert.equal(BuildRequest.findById(711).status(), 'pending');
427                 assert.equal(BuildRequest.findById(712).status(), 'pending');
428                 assert.equal(BuildRequest.findById(713).status(), 'pending');
429                 return BuildRequest.fetchForTriggerable(MockData.mockTestSyncConfigWithTwoBuilders().triggerableName);
430             }).then(function () {
431                 assert.equal(BuildRequest.all().length, 8);
432                 assert.equal(BuildRequest.findById(700).status(), 'completed');
433                 assert.equal(BuildRequest.findById(701).status(), 'running');
434                 assert.equal(BuildRequest.findById(702).status(), 'scheduled');
435                 assert.equal(BuildRequest.findById(703).status(), 'pending');
436                 assert.equal(BuildRequest.findById(710).status(), 'scheduled');
437                 assert.equal(BuildRequest.findById(711).status(), 'pending');
438                 assert.equal(BuildRequest.findById(712).status(), 'pending');
439                 assert.equal(BuildRequest.findById(713).status(), 'pending');
440                 done();
441             }).catch(done);
442         });
443     });
444 });