e0e58430108ffb9db44181189dcf6c0cc837dede
[WebKit-https.git] / Websites / perf.webkit.org / public / privileged-api / create-test-group.php
1 <?php
2
3 require_once('../include/json-header.php');
4 require_once('../include/repository-group-finder.php');
5
6 function main()
7 {
8     $db = connect();
9     $data = ensure_privileged_api_data_and_token_or_slave($db);
10     $author = remote_user_name($data);
11
12     $arguments = validate_arguments($data, array(
13         'name' => '/.+/',
14         'task' => 'int?',
15         'repetitionCount' => 'int?',
16     ));
17     $name = $arguments['name'];
18     $task_id = array_get($arguments, 'task');
19     $task_name = array_get($data, 'taskName');
20     $repetition_count = $arguments['repetitionCount'];
21     $platform_id = array_get($data, 'platform');
22     $test_id = array_get($data, 'test');
23     $revision_set_list = array_get($data, 'revisionSets');
24     $commit_sets_info = array_get($data, 'commitSets');
25
26     if (!$task_id == !$task_name)
27         exit_with_error('InvalidTask');
28
29     if ($task_id)
30         require_format('Task', $task_id, '/^\d+$/');
31     if ($task_name || $platform_id || $test_id) {
32         require_format('Platform', $platform_id, '/^\d+$/');
33         require_format('Test', $test_id, '/^\d+$/');
34     }
35
36     if (!$revision_set_list && !$commit_sets_info)
37         exit_with_error('InvalidCommitSets');
38
39     if ($repetition_count === null)
40         $repetition_count = 1;
41     else if ($repetition_count < 1)
42         exit_with_error('InvalidRepetitionCount', array('repetitionCount' => $repetition_count));
43
44     $triggerable_id = NULL;
45     if ($task_id) {
46         $task = $db->select_first_row('analysis_tasks', 'task', array('id' => $task_id));
47         if (!$task)
48             exit_with_error('InvalidTask', array('task' => $task_id));
49         $triggerable = find_triggerable_for_task($db, $task_id);
50         if ($triggerable) {
51             $triggerable_id = $triggerable['id'];
52             if (!$platform_id && !$test_id) {
53                 $platform_id = $triggerable['platform'];
54                 $test_id = $triggerable['test'];
55             } else {
56                 if ($triggerable['platform'] && $platform_id != $triggerable['platform'])
57                     exit_with_error('InconsistentPlatform', array('groupPlatform' => $platform_id, 'taskPlatform' => $triggerable['platform']));
58                 if ($triggerable['test'] && $test_id != $triggerable['test'])
59                     exit_with_error('InconsistentTest', array('groupTest' => $test_id, 'taskTest' => $triggerable['test']));
60             }
61         }
62     }
63     if (!$triggerable_id && $platform_id && $test_id) {
64         $triggerable_configuration = $db->select_first_row('triggerable_configurations', 'trigconfig',
65             array('test' => $test_id, 'platform' => $platform_id));
66         if ($triggerable_configuration)
67             $triggerable_id = $triggerable_configuration['trigconfig_triggerable'];
68     }
69
70     if (!$triggerable_id)
71         exit_with_error('TriggerableNotFoundForTask', array('task' => $task_id, 'platform' => $platform_id, 'test' => $test_id));
72
73     if ($revision_set_list)
74         $commit_sets = commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list);
75     else // V2 UI compatibility
76         $commit_sets = ensure_commit_sets($db, $triggerable_id, $commit_sets_info);
77
78     $db->begin_transaction();
79
80     if ($task_name)
81         $task_id = $db->insert_row('analysis_tasks', 'task', array('name' => $task_name, 'author' => $author));
82
83     $configuration_list = array();
84     foreach ($commit_sets as $commit_list) {
85         $commit_set_id = $db->insert_row('commit_sets', 'commitset', array());
86         foreach ($commit_list['set'] as $commit_row) {
87             $commit_row['set'] = $commit_set_id;
88             $db->insert_row('commit_set_items', 'commitset', $commit_row, 'commit');
89         }
90         array_push($configuration_list, array('commit_set' => $commit_set_id, 'repository_group' => $commit_list['repository_group']));
91     }
92
93     $group_id = $db->insert_row('analysis_test_groups', 'testgroup',
94         array('task' => $task_id, 'name' => $name, 'author' => $author));
95
96     $order = 0;
97     for ($i = 0; $i < $repetition_count; $i++) {
98         foreach ($configuration_list as $config) {
99             $db->insert_row('build_requests', 'request', array(
100                 'triggerable' => $triggerable_id,
101                 'repository_group' => $config['repository_group'],
102                 'platform' => $platform_id,
103                 'test' => $test_id,
104                 'group' => $group_id,
105                 'order' => $order,
106                 'commit_set' => $config['commit_set'],));
107             $order++;
108         }
109     }
110
111     $db->commit_transaction();
112
113     exit_with_success(array('taskId' => $task_id, 'testGroupId' => $group_id));
114 }
115
116 function commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list)
117 {
118     if (count($revision_set_list) < 2)
119         exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list));
120
121     $finder = new RepositoryGroupFinder($db, $triggerable_id);
122     $commit_set_list = array();
123     foreach ($revision_set_list as $revision_set) {
124         if (!count($revision_set))
125             exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list));
126
127         $commit_set = array();
128         $repository_list = array();
129         foreach ($revision_set as $repository_id => $revision) {
130             if ($repository_id == 'customRoots') {
131                 $file_id_list = $revision;
132                 foreach ($file_id_list as $file_id) {
133                     if (!$db->select_first_row('uploaded_files', 'file', array('id' => $file_id)))
134                         exit_with_error('InvalidUploadedFile', array('file' => $file_id));
135                     array_push($commit_set, array('root_file' => $file_id));
136                 }
137                 continue;
138             }
139             if (!is_numeric($repository_id))
140                 exit_with_error('InvalidRepository', array('repository' => $repository_id));
141             $commit = $db->select_first_row('commits', 'commit',
142                 array('repository' => intval($repository_id), 'revision' => $revision));
143             if (!$commit)
144                 exit_with_error('RevisionNotFound', array('repository' => $repository_id, 'revision' => $revision));
145             array_push($commit_set, array('commit' => $commit['commit_id']));
146             array_push($repository_list, $repository_id);
147         }
148
149         $repository_group_id = $finder->find_by_repositories($repository_list);
150         if (!$repository_group_id)
151             exit_with_error('NoMatchingRepositoryGroup', array('repositoris' => $repository_list));
152
153         array_push($commit_set_list, array('repository_group' => $repository_group_id, 'set' => $commit_set));
154     }
155
156     return $commit_set_list;
157 }
158
159 function ensure_commit_sets($db, $triggerable_id, $commit_sets_info) {
160     $repository_name_to_id = array();
161     foreach ($db->select_rows('repositories', 'repository', array('owner' => NULL)) as $row)
162         $repository_name_to_id[$row['repository_name']] = $row['repository_id'];
163
164     $commit_sets = array();
165     $repository_list = array();
166     foreach ($commit_sets_info as $repository_name => $revisions) {
167         $repository_id = array_get($repository_name_to_id, $repository_name);
168         if (!$repository_id)
169             exit_with_error('RepositoryNotFound', array('name' => $repository_name));
170         array_push($repository_list, $repository_id);
171
172         foreach ($revisions as $i => $revision) {
173             $commit = $db->select_first_row('commits', 'commit', array('repository' => $repository_id, 'revision' => $revision));
174             if (!$commit)
175                 exit_with_error('RevisionNotFound', array('repository' => $repository_name, 'revision' => $revision));
176             array_set_default($commit_sets, $i, array('set' => array()));
177             array_push($commit_sets[$i]['set'], array('commit' => $commit['commit_id']));
178         }
179     }
180
181     $finder = new RepositoryGroupFinder($db, $triggerable_id);
182     $repository_group_id = $finder->find_by_repositories($repository_list);
183     if (!$repository_group_id)
184         exit_with_error('NoMatchingRepositoryGroup', array('repositoris' => $repository_list));
185
186     if (count($commit_sets) < 2)
187         exit_with_error('InvalidCommitSets', array('commitSets' => $commit_sets_info));
188
189     $commit_count_per_set = count($commit_sets[0]['set']);
190     foreach ($commit_sets as &$commits) {
191         $commits['repository_group'] = $repository_group_id;
192         if ($commit_count_per_set != count($commits['set']))
193             exit_with_error('InvalidCommitSets', array('commitSets' => $commit_sets));
194     }
195
196     return $commit_sets;
197 }
198
199 main();
200
201 ?>