3 const assert = require('assert');
5 const OSBuildFetcher = require('../tools/js/os-build-fetcher.js').OSBuildFetcher;
6 const MockRemoteAPI = require('../unit-tests/resources/mock-remote-api.js').MockRemoteAPI;
7 const TestServer = require('./resources/test-server.js');
8 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
9 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
10 const MockSubprocess = require('./resources/mock-subprocess.js').MockSubprocess;
11 const MockLogger = require('./resources/mock-logger.js').MockLogger;
14 describe('OSBuildFetcher', function() {
18 beforeEach(function () {
19 MockRemoteAPI.reset('http://build.webkit.org');
20 MockSubprocess.reset();
24 'slaveName': 'someSlave',
25 'slavePassword': 'somePassword',
30 'password': 'somePassword'
33 const ownedCommitWithWebKit = {
34 'WebKit': {'revision': '141978'}
37 const anotherownedCommitWithWebKit = {
38 'WebKit': {'revision': '141999'}
41 const anotherownedCommitWithWebKitAndJavaScriptCore = {
42 'WebKit': {'revision': '142000'},
43 'JavaScriptCore': {'revision': '142000'}
48 'revision': 'Sierra16D32',
52 const anotherOSXCommit = {
54 'revision': 'Sierra16E32',
63 'command': ['list', 'all osx 16Dxx builds'],
64 'ownedCommitCommand': ['list', 'ownedCommit', 'for', 'revision'],
65 'linesToIgnore': '^\\.*$',
66 'minRevision': 'Sierra16D0',
67 'maxRevision': 'Sierra16D999'
70 'command': ['list', 'all osx 16Exx builds'],
71 'ownedCommitCommand': ['list', 'ownedCommit', 'for', 'revision'],
72 'linesToIgnore': '^\\.*$',
73 'minRevision': 'Sierra16E0',
74 'maxRevision': 'Sierra16E999'
80 const configWithoutownedCommitCommand = {
84 'command': ['list', 'all osx 16Dxx builds'],
85 'linesToIgnore': '^\\.*$',
86 'minRevision': 'Sierra16D0',
87 'maxRevision': 'Sierra16D999'
90 'command': ['list', 'all osx 16Exx builds'],
91 'linesToIgnore': '^\\.*$',
92 'minRevision': 'Sierra16E0',
93 'maxRevision': 'Sierra16E999'
98 describe('OSBuilderFetcher._computeOrder', () => {
99 it('should calculate the right order for a given valid revision', () => {
100 const fetcher = new OSBuildFetcher({});
101 assert.equal(fetcher._computeOrder('Sierra16D32'), 1603003200);
102 assert.equal(fetcher._computeOrder('16D321'), 1603032100);
103 assert.equal(fetcher._computeOrder('16d321'), 1603032100);
104 assert.equal(fetcher._computeOrder('16D321z'), 1603032126);
105 assert.equal(fetcher._computeOrder('16d321Z'), 1603032126);
106 assert.equal(fetcher._computeOrder('10.12.3 16D32'), 1603003200);
107 assert.equal(fetcher._computeOrder('10.12.3 Sierra16D32'), 1603003200);
110 it('should throw assertion error when given a invalid revision', () => {
111 const fetcher = new OSBuildFetcher({});
112 assert.throws(() => fetcher._computeOrder('invalid'), 'AssertionError [ERR_ASSERTION]');
113 assert.throws(() => fetcher._computeOrder(''), 'AssertionError [ERR_ASSERTION]');
114 assert.throws(() => fetcher._computeOrder('16'), 'AssertionError [ERR_ASSERTION]');
115 assert.throws(() => fetcher._computeOrder('16D'), 'AssertionError [ERR_ASSERTION]');
116 assert.throws(() => fetcher._computeOrder('123'), 'AssertionError [ERR_ASSERTION]');
117 assert.throws(() => fetcher._computeOrder('D123'), 'AssertionError [ERR_ASSERTION]');
118 assert.throws(() => fetcher._computeOrder('123z'), 'AssertionError [ERR_ASSERTION]');
119 assert.throws(() => fetcher._computeOrder('16[163'), 'AssertionError [ERR_ASSERTION]');
120 assert.throws(() => fetcher._computeOrder('16D163['), 'AssertionError [ERR_ASSERTION]');
124 describe('OSBuilderFetcher._commitsForAvailableBuilds', () => {
125 it('should only return commits whose orders are higher than specified order', () => {
126 const logger = new MockLogger;
127 const fetchter = new OSBuildFetcher({}, null, null, MockSubprocess, logger);
128 const waitForInvocationPromise = MockSubprocess.waitForInvocation();
129 const fetchCommitsPromise = fetchter._commitsForAvailableBuilds('OSX', ['list', 'build1'], '^\\.*$', 1604000000);
131 return waitForInvocationPromise.then(() => {
132 assert.equal(MockSubprocess.invocations.length, 1);
133 assert.deepEqual(MockSubprocess.invocations[0].command, ['list', 'build1']);
134 MockSubprocess.invocations[0].resolve('16D321\n16E321z\n\n16F321');
135 return fetchCommitsPromise;
136 }).then((results) => {
137 assert.equal(results.length, 2);
138 assert.deepEqual(results[0], {repository: 'OSX', order: 1604032126, revision: '16E321z'});
139 assert.deepEqual(results[1], {repository: 'OSX', order: 1605032100, revision: '16F321'});
144 describe('OSBuildFetcher._addOwnedCommitsForBuild', () => {
145 it('should add owned-commit info for commits', () => {
146 const logger = new MockLogger;
147 const fetchter = new OSBuildFetcher({}, null, null, MockSubprocess, logger);
148 const waitForInvocationPromise = MockSubprocess.waitForInvocation();
149 const addownedCommitPromise = fetchter._addOwnedCommitsForBuild([osxCommit, anotherOSXCommit], ['ownedCommit', 'for', 'revision']);
151 return waitForInvocationPromise.then(() => {
152 assert.equal(MockSubprocess.invocations.length, 1);
153 assert.deepEqual(MockSubprocess.invocations[0].command, ['ownedCommit', 'for', 'revision', 'Sierra16D32']);
154 MockSubprocess.invocations[0].resolve(JSON.stringify(ownedCommitWithWebKit));
155 MockSubprocess.reset();
156 return MockSubprocess.waitForInvocation();
158 assert.equal(MockSubprocess.invocations.length, 1);
159 assert.deepEqual(MockSubprocess.invocations[0].command, ['ownedCommit', 'for', 'revision', 'Sierra16E32']);
160 MockSubprocess.invocations[0].resolve(JSON.stringify(anotherownedCommitWithWebKit));
161 return addownedCommitPromise;
162 }).then((results) => {
163 assert.equal(results.length, 2);
164 assert.equal(results[0]['repository'], osxCommit['repository']);
165 assert.equal(results[0]['revision'], osxCommit['revision']);
166 assert.deepEqual(results[0]['ownedCommits'], ownedCommitWithWebKit);
167 assert.equal(results[1]['repository'], anotherOSXCommit['repository']);
168 assert.equal(results[1]['revision'], anotherOSXCommit['revision']);
169 assert.deepEqual(results[1]['ownedCommits'], anotherownedCommitWithWebKit);
173 it('should fail if the command to get owned-commit info fails', () => {
174 const logger = new MockLogger;
175 const fetchter = new OSBuildFetcher({}, null, null, MockSubprocess, logger);
176 const waitForInvocationPromise = MockSubprocess.waitForInvocation();
177 const addownedCommitPromise = fetchter._addOwnedCommitsForBuild([osxCommit], ['ownedCommit', 'for', 'revision'])
179 return waitForInvocationPromise.then(() => {
180 assert.equal(MockSubprocess.invocations.length, 1);
181 assert.deepEqual(MockSubprocess.invocations[0].command, ['ownedCommit', 'for', 'revision', 'Sierra16D32']);
182 MockSubprocess.invocations[0].reject('Failed getting owned-commit');
184 return addownedCommitPromise.then(() => {
185 assert(false, 'should never be reached');
186 }, (error_output) => {
187 assert(error_output);
188 assert.equal(error_output, 'Failed getting owned-commit');
194 it('should fail if entries in owned-commits does not contain revision', () => {
195 const logger = new MockLogger;
196 const fetchter = new OSBuildFetcher({}, null, null, MockSubprocess, logger);
197 const waitForInvocationPromise = MockSubprocess.waitForInvocation();
198 const addownedCommitPromise = fetchter._addOwnedCommitsForBuild([osxCommit], ['ownedCommit', 'for', 'revision'])
200 return waitForInvocationPromise.then(() => {
201 assert.equal(MockSubprocess.invocations.length, 1);
202 assert.deepEqual(MockSubprocess.invocations[0].command, ['ownedCommit', 'for', 'revision', 'Sierra16D32']);
203 MockSubprocess.invocations[0].resolve('{"WebKit":{"RandomKey": "RandomValue"}}');
205 return addownedCommitPromise.then(() => {
206 assert(false, 'should never be reached');
207 }, (error_output) => {
208 assert(error_output);
209 assert.equal(error_output.name, 'AssertionError [ERR_ASSERTION]');
215 describe('OSBuildFetcher.fetchAndReportNewBuilds', () => {
216 const invocations = MockSubprocess.invocations;
218 beforeEach(function () {
219 TestServer.database().connect({keepAlive: true});
222 afterEach(function () {
223 TestServer.database().disconnect();
226 it('should report all build commits with owned-commits', () => {
227 const logger = new MockLogger;
228 const fetchter = new OSBuildFetcher(config, TestServer.remoteAPI(), slaveAuth, MockSubprocess, logger);
229 const db = TestServer.database();
230 let fetchAndReportPromise = null;
231 let fetchAvailableBuildsPromise = null;
233 return addSlaveForReport(emptyReport).then(() => {
235 db.insert('repositories', {'id': 10, 'name': 'OSX'}),
236 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D67', 'order': 1603006700, 'reported': true}),
237 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D68', 'order': 1603006800, 'reported': true}),
238 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D69', 'order': 1603006900, 'reported': false}),
239 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E32', 'order': 1604003200, 'reported': true}),
240 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E33', 'order': 1604003300, 'reported': true}),
241 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E33g', 'order': 1604003307, 'reported': true})]);
243 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1603000000&to=1603099900');
244 }).then((result) => {
245 assert.equal(result['commits'].length, 1);
246 assert.equal(result['commits'][0]['revision'], 'Sierra16D68');
247 assert.equal(result['commits'][0]['order'], 1603006800);
248 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1604000000&to=1604099900');
249 }).then((result) => {
250 assert.equal(result['commits'].length, 1);
251 assert.equal(result['commits'][0]['revision'], 'Sierra16E33g');
252 assert.equal(result['commits'][0]['order'], 1604003307);
253 const waitForInvocationPromise = MockSubprocess.waitForInvocation();
254 fetchAvailableBuildsPromise = fetchter._fetchAvailableBuilds();
255 return waitForInvocationPromise;
257 assert.equal(invocations.length, 1);
258 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Dxx builds']);
259 invocations[0].resolve('\n\nSierra16D68\nSierra16D69\n');
260 return MockSubprocess.resetAndWaitForInvocation();
262 assert.equal(invocations.length, 1);
263 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16D69']);
264 invocations[0].resolve(JSON.stringify(ownedCommitWithWebKit));
265 return MockSubprocess.resetAndWaitForInvocation();
267 assert.equal(invocations.length, 1);
268 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Exx builds']);
269 invocations[0].resolve('\n\nSierra16E32\nSierra16E33\nSierra16E33h\nSierra16E34');
270 return MockSubprocess.resetAndWaitForInvocation();
272 assert.equal(invocations.length, 1);
273 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16E33h']);
274 invocations[0].resolve(JSON.stringify(anotherownedCommitWithWebKit));
275 return MockSubprocess.resetAndWaitForInvocation();
277 assert.equal(invocations.length, 1);
278 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16E34']);
279 invocations[0].resolve(JSON.stringify(anotherownedCommitWithWebKitAndJavaScriptCore));
280 return fetchAvailableBuildsPromise;
281 }).then((results) => {
282 assert.equal(results.length, 3);
283 MockSubprocess.reset();
284 fetchAndReportPromise = fetchter.fetchAndReportNewBuilds();
285 return MockSubprocess.waitForInvocation();
287 assert.equal(invocations.length, 1);
288 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Dxx builds']);
289 invocations[0].resolve('\n\nSierra16D68\nSierra16D69\n');
290 return MockSubprocess.resetAndWaitForInvocation();
292 assert.equal(invocations.length, 1);
293 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16D69']);
294 invocations[0].resolve(JSON.stringify(ownedCommitWithWebKit));
295 return MockSubprocess.resetAndWaitForInvocation();
297 assert.equal(invocations.length, 1);
298 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Exx builds']);
299 invocations[0].resolve('\n\nSierra16E32\nSierra16E33\nSierra16E33h\nSierra16E34');
300 return MockSubprocess.resetAndWaitForInvocation();
302 assert.equal(invocations.length, 1);
303 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16E33h']);
304 invocations[0].resolve(JSON.stringify(anotherownedCommitWithWebKit));
305 return MockSubprocess.resetAndWaitForInvocation();
307 assert.equal(invocations.length, 1);
308 invocations[0].resolve(JSON.stringify(anotherownedCommitWithWebKitAndJavaScriptCore));
309 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16E34']);
311 return fetchAndReportPromise;
312 }).then((result) => {
313 assert.equal(result['status'], 'OK');
315 db.selectRows('repositories', {'name': 'WebKit'}),
316 db.selectRows('repositories', {'name': 'JavaScriptCore'}),
317 db.selectRows('commits', {'revision': 'Sierra16D69'}),
318 db.selectRows('commits', {'revision': 'Sierra16E33h'}),
319 db.selectRows('commits', {'revision': 'Sierra16E34'})]);
320 }).then((results) => {
321 const webkitRepository = results[0];
322 const jscRepository = results[1];
323 const osxCommit16D69 = results[2];
324 const osxCommit16E33h = results[3];
325 const osxCommit16E34 = results[4];
327 assert.equal(webkitRepository.length, 1);
328 assert.equal(webkitRepository[0]['owner'], 10);
329 assert.equal(jscRepository.length, 1);
330 assert.equal(jscRepository[0]['owner'], 10);
332 assert.equal(osxCommit16D69.length, 1);
333 assert.equal(osxCommit16D69[0]['repository'], 10);
334 assert.equal(osxCommit16D69[0]['order'], 1603006900);
336 assert.equal(osxCommit16E33h.length, 1);
337 assert.equal(osxCommit16E33h[0]['repository'], 10);
338 assert.equal(osxCommit16E33h[0]['order'], 1604003308);
340 assert.equal(osxCommit16E34.length, 1);
341 assert.equal(osxCommit16E34[0]['repository'], 10);
342 assert.equal(osxCommit16E34[0]['order'], 1604003400);
344 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1603000000&to=1603099900');
345 }).then((result) => {
346 assert.equal(result['commits'].length, 1);
347 assert.equal(result['commits'][0]['revision'], 'Sierra16D69');
348 assert.equal(result['commits'][0]['order'], 1603006900);
350 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1604000000&to=1604099900');
351 }).then((result) => {
352 assert.equal(result['commits'].length, 1);
353 assert.equal(result['commits'][0]['revision'], 'Sierra16E34');
354 assert.equal(result['commits'][0]['order'], 1604003400);
358 it('should report commits without owned-commits if "ownedCommitCommand" is not specified in config', () => {
359 const logger = new MockLogger;
360 const fetchter = new OSBuildFetcher(configWithoutownedCommitCommand, TestServer.remoteAPI(), slaveAuth, MockSubprocess, logger);
361 const db = TestServer.database();
362 let fetchAndReportPromise = null;
363 let fetchAvailableBuildsPromise = null;
365 return addSlaveForReport(emptyReport).then(() => {
367 db.insert('repositories', {'id': 10, 'name': 'OSX'}),
368 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D67', 'order': 1603006700, 'reported': true}),
369 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D68', 'order': 1603006800, 'reported': true}),
370 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D69', 'order': 1603006900, 'reported': false}),
371 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E32', 'order': 1604003200, 'reported': true}),
372 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E33', 'order': 1604003300, 'reported': true}),
373 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E33g', 'order': 1604003307, 'reported': true})]);
375 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1603000000&to=1603099900');
376 }).then((result) => {
377 assert.equal(result['commits'].length, 1);
378 assert.equal(result['commits'][0]['revision'], 'Sierra16D68');
379 assert.equal(result['commits'][0]['order'], 1603006800);
381 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1604000000&to=1604099900');
382 }).then((result) => {
383 assert.equal(result['commits'].length, 1);
384 assert.equal(result['commits'][0]['revision'], 'Sierra16E33g');
385 assert.equal(result['commits'][0]['order'], 1604003307);
386 const waitForInvocationPromise = MockSubprocess.waitForInvocation();
387 fetchAndReportPromise = fetchter.fetchAndReportNewBuilds();
388 return waitForInvocationPromise;
390 assert.equal(invocations.length, 1);
391 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Dxx builds']);
392 invocations[0].resolve('\n\nSierra16D68\nSierra16D69\n');
393 return MockSubprocess.resetAndWaitForInvocation();
395 assert.equal(invocations.length, 1);
396 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Exx builds']);
397 invocations[0].resolve('\n\nSierra16E32\nSierra16E33\nSierra16E33h\nSierra16E34');
398 return fetchAndReportPromise;
399 }).then((result) => {
400 assert.equal(result['status'], 'OK');
402 db.selectRows('repositories', {'name': 'WebKit'}),
403 db.selectRows('repositories', {'name': 'JavaScriptCore'}),
404 db.selectRows('commits', {'revision': 'Sierra16D69'}),
405 db.selectRows('commits', {'revision': 'Sierra16E33h'}),
406 db.selectRows('commits', {'revision': 'Sierra16E34'})]);
407 }).then((results) => {
408 const webkitRepository = results[0];
409 const jscRepository = results[1];
410 const osxCommit16D69 = results[2];
411 const osxCommit16E33h = results[3];
412 const osxCommit16E34 = results[4];
414 assert.equal(webkitRepository.length, 0);
415 assert.equal(jscRepository.length, 0);
417 assert.equal(osxCommit16D69.length, 1);
418 assert.equal(osxCommit16D69[0]['repository'], 10);
419 assert.equal(osxCommit16D69[0]['order'], 1603006900);
421 assert.equal(osxCommit16E33h.length, 1);
422 assert.equal(osxCommit16E33h[0]['repository'], 10);
423 assert.equal(osxCommit16E33h[0]['order'], 1604003308);
425 assert.equal(osxCommit16E34.length, 1);
426 assert.equal(osxCommit16E34[0]['repository'], 10);
427 assert.equal(osxCommit16E34[0]['order'], 1604003400);
429 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1603000000&to=1603099900');
430 }).then((result) => {
431 assert.equal(result['commits'].length, 1);
432 assert.equal(result['commits'][0]['revision'], 'Sierra16D69');
433 assert.equal(result['commits'][0]['order'], 1603006900);
435 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1604000000&to=1604099900');
436 }).then((result) => {
437 assert.equal(result['commits'].length, 1);
438 assert.equal(result['commits'][0]['revision'], 'Sierra16E34');
439 assert.equal(result['commits'][0]['order'], 1604003400);
443 it('should stop reporting if any custom command fails', () => {
444 const logger = new MockLogger;
445 const fetchter = new OSBuildFetcher(config, TestServer.remoteAPI(), slaveAuth, MockSubprocess, logger);
446 const db = TestServer.database();
447 let fetchAndReportPromise = null;
449 return addSlaveForReport(emptyReport).then(() => {
451 db.insert('repositories', {'id': 10, 'name': 'OSX'}),
452 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D67', 'order': 1603006700, 'reported': true}),
453 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D68', 'order': 1603006800, 'reported': true}),
454 db.insert('commits', {'repository': 10, 'revision': 'Sierra16D69', 'order': 1603006900, 'reported': false}),
455 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E32', 'order': 1604003200, 'reported': true}),
456 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E33', 'order': 1604003300, 'reported': true}),
457 db.insert('commits', {'repository': 10, 'revision': 'Sierra16E33g', 'order': 1604003307, 'reported': true})]);
459 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1603000000&to=1603099900');
460 }).then((result) => {
461 assert.equal(result['commits'].length, 1);
462 assert.equal(result['commits'][0]['revision'], 'Sierra16D68');
463 assert.equal(result['commits'][0]['order'], 1603006800);
465 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1604000000&to=1604099900');
466 }).then((result) => {
467 assert.equal(result['commits'].length, 1);
468 assert.equal(result['commits'][0]['revision'], 'Sierra16E33g');
469 assert.equal(result['commits'][0]['order'], 1604003307);
471 const waitForInvocationPromise = MockSubprocess.waitForInvocation();
472 fetchAndReportPromise = fetchter.fetchAndReportNewBuilds();
473 return waitForInvocationPromise;
475 assert.equal(invocations.length, 1);
476 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Dxx builds']);
477 invocations[0].resolve('\n\nSierra16D68\nSierra16D69\n');
478 return MockSubprocess.resetAndWaitForInvocation();
480 assert.equal(invocations.length, 1);
481 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16D69']);
482 MockSubprocess.invocations[0].resolve(JSON.stringify(ownedCommitWithWebKit));
483 return MockSubprocess.resetAndWaitForInvocation();
485 assert.equal(invocations.length, 1);
486 assert.deepEqual(invocations[0].command, ['list', 'all osx 16Exx builds']);
487 invocations[0].resolve('\n\nSierra16E32\nSierra16E33\nSierra16E33h\nSierra16E34');
488 return MockSubprocess.resetAndWaitForInvocation();
490 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16E33h']);
491 invocations[0].resolve(JSON.stringify(anotherownedCommitWithWebKit));
492 return MockSubprocess.resetAndWaitForInvocation();
494 assert.equal(invocations.length, 1);
495 assert.deepEqual(invocations[0].command, ['list', 'ownedCommit', 'for', 'revision', 'Sierra16E34']);
496 invocations[0].reject('Command failed');
497 return fetchAndReportPromise.then(() => {
498 assert(false, 'should never be reached');
499 }, (error_output) => {
500 assert(error_output);
501 assert.equal(error_output, 'Command failed');
504 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1603000000&to=1603099900');
505 }).then((result) => {
506 assert.equal(result['commits'].length, 1);
507 assert.equal(result['commits'][0]['revision'], 'Sierra16D68');
508 assert.equal(result['commits'][0]['order'], 1603006800);
510 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=1604000000&to=1604099900');
511 }).then((result) => {
512 assert.equal(result['commits'].length, 1);
513 assert.equal(result['commits'][0]['revision'], 'Sierra16E33g');
514 assert.equal(result['commits'][0]['order'], 1604003307);