Prior to https://github.com/NixOS/hydra/pull/856, the type
-related constraints
were a bit too loose, allowing some variations that should have been seen as
invalid. This commit adds a test (inspired by
https://github.com/NixOS/hydra/pull/856#issuecomment-772820929) to ensure these
constraints stay unviolated.
LIKQZ4LGLFOQCUKG5G4ZTQACGOQ4PU4PI4BENALETS747YHE5Y2QC
use strict;
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;