Tests: restructure to more closely mirror the sources
t/ had lots of directories and files mirroring src/lib/Hydra. This moves those files under t/Hydra
This commit is contained in:
133
t/Hydra/Controller/Admin/clear-queue-non-current.t
Normal file
133
t/Hydra/Controller/Admin/clear-queue-non-current.t
Normal file
@ -0,0 +1,133 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
use File::Copy;
|
||||
|
||||
my %ctx = test_init(
|
||||
hydra_config => q|
|
||||
# No caching for PathInput plugin, otherwise we get wrong values
|
||||
# (as it has a 30s window where no changes to the file are considered).
|
||||
path_input_cache_validity_seconds = 0
|
||||
|
|
||||
);
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
use HTTP::Request::Common qw(POST PUT GET DELETE);
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# Create a user to log in to
|
||||
my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' });
|
||||
$user->setPassword('foobar');
|
||||
$user->userroles->update_or_create({ role => 'admin' });
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => 'tests', displayname => 'Tests', owner => 'alice'});
|
||||
|
||||
my $scratchdir = $ctx{tmpdir} . "/scratch";
|
||||
my $jobset = createBaseJobset("basic", "default.nix", $scratchdir);
|
||||
|
||||
subtest "Create and evaluate our job at version 1" => sub {
|
||||
mkdir $scratchdir or die "mkdir($scratchdir): $!\n";
|
||||
|
||||
# Note: this recreates the raw derivation and skips
|
||||
# the generated config.nix because we never actually
|
||||
# build anything.
|
||||
open(my $fh, ">", "$scratchdir/default.nix");
|
||||
print $fh <<EOF;
|
||||
{
|
||||
example = derivation {
|
||||
builder = "./builder.sh";
|
||||
name = "example";
|
||||
system = builtins.currentSystem;
|
||||
version = 1;
|
||||
};
|
||||
}
|
||||
EOF
|
||||
close($fh);
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating our default.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 1, "Evaluating our default.nix should result in 1 builds");
|
||||
};
|
||||
|
||||
subtest "Update and evaluate our job to version 2" => sub {
|
||||
open(my $fh, ">", "$scratchdir/default.nix");
|
||||
print $fh <<EOF;
|
||||
{
|
||||
example = derivation {
|
||||
builder = "./builder.sh";
|
||||
name = "example";
|
||||
system = builtins.currentSystem;
|
||||
version = 2;
|
||||
};
|
||||
}
|
||||
EOF
|
||||
close($fh);
|
||||
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating our default.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 2, "Evaluating our default.nix should result in 1 more build, resulting in 2 queued builds");
|
||||
};
|
||||
|
||||
my ($firstBuild, $secondBuild, @builds) = queuedBuildsForJobset($jobset)->search(
|
||||
{},
|
||||
{ order_by => { -asc => 'id' }}
|
||||
);
|
||||
subtest "Validating the first build" => sub {
|
||||
isnt($firstBuild, undef, "We have our first build");
|
||||
is($firstBuild->id, 1, "The first build is ID 1");
|
||||
is($firstBuild->finished, 0, "The first build is not yet finished");
|
||||
is($firstBuild->buildstatus, undef, "The first build status is null");
|
||||
};
|
||||
|
||||
subtest "Validating the second build" => sub {
|
||||
isnt($secondBuild, undef, "We have our second build");
|
||||
is($secondBuild->id, 2, "The second build is ID 2");
|
||||
is($secondBuild->finished, 0, "The second build is not yet finished");
|
||||
is($secondBuild->buildstatus, undef, "The second build status is null");
|
||||
};
|
||||
|
||||
is(@builds, 0, "No other builds were created");
|
||||
|
||||
# Login and save cookie for future requests
|
||||
my $req = request(POST '/login',
|
||||
Referer => 'http://localhost/',
|
||||
Content => {
|
||||
username => 'alice',
|
||||
password => 'foobar'
|
||||
}
|
||||
);
|
||||
is($req->code, 302, "Logging in gets a 302");
|
||||
my $cookie = $req->header("set-cookie");
|
||||
|
||||
subtest 'Cancel queued, non-current builds' => sub {
|
||||
my $restart = request(PUT '/admin/clear-queue-non-current',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Referer => '/admin/example-referer',
|
||||
Cookie => $cookie,
|
||||
);
|
||||
is($restart->code, 302, "Canceling 302's back to the build");
|
||||
is($restart->header("location"), "/admin/example-referer", "We're redirected back to the referer");
|
||||
};
|
||||
|
||||
subtest "Validating the first build is canceled" => sub {
|
||||
my $build = $db->resultset('Builds')->find($firstBuild->id);
|
||||
is($build->finished, 1, "Build should be 'finished'.");
|
||||
is($build->buildstatus, 4, "Build should be canceled.");
|
||||
};
|
||||
|
||||
subtest "Validating the second build is not canceled" => sub {
|
||||
my $build = $db->resultset('Builds')->find($secondBuild->id);
|
||||
is($build->finished, 0, "Build should be unfinished.");
|
||||
is($build->buildstatus, undef, "Build status should be null.");
|
||||
};
|
||||
|
||||
done_testing;
|
67
t/Hydra/Controller/Build/cancel.t
Normal file
67
t/Hydra/Controller/Build/cancel.t
Normal file
@ -0,0 +1,67 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
use HTTP::Request::Common qw(POST PUT GET DELETE);
|
||||
|
||||
# This test verifies that creating, reading, updating, and deleting a jobset via
|
||||
# the HTTP API works as expected.
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# Create a user to log in to
|
||||
my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' });
|
||||
$user->setPassword('foobar');
|
||||
$user->userroles->update_or_create({ role => 'admin' });
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => 'tests', displayname => 'Tests', owner => 'alice'});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/basic.nix should result in 3 builds");
|
||||
|
||||
my ($build, @builds) = queuedBuildsForJobset($jobset);
|
||||
is($build->finished, 0, "Unbuilt build should not be finished.");
|
||||
is($build->buildstatus, undef, "Unbuilt build should be undefined.");
|
||||
|
||||
|
||||
# Login and save cookie for future requests
|
||||
my $req = request(POST '/login',
|
||||
Referer => 'http://localhost/',
|
||||
Content => {
|
||||
username => 'alice',
|
||||
password => 'foobar'
|
||||
}
|
||||
);
|
||||
is($req->code, 302, "Logging in gets a 302");
|
||||
my $cookie = $req->header("set-cookie");
|
||||
|
||||
|
||||
subtest 'Cancel the build' => sub {
|
||||
my $restart = request(PUT '/build/' . $build->id . '/cancel',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
);
|
||||
is($restart->code, 302, "Restarting 302's back to the build");
|
||||
is($restart->header("location"), "http://localhost/build/" . $build->id);
|
||||
|
||||
my $newbuild = $db->resultset('Builds')->find($build->id);
|
||||
is($newbuild->finished, 1, "Build 'fails' from jobs/basic.nix should be 'finished'.");
|
||||
is($newbuild->buildstatus, 4, "Build 'fails' from jobs/basic.nix should be canceled.");
|
||||
};
|
||||
|
||||
done_testing;
|
47
t/Hydra/Controller/Build/constituents.t
Normal file
47
t/Hydra/Controller/Build/constituents.t
Normal file
@ -0,0 +1,47 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
use Data::Dumper;
|
||||
use URI;
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
use HTTP::Request::Common;
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
my $jobset = createBaseJobset("aggregate", "aggregate.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/aggregate.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/aggregate.nix should result in 3 builds");
|
||||
for my $build (queuedBuildsForJobset($jobset)) {
|
||||
ok(runBuild($build), "Build '".$build->job."' from jobs/aggregate.nix should exit with return code 0");
|
||||
}
|
||||
|
||||
my $build_redirect = request(GET '/job/tests/aggregate/aggregate/latest-finished');
|
||||
|
||||
my $url = URI->new($build_redirect->header('location'))->path . "/constituents";
|
||||
my $constituents = request(GET $url,
|
||||
Accept => 'application/json',
|
||||
);
|
||||
|
||||
ok($constituents->is_success, "Getting the constituent builds");
|
||||
my $data = decode_json($constituents->content);
|
||||
|
||||
my ($buildA) = grep { $_->{nixname} eq "empty-dir-a" } @$data;
|
||||
my ($buildB) = grep { $_->{nixname} eq "empty-dir-b" } @$data;
|
||||
|
||||
is($buildA->{job}, "a");
|
||||
is($buildB->{job}, "b");
|
||||
|
||||
done_testing;
|
34
t/Hydra/Controller/Build/evals.t
Normal file
34
t/Hydra/Controller/Build/evals.t
Normal file
@ -0,0 +1,34 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use Data::Dumper;
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
use HTTP::Request::Common;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/basic.nix should result in 3 builds");
|
||||
my ($build, @builds) = queuedBuildsForJobset($jobset);
|
||||
|
||||
ok(runBuild($build), "Build '".$build->job."' from jobs/basic.nix should exit with return code 0");
|
||||
|
||||
subtest "/build/ID/evals" => sub {
|
||||
my $evals = request(GET '/build/' . $build->id . '/evals');
|
||||
ok($evals->is_success, "The page listing evaluations this build is part of returns 200.");
|
||||
};
|
||||
|
||||
done_testing;
|
76
t/Hydra/Controller/Build/restart.t
Normal file
76
t/Hydra/Controller/Build/restart.t
Normal file
@ -0,0 +1,76 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
use HTTP::Request::Common qw(POST PUT GET DELETE);
|
||||
|
||||
# This test verifies that creating, reading, updating, and deleting a jobset via
|
||||
# the HTTP API works as expected.
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# Create a user to log in to
|
||||
my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' });
|
||||
$user->setPassword('foobar');
|
||||
$user->userroles->update_or_create({ role => 'admin' });
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => 'tests', displayname => 'Tests', owner => 'alice'});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/basic.nix should result in 3 builds");
|
||||
|
||||
my $failing;
|
||||
for my $build (queuedBuildsForJobset($jobset)) {
|
||||
ok(runBuild($build), "Build '".$build->job."' from jobs/basic.nix should exit with return code 0");
|
||||
my $newbuild = $db->resultset('Builds')->find($build->id);
|
||||
is($newbuild->finished, 1, "Build '".$build->job."' from jobs/basic.nix should be finished.");
|
||||
|
||||
if ($build->job eq "fails") {
|
||||
is($newbuild->buildstatus, 1, "Build 'fails' from jobs/basic.nix should have buildstatus 1.");
|
||||
$failing = $build;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
isnt($failing, undef, "We should have the failing build to restart");
|
||||
|
||||
# Login and save cookie for future requests
|
||||
my $req = request(POST '/login',
|
||||
Referer => 'http://localhost/',
|
||||
Content => {
|
||||
username => 'alice',
|
||||
password => 'foobar'
|
||||
}
|
||||
);
|
||||
is($req->code, 302, "Logging in gets a 302");
|
||||
my $cookie = $req->header("set-cookie");
|
||||
|
||||
|
||||
subtest 'Restart the failing build' => sub {
|
||||
my $restart = request(PUT '/build/' . $failing->id . '/restart',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
);
|
||||
is($restart->code, 302, "Restarting 302's back to the build");
|
||||
is($restart->header("location"), "http://localhost/build/" . $failing->id);
|
||||
|
||||
my $newbuild = $db->resultset('Builds')->find($failing->id);
|
||||
is($newbuild->finished, 0, "Build 'fails' from jobs/basic.nix should not be finished.");
|
||||
};
|
||||
|
||||
done_testing;
|
65
t/Hydra/Controller/Jobset/channel.t
Normal file
65
t/Hydra/Controller/Jobset/channel.t
Normal file
@ -0,0 +1,65 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use IO::Uncompress::Bunzip2 qw(bunzip2);
|
||||
use Archive::Tar;
|
||||
use JSON::MaybeXS qw(decode_json);
|
||||
use Data::Dumper;
|
||||
my %ctx = test_init(
|
||||
use_external_destination_store => 0
|
||||
);
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
# Most basic test case, no parameters
|
||||
my $jobset = createBaseJobset("nested-attributes", "nested-attributes.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset));
|
||||
is(nrQueuedBuildsForJobset($jobset), 4);
|
||||
|
||||
for my $build (queuedBuildsForJobset($jobset)) {
|
||||
ok(runBuild($build), "Build '".$build->job."' should exit with return code 0");
|
||||
my $newbuild = $db->resultset('Builds')->find($build->id);
|
||||
is($newbuild->finished, 1, "Build '".$build->job."' should be finished.");
|
||||
is($newbuild->buildstatus, 0, "Build '".$build->job."' should have buildstatus 0.");
|
||||
}
|
||||
|
||||
my $compressed = get('/jobset/tests/nested-attributes/channel/latest/nixexprs.tar.bz2');
|
||||
my $tarcontent;
|
||||
bunzip2(\$compressed => \$tarcontent);
|
||||
open(my $tarfh, "<", \$tarcontent);
|
||||
my $tar = Archive::Tar->new($tarfh);
|
||||
|
||||
my $defaultnix = $ctx{"tmpdir"} . "/channel-default.nix";
|
||||
$tar->extract_file("channel/default.nix", $defaultnix);
|
||||
|
||||
print STDERR $tar->get_content("channel/default.nix");
|
||||
|
||||
(my $status, my $stdout, my $stderr) = Hydra::Helper::Nix::captureStdoutStderr(5, "nix-env", "--json", "--query", "--available", "--attr-path", "--file", $defaultnix);
|
||||
is($stderr, "", "Stderr should be empty");
|
||||
is($status, 0, "Querying the packages should succeed");
|
||||
|
||||
my $packages = decode_json($stdout);
|
||||
my $keys = [sort keys %$packages];
|
||||
is($keys, [
|
||||
"packageset-nested",
|
||||
"packageset.deeper.deeper.nested",
|
||||
"packageset.nested",
|
||||
"packageset.nested2",
|
||||
]);
|
||||
is($packages->{"packageset-nested"}->{"name"}, "actually-top-level");
|
||||
is($packages->{"packageset.nested"}->{"name"}, "actually-nested");
|
||||
|
||||
done_testing;
|
35
t/Hydra/Controller/Jobset/evals.t
Normal file
35
t/Hydra/Controller/Jobset/evals.t
Normal file
@ -0,0 +1,35 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use Data::Dumper;
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
use HTTP::Request::Common;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
|
||||
subtest "/jobset/PROJECT/JOBSET" => sub {
|
||||
my $jobset = request(GET '/jobset/' . $project->name . '/' . $jobset->name);
|
||||
ok($jobset->is_success, "The page showing the jobset returns 200.");
|
||||
};
|
||||
|
||||
subtest "/jobset/PROJECT/JOBSET/evals" => sub {
|
||||
my $jobsetevals = request(GET '/jobset/' . $project->name . '/' . $jobset->name . '/evals');
|
||||
ok($jobsetevals->is_success, "The page showing the jobset evals returns 200.");
|
||||
};
|
||||
|
||||
done_testing;
|
205
t/Hydra/Controller/Jobset/http.t
Normal file
205
t/Hydra/Controller/Jobset/http.t
Normal file
@ -0,0 +1,205 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
use HTTP::Request::Common qw(POST PUT GET DELETE);
|
||||
|
||||
# This test verifies that creating, reading, updating, and deleting a jobset via
|
||||
# the HTTP API works as expected.
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# Create a user to log in to
|
||||
my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' });
|
||||
$user->setPassword('foobar');
|
||||
$user->userroles->update_or_create({ role => 'admin' });
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => 'tests', displayname => 'Tests', owner => 'alice'});
|
||||
|
||||
# Login and save cookie for future requests
|
||||
my $req = request(POST '/login',
|
||||
Referer => 'http://localhost/',
|
||||
Content => {
|
||||
username => 'alice',
|
||||
password => 'foobar'
|
||||
}
|
||||
);
|
||||
is($req->code, 302);
|
||||
my $cookie = $req->header("set-cookie");
|
||||
|
||||
|
||||
subtest 'Create new jobset "job" as flake type' => sub {
|
||||
my $jobsetcreate = request(PUT '/jobset/tests/job',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
Content => encode_json({
|
||||
enabled => 2,
|
||||
visible => JSON::MaybeXS::true,
|
||||
name => "job",
|
||||
type => 1,
|
||||
description => "test jobset",
|
||||
flake => "github:nixos/nix",
|
||||
checkinterval => 0,
|
||||
schedulingshares => 100,
|
||||
keepnr => 3
|
||||
})
|
||||
);
|
||||
ok($jobsetcreate->is_success);
|
||||
is($jobsetcreate->header("location"), "http://localhost/jobset/tests/job");
|
||||
};
|
||||
|
||||
|
||||
subtest 'Read newly-created jobset "job"' => sub {
|
||||
my $jobsetinfo = request(GET '/jobset/tests/job',
|
||||
Accept => 'application/json',
|
||||
);
|
||||
ok($jobsetinfo->is_success);
|
||||
is(decode_json($jobsetinfo->content), {
|
||||
checkinterval => 0,
|
||||
description => "test jobset",
|
||||
emailoverride => "",
|
||||
enabled => 2,
|
||||
enableemail => JSON::MaybeXS::false,
|
||||
errortime => undef,
|
||||
errormsg => "",
|
||||
fetcherrormsg => "",
|
||||
flake => "github:nixos/nix",
|
||||
visible => JSON::MaybeXS::true,
|
||||
inputs => {},
|
||||
keepnr => 3,
|
||||
lastcheckedtime => undef,
|
||||
name => "job",
|
||||
nixexprinput => "",
|
||||
nixexprpath => "",
|
||||
project => "tests",
|
||||
schedulingshares => 100,
|
||||
starttime => undef,
|
||||
triggertime => undef,
|
||||
type => 1
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
subtest 'Update jobset "job" to legacy type' => sub {
|
||||
my $jobsetupdate = request(PUT '/jobset/tests/job',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
Content => encode_json({
|
||||
enabled => 3,
|
||||
visible => JSON::MaybeXS::true,
|
||||
name => "job",
|
||||
type => 0,
|
||||
nixexprinput => "ofborg",
|
||||
nixexprpath => "release.nix",
|
||||
inputs => {
|
||||
ofborg => {
|
||||
name => "ofborg",
|
||||
type => "git",
|
||||
value => "https://github.com/NixOS/ofborg.git released"
|
||||
}
|
||||
},
|
||||
description => "test jobset",
|
||||
checkinterval => 0,
|
||||
schedulingshares => 50,
|
||||
keepnr => 1
|
||||
})
|
||||
);
|
||||
ok($jobsetupdate->is_success);
|
||||
|
||||
# Read newly-updated jobset "job"
|
||||
my $jobsetinfo = request(GET '/jobset/tests/job',
|
||||
Accept => 'application/json',
|
||||
);
|
||||
ok($jobsetinfo->is_success);
|
||||
is(decode_json($jobsetinfo->content), {
|
||||
checkinterval => 0,
|
||||
description => "test jobset",
|
||||
emailoverride => "",
|
||||
enabled => 3,
|
||||
enableemail => JSON::MaybeXS::false,
|
||||
errortime => undef,
|
||||
errormsg => "",
|
||||
fetcherrormsg => "",
|
||||
flake => "",
|
||||
visible => JSON::MaybeXS::true,
|
||||
inputs => {
|
||||
ofborg => {
|
||||
name => "ofborg",
|
||||
type => "git",
|
||||
emailresponsible => JSON::MaybeXS::false,
|
||||
value => "https://github.com/NixOS/ofborg.git released"
|
||||
}
|
||||
},
|
||||
keepnr => 1,
|
||||
lastcheckedtime => undef,
|
||||
name => "job",
|
||||
nixexprinput => "ofborg",
|
||||
nixexprpath => "release.nix",
|
||||
project => "tests",
|
||||
schedulingshares => 50,
|
||||
starttime => undef,
|
||||
triggertime => undef,
|
||||
type => 0
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
subtest 'Update jobset "job" to have an invalid input type' => sub {
|
||||
my $jobsetupdate = request(PUT '/jobset/tests/job',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
Content => encode_json({
|
||||
enabled => 3,
|
||||
visible => JSON::MaybeXS::true,
|
||||
name => "job",
|
||||
type => 0,
|
||||
nixexprinput => "ofborg",
|
||||
nixexprpath => "release.nix",
|
||||
inputs => {
|
||||
ofborg => {
|
||||
name => "ofborg",
|
||||
type => "123",
|
||||
value => "https://github.com/NixOS/ofborg.git released"
|
||||
}
|
||||
},
|
||||
description => "test jobset",
|
||||
checkinterval => 0,
|
||||
schedulingshares => 50,
|
||||
keepnr => 1
|
||||
})
|
||||
);
|
||||
ok(!$jobsetupdate->is_success);
|
||||
ok($jobsetupdate->content =~ m/Invalid input type.*valid types:/);
|
||||
};
|
||||
|
||||
|
||||
subtest 'Delete jobset "job"' => sub {
|
||||
my $jobsetinfo = request(DELETE '/jobset/tests/job',
|
||||
Accept => 'application/json',
|
||||
Cookie => $cookie
|
||||
);
|
||||
ok($jobsetinfo->is_success);
|
||||
|
||||
# Jobset "job" should no longer exist.
|
||||
$jobsetinfo = request(GET '/jobset/tests/job',
|
||||
Accept => 'application/json',
|
||||
);
|
||||
ok(!$jobsetinfo->is_success);
|
||||
};
|
||||
|
||||
done_testing;
|
123
t/Hydra/Controller/Jobset/type-constraints.t
Normal file
123
t/Hydra/Controller/Jobset/type-constraints.t
Normal file
@ -0,0 +1,123 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Data::Dumper;
|
||||
use Test2::V0;
|
||||
use Test2::Compare qw(compare strict_convert);
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# This test checks a matrix of jobset configuration options for constraint violations.
|
||||
|
||||
my @types = ( 0, 1, 2 );
|
||||
my @nixexprinputs = ( undef, "input" );
|
||||
my @nixexprpaths = ( undef, "path" );
|
||||
my @flakes = ( undef, "flake" );
|
||||
|
||||
my @expected_failing;
|
||||
my @expected_succeeding = (
|
||||
{
|
||||
"name" => "test",
|
||||
"emailoverride" => "",
|
||||
"type" => 0,
|
||||
"nixexprinput" => "input",
|
||||
"nixexprpath" => "path",
|
||||
"flake" => undef,
|
||||
},
|
||||
{
|
||||
"name" => "test",
|
||||
"emailoverride" => "",
|
||||
"type" => 1,
|
||||
"nixexprinput" => undef,
|
||||
"nixexprpath" => undef,
|
||||
"flake" => "flake",
|
||||
},
|
||||
);
|
||||
|
||||
# Checks if two Perl hashes (in scalar context) contain the same data.
|
||||
# Returns 0 if they are different and 1 if they are the same.
|
||||
sub test_scenario_matches {
|
||||
my ($first, $second) = @_;
|
||||
|
||||
my $ret = compare($first, $second, \&strict_convert);
|
||||
|
||||
if (defined $ret == 1) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Construct a matrix of parameters that should violate the Jobsets table's constraints.
|
||||
foreach my $type (@types) {
|
||||
foreach my $nixexprinput (@nixexprinputs) {
|
||||
foreach my $nixexprpath (@nixexprpaths) {
|
||||
foreach my $flake (@flakes) {
|
||||
my $hash = {
|
||||
"name" => "test",
|
||||
"emailoverride" => "",
|
||||
"type" => $type,
|
||||
"nixexprinput" => $nixexprinput,
|
||||
"nixexprpath" => $nixexprpath,
|
||||
"flake" => $flake,
|
||||
};
|
||||
|
||||
push(@expected_failing, $hash) if (!grep { test_scenario_matches($_, $hash) } @expected_succeeding);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
# Validate that the list of parameters that should fail the constraints do indeed fail.
|
||||
subtest "Expected constraint failures" => sub {
|
||||
my $count = 1;
|
||||
foreach my $case (@expected_failing) {
|
||||
subtest "Case $count: " . Dumper ($case) => sub {
|
||||
dies {
|
||||
# Necessary, otherwise cases will fail because the `->create`
|
||||
# will throw an exception due to an expected constraint failure
|
||||
# (which will cause the `ok()` to be skipped, leading to no
|
||||
# assertions in the subtest).
|
||||
is(1, 1);
|
||||
|
||||
ok(
|
||||
!$project->jobsets->create($case),
|
||||
"Expected jobset to violate constraints"
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
$count++;
|
||||
};
|
||||
};
|
||||
|
||||
# Validate that the list of parameters that should not fail the constraints do indeed succeed.
|
||||
subtest "Expected constraint successes" => sub {
|
||||
my $count = 1;
|
||||
foreach my $case (@expected_succeeding) {
|
||||
subtest "Case $count: " . Dumper ($case) => sub {
|
||||
my $jobset = $project->jobsets->create($case);
|
||||
|
||||
ok(
|
||||
$jobset,
|
||||
"Expected jobset to not violate constraints"
|
||||
);
|
||||
|
||||
# Delete the jobset so the next jobset won't violate the name constraint.
|
||||
$jobset->delete;
|
||||
};
|
||||
|
||||
$count++;
|
||||
};
|
||||
};
|
||||
|
||||
done_testing;
|
67
t/Hydra/Controller/JobsetEval/cancel.t
Normal file
67
t/Hydra/Controller/JobsetEval/cancel.t
Normal file
@ -0,0 +1,67 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
use HTTP::Request::Common qw(POST PUT GET DELETE);
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# Create a user to log in to
|
||||
my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' });
|
||||
$user->setPassword('foobar');
|
||||
$user->userroles->update_or_create({ role => 'admin' });
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => 'tests', displayname => 'Tests', owner => 'alice'});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/basic.nix should result in 3 builds");
|
||||
|
||||
my ($eval, @evals) = $jobset->jobsetevals;
|
||||
isnt($eval, undef, "We have an evaluation to restart");
|
||||
|
||||
my ($build, @builds) = queuedBuildsForJobset($jobset);
|
||||
is($build->finished, 0, "Unbuilt build should not be finished.");
|
||||
is($build->buildstatus, undef, "Unbuilt build should be undefined.");
|
||||
|
||||
|
||||
# Login and save cookie for future requests
|
||||
my $req = request(POST '/login',
|
||||
Referer => 'http://localhost/',
|
||||
Content => {
|
||||
username => 'alice',
|
||||
password => 'foobar'
|
||||
}
|
||||
);
|
||||
is($req->code, 302, "Logging in gets a 302");
|
||||
my $cookie = $req->header("set-cookie");
|
||||
|
||||
|
||||
subtest 'Cancel the JobsetEval builds' => sub {
|
||||
my $restart = request(PUT '/eval/' . $eval->id . '/cancel',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
);
|
||||
is($restart->code, 302, "Canceling 302's back to the build");
|
||||
is($restart->header("location"), "http://localhost/eval/" . $eval->id, "We're redirected back to the eval page");
|
||||
|
||||
my $newbuild = $db->resultset('Builds')->find($build->id);
|
||||
is($newbuild->finished, 1, "Build 'fails' from jobs/basic.nix should be 'finished'.");
|
||||
is($newbuild->buildstatus, 4, "Build 'fails' from jobs/basic.nix should be canceled.");
|
||||
};
|
||||
|
||||
done_testing;
|
100
t/Hydra/Controller/JobsetEval/restart.t
Normal file
100
t/Hydra/Controller/JobsetEval/restart.t
Normal file
@ -0,0 +1,100 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
use HTTP::Request::Common qw(POST PUT GET DELETE);
|
||||
|
||||
# This test verifies that creating, reading, updating, and deleting a jobset via
|
||||
# the HTTP API works as expected.
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# Create a user to log in to
|
||||
my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' });
|
||||
$user->setPassword('foobar');
|
||||
$user->userroles->update_or_create({ role => 'admin' });
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => 'tests', displayname => 'Tests', owner => 'alice'});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/basic.nix should result in 3 builds");
|
||||
|
||||
my ($eval, @evals) = $jobset->jobsetevals;
|
||||
my ($abortedBuild, $failedBuild, @builds) = queuedBuildsForJobset($jobset);
|
||||
|
||||
isnt($eval, undef, "We have an evaluation to restart");
|
||||
|
||||
# Make the build be aborted
|
||||
isnt($abortedBuild, undef, "We should have the aborted build to restart");
|
||||
$abortedBuild->update({
|
||||
finished => 1,
|
||||
buildstatus => 3,
|
||||
stoptime => 1,
|
||||
starttime => 1,
|
||||
});
|
||||
|
||||
# Make the build be failed
|
||||
isnt($failedBuild, undef, "We should have the failed build to restart");
|
||||
$failedBuild->update({
|
||||
finished => 1,
|
||||
buildstatus => 5,
|
||||
stoptime => 1,
|
||||
starttime => 1,
|
||||
});
|
||||
|
||||
# Login and save cookie for future requests
|
||||
my $req = request(POST '/login',
|
||||
Referer => 'http://localhost/',
|
||||
Content => {
|
||||
username => 'alice',
|
||||
password => 'foobar'
|
||||
}
|
||||
);
|
||||
is($req->code, 302, "Logging in gets a 302");
|
||||
my $cookie = $req->header("set-cookie");
|
||||
|
||||
|
||||
subtest 'Restart all aborted JobsetEval builds' => sub {
|
||||
my $restart = request(PUT '/eval/' . $eval->id . '/restart-aborted',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
);
|
||||
is($restart->code, 302, "Restarting 302's back to the build");
|
||||
is($restart->header("location"), "http://localhost/eval/" . $eval->id);
|
||||
|
||||
my $newAbortedBuild = $db->resultset('Builds')->find($abortedBuild->id);
|
||||
is($newAbortedBuild->finished, 0, "The aborted build is no longer finished");
|
||||
|
||||
my $newFailedBuild = $db->resultset('Builds')->find($failedBuild->id);
|
||||
is($newFailedBuild->finished, 1, "The failed build is still finished");
|
||||
};
|
||||
|
||||
subtest 'Restart all failed JobsetEval builds' => sub {
|
||||
my $restart = request(PUT '/eval/' . $eval->id . '/restart-failed',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
);
|
||||
is($restart->code, 302, "Restarting 302's back to the build");
|
||||
is($restart->header("location"), "http://localhost/eval/" . $eval->id);
|
||||
|
||||
my $newFailedBuild = $db->resultset('Builds')->find($failedBuild->id);
|
||||
is($newFailedBuild->finished, 0, "The failed build is no longer finished");
|
||||
};
|
||||
|
||||
done_testing;
|
30
t/Hydra/Controller/Root/evals.t
Normal file
30
t/Hydra/Controller/Root/evals.t
Normal file
@ -0,0 +1,30 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use Data::Dumper;
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
use HTTP::Request::Common;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
|
||||
subtest "/evals" => sub {
|
||||
my $global = request(GET '/evals');
|
||||
ok($global->is_success, "The page showing the all evals returns 200.");
|
||||
};
|
||||
|
||||
done_testing;
|
48
t/Hydra/Controller/Root/narinfo.t
Normal file
48
t/Hydra/Controller/Root/narinfo.t
Normal file
@ -0,0 +1,48 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use Data::Dumper;
|
||||
use JSON::MaybeXS qw(decode_json);
|
||||
my %ctx = test_init(
|
||||
# Without this, the test will fail because a `file:` store is not treated as a
|
||||
# local store by `isLocalStore` in src/lib/Hydra/Helper/Nix.pm, and any
|
||||
# requests to /HASH.narinfo will fail.
|
||||
use_external_destination_store => 0
|
||||
);
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
use HTTP::Request::Common;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
for my $build (queuedBuildsForJobset($jobset)) {
|
||||
ok(runBuild($build), "Build '".$build->job."' from jobs/basic.nix should exit with return code 0");
|
||||
}
|
||||
|
||||
subtest "/HASH.narinfo" => sub {
|
||||
my $build_redirect = request(GET '/job/tests/basic/empty_dir/latest-finished');
|
||||
my $url = URI->new($build_redirect->header('location'))->path;
|
||||
my $json = request(GET $url, Accept => 'application/json');
|
||||
my $data = decode_json($json->content);
|
||||
my $outpath = $data->{buildoutputs}{out}{path};
|
||||
my ($hash) = $outpath =~ qr{/nix/store/([a-z0-9]{32}).*};
|
||||
my $narinfo_response = request(GET "/$hash.narinfo");
|
||||
ok($narinfo_response->is_success, "Getting the narinfo of a build");
|
||||
|
||||
my ($storepath) = $narinfo_response->content =~ qr{StorePath: (.*)};
|
||||
is($storepath, $outpath, "The returned store path is the same as the out path")
|
||||
};
|
||||
|
||||
done_testing;
|
30
t/Hydra/Controller/Root/queue-runner-status.t
Normal file
30
t/Hydra/Controller/Root/queue-runner-status.t
Normal file
@ -0,0 +1,30 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use Data::Dumper;
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
use HTTP::Request::Common;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
|
||||
|
||||
my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});
|
||||
|
||||
ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");
|
||||
|
||||
subtest "/queue-runner-status" => sub {
|
||||
my $global = request(GET '/queue-runner-status');
|
||||
ok($global->is_success, "The page showing the the queue runner status 200's.");
|
||||
};
|
||||
|
||||
done_testing;
|
31
t/Hydra/Controller/metrics.t
Normal file
31
t/Hydra/Controller/metrics.t
Normal file
@ -0,0 +1,31 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
use HTTP::Request::Common;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
request(GET '/');
|
||||
my $metrics = request(GET '/metrics');
|
||||
ok($metrics->is_success);
|
||||
|
||||
like(
|
||||
$metrics->content,
|
||||
qr/http_requests_total\{action="index",code="200",controller="Hydra::Controller::Root",method="GET"\} 1/,
|
||||
"Metrics are collected"
|
||||
);
|
||||
|
||||
done_testing;
|
140
t/Hydra/Controller/projects.t
Normal file
140
t/Hydra/Controller/projects.t
Normal file
@ -0,0 +1,140 @@
|
||||
use feature 'unicode_strings';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Setup;
|
||||
use JSON::MaybeXS qw(decode_json encode_json);
|
||||
|
||||
my %ctx = test_init();
|
||||
|
||||
require Hydra::Schema;
|
||||
require Hydra::Model::DB;
|
||||
require Hydra::Helper::Nix;
|
||||
use HTTP::Request::Common;
|
||||
|
||||
use Test2::V0;
|
||||
require Catalyst::Test;
|
||||
Catalyst::Test->import('Hydra');
|
||||
|
||||
my $db = Hydra::Model::DB->new;
|
||||
hydra_setup($db);
|
||||
|
||||
# Create a user to log in to
|
||||
my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' });
|
||||
$user->setPassword('foobar');
|
||||
$user->userroles->update_or_create({ role => 'admin' });
|
||||
|
||||
my $project = $db->resultset('Projects')->create({name => "tests", displayname => "Tests", owner => "root"});
|
||||
|
||||
# Login and save cookie for future requests
|
||||
my $req = request(POST '/login',
|
||||
Referer => 'http://localhost/',
|
||||
Content => {
|
||||
username => 'alice',
|
||||
password => 'foobar'
|
||||
}
|
||||
);
|
||||
is($req->code, 302);
|
||||
my $cookie = $req->header("set-cookie");
|
||||
|
||||
subtest "Read project 'tests'" => sub {
|
||||
my $projectinfo = request(GET '/project/tests',
|
||||
Accept => 'application/json',
|
||||
);
|
||||
|
||||
ok($projectinfo->is_success);
|
||||
is(decode_json($projectinfo->content), {
|
||||
description => "",
|
||||
displayname => "Tests",
|
||||
enabled => JSON::MaybeXS::true,
|
||||
hidden => JSON::MaybeXS::false,
|
||||
homepage => "",
|
||||
jobsets => [],
|
||||
name => "tests",
|
||||
owner => "root"
|
||||
});
|
||||
};
|
||||
|
||||
subtest "Transitioning from declarative project to normal" => sub {
|
||||
subtest "Make project declarative" => sub {
|
||||
my $projectupdate = request(PUT '/project/tests',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
Content => encode_json({
|
||||
enabled => JSON::MaybeXS::true,
|
||||
visible => JSON::MaybeXS::true,
|
||||
name => "tests",
|
||||
displayname => "Tests",
|
||||
declarative => {
|
||||
file => "bogus",
|
||||
type => "boolean",
|
||||
value => "false"
|
||||
}
|
||||
})
|
||||
);
|
||||
ok($projectupdate->is_success);
|
||||
};
|
||||
|
||||
subtest "Project has '.jobsets' jobset" => sub {
|
||||
my $projectinfo = request(GET '/project/tests',
|
||||
Accept => 'application/json',
|
||||
);
|
||||
|
||||
ok($projectinfo->is_success);
|
||||
is(decode_json($projectinfo->content), {
|
||||
description => "",
|
||||
displayname => "Tests",
|
||||
enabled => JSON::MaybeXS::true,
|
||||
hidden => JSON::MaybeXS::false,
|
||||
homepage => "",
|
||||
jobsets => [".jobsets"],
|
||||
name => "tests",
|
||||
owner => "root",
|
||||
declarative => {
|
||||
file => "bogus",
|
||||
type => "boolean",
|
||||
value => "false"
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
subtest "Make project normal" => sub {
|
||||
my $projectupdate = request(PUT '/project/tests',
|
||||
Accept => 'application/json',
|
||||
Content_Type => 'application/json',
|
||||
Cookie => $cookie,
|
||||
Content => encode_json({
|
||||
enabled => JSON::MaybeXS::true,
|
||||
visible => JSON::MaybeXS::true,
|
||||
name => "tests",
|
||||
displayname => "Tests",
|
||||
declarative => {
|
||||
file => "",
|
||||
type => "boolean",
|
||||
value => "false"
|
||||
}
|
||||
})
|
||||
);
|
||||
ok($projectupdate->is_success);
|
||||
};
|
||||
|
||||
subtest "Project doesn't have '.jobsets' jobset" => sub {
|
||||
my $projectinfo = request(GET '/project/tests',
|
||||
Accept => 'application/json',
|
||||
);
|
||||
|
||||
ok($projectinfo->is_success);
|
||||
is(decode_json($projectinfo->content), {
|
||||
description => "",
|
||||
displayname => "Tests",
|
||||
enabled => JSON::MaybeXS::true,
|
||||
hidden => JSON::MaybeXS::false,
|
||||
homepage => "",
|
||||
jobsets => [],
|
||||
name => "tests",
|
||||
owner => "root"
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
done_testing;
|
Reference in New Issue
Block a user