File Coverage

blib/lib/Tapper/Schema/TestrunDB/Result/Report.pm
Criterion Covered Total %
statement 52 66 78.7
branch 6 12 50.0
condition 3 7 42.8
subroutine 9 11 81.8
pod 5 5 100.0
total 75 101 74.2


line stmt bran cond sub pod time code
1             package Tapper::Schema::TestrunDB::Result::Report;
2             our $AUTHORITY = 'cpan:TAPPER';
3             $Tapper::Schema::TestrunDB::Result::Report::VERSION = '5.0.9';
4             # ABSTRACT: Tapper - containing reports
5              
6 7     7   3169 use 5.010;
  7         20  
7 7     7   23 use strict;
  7         7  
  7         108  
8 7     7   19 use warnings;
  7         8  
  7         143  
9              
10 7     7   21 use parent 'DBIx::Class';
  7         7  
  7         27  
11              
12 7     7   325 use Tapper::Config;
  7         8  
  7         138  
13 7     7   514 use Data::Dumper;
  7         4876  
  7         5198  
14              
15             __PACKAGE__->load_components(qw(InflateColumn::DateTime TimeStamp Core));
16             __PACKAGE__->table("report");
17             __PACKAGE__->add_columns
18             (
19             "id", { data_type => "INT", default_value => undef, is_nullable => 0, size => 11, is_auto_increment => 1, },
20             "suite_id", { data_type => "INT", default_value => undef, is_nullable => 1, size => 11, is_foreign_key => 1, },
21             "suite_version", { data_type => "VARCHAR", default_value => undef, is_nullable => 1, size => 255, },
22             "reportername", { data_type => "VARCHAR", default_value => "", is_nullable => 1, size => 255, },
23             "peeraddr", { data_type => "VARCHAR", default_value => "", is_nullable => 1, size => 255, },
24             "peerport", { data_type => "VARCHAR", default_value => "", is_nullable => 1, size => 255, },
25             "peerhost", { data_type => "VARCHAR", default_value => "", is_nullable => 1, size => 255, },
26             #
27             # tap parse result and its human interpretation
28             #
29             "successgrade", { data_type => "VARCHAR", default_value => "", is_nullable => 1, size => 10, },
30             "reviewed_successgrade", { data_type => "VARCHAR", default_value => "", is_nullable => 1, size => 10, },
31             #
32             # tap parse results
33             #
34             "total", { data_type => "INT", default_value => undef, is_nullable => 1, size => 10, },
35             "failed", { data_type => "INT", default_value => undef, is_nullable => 1, size => 10, },
36             "parse_errors", { data_type => "INT", default_value => undef, is_nullable => 1, size => 10, },
37             "passed", { data_type => "INT", default_value => undef, is_nullable => 1, size => 10, },
38             "skipped", { data_type => "INT", default_value => undef, is_nullable => 1, size => 10, },
39             "todo", { data_type => "INT", default_value => undef, is_nullable => 1, size => 10, },
40             "todo_passed", { data_type => "INT", default_value => undef, is_nullable => 1, size => 10, },
41             "success_ratio", { data_type => "VARCHAR", default_value => undef, is_nullable => 1, size => 20, },
42             #
43             "starttime_test_program", { data_type => "DATETIME", default_value => undef, is_nullable => 1, },
44             "endtime_test_program", { data_type => "DATETIME", default_value => undef, is_nullable => 1, },
45             #
46             "machine_name", { data_type => "VARCHAR", default_value => "", is_nullable => 1, size => 255, },
47             "machine_description", { data_type => "TEXT", default_value => "", is_nullable => 1, },
48             #
49             "created_at", { data_type => "DATETIME", default_value => undef, is_nullable => 0, set_on_create => 1, },
50             "updated_at", { data_type => "DATETIME", default_value => undef, is_nullable => 0, set_on_create => 1, set_on_update => 1, },
51             );
52              
53             __PACKAGE__->set_primary_key("id");
54              
55             __PACKAGE__->belongs_to ( suite => 'Tapper::Schema::TestrunDB::Result::Suite', { 'foreign.id' => 'self.suite_id' }, { 'join_type' => 'LEFT OUTER' });
56             __PACKAGE__->might_have ( reportgrouparbitrary => 'Tapper::Schema::TestrunDB::Result::ReportgroupArbitrary', { 'foreign.report_id' => 'self.id' }, { 'join_type' => 'LEFT OUTER' });
57             __PACKAGE__->might_have ( reportgrouptestrun => 'Tapper::Schema::TestrunDB::Result::ReportgroupTestrun', { 'foreign.report_id' => 'self.id' }, { 'join_type' => 'LEFT OUTER' });
58             __PACKAGE__->might_have ( tap => 'Tapper::Schema::TestrunDB::Result::Tap', { 'foreign.report_id' => 'self.id' }, { 'join_type' => 'LEFT OUTER' });
59              
60             __PACKAGE__->has_many ( comments => 'Tapper::Schema::TestrunDB::Result::ReportComment', { 'foreign.report_id' => 'self.id' });
61             __PACKAGE__->has_many ( topics => 'Tapper::Schema::TestrunDB::Result::ReportTopic', { 'foreign.report_id' => 'self.id' });
62             __PACKAGE__->has_many ( files => 'Tapper::Schema::TestrunDB::Result::ReportFile', { 'foreign.report_id' => 'self.id' });
63             __PACKAGE__->has_many ( reportsections => 'Tapper::Schema::TestrunDB::Result::ReportSection', { 'foreign.report_id' => 'self.id' });
64              
65              
66              
67             sub sqlt_deploy_hook
68             {
69 7     7 1 26902 my ($self, $sqlt_table) = @_;
70 7         36 $sqlt_table->add_index(name => 'report_idx_machine_name', fields => ['machine_name']);
71             # $sqlt_table->add_index(name => 'report_idx_suite_id', fields => ['suite_id']); # implicitely done(?)
72 7         2930 $sqlt_table->add_index(name => 'report_idx_created_at', fields => ['created_at']);
73             }
74              
75             #sub suite_name { shift->suite->name }
76             #sub suite_name { my ($self, $arg) = @_; return $self->search({ "suite.name" => $arg })};
77              
78              
79              
80             sub sections_cpuinfo
81             {
82 0     0 1 0 my ($self) = @_;
83 0         0 my $sections = $self->reportsections;
84 0         0 my @cpus;
85 0         0 while (my $section = $sections->next) {
86 0         0 push @cpus, $section->cpuinfo;
87             }
88 0         0 return @cpus;
89             }
90              
91              
92             sub sections_osname
93             {
94 0     0 1 0 my ($self) = @_;
95 0         0 my $sections = $self->reportsections;
96 0         0 my @cpus;
97 0         0 while (my $section = $sections->next) {
98 0         0 push @cpus, $section->osname;
99             }
100 0         0 return @cpus;
101             }
102              
103              
104             sub some_meta_available
105             {
106 2     2 1 6886 my ($self) = @_;
107              
108 2         27 my $sections = $self->reportsections;
109 2         2664 while (my $section = $sections->next) {
110 1 50       3467 return 1 if $section->some_meta_available;
111             }
112 1         3627 return 0;
113             }
114              
115              
116             sub get_cached_tapdom
117             {
118 1     1 1 11516 my ($r) = @_;
119              
120 1         10 my $cache_tapdom_in_db = Tapper::Config->subconfig->{cache_tapdom_in_db};
121              
122 1         655 require Tapper::TAP::Harness;
123 1         557889 require TAP::DOM;
124              
125 1         5276 my $TAPVERSION = "TAP Version 13";
126 1         4 my $tapdom_sections = [];
127              
128 1         9 my $report = $r->result_source->schema->resultset('Report')->find($r->id);
129 1         3866 my $tapdom_str;
130 1 50       35 $tapdom_str = $report->tap->tapdom if $cache_tapdom_in_db;
131              
132             # set TAPPER_FORCE_NEW_TAPDOM to force the re-generation of the TAP DOM, e.g. when the TAP::DOM module changes
133 1 50 33     2783 if ($tapdom_str and not -e '/tmp/TAPPER_FORCE_NEW_TAPDOM')
134             {
135             #say STDERR "EVAL ", $r->id;
136 0         0 eval '$tapdom_sections = my '.$tapdom_str; ## no critic (ProhibitStringyEval)
137             }
138             else
139             {
140             # say STDERR "RUN TAPPER::TAP::HARNESS ", $r->id;
141              
142 1         15 my $report_tap = $report->tap->tap;
143 1   50     38 my $tap_is_archive = $report->tap->tap_is_archive || 0;
144              
145             # We got "Out of memory!" with monster TAP reports.
146 1 50       30 if (length $report_tap > 2_000_000) {
147 0         0 warn "Ignore report ".$r->id." due to too large TAP. ";
148             }
149             else
150             {
151 1         17 my $harness = new Tapper::TAP::Harness( tap => $report_tap,
152             tap_is_archive => $tap_is_archive );
153 1         1430 $harness->evaluate_report();
154             #print STDERR Dumper($harness->parsed_report);
155 1         4298 foreach (@{$harness->parsed_report->{tap_sections}})
  1         21  
156             {
157             #print STDERR ".";
158 1   50     8 my $rawtap = $_->{raw} || '';
159             #say STDERR "x"x100, "\n", $rawtap, "\n", "x"x 100;
160 1 50       6 $rawtap = $TAPVERSION."\n".$rawtap unless $rawtap =~ /^TAP Version/ms;
161             #say STDERR length($rawtap);
162 1         10 my $tapdom = new TAP::DOM ( tap => $rawtap,
163             ignore => [qw( raw as_string )],
164             ignorelines => qr/^\#\# /, # mostly used in oprofile
165             );
166             push @$tapdom_sections, { section => { $_->{section_name} => { tap => $tapdom,
167             meta => $_->{section_meta},
168             }
169             }
170 1         1784 };
171             }
172 1         6 $tapdom_str = Dumper($tapdom_sections);
173 1 50       439 if ($cache_tapdom_in_db) {
174 1         27 $report->tap->tapdom( $tapdom_str );
175             #say STDERR "new report: ", Dumper($report);
176 1         391 $report->tap->update;
177 1         18612 $report->update;
178             }
179             }
180             }
181             #print STDERR ".\n";
182 1         1431 return $tapdom_sections;
183             }
184              
185             1;
186              
187             __END__
188              
189             =pod
190              
191             =encoding UTF-8
192              
193             =head1 NAME
194              
195             Tapper::Schema::TestrunDB::Result::Report - Tapper - containing reports
196              
197             =head2 sqlt_deploy_hook
198              
199             Add useful indexes at deploy time.
200              
201             =head2 sections_cpuinfo
202              
203             Return list of I<cpuinfo> of all report sections.
204              
205             =head2 sections_osname
206              
207             Return list of I<osname> of all report sections.
208              
209             =head2 some_meta_available
210              
211             Return list of I<some_meta_available> of all report sections.
212              
213             =head2 get_cached_tapdom
214              
215             Return a TAP-DOM of the report, creating it on demand.
216              
217             =head1 AUTHORS
218              
219             =over 4
220              
221             =item *
222              
223             AMD OSRC Tapper Team <tapper@amd64.org>
224              
225             =item *
226              
227             Tapper Team <tapper-ops@amazon.com>
228              
229             =back
230              
231             =head1 COPYRIGHT AND LICENSE
232              
233             This software is Copyright (c) 2017 by Advanced Micro Devices, Inc..
234              
235             This is free software, licensed under:
236              
237             The (two-clause) FreeBSD License
238              
239             =cut