From 662cdf042160c4b381f103f893cce77eb29a9fc8 Mon Sep 17 00:00:00 2001
From: Eelco Dolstra
Date: Mon, 2 Apr 2012 16:11:22 +0200
Subject: [PATCH] Add support for viewing jobset evaluations
---
src/lib/Hydra/Base/Controller/ListBuilds.pm | 2 +-
src/lib/Hydra/Controller/Jobset.pm | 29 ++++++++
src/lib/Hydra/Controller/JobsetEval.pm | 76 +++++++++++++++++++++
src/root/all.tt | 19 +-----
src/root/common.tt | 33 +++++++--
src/root/jobset-eval.tt | 41 +++++++++++
src/root/jobset-evals.tt | 47 +++++++++++++
src/root/navbar.tt | 3 +
src/root/static/css/hydra.css | 9 ++-
9 files changed, 236 insertions(+), 23 deletions(-)
create mode 100644 src/lib/Hydra/Controller/JobsetEval.pm
create mode 100644 src/root/jobset-eval.tt
create mode 100644 src/root/jobset-evals.tt
diff --git a/src/lib/Hydra/Base/Controller/ListBuilds.pm b/src/lib/Hydra/Base/Controller/ListBuilds.pm
index 573fe344..2cf70d75 100644
--- a/src/lib/Hydra/Base/Controller/ListBuilds.pm
+++ b/src/lib/Hydra/Base/Controller/ListBuilds.pm
@@ -60,7 +60,7 @@ sub all : Chained('get_builds') PathPart {
$c->stash->{page} = $page;
$c->stash->{resultsPerPage} = $resultsPerPage;
- $c->stash->{totalBuilds} = $nrBuilds;
+ $c->stash->{total} = $nrBuilds;
$c->stash->{builds} = [ $c->stash->{allBuilds}->search(
{ finished => 1 },
diff --git a/src/lib/Hydra/Controller/Jobset.pm b/src/lib/Hydra/Controller/Jobset.pm
index d9a9b2a9..a0a0cdf5 100644
--- a/src/lib/Hydra/Controller/Jobset.pm
+++ b/src/lib/Hydra/Controller/Jobset.pm
@@ -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;
diff --git a/src/lib/Hydra/Controller/JobsetEval.pm b/src/lib/Hydra/Controller/JobsetEval.pm
new file mode 100644
index 00000000..23980e9e
--- /dev/null
+++ b/src/lib/Hydra/Controller/JobsetEval.pm
@@ -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;
diff --git a/src/root/all.tt b/src/root/all.tt
index 746b16c8..355fac0e 100644
--- a/src/root/all.tt
+++ b/src/root/all.tt
@@ -7,23 +7,10 @@
[% ELSIF project %] for Project [% project.name %][% END %]
Showing builds [% (page - 1) * resultsPerPage + 1 %] - [% (page - 1) * resultsPerPage + builds.size %]
-out of [% totalBuilds %] in order of descending timestamp.
+out of [% total %] in order of descending timestamp.
-[% BLOCK renderNav %]
-
-[First]
-[% IF page > 1 %]
- [Prev]
-[% END %]
-[% IF page * resultsPerPage < totalBuilds %]
- [Next]
-[% END %]
-[Last]
-
-[% END %]
-
-[% INCLUDE renderNav %]
+[% INCLUDE renderPager %]
[% INCLUDE renderBuildList hideProjectName=project hideJobsetName=jobset hideJobName=job %]
-[% INCLUDE renderNav %]
+[% INCLUDE renderPager %]
[% END %]
diff --git a/src/root/common.tt b/src/root/common.tt
index 48fd4e3a..ae7ae96e 100644
--- a/src/root/common.tt
+++ b/src/root/common.tt
@@ -62,8 +62,8 @@
[% END %]
-[%- BLOCK renderBuildList -%]
-
+[%- BLOCK renderBuildListHeader -%]
+
[%- IF !hideResultInfo -%]
@@ -89,6 +89,9 @@
+[%- END -%]
+
+[%- BLOCK renderBuildListBody -%]
[%- odd = 0 -%]
[%- FOREACH build IN builds -%]
[% title %][%- END -%]
[%- BLOCK showBuildStats -%]
@@ -377,8 +390,18 @@
[% END %]
-[% BLOCK buildsGraph %]
-
-
+[% BLOCK renderPager %]
+
+[First]
+[% IF page > 1 %]
+ [Prev]
[% END %]
+[% IF page * resultsPerPage < total %]
+ [Next]
+[% END %]
+[Last]
+
+[% END %]
+
+
diff --git a/src/root/jobset-eval.tt b/src/root/jobset-eval.tt
new file mode 100644
index 00000000..9e97b7ed
--- /dev/null
+++ b/src/root/jobset-eval.tt
@@ -0,0 +1,41 @@
+[% WRAPPER layout.tt title="Bla" %]
+[% PROCESS common.tt %]
+
+Jobset [% project.name %]:[% jobset.name %] Evaluation [% eval.id %]
+
+
+
+[%- 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 %]
+ ([% size - max %] more builds omitted) |
+ [% END %]
+[% END %]
+
+[% INCLUDE renderBuildListHeader unsortable=1 %]
+
+[% IF nowFail.size > 0 %]
+
+ [% INCLUDE renderSome builds=nowFail %]
+[% END %]
+
+[% IF nowSucceed.size > 0 %]
+
+ [% INCLUDE renderSome builds=nowSucceed %]
+[% END %]
+
+[% IF stillFail.size > 0 %]
+
+ [% INCLUDE renderSome builds=stillFail %]
+[% END %]
+
+[% IF stillSucceed.size > 0 %]
+
+ [% INCLUDE renderSome builds=stillSucceed %]
+[% END %]
+
+[% INCLUDE renderBuildListFooter %]
+
+[% END %]
diff --git a/src/root/jobset-evals.tt b/src/root/jobset-evals.tt
new file mode 100644
index 00000000..bd75daba
--- /dev/null
+++ b/src/root/jobset-evals.tt
@@ -0,0 +1,47 @@
+[% WRAPPER layout.tt title="Jobset ‘$project.name:$jobset.name’ evaluations" %]
+[% PROCESS common.tt %]
+
+Evaluations of Jobset [% INCLUDE renderLink
+ uri = c.uri_for(c.controller('Project').action_for('view'), [project.name])
+ title = project.name %]:[% jobset.name %]
+
+Showing evaluations [% (page - 1) * resultsPerPage + 1 %] - [%
+(page - 1) * resultsPerPage + evals.size %] out of [% total %].
+
+[% INCLUDE renderPager %]
+
+
+
+
+ # |
+ Date |
+ Success |
+
+
+
+ [% last = evals.size - 2; FOREACH n IN [0..last]; eval = evals.$n; m = n + 1; next = evals.$m; %]
+
+ [% eval.id %] |
+ [% INCLUDE renderDateTime timestamp = eval.timestamp %] |
+
+ [% eval.get_column('nrSucceeded') %] / [% eval.get_column('nrBuilds') %]
+ [% IF eval.get_column('nrScheduled') > 0 %]
+ [% eval.get_column('nrScheduled') %] scheduled
+ [% END %]
+ |
+
+ [% diff = eval.get_column('nrSucceeded') - next.get_column('nrSucceeded');
+ IF diff > 0 %]
+ +[% diff %]
+ [% ELSIF diff < 0 && eval.get_column('nrScheduled') == 0 %]
+ [% diff %]
+ [% END %]
+ |
+
+ [% END %]
+
+
+
+[% INCLUDE renderPager %]
+
+[% END %]
diff --git a/src/root/navbar.tt b/src/root/navbar.tt
index 8521b7f3..161dc819 100644
--- a/src/root/navbar.tt
+++ b/src/root/navbar.tt
@@ -44,6 +44,9 @@
[% INCLUDE makeLink
uri = c.uri_for(c.controller('Jobset').action_for('index'), [project.name, jobset.name])
title = "Overview" %]
+ [% INCLUDE makeLink
+ uri = c.uri_for(c.controller('Jobset').action_for('evals'), [project.name, jobset.name])
+ title = "Evaluations" %]
[% INCLUDE makeLink
uri = c.uri_for(c.controller('Jobset').action_for('all'), [project.name, jobset.name])
title = "All builds" %]
diff --git a/src/root/static/css/hydra.css b/src/root/static/css/hydra.css
index 87e7cfeb..9df9f5b5 100644
--- a/src/root/static/css/hydra.css
+++ b/src/root/static/css/hydra.css
@@ -38,7 +38,14 @@ th, td {
}
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) {