]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1578965 - Security Bugs Report: Change median age of open bugs to # of bugs older...
authorIsrael Madueme <purelogiq@gmail.com>
Thu, 26 Sep 2019 17:34:52 +0000 (13:34 -0400)
committerGitHub <noreply@github.com>
Thu, 26 Sep 2019 17:34:52 +0000 (13:34 -0400)
Bugzilla/Report/SecurityRisk.pm
scripts/secbugsreport.pl
t/security-risk.t
template/en/default/reports/email/security-risk.html.tmpl

index a667f7b6c6f813c33bac1fa4210f9fed84191889..b669e47d55cf152fd395efa0618b4a98a844b809 100644 (file)
@@ -102,6 +102,8 @@ has 'initial_bugs' => (
 has 'check_open_state' =>
   (is => 'ro', isa => CodeRef, default => sub { return \&is_open_state; },);
 
+has 'very_old_days' => (is => 'ro', isa => Int, default => 45);
+
 has 'events' => (
   is  => 'lazy',
   isa => ArrayRef [
@@ -121,10 +123,10 @@ has 'results' => (
     Dict [
       date         => $DateTime,
       bugs_by_team => HashRef [
-        Dict [open => ArrayRef [Int], closed => ArrayRef [Int], median_age_open => Num]
+        Dict [open => ArrayRef [Int], closed => ArrayRef [Int], very_old_bugs => ArrayRef [Int]]
       ],
       bugs_by_sec_keyword => HashRef [
-        Dict [open => ArrayRef [Int], closed => ArrayRef [Int], median_age_open => Num]
+        Dict [open => ArrayRef [Int], closed => ArrayRef [Int], very_old_bugs => ArrayRef [Int]]
       ],
     ],
   ],
@@ -438,11 +440,11 @@ sub _build_graphs {
     {
       id    => 'bugs_by_sec_keyword_age',
       title => sprintf(
-        'Median age of open security bugs by severity (%s to %s)',
+        '# of open security bugs older than 45 days by severity (%s to %s)',
         $self->start_date->ymd,
         $self->end_date->ymd
       ),
-      range_label => 'Median Age (days)',
+      range_label => 'Bug Count',
       datasets    => [
         map {
           my $keyword = $_;
@@ -450,8 +452,9 @@ sub _build_graphs {
             name   => $_,
             keys   => [map { $_->{date}->epoch } @{$self->results}],
             values => [
-              map { $_->{bugs_by_sec_keyword}->{$keyword}->{median_age_open} }
-                @{$self->results}
+              map {
+                scalar @{$_->{bugs_by_sec_keyword}->{$keyword}->{very_old_bugs}}
+              } @{$self->results}
             ],
           }
         } @{$self->sec_keywords}
@@ -461,19 +464,22 @@ sub _build_graphs {
     {
       id    => 'bugs_by_team_age',
       title => sprintf(
-        'Median age of open security bugs by team (%s to %s)',
+        '# of open security bugs older than 45 days by team (%s to %s)',
         $self->start_date->ymd,
         $self->end_date->ymd
       ),
-      range_label => 'Median Age (days)',
+      range_label => 'Bug Count',
       datasets    => [
         map {
           my $team = $_;
           {
             name => $_,
             keys => [map { $_->{date}->epoch } @{$self->results}],
-            values =>
-              [map { $_->{bugs_by_team}->{$team}->{median_age_open} } @{$self->results}],
+            values => [
+              map {
+                scalar @{$_->{bugs_by_team}->{$team}->{very_old_bugs}}
+              }@{$self->results}
+            ],
           }
         } keys %{$self->teams}
       ],
@@ -562,13 +568,13 @@ sub _bugs_by_team {
   foreach my $team (keys %{$self->teams}) {
     my @open   = map { $_->{id} } grep { ($_->{is_open}) } @{$groups->{$team}};
     my @closed = map { $_->{id} } grep { !($_->{is_open}) } @{$groups->{$team}};
-    my @ages   = map {
-      $_->{created_at}->subtract_datetime_absolute($report_date)->seconds / 86_400;
+    my @very_old_bugs   = map { $_->{id} } grep {
+      $_->{created_at}->subtract_datetime_absolute($report_date)->seconds / 86_400 >= $self->very_old_days;
     } grep { ($_->{is_open}) } @{$groups->{$team}};
     $result->{$team} = {
       open            => \@open,
       closed          => \@closed,
-      median_age_open => @ages ? _median(@ages) : 0,
+      very_old_bugs   => \@very_old_bugs,
     };
   }
 
@@ -593,13 +599,13 @@ sub _bugs_by_sec_keyword {
     my @open = map { $_->{id} } grep { ($_->{is_open}) } @{$groups->{$sec_keyword}};
     my @closed
       = map { $_->{id} } grep { !($_->{is_open}) } @{$groups->{$sec_keyword}};
-    my @ages = map {
-      $_->{created_at}->subtract_datetime_absolute($report_date)->seconds / 86_400
+    my @very_old_bugs   = map { $_->{id} } grep {
+      $_->{created_at}->subtract_datetime_absolute($report_date)->seconds / 86_400 >= $self->very_old_days;
     } grep { ($_->{is_open}) } @{$groups->{$sec_keyword}};
     $result->{$sec_keyword} = {
       open            => \@open,
       closed          => \@closed,
-      median_age_open => @ages ? _median(@ages) : 0,
+      very_old_bugs   => \@very_old_bugs,
     };
   }
 
@@ -626,11 +632,5 @@ sub _find_team {
   return undef;
 }
 
-sub _median {
-
-  # From tlm @ https://www.perlmonks.org/?node_id=474564. Jul 14, 2005
-  return sum((sort { $a <=> $b } @_)[int($#_ / 2), ceil($#_ / 2)]) / 2;
-}
-
 
 1;
index aac1995d1a4277e9a129b3549e589ddb420074df..29276c774220c8a6dcc40af00d0ac74005ca0231 100644 (file)
@@ -65,7 +65,8 @@ my $report       = Bugzilla::Report::SecurityRisk->new(
   start_date   => $start_date,
   end_date     => $end_date,
   teams        => $teams,
-  sec_keywords => $sec_keywords
+  sec_keywords => $sec_keywords,
+  very_old_days => 45
 );
 
 my $bugs_by_team = $report->results->[-1]->{bugs_by_team};
@@ -83,6 +84,7 @@ my $vars = {
   deltas             => $report->deltas,
   missing_products   => $report->missing_products,
   missing_components => $report->missing_components,
+  very_old_days      => $report->very_old_days,
   build_bugs_link    => \&build_bugs_link,
 };
 
index ed5b9b568f96011ef09fdc7c07d0b023cc5fc579..09940dac7b8e24baf8c1d04b3f72adeaa1f16e2f 100644 (file)
@@ -37,6 +37,7 @@ try {
     teams      => decode_json($teams_json),
     sec_keywords     => ['sec-critical', 'sec-high'],
     check_open_state => \&check_open_state_mock,
+    very_old_days    => 45,
     initial_bug_ids  => [1, 2, 3, 4],
     initial_bugs     => {
       1 => {
@@ -114,14 +115,14 @@ try {
           # Rewind the event that caused 1 to close.
           open            => [1],
           closed          => [],
-          median_age_open => 8
+          very_old_bugs   => []
         },
         'Backend' => {
 
           # 2 wasn't a sec-critical bug on the report date.
           open            => [3],
           closed          => [],
-          median_age_open => 4
+          very_old_bugs   => []
         }
       },
       bugs_by_sec_keyword => {
@@ -130,26 +131,26 @@ try {
           # 2 wasn't a sec-critical bug and 4 wasn't created yet on the report date.
           open            => [],
           closed          => [],
-          median_age_open => 0
+          very_old_bugs   => []
         },
         'sec-high' => {
 
           # Rewind the event that caused 1 to close.
           open            => [1, 3],
           closed          => [],
-          median_age_open => 6
+          very_old_bugs   => []
         }
       },
     },
     {    # The report on 2000-01-16 matches the state of initial_bugs.
       date         => DateTime->new(year => 2000, month => 1, day => 16),
       bugs_by_team => {
-        'Frontend' => {open => [4], closed => [1], median_age_open => 6},
-        'Backend'  => {open => [3], closed => [2], median_age_open => 11}
+        'Frontend' => {open => [4], closed => [1], very_old_bugs => []},
+        'Backend'  => {open => [3], closed => [2], very_old_bugs => []}
       },
       bugs_by_sec_keyword => {
-        'sec-critical' => {open => [4], closed => [2], median_age_open => 6},
-        'sec-high'     => {open => [3], closed => [1], median_age_open => 11}
+        'sec-critical' => {open => [4], closed => [2], very_old_bugs => []},
+        'sec-high'     => {open => [3], closed => [1], very_old_bugs => []}
       },
     },
   ];
index 90e335f4665e79a6001fc110b498ab96f1d48e23..f8e8adeb11c22b6b41bf9c5e86cee2e1c5d19967 100644 (file)
@@ -94,7 +94,7 @@
     <th style="padding: 0px 15px 10px 0px; text-align: right;">Closed<br />Last Week</th>
     <th style="padding: 0px 15px 10px 0px; text-align: right;">Added<br />Last Week</th>
     <th style="padding: 0px 15px 10px 0px; text-align: right; border-right: 1px solid grey;">
-      Median Age<br/>of Open [% terms.Bugs %]<br>
+      Older than <br> [% very_old_days FILTER html %] Days<br>
     </th>
     [% FOREACH result IN results.reverse %]
       [% NEXT IF loop.count < 2 %]
     <tr>
       <td style="padding: 0px 15px 10px 0px;">[% keyword FILTER html %]</td>
       <td style="padding: 0px 15px 10px 0px; text-align: right;">
-          [% IF results.reverse.0.bugs_by_sec_keyword.$keyword.open %]
+          [% IF results.reverse.0.bugs_by_sec_keyword.$keyword.open.size %]
             <a style="text-decoration: none;" href="[% build_bugs_link(results.reverse.0.bugs_by_sec_keyword.$keyword.open) FILTER html %]">
               [% results.reverse.0.bugs_by_sec_keyword.$keyword.open.size FILTER html %]
             </a>
         [% END %]
       </td>
       <td style="padding: 0px 15px 10px 0px; text-align: right; border-right: 1px solid grey; ">
-        [% results.-1.bugs_by_sec_keyword.$keyword.median_age_open FILTER format("%.0f") FILTER html %] days
+        [% IF results.reverse.0.bugs_by_sec_keyword.$keyword.very_old_bugs.size %]
+            <a style="text-decoration: none;" href="[% build_bugs_link(results.reverse.0.bugs_by_sec_keyword.$keyword.very_old_bugs) FILTER html %]">
+              [% results.reverse.0.bugs_by_sec_keyword.$keyword.very_old_bugs.size FILTER html %]
+            </a>
+          [% ELSE %]
+            0
+          [% END %]
       </td>
       [% FOREACH result IN results.reverse %]
         [% NEXT IF loop.count < 2 %]