bafd8251614e63f3e8431754705494acba61741d
[WebKit-https.git] / Websites / perf.webkit.org / public / include / manifest-generator.php
1 <?php
2
3 class ManifestGenerator {
4     private $db;
5     private $manifest;
6
7     // FIXME: Compute this value from config.json
8     const MANIFEST_PATH = '../data/manifest.json';
9
10     function __construct($db) {
11         $this->db = $db;
12         $this->elapsed_time = NULL;
13     }
14
15     function generate() {
16         $start_time = microtime(true);
17
18         $platform_table = $this->db->fetch_table('platforms');
19         $repositories_table = $this->db->fetch_table('repositories');
20
21         $repositories_with_commit = $this->db->query_and_fetch_all(
22             'SELECT DISTINCT(commit_repository) FROM commits WHERE commit_reported IS TRUE');
23         if (!$repositories_with_commit)
24             $repositories_with_commit = array();
25
26         foreach ($repositories_with_commit as &$row)
27             $row = $row['commit_repository'];
28
29         $tests = (object)$this->tests();
30         $metrics = (object)$this->metrics();
31         $platforms = (object)$this->platforms($platform_table, false);
32         $dashboard = (object)$this->platforms($platform_table, true);
33         $repositories = (object)$this->repositories($repositories_table, $repositories_with_commit);
34
35         $this->manifest = array(
36             'siteTitle' => config('siteTitle', 'Performance Dashboard'),
37             'tests' => &$tests,
38             'metrics' => &$metrics,
39             'all' => &$platforms,
40             'dashboard' => &$dashboard,
41             'repositories' => &$repositories,
42             'builders' => (object)$this->builders(),
43             'bugTrackers' => (object)$this->bug_trackers($repositories_table),
44             'triggerables'=> (object)$this->triggerables(),
45             'dashboards' => (object)config('dashboards'),
46             'summaryPages' => config('summaryPages'),
47             'fileUploadSizeLimit' => config('uploadFileLimitInMB', 0) * 1024 * 1024,
48             'testAgeToleranceInHours' => config('testAgeToleranceInHours'),
49         );
50
51         $this->elapsed_time = (microtime(true) - $start_time) * 1000;
52
53         return TRUE;
54     }
55
56     function manifest() { return $this->manifest; }
57
58     function store() {
59         return generate_json_data_with_elapsed_time_if_needed('manifest.json', $this->manifest, $this->elapsed_time);
60     }
61
62     private function tests() {
63         $tests = array();
64         $tests_table = $this->db->fetch_table('tests');
65         if (!$tests_table)
66             return $tests;
67         foreach ($tests_table as $test_row) {
68             $tests[$test_row['test_id']] = array(
69                 'name' => $test_row['test_name'],
70                 'url' => $test_row['test_url'],
71                 'parentId' => $test_row['test_parent'],
72             );
73         }
74         return $tests;
75     }
76
77     private function metrics() {
78         $metrics = array();
79         $metrics_table = $this->db->query_and_fetch_all('SELECT * FROM test_metrics LEFT JOIN aggregators ON metric_aggregator = aggregator_id');
80         if (!$metrics_table)
81             return $metrics;
82         foreach ($metrics_table as $row) {
83             $metrics[$row['metric_id']] = array(
84                 'name' => $row['metric_name'],
85                 'test' => $row['metric_test'],
86                 'aggregator' => $row['aggregator_name']);
87         }
88         return $metrics;
89     }
90
91     private function platforms($platform_table, $is_dashboard) {
92         $metrics = $this->db->query_and_fetch_all('SELECT config_metric AS metric_id, config_platform AS platform_id,
93             extract(epoch from max(config_runs_last_modified) at time zone \'utc\') * 1000 AS last_modified, bool_or(config_is_in_dashboard) AS in_dashboard
94             FROM test_configurations GROUP BY config_metric, config_platform ORDER BY config_platform');
95
96         $platform_metrics = array();
97
98         if ($metrics) {
99             $current_platform_entry = null;
100             foreach ($metrics as $metric_row) {
101                 if ($is_dashboard && !Database::is_true($metric_row['in_dashboard']))
102                     continue;
103
104                 $platform_id = $metric_row['platform_id'];
105                 if (!$current_platform_entry || $current_platform_entry['id'] != $platform_id) {
106                     $current_platform_entry = &array_ensure_item_has_array($platform_metrics, $platform_id);
107                     $current_platform_entry['id'] = $platform_id;
108                     array_ensure_item_has_array($current_platform_entry, 'metrics');
109                     array_ensure_item_has_array($current_platform_entry, 'last_modified');
110                 }
111
112                 array_push($current_platform_entry['metrics'], $metric_row['metric_id']);
113                 array_push($current_platform_entry['last_modified'], intval($metric_row['last_modified']));
114             }
115         }
116         $configurations = array();
117
118         $platforms = array();
119         if ($platform_table) {
120             foreach ($platform_table as $platform_row) {
121                 if (Database::is_true($platform_row['platform_hidden']))
122                     continue;
123                 $id = $platform_row['platform_id'];
124                 if (array_key_exists($id, $platform_metrics)) {
125                     $platforms[$id] = array(
126                         'name' => $platform_row['platform_name'],
127                         'metrics' => $platform_metrics[$id]['metrics'],
128                         'lastModified' => $platform_metrics[$id]['last_modified']);
129                 }
130             }
131         }
132         return $platforms;
133     }
134
135     private function repositories($repositories_table, $repositories_with_commit) {
136         $repositories = array();
137         if (!$repositories_table)
138             return $repositories;
139         foreach ($repositories_table as $row) {
140             $repositories[$row['repository_id']] = array(
141                 'name' => $row['repository_name'],
142                 'url' => $row['repository_url'],
143                 'blameUrl' => $row['repository_blame_url'],
144                 'owner'=> $row['repository_owner'],
145                 'hasReportedCommits' => in_array($row['repository_id'], $repositories_with_commit));
146         }
147
148         return $repositories;
149     }
150
151     private function builders() {
152         $builders_table = $this->db->fetch_table('builders');
153         if (!$builders_table)
154             return array();
155         $builders = array();
156         foreach ($builders_table as $row)
157             $builders[$row['builder_id']] = array('name' => $row['builder_name'], 'buildUrl' => $row['builder_build_url']);
158
159         return $builders;
160     }
161
162     private function bug_trackers($repositories_table) {
163         $tracker_id_to_repositories = array();
164         $tracker_repositories_table = $this->db->fetch_table('tracker_repositories');
165         if ($tracker_repositories_table) {
166             foreach ($tracker_repositories_table as $row) {
167                 array_push(array_ensure_item_has_array($tracker_id_to_repositories, $row['tracrepo_tracker']),
168                     $row['tracrepo_repository']);
169             }
170         }
171
172         $bug_trackers = array();
173         $bug_trackers_table = $this->db->fetch_table('bug_trackers');
174         if ($bug_trackers_table) {
175             foreach ($bug_trackers_table as $row) {
176                 $bug_trackers[$row['tracker_id']] = array(
177                     'name' => $row['tracker_name'],
178                     'bugUrl' => $row['tracker_bug_url'],
179                     'newBugUrl' => $row['tracker_new_bug_url'],
180                     'repositories' => array_get($tracker_id_to_repositories, $row['tracker_id']));
181             }
182         }
183
184         return $bug_trackers;
185     }
186
187     private function triggerables()
188     {
189         return ManifestGenerator::fetch_triggerables($this->db, array());
190     }
191
192     static function fetch_triggerables($db, $query)
193     {
194         $triggerables = $db->select_rows('build_triggerables', 'triggerable', $query);
195         if (!$triggerables)
196             return array();
197
198         $id_to_triggerable = array();
199         $triggerable_id_to_repository_set = array();
200         foreach ($triggerables as &$row) {
201             $id = $row['triggerable_id'];
202             $id_to_triggerable[$id] = array(
203                 'name' => $row['triggerable_name'],
204                 'isDisabled' => Database::is_true($row['triggerable_disabled']),
205                 'acceptedRepositories' => array(),
206                 'repositoryGroups' => array(),
207                 'configurations' => array());
208             $triggerable_id_to_repository_set[$id] = array();
209         }
210
211         $repository_groups = $db->fetch_table('triggerable_repository_groups', 'repositorygroup_name');
212         $group_repositories = $db->fetch_table('triggerable_repositories');
213         if ($repository_groups && $group_repositories) {
214             $repository_set_by_group = array();
215             foreach ($group_repositories as &$repository_row) {
216                 $group_id = $repository_row['trigrepo_group'];
217                 array_ensure_item_has_array($repository_set_by_group, $group_id);
218                 array_push($repository_set_by_group[$group_id], array(
219                     'repository' => $repository_row['trigrepo_repository'],
220                     'acceptsPatch' => Database::is_true($repository_row['trigrepo_accepts_patch'])));
221             }
222             foreach ($repository_groups as &$group_row) {
223                 $triggerable_id = $group_row['repositorygroup_triggerable'];
224                 if (!array_key_exists($triggerable_id, $id_to_triggerable))
225                     continue;
226                 $triggerable = &$id_to_triggerable[$triggerable_id];
227                 $group_id = $group_row['repositorygroup_id'];
228                 $repository_list = array_get($repository_set_by_group, $group_id, array());
229                 array_push($triggerable['repositoryGroups'], array(
230                     'id' => $group_row['repositorygroup_id'],
231                     'name' => $group_row['repositorygroup_name'],
232                     'description' => $group_row['repositorygroup_description'],
233                     'hidden' => Database::is_true($group_row['repositorygroup_hidden']),
234                     'acceptsCustomRoots' => Database::is_true($group_row['repositorygroup_accepts_roots']),
235                     'repositories' => $repository_list));
236                 // V2 UI compatibility.
237                 foreach ($repository_list as $repository_data) {
238                     $repository_id = $repository_data['repository'];
239                     $set = &$triggerable_id_to_repository_set[$triggerable_id];
240                     if (array_key_exists($repository_id, $set))
241                         continue;
242                     $set[$repository_id] = true;
243                     array_push($triggerable['acceptedRepositories'], $repository_id);
244                 }
245
246             }
247         }
248
249         $configuration_map = $db->fetch_table('triggerable_configurations');
250         if ($configuration_map) {
251             foreach ($configuration_map as &$row) {
252                 $triggerable_id = $row['trigconfig_triggerable'];
253                 if (!array_key_exists($triggerable_id, $id_to_triggerable))
254                     continue;
255                 $triggerable = &$id_to_triggerable[$triggerable_id];
256                 array_push($triggerable['configurations'], array($row['trigconfig_test'], $row['trigconfig_platform']));
257             }
258         }
259
260         return $id_to_triggerable;
261     }
262 }
263
264 ?>