20af3812a8cb2425b1e7a9d3ba55bca14d334aeb
[WebKit.git] / Websites / perf.webkit.org / server-tests / api-manifest-tests.js
1 'use strict';
2
3 const assert = require('assert');
4
5 require('../tools/js/v3-models.js');
6
7 const MockData = require('./resources/mock-data.js');
8 const TestServer = require('./resources/test-server.js');
9 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
10
11 describe('/api/manifest', function () {
12     prepareServerTest(this);
13
14     it("should generate an empty manifest when database is empty", () => {
15         return TestServer.remoteAPI().getJSON('/api/manifest').then((manifest) => {
16             assert.deepEqual(Object.keys(manifest).sort(), ['all', 'bugTrackers', 'builders', 'dashboard', 'dashboards',
17                 'elapsedTime', 'fileUploadSizeLimit', 'metrics', 'repositories', 'siteTitle', 'status', 'summaryPages', 'testAgeToleranceInHours', 'tests', 'triggerables']);
18
19             assert.equal(typeof(manifest.elapsedTime), 'number');
20             delete manifest.elapsedTime;
21
22             assert.deepStrictEqual(manifest, {
23                 siteTitle: TestServer.testConfig().siteTitle,
24                 all: {},
25                 bugTrackers: {},
26                 builders: {},
27                 dashboard: {},
28                 dashboards: {},
29                 fileUploadSizeLimit: 2097152, // 2MB during testing.
30                 metrics: {},
31                 repositories: {},
32                 testAgeToleranceInHours: null,
33                 tests: {},
34                 triggerables: {},
35                 summaryPages: [],
36                 status: 'OK'
37             });
38         });
39     });
40
41     const bugzillaData = {id: 1, name: 'Bugzilla', bug_url: 'https://webkit.org/b/$number', new_bug_url: 'https://bugs.webkit.org/'};
42     const radarData = {id: 2, name: 'Radar'};
43
44     it("should generate manifest with bug trackers without repositories", () => {
45         return TestServer.database().insert('bug_trackers', bugzillaData).then(() => {
46             return TestServer.remoteAPI().getJSON('/api/manifest');
47         }).then((content) => {
48             assert.deepEqual(content.bugTrackers, {1: {name: 'Bugzilla', bugUrl: 'https://webkit.org/b/$number',
49                 newBugUrl: 'https://bugs.webkit.org/', repositories: null}});
50
51             let manifest = Manifest._didFetchManifest(content);
52             let tracker = BugTracker.findById(1);
53             assert(tracker);
54             assert.equal(tracker.name(), 'Bugzilla');
55             assert.equal(tracker.bugUrl(123), 'https://webkit.org/b/123');
56             assert.equal(tracker.newBugUrl(), 'https://bugs.webkit.org/');
57         });
58     });
59
60     it("should generate manifest with bug trackers and repositories", () => {
61         let db = TestServer.database();
62         return Promise.all([
63             db.insert('bug_trackers', bugzillaData),
64             db.insert('bug_trackers', radarData),
65             db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
66             db.insert('repositories', {id: 9, name: 'macOS'}),
67             db.insert('repositories', {id: 22, name: 'iOS'}),
68             db.insert('tracker_repositories', {tracker: bugzillaData.id, repository: 11}),
69             db.insert('tracker_repositories', {tracker: radarData.id, repository: 9}),
70             db.insert('tracker_repositories', {tracker: radarData.id, repository: 22}),
71         ]).then(() => {
72             return TestServer.remoteAPI().getJSON('/api/manifest');
73         }).then((content) => {
74             let manifest = Manifest._didFetchManifest(content);
75
76             let webkit = Repository.findById(11);
77             assert(webkit);
78             assert.equal(webkit.name(), 'WebKit');
79             assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
80
81             let macos = Repository.findById(9);
82             assert(macos);
83             assert.equal(macos.name(), 'macOS');
84
85             let ios = Repository.findById(22);
86             assert(ios);
87             assert.equal(ios.name(), 'iOS');
88
89             let tracker = BugTracker.findById(1);
90             assert(tracker);
91             assert.equal(tracker.name(), 'Bugzilla');
92             assert.equal(tracker.bugUrl(123), 'https://webkit.org/b/123');
93             assert.equal(tracker.newBugUrl(), 'https://bugs.webkit.org/');
94             assert.deepEqual(tracker.repositories(), [webkit]);
95
96             tracker = BugTracker.findById(2);
97             assert(tracker);
98             assert.equal(tracker.name(), 'Radar');
99             assert.deepEqual(Repository.sortByName(tracker.repositories()), [ios, macos]);
100         });
101     });
102
103     it("should generate manifest with repositories and each repository should know its owned repositories", () => {
104         const db = TestServer.database();
105         return Promise.all([
106             db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
107             db.insert('repositories', {id: 9, name: 'OS X'}),
108             db.insert('repositories', {id: 22, name: 'iOS'}),
109             db.insert('repositories', {id: 35, name: 'JavaScriptCore', owner: 9}),
110         ]).then(() => {
111             return TestServer.remoteAPI().getJSON('/api/manifest');
112         }).then((content) => {
113             let manifest = Manifest._didFetchManifest(content);
114
115             let webkit = Repository.findById(11);
116             assert(webkit);
117             assert.equal(webkit.name(), 'WebKit');
118             assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
119             assert.equal(webkit.ownedRepositories(), null);
120
121             let osx = Repository.findById(9);
122             assert(osx);
123             assert.equal(osx.name(), 'OS X');
124             assert.deepEqual(osx.ownedRepositories(), [Repository.findById(35)]);
125
126             let ios = Repository.findById(22);
127             assert(ios);
128             assert.equal(ios.name(), 'iOS');
129             assert.equal(ios.ownedRepositories(), null);
130         });
131     });
132
133     it("should generate manifest with builders", () => {
134         let db = TestServer.database();
135         return Promise.all([
136             db.insert('builders', {id: 1, name: 'SomeBuilder', password_hash: 'a',
137                 build_url: 'https://build.webkit.org/builders/$builderName/build/$buildNumber'}),
138             db.insert('builders', {id: 2, name: 'SomeOtherBuilder', password_hash: 'b'})
139         ]).then(() => {
140             return TestServer.remoteAPI().getJSON('/api/manifest');
141         }).then((content) => {
142             assert.deepEqual(content.builders, {
143                 '1': {name: 'SomeBuilder', buildUrl: 'https://build.webkit.org/builders/$builderName/build/$buildNumber'},
144                 '2': {name: 'SomeOtherBuilder', buildUrl: null}
145             });
146
147             let manifest = Manifest._didFetchManifest(content);
148
149             let builder = Builder.findById(1);
150             assert(builder);
151             assert.equal(builder.name(), 'SomeBuilder');
152             assert.equal(builder.urlForBuild(123), 'https://build.webkit.org/builders/SomeBuilder/build/123');
153
154             builder = Builder.findById(2);
155             assert(builder);
156             assert.equal(builder.name(), 'SomeOtherBuilder');
157             assert.equal(builder.urlForBuild(123), null);
158         });
159     });
160
161     it("should generate manifest with tests, metrics, and platforms", () => {
162         let db = TestServer.database();
163         return Promise.all([
164             db.insert('tests', {id: 1, name: 'SomeTest'}),
165             db.insert('tests', {id: 2, name: 'SomeOtherTest'}),
166             db.insert('tests', {id: 3, name: 'ChildTest', parent: 1}),
167             db.insert('tests', {id: 4, name: 'GrandChild', parent: 3}),
168             db.insert('aggregators', {id: 200, name: 'Total'}),
169             db.insert('test_metrics', {id: 5, test: 1, name: 'Time'}),
170             db.insert('test_metrics', {id: 6, test: 2, name: 'Time', aggregator: 200}),
171             db.insert('test_metrics', {id: 7, test: 2, name: 'Malloc', aggregator: 200}),
172             db.insert('test_metrics', {id: 8, test: 3, name: 'Time'}),
173             db.insert('test_metrics', {id: 9, test: 4, name: 'Time'}),
174             db.insert('platforms', {id: 23, name: 'iOS 9 iPhone 5s'}),
175             db.insert('platforms', {id: 46, name: 'Trunk Mavericks'}),
176             db.insert('test_configurations', {id: 101, metric: 5, platform: 46, type: 'current'}),
177             db.insert('test_configurations', {id: 102, metric: 6, platform: 46, type: 'current'}),
178             db.insert('test_configurations', {id: 103, metric: 7, platform: 46, type: 'current'}),
179             db.insert('test_configurations', {id: 104, metric: 8, platform: 46, type: 'current'}),
180             db.insert('test_configurations', {id: 105, metric: 9, platform: 46, type: 'current'}),
181             db.insert('test_configurations', {id: 106, metric: 5, platform: 23, type: 'current'}),
182             db.insert('test_configurations', {id: 107, metric: 5, platform: 23, type: 'baseline'}),
183         ]).then(() => {
184             return TestServer.remoteAPI().getJSON('/api/manifest');
185         }).then((content) => {
186             assert.deepEqual(content.tests, {
187                 "1": {"name": "SomeTest", "parentId": null, "url": null},
188                 "2": {"name": "SomeOtherTest", "parentId": null, "url": null},
189                 "3": {"name": "ChildTest", "parentId": "1", "url": null},
190                 "4": {"name": "GrandChild", "parentId": "3", "url": null},
191             });
192
193             assert.deepEqual(content.metrics, {
194                 '5': {name: 'Time', test: '1', aggregator: null},
195                 '6': {name: 'Time', test: '2', aggregator: 'Total'},
196                 '7': {name: 'Malloc', test: '2', aggregator: 'Total'},
197                 '8': {name: 'Time', test: '3', aggregator: null},
198                 '9': {name: 'Time', test: '4', aggregator: null},
199             });
200
201             let manifest = Manifest._didFetchManifest(content);
202
203             let someTest = Test.findById(1);
204             let someTestMetric = Metric.findById(5);
205             let someOtherTest = Test.findById(2);
206             let someOtherTestTime = Metric.findById(6);
207             let someOtherTestMalloc = Metric.findById(7);
208             let childTest = Test.findById(3);
209             let childTestMetric = Metric.findById(8);
210             let grandChildTest = Test.findById(4);
211             let ios9iphone5s = Platform.findById(23);
212             let mavericks = Platform.findById(46);
213             assert(someTest);
214             assert(someTestMetric);
215             assert(someOtherTest);
216             assert(someOtherTestTime);
217             assert(someOtherTestMalloc);
218             assert(childTest);
219             assert(childTestMetric);
220             assert(grandChildTest);
221             assert(ios9iphone5s);
222             assert(mavericks);
223
224             assert.equal(mavericks.name(), 'Trunk Mavericks');
225             assert(mavericks.hasTest(someTest));
226             assert(mavericks.hasTest(someOtherTest));
227             assert(mavericks.hasTest(childTest));
228             assert(mavericks.hasTest(grandChildTest));
229             assert(mavericks.hasMetric(someTestMetric));
230             assert(mavericks.hasMetric(someOtherTestTime));
231             assert(mavericks.hasMetric(someOtherTestMalloc));
232             assert(mavericks.hasMetric(childTestMetric));
233
234             assert.equal(ios9iphone5s.name(), 'iOS 9 iPhone 5s');
235             assert(ios9iphone5s.hasTest(someTest));
236             assert(!ios9iphone5s.hasTest(someOtherTest));
237             assert(!ios9iphone5s.hasTest(childTest));
238             assert(!ios9iphone5s.hasTest(grandChildTest));
239             assert(ios9iphone5s.hasMetric(someTestMetric));
240             assert(!ios9iphone5s.hasMetric(someOtherTestTime));
241             assert(!ios9iphone5s.hasMetric(someOtherTestMalloc));
242             assert(!ios9iphone5s.hasMetric(childTestMetric));
243
244             assert.equal(someTest.name(), 'SomeTest');
245             assert.equal(someTest.parentTest(), null);
246             assert.deepEqual(someTest.path(), [someTest]);
247             assert(!someTest.onlyContainsSingleMetric());
248             assert.deepEqual(someTest.childTests(), [childTest]);
249             assert.deepEqual(someTest.metrics(), [someTestMetric]);
250
251             assert.equal(someTestMetric.name(), 'Time');
252             assert.equal(someTestMetric.aggregatorName(), null);
253             assert.equal(someTestMetric.label(), 'Time');
254             assert.deepEqual(someTestMetric.childMetrics(), childTest.metrics());
255             assert.equal(someTestMetric.fullName(), 'SomeTest : Time');
256
257             assert.equal(someOtherTest.name(), 'SomeOtherTest');
258             assert.equal(someOtherTest.parentTest(), null);
259             assert.deepEqual(someOtherTest.path(), [someOtherTest]);
260             assert(!someOtherTest.onlyContainsSingleMetric());
261             assert.deepEqual(someOtherTest.childTests(), []);
262             assert.equal(someOtherTest.metrics().length, 2);
263             assert.equal(someOtherTest.metrics()[0].name(), 'Time');
264             assert.equal(someOtherTest.metrics()[0].aggregatorName(), 'Total');
265             assert.equal(someOtherTest.metrics()[0].label(), 'Time : Total');
266             assert.equal(someOtherTest.metrics()[0].childMetrics().length, 0);
267             assert.equal(someOtherTest.metrics()[0].fullName(), 'SomeOtherTest : Time : Total');
268             assert.equal(someOtherTest.metrics()[1].name(), 'Malloc');
269             assert.equal(someOtherTest.metrics()[1].aggregatorName(), 'Total');
270             assert.equal(someOtherTest.metrics()[1].label(), 'Malloc : Total');
271             assert.equal(someOtherTest.metrics()[1].childMetrics().length, 0);
272             assert.equal(someOtherTest.metrics()[1].fullName(), 'SomeOtherTest : Malloc : Total');
273
274             assert.equal(childTest.name(), 'ChildTest');
275             assert.equal(childTest.parentTest(), someTest);
276             assert.deepEqual(childTest.path(), [someTest, childTest]);
277             assert(!childTest.onlyContainsSingleMetric());
278             assert.deepEqual(childTest.childTests(), [grandChildTest]);
279             assert.equal(childTest.metrics().length, 1);
280             assert.equal(childTest.metrics()[0].label(), 'Time');
281             assert.equal(childTest.metrics()[0].fullName(), 'SomeTest \u220B ChildTest : Time');
282
283             assert.equal(grandChildTest.name(), 'GrandChild');
284             assert.equal(grandChildTest.parentTest(), childTest);
285             assert.deepEqual(grandChildTest.path(), [someTest, childTest, grandChildTest]);
286             assert(grandChildTest.onlyContainsSingleMetric());
287             assert.deepEqual(grandChildTest.childTests(), []);
288             assert.equal(grandChildTest.metrics().length, 1);
289             assert.equal(grandChildTest.metrics()[0].label(), 'Time');
290             assert.equal(grandChildTest.metrics()[0].fullName(), 'SomeTest \u220B ChildTest \u220B GrandChild : Time');
291         });
292     });
293
294     it("should generate manifest with triggerables", () => {
295         let db = TestServer.database();
296         return Promise.all([
297             db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
298             db.insert('repositories', {id: 9, name: 'macOS'}),
299             db.insert('repositories', {id: 101, name: 'WebKit', owner: 9, url: 'https://trac.webkit.org/$1'}),
300             db.insert('build_triggerables', {id: 200, name: 'build.webkit.org'}),
301             db.insert('build_triggerables', {id: 201, name: 'ios-build.webkit.org'}),
302             db.insert('build_triggerables', {id: 202, name: 'mac-build.webkit.org', disabled: true}),
303             db.insert('tests', {id: 1, name: 'SomeTest'}),
304             db.insert('tests', {id: 2, name: 'SomeOtherTest'}),
305             db.insert('tests', {id: 3, name: 'ChildTest', parent: 1}),
306             db.insert('platforms', {id: 23, name: 'iOS 9 iPhone 5s'}),
307             db.insert('platforms', {id: 46, name: 'Trunk Mavericks'}),
308             db.insert('platforms', {id: 104, name: 'Trunk Sierra MacBookPro11,2'}),
309             db.insert('test_metrics', {id: 5, test: 1, name: 'Time'}),
310             db.insert('test_metrics', {id: 8, test: 2, name: 'FrameRate'}),
311             db.insert('test_metrics', {id: 9, test: 3, name: 'Time'}),
312             db.insert('test_configurations', {id: 101, metric: 5, platform: 46, type: 'current'}),
313             db.insert('test_configurations', {id: 102, metric: 8, platform: 46, type: 'current'}),
314             db.insert('test_configurations', {id: 103, metric: 9, platform: 46, type: 'current'}),
315             db.insert('test_configurations', {id: 104, metric: 5, platform: 23, type: 'current'}),
316             db.insert('test_configurations', {id: 105, metric: 8, platform: 23, type: 'current'}),
317             db.insert('test_configurations', {id: 106, metric: 9, platform: 23, type: 'current'}),
318             db.insert('test_configurations', {id: 107, metric: 5, platform: 104, type: 'current'}),
319             db.insert('test_configurations', {id: 108, metric: 8, platform: 104, type: 'current'}),
320             db.insert('test_configurations', {id: 109, metric: 9, platform: 104, type: 'current'}),
321             db.insert('triggerable_repository_groups', {id: 300, triggerable: 200, name: 'default'}),
322             db.insert('triggerable_repository_groups', {id: 301, triggerable: 201, name: 'default'}),
323             db.insert('triggerable_repository_groups', {id: 302, triggerable: 202, name: 'system-and-webkit'}),
324             db.insert('triggerable_repository_groups', {id: 312, triggerable: 202, name: 'system-and-roots', accepts_roots: true}),
325             db.insert('triggerable_repositories', {group: 300, repository: 11}),
326             db.insert('triggerable_repositories', {group: 301, repository: 11}),
327             db.insert('triggerable_repositories', {group: 302, repository: 11}),
328             db.insert('triggerable_repositories', {group: 302, repository: 9}),
329             db.insert('triggerable_repositories', {group: 312, repository: 9}),
330             db.insert('triggerable_configurations', {triggerable: 200, test: 1, platform: 46}),
331             db.insert('triggerable_configurations', {triggerable: 200, test: 2, platform: 46}),
332             db.insert('triggerable_configurations', {triggerable: 201, test: 1, platform: 23}),
333             db.insert('triggerable_configurations', {triggerable: 201, test: 2, platform: 23}),
334             db.insert('triggerable_configurations', {triggerable: 202, test: 1, platform: 104}),
335             db.insert('triggerable_configurations', {triggerable: 202, test: 2, platform: 104}),
336         ]).then(() => {
337             return Manifest.fetch();
338         }).then(() => {
339             const webkit = Repository.findById(11);
340             assert.equal(webkit.name(), 'WebKit');
341             assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
342
343             const osWebkit1 = Repository.findById(101);
344             assert.equal(osWebkit1.name(), 'WebKit');
345             assert.equal(osWebkit1.ownerId(), 9);
346             assert.equal(osWebkit1.urlForRevision(123), 'https://trac.webkit.org/123');
347
348             const macos = Repository.findById(9);
349             assert.equal(macos.name(), 'macOS');
350
351             const someTest = Test.findById(1);
352             assert.equal(someTest.name(), 'SomeTest');
353
354             const someOtherTest = Test.findById(2);
355             assert.equal(someOtherTest.name(), 'SomeOtherTest');
356
357             const childTest = Test.findById(3);
358             assert.equal(childTest.name(), 'ChildTest');
359
360             const ios9iphone5s = Platform.findById(23);
361             assert.equal(ios9iphone5s.name(), 'iOS 9 iPhone 5s');
362
363             const mavericks = Platform.findById(46);
364             assert.equal(mavericks.name(), 'Trunk Mavericks');
365
366             const sierra = Platform.findById(104);
367             assert.equal(sierra.name(), 'Trunk Sierra MacBookPro11,2');
368
369             assert.equal(Triggerable.all().length, 3);
370
371             const macosTriggerable = Triggerable.findByTestConfiguration(someTest, mavericks);
372             assert.equal(macosTriggerable.name(), 'build.webkit.org');
373
374             assert.equal(Triggerable.findByTestConfiguration(someOtherTest, mavericks), macosTriggerable);
375             assert.equal(Triggerable.findByTestConfiguration(childTest, mavericks), macosTriggerable);
376
377             const iosTriggerable = Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s);
378             assert.notEqual(iosTriggerable, macosTriggerable);
379             assert.equal(iosTriggerable.name(), 'ios-build.webkit.org');
380
381             assert.equal(Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s), iosTriggerable);
382             assert.equal(Triggerable.findByTestConfiguration(childTest, ios9iphone5s), iosTriggerable);
383
384             const macTriggerable = Triggerable.findByTestConfiguration(someTest, sierra);
385             assert.equal(macTriggerable.name(), 'mac-build.webkit.org');
386             assert(macTriggerable.acceptsTest(someTest));
387
388             const groups = macTriggerable.repositoryGroups();
389             assert.deepEqual(groups.length, 2);
390             TriggerableRepositoryGroup.sortByName(groups);
391
392             const emptyCustomSet = new CustomCommitSet;
393
394             const customSetWithOSX = new CustomCommitSet;
395             customSetWithOSX.setRevisionForRepository(macos, '10.11 15A284');
396
397             const cusomSetWithOSXAndWebKit = new CustomCommitSet;
398             cusomSetWithOSXAndWebKit.setRevisionForRepository(webkit, '191622');
399             cusomSetWithOSXAndWebKit.setRevisionForRepository(macos, '10.11 15A284');
400
401             const cusomSetWithWebKit = new CustomCommitSet;
402             cusomSetWithWebKit.setRevisionForRepository(webkit, '191622');
403
404             assert.equal(groups[0].name(), 'system-and-roots');
405             assert.equal(groups[0].acceptsCustomRoots(), true);
406             assert.deepEqual(Repository.sortByName(groups[0].repositories()), [macos]);
407             assert.equal(groups[0].accepts(emptyCustomSet), false);
408             assert.equal(groups[0].accepts(customSetWithOSX), true);
409             assert.equal(groups[0].accepts(cusomSetWithOSXAndWebKit), false);
410             assert.equal(groups[0].accepts(cusomSetWithWebKit), false);
411
412             assert.equal(groups[1].name(), 'system-and-webkit');
413             assert.equal(groups[1].acceptsCustomRoots(), false);
414             assert.deepEqual(Repository.sortByName(groups[1].repositories()), [webkit, macos]);
415             assert.equal(groups[1].accepts(emptyCustomSet), false);
416             assert.equal(groups[1].accepts(customSetWithOSX), false);
417             assert.equal(groups[1].accepts(cusomSetWithOSXAndWebKit), true);
418             assert.equal(groups[1].accepts(cusomSetWithWebKit), false);
419         });
420     });
421
422 });