forked from lix-project/hydra
Dynamic RunCommand: validate that the job's out exists, is a file (or points to a file) which is executable.
This commit is contained in:
parent
c2be27e82b
commit
1a30a0c2f1
|
@ -41,6 +41,32 @@ sub isBuildEligibleForDynamicRunCommand {
|
||||||
my ($build) = @_;
|
my ($build) = @_;
|
||||||
|
|
||||||
if ($build->get_column("job") =~ "^runCommandHook\..+") {
|
if ($build->get_column("job") =~ "^runCommandHook\..+") {
|
||||||
|
my $out = $build->buildoutputs->find({name => "out"});
|
||||||
|
if (!defined $out) {
|
||||||
|
warn "DynamicRunCommand hook on " . $build->job . " (" . $build->id . ") rejected: no output named 'out'.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $path = $out->path;
|
||||||
|
if (-l $path) {
|
||||||
|
$path = readlink($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! -e $path) {
|
||||||
|
warn "DynamicRunCommand hook on " . $build->job . " (" . $build->id . ") rejected: The 'out' output doesn't exist locally. This is a bug.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! -x $path) {
|
||||||
|
warn "DynamicRunCommand hook on " . $build->job . " (" . $build->id . ") rejected: The 'out' output is not executable.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! -f $path) {
|
||||||
|
warn "DynamicRunCommand hook on " . $build->job . " (" . $build->id . ") rejected: The 'out' output is not a regular file or symlink.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,9 +135,7 @@ sub fanoutToCommands {
|
||||||
# missing test cases:
|
# missing test cases:
|
||||||
#
|
#
|
||||||
# 1. is it enabled on the jobset?
|
# 1. is it enabled on the jobset?
|
||||||
# 2. what if the result is a directory?
|
# 2. what if the build failed?
|
||||||
# 3. what if the job doens't have an out?
|
|
||||||
# 4. what if the build failed?
|
|
||||||
if (isBuildEligibleForDynamicRunCommand($build)) {
|
if (isBuildEligibleForDynamicRunCommand($build)) {
|
||||||
my $job = $build->get_column('job');
|
my $job = $build->get_column('job');
|
||||||
my $out = $build->buildoutputs->find({name => "out"});
|
my $out = $build->buildoutputs->find({name => "out"});
|
||||||
|
|
|
@ -93,36 +93,72 @@ subtest "fanoutToCommandsWithDynamicRunCommandSupport" => sub {
|
||||||
};
|
};
|
||||||
|
|
||||||
subtest "isBuildEligibleForDynamicRunCommand" => sub {
|
subtest "isBuildEligibleForDynamicRunCommand" => sub {
|
||||||
my $build = Hydra::Schema::Result::Builds->new({
|
subtest "Non-matches based on name alone ..." => sub {
|
||||||
"job" => "foo bar baz"
|
my $build = $builds->{"foo-bar-baz"};
|
||||||
});
|
is(
|
||||||
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($build),
|
||||||
|
0,
|
||||||
|
"The job name does not match"
|
||||||
|
);
|
||||||
|
|
||||||
is(
|
$build->set_column("job", "runCommandHook");
|
||||||
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($build),
|
is(
|
||||||
0,
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($build),
|
||||||
"The job name does not match"
|
0,
|
||||||
);
|
"The job name does not match"
|
||||||
|
);
|
||||||
|
|
||||||
$build->set_column("job", "runCommandHook");
|
$build->set_column("job", "runCommandHook.");
|
||||||
is(
|
is(
|
||||||
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($build),
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($build),
|
||||||
0,
|
0,
|
||||||
"The job name does not match"
|
"The job name does not match"
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
$build->set_column("job", "runCommandHook.");
|
subtest "On outputs ..." => sub {
|
||||||
is(
|
is(
|
||||||
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($build),
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($builds->{"runCommandHook.example"}),
|
||||||
0,
|
1,
|
||||||
"The job name does not match"
|
"out is an executable file"
|
||||||
);
|
);
|
||||||
|
|
||||||
$build->set_column("job", "runCommandHook.a");
|
is(
|
||||||
is(
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($builds->{"runCommandHook.symlink"}),
|
||||||
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($build),
|
1,
|
||||||
1,
|
"out is a symlink to an executable file"
|
||||||
"The job name does match"
|
);
|
||||||
);
|
|
||||||
|
is(
|
||||||
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($builds->{"runCommandHook.no-out"}),
|
||||||
|
0,
|
||||||
|
"No output named out"
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($builds->{"runCommandHook.out-is-directory"}),
|
||||||
|
0,
|
||||||
|
"out is a directory"
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($builds->{"runCommandHook.out-is-not-executable-file"}),
|
||||||
|
0,
|
||||||
|
"out is a file which is not not executable"
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($builds->{"runCommandHook.symlink-non-executable"}),
|
||||||
|
0,
|
||||||
|
"out is a symlink to a non-executable file"
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
Hydra::Plugin::RunCommand::isBuildEligibleForDynamicRunCommand($builds->{"runCommandHook.symlink-directory"}),
|
||||||
|
0,
|
||||||
|
"out is a symlink to a directory"
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,130 @@
|
||||||
with import ./config.nix;
|
with import ./config.nix;
|
||||||
{
|
rec {
|
||||||
runCommandHook.example = mkDerivation
|
foo-bar-baz = mkDerivation {
|
||||||
{
|
name = "foo-bar-baz";
|
||||||
name = "my-build-product";
|
builder = "/bin/sh";
|
||||||
builder = "/bin/sh";
|
outputs = [ "out" ];
|
||||||
outputs = [ "out" "bin" ];
|
args = [
|
||||||
args = [
|
(
|
||||||
(
|
builtins.toFile "builder.sh" ''
|
||||||
builtins.toFile "builder.sh" ''
|
#! /bin/sh
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
echo "$PATH"
|
touch $out
|
||||||
|
''
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
mkdir $bin
|
runCommandHook.example = mkDerivation {
|
||||||
echo "foo" > $bin/bar
|
name = "my-build-product";
|
||||||
|
builder = "/bin/sh";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
args = [
|
||||||
|
(
|
||||||
|
builtins.toFile "builder.sh" ''
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
metrics=$out/nix-support/hydra-metrics
|
touch $out
|
||||||
mkdir -p "$(dirname "$metrics")"
|
chmod +x $out
|
||||||
echo "lineCoverage 18 %" >> "$metrics"
|
# ... dunno ...
|
||||||
echo "maxResident 27 KiB" >> "$metrics"
|
''
|
||||||
''
|
)
|
||||||
)
|
];
|
||||||
];
|
};
|
||||||
};
|
|
||||||
|
runCommandHook.symlink = mkDerivation {
|
||||||
|
name = "symlink-out";
|
||||||
|
builder = "/bin/sh";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
args = [
|
||||||
|
(
|
||||||
|
builtins.toFile "builder.sh" ''
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
ln -s $1 $out
|
||||||
|
''
|
||||||
|
)
|
||||||
|
|
||||||
|
runCommandHook.example
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
runCommandHook.no-out = mkDerivation {
|
||||||
|
name = "no-out";
|
||||||
|
builder = "/bin/sh";
|
||||||
|
outputs = [ "bin" ];
|
||||||
|
args = [
|
||||||
|
(
|
||||||
|
builtins.toFile "builder.sh" ''
|
||||||
|
#! /bin/sh
|
||||||
|
mkdir $bin
|
||||||
|
''
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
runCommandHook.out-is-directory = mkDerivation {
|
||||||
|
name = "out-is-directory";
|
||||||
|
builder = "/bin/sh";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
args = [
|
||||||
|
(
|
||||||
|
builtins.toFile "builder.sh" ''
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
mkdir $out
|
||||||
|
''
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
runCommandHook.out-is-not-executable-file = mkDerivation {
|
||||||
|
name = "out-is-directory";
|
||||||
|
builder = "/bin/sh";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
args = [
|
||||||
|
(
|
||||||
|
builtins.toFile "builder.sh" ''
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
touch $out
|
||||||
|
''
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
runCommandHook.symlink-non-executable = mkDerivation {
|
||||||
|
name = "symlink-out";
|
||||||
|
builder = "/bin/sh";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
args = [
|
||||||
|
(
|
||||||
|
builtins.toFile "builder.sh" ''
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
ln -s $1 $out
|
||||||
|
''
|
||||||
|
)
|
||||||
|
|
||||||
|
runCommandHook.out-is-not-executable-file
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
runCommandHook.symlink-directory = mkDerivation {
|
||||||
|
name = "symlink-directory";
|
||||||
|
builder = "/bin/sh";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
args = [
|
||||||
|
(
|
||||||
|
builtins.toFile "builder.sh" ''
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
ln -s $1 $out
|
||||||
|
''
|
||||||
|
)
|
||||||
|
|
||||||
|
runCommandHook.out-is-directory
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue