Add support for viewing jobset evaluations

This commit is contained in:
Eelco Dolstra 2012-04-02 16:11:22 +02:00
parent d33fbad438
commit 662cdf0421
9 changed files with 236 additions and 23 deletions

View file

@ -60,7 +60,7 @@ sub all : Chained('get_builds') PathPart {
$c->stash->{page} = $page; $c->stash->{page} = $page;
$c->stash->{resultsPerPage} = $resultsPerPage; $c->stash->{resultsPerPage} = $resultsPerPage;
$c->stash->{totalBuilds} = $nrBuilds; $c->stash->{total} = $nrBuilds;
$c->stash->{builds} = [ $c->stash->{allBuilds}->search( $c->stash->{builds} = [ $c->stash->{allBuilds}->search(
{ finished => 1 }, { finished => 1 },

View file

@ -329,5 +329,34 @@ sub clone_submit : Chained('jobset') PathPart('clone/submit') Args(0) {
} }
sub evals : Chained('jobset') PathPart('evals') Args(0) {
my ($self, $c) = @_;
$c->stash->{template} = 'jobset-evals.tt';
my $page = int($c->req->param('page') || "1") || 1;
my $resultsPerPage = 20;
$c->stash->{page} = $page;
$c->stash->{resultsPerPage} = $resultsPerPage;
$c->stash->{total} = $c->stash->{jobset}->jobsetevals->search({hasnewbuilds => 1})->count;
$c->stash->{evals} = [ $c->stash->{jobset}->jobsetevals->search(
{ hasnewbuilds => 1 },
{ order_by => "id DESC"
, '+select' => # !!! Slow - should precompute this.
[ "(select count(*) from JobsetEvalMembers where eval = me.id)"
, "(select count(*) from JobsetEvalMembers where eval = me.id and exists(select 1 from Builds b where b.id = build and b.finished = 0))"
, "(select count(*) from JobsetEvalMembers where eval = me.id and exists(select 1 from Builds b where b.id = build and b.finished = 1))"
, "(select count(*) from JobsetEvalMembers where eval = me.id and exists(select 1 from Builds b where b.id = build and b.finished = 1 and b.buildStatus = 0))"
]
, '+as' => [ "nrBuilds", "nrScheduled", "nrFinished", "nrSucceeded" ]
, rows => $resultsPerPage
, page => $page
}
) ];
}
1; 1;

View file

@ -0,0 +1,76 @@
package Hydra::Controller::JobsetEval;
use strict;
use warnings;
use base 'Catalyst::Controller';
use Hydra::Helper::Nix;
use Hydra::Helper::CatalystUtils;
sub eval : Chained('/') PathPart('eval') CaptureArgs(1) {
my ($self, $c, $evalId) = @_;
my $eval = $c->model('DB::JobsetEvals')->find($evalId)
or notFound($c, "Evaluation $evalId doesn't exist.");
$c->stash->{eval} = $eval;
$c->stash->{project} = $eval->project;
$c->stash->{jobset} = $eval->jobset;
}
sub view : Chained('eval') PathPart('') Args(0) {
my ($self, $c) = @_;
$c->stash->{template} = 'jobset-eval.tt';
my $eval = $c->stash->{eval};
my ($eval2) = $eval->jobset->jobsetevals->search(
{ hasnewbuilds => 1, id => { '<', $eval->id } },
{ order_by => "id DESC", rows => 1 });
my @builds = $eval->builds->search({}, { order_by => ["job", "system", "id"], columns => [@buildListColumns] });
my @builds2 = $eval2->builds->search({}, { order_by => ["job", "system", "id"], columns => [@buildListColumns] });
print STDERR "EVAL IS ", $eval2->id, "\n";
print STDERR scalar(@builds), "\n";
print STDERR scalar(@builds2), "\n";
$c->stash->{stillSucceed} = [];
$c->stash->{stillFail} = [];
$c->stash->{nowSucceed} = [];
$c->stash->{nowFail} = [];
my $n = 0;
foreach my $build (@builds) {
my $d;
while ($n < scalar(@builds2)) {
my $build2 = $builds2[$n];
my $d = $build->get_column('job') cmp $build2->get_column('job')
|| $build->get_column('system') cmp $build2->get_column('system');
#print STDERR $build->id, " ", $build->get_column('job'), " ", $build->system, " ", $d, "\n";
last if $d == -1;
if ($d == 0) {
#print STDERR $build->buildstatus, "\n";
#print STDERR $build2->buildstatus, "\n";
if ($build->buildstatus == 0 && $build2->buildstatus == 0) {
push @{$c->stash->{stillSucceed}}, $build;
} elsif ($build->buildstatus != 0 && $build2->buildstatus != 0) {
push @{$c->stash->{stillFail}}, $build;
} elsif ($build->buildstatus == 0 && $build2->buildstatus != 0) {
push @{$c->stash->{nowSucceed}}, $build;
} elsif ($build->buildstatus != 0 && $build2->buildstatus == 0) {
push @{$c->stash->{nowFail}}, $build;
}
last;
}
$n++;
}
}
$c->stash->{full} = ($c->req->params->{full} || "0") eq "1";
}
1;

View file

@ -7,23 +7,10 @@
[% ELSIF project %] for Project <tt>[% project.name %]</tt>[% END %]</h1> [% ELSIF project %] for Project <tt>[% project.name %]</tt>[% END %]</h1>
<p>Showing builds [% (page - 1) * resultsPerPage + 1 %] - [% (page - 1) * resultsPerPage + builds.size %] <p>Showing builds [% (page - 1) * resultsPerPage + 1 %] - [% (page - 1) * resultsPerPage + builds.size %]
out of [% totalBuilds %] in order of descending timestamp.</p> out of [% total %] in order of descending timestamp.</p>
[% BLOCK renderNav %] [% INCLUDE renderPager %]
<p>
[<a href="[% "$baseUri?page=1" %]">First</a>]
[% IF page > 1 %]
[<a href="[% "$baseUri?page="; (page - 1) %]">Prev</a>]
[% END %]
[% IF page * resultsPerPage < totalBuilds %]
[<a href="[% "$baseUri?page="; (page + 1) %]">Next</a>]
[% END %]
[<a href="[% "$baseUri?page="; (totalBuilds - 1) div resultsPerPage + 1 %]">Last</a>]
</p>
[% END %]
[% INCLUDE renderNav %]
[% INCLUDE renderBuildList hideProjectName=project hideJobsetName=jobset hideJobName=job %] [% INCLUDE renderBuildList hideProjectName=project hideJobsetName=jobset hideJobName=job %]
[% INCLUDE renderNav %] [% INCLUDE renderPager %]
[% END %] [% END %]

View file

@ -62,8 +62,8 @@
[% END %] [% END %]
[%- BLOCK renderBuildList -%] [%- BLOCK renderBuildListHeader -%]
<table class="buildList tablesorter[% IF !showSchedulingInfo %] clean[% END %]"> <table class="buildList [% IF !unsortable %]tablesorter[% END %] [% IF !showSchedulingInfo %] clean[% END %]">
<thead> <thead>
<tr> <tr>
[%- IF !hideResultInfo -%] [%- IF !hideResultInfo -%]
@ -89,6 +89,9 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
[%- END -%]
[%- BLOCK renderBuildListBody -%]
[%- odd = 0 -%] [%- odd = 0 -%]
[%- FOREACH build IN builds -%] [%- FOREACH build IN builds -%]
<tr class="clickable <tr class="clickable
@ -130,10 +133,20 @@
[%- END -%] [%- END -%]
</tr> </tr>
[%- END -%] [%- END -%]
[%- END -%]
[%- BLOCK renderBuildListFooter -%]
</tbody> </tbody>
</table> </table>
[%- END -%] [%- END -%]
[%- BLOCK renderBuildList -%]
[%- INCLUDE renderBuildListHeader -%]
[%- INCLUDE renderBuildListBody -%]
[%- INCLUDE renderBuildListFooter -%]
[%- END -%]
[%- BLOCK renderLink -%]<a href="[% uri %]">[% title %]</a>[%- END -%] [%- BLOCK renderLink -%]<a href="[% uri %]">[% title %]</a>[%- END -%]
[%- BLOCK showBuildStats -%] [%- BLOCK showBuildStats -%]
@ -377,8 +390,18 @@
</table> </table>
[% END %] [% END %]
[% BLOCK buildsGraph %]
[% BLOCK renderPager %]
<p>
[<a href="[% "$baseUri?page=1" %]">First</a>]
[% IF page > 1 %]
[<a href="[% "$baseUri?page="; (page - 1) %]">Prev</a>]
[% END %] [% END %]
[% IF page * resultsPerPage < total %]
[<a href="[% "$baseUri?page="; (page + 1) %]">Next</a>]
[% END %]
[<a href="[% "$baseUri?page="; (total - 1) div resultsPerPage + 1 %]">Last</a>]
</p>
[% END %]

41
src/root/jobset-eval.tt Normal file
View file

@ -0,0 +1,41 @@
[% WRAPPER layout.tt title="Bla" %]
[% PROCESS common.tt %]
<h1>Jobset <tt>[% project.name %]:[% jobset.name %]</tt> Evaluation [% eval.id %]</h1>
<!-- <p>Info on evaluation [% eval.id %]...<p> -->
[%- BLOCK renderSome -%]
[% size = builds.size; max = full ? size : 30; %]
[% INCLUDE renderBuildListBody builds=builds.slice(0, (size > max ? max : size) - 1)
hideProjectName=1 hideJobsetName=1 %]
[% IF size > max %]
<tr><td class="centered" colspan="0"><a href="[% c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id], full => 1) %]"><em>([% size - max %] more builds omitted)</em></a></td></tr>
[% END %]
[% END %]
[% INCLUDE renderBuildListHeader unsortable=1 %]
[% IF nowFail.size > 0 %]
<tr><th class="subheader" colspan="0">Builds that now <strong>fail</strong></th></tr>
[% INCLUDE renderSome builds=nowFail %]
[% END %]
[% IF nowSucceed.size > 0 %]
<tr><th class="subheader" colspan="0">Builds that now <strong>succeed</strong></th></tr>
[% INCLUDE renderSome builds=nowSucceed %]
[% END %]
[% IF stillFail.size > 0 %]
<tr><th class="subheader" colspan="0">Builds that still <strong>fail</strong></th></tr>
[% INCLUDE renderSome builds=stillFail %]
[% END %]
[% IF stillSucceed.size > 0 %]
<tr><th class="subheader" colspan="0">Builds that still <strong>succeed</strong></th></tr>
[% INCLUDE renderSome builds=stillSucceed %]
[% END %]
[% INCLUDE renderBuildListFooter %]
[% END %]

47
src/root/jobset-evals.tt Normal file
View file

@ -0,0 +1,47 @@
[% WRAPPER layout.tt title="Jobset $project.name:$jobset.name evaluations" %]
[% PROCESS common.tt %]
<h1>Evaluations of Jobset <tt>[% INCLUDE renderLink
uri = c.uri_for(c.controller('Project').action_for('view'), [project.name])
title = project.name %]:[% jobset.name %]</tt></h1>
<p>Showing evaluations [% (page - 1) * resultsPerPage + 1 %] - [%
(page - 1) * resultsPerPage + evals.size %] out of [% total %].</p>
[% INCLUDE renderPager %]
<table class="tablesorter">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th colspan='2'>Success</th>
</tr>
</thead>
<tbody>
[% last = evals.size - 2; FOREACH n IN [0..last]; eval = evals.$n; m = n + 1; next = evals.$m; %]
<tr>
<td><a href="[% c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id]) %]">[% eval.id %]</a>&nbsp;</td>
<td>[% INCLUDE renderDateTime timestamp = eval.timestamp %]&nbsp;</td>
<td align='right'>
[% eval.get_column('nrSucceeded') %] / [% eval.get_column('nrBuilds') %]
[% IF eval.get_column('nrScheduled') > 0 %]
<br />[% eval.get_column('nrScheduled') %] scheduled
[% END %]
</td>
<td align='right'>
[% diff = eval.get_column('nrSucceeded') - next.get_column('nrSucceeded');
IF diff > 0 %]
<span class='green'><strong>+[% diff %]</strong></span>
[% ELSIF diff < 0 && eval.get_column('nrScheduled') == 0 %]
<span class='red'><strong>[% diff %]</strong></span>
[% END %]
</td>
</tr>
[% END %]
</tbody>
</table>
[% INCLUDE renderPager %]
[% END %]

View file

@ -44,6 +44,9 @@
[% INCLUDE makeLink [% INCLUDE makeLink
uri = c.uri_for(c.controller('Jobset').action_for('index'), [project.name, jobset.name]) uri = c.uri_for(c.controller('Jobset').action_for('index'), [project.name, jobset.name])
title = "Overview" %] title = "Overview" %]
[% INCLUDE makeLink
uri = c.uri_for(c.controller('Jobset').action_for('evals'), [project.name, jobset.name])
title = "Evaluations" %]
[% INCLUDE makeLink [% INCLUDE makeLink
uri = c.uri_for(c.controller('Jobset').action_for('all'), [project.name, jobset.name]) uri = c.uri_for(c.controller('Jobset').action_for('all'), [project.name, jobset.name])
title = "All builds" %] title = "All builds" %]

View file

@ -38,7 +38,14 @@ th, td {
} }
th { th {
background-color:#E6EEEE; background-color: #E6EEEE;
}
th.subheader {
background-color: #f0f0f8;
font-size: 120%;
text-align: center;
font-weight: normal;
} }
table.tablesorter:not(.clean) tr:nth-child(even) { table.tablesorter:not(.clean) tr:nth-child(even) {