Add support for viewing jobset evaluations
[?]
Apr 2, 2012, 2:11 PM
U4TD3AIQXBJFFUORTMIC4IHZTVBORRKL2TZ2FSP4G665ECZOEMNACDependencies
- [2]
G5YSUSNZIn build tables, hide the project, jobset and/or job name if they're constant - [3]
S5PV6IIM* Represent jobs explicitly in the DB. - [4]
3HZY24CX* Make jobsets viewable under - [5]
J7EE2XZAFix a huge performance regression in the jobstatus page - [6]
T2232OBS* Add some DB indices to make the /releases page much faster. - [7]
SMCOU72Fhydra: add some admin for adding/enabling/etc build machines - [8]
6FXGLP7T* Render durations nicely. - [9]
FPK5LF53* Put the project-related actions in a separate controller. Put the - [10]
DEMSSSB2* Controller for jobs which inherits all actions in ListBuilds. So - [11]
PRNGXWJ3* hydra: more minor css tweaks - [12]
2AIIYGI5* Show job status and all builds for a project. - [13]
HPEG2RHVMerge the BuildResultInfo table into the Builds table - [14]
4S4ZMFJK* Links on trs. - [15]
E74FJWCF* Pass the page number in the URI query string. - [16]
22JB5HNEmake changes section more compact/readable - [17]
JLDUSNUO* Unify rendering of finished and scheduled builds. - [18]
YTSIRIMK* Separate job status and all builds pages. - [19]
GNIEG2GC* Disambiguate jobs by jobset name. I.e. jobs with the same name in - [20]
SJN2QPWH* Big speed-up of the job status page and the channel generation (such - [21]
OZ5UBJEK - [22]
7Z3YOKCV* PROCESS -> INCLUDE in most cases. INCLUDE does proper scoping of - [23]
AVOPQAF7* Make the "all" page faster by not doing four identical `select - [24]
ELABMHJI* hydra: layout changes - [25]
E5DMQRPORemove unnecessary whitespace in the HTML output - [26]
QL55ECJ6- adapted ui for hydra, more in line with nixos.org website - [27]
UWVMQIAC* Refactoring. - [28]
ZI535LI6* hydra: 'new' UI for project/jobset/job/build - [*]
RSEGBU6CHydra/20: Jobset clone feature - [*]
D5QIOJGP* Move everything up one directory. - [*]
IK53RV4V - [*]
IE3SRMWZ* Show global and per-project statistics. - [*]
ODNCGFQ5* Improved the navigation bar: don't include all projects (since that - [*]
J5UVLXOK* Start of a basic Catalyst web interface.
Change contents
- replacement in src/lib/Hydra/Base/Controller/ListBuilds.pm at line 63
$c->stash->{totalBuilds} = $nrBuilds;$c->stash->{total} = $nrBuilds; - edit in src/lib/Hydra/Controller/Jobset.pm at line 330
sub evals : Chained('jobset') PathPart('evals') Args(0) {my ($self, $c) = @_;$c->stash->{template} = 'jobset-evals.tt'; - edit in src/lib/Hydra/Controller/Jobset.pm at line 337
my $page = int($c->req->param('page') || "1") || 1; - edit in src/lib/Hydra/Controller/Jobset.pm at line 339
my $resultsPerPage = 20; - edit in src/lib/Hydra/Controller/Jobset.pm at line 341
$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}) ];} - file addition: JobsetEval.pm[31.188]
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; - replacement in src/root/all.tt at line 10
out of [% totalBuilds %] in order of descending timestamp.</p>out of [% total %] in order of descending timestamp.</p> - replacement in src/root/all.tt at line 12[3.1298]→[3.30:52](∅→∅),[3.52]→[3.107:111](∅→∅),[3.1329]→[3.107:111](∅→∅),[3.111]→[3.76:122](∅→∅),[3.1329]→[3.76:122](∅→∅),[3.122]→[3.1377:1395](∅→∅),[3.1366]→[3.1377:1395](∅→∅),[3.1377]→[3.1377:1395](∅→∅),[3.1395]→[3.123:181](∅→∅),[3.181]→[3.1453:1508](∅→∅),[3.1420]→[3.1453:1508](∅→∅),[3.1453]→[3.1453:1508](∅→∅),[3.1508]→[3.182:240](∅→∅),[3.240]→[3.1566:1576](∅→∅),[3.1474]→[3.1566:1576](∅→∅),[3.1566]→[3.1566:1576](∅→∅),[3.1576]→[3.241:327](∅→∅),[3.327]→[3.112:117](∅→∅),[3.117]→[3.53:63](∅→∅),[3.1663]→[3.64:89](∅→∅)
[% BLOCK renderNav %]<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 renderPager %] - replacement in src/root/all.tt at line 14
[% INCLUDE renderNav %][% INCLUDE renderPager %] - replacement in src/root/common.tt at line 65
[%- BLOCK renderBuildList -%]<table class="buildList tablesorter[% IF !showSchedulingInfo %] clean[% END %]">[%- BLOCK renderBuildListHeader -%]<table class="buildList [% IF !unsortable %]tablesorter[% END %] [% IF !showSchedulingInfo %] clean[% END %]"> - edit in src/root/common.tt at line 92
[%- END -%][%- BLOCK renderBuildListBody -%] - edit in src/root/common.tt at line 136
[%- END -%][%- BLOCK renderBuildListFooter -%] - edit in src/root/common.tt at line 141
[%- END -%][%- BLOCK renderBuildList -%][%- INCLUDE renderBuildListHeader -%][%- INCLUDE renderBuildListBody -%][%- INCLUDE renderBuildListFooter -%] - edit in src/root/common.tt at line 149
- edit in src/root/common.tt at line 393
[% BLOCK buildsGraph %] - edit in src/root/common.tt at line 394
[% BLOCK renderPager %]<p>[<a href="[% "$baseUri?page=1" %]">First</a>][% IF page > 1 %][<a href="[% "$baseUri?page="; (page - 1) %]">Prev</a>][% 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 %] - edit in src/root/common.tt at line 408
[% END %] - file addition: jobset-eval.tt[31.1486]
[% 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 %] - file addition: jobset-evals.tt[31.1486]
[% WRAPPER layout.tt title="Jobset ‘$project.name:$jobset.name’ evaluations" %][% PROCESS common.tt %]<h1>Evaluations of Jobset <tt>[% INCLUDE renderLinkuri = 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> </td><td>[% INCLUDE renderDateTime timestamp = eval.timestamp %] </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 %] - edit in src/root/navbar.tt at line 48
uri = c.uri_for(c.controller('Jobset').action_for('evals'), [project.name, jobset.name])title = "Evaluations" %][% INCLUDE makeLink - replacement in src/root/static/css/hydra.css at line 41
background-color:#E6EEEE;background-color: #E6EEEE;}th.subheader {background-color: #f0f0f8;font-size: 120%;text-align: center;font-weight: normal;