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 %] + Builds that now fail + [% INCLUDE renderSome builds=nowFail %] +[% END %] + +[% IF nowSucceed.size > 0 %] + Builds that now succeed + [% INCLUDE renderSome builds=nowSucceed %] +[% END %] + +[% IF stillFail.size > 0 %] + Builds that still fail + [% INCLUDE renderSome builds=stillFail %] +[% END %] + +[% IF stillSucceed.size > 0 %] + Builds that still succeed + [% 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 %] + + + + + + + + + + + [% last = evals.size - 2; FOREACH n IN [0..last]; eval = evals.$n; m = n + 1; next = evals.$m; %] + + + + + + + [% END %] + +
#DateSuccess
[% 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 %] +
+ +[% 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) {