Remove the Jobs table

This table has been superfluous for a long time.
This commit is contained in:
Eelco Dolstra 2020-05-27 20:09:36 +02:00
parent af9f635a5a
commit 8adb433e3b
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
25 changed files with 100 additions and 440 deletions

View file

@ -86,7 +86,7 @@ sub build_GET {
$c->stash->{prevBuilds} = [$c->model('DB::Builds')->search( $c->stash->{prevBuilds} = [$c->model('DB::Builds')->search(
{ project => $c->stash->{project}->name { project => $c->stash->{project}->name
, jobset => $c->stash->{jobset}->name , jobset => $c->stash->{jobset}->name
, job => $c->stash->{job}->name , job => $c->stash->{job}
, 'me.system' => $build->system , 'me.system' => $build->system
, finished => 1 , finished => 1
, buildstatus => 0 , buildstatus => 0

View file

@ -24,18 +24,16 @@ sub job : Chained('/') PathPart('job') CaptureArgs(3) {
$c->detach; $c->detach;
} }
$c->stash->{job} = $c->stash->{jobset}->jobs->find({ name => $jobName }) $c->stash->{job} = $jobName;
or notFound($c, "Job $projectName:$jobsetName:$jobName doesn't exist."); $c->stash->{project} = $c->stash->{jobset}->project;
$c->stash->{project} = $c->stash->{job}->project;
} }
sub prometheus : Chained('job') PathPart('prometheus') Args(0) { sub prometheus : Chained('job') PathPart('prometheus') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my $job = $c->stash->{job};
my $prometheus = Net::Prometheus->new; my $prometheus = Net::Prometheus->new;
my $lastBuild = $job->builds->find( my $lastBuild = $c->stash->{jobset}->builds->find(
{ finished => 1 }, { job => $c->stash->{job}, finished => 1 },
{ order_by => 'id DESC', rows => 1, columns => [@buildListColumns] } { order_by => 'id DESC', rows => 1, columns => [@buildListColumns] }
); );
@ -46,7 +44,7 @@ sub prometheus : Chained('job') PathPart('prometheus') Args(0) {
)->labels( )->labels(
$c->stash->{project}->name, $c->stash->{project}->name,
$c->stash->{jobset}->name, $c->stash->{jobset}->name,
$c->stash->{job}->name, $c->stash->{job},
)->inc($lastBuild->stoptime); )->inc($lastBuild->stoptime);
$prometheus->new_gauge( $prometheus->new_gauge(
@ -56,7 +54,7 @@ sub prometheus : Chained('job') PathPart('prometheus') Args(0) {
)->labels( )->labels(
$c->stash->{project}->name, $c->stash->{project}->name,
$c->stash->{jobset}->name, $c->stash->{jobset}->name,
$c->stash->{job}->name, $c->stash->{job},
)->inc($lastBuild->buildstatus > 0); )->inc($lastBuild->buildstatus > 0);
$c->stash->{'plain'} = { data => $prometheus->render }; $c->stash->{'plain'} = { data => $prometheus->render };
@ -65,23 +63,22 @@ sub prometheus : Chained('job') PathPart('prometheus') Args(0) {
sub overview : Chained('job') PathPart('') Args(0) { sub overview : Chained('job') PathPart('') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my $job = $c->stash->{job};
$c->stash->{template} = 'job.tt'; $c->stash->{template} = 'job.tt';
$c->stash->{lastBuilds} = $c->stash->{lastBuilds} =
[ $job->builds->search({ finished => 1 }, [ $c->stash->{jobset}->builds->search({ job => $c->stash->{job}, finished => 1 },
{ order_by => 'id DESC', rows => 10, columns => [@buildListColumns] }) ]; { order_by => 'id DESC', rows => 10, columns => [@buildListColumns] }) ];
$c->stash->{queuedBuilds} = [ $c->stash->{queuedBuilds} = [
$job->builds->search( $c->stash->{jobset}->builds->search(
{ finished => 0 }, { job => $c->stash->{job}, finished => 0 },
{ order_by => ["priority DESC", "id"] } { order_by => ["priority DESC", "id"] }
) ]; ) ];
# If this is an aggregate job, then get its constituents. # If this is an aggregate job, then get its constituents.
my @constituents = $c->model('DB::Builds')->search( my @constituents = $c->model('DB::Builds')->search(
{ aggregate => { -in => $job->builds->search({}, { columns => ["id"], order_by => "id desc", rows => 15 })->as_query } }, { aggregate => { -in => $c->stash->{jobset}->builds->search({ job => $c->stash->{job} }, { columns => ["id"], order_by => "id desc", rows => 15 })->as_query } },
{ join => 'aggregateconstituents_constituents', { join => 'aggregateconstituents_constituents',
columns => ['id', 'job', 'finished', 'buildstatus'], columns => ['id', 'job', 'finished', 'buildstatus'],
+select => ['aggregateconstituents_constituents.aggregate'], +select => ['aggregateconstituents_constituents.aggregate'],
@ -91,10 +88,9 @@ sub overview : Chained('job') PathPart('') Args(0) {
my $aggregates = {}; my $aggregates = {};
my %constituentJobs; my %constituentJobs;
foreach my $b (@constituents) { foreach my $b (@constituents) {
my $jobName = $b->get_column('job'); $aggregates->{$b->get_column('aggregate')}->{constituents}->{$b->job} =
$aggregates->{$b->get_column('aggregate')}->{constituents}->{$jobName} =
{ id => $b->id, finished => $b->finished, buildstatus => $b->buildstatus }; { id => $b->id, finished => $b->finished, buildstatus => $b->buildstatus };
$constituentJobs{$jobName} = 1; $constituentJobs{$b->job} = 1;
} }
foreach my $agg (keys %$aggregates) { foreach my $agg (keys %$aggregates) {
@ -109,24 +105,23 @@ sub overview : Chained('job') PathPart('') Args(0) {
$c->stash->{starred} = $c->user->starredjobs( $c->stash->{starred} = $c->user->starredjobs(
{ project => $c->stash->{project}->name { project => $c->stash->{project}->name
, jobset => $c->stash->{jobset}->name , jobset => $c->stash->{jobset}->name
, job => $c->stash->{job}->name , job => $c->stash->{job}
})->count == 1 if $c->user_exists; })->count == 1 if $c->user_exists;
} }
sub metrics_tab : Chained('job') PathPart('metrics-tab') Args(0) { sub metrics_tab : Chained('job') PathPart('metrics-tab') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my $job = $c->stash->{job};
$c->stash->{template} = 'job-metrics-tab.tt'; $c->stash->{template} = 'job-metrics-tab.tt';
$c->stash->{metrics} = [ $job->buildmetrics->search( $c->stash->{metrics} = [ $c->stash->{jobset}->buildmetrics->search(
{ }, { select => ["name"], distinct => 1, order_by => "name", }) ]; { job => $c->stash->{job} }, { select => ["name"], distinct => 1, order_by => "name", }) ];
} }
sub build_times : Chained('job') PathPart('build-times') Args(0) { sub build_times : Chained('job') PathPart('build-times') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my @res = $c->stash->{job}->builds->search( my @res = $c->stash->{jobset}->builds->search(
{ finished => 1, buildstatus => 0, closuresize => { '!=', 0 } }, { job => $c->stash->{job}, finished => 1, buildstatus => 0, closuresize => { '!=', 0 } },
{ join => "actualBuildStep" { join => "actualBuildStep"
, "+select" => ["actualBuildStep.stoptime - actualBuildStep.starttime"] , "+select" => ["actualBuildStep.stoptime - actualBuildStep.starttime"]
, "+as" => ["actualBuildTime"], , "+as" => ["actualBuildTime"],
@ -137,8 +132,8 @@ sub build_times : Chained('job') PathPart('build-times') Args(0) {
sub closure_sizes : Chained('job') PathPart('closure-sizes') Args(0) { sub closure_sizes : Chained('job') PathPart('closure-sizes') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my @res = $c->stash->{job}->builds->search( my @res = $c->stash->{jobset}->builds->search(
{ finished => 1, buildstatus => 0, closuresize => { '!=', 0 } }, { job => $c->stash->{job}, finished => 1, buildstatus => 0, closuresize => { '!=', 0 } },
{ order_by => "id", columns => [ "id", "timestamp", "closuresize" ] }); { order_by => "id", columns => [ "id", "timestamp", "closuresize" ] });
$self->status_ok($c, entity => [ map { { id => $_->id, timestamp => $_ ->timestamp, value => $_->closuresize } } @res ]); $self->status_ok($c, entity => [ map { { id => $_->id, timestamp => $_ ->timestamp, value => $_->closuresize } } @res ]);
} }
@ -146,8 +141,8 @@ sub closure_sizes : Chained('job') PathPart('closure-sizes') Args(0) {
sub output_sizes : Chained('job') PathPart('output-sizes') Args(0) { sub output_sizes : Chained('job') PathPart('output-sizes') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my @res = $c->stash->{job}->builds->search( my @res = $c->stash->{jobset}->builds->search(
{ finished => 1, buildstatus => 0, size => { '!=', 0 } }, { job => $c->stash->{job}, finished => 1, buildstatus => 0, size => { '!=', 0 } },
{ order_by => "id", columns => [ "id", "timestamp", "size" ] }); { order_by => "id", columns => [ "id", "timestamp", "size" ] });
$self->status_ok($c, entity => [ map { { id => $_->id, timestamp => $_ ->timestamp, value => $_->size } } @res ]); $self->status_ok($c, entity => [ map { { id => $_->id, timestamp => $_ ->timestamp, value => $_->size } } @res ]);
} }
@ -159,8 +154,8 @@ sub metric : Chained('job') PathPart('metric') Args(1) {
$c->stash->{template} = 'metric.tt'; $c->stash->{template} = 'metric.tt';
$c->stash->{metricName} = $metricName; $c->stash->{metricName} = $metricName;
my @res = $c->stash->{job}->buildmetrics->search( my @res = $c->stash->{jobset}->buildmetrics->search(
{ name => $metricName }, { job => $c->stash->{job}, name => $metricName },
{ order_by => "timestamp", columns => [ "build", "name", "timestamp", "value", "unit" ] }); { order_by => "timestamp", columns => [ "build", "name", "timestamp", "value", "unit" ] });
$self->status_ok($c, entity => [ map { { id => $_->get_column("build"), timestamp => $_ ->timestamp, value => $_->value, unit => $_->unit } } @res ]); $self->status_ok($c, entity => [ map { { id => $_->get_column("build"), timestamp => $_ ->timestamp, value => $_->value, unit => $_->unit } } @res ]);
@ -170,11 +165,11 @@ sub metric : Chained('job') PathPart('metric') Args(1) {
# Hydra::Base::Controller::ListBuilds needs this. # Hydra::Base::Controller::ListBuilds needs this.
sub get_builds : Chained('job') PathPart('') CaptureArgs(0) { sub get_builds : Chained('job') PathPart('') CaptureArgs(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
$c->stash->{allBuilds} = $c->stash->{job}->builds; $c->stash->{allBuilds} = $c->stash->{jobset}->builds->search({ job => $c->stash->{job} });
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceededForJob') $c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceededForJob')
->search({}, {bind => [$c->stash->{jobset}->id, $c->stash->{job}->name]}); ->search({}, {bind => [$c->stash->{jobset}->id, $c->stash->{job}]});
$c->stash->{channelBaseName} = $c->stash->{channelBaseName} =
$c->stash->{project}->name . "-" . $c->stash->{jobset}->name . "-" . $c->stash->{job}->name; $c->stash->{project}->name . "-" . $c->stash->{jobset}->name . "-" . $c->stash->{job};
} }
@ -185,7 +180,7 @@ sub star : Chained('job') PathPart('star') Args(0) {
my $args = my $args =
{ project => $c->stash->{project}->name { project => $c->stash->{project}->name
, jobset => $c->stash->{jobset}->name , jobset => $c->stash->{jobset}->name
, job => $c->stash->{job}->name , job => $c->stash->{job}
}; };
if ($c->request->params->{star} eq "1") { if ($c->request->params->{star} eq "1") {
$c->user->starredjobs->update_or_create($args); $c->user->starredjobs->update_or_create($args);

View file

@ -459,16 +459,16 @@ sub search :Local Args(0) {
}, },
{ order_by => ["project", "name"], join => ["project"] } ) ]; { order_by => ["project", "name"], join => ["project"] } ) ];
$c->stash->{jobs} = [ $c->model('DB::Jobs')->search( $c->stash->{jobs} = [ $c->model('DB::Builds')->search(
{ "me.name" => { ilike => "%$query%" } { "job" => { ilike => "%$query%" }
, "project.hidden" => 0 , "project.hidden" => 0
, "jobset.hidden" => 0 , "jobset.hidden" => 0
, iscurrent => 1
}, },
{ order_by => ["enabled_ desc", "project", "jobset", "name"], join => ["project", "jobset"] { order_by => ["project", "jobset", "job"], join => ["project", "jobset"]
, "+select" => [\ "(project.enabled = 1 and jobset.enabled = 1 and exists (select 1 from Builds where project = project.name and jobset = jobset.name and job = me.name and iscurrent = 1)) as enabled_"]
, "+as" => ["enabled"]
, rows => $c->stash->{limit} + 1 , rows => $c->stash->{limit} + 1
} ) ]; } )
];
# Perform build search in separate queries to prevent seq scan on buildoutputs table. # Perform build search in separate queries to prevent seq scan on buildoutputs table.
$c->stash->{builds} = [ $c->model('DB::Builds')->search( $c->stash->{builds} = [ $c->model('DB::Builds')->search(

View file

@ -339,10 +339,10 @@ sub dashboard :Chained('dashboard_base') :PathPart('') :Args(0) {
# Get the N most recent builds for each starred job. # Get the N most recent builds for each starred job.
$c->stash->{starredJobs} = []; $c->stash->{starredJobs} = [];
foreach my $j ($c->stash->{user}->starredjobs->search({}, { order_by => ['project', 'jobset', 'job'] })) { foreach my $j ($c->stash->{user}->starredjobs->search({}, { order_by => ['project', 'jobset', 'job'] })) {
my @builds = $j->job->builds->search( my @builds = $j->jobset->builds->search(
{ }, { job => $j->job },
{ rows => 20, order_by => "id desc" }); { rows => 20, order_by => "id desc" });
push @{$c->stash->{starredJobs}}, { job => $j->job, builds => [@builds] }; push @{$c->stash->{starredJobs}}, { job => $j, builds => [@builds] };
} }
} }

View file

@ -46,7 +46,7 @@ sub getBuild {
sub getPreviousBuild { sub getPreviousBuild {
my ($build) = @_; my ($build) = @_;
return undef if !defined $build; return undef if !defined $build;
return $build->job->builds->search( return $build->jobset->builds->search(
{ finished => 1 { finished => 1
, system => $build->system , system => $build->system
, 'me.id' => { '<' => $build->id } , 'me.id' => { '<' => $build->id }

View file

@ -71,7 +71,6 @@ __PACKAGE__->table("buildmetrics");
=head2 job =head2 job
data_type: 'text' data_type: 'text'
is_foreign_key: 1
is_nullable: 0 is_nullable: 0
=head2 timestamp =head2 timestamp
@ -95,7 +94,7 @@ __PACKAGE__->add_columns(
"jobset", "jobset",
{ data_type => "text", is_foreign_key => 1, is_nullable => 0 }, { data_type => "text", is_foreign_key => 1, is_nullable => 0 },
"job", "job",
{ data_type => "text", is_foreign_key => 1, is_nullable => 0 }, { data_type => "text", is_nullable => 0 },
"timestamp", "timestamp",
{ data_type => "integer", is_nullable => 0 }, { data_type => "integer", is_nullable => 0 },
); );
@ -131,21 +130,6 @@ __PACKAGE__->belongs_to(
{ is_deferrable => 0, on_delete => "CASCADE", on_update => "NO ACTION" }, { is_deferrable => 0, on_delete => "CASCADE", on_update => "NO ACTION" },
); );
=head2 job
Type: belongs_to
Related object: L<Hydra::Schema::Jobs>
=cut
__PACKAGE__->belongs_to(
"job",
"Hydra::Schema::Jobs",
{ jobset => "jobset", name => "job", project => "project" },
{ is_deferrable => 0, on_delete => "NO ACTION", on_update => "CASCADE" },
);
=head2 jobset =head2 jobset
Type: belongs_to Type: belongs_to
@ -177,8 +161,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-02-06 12:22:36 # Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-27 17:40:41
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Roy7h/K9u7DQOzet4B1sbA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:AYUVs6RdefFKw+g9Yxcu/A
sub json_hint { sub json_hint {
return { columns => ['value', 'unit'] }; return { columns => ['value', 'unit'] };

View file

@ -73,7 +73,6 @@ __PACKAGE__->table("builds");
=head2 job =head2 job
data_type: 'text' data_type: 'text'
is_foreign_key: 1
is_nullable: 0 is_nullable: 0
=head2 nixname =head2 nixname
@ -224,7 +223,7 @@ __PACKAGE__->add_columns(
"jobset_id", "jobset_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"job", "job",
{ data_type => "text", is_foreign_key => 1, is_nullable => 0 }, { data_type => "text", is_nullable => 0 },
"nixname", "nixname",
{ data_type => "text", is_nullable => 1 }, { data_type => "text", is_nullable => 1 },
"description", "description",
@ -439,21 +438,6 @@ __PACKAGE__->has_many(
undef, undef,
); );
=head2 job
Type: belongs_to
Related object: L<Hydra::Schema::Jobs>
=cut
__PACKAGE__->belongs_to(
"job",
"Hydra::Schema::Jobs",
{ jobset => "jobset", name => "job", project => "project" },
{ is_deferrable => 0, on_delete => "NO ACTION", on_update => "CASCADE" },
);
=head2 jobset =head2 jobset
Type: belongs_to Type: belongs_to
@ -558,8 +542,8 @@ __PACKAGE__->many_to_many(
); );
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-06 12:32:57 # Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-27 17:40:41
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3IyFj/9Zf/hvmhBY4U/IBQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:RIKKFfcKXFWIUeM8ma++iw
__PACKAGE__->has_many( __PACKAGE__->has_many(
"dependents", "dependents",

View file

@ -1,216 +0,0 @@
use utf8;
package Hydra::Schema::Jobs;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Hydra::Schema::Jobs
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 COMPONENTS LOADED
=over 4
=item * L<Hydra::Component::ToJSON>
=back
=cut
__PACKAGE__->load_components("+Hydra::Component::ToJSON");
=head1 TABLE: C<jobs>
=cut
__PACKAGE__->table("jobs");
=head1 ACCESSORS
=head2 project
data_type: 'text'
is_foreign_key: 1
is_nullable: 0
=head2 jobset
data_type: 'text'
is_foreign_key: 1
is_nullable: 0
=head2 jobset_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 name
data_type: 'text'
is_nullable: 0
=cut
__PACKAGE__->add_columns(
"project",
{ data_type => "text", is_foreign_key => 1, is_nullable => 0 },
"jobset",
{ data_type => "text", is_foreign_key => 1, is_nullable => 0 },
"jobset_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"name",
{ data_type => "text", is_nullable => 0 },
);
=head1 PRIMARY KEY
=over 4
=item * L</project>
=item * L</jobset>
=item * L</name>
=back
=cut
__PACKAGE__->set_primary_key("project", "jobset", "name");
=head1 RELATIONS
=head2 buildmetrics
Type: has_many
Related object: L<Hydra::Schema::BuildMetrics>
=cut
__PACKAGE__->has_many(
"buildmetrics",
"Hydra::Schema::BuildMetrics",
{
"foreign.job" => "self.name",
"foreign.jobset" => "self.jobset",
"foreign.project" => "self.project",
},
undef,
);
=head2 builds
Type: has_many
Related object: L<Hydra::Schema::Builds>
=cut
__PACKAGE__->has_many(
"builds",
"Hydra::Schema::Builds",
{
"foreign.job" => "self.name",
"foreign.jobset" => "self.jobset",
"foreign.project" => "self.project",
},
undef,
);
=head2 jobset
Type: belongs_to
Related object: L<Hydra::Schema::Jobsets>
=cut
__PACKAGE__->belongs_to(
"jobset",
"Hydra::Schema::Jobsets",
{ id => "jobset_id" },
{ is_deferrable => 0, on_delete => "CASCADE", on_update => "NO ACTION" },
);
=head2 jobset_project_jobset
Type: belongs_to
Related object: L<Hydra::Schema::Jobsets>
=cut
__PACKAGE__->belongs_to(
"jobset_project_jobset",
"Hydra::Schema::Jobsets",
{ name => "jobset", project => "project" },
{ is_deferrable => 0, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 project
Type: belongs_to
Related object: L<Hydra::Schema::Projects>
=cut
__PACKAGE__->belongs_to(
"project",
"Hydra::Schema::Projects",
{ name => "project" },
{ is_deferrable => 0, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 starredjobs
Type: has_many
Related object: L<Hydra::Schema::StarredJobs>
=cut
__PACKAGE__->has_many(
"starredjobs",
"Hydra::Schema::StarredJobs",
{
"foreign.job" => "self.name",
"foreign.jobset" => "self.jobset",
"foreign.project" => "self.project",
},
undef,
);
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-02-06 12:33:28
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:C5Tyh8Ke4yC6q7KIFVOHcQ
=head2 builds
Type: has_many
Related object: L<Hydra::Sc2hema::Builds>
=cut
__PACKAGE__->has_many(
"builds",
"Hydra::Schema::Builds",
{
"foreign.job" => "self.name",
"foreign.jobset_id" => "self.jobset_id",
},
undef,
);
1;

View file

@ -201,8 +201,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-02-09 15:21:11 # Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-27 17:40:41
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Ar6GRni8AcAQmuZyg6tFKw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:M61ikfnjORU7jDAH8P/j7w
__PACKAGE__->has_many( __PACKAGE__->has_many(
"buildIds", "buildIds",

View file

@ -290,39 +290,6 @@ __PACKAGE__->has_many(
undef, undef,
); );
=head2 jobs_jobset_ids
Type: has_many
Related object: L<Hydra::Schema::Jobs>
=cut
__PACKAGE__->has_many(
"jobs_jobset_ids",
"Hydra::Schema::Jobs",
{ "foreign.jobset_id" => "self.id" },
undef,
);
=head2 jobs_project_jobsets
Type: has_many
Related object: L<Hydra::Schema::Jobs>
=cut
__PACKAGE__->has_many(
"jobs_project_jobsets",
"Hydra::Schema::Jobs",
{
"foreign.jobset" => "self.name",
"foreign.project" => "self.project",
},
undef,
);
=head2 jobsetevals =head2 jobsetevals
Type: has_many Type: has_many
@ -408,8 +375,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-02-09 15:32:17 # Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-27 17:40:41
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:P8+t7rgpOqkGwRdM2b+3Bw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:aDW78MCelU/ma953aTcHvA
=head2 builds =head2 builds

View file

@ -157,21 +157,6 @@ __PACKAGE__->has_many(
undef, undef,
); );
=head2 jobs
Type: has_many
Related object: L<Hydra::Schema::Jobs>
=cut
__PACKAGE__->has_many(
"jobs",
"Hydra::Schema::Jobs",
{ "foreign.project" => "self.name" },
undef,
);
=head2 jobsetevals =head2 jobsetevals
Type: has_many Type: has_many
@ -273,8 +258,8 @@ Composing rels: L</projectmembers> -> username
__PACKAGE__->many_to_many("usernames", "projectmembers", "username"); __PACKAGE__->many_to_many("usernames", "projectmembers", "username");
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-06 12:32:57 # Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-27 17:40:41
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dEIVgrFGilPfITprs6nYuA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:iBGJjFWiI9Wy9zwT7xGOEA
my %hint = ( my %hint = (
columns => [ columns => [

View file

@ -56,7 +56,6 @@ __PACKAGE__->table("starredjobs");
=head2 job =head2 job
data_type: 'text' data_type: 'text'
is_foreign_key: 1
is_nullable: 0 is_nullable: 0
=cut =cut
@ -69,7 +68,7 @@ __PACKAGE__->add_columns(
"jobset", "jobset",
{ data_type => "text", is_foreign_key => 1, is_nullable => 0 }, { data_type => "text", is_foreign_key => 1, is_nullable => 0 },
"job", "job",
{ data_type => "text", is_foreign_key => 1, is_nullable => 0 }, { data_type => "text", is_nullable => 0 },
); );
=head1 PRIMARY KEY =head1 PRIMARY KEY
@ -92,21 +91,6 @@ __PACKAGE__->set_primary_key("username", "project", "jobset", "job");
=head1 RELATIONS =head1 RELATIONS
=head2 job
Type: belongs_to
Related object: L<Hydra::Schema::Jobs>
=cut
__PACKAGE__->belongs_to(
"job",
"Hydra::Schema::Jobs",
{ jobset => "jobset", name => "job", project => "project" },
{ is_deferrable => 0, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 jobset =head2 jobset
Type: belongs_to Type: belongs_to
@ -153,8 +137,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-02-06 12:22:36 # Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-05-27 17:36:07
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:fw4FfzmOhzDk0ZoSuNr2ww # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:RRDQ6UQL/bjXPD+HO1s5ug
# You can replace this text with custom code or comments, and it will be preserved on regeneration # You can replace this text with custom code or comments, and it will be preserved on regeneration

View file

@ -37,12 +37,8 @@ sub stripSSHUser {
# Check whether the given job is a member of the most recent jobset # Check whether the given job is a member of the most recent jobset
# evaluation. # evaluation.
sub jobExists { sub jobExists {
my ($self, $c, $job) = @_; my ($self, $c, $jobset, $jobName) = @_;
my $latestEval = $job->jobset->jobsetevals->search( return defined $jobset->builds->search({ job => $jobName, iscurrent => 1 })->single;
{ hasnewbuilds => 1},
{ rows => 1, order_by => ["id desc"] })->single;
return 0 if !defined $latestEval; # can't happen
return scalar($latestEval->builds->search({ job => $job->name })) != 0;
} }
1; 1;

View file

@ -1,5 +1,5 @@
[% WRAPPER layout.tt title="Latest builds" _ [% WRAPPER layout.tt title="Latest builds" _
(job ? " for job $project.name:$jobset.name:$job.name" : (job ? " for job $project.name:$jobset.name:$job" :
jobset ? " for jobset $project.name:$jobset.name" : jobset ? " for jobset $project.name:$jobset.name" :
project ? " for project $project.name" : "") %] project ? " for project $project.name" : "") %]
[% PROCESS common.tt %] [% PROCESS common.tt %]

View file

@ -1,4 +1,4 @@
[% WRAPPER layout.tt title="Build $id of job $project.name:$jobset.name:$job.name" %] [% WRAPPER layout.tt title="Build $id of job $project.name:$jobset.name:$job" %]
[% PROCESS common.tt %] [% PROCESS common.tt %]
[% PROCESS "product-list.tt" %] [% PROCESS "product-list.tt" %]
[% USE HTML %] [% USE HTML %]
@ -258,7 +258,7 @@ END;
<p class="error">Note: this build is no longer available.</p> <p class="error">Note: this build is no longer available.</p>
[% END %] [% END %]
[% INCLUDE renderProductList latestRoot=['/job' build.project.name build.jobset.name build.job.name 'latest'] %] [% INCLUDE renderProductList latestRoot=['/job' build.project.name build.jobset.name build.job 'latest'] %]
[% END %] [% END %]
@ -384,7 +384,7 @@ END;
<th>Output store paths:</th> <th>Output store paths:</th>
<td><tt>[% INCLUDE renderOutputs outputs=build.buildoutputs %]</tt></td> <td><tt>[% INCLUDE renderOutputs outputs=build.buildoutputs %]</tt></td>
</tr> </tr>
[% chartsURL = c.uri_for('/job' build.project.name build.jobset.name build.job.name) _ "#tabs-charts" %] [% chartsURL = c.uri_for('/job' build.project.name build.jobset.name build.job) _ "#tabs-charts" %]
[% IF build.finished && build.closuresize %] [% IF build.finished && build.closuresize %]
<tr> <tr>
<th>Closure size:</th> <th>Closure size:</th>
@ -425,7 +425,7 @@ END;
<tbody> <tbody>
[% FOREACH metric IN build.buildmetrics %] [% FOREACH metric IN build.buildmetrics %]
<tr> <tr>
<td><tt><a class="row-link" [% HTML.attributes(href => c.uri_for('/job' project.name jobset.name job.name 'metric' metric.name)) %]">[%HTML.escape(metric.name)%]</a></tt></td> <td><tt><a class="row-link" [% HTML.attributes(href => c.uri_for('/job' project.name jobset.name job 'metric' metric.name)) %]">[%HTML.escape(metric.name)%]</a></tt></td>
<td style="text-align: right">[%metric.value%]</td> <td style="text-align: right">[%metric.value%]</td>
<td>[%metric.unit%]</td> <td>[%metric.unit%]</td>
</tr> </tr>
@ -507,7 +507,7 @@ END;
running the following command:</p> running the following command:</p>
<pre> <pre>
<span class="shell-prompt"># </span>nix build [% HTML.escape(eval.flake) %]#hydraJobs.[% HTML.escape(job.name) %] <span class="shell-prompt"># </span>nix build [% HTML.escape(eval.flake) %]#hydraJobs.[% HTML.escape(job) %]
</pre> </pre>
[% ELSE %] [% ELSE %]

View file

@ -22,7 +22,7 @@
<tdata> <tdata>
[% FOREACH j IN starredJobs %] [% FOREACH j IN starredJobs %]
<tr> <tr>
<td><span class="[% IF !jobExists(j.job) %]disabled-job[% END %]">[% INCLUDE renderFullJobName project=j.job.get_column('project') jobset=j.job.get_column('jobset') job=j.job.name %]</span></td> <td><span class="[% IF !jobExists(j.job.jobset j.job.job) %]disabled-job[% END %]">[% INCLUDE renderFullJobName project=j.job.get_column('project') jobset=j.job.get_column('jobset') job=j.job.job %]</span></td>
[% FOREACH b IN j.builds %] [% FOREACH b IN j.builds %]
<td><a href="[% c.uri_for('/build' b.id) %]">[% INCLUDE renderBuildStatusIcon size=16 build=b %]</a></td> <td><a href="[% c.uri_for('/build' b.id) %]">[% INCLUDE renderBuildStatusIcon size=16 build=b %]</a></td>
[% END %] [% END %]

View file

@ -4,23 +4,23 @@
<h3>Build time (in seconds)</h3> <h3>Build time (in seconds)</h3>
[% INCLUDE createChart id="build-times" yaxis="sec" dataUrl=c.uri_for('/job' project.name jobset.name job.name 'build-times') %] [% INCLUDE createChart id="build-times" yaxis="sec" dataUrl=c.uri_for('/job' project.name jobset.name job 'build-times') %]
<h3>Closure size (in MiB)</h3> <h3>Closure size (in MiB)</h3>
[% INCLUDE createChart id="closure-size" yaxis="mib" dataUrl=c.uri_for('/job' project.name jobset.name job.name 'closure-sizes') %] [% INCLUDE createChart id="closure-size" yaxis="mib" dataUrl=c.uri_for('/job' project.name jobset.name job 'closure-sizes') %]
<h3>Output size (in MiB)</h3> <h3>Output size (in MiB)</h3>
[% INCLUDE createChart id="output-size" yaxis="mib" dataUrl=c.uri_for('/job' project.name jobset.name job.name 'output-sizes') %] [% INCLUDE createChart id="output-size" yaxis="mib" dataUrl=c.uri_for('/job' project.name jobset.name job 'output-sizes') %]
[% FOREACH metric IN metrics %] [% FOREACH metric IN metrics %]
<h3>Metric: <a [% HTML.attributes(href => c.uri_for('/job' project.name jobset.name job.name 'metric' metric.name)) %]><tt>[%HTML.escape(metric.name)%]</tt></a></h3> <h3>Metric: <a [% HTML.attributes(href => c.uri_for('/job' project.name jobset.name job 'metric' metric.name)) %]><tt>[%HTML.escape(metric.name)%]</tt></a></h3>
[% id = "metric-" _ metric.name; [% id = "metric-" _ metric.name;
id = id.replace('\.', '_'); id = id.replace('\.', '_');
INCLUDE createChart dataUrl=c.uri_for('/job' project.name jobset.name job.name 'metric' metric.name); %] INCLUDE createChart dataUrl=c.uri_for('/job' project.name jobset.name job 'metric' metric.name); %]
[% END %] [% END %]

View file

@ -1,5 +1,5 @@
[% WRAPPER layout.tt [% WRAPPER layout.tt
title="Job $project.name:$jobset.name:$job.name" title="Job $project.name:$jobset.name:$job"
starUri=c.uri_for(c.controller('Job').action_for('star'), c.req.captures) starUri=c.uri_for(c.controller('Job').action_for('star'), c.req.captures)
%] %]
[% PROCESS common.tt %] [% PROCESS common.tt %]
@ -7,7 +7,7 @@
[% INCLUDE includeFlot %] [% INCLUDE includeFlot %]
[% IF !jobExists(job) %] [% IF !jobExists(jobset, job) %]
<div class="alert alert-warning">This job is not a member of the <a <div class="alert alert-warning">This job is not a member of the <a
href="[%c.uri_for('/jobset' project.name jobset.name href="[%c.uri_for('/jobset' project.name jobset.name
'evals')%]">latest evaluation</a> of its jobset. This means it was 'evals')%]">latest evaluation</a> of its jobset. This means it was
@ -29,7 +29,7 @@ removed or had an evaluation error.</div>
[% IF lastBuilds.size != 0 %] [% IF lastBuilds.size != 0 %]
<h3>Latest builds</h3> <h3>Latest builds</h3>
[% INCLUDE renderBuildList builds=lastBuilds [% INCLUDE renderBuildList builds=lastBuilds
linkToAll=c.uri_for('/job' project.name jobset.name job.name 'all') %] linkToAll=c.uri_for('/job' project.name jobset.name job 'all') %]
[% END %] [% END %]
[% IF queuedBuilds.size != 0 %] [% IF queuedBuilds.size != 0 %]
<h3>Queued builds</h3> <h3>Queued builds</h3>
@ -84,12 +84,12 @@ removed or had an evaluation error.</div>
[% END %] [% END %]
[% INCLUDE makeLazyTab tabName="tabs-charts" uri=c.uri_for('/job' project.name jobset.name job.name 'metrics-tab') %] [% INCLUDE makeLazyTab tabName="tabs-charts" uri=c.uri_for('/job' project.name jobset.name job 'metrics-tab') %]
<div id="tabs-links" class="tab-pane"> <div id="tabs-links" class="tab-pane">
<ul> <ul>
<li><a href="[% c.uri_for('/job' project.name jobset.name job.name 'latest') %]">Latest successful build</a></li> <li><a href="[% c.uri_for('/job' project.name jobset.name job 'latest') %]">Latest successful build</a></li>
<li><a href="[% c.uri_for('/job' project.name jobset.name job.name 'latest-finished') %]">Latest successful build from a finished evaluation</a></li> <li><a href="[% c.uri_for('/job' project.name jobset.name job 'latest-finished') %]">Latest successful build from a finished evaluation</a></li>
</ul> </ul>
</div> </div>

View file

@ -67,7 +67,7 @@
<tbody> <tbody>
[% FOREACH j IN jobs %] [% FOREACH j IN jobs %]
<tr> <tr>
<td><span class="[% IF !j.get_column('enabled') %]disabled-job[% END %]">[% INCLUDE renderFullJobName project=j.get_column('project') jobset=j.get_column('jobset') job=j.name inRow=1 %]</span></td> <td><span>[% INCLUDE renderFullJobName project=j.get_column('project') jobset=j.get_column('jobset') job=j.job inRow=1 %]</span></td>
</tr> </tr>
[% END %] [% END %]
</tbody> </tbody>

View file

@ -65,15 +65,15 @@
[% IF job %] [% IF job %]
[% WRAPPER makeSubMenu title="Job" %] [% WRAPPER makeSubMenu title="Job" %]
<li class="nav-header">[% HTML.escape(job.name) %]</li> <li class="nav-header">[% HTML.escape(job) %]</li>
<li class="divider"></li> <li class="divider"></li>
[% INCLUDE menuItem [% INCLUDE menuItem
uri = c.uri_for(c.controller('Job').action_for('overview'), [project.name, jobset.name, job.name]) uri = c.uri_for(c.controller('Job').action_for('overview'), [project.name, jobset.name, job])
title = "Overview" %] title = "Overview" %]
[% INCLUDE menuItem [% INCLUDE menuItem
uri = c.uri_for(c.controller('Job').action_for('all'), [project.name, jobset.name, job.name]) uri = c.uri_for(c.controller('Job').action_for('all'), [project.name, jobset.name, job])
title = "Latest builds" %] title = "Latest builds" %]
[% INCLUDE menuItem uri = c.uri_for('/job' project.name jobset.name job.name 'channel' 'latest') title = "Channel" %] [% INCLUDE menuItem uri = c.uri_for('/job' project.name jobset.name job 'channel' 'latest') title = "Channel" %]
[% END %] [% END %]
[% END %] [% END %]

View file

@ -402,13 +402,6 @@ sub checkBuild {
my $build; my $build;
$db->txn_do(sub { $db->txn_do(sub {
my $job = $jobset->jobs->update_or_create({
name => $jobName,
jobset_id => $jobset->id,
project => $jobset->project,
jobset => $jobset->name,
});
# Don't add a build that has already been scheduled for this # Don't add a build that has already been scheduled for this
# job, or has been built but is still a "current" build for # job, or has been built but is still a "current" build for
# this job. Note that this means that if the sources of a job # this job. Note that this means that if the sources of a job
@ -452,11 +445,12 @@ sub checkBuild {
} }
# Add the build to the database. # Add the build to the database.
$build = $job->builds->create( $build = $jobset->builds->create(
{ timestamp => $time { timestamp => $time
, project => $jobset->project , project => $jobset->project
, jobset => $jobset->name , jobset => $jobset->name
, jobset_id => $jobset->id , jobset_id => $jobset->id
, job => $jobName
, description => null($buildInfo->{description}) , description => null($buildInfo->{description})
, license => null($buildInfo->{license}) , license => null($buildInfo->{license})
, homepage => null($buildInfo->{homepage}) , homepage => null($buildInfo->{homepage})

View file

@ -134,19 +134,6 @@ create table JobsetInputAlts (
); );
create table Jobs (
project text not null,
jobset text not null,
jobset_id integer not null,
name text not null,
primary key (project, jobset, name),
foreign key (jobset_id) references Jobsets(id) on delete cascade,
foreign key (project) references Projects(name) on delete cascade on update cascade,
foreign key (project, jobset) references Jobsets(project, name) on delete cascade on update cascade
);
create table Builds ( create table Builds (
id serial primary key not null, id serial primary key not null,
@ -226,8 +213,7 @@ create table Builds (
foreign key (jobset_id) references Jobsets(id) on delete cascade, foreign key (jobset_id) references Jobsets(id) on delete cascade,
foreign key (project) references Projects(name) on update cascade, foreign key (project) references Projects(name) on update cascade,
foreign key (project, jobset) references Jobsets(project, name) on update cascade, foreign key (project, jobset) references Jobsets(project, name) on update cascade
foreign key (project, jobset, job) references Jobs(project, jobset, name) on update cascade
); );
@ -371,8 +357,7 @@ create table BuildMetrics (
primary key (build, name), primary key (build, name),
foreign key (build) references Builds(id) on delete cascade, foreign key (build) references Builds(id) on delete cascade,
foreign key (project) references Projects(name) on update cascade, foreign key (project) references Projects(name) on update cascade,
foreign key (project, jobset) references Jobsets(project, name) on update cascade, foreign key (project, jobset) references Jobsets(project, name) on update cascade
foreign key (project, jobset, job) references Jobs(project, jobset, name) on update cascade
); );
@ -545,8 +530,7 @@ create table StarredJobs (
primary key (userName, project, jobset, job), primary key (userName, project, jobset, job),
foreign key (userName) references Users(userName) on update cascade on delete cascade, foreign key (userName) references Users(userName) on update cascade on delete cascade,
foreign key (project) references Projects(name) on update cascade on delete cascade, foreign key (project) references Projects(name) on update cascade on delete cascade,
foreign key (project, jobset) references Jobsets(project, name) on update cascade on delete cascade, foreign key (project, jobset) references Jobsets(project, name) on update cascade on delete cascade
foreign key (project, jobset, job) references Jobs(project, jobset, name) on update cascade on delete cascade
); );

View file

@ -22,7 +22,6 @@ make_schema_at("Hydra::Schema", {
"cachedpathinputs" => "CachedPathInputs", "cachedpathinputs" => "CachedPathInputs",
"cachedsubversioninputs" => "CachedSubversionInputs", "cachedsubversioninputs" => "CachedSubversionInputs",
"failedpaths" => "FailedPaths", "failedpaths" => "FailedPaths",
"jobs" => "Jobs",
"jobsetevalinputs" => "JobsetEvalInputs", "jobsetevalinputs" => "JobsetEvalInputs",
"jobsetevalmembers" => "JobsetEvalMembers", "jobsetevalmembers" => "JobsetEvalMembers",
"jobsetevals" => "JobsetEvals", "jobsetevals" => "JobsetEvals",

4
src/sql/upgrade-67.sql Normal file
View file

@ -0,0 +1,4 @@
alter table Builds drop constraint builds_project_fkey2;
alter table BuildMetrics drop constraint buildmetrics_project_fkey2;
alter table StarredJobs drop constraint starredjobs_project_fkey2;
drop table Jobs;

View file

@ -25,10 +25,10 @@ ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exi
ok(nrQueuedBuildsForJobset($jobset) == 3 , "Evaluating jobs/basic.nix should result in 3 builds"); ok(nrQueuedBuildsForJobset($jobset) == 3 , "Evaluating jobs/basic.nix should result in 3 builds");
for my $build (queuedBuildsForJobset($jobset)) { for my $build (queuedBuildsForJobset($jobset)) {
ok(runBuild($build), "Build '".$build->job->name."' from jobs/basic.nix should exit with code 0"); ok(runBuild($build), "Build '".$build->job."' from jobs/basic.nix should exit with code 0");
my $newbuild = $db->resultset('Builds')->find($build->id); my $newbuild = $db->resultset('Builds')->find($build->id);
my $expected = $build->job->name eq "fails" ? 1 : $build->job->name =~ /with_failed/ ? 6 : 0; my $expected = $build->job eq "fails" ? 1 : $build->job =~ /with_failed/ ? 6 : 0;
ok($newbuild->finished == 1 && $newbuild->buildstatus == $expected, "Build '".$build->job->name."' from jobs/basic.nix should have buildstatus $expected"); ok($newbuild->finished == 1 && $newbuild->buildstatus == $expected, "Build '".$build->job."' from jobs/basic.nix should have buildstatus $expected");
} }
# Test jobset with 2 jobs, one has parameter of succeeded build of the other # Test jobset with 2 jobs, one has parameter of succeeded build of the other
@ -37,17 +37,17 @@ $jobset = createJobsetWithOneInput("build-output-as-input", "build-output-as-inp
ok(evalSucceeds($jobset), "Evaluating jobs/build-output-as-input.nix should exit with return code 0"); ok(evalSucceeds($jobset), "Evaluating jobs/build-output-as-input.nix should exit with return code 0");
ok(nrQueuedBuildsForJobset($jobset) == 1 , "Evaluating jobs/build-output-as-input.nix for first time should result in 1 build in queue"); ok(nrQueuedBuildsForJobset($jobset) == 1 , "Evaluating jobs/build-output-as-input.nix for first time should result in 1 build in queue");
for my $build (queuedBuildsForJobset($jobset)) { for my $build (queuedBuildsForJobset($jobset)) {
ok(runBuild($build), "Build '".$build->job->name."' from jobs/basic.nix should exit with code 0"); ok(runBuild($build), "Build '".$build->job."' from jobs/basic.nix should exit with code 0");
my $newbuild = $db->resultset('Builds')->find($build->id); my $newbuild = $db->resultset('Builds')->find($build->id);
ok($newbuild->finished == 1 && $newbuild->buildstatus == 0, "Build '".$build->job->name."' from jobs/basic.nix should have buildstatus 0"); ok($newbuild->finished == 1 && $newbuild->buildstatus == 0, "Build '".$build->job."' from jobs/basic.nix should have buildstatus 0");
} }
ok(evalSucceeds($jobset), "Evaluating jobs/build-output-as-input.nix for second time should exit with return code 0"); ok(evalSucceeds($jobset), "Evaluating jobs/build-output-as-input.nix for second time should exit with return code 0");
ok(nrQueuedBuildsForJobset($jobset) == 1 , "Evaluating jobs/build-output-as-input.nix for second time after building build1 should result in 1 build in queue"); ok(nrQueuedBuildsForJobset($jobset) == 1 , "Evaluating jobs/build-output-as-input.nix for second time after building build1 should result in 1 build in queue");
for my $build (queuedBuildsForJobset($jobset)) { for my $build (queuedBuildsForJobset($jobset)) {
ok(runBuild($build), "Build '".$build->job->name."' from jobs/basic.nix should exit with code 0"); ok(runBuild($build), "Build '".$build->job."' from jobs/basic.nix should exit with code 0");
my $newbuild = $db->resultset('Builds')->find($build->id); my $newbuild = $db->resultset('Builds')->find($build->id);
ok($newbuild->finished == 1 && $newbuild->buildstatus == 0, "Build '".$build->job->name."' from jobs/basic.nix should have buildstatus 0"); ok($newbuild->finished == 1 && $newbuild->buildstatus == 0, "Build '".$build->job."' from jobs/basic.nix should have buildstatus 0");
} }
@ -158,16 +158,16 @@ ok(evalSucceeds($jobset), "Evaluating jobs/build-products.nix s
ok(nrQueuedBuildsForJobset($jobset) == 2 , "Evaluating jobs/build-products.nix should result in 2 builds"); ok(nrQueuedBuildsForJobset($jobset) == 2 , "Evaluating jobs/build-products.nix should result in 2 builds");
for my $build (queuedBuildsForJobset($jobset)) { for my $build (queuedBuildsForJobset($jobset)) {
ok(runBuild($build), "Build '".$build->job->name."' from jobs/build-products.nix should exit with code 0"); ok(runBuild($build), "Build '".$build->job."' from jobs/build-products.nix should exit with code 0");
my $newbuild = $db->resultset('Builds')->find($build->id); my $newbuild = $db->resultset('Builds')->find($build->id);
ok($newbuild->finished == 1 && $newbuild->buildstatus == 0, "Build '".$build->job->name."' from jobs/build-products.nix should have buildstatus 0"); ok($newbuild->finished == 1 && $newbuild->buildstatus == 0, "Build '".$build->job."' from jobs/build-products.nix should have buildstatus 0");
my $buildproducts = $db->resultset('BuildProducts')->search({ build => $build->id }); my $buildproducts = $db->resultset('BuildProducts')->search({ build => $build->id });
my $buildproduct = $buildproducts->next; my $buildproduct = $buildproducts->next;
if($build->job->name eq "simple") { if($build->job eq "simple") {
ok($buildproduct->name eq "text.txt", "We should have text.txt, but found: ".$buildproduct->name."\n"); ok($buildproduct->name eq "text.txt", "We should have text.txt, but found: ".$buildproduct->name."\n");
} elsif ($build->job->name eq "with_spaces") { } elsif ($build->job eq "with_spaces") {
ok($buildproduct->name eq "some text.txt", "We should have: \"some text.txt\", but found: ".$buildproduct->name."\n"); ok($buildproduct->name eq "some text.txt", "We should have: \"some text.txt\", but found: ".$buildproduct->name."\n");
} }
} }