|
17 | 17 |
|
18 | 18 | namespace CDash\Controller\Api; |
19 | 19 |
|
20 | | -use App\Models\Project as EloquentProject; |
21 | | -use App\Models\Test; |
22 | | -use App\Utils\RepositoryUtils; |
| 20 | +use Exception; |
23 | 21 | use Illuminate\Http\JsonResponse; |
24 | 22 | use Illuminate\Support\Facades\DB; |
25 | 23 | use Symfony\Component\HttpFoundation\StreamedResponse; |
@@ -56,306 +54,6 @@ function () use ($query): void { |
56 | 54 | ); |
57 | 55 | } |
58 | 56 |
|
59 | | - $response = begin_JSON_response(); |
60 | | - |
61 | | - $site = $this->build->GetSite(); |
62 | | - |
63 | | - $this->setDate($this->build->GetDate()); |
64 | | - |
65 | | - $response['title'] = "{$this->project->Name} - Tests"; |
66 | | - get_dashboard_JSON($this->project->Name, $this->date, $response); |
67 | | - |
68 | | - $project_response = []; |
69 | | - $project_response['showtesttime'] = $this->project->ShowTestTime; |
70 | | - $response['project'] = $project_response; |
71 | | - |
72 | | - $stmt = $this->db->prepare(' |
73 | | - SELECT |
74 | | - *, |
75 | | - b2t.id as testid |
76 | | - FROM build2test b2t |
77 | | - JOIN testoutput ON (testoutput.id = b2t.outputid) |
78 | | - WHERE b2t.id = :buildtestid |
79 | | - '); |
80 | | - $this->db->execute($stmt, [':buildtestid' => $this->buildtest->id]); |
81 | | - $testRow = $stmt->fetch(); |
82 | | - $testName = $testRow['testname']; |
83 | | - $outputid = $testRow['outputid']; |
84 | | - $testid = $testRow['testid']; |
85 | | - |
86 | | - $menu = []; |
87 | | - $menu['back'] = "viewTest.php?buildid={$this->build->Id}"; |
88 | | - |
89 | | - // Did the user request a specific chart? |
90 | | - // If so we should make that chart appears when they click next or previous. |
91 | | - $extra_url = ''; |
92 | | - if (array_key_exists('graph', $_GET)) { |
93 | | - $extra_url = '?graph=' . $_GET['graph']; |
94 | | - } |
95 | | - |
96 | | - // Get previous/current/next results for this buildtest. |
97 | | - $previous_buildtestid = $this->getRelatedBuildTest('previous'); |
98 | | - $current_buildtestid = $this->getRelatedBuildTest('current'); |
99 | | - $next_buildtestid = $this->getRelatedBuildTest('next'); |
100 | | - |
101 | | - // Navigation menu entry for 'Previous'. |
102 | | - if ($previous_buildtestid) { |
103 | | - $menu['previous'] = "/tests/{$previous_buildtestid}{$extra_url}"; |
104 | | - } else { |
105 | | - $menu['previous'] = false; |
106 | | - } |
107 | | - |
108 | | - // Current |
109 | | - if ($current_buildtestid) { |
110 | | - $menu['current'] = "/tests/{$current_buildtestid}{$extra_url}"; |
111 | | - } else { |
112 | | - $menu['current'] = false; |
113 | | - } |
114 | | - |
115 | | - // Next |
116 | | - if ($next_buildtestid) { |
117 | | - $menu['next'] = "/tests/{$next_buildtestid}{$extra_url}"; |
118 | | - } else { |
119 | | - $menu['next'] = false; |
120 | | - } |
121 | | - |
122 | | - $response['menu'] = $menu; |
123 | | - |
124 | | - $test_response = []; |
125 | | - $test_response['buildid'] = $this->build->Id; |
126 | | - $test_response['build'] = $this->build->Name; |
127 | | - $test_response['buildstarttime'] = date(FMT_DATETIMESTD, strtotime($this->build->StartTime . ' UTC')); |
128 | | - $test_response['site'] = $site->name; |
129 | | - $test_response['siteid'] = $site->id; |
130 | | - $test_response['test'] = $testName; |
131 | | - $test_response['time'] = time_difference($testRow['time'], true, '', true); |
132 | | - $test_response['command'] = $testRow['command']; |
133 | | - $test_response['details'] = $testRow['details']; |
134 | | - $test_response['output'] = $this->utf8_for_xml($testRow['output']); |
135 | | - |
136 | | - if ($this->project->DisplayLabels) { |
137 | | - $test_response['labels'] = $this->buildtest->getLabels()->keys()->implode(', '); |
138 | | - } else { |
139 | | - $test_response['labels'] = ''; |
140 | | - } |
141 | | - |
142 | | - $test_response['summaryLink'] = "queryTests.php?project={$this->project->Name}&filtercount=1&showfilters=1&field1=testname&compare1=61&value1={$testName}&date={$this->date}"; |
143 | | - switch ($testRow['status']) { |
144 | | - case 'passed': |
145 | | - $test_response['status'] = 'Passed'; |
146 | | - $test_response['statusColor'] = 'normal-text'; |
147 | | - break; |
148 | | - case 'failed': |
149 | | - $test_response['status'] = 'Failed'; |
150 | | - $test_response['statusColor'] = 'error-text'; |
151 | | - break; |
152 | | - case 'notrun': |
153 | | - $test_response['status'] = 'Not Run'; |
154 | | - $test_response['statusColor'] = 'warning-text'; |
155 | | - break; |
156 | | - } |
157 | | - |
158 | | - // Find the repository revision. |
159 | | - $update_response = [ |
160 | | - 'revision' => '', |
161 | | - 'priorrevision' => '', |
162 | | - 'path' => '', |
163 | | - 'revisionurl' => '', |
164 | | - 'revisiondiff' => '', |
165 | | - ]; |
166 | | - $stmt = $this->db->prepare( |
167 | | - 'SELECT status, revision, priorrevision, path |
168 | | - FROM buildupdate bu |
169 | | - JOIN build b ON (b.updateid = bu.id) |
170 | | - WHERE b.id = :buildid'); |
171 | | - $this->db->execute($stmt, [':buildid' => $this->build->Id]); |
172 | | - $status_array = $stmt->fetch(); |
173 | | - if (is_array($status_array)) { |
174 | | - if (strlen($status_array['status']) > 0 && $status_array['status'] != '0') { |
175 | | - $update_response['status'] = $status_array['status']; |
176 | | - } |
177 | | - $update_response['revision'] = $status_array['revision']; |
178 | | - $update_response['priorrevision'] = $status_array['priorrevision']; |
179 | | - $update_response['path'] = $status_array['path']; |
180 | | - $update_response['revisionurl'] = |
181 | | - RepositoryUtils::get_revision_url($this->project->Id, $status_array['revision'], $status_array['priorrevision']); |
182 | | - $update_response['revisiondiff'] = |
183 | | - RepositoryUtils::get_revision_url($this->project->Id, $status_array['priorrevision'], ''); // no prior revision... |
184 | | - } |
185 | | - $test_response['update'] = $update_response; |
186 | | - |
187 | | - $test_response['timemean'] = $testRow['timemean']; |
188 | | - $test_response['timestd'] = $testRow['timestd']; |
189 | | - |
190 | | - $testtimemaxstatus = $this->project->TestTimeMaxStatus; |
191 | | - if ($testRow['timestatus'] == 0) { |
192 | | - $test_response['timestatus'] = 'Passed'; |
193 | | - $test_response['timeStatusColor'] = 'normal-text'; |
194 | | - } else { |
195 | | - $threshold = $test_response['timemean'] + |
196 | | - $this->project->TestTimeStd * $test_response['timestd']; |
197 | | - $test_response['threshold'] = time_difference($threshold, true, '', true); |
198 | | - if ($testRow['timestatus'] >= $testtimemaxstatus) { |
199 | | - $test_response['timestatus'] = 'Failed'; |
200 | | - $test_response['timeStatusColor'] = 'error-text'; |
201 | | - } else { |
202 | | - $test_response['timestatus'] = 'Warning'; |
203 | | - $test_response['timeStatusColor'] = 'warning-text'; |
204 | | - } |
205 | | - } |
206 | | - |
207 | | - // Get any images associated with this test. |
208 | | - $compareimages_response = []; |
209 | | - $test_images = Test::findOrFail((int) $testid) |
210 | | - ->testImages() |
211 | | - ->whereIn('role', [ |
212 | | - 'TestImage', |
213 | | - 'ValidImage', |
214 | | - 'BaselineImage', |
215 | | - 'DifferenceImage2', |
216 | | - ])->get(); |
217 | | - foreach ($test_images as $row) { |
218 | | - $compareimages_response[] = [ |
219 | | - 'imgid' => $row->imgid, |
220 | | - 'role' => $row->role, |
221 | | - ]; |
222 | | - } |
223 | | - if (!empty($compareimages_response)) { |
224 | | - $test_response['compareimages'] = $compareimages_response; |
225 | | - } |
226 | | - |
227 | | - $images_response = []; |
228 | | - $test_images = Test::findOrFail((int) $testid) |
229 | | - ->testImages() |
230 | | - ->whereNotIn('role', [ |
231 | | - 'ValidImage', |
232 | | - 'BaselineImage', |
233 | | - 'DifferenceImage2', |
234 | | - ])->get(); |
235 | | - foreach ($test_images as $row) { |
236 | | - $images_response[] = [ |
237 | | - 'imgid' => $row->imgid, |
238 | | - 'role' => $row->role, |
239 | | - ]; |
240 | | - } |
241 | | - if (!empty($images_response)) { |
242 | | - $test_response['images'] = $images_response; |
243 | | - } |
244 | | - |
245 | | - // Get any measurements associated with this test. |
246 | | - $measurements_response = []; |
247 | | - $stmt = $this->db->prepare( |
248 | | - 'SELECT name, type, value FROM testmeasurement |
249 | | - WHERE testid = :testid |
250 | | - ORDER BY id'); |
251 | | - $this->db->execute($stmt, [':testid' => $testid]); |
252 | | - $fileid = 1; |
253 | | - $test_response['environment'] = ''; |
254 | | - $preformatted_measurements = []; |
255 | | - |
256 | | - while ($row = $stmt->fetch()) { |
257 | | - if ($row['name'] === 'Environment' && $row['type'] === 'text/string') { |
258 | | - $test_response['environment'] = $row['value']; |
259 | | - continue; |
260 | | - } elseif ($row['type'] === 'text/preformatted') { |
261 | | - $preformatted_measurement = ['name' => $row['name'], 'value' => $row['value']]; |
262 | | - $preformatted_measurements[] = $preformatted_measurement; |
263 | | - continue; |
264 | | - } |
265 | | - |
266 | | - $measurement_response = []; |
267 | | - $measurement_response['name'] = $row['name']; |
268 | | - $measurement_response['type'] = $row['type']; |
269 | | - |
270 | | - // CTest base64-encodes the type text/plain... |
271 | | - $value = $row['value']; |
272 | | - if ($row['type'] === 'text/plain') { |
273 | | - if (substr($value, strlen($value) - 2) === '==') { |
274 | | - $value = base64_decode($value); |
275 | | - } |
276 | | - } elseif ($row['type'] === 'file') { |
277 | | - $measurement_response['fileid'] = $fileid++; |
278 | | - } |
279 | | - // Add nl2br for type text/plain and text/string |
280 | | - if ($row['type'] === 'text/plain' || $row['type'] === 'text/string') { |
281 | | - $value = nl2br($value); |
282 | | - } |
283 | | - |
284 | | - // If the type is a file we just don't pass the text (too big) to the output |
285 | | - if ($row['type'] === 'file') { |
286 | | - $value = ''; |
287 | | - } |
288 | | - |
289 | | - $measurement_response['value'] = $value; |
290 | | - $measurements_response[] = $measurement_response; |
291 | | - } |
292 | | - |
293 | | - // Get the list of extra test measurements that have been explicitly added to this project. |
294 | | - $extra_measurements = EloquentProject::findOrFail($this->project->Id) |
295 | | - ->pinnedTestMeasurements() |
296 | | - ->orderBy('position') |
297 | | - ->pluck('name') |
298 | | - ->toArray(); |
299 | | - |
300 | | - // Sort measurements: put those listed explicitly first (sorted by position) |
301 | | - // then sort the rest alphabetically by name. |
302 | | - $sort_measurements = function ($a, $b) use ($extra_measurements) { |
303 | | - $index_a = array_search($a['name'], $extra_measurements); |
304 | | - $index_b = array_search($b['name'], $extra_measurements); |
305 | | - if ($index_a !== false && $index_b !== false) { |
306 | | - return ($index_a < $index_b) ? -1 : 1; |
307 | | - } elseif ($index_a !== false) { |
308 | | - return -1; |
309 | | - } elseif ($index_b !== false) { |
310 | | - return 1; |
311 | | - } |
312 | | - return strcmp($a['name'], $b['name']); |
313 | | - }; |
314 | | - usort($measurements_response, $sort_measurements); |
315 | | - $test_response['measurements'] = $measurements_response; |
316 | | - usort($preformatted_measurements, $sort_measurements); |
317 | | - $test_response['preformatted_measurements'] = $preformatted_measurements; |
318 | | - $response['test'] = $test_response; |
319 | | - $this->pageTimer->end($response); |
320 | | - return response()->json($response); |
321 | | - } |
322 | | - |
323 | | - private function getRelatedBuildTest($which_buildtest) |
324 | | - { |
325 | | - switch ($which_buildtest) { |
326 | | - case 'previous': |
327 | | - $this->testHistoryQueryOrder = 'DESC'; |
328 | | - $this->testHistoryQueryExtraWheres = 'AND b.starttime < :starttime'; |
329 | | - $this->testHistoryQueryParams[':starttime'] = $this->build->StartTime; |
330 | | - break; |
331 | | - case 'next': |
332 | | - $this->testHistoryQueryOrder = 'ASC'; |
333 | | - $this->testHistoryQueryExtraWheres = 'AND b.starttime > :starttime'; |
334 | | - $this->testHistoryQueryParams[':starttime'] = $this->build->StartTime; |
335 | | - break; |
336 | | - case 'current': |
337 | | - default: |
338 | | - $this->testHistoryQueryOrder = 'DESC'; |
339 | | - $this->testHistoryQueryExtraWheres = ''; |
340 | | - if (array_key_exists(':starttime', $this->testHistoryQueryParams)) { |
341 | | - unset($this->testHistoryQueryParams[':starttime']); |
342 | | - } |
343 | | - break; |
344 | | - } |
345 | | - $this->testHistoryQueryLimit = 'LIMIT 1'; |
346 | | - $this->generateTestHistoryQuery(); |
347 | | - $stmt = $this->db->prepare($this->testHistoryQuery); |
348 | | - $this->db->execute($stmt, $this->testHistoryQueryParams); |
349 | | - $row = $stmt->fetch(); |
350 | | - if (is_array($row)) { |
351 | | - return $row['buildtestid']; |
352 | | - } |
353 | | - return null; |
354 | | - } |
355 | | - |
356 | | - // Remove bad characters for XML parser |
357 | | - private function utf8_for_xml($string): string |
358 | | - { |
359 | | - return preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{001b}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $string); |
| 57 | + throw new Exception('fileid query parameter is required'); |
360 | 58 | } |
361 | 59 | } |
0 commit comments