50f233b45673536adf1bf0ff16a7b36b55770805
[WebKit-https.git] / Websites / perf.webkit.org / public / api / runs.php
1 <?php
2
3 require('../include/json-header.php');
4
5 function fetch_runs_for_config($db, $config) {
6     $raw_runs = $db->query_and_fetch_all('
7         SELECT test_runs.*, builds.*, array_agg((commit_repository, commit_revision, commit_time)) AS revisions
8             FROM builds
9                 LEFT OUTER JOIN build_commits ON commit_build = build_id
10                 LEFT OUTER JOIN commits ON build_commit = commit_id, test_runs
11             WHERE run_build = build_id AND run_config = $1 AND NOT EXISTS (SELECT * FROM build_requests WHERE request_build = build_id)
12             GROUP BY build_id, run_id', array($config['config_id']));
13
14     $formatted_runs = array();
15     if (!$raw_runs)
16         return $formatted_runs;
17
18     foreach ($raw_runs as $run)
19         array_push($formatted_runs, format_run($run));
20
21     return $formatted_runs;
22 }
23
24 function parse_revisions_array($postgres_array) {
25     global $repository_id_to_name;
26
27     // e.g. {"(WebKit,131456,\"2012-10-16 14:53:00\")","(Chromium,162004,)"}
28     $outer_array = json_decode('[' . trim($postgres_array, '{}') . ']');
29     $revisions = array();
30     foreach ($outer_array as $item) {
31         $name_and_revision = explode(',', trim($item, '()'));
32         if (!$name_and_revision[0])
33             continue;
34         $time = strtotime(trim($name_and_revision[2], '"')) * 1000;
35         $revisions[$repository_id_to_name[trim($name_and_revision[0], '"')]] = array(trim($name_and_revision[1], '"'), $time);
36     }
37     return $revisions;
38 }
39
40 function format_run($run) {
41     return array(
42         'id' => intval($run['run_id']),
43         'mean' => floatval($run['run_mean_cache']),
44         'iterationCount' => intval($run['run_iteration_count_cache']),
45         'sum' => floatval($run['run_sum_cache']),
46         'squareSum' => floatval($run['run_square_sum_cache']),
47         'revisions' => parse_revisions_array($run['revisions']),
48         'buildTime' => strtotime($run['build_time']) * 1000,
49         'buildNumber' => intval($run['build_number']),
50         'builder' => $run['build_builder']);
51 }
52
53 function main($path) {
54     if (count($path) != 1)
55         exit_with_error('InvalidRequest');
56
57     $parts = explode('-', $path[0]);
58     if (count($parts) != 2)
59         exit_with_error('InvalidRequest');
60
61     $db = new Database;
62     if (!$db->connect())
63         exit_with_error('DatabaseConnectionFailure');
64
65     // FIXME: We should support revalication as well as caching results in the server side.
66     $maxage = config('jsonCacheMaxAge');
67     header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $maxage) . ' GMT');
68     header("Cache-Control: maxage=$maxage");
69
70     $platform_id = intval($parts[0]);
71     $metric_id = intval($parts[1]);
72     $config_rows = $db->query_and_fetch_all('SELECT config_id, config_type, config_platform, config_metric
73         FROM test_configurations WHERE config_metric = $1 AND config_platform = $2', array($metric_id, $platform_id));
74     if (!$config_rows)
75         exit_with_error('ConfigurationNotFound');
76
77     $repository_id_to_name = array();
78     if ($repository_table = $db->fetch_table('repositories')) {
79         foreach ($repository_table as $repository)
80             $repository_id_to_name[$repository['repository_id']] = $repository['repository_name'];
81     }
82
83     $results = array();
84     foreach ($config_rows as $config) {
85         if ($runs = fetch_runs_for_config($db, $config))
86             $results[$config['config_type']] = $runs;
87     }
88
89     exit_with_success($results);
90 }
91
92 main(array_key_exists('PATH_INFO', $_SERVER) ? explode('/', trim($_SERVER['PATH_INFO'], '/')) : array());
93
94 ?>