File Coverage

blib/lib/Tapper/Reports/Web/Controller/Tapper/ContinuousTestruns.pm
Criterion Covered Total %
statement 48 158 30.3
branch 0 20 0.0
condition 0 7 0.0
subroutine 16 31 51.6
pod 0 10 0.0
total 64 226 28.3


line stmt bran cond sub pod time code
1             package Tapper::Reports::Web::Controller::Tapper::ContinuousTestruns;
2             our $AUTHORITY = 'cpan:TAPPER';
3             $Tapper::Reports::Web::Controller::Tapper::ContinuousTestruns::VERSION = '5.0.14';
4             # ABSTRACT: Tapper - List and edit continuous tests
5              
6 10     10   5964 use strict;
  10         882  
  10         384  
7 10     10   71 use warnings;
  10         30  
  10         307  
8              
9 10     10   63 use parent 'Tapper::Reports::Web::Controller::Base';
  10         23  
  10         65  
10              
11 10     10   698 use Try::Tiny;
  10         23  
  10         668  
12 10     10   69 use Tapper::Model 'model';
  10         26  
  10         1167  
13              
14             sub index :Path : Args() {
15              
16 0     0   0 my ( $or_self, $or_c ) = @_;
17              
18 0         0 $or_c->go('/tapper/continuoustestruns/prepare_list');
19              
20 0         0 return 1;
21              
22 10     10   91 }
  10         23  
  10         81  
23              
24             sub prepare_list : Private {
25              
26 0     0 0 0 my ( $or_self, $or_c ) = @_;
27              
28 0         0 $or_c->stash->{head_overview} = 'Continuous Testruns';
29 0         0 $or_c->stash->{continuous_testruns} = $or_c->model('TestrunDB')->fetch_raw_sql({
30             query_name => 'testruns::continuous_list',
31             fetch_type => '@%',
32             });
33              
34 0         0 return 1;
35              
36 10     10   130564 }
  10         29  
  10         68  
37              
38             sub update_testrun : Private {
39              
40 0     0 0 0 my ( $or_self, $or_schema, $hr_atts ) = @_;
41              
42 0         0 for my $s_key (qw/ old_state testrun_id /) {
43 0 0       0 if (! $hr_atts->{$s_key} ) {
44 0         0 return "missing attribute: '$s_key'";
45             }
46             }
47              
48 0         0 require DateTime;
49 0         0 my $dt_now = DateTime->now()->strftime('%F %T');
50              
51 0         0 my $i_success = 0;
52 0 0       0 if ( $hr_atts->{testrun_id} =~ /^\d+$/ ) {
53              
54             try {
55             $or_schema->txn_do(sub {
56              
57 0         0 my $hr_update = {};
58 0 0       0 if ( exists $hr_atts->{new_state} ) {
59 0         0 $hr_update->{status} = $hr_atts->{new_state};
60             }
61 0 0       0 if ( exists $hr_atts->{auto_rerun} ) {
62 0         0 $hr_update->{auto_rerun} = $hr_atts->{auto_rerun};
63             }
64              
65             $or_schema->resultset("TestrunScheduling")
66             ->search({
67             auto_rerun => 1,
68             testrun_id => $hr_atts->{testrun_id},
69             status => $hr_atts->{old_state},
70             })
71 0         0 ->update( $hr_update )
72             ;
73              
74 0     0   0 });
75             }
76             catch {
77 0     0   0 return "Transaction failed: $_";
78 0         0 };
79              
80 0         0 return '';
81             }
82             else {
83 0         0 return "Testrun-ID has a wrong format";
84             }
85              
86 0         0 return '';
87              
88 10     10   13994 }
  10         36  
  10         71  
89              
90             sub pause : Local {
91              
92 0     0 0 0 my ( $or_self, $or_c ) = @_;
93              
94             $or_c->stash->{error} = $or_self->update_testrun(
95             $or_c->model('TestrunDB'),
96             {
97             old_state => 'schedule',
98             new_state => 'prepare',
99             testrun_id => $or_c->req->params->{testrun_id}
100             },
101 0         0 );
102              
103 0         0 $or_c->response->redirect('/tapper/continuoustestruns');
104 0         0 $or_c->detach();
105              
106 0         0 return 1;
107              
108 10     10   11104 }
  10         31  
  10         51  
