237 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
use strict;
 | 
						|
use warnings;
 | 
						|
use Setup;
 | 
						|
use Test2::V0;
 | 
						|
use Catalyst::Test ();
 | 
						|
use HTTP::Request;
 | 
						|
use HTTP::Request::Common;
 | 
						|
use JSON::MaybeXS qw(decode_json encode_json);
 | 
						|
 | 
						|
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');
 | 
						|
 | 
						|
# Create a user to log in to
 | 
						|
my $user = $ctx->db->resultset('Users')->create({ username => 'alice', emailaddress => 'alice@example.com', password => '!' });
 | 
						|
$user->setPassword('foobar');
 | 
						|
$user->userroles->update_or_create({ role => 'admin' });
 | 
						|
 | 
						|
# Login and save cookie for future requests
 | 
						|
my $req = request(POST '/login',
 | 
						|
    Referer => 'http://localhost/',
 | 
						|
    Content => {
 | 
						|
        username => 'alice',
 | 
						|
        password => 'foobar'
 | 
						|
    }
 | 
						|
);
 | 
						|
is($req->code, 302, "The login redirects");
 | 
						|
my $cookie = $req->header("set-cookie");
 | 
						|
 | 
						|
my $finishedBuilds = $ctx->makeAndEvaluateJobset(
 | 
						|
    expression => "one-job.nix",
 | 
						|
    build => 1
 | 
						|
);
 | 
						|
 | 
						|
my $queuedBuilds = $ctx->makeAndEvaluateJobset(
 | 
						|
    expression => "one-job.nix",
 | 
						|
    build => 0
 | 
						|
);
 | 
						|
 | 
						|
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,
 | 
						|
        }]);
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
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]);
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
subtest "/api/push" => sub {
 | 
						|
    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(POST "/api/push?jobsets=$projectName:$jobsetName&force=1",
 | 
						|
            Cookie => $cookie,
 | 
						|
            Referer => 'http://localhost/',
 | 
						|
        );
 | 
						|
        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;
 | 
						|
 | 
						|
        my $response = request(POST "/api/push?repos=$repo&force=1",
 | 
						|
            Cookie => $cookie,
 | 
						|
            Referer => 'http://localhost/',
 | 
						|
        );
 | 
						|
        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");
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
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 => {
 | 
						|
                        name => "OWNER",
 | 
						|
                    },
 | 
						|
                    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 => {
 | 
						|
                        name => "OWNER",
 | 
						|
                    },
 | 
						|
                    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.");
 | 
						|
    };
 | 
						|
};
 | 
						|
 | 
						|
done_testing;
 |