Rewrite 'pull-os-versions' script in Javascript to add support for reporting os revis...
[WebKit.git] / Websites / perf.webkit.org / server-tests / api-commits.js
1 'use strict';
2
3 const assert = require('assert');
4
5 const TestServer = require('./resources/test-server.js');
6 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
7 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
8
9 describe("/api/commits/", function () {
10     prepareServerTest(this);
11
12     const subversionCommits = {
13         "slaveName": "someSlave",
14         "slavePassword": "somePassword",
15         "commits": [
16             {
17                 "repository": "WebKit",
18                 "revision": "210948",
19                 "time": "2017-01-20T02:52:34.577Z",
20                 "author": {"name": "Zalan Bujtas", "account": "zalan@apple.com"},
21                 "message": "a message",
22             },
23             {
24                 "repository": "WebKit",
25                 "revision": "210949",
26                 "time": "2017-01-20T03:23:50.645Z",
27                 "author": {"name": "Chris Dumez", "account": "cdumez@apple.com"},
28                 "message": "some message",
29             },
30             {
31                 "repository": "WebKit",
32                 "previousCommit": "210949",
33                 "revision": "210950",
34                 "time": "2017-01-20T03:49:37.887Z",
35                 "author": {"name": "Commit Queue", "account": "commit-queue@webkit.org"},
36                 "message": "another message",
37             }
38         ]
39     }
40
41     const systemVersionCommits = {
42         "slaveName": "someSlave",
43         "slavePassword": "somePassword",
44         "commits": [
45             {
46                 "repository": "OSX",
47                 "revision": "16D32",
48                 "order": 6
49             },
50             {
51                 "repository": "OSX",
52                 "revision": "16C68",
53                 "order": 5
54             },
55             {
56                 "repository": "OSX",
57                 "revision": "16C67",
58                 "order": 4
59             },
60             {
61                 "repository": "OSX",
62                 "revision": "16B2657",
63                 "order": 3
64             },
65             {
66                 "repository": "OSX",
67                 "revision": "16B2555",
68                 "order": 2
69             },
70             {
71                 "repository": "OSX",
72                 "revision": "16A323",
73                 "order": 1
74             }
75         ]
76     }
77
78     const notYetReportedCommit = {
79         revision: '210951',
80         time: '2017-01-20T03:56:20.045Z'
81     }
82
83     function assertCommitIsSameAsOneSubmitted(commit, submitted)
84     {
85         assert.equal(commit['revision'], submitted['revision']);
86         assert.equal(new Date(commit['time']).toISOString(), submitted['time']);
87         assert.equal(commit['message'], submitted['message']);
88         assert.equal(commit['authorName'], submitted['author']['name']);
89         assert.equal(commit['authorEmail'], submitted['author']['account']);
90         if(submitted['previousCommit']) {
91             assert.ok(commit['previousCommit']);
92         } else {
93             assert.equal(commit['previousCommit'], null);
94         }
95     }
96
97     describe('/api/commits/<repository>/', () => {
98         it("should return RepositoryNotFound when there are no matching repository", () => {
99             return TestServer.remoteAPI().getJSON('/api/commits/WebKit').then((response) => {
100                 assert.equal(response['status'], 'RepositoryNotFound');
101             });
102         });
103
104         it("should return an empty result when there are no reported commits", () => {
105             const db = TestServer.database();
106             return Promise.all([
107                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
108                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
109             ]).then(() => {
110                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit');
111             }).then((response) => {
112                 assert.equal(response['status'], 'OK');
113                 assert.deepEqual(response['commits'], []);
114             });
115         });
116
117         it("should return the list of all commits for a given repository", () => {
118             return addSlaveForReport(subversionCommits).then(() => {
119                 return TestServer.remoteAPI().postJSON('/api/report-commits/', subversionCommits);
120             }).then(function (response) {
121                 assert.equal(response['status'], 'OK');
122                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/');
123             }).then(function (result) {
124                 assert.equal(result['status'], 'OK');
125
126                 const commits = result['commits'];
127                 assert.equal(commits.length, 3);
128                 const submittedCommits = subversionCommits['commits'];
129                 assertCommitIsSameAsOneSubmitted(commits[0], submittedCommits[0]);
130                 assertCommitIsSameAsOneSubmitted(commits[1], submittedCommits[1]);
131                 assertCommitIsSameAsOneSubmitted(commits[2], submittedCommits[2]);
132                 assert.equal(commits[2]['previousCommit'], commits[1]['id']);
133             });
134         });
135
136         it("should return the list of ordered commits for a given repository", () => {
137             return addSlaveForReport(subversionCommits).then(() => {
138                 return TestServer.remoteAPI().postJSON('/api/report-commits/', systemVersionCommits);
139             }).then(function (response) {
140                 assert.equal(response['status'], 'OK');
141                 return TestServer.remoteAPI().getJSON('/api/commits/OSX/');
142             }).then(function (result) {
143                 assert.equal(result['status'], 'OK');
144                 const commits = result['commits'];
145                 const submittedCommits = systemVersionCommits['commits'];
146                 assert.equal(commits.length, submittedCommits.length);
147                 assert.equal(commits[0]['revision'], submittedCommits[5]['revision']);
148                 assert.equal(commits[1]['revision'], submittedCommits[4]['revision']);
149                 assert.equal(commits[2]['revision'], submittedCommits[3]['revision']);
150                 assert.equal(commits[3]['revision'], submittedCommits[2]['revision']);
151                 assert.equal(commits[4]['revision'], submittedCommits[1]['revision']);
152                 assert.equal(commits[5]['revision'], submittedCommits[0]['revision']);
153             });
154         });
155     });
156
157     describe('/api/commits/<repository>/oldest', () => {
158         it("should return RepositoryNotFound when there are no matching repository", () => {
159             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/oldest').then((response) => {
160                 assert.equal(response['status'], 'RepositoryNotFound');
161             });
162         });
163
164         it("should return an empty results when there are no commits", () => {
165             return TestServer.database().insert('repositories', {'id': 1, 'name': 'WebKit'}).then(() => {
166                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/oldest');
167             }).then((response) => {
168                 assert.equal(response['status'], 'OK');
169                 assert.deepEqual(response['commits'], []);
170             });
171         });
172
173         it("should return the oldest commit", () => {
174             const remote = TestServer.remoteAPI();
175             return addSlaveForReport(subversionCommits).then(() => {
176                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
177             }).then(() => {
178                 return remote.getJSON('/api/commits/WebKit/oldest');
179             }).then(function (result) {
180                 assert.equal(result['status'], 'OK');
181                 assert.equal(result['commits'].length, 1);
182                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'][0]);
183             });
184         });
185
186         it("should return the oldest commit based on 'commit_order' when 'commit_time' is missing", () => {
187             const remote = TestServer.remoteAPI();
188             return addSlaveForReport(systemVersionCommits).then(() => {
189                 return remote.postJSONWithStatus('/api/report-commits/', systemVersionCommits);
190             }).then(() => {
191                 return remote.getJSON('/api/commits/OSX/oldest');
192             }).then(function (result) {
193                 assert.equal(result['status'], 'OK');
194                 assert.equal(result['commits'].length, 1);
195                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][5]['revision']);
196             });
197         });
198     });
199
200     describe('/api/commits/<repository>/latest', () => {
201         it("should return RepositoryNotFound when there are no matching repository", () => {
202             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/latest').then((response) => {
203                 assert.equal(response['status'], 'RepositoryNotFound');
204             });
205         });
206
207         it("should return an empty results when there are no commits", () => {
208             return TestServer.database().insert('repositories', {'id': 1, 'name': 'WebKit'}).then(() => {
209                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/latest');
210             }).then((response) => {
211                 assert.equal(response['status'], 'OK');
212                 assert.deepEqual(response['commits'], []);
213             });
214         });
215
216         it("should return the oldest commit", () => {
217             const remote = TestServer.remoteAPI();
218             return addSlaveForReport(subversionCommits).then(() => {
219                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
220             }).then(() => {
221                 return remote.getJSON('/api/commits/WebKit/latest');
222             }).then(function (result) {
223                 assert.equal(result['status'], 'OK');
224                 assert.equal(result['commits'].length, 1);
225                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'].slice().pop());
226             });
227         });
228
229         it("should return the latest commit based on 'commit_order' when 'commit_time' is missing", () => {
230             const remote = TestServer.remoteAPI();
231             return addSlaveForReport(systemVersionCommits).then(() => {
232                 return remote.postJSONWithStatus('/api/report-commits/', systemVersionCommits);
233             }).then(() => {
234                 return remote.getJSON('/api/commits/OSX/latest');
235             }).then(function (result) {
236                 assert.equal(result['status'], 'OK');
237                 assert.equal(result['commits'].length, 1);
238                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][0]['revision']);
239             });
240         });
241     });
242
243     describe('/api/commits/<repository>/last-reported', () => {
244         it("should return RepositoryNotFound when there are no matching repository", () => {
245             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/last-reported').then((response) => {
246                 assert.equal(response['status'], 'RepositoryNotFound');
247             });
248         });
249
250         it("should return an empty result when there are no reported commits", () => {
251             const db = TestServer.database();
252             return Promise.all([
253                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
254                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
255             ]).then(() => {
256                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/last-reported');
257             }).then((response) => {
258                 assert.equal(response['status'], 'OK');
259                 assert.deepEqual(response['commits'], []);
260             });
261         });
262
263         it("should return an empty results when there are no reported commits", () => {
264             return TestServer.database().insert('repositories', {'id': 1, 'name': 'WebKit'}).then(() => {
265                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/last-reported');
266             }).then((response) => {
267                 assert.equal(response['status'], 'OK');
268                 assert.deepEqual(response['commits'], []);
269             });
270         });
271
272         it("should return the oldest reported commit", () => {
273             const db = TestServer.database();
274             const remote = TestServer.remoteAPI();
275             return Promise.all([
276                 addSlaveForReport(subversionCommits),
277                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
278                 db.insert('commits', {'repository': 1, 'revision': notYetReportedCommit.revision, 'time': notYetReportedCommit.time}),
279             ]).then(() => {
280                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
281             }).then(() => {
282                 return remote.getJSON('/api/commits/WebKit/last-reported');
283             }).then(function (result) {
284                 assert.equal(result['status'], 'OK');
285                 assert.equal(result['commits'].length, 1);
286                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'].slice().pop());
287             });
288         });
289
290         it("should return the last reported commit based on 'commit_order' when 'commit_time' is missing", () => {
291             const remote = TestServer.remoteAPI();
292             return addSlaveForReport(systemVersionCommits).then(() => {
293                 return remote.postJSONWithStatus('/api/report-commits/', systemVersionCommits);
294             }).then(() => {
295                 return remote.getJSON('/api/commits/OSX/last-reported');
296             }).then(function (result) {
297                 assert.equal(result['status'], 'OK');
298                 assert.equal(result['commits'].length, 1);
299                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][0]['revision']);
300             });
301         });
302     });
303
304     describe('/api/commits/<repository>/last-reported?from=<start_order>&to=<end_order>', () => {
305         it("should return a list of commit in given valid order range", () => {
306             const db = TestServer.database();
307             return Promise.all([
308                 db.insert('repositories', {'id': 1, 'name': 'OSX'}),
309                 db.insert('commits', {'repository': 1, 'revision': 'Sierra16C67', 'order': 367, 'reported': true}),
310                 db.insert('commits', {'repository': 1, 'revision': 'Sierra16C68', 'order': 368, 'reported': true}),
311                 db.insert('commits', {'repository': 1, 'revision': 'Sierra16C69', 'order': 369, 'reported': false}),
312                 db.insert('commits', {'repository': 1, 'revision': 'Sierra16D32', 'order': 432, 'reported': true})
313             ]).then(() => {
314                 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=367&to=370');
315             }).then((response) => {
316                 assert.equal(response['status'], 'OK');
317                 const results = response['commits'];
318                 assert.equal(results.length, 1);
319                 const commit = results[0];
320                 assert.equal(commit.revision, 'Sierra16C68');
321             }).then(() => {
322                 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=370&to=367');
323             }).then((response) => {
324                 assert.equal(response['status'], 'OK');
325                 const results = response['commits'];
326                 assert.equal(results.length, 0);
327             }).then(() => {
328                 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=200&to=299');
329             }).then((response) => {
330                 assert.equal(response['status'], 'OK');
331                 const results = response['commits'];
332                 assert.equal(results.length, 0);
333             }).then(() => {
334                 return TestServer.remoteAPI().getJSON('/api/commits/OSX/last-reported?from=369&to=432');
335             }).then((response) => {
336                 assert.equal(response['status'], 'OK');
337                 const results = response['commits'];
338                 assert.equal(results.length, 1);
339                 const commit = results[0];
340                 assert.equal(commit.revision, 'Sierra16D32');
341             });
342         });
343     });
344
345     describe('/api/commits/<repository>/<commit>', () => {
346         it("should return RepositoryNotFound when there are no matching repository", () => {
347             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/210949').then((response) => {
348                 assert.equal(response['status'], 'RepositoryNotFound');
349             });
350         });
351
352         it("should return UnknownCommit when one of the specified commit does not exist in the database", () => {
353             const db = TestServer.database();
354             return Promise.all([
355                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
356                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
357             ]).then(() => {
358                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/210949');
359             }).then((response) => {
360                 assert.equal(response['status'], 'UnknownCommit');
361             });
362         });
363
364         it("should return the commit even if it had not been reported", () => {
365             const db = TestServer.database();
366             return Promise.all([
367                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
368                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
369             ]).then(() => {
370                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/210950');
371             }).then((result) => {
372                 assert.equal(result['status'], 'OK');
373                 assert.equal(result['commits'].length, 1);
374                 assertCommitIsSameAsOneSubmitted(result['commits'][0], {
375                     previousCommit: null,
376                     revision: '210950',
377                     time: '2017-01-20T03:49:37.887Z',
378                     author: {name: null, account: null},
379                     message: null,
380                 });
381             });
382         });
383
384         it("should return the full result for a reported commit", () => {
385             const remote = TestServer.remoteAPI();
386             return addSlaveForReport(subversionCommits).then(() => {
387                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
388             }).then(() => {
389                 return remote.getJSON('/api/commits/WebKit/210949');
390             }).then((result) => {
391                 assert.equal(result['status'], 'OK');
392                 assert.deepEqual(result['commits'].length, 1);
393                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'][1]);
394             });
395         });
396
397     });
398
399     describe('/api/commits/<repository>/?from=<commit-1>&to=<commit-2>', () => {
400         it("should return RepositoryNotFound when there are no matching repository", () => {
401             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210900&to=211000').then((response) => {
402                 assert.equal(response['status'], 'RepositoryNotFound');
403             });
404         });
405
406         it("should return UnknownCommit when one of the specified commit does not exist in the database", () => {
407             const db = TestServer.database();
408             return Promise.all([
409                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
410                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
411             ]).then(() => {
412                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210900&to=211000');
413             }).then((response) => {
414                 assert.equal(response['status'], 'UnknownCommit');
415             });
416         });
417
418         it("should return an empty result when commits in the specified range have not reported", () => {
419             const db = TestServer.database();
420             return Promise.all([
421                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
422                 db.insert('commits', {'repository': 1, 'revision': '210949', 'time': '2017-01-20T03:23:50.645Z'}),
423                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'}),
424             ]).then(() => {
425                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210949&to=210950');
426             }).then((response) => {
427                 assert.equal(response['status'], 'OK');
428                 assert.deepEqual(response['commits'], []);
429             });
430         });
431
432         it("should return reported commits in the specified range", () => {
433             const db = TestServer.database();
434             return Promise.all([
435                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
436                 db.insert('commits', {'repository': 1, 'revision': '210949', 'time': '2017-01-20T03:23:50.645Z', 'reported': true}),
437                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z', 'reported': true}),
438             ]).then(() => {
439                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210949&to=210950');
440             }).then((result) => {
441                 assert.equal(result['status'], 'OK');
442                 assert.deepEqual(result['commits'].length, 2);
443                 assertCommitIsSameAsOneSubmitted(result['commits'][0], {
444                     previousCommit: null,
445                     revision: '210949',
446                     time: '2017-01-20T03:23:50.645Z',
447                     author: {name: null, account: null},
448                     message: null,
449                 });
450                 assertCommitIsSameAsOneSubmitted(result['commits'][1], {
451                     previousCommit: null,
452                     revision: '210950',
453                     time: '2017-01-20T03:49:37.887Z',
454                     author: {name: null, account: null},
455                     message: null,
456                 });
457             });
458         });
459
460         it("should not include a revision not within the specified range", () => {
461             const remote = TestServer.remoteAPI();
462             return addSlaveForReport(subversionCommits).then(() => {
463                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
464             }).then(() => {
465                 return remote.getJSON('/api/commits/WebKit/?from=210948&to=210949');
466             }).then((result) => {
467                 assert.equal(result['status'], 'OK');
468                 assert.deepEqual(result['commits'].length, 2);
469                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'][0]);
470                 assertCommitIsSameAsOneSubmitted(result['commits'][1], subversionCommits['commits'][1]);
471             });
472         });
473
474     });
475
476 });