109              
110             sub continue : Local {
111              
112 0     0 0 0 my ( $or_self, $or_c ) = @_;
113              
114             $or_c->stash->{error} = $or_self->update_testrun(
115             $or_c->model('TestrunDB'),
116             {
117             old_state => 'prepare',
118             new_state => 'schedule',
119             testrun_id => $or_c->req->params->{testrun_id}
120             },
121 0         0 );
122              
123 0         0 $or_c->response->redirect('/tapper/continuoustestruns');
124 0         0 $or_c->detach();
125              
126 0         0 return 1;
127              
128 10     10   11108 }
  10         28  
  10         56  
129              
130             sub cancel : Local {
131              
132 0     0 0 0 my ( $or_self, $or_c ) = @_;
133              
134             $or_c->stash->{error} = $or_self->update_testrun(
135             $or_c->model('TestrunDB'),
136             {
137             auto_rerun => 0,
138             old_state => [ 'prepare', 'schedule' ],
139             testrun_id => $or_c->req->params->{testrun_id}
140             },
141 0         0 );
142              
143 0         0 $or_c->response->redirect('/tapper/continuoustestruns');
144 0         0 $or_c->detach();
145              
146 0         0 return 1;
147              
148 10     10   11488 }
  10         27  
  10         57  
149              
150             sub clone : Local {
151              
152 0     0 0 0 my ( $or_self, $or_c ) = @_;
153              
154 0         0 $or_c->stash->{command} = 'clone';
155 0         0 $or_c->go('/tapper/continuoustestruns/edit_page');
156              
157 0         0 return 1;
158              
159 10     10   10598 }
  10         34  
  10         54  
160              
161             sub edit : Local {
162              
163 0     0 0 0 my ( $or_self, $or_c ) = @_;
164              
165 0         0 $or_c->stash->{command} = 'edit';
166 0         0 $or_c->go('/tapper/continuoustestruns/edit_page');
167              
168 0         0 return 1;
169              
170 10     10   10513 }
  10         30  
  10         61  
171              
172             sub edit_page : Private {
173              
174 0     0 0 0 my ( $or_self, $or_c ) = @_;
175              
176 0         0 $or_c->stash->{head_overview} = 'Continuous Testruns - ' . ucfirst( $or_c->stash->{command} );
177              
178 0 0       0 if (! $or_c->stash->{continuous_testrun} ) {
179             my $or_testrun = $or_c
180             ->model('TestrunDB')
181             ->resultset('Testrun')
182             ->search({
183             'testrun_scheduling.auto_rerun' => 1,
184             'testrun_scheduling.testrun_id' => $or_c->req->params->{testrun_id},
185 0         0 'testrun_scheduling.status' => [qw/ prepare schedule /],
186             },{
187             'join' => [
188             'testrun_scheduling',
189             { 'testrun_requested_host' => 'host' },
190             { 'testrun_precondition' => 'precondition' },
191             ],
192             'order_by' => {
193             -asc => 'testrun_precondition.succession',
194             },
195             })
196             ->first()
197             ;
198             $or_c->stash->{continuous_testrun} = {
199             testrun_id => $or_c->req->params->{testrun_id},
200             topic => $or_testrun->topic_name,
201             queue => $or_testrun->testrun_scheduling->queue_id,
202             host => [
203             map {
204 0         0 [ $_->host_id, $_->host->name ]
205             } $or_testrun->testrun_requested_host
206             ],
207             preconditions => [
208             map {
209 0         0 {
210 0   0     0 text => $_->precondition->precondition,
211             shortname => $_->precondition->shortname || q##,
212             }
213             } $or_testrun->testrun_precondition
214             ],
215             };
216             }
217              
218 0         0 return 1;
219              
220 10     10   12366 }
  10         40  
  10         74  
