Extend create-analysis-test API to be able to create with confirming test group.
[WebKit-https.git] / Websites / perf.webkit.org / public / privileged-api / create-analysis-task.php
1 <?php
2
3 require_once('../include/json-header.php');
4 require_once('../include/commit-sets-helpers.php');
5
6 function main() {
7     $db = connect();
8     $data = ensure_privileged_api_data_and_token_or_slave($db);
9
10     $author = remote_user_name($data);
11     $name = array_get($data, 'name');
12     $repetition_count = array_get($data, 'repetitionCount');
13     $test_group_name = array_get($data, 'testGroupName');
14     $revision_set_list = array_get($data, 'revisionSets');
15
16     $segmentation_name = array_get($data, 'segmentationStrategy');
17     $test_range_name = array_get($data, 'testRangeStrategy');
18
19     if (!$name)
20         exit_with_error('MissingName', array('name' => $name));
21
22     $range = validate_arguments($data, array('startRun' => 'int', 'endRun' => 'int'));
23
24     $start_run = ensure_row_by_id($db, 'test_runs', 'run', $range['startRun'], 'InvalidStartRun', $range);
25     $start_run_id = $start_run['run_id'];
26     $end_run = ensure_row_by_id($db, 'test_runs', 'run', $range['endRun'], 'InvalidEndRun', $range);
27     $end_run_id = $end_run['run_id'];
28
29     $config = ensure_config_from_runs($db, $start_run, $end_run);
30
31     $start_run_time = time_for_run($db, $start_run_id);
32     $end_run_time = time_for_run($db, $end_run_id);
33     if (!$start_run_time || !$end_run_time || $start_run_time == $end_run_time)
34         exit_with_error('InvalidTimeRange', array('startTime' => $start_run_time, 'endTime' => $end_run_time));
35
36     $db->begin_transaction();
37
38     $segmentation_id = NULL;
39     if ($segmentation_name) {
40         $segmentation_id = $db->select_or_insert_row('analysis_strategies', 'strategy', array('name' => $segmentation_name));
41         if (!$segmentation_id) {
42             $db->rollback_transaction();
43             exit_with_error('CannotFindOrInsertSegmentationStrategy', array('segmentationStrategy' => $segmentation_name));
44         }
45     }
46
47     $test_range_id = NULL;
48     if ($test_range_name) {
49         $test_range_id = $db->select_or_insert_row('analysis_strategies', 'strategy', array('name' => $test_range_name));
50         if (!$test_range_id) {
51             $db->rollback_transaction();
52             exit_with_error('CannotFindOrInsertTestRangeStrategy', array('testRangeStrategy' => $test_range_name));
53         }
54     }
55
56     $duplicate = $db->select_first_row('analysis_tasks', 'task', array('start_run' => $start_run_id, 'end_run' => $end_run_id));
57     if ($duplicate) {
58         $db->rollback_transaction();
59         exit_with_error('DuplicateAnalysisTask', array('duplicate' => $duplicate));
60     }
61
62     $task_id = $db->insert_row('analysis_tasks', 'task', array(
63         'name' => $name,
64         'author' => $author,
65         'platform' => $config['config_platform'],
66         'metric' => $config['config_metric'],
67         'start_run' => $start_run_id,
68         'start_run_time' => $start_run_time,
69         'end_run' => $end_run_id,
70         'end_run_time' => $end_run_time,
71         'segmentation' => $segmentation_id,
72         'test_range' => $test_range_id));
73
74     if ($repetition_count) {
75         $triggerable = find_triggerable_for_task($db, $task_id);
76         if (!$triggerable || !$triggerable['id']) {
77             $db->rollback_transaction();
78             exit_with_error('TriggerableNotFoundForTask', array('task' => $task_id, 'platform' => $config['config_platform']));
79         }
80         if ($triggerable['platform'] != $config['config_platform']) {
81             $db->rollback_transaction();
82             exit_with_error('InconsistentPlatform', array('configPlatform' => $config['config_platform'], 'taskPlatform' => $triggerable['platform']));
83         }
84         $triggerable_id = $triggerable['id'];
85         $test_id = $triggerable['test'];
86         $commit_sets = commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list);
87         create_test_group_and_build_requests($db, $commit_sets, $task_id, $test_group_name, $author, $triggerable_id, $config['config_platform'], $test_id, $repetition_count);
88     }
89
90     $db->commit_transaction();
91
92     exit_with_success(array('taskId' => $task_id));
93 }
94
95 function ensure_row_by_id($db, $table, $prefix, $id, $error_name, $error_params) {
96     $row = $db->select_first_row($table, $prefix, array('id' => $id));
97     if (!$row)
98         exit_with_error($error_name, array($error_params));
99     return $row;
100 }
101
102 function ensure_config_from_runs($db, $start_run, $end_run) {
103     $range = array('startRun' => $start_run, 'endRun' => $end_run);
104
105     if ($start_run['run_config'] != $end_run['run_config'])
106         exit_with_error('RunConfigMismatch', $range);
107
108     return ensure_row_by_id($db, 'test_configurations', 'config', $start_run['run_config'], 'ConfigNotFound', $range);
109 }
110
111 function time_for_run($db, $run_id) {
112     $result = $db->query_and_fetch_all('SELECT max(commit_time) as time, max(build_time) as build_time
113         FROM test_runs JOIN builds ON run_build = build_id
114             JOIN build_commits ON commit_build = build_id
115             JOIN commits ON build_commit = commit_id
116         WHERE run_id = $1', array($run_id));
117
118     $first_result = array_get($result, 0, array());
119     return $first_result['time'] ? $first_result['time'] : $first_result['build_time'];
120 }
121
122 main();
123
124 ?>