forked from lix-project/hydra
Add a page to show the latest evaluations for the entire server
This commit is contained in:
parent
767cab6cd2
commit
ba68826860
|
@ -49,7 +49,7 @@ sub jobsetIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$c->stash->{evals} = getEvals($self, $c, 0, 10);
|
$c->stash->{evals} = getEvals($self, $c, scalar $c->stash->{jobset}->jobsetevals, 0, 10);
|
||||||
|
|
||||||
$c->stash->{systems} =
|
$c->stash->{systems} =
|
||||||
[ $c->stash->{jobset}->builds->search({ iscurrent => 1 }, { select => ["system"], distinct => 1, order_by => "system" }) ];
|
[ $c->stash->{jobset}->builds->search({ iscurrent => 1 }, { select => ["system"], distinct => 1, order_by => "system" }) ];
|
||||||
|
@ -303,77 +303,21 @@ sub clone_submit : Chained('jobset') PathPart('clone/submit') Args(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub getEvals {
|
|
||||||
my ($self, $c, $offset, $rows) = @_;
|
|
||||||
|
|
||||||
my @evals = $c->stash->{jobset}->jobsetevals->search(
|
|
||||||
{ hasnewbuilds => 1 },
|
|
||||||
{ order_by => "id DESC", rows => $rows + 1, offset => $offset });
|
|
||||||
|
|
||||||
my @res = ();
|
|
||||||
my $prevInputs = [];
|
|
||||||
my $prev;
|
|
||||||
for (my $n = scalar @evals - 1; $n >= 0; $n--) {
|
|
||||||
my $cur = $evals[$n];
|
|
||||||
|
|
||||||
# Get stats for this eval.
|
|
||||||
my $nrScheduled;
|
|
||||||
my $nrSucceeded = $cur->nrsucceeded;
|
|
||||||
if (defined $nrSucceeded) {
|
|
||||||
$nrScheduled = 0;
|
|
||||||
} else {
|
|
||||||
$nrScheduled = $cur->builds->search({finished => 0})->count;
|
|
||||||
$nrSucceeded = $cur->builds->search({finished => 1, buildStatus => 0})->count;
|
|
||||||
if ($nrScheduled == 0) {
|
|
||||||
$cur->update({nrsucceeded => $nrSucceeded});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Compute what inputs changed between each eval.
|
|
||||||
my $curInputs = [ $cur->jobsetevalinputs->search(
|
|
||||||
{ -or => [ -and => [ uri => { '!=' => undef }, revision => { '!=' => undef }], dependency => { '!=' => undef }], altNr => 0 },
|
|
||||||
{ order_by => "name" }) ];
|
|
||||||
my @changedInputs;
|
|
||||||
my %prevInputsHash;
|
|
||||||
$prevInputsHash{$_->name} = $_ foreach @{$prevInputs};
|
|
||||||
foreach my $input (@{$curInputs}) {
|
|
||||||
my $p = $prevInputsHash{$input->name};
|
|
||||||
push @changedInputs, $input
|
|
||||||
if !defined $p || ($input->revision || "") ne ($p->revision || "") || $input->type ne $p->type || ($input->uri || "") ne ($p->uri || "") ||
|
|
||||||
( defined $input->dependency && defined $p->dependency && $input->dependency->id ne $p->dependency->id);
|
|
||||||
}
|
|
||||||
$prevInputs = $curInputs;
|
|
||||||
|
|
||||||
my $e =
|
|
||||||
{ eval => $cur
|
|
||||||
, nrScheduled => $nrScheduled
|
|
||||||
, nrSucceeded => $nrSucceeded
|
|
||||||
, nrFailed => $cur->nrbuilds - $nrSucceeded - $nrScheduled
|
|
||||||
, diff => defined $prev ? $nrSucceeded - $prev->{nrSucceeded} : 0
|
|
||||||
, changedInputs => [ @changedInputs ]
|
|
||||||
};
|
|
||||||
push @res, $e if $n < $rows;
|
|
||||||
$prev = $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [reverse @res];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub evals : Chained('jobset') PathPart('evals') Args(0) {
|
sub evals : Chained('jobset') PathPart('evals') Args(0) {
|
||||||
my ($self, $c) = @_;
|
my ($self, $c) = @_;
|
||||||
|
|
||||||
$c->stash->{template} = 'jobset-evals.tt';
|
$c->stash->{template} = 'evals.tt';
|
||||||
|
|
||||||
my $page = int($c->req->param('page') || "1") || 1;
|
my $page = int($c->req->param('page') || "1") || 1;
|
||||||
|
|
||||||
my $resultsPerPage = 20;
|
my $resultsPerPage = 20;
|
||||||
|
|
||||||
|
my $evals = $c->stash->{jobset}->jobsetevals;
|
||||||
|
|
||||||
$c->stash->{page} = $page;
|
$c->stash->{page} = $page;
|
||||||
$c->stash->{resultsPerPage} = $resultsPerPage;
|
$c->stash->{resultsPerPage} = $resultsPerPage;
|
||||||
$c->stash->{total} = $c->stash->{jobset}->jobsetevals->search({hasnewbuilds => 1})->count;
|
$c->stash->{total} = $evals->search({hasnewbuilds => 1})->count;
|
||||||
|
$c->stash->{evals} = getEvals($self, $c, $evals, ($page - 1) * $resultsPerPage, $resultsPerPage)
|
||||||
$c->stash->{evals} = getEvals($self, $c, ($page - 1) * $resultsPerPage, $resultsPerPage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -281,4 +281,22 @@ sub logo :Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub evals :Local Args(0) {
|
||||||
|
my ($self, $c) = @_;
|
||||||
|
|
||||||
|
$c->stash->{template} = 'evals.tt';
|
||||||
|
|
||||||
|
my $page = int($c->req->param('page') || "1") || 1;
|
||||||
|
|
||||||
|
my $resultsPerPage = 20;
|
||||||
|
|
||||||
|
my $evals = $c->model('DB::JobsetEvals');
|
||||||
|
|
||||||
|
$c->stash->{page} = $page;
|
||||||
|
$c->stash->{resultsPerPage} = $resultsPerPage;
|
||||||
|
$c->stash->{total} = $evals->search({hasnewbuilds => 1})->count;
|
||||||
|
$c->stash->{evals} = getEvals($self, $c, $evals, ($page - 1) * $resultsPerPage, $resultsPerPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -15,7 +15,8 @@ our @EXPORT = qw(
|
||||||
getPrimaryBuildTotal
|
getPrimaryBuildTotal
|
||||||
getViewResult getLatestSuccessfulViewResult
|
getViewResult getLatestSuccessfulViewResult
|
||||||
jobsetOverview removeAsciiEscapes getDrvLogPath logContents
|
jobsetOverview removeAsciiEscapes getDrvLogPath logContents
|
||||||
getMainOutput);
|
getMainOutput
|
||||||
|
getEvals);
|
||||||
|
|
||||||
|
|
||||||
sub getHydraHome {
|
sub getHydraHome {
|
||||||
|
@ -287,4 +288,61 @@ sub getMainOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub getEvals {
|
||||||
|
my ($self, $c, $evals, $offset, $rows) = @_;
|
||||||
|
|
||||||
|
my @evals = $evals->search(
|
||||||
|
{ hasnewbuilds => 1 },
|
||||||
|
{ order_by => "id DESC", rows => $rows + 1, offset => $offset });
|
||||||
|
|
||||||
|
my @res = ();
|
||||||
|
my $prevInputs = [];
|
||||||
|
my $prev;
|
||||||
|
for (my $n = scalar @evals - 1; $n >= 0; $n--) {
|
||||||
|
my $cur = $evals[$n];
|
||||||
|
|
||||||
|
# Get stats for this eval.
|
||||||
|
my $nrScheduled;
|
||||||
|
my $nrSucceeded = $cur->nrsucceeded;
|
||||||
|
if (defined $nrSucceeded) {
|
||||||
|
$nrScheduled = 0;
|
||||||
|
} else {
|
||||||
|
$nrScheduled = $cur->builds->search({finished => 0})->count;
|
||||||
|
$nrSucceeded = $cur->builds->search({finished => 1, buildStatus => 0})->count;
|
||||||
|
if ($nrScheduled == 0) {
|
||||||
|
$cur->update({nrsucceeded => $nrSucceeded});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compute what inputs changed between each eval.
|
||||||
|
my $curInputs = [ $cur->jobsetevalinputs->search(
|
||||||
|
{ -or => [ -and => [ uri => { '!=' => undef }, revision => { '!=' => undef }], dependency => { '!=' => undef }], altNr => 0 },
|
||||||
|
{ order_by => "name" }) ];
|
||||||
|
my @changedInputs;
|
||||||
|
my %prevInputsHash;
|
||||||
|
$prevInputsHash{$_->name} = $_ foreach @{$prevInputs};
|
||||||
|
foreach my $input (@{$curInputs}) {
|
||||||
|
my $p = $prevInputsHash{$input->name};
|
||||||
|
push @changedInputs, $input
|
||||||
|
if !defined $p || ($input->revision || "") ne ($p->revision || "") || $input->type ne $p->type || ($input->uri || "") ne ($p->uri || "") ||
|
||||||
|
( defined $input->dependency && defined $p->dependency && $input->dependency->id ne $p->dependency->id);
|
||||||
|
}
|
||||||
|
$prevInputs = $curInputs;
|
||||||
|
|
||||||
|
my $e =
|
||||||
|
{ eval => $cur
|
||||||
|
, nrScheduled => $nrScheduled
|
||||||
|
, nrSucceeded => $nrSucceeded
|
||||||
|
, nrFailed => $cur->nrbuilds - $nrSucceeded - $nrScheduled
|
||||||
|
, diff => defined $prev ? $nrSucceeded - $prev->{nrSucceeded} : 0
|
||||||
|
, changedInputs => [ @changedInputs ]
|
||||||
|
};
|
||||||
|
push @res, $e if $n < $rows;
|
||||||
|
$prev = $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [reverse @res];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -384,10 +384,13 @@ BLOCK renderEvals %]
|
||||||
<table class="tablesorter table table-condensed table-striped">
|
<table class="tablesorter table table-condensed table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
[% IF !jobset %]
|
||||||
|
<th>Jobset</th>
|
||||||
|
[% END %]
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
<th>Date</th>
|
<th style="width: 10em">Date</th>
|
||||||
<th>Input changes</th>
|
<th>Input changes</th>
|
||||||
<th colspan='2'>Success</th>
|
<th colspan='2' style="width: 25em">Success</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -395,6 +398,9 @@ BLOCK renderEvals %]
|
||||||
eval = e.eval;
|
eval = e.eval;
|
||||||
link = c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id]) %]
|
link = c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id]) %]
|
||||||
<tr class="clickable" onclick="window.location = '[% link %]'">
|
<tr class="clickable" onclick="window.location = '[% link %]'">
|
||||||
|
[% IF !jobset %]
|
||||||
|
<td>[% INCLUDE renderFullJobsetName project=eval.get_column('project') jobset=eval.get_column('jobset') %]</td>
|
||||||
|
[% END %]
|
||||||
<td><a href="[% link %]">[% eval.id %]</a></td>
|
<td><a href="[% link %]">[% eval.id %]</a></td>
|
||||||
<td>[% INCLUDE renderDateTime timestamp = eval.timestamp %]</td>
|
<td>[% INCLUDE renderDateTime timestamp = eval.timestamp %]</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -402,7 +408,7 @@ BLOCK renderEvals %]
|
||||||
sep='';
|
sep='';
|
||||||
FOREACH input IN e.changedInputs;
|
FOREACH input IN e.changedInputs;
|
||||||
sep; %] [% input.name %] → [% INCLUDE renderShortEvalInput input=input;
|
sep; %] [% input.name %] → [% INCLUDE renderShortEvalInput input=input;
|
||||||
sep=',';
|
sep=', ';
|
||||||
END;
|
END;
|
||||||
ELSE %]
|
ELSE %]
|
||||||
-
|
-
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
[% WRAPPER layout.tt title=(httpStatus ? httpStatus : "Error") %]
|
[% WRAPPER layout.tt title=(httpStatus ? httpStatus : "Error") %]
|
||||||
[% USE HTML %]
|
[% USE HTML %]
|
||||||
|
|
||||||
<p>I'm very sorry, but the following error(s) occurred:</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
[% FOREACH error IN errors %]
|
[% FOREACH error IN errors %]
|
||||||
<li><div class="error-msg">[% HTML.escape(error) %]</div></li>
|
<div class="alert alert-error">[% HTML.escape(error) %]</div>
|
||||||
[% END %]
|
[% END %]
|
||||||
</ul>
|
|
||||||
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[% WRAPPER layout.tt title="Evaluations of jobset $project.name:$jobset.name" %]
|
[% WRAPPER layout.tt title=(jobset ? "Evaluations of jobset $project.name:$jobset.name" : "Latest evaluations") %]
|
||||||
[% PROCESS common.tt %]
|
[% PROCESS common.tt %]
|
||||||
|
|
||||||
<p>Showing evaluations [% (page - 1) * resultsPerPage + 1 %] - [%
|
<p>Showing evaluations [% (page - 1) * resultsPerPage + 1 %] - [%
|
|
@ -36,6 +36,9 @@
|
||||||
[% INCLUDE makeLink
|
[% INCLUDE makeLink
|
||||||
uri = c.uri_for(c.controller('Root').action_for('machines'))
|
uri = c.uri_for(c.controller('Root').action_for('machines'))
|
||||||
title = "Machine status" %]
|
title = "Machine status" %]
|
||||||
|
[% INCLUDE makeLink
|
||||||
|
uri = c.uri_for(c.controller('Root').action_for('evals'))
|
||||||
|
title = "Latest evaluations" %]
|
||||||
[% INCLUDE makeLink
|
[% INCLUDE makeLink
|
||||||
uri = c.uri_for(c.controller('Root').action_for('all'))
|
uri = c.uri_for(c.controller('Root').action_for('all'))
|
||||||
title = "Latest builds" %]
|
title = "Latest builds" %]
|
||||||
|
|
Loading…
Reference in a new issue