221              
222             sub save : Local {
223              
224 0     0 0 0 my ( $or_self, $or_c ) = @_;
225              
226 0         0 my $or_schema = $or_c->model('TestrunDB');
227 0         0 my $ar_precondition_texts = toarrayref( $or_c->req->params->{precondition_text} );
228 0         0 my $ar_precondition_shorts = toarrayref( $or_c->req->params->{precondition_short} );
229              
230             try {
231             $or_schema->txn_do(sub {
232              
233 0         0 my $i_testrun_id;
234             my $hr_topic_search = {
235             'topic_name' => $or_c->req->params->{topic},
236 0         0 'testrun_scheduling.auto_rerun' => 1,
237             'testrun_scheduling.status' => ['prepare','schedule'],
238             };
239              
240 0 0       0 if ( $or_c->req->params->{command} eq 'edit' ) {
    0          
241              
242 0         0 $i_testrun_id = $or_c->req->params->{testrun_id};
243 0         0 $hr_topic_search->{-not} = { 'me.id' => $i_testrun_id };
244              
245             # check topic name
246 0 0       0 if (
247             $or_schema
248             ->resultset('Testrun')
249             ->search($hr_topic_search,{
250             'join' => 'testrun_scheduling',
251             })
252             ->count() > 0
253             ) {
254 0         0 die "topic name already exists $i_testrun_id\n";
255             }
256              
257             # update topic
258             $or_schema
259             ->resultset('Testrun')
260             ->search({
261             -not => { topic_name => $or_c->req->params->{topic}, },
262             id => $i_testrun_id,
263             })
264             ->update({
265             topic_name => $or_c->req->params->{topic},
266             })
267 0         0 ;
268              
269             # update queue
270             $or_schema
271             ->resultset('TestrunScheduling')
272             ->search({
273             -not => { queue_id => $or_c->req->params->{queue_id}, },
274             testrun_id => $i_testrun_id,
275             auto_rerun => 1,
276             status => ['prepare','schedule'],
277             })
278             ->update({
279             queue_id => $or_c->req->params->{queue}
280             })
281 0         0 ;
282              
283             # delete old preconditions
284 0         0 $or_schema
285             ->resultset('TestrunPrecondition')
286             ->search({ testrun_id => $i_testrun_id })
287             ->delete_all()
288             ;
289              
290             # delete old testruns
291 0         0 $or_schema
292             ->resultset('TestrunRequestedHost')
293             ->search({ testrun_id => $i_testrun_id })
294             ->delete_all()
295             ;
296              
297             }
298             elsif ( $or_c->req->params->{command} eq 'clone' ) {
299              
300             # check topic name
301 0 0       0 if (
302             $or_schema
303             ->resultset('Testrun')
304             ->search($hr_topic_search,{
305             'join' => 'testrun_scheduling',
306             })
307             ->count() > 0
308             ) {
309 0         0 die "topic name already exists\n";
310             }
311              
312             # add a new testrun entry
313             my $or_testrun = $or_schema
314             ->resultset('Testrun')
315             ->find( $or_c->req->params->{testrun_id} )
316 0         0 ;
317             my $or_new_testrun = $or_schema
318             ->resultset('Testrun')
319             ->new({
320             shortname => $or_testrun->shortname,
321             notes => $or_testrun->notes,
322             topic_name => $or_c->req->params->{topic},
323 0         0 owner_id => $or_testrun->owner_id,
324             testplan_id => $or_testrun->testplan_id,
325             wait_after_tests => $or_testrun->wait_after_tests,
326             rerun_on_error => $or_testrun->rerun_on_error,
327             })
328             ->insert()
329             ;
330              
331             # add a new testrun scheduling entry
332             my $or_testrun_scheduling = $or_schema
333             ->resultset('TestrunScheduling')
334             ->search({
335             testrun_id => $or_c->req->params->{testrun_id},
336 0         0 auto_rerun => 1,
337             status => ['prepare','schedule'],
338             })
339             ->first()
340             ;
341              
342 0         0 $i_testrun_id = $or_new_testrun->id();
343              
344             $or_schema
345             ->resultset('TestrunScheduling')
346             ->new({
347             testrun_id => $i_testrun_id,
348             queue_id => $or_c->req->params->{queue},
349 0         0 prioqueue_seq => $or_testrun_scheduling->prioqueue_seq,
350             status => 'schedule',
351             auto_rerun => 1,
352             })
353             ->insert()
354             ;
355              
356             }
357             else {
358 0         0 die 'unknown command "' . $or_c->req->params->{command} . '"' . "\n";
359             }
360              
361             # insert testrun preconditions
362 0         0 $or_schema
363             ->resultset('TestrunPrecondition')
364             ->search({ testrun_id => $i_testrun_id })
365             ->delete_all()
366             ;
367              
368 0         0 my $i_counter = 0;
369 0         0 for my $s_text ( @{$ar_precondition_texts} ) {
  0         0  
370              
371 0   0     0 my $s_short = $ar_precondition_shorts->[$i_counter] || q##;
372 0   0     0 my $or_precond =
373             $or_schema
374             ->resultset('Precondition')
375             ->search({
376             shortname => $s_short,
377             precondition => $s_text,
378             },{
379             order_by => { -asc => 'id' },
380             })
381             ->first()
382             ||
383             $or_schema
384             ->resultset('Precondition')
385             ->new({
386             shortname => $s_short,
387             precondition => $s_text,
388             })
389             ->insert()
390             ;
391              
392             # insert testrun - precondition relation
393 0         0 $or_schema
394             ->resultset('TestrunPrecondition')
395             ->new({
396             testrun_id => $i_testrun_id,
397             precondition_id => $or_precond->id,
398             succession => $i_counter + 1,
399             })
400             ->insert()
401             ;
402              
403 0         0 $i_counter++;
404              
405             }
406              
407             # insert testrun requested hosts
408 0         0 for my $i_host ( @{toarrayref( $or_c->req->params->{host} )} ) {
  0         0  
409 0         0 $or_schema
410             ->resultset('TestrunRequestedHost')
411             ->new({
412             host_id => $i_host,
413             testrun_id => $i_testrun_id,
414             })
415             ->insert()
416             ;
417             }
418              
419 0     0   0 });
420             }
421             catch {
422              
423 0     0   0 my $i_precondition_counter = 0;
424 0         0 $or_c->stash->{error} = "Transaction failed: $_";
425 0         0 $or_c->stash->{command} = $or_c->req->params->{command};
426             $or_c->stash->{continuous_testrun} = {
427             testrun_id => $or_c->req->params->{testrun_id},
428             topic => $or_c->req->params->{topic},
429             queue => $or_c->req->params->{queue},
430             host => [
431             map {[
432 0         0 $_, $or_schema->resultset('Host')->find( $_ )->name,
433 0         0 ]} @{toarrayref( $or_c->req->params->{host} )}
434             ],
435             preconditions => [
436             map {
437             {
438 0         0 text => $ar_precondition_texts->[$i_precondition_counter],
439             shortname => $ar_precondition_shorts->[$i_precondition_counter++],
440             };
441              
442 0         0 } @{$ar_precondition_texts}
  0         0  
443             ],
444             };
445 0         0 $or_c->go('/tapper/continuoustestruns/'.$or_c->req->params->{command});
446 0         0 };
447              
448 0         0 $or_c->response->redirect('/tapper/continuoustestruns');
449 0         0 $or_c->detach();
450              
451 0         0 return 1;
452              
453 10     10   20326 }
  10         30  
  10         58  
454              
455             sub toarrayref : Private {
456              
457 0     0 0   my ( $value ) = @_;
458              
459 0 0         if ( ref( $value ) ne 'ARRAY' ) {
460 0           return [ $value ];
461             }
462              
463 0           return $value;
464              
465 10     10   10981 }
  10         25  
  10         79  
466              
467             1;
468              
469             __END__
470              
471             =pod
472              
473             =encoding UTF-8
474              
475             =head1 NAME
476              
477             Tapper::Reports::Web::Controller::Tapper::ContinuousTestruns - Tapper - List and edit continuous tests
478              
479             =head1 AUTHORS
480              
481             =over 4
482              
483             =item *
484              
485             AMD OSRC Tapper Team <tapper@amd64.org>
486              
487             =item *
488              
489             Tapper Team <tapper-ops@amazon.com>
490              
491             =back
492              
493             =head1 COPYRIGHT AND LICENSE
494              
495             This software is Copyright (c) 2019 by Advanced Micro Devices, Inc..
496              
497             This is free software, licensed under:
498              
499             The (two-clause) FreeBSD License
500              
501             =cut