Fix handling of IPC::Run::run exit status

Turns out that the exit status is returned in $?, not as the return
value of run().  So our error checking was completely bogus.
This commit is contained in:
Eelco Dolstra 2013-01-23 15:56:28 +01:00
parent 60e36d3d1a
commit 58dd49e645
4 changed files with 56 additions and 64 deletions

View file

@ -424,7 +424,7 @@ sub force_eval : Chained('admin') Path('eval') Args(2) {
$c->stash->{jobset} = $c->stash->{jobset_}->single
or notFound($c, "Jobset $jobsetName doesn't exist.");
(my $res, my $stdout, my $stderr) = captureStdoutStderr(60, ("hydra-evaluator", $projectName, $jobsetName));
captureStdoutStderr(60, "hydra-evaluator", $projectName, $jobsetName);
$c->res->redirect("/project/$projectName");
}

View file

@ -116,7 +116,7 @@ sub fetchInputPath {
print STDERR "copying input ", $name, " from $uri\n";
$storePath = `nix-store --add "$uri"`
or die "Cannot copy path $uri to the Nix store.\n";
or die "cannot copy path $uri to the Nix store.\n";
chomp $storePath;
$sha256 = getStorePathHash $storePath;
@ -170,8 +170,8 @@ sub fetchInputSVN {
# First figure out the last-modified revision of the URI.
my @cmd = (["svn", "ls", "-v", "--depth", "empty", $uri],
"|", ["sed", 's/^ *\([0-9]*\).*/\1/']);
die "Cannot get head revision of Subversion repository at `$uri':\n$stderr"
unless IPC::Run::run(@cmd, \$stdout, \$stderr);
IPC::Run::run(@cmd, \$stdout, \$stderr);
die "cannot get head revision of Subversion repository at `$uri':\n$stderr" if $?;
$revision = $stdout; $revision =~ s/\s*([0-9]+)\s*/$1/sm;
}
@ -194,8 +194,8 @@ sub fetchInputSVN {
print STDERR "checking out Subversion input ", $name, " from $uri revision $revision into $wcPath\n";
(my $res, $stdout, $stderr) = captureStdoutStderr(600,
("svn", "checkout", $uri, "-r", $revision, $wcPath));
(my $res, $stdout, $stderr) = captureStdoutStderr(600, "svn", "checkout", $uri, "-r", $revision, $wcPath);
die "error checking out Subversion repo at `$uri':\n$stderr" if $res;
if ($checkout) {
$storePath = addToStore($wcPath, 1, "sha256");
@ -322,9 +322,8 @@ sub fetchInputGit {
if (! -d $clonePath) {
# Clone everything and fetch the branch.
# TODO: Optimize the first clone by using "git init $clonePath" and "git remote add origin $uri".
($res, $stdout, $stderr) = captureStdoutStderr(600,
("git", "clone", "--branch", $branch, $uri, $clonePath));
die "Error cloning git repo at `$uri':\n$stderr" unless $res;
($res, $stdout, $stderr) = captureStdoutStderr(600, "git", "clone", "--branch", $branch, $uri, $clonePath);
die "error cloning git repo at `$uri':\n$stderr" if $res;
}
chdir $clonePath or die $!; # !!! urgh, shouldn't do a chdir
@ -333,18 +332,18 @@ sub fetchInputGit {
# the remote branch for whatever the repository state is. This command mirror
# only one branch of the remote repository.
($res, $stdout, $stderr) = captureStdoutStderr(600,
("git", "fetch", "-fu", "origin", "+$branch:$branch"));
"git", "fetch", "-fu", "origin", "+$branch:$branch");
($res, $stdout, $stderr) = captureStdoutStderr(600,
("git", "fetch", "-fu", "origin")) unless $res;
die "Error fetching latest change from git repo at `$uri':\n$stderr" unless $res;
"git", "fetch", "-fu", "origin") if $res;
die "error fetching latest change from git repo at `$uri':\n$stderr" if $res;
($res, $stdout, $stderr) = captureStdoutStderr(600,
("git", "rev-parse", "$branch"));
die "Error getting revision number of Git branch '$branch' at `$uri':\n$stderr" unless $res;
die "error getting revision number of Git branch '$branch' at `$uri':\n$stderr" if $res;
my ($revision) = split /\n/, $stdout;
die unless $revision =~ /^[0-9a-fA-F]+$/;
die "Error getting a well-formated revision number of Git branch '$branch' at `$uri':\n$stdout" unless $res;
die "error getting a well-formated revision number of Git branch '$branch' at `$uri':\n$stdout"
unless $revision =~ /^[0-9a-fA-F]+$/;
my $ref = "refs/heads/$branch";
@ -353,17 +352,15 @@ sub fetchInputGit {
if (defined $deepClone) {
# Checkout the branch to look at its content.
($res, $stdout, $stderr) = captureStdoutStderr(600,
("git", "checkout", "$branch"));
die "Error checking out Git branch '$branch' at `$uri':\n$stderr" unless $res;
($res, $stdout, $stderr) = captureStdoutStderr(600, "git", "checkout", "$branch");
die "error checking out Git branch '$branch' at `$uri':\n$stderr" if $res;
if (-f ".topdeps") {
# This is a TopGit branch. Fetch all the topic branches so
# that builders can run "tg patch" and similar.
($res, $stdout, $stderr) = captureStdoutStderr(600,
("tg", "remote", "--populate", "origin"));
print STDERR "Warning: `tg remote --populate origin' failed:\n$stderr" unless $res;
"tg", "remote", "--populate", "origin");
print STDERR "warning: `tg remote --populate origin' failed:\n$stderr" if $res;
}
}
@ -400,9 +397,8 @@ sub fetchInputGit {
$ENV{"NIX_PREFETCH_GIT_DEEP_CLONE"} = "1";
}
($res, $stdout, $stderr) = captureStdoutStderr(600,
("nix-prefetch-git", $clonePath, $revision));
die "Cannot check out Git repository branch '$branch' at `$uri':\n$stderr" unless $res;
($res, $stdout, $stderr) = captureStdoutStderr(600, "nix-prefetch-git", $clonePath, $revision);
die "cannot check out Git repository branch '$branch' at `$uri':\n$stderr" if $res;
($sha256, $storePath) = split ' ', $stdout;
@ -454,22 +450,19 @@ sub fetchInputBazaar {
my $clonePath = scmPath . "/" . sha256_hex($uri);
if (! -d $clonePath) {
(my $res, $stdout, $stderr) = captureStdoutStderr(600,
("bzr", "branch", $uri, $clonePath));
die "Error cloning bazaar branch at `$uri':\n$stderr" unless $res;
(my $res, $stdout, $stderr) = captureStdoutStderr(600, "bzr", "branch", $uri, $clonePath);
die "error cloning bazaar branch at `$uri':\n$stderr" if $res;
}
chdir $clonePath or die $!;
(my $res, $stdout, $stderr) = captureStdoutStderr(600,
("bzr", "pull"));
die "Error pulling latest change bazaar branch at `$uri':\n$stderr" unless $res;
(my $res, $stdout, $stderr) = captureStdoutStderr(600, "bzr", "pull");
die "error pulling latest change bazaar branch at `$uri':\n$stderr" if $res;
# First figure out the last-modified revision of the URI.
my @cmd = (["bzr", "revno"],
"|", ["sed", 's/^ *\([0-9]*\).*/\1/']);
my @cmd = (["bzr", "revno"], "|", ["sed", 's/^ *\([0-9]*\).*/\1/']);
die "Cannot get head revision of Bazaar branch at `$uri':\n$stderr"
unless IPC::Run::run(@cmd, \$stdout, \$stderr);
IPC::Run::run(@cmd, \$stdout, \$stderr);
die "cannot get head revision of Bazaar branch at `$uri':\n$stderr" if $?;
my $revision = $stdout; chomp $revision;
die unless $revision =~ /^\d+$/;
@ -488,8 +481,8 @@ sub fetchInputBazaar {
$ENV{"NIX_PREFETCH_BZR_LEAVE_DOT_BZR"} = "$checkout";
(my $res, $stdout, $stderr) = captureStdoutStderr(600,
("nix-prefetch-bzr", $clonePath, $revision));
die "Cannot check out Bazaar branch `$uri':\n$stderr" unless $res;
"nix-prefetch-bzr", $clonePath, $revision);
die "cannot check out Bazaar branch `$uri':\n$stderr" if $res;
($sha256, $storePath) = split ' ', $stdout;
@ -527,18 +520,18 @@ sub fetchInputHg {
if (! -d $clonePath) {
(my $res, $stdout, $stderr) = captureStdoutStderr(600,
("hg", "clone", $uri, $clonePath));
die "Error cloning mercurial repo at `$uri':\n$stderr" unless $res;
"hg", "clone", $uri, $clonePath);
die "error cloning mercurial repo at `$uri':\n$stderr" if $res;
}
# hg pull + check rev
chdir $clonePath or die $!;
(my $res, $stdout, $stderr) = captureStdoutStderr(600,
("hg", "pull"));
die "Error pulling latest change mercurial repo at `$uri':\n$stderr" unless $res;
(my $res, $stdout, $stderr) = captureStdoutStderr(600, "hg", "pull");
die "error pulling latest change mercurial repo at `$uri':\n$stderr" if $res;
(my $res1, $stdout, $stderr) = captureStdoutStderr(600,("hg", "log", "-r", $id, "--template", "{node|short} {rev} {branch}"));
die "Error getting branch and revision of $id from `$uri':\n$stderr" unless $res1;
(my $res1, $stdout, $stderr) = captureStdoutStderr(600,
"hg", "log", "-r", $id, "--template", "{node|short} {rev} {branch}");
die "error getting branch and revision of $id from `$uri':\n$stderr" if $res1;
my ($revision, $revCount, $branch) = split ' ', $stdout;
@ -556,8 +549,8 @@ sub fetchInputHg {
$ENV{"PRINT_PATH"} = "1";
(my $res, $stdout, $stderr) = captureStdoutStderr(600,
("nix-prefetch-hg", $clonePath, $revision));
die "Cannot check out Mercurial repository `$uri':\n$stderr" unless $res;
"nix-prefetch-hg", $clonePath, $revision);
die "cannot check out Mercurial repository `$uri':\n$stderr" if $res;
($sha256, $storePath) = split ' ', $stdout;
@ -623,7 +616,7 @@ sub fetchInput {
push @inputs, { value => $value };
}
else {
die "Input `" . $name . "' has unknown type `$type'.";
die "input `" . $name . "' has unknown type `$type'.";
}
foreach my $input (@inputs) {
@ -709,7 +702,6 @@ sub inputsToArgs {
sub captureStdoutStderr {
my ($timeout, @cmd) = @_;
my $res;
my $stdin = "";
my $stdout;
my $stderr;
@ -717,16 +709,15 @@ sub captureStdoutStderr {
eval {
local $SIG{ALRM} = sub { die "timeout\n" }; # NB: \n required
alarm $timeout;
$res = IPC::Run::run(\@cmd, \$stdin, \$stdout, \$stderr);
IPC::Run::run(\@cmd, \$stdin, \$stdout, \$stderr);
alarm 0;
};
if ($@) {
die unless $@ eq "timeout\n"; # propagate unexpected errors
return (undef, "", "timeout\n");
die unless $@ eq "timeout\n"; # propagate unexpected errors
return (-1, "", "timeout\n");
} else {
return ($res, $stdout, $stderr);
return ($?, $stdout, $stderr);
}
}
@ -735,8 +726,8 @@ sub evalJobs {
my ($inputInfo, $exprType, $nixExprInputName, $nixExprPath) = @_;
my $nixExprInput = $inputInfo->{$nixExprInputName}->[0]
or die "Cannot find the input containing the job expression.\n";
die "Multiple alternatives for the input containing the Nix expression are not supported.\n"
or die "cannot find the input containing the job expression.\n";
die "multiple alternatives for the input containing the Nix expression are not supported.\n"
if scalar @{$inputInfo->{$nixExprInputName}} != 1;
my $nixExprFullPath = $nixExprInput->{storePath} . "/" . $nixExprPath;
@ -744,8 +735,8 @@ sub evalJobs {
print STDERR "evaluator ${evaluator}\n";
(my $res, my $jobsXml, my $stderr) = captureStdoutStderr(10800,
($evaluator, $nixExprFullPath, "--gc-roots-dir", getGCRootsDir, "-j", 1, inputsToArgs($inputInfo, $exprType)));
die "Cannot evaluate the Nix expression containing the jobs:\n$stderr" unless $res;
$evaluator, $nixExprFullPath, "--gc-roots-dir", getGCRootsDir, "-j", 1, inputsToArgs($inputInfo, $exprType));
die "cannot evaluate the Nix expression containing the jobs:\n$stderr" if $res;
print STDERR "$stderr";

View file

@ -24,18 +24,19 @@ TESTS = \
query-all-tables.pl \
evaluation-tests.pl
clean :
clean:
chmod -R a+w nix || true
rm -rf db.sqlite data nix git-repo hg-repo svn-repo svn-checkout svn-checkout-repo bzr-repo bzr-checkout-repo
rm -f .*-state
check_SCRIPTS = db.sqlite repos
db.sqlite : $(top_srcdir)/src/sql/hydra-sqlite.sql
db.sqlite: $(top_srcdir)/src/sql/hydra-sqlite.sql
$(TESTS_ENVIRONMENT) $(top_srcdir)/src/script/hydra-init
repos : dirs
repos: dirs
dirs :
dirs:
mkdir -p data
touch data/hydra.conf
mkdir -p nix

View file

@ -66,20 +66,20 @@ sub evalSucceeds {
print STDERR "Evaluation errors for jobset ".$jobset->project->name.":".$jobset->name.": \n".$jobset->errormsg."\n" if $jobset->errormsg;
print STDERR "STDOUT: $stdout\n" if $stdout ne "";
print STDERR "STDERR: $stderr\n" if $stderr ne "";
return $res;
return !$res;
}
sub runBuild {
my ($build) = @_;
my ($res, $stdout, $stderr) = captureStdoutStderr(60, ("../src/script/hydra-build", $build->id));
print "STDERR: $stderr" if $res;
return ($res, $stdout, $stderr);
print "STDERR: $stderr" if $stderr ne "";
return !$res;
}
sub updateRepository {
my ($scm, $update) = @_;
my ($res, $stdout, $stderr) = captureStdoutStderr(60, ($update, $scm));
die "Unexpected update error with $scm: $stderr\n" unless $res;
die "unexpected update error with $scm: $stderr\n" if $res;
my ($message, $loop, $status) = $stdout =~ m/::(.*) -- (.*) -- (.*)::/;
print STDOUT "Update $scm repository: $message\n";
return ($loop eq "continue", $status eq "updated");