2022-01-14 18:33:44 +00:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use Setup;
|
|
|
|
use Test2::V0;
|
|
|
|
use Catalyst::Test ();
|
2022-01-14 19:41:37 +00:00
|
|
|
use HTTP::Request;
|
2022-01-14 18:33:44 +00:00
|
|
|
use HTTP::Request::Common;
|
2022-01-14 19:41:37 +00:00
|
|
|
use JSON::MaybeXS qw(decode_json encode_json);
|
2022-01-14 18:33:44 +00:00
|
|
|
|
|
|
|
sub is_json {
|
|
|
|
my ($response, $message) = @_;
|
|
|
|
|
|
|
|
my $data;
|
|
|
|
my $valid_json = lives { $data = decode_json($response->content); };
|
|
|
|
ok($valid_json, $message // "We get back valid JSON.");
|
|
|
|
if (!$valid_json) {
|
|
|
|
use Data::Dumper;
|
|
|
|
print STDERR Dumper $response->content;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $ctx = test_context();
|
|
|
|
|
|
|
|
Catalyst::Test->import('Hydra');
|
|
|
|
|
|
|
|
my $finishedBuilds = $ctx->makeAndEvaluateJobset(
|
|
|
|
expression => "one-job.nix",
|
|
|
|
build => 1
|
|
|
|
);
|
|
|
|
|
|
|
|
my $queuedBuilds = $ctx->makeAndEvaluateJobset(
|
|
|
|
expression => "one-job.nix",
|
|
|
|
build => 0
|
|
|
|
);
|
|
|
|
|
2024-08-27 00:57:16 +00:00
|
|
|
# Login and save cookie for future requests
|
|
|
|
my $req = request(POST '/login',
|
|
|
|
Referer => 'http://localhost/',
|
|
|
|
Content => {
|
|
|
|
username => 'root',
|
|
|
|
password => 'rootPassword'
|
|
|
|
}
|
|
|
|
);
|
|
|
|
is($req->code, 302, "Logging in gets a 302");
|
|
|
|
my $cookie = $req->header("set-cookie");
|
|
|
|
|
2022-01-14 18:33:44 +00:00
|
|
|
subtest "/api/queue" => sub {
|
|
|
|
my $response = request(GET '/api/queue?nr=1');
|
|
|
|
ok($response->is_success, "The API enpdoint showing the queue returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
my $build = $queuedBuilds->{"one_job"};
|
|
|
|
like($data, [{
|
|
|
|
priority => $build->priority,
|
|
|
|
id => $build->id,
|
|
|
|
}]);
|
|
|
|
};
|
|
|
|
|
|
|
|
subtest "/api/latestbuilds" => sub {
|
|
|
|
subtest "with no specific parameters" => sub {
|
|
|
|
my $response = request(GET '/api/latestbuilds?nr=1');
|
|
|
|
ok($response->is_success, "The API enpdoint showing the latest builds returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
my $build = $finishedBuilds->{"one_job"};
|
|
|
|
like($data, [{
|
|
|
|
buildstatus => $build->buildstatus,
|
|
|
|
id => $build->id,
|
|
|
|
}]);
|
|
|
|
};
|
|
|
|
|
|
|
|
subtest "with very specific parameters" => sub {
|
|
|
|
my $build = $finishedBuilds->{"one_job"};
|
|
|
|
my $projectName = $build->project->name;
|
|
|
|
my $jobsetName = $build->jobset->name;
|
|
|
|
my $jobName = $build->job;
|
|
|
|
my $system = $build->system;
|
|
|
|
my $response = request(GET "/api/latestbuilds?nr=1&project=$projectName&jobset=$jobsetName&job=$jobName&system=$system");
|
|
|
|
ok($response->is_success, "The API enpdoint showing the latest builds returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
|
|
|
|
like($data, [{
|
|
|
|
buildstatus => $build->buildstatus,
|
|
|
|
id => $build->id,
|
|
|
|
}]);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2022-01-14 18:42:00 +00:00
|
|
|
subtest "/api/nrbuilds" => sub {
|
|
|
|
subtest "with no specific parameters" => sub {
|
|
|
|
my $response = request(GET '/api/nrbuilds?nr=1&period=hour');
|
|
|
|
ok($response->is_success, "The API enpdoint showing the latest builds returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
is($data, [1]);
|
|
|
|
};
|
|
|
|
|
|
|
|
subtest "with very specific parameters" => sub {
|
|
|
|
my $build = $finishedBuilds->{"one_job"};
|
|
|
|
my $projectName = $build->project->name;
|
|
|
|
my $jobsetName = $build->jobset->name;
|
|
|
|
my $jobName = $build->job;
|
|
|
|
my $system = $build->system;
|
|
|
|
my $response = request(GET "/api/nrbuilds?nr=1&period=hour&project=$projectName&jobset=$jobsetName&job=$jobName&system=$system");
|
|
|
|
ok($response->is_success, "The API enpdoint showing the latest builds returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
is($data, [1]);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2022-01-14 19:04:03 +00:00
|
|
|
subtest "/api/push" => sub {
|
2024-08-27 00:57:16 +00:00
|
|
|
subtest "without authentication" => sub {
|
2022-01-14 19:04:03 +00:00
|
|
|
my $build = $finishedBuilds->{"one_job"};
|
|
|
|
my $jobset = $build->jobset;
|
|
|
|
my $projectName = $jobset->project->name;
|
|
|
|
my $jobsetName = $jobset->name;
|
|
|
|
is($jobset->forceeval, undef, "The existing jobset is not set to be forced to eval");
|
|
|
|
|
|
|
|
my $response = request(GET "/api/push?jobsets=$projectName:$jobsetName&force=1");
|
2024-08-27 00:57:16 +00:00
|
|
|
is($response->code, 403, "The API enpdoint for triggering jobsets requires authentication.");
|
|
|
|
};
|
|
|
|
|
|
|
|
subtest "with a specific jobset" => sub {
|
|
|
|
my $build = $finishedBuilds->{"one_job"};
|
|
|
|
my $jobset = $build->jobset;
|
|
|
|
my $projectName = $jobset->project->name;
|
|
|
|
my $jobsetName = $jobset->name;
|
|
|
|
is($jobset->forceeval, undef, "The existing jobset is not set to be forced to eval");
|
|
|
|
|
|
|
|
my $response = request(GET "/api/push?jobsets=$projectName:$jobsetName&force=1",
|
|
|
|
Cookie => $cookie);
|
2022-01-14 19:04:03 +00:00
|
|
|
ok($response->is_success, "The API enpdoint for triggering jobsets returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
is($data, { jobsetsTriggered => [ "$projectName:$jobsetName" ] });
|
|
|
|
|
|
|
|
my $updatedJobset = $ctx->db->resultset('Jobsets')->find({ id => $jobset->id });
|
|
|
|
is($updatedJobset->forceeval, 1, "The jobset is now forced to eval");
|
|
|
|
};
|
|
|
|
|
|
|
|
subtest "with a specific source" => sub {
|
|
|
|
my $repo = $ctx->jobsdir;
|
|
|
|
my $jobsetA = $queuedBuilds->{"one_job"}->jobset;
|
|
|
|
my $jobsetB = $finishedBuilds->{"one_job"}->jobset;
|
|
|
|
|
|
|
|
is($jobsetA->forceeval, undef, "The existing jobset is not set to be forced to eval");
|
|
|
|
|
|
|
|
print STDERR $repo;
|
|
|
|
|
2024-08-27 00:57:16 +00:00
|
|
|
my $response = request(GET "/api/push?repos=$repo&force=1",
|
|
|
|
Cookie => $cookie);
|
2022-01-14 19:04:03 +00:00
|
|
|
ok($response->is_success, "The API enpdoint for triggering jobsets returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
is($data, { jobsetsTriggered => [
|
|
|
|
"${\$jobsetA->project->name}:${\$jobsetA->name}",
|
|
|
|
"${\$jobsetB->project->name}:${\$jobsetB->name}"
|
|
|
|
] });
|
|
|
|
|
|
|
|
my $updatedJobset = $ctx->db->resultset('Jobsets')->find({ id => $jobsetA->id });
|
|
|
|
is($updatedJobset->forceeval, 1, "The jobset is now forced to eval");
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2022-01-14 19:41:37 +00:00
|
|
|
subtest "/api/push-github" => sub {
|
|
|
|
# Create a project and jobset which looks like it comes from GitHub
|
|
|
|
my $user = $ctx->db()->resultset('Users')->create({
|
|
|
|
username => "api-push-github",
|
|
|
|
emailaddress => 'api-push-github@example.org',
|
|
|
|
password => ''
|
|
|
|
});
|
|
|
|
|
|
|
|
my $project = $ctx->db()->resultset('Projects')->create({
|
|
|
|
name => "api-push-github",
|
|
|
|
displayname => "api-push-github",
|
|
|
|
owner => $user->username
|
|
|
|
});
|
|
|
|
|
|
|
|
subtest "with a legacy input type" => sub {
|
|
|
|
my $jobset = $project->jobsets->create({
|
|
|
|
name => "legacy-input-type",
|
|
|
|
nixexprinput => "src",
|
|
|
|
nixexprpath => "default.nix",
|
|
|
|
emailoverride => ""
|
|
|
|
});
|
|
|
|
|
|
|
|
my $jobsetinput = $jobset->jobsetinputs->create({name => "src", type => "git"});
|
|
|
|
$jobsetinput->jobsetinputalts->create({altnr => 0, value => "https://github.com/OWNER/LEGACY-REPO.git"});
|
|
|
|
|
|
|
|
my $req = POST '/api/push-github',
|
|
|
|
"Content-Type" => "application/json",
|
|
|
|
"Content" => encode_json({
|
|
|
|
repository => {
|
|
|
|
owner => {
|
2024-08-25 11:53:19 +00:00
|
|
|
login => "OWNER",
|
2022-01-14 19:41:37 +00:00
|
|
|
},
|
|
|
|
name => "LEGACY-REPO",
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
my $response = request($req);
|
|
|
|
ok($response->is_success, "The API enpdoint for triggering jobsets returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
is($data, { jobsetsTriggered => [ "api-push-github:legacy-input-type" ] }, "The correct jobsets are triggered.");
|
|
|
|
};
|
|
|
|
|
|
|
|
subtest "with a flake input type" => sub {
|
|
|
|
my $jobset = $project->jobsets->create({
|
|
|
|
name => "flake-input-type",
|
|
|
|
type => 1,
|
|
|
|
flake => "github:OWNER/FLAKE-REPO",
|
|
|
|
emailoverride => ""
|
|
|
|
});
|
|
|
|
|
|
|
|
my $req = POST '/api/push-github',
|
|
|
|
"Content-Type" => "application/json",
|
|
|
|
"Content" => encode_json({
|
|
|
|
repository => {
|
|
|
|
owner => {
|
2024-08-25 11:53:19 +00:00
|
|
|
login => "OWNER",
|
2022-01-14 19:41:37 +00:00
|
|
|
},
|
|
|
|
name => "FLAKE-REPO",
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
my $response = request($req);
|
|
|
|
ok($response->is_success, "The API enpdoint for triggering jobsets returns 200.");
|
|
|
|
|
|
|
|
my $data = is_json($response);
|
|
|
|
is($data, { jobsetsTriggered => [ "api-push-github:flake-input-type" ] }, "The correct jobsets are triggered.");
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2022-01-14 18:33:44 +00:00
|
|
|
done_testing;
|