| 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 |