Add the support for scheduling a A/B testing with a patch.
[WebKit-https.git] / Websites / perf.webkit.org / public / v3 / models / triggerable.js
1 class Triggerable extends LabeledObject {
2
3     constructor(id, object)
4     {
5         super(id, object);
6         this._name = object.name;
7         this._isDisabled = !!object.isDisabled;
8         this._acceptedRepositories = object.acceptedRepositories;
9         this._repositoryGroups = object.repositoryGroups;
10         this._configurationList = object.configurations;
11         this._acceptedTests = new Set;
12
13         const configurationMap = this.ensureNamedStaticMap('testConfigurations');
14         for (const config of object.configurations) {
15             const key = `${config.test.id()}-${config.platform.id()}`;
16             this._acceptedTests.add(config.test);
17             console.assert(!(key in configurationMap));
18             configurationMap[key] = this;
19         }
20     }
21
22     name() { return this._name; }
23     isDisabled() { return this._isDisabled; }
24     repositoryGroups() { return this._repositoryGroups; }
25
26     acceptsTest(test) { return this._acceptedTests.has(test); }
27
28     static findByTestConfiguration(test, platform)
29     {
30         let configurationMap = this.ensureNamedStaticMap('testConfigurations');
31         if (!configurationMap)
32             return null;
33         for (; test; test = test.parentTest()) {
34             const key = `${test.id()}-${platform.id()}`;
35             if (key in configurationMap)
36                 return configurationMap[key];
37         }
38         return null;
39     }
40
41     static triggerablePlatformsForTests(tests)
42     {
43         console.assert(tests instanceof Array);
44         if (!tests.length)
45             return [];
46         return this.sortByName(Platform.all().filter((platform) => {
47             return tests.every((test) => {
48                 const triggerable = Triggerable.findByTestConfiguration(test, platform);
49                 return triggerable && !triggerable.isDisabled();
50             });
51         }));
52     }
53 }
54
55 class TriggerableRepositoryGroup extends LabeledObject {
56
57     constructor(id, object)
58     {
59         super(id, object);
60         this._description = object.description;
61         this._acceptsCustomRoots = !!object.acceptsCustomRoots;
62         this._repositories = Repository.sortByNamePreferringOnesWithURL(object.repositories.map((item) => item.repository));
63         this._patchAcceptingSet = new Set(object.repositories.filter((item) => item.acceptsPatch).map((item) => item.repository));
64     }
65
66     accepts(commitSet)
67     {
68         // FIXME: Add a check for patch.
69         const commitSetRepositories = Repository.sortByNamePreferringOnesWithURL(commitSet.repositories());
70         if (this._repositories.length != commitSetRepositories.length)
71             return false;
72         for (let i = 0; i < this._repositories.length; i++) {
73             const currentRepository = this._repositories[i];
74             if (currentRepository != commitSetRepositories[i])
75                 return false;
76             if (commitSet.patchForRepository(currentRepository) && !this._patchAcceptingSet.has(currentRepository))
77                 return false;
78         }
79         if (commitSet.customRoots().length && !this._acceptsCustomRoots)
80             return false;
81         return true;
82     }
83
84     acceptsPatchForRepository(repository)
85     {
86         return this._patchAcceptingSet.has(repository);
87     }
88
89     description() { return this._description || this.name(); }
90     acceptsCustomRoots() { return this._acceptsCustomRoots; }
91     repositories() { return this._repositories; }
92
93     static sortByNamePreferringSmallerRepositories(groupList)
94     {
95         return groupList.sort((a, b) => {
96             if (a.repositories().length < b.repositories().length)
97                 return -1;
98             else if (a.repositories().length > b.repositories().length)
99                 return 1;
100             if (a.name() < b.name())
101                 return -1;
102             else if (a.name() > b.name())
103                 return 1;
104             return 0;
105         });
106     }
107 }
108
109 if (typeof module != 'undefined') {
110     module.exports.Triggerable = Triggerable;
111     module.exports.TriggerableRepositoryGroup = TriggerableRepositoryGroup;
112 }
113