Record the errno if exec fails

[?]
Nov 18, 2021, 6:46 PM
CBU7KGFEC5OECK45W7T3VGU6QKLTZXUZ3JA2QSQDSJMFZSD34QDQC

Dependencies

  • [2] VYS5RV7Y RunCommand: create run logs for each execution
  • [3] 7FJKVZAN RunCommand: calculate all the commands to run against before starting
  • [4] 2GNJU4VF RunCommandLogs: init table
  • [5] 6ZXL5UOP Add a plugin to execute arbitrary commands when a build finishes
  • [*] 33SD7P6N RunCommand tests: move in to a subdirectory

Change contents

  • replacement in src/lib/Hydra/Plugin/RunCommand.pm at line 164
    [3.3408][3.3408:3492]()
    or warn "notification command '$command' failed with exit status $?\n";
    [3.3408]
    [2.338]
    or warn "notification command '$command' failed with exit status $? ($!)\n";
  • replacement in src/lib/Hydra/Plugin/RunCommand.pm at line 166
    [2.339][2.339:388]()
    $runlog->completed_with_child_error($?);
    [2.339]
    [3.3492]
    $runlog->completed_with_child_error($?, $!);
  • replacement in src/lib/Hydra/Schema/Result/RunCommandLogs.pm at line 200
    [2.1448][2.1448:1480]()
    $errno = $reported_errno;
    [2.1448]
    [2.1480]
    #
    # The `+ 0` is because $! is a dual var and likes to be a string
    # if it can. +0 forces it to not be. Sigh.
    $errno = $reported_errno + 0;
  • file addition: errno.t (----------)
    [7.1]
    use feature 'unicode_strings';
    use strict;
    use warnings;
    use JSON::MaybeXS;
    use Setup;
    my %ctx = test_init(
    hydra_config => q|
    <runcommand>
    command = invalid-command-this-does-not-exist
    </runcommand>
    |);
    require Hydra::Schema;
    require Hydra::Model::DB;
    use Test2::V0;
    my $db = Hydra::Model::DB->new;
    hydra_setup($db);
    my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});
    # Most basic test case, no parameters
    my $jobset = createBaseJobset("basic", "runcommand.nix", $ctx{jobsdir});
    ok(evalSucceeds($jobset), "Evaluating jobs/runcommand.nix should exit with return code 0");
    is(nrQueuedBuildsForJobset($jobset), 1, "Evaluating jobs/runcommand.nix should result in 1 build1");
    (my $build) = queuedBuildsForJobset($jobset);
    is($build->job, "metrics", "The only job should be metrics");
    ok(runBuild($build), "Build should exit with return code 0");
    my $newbuild = $db->resultset('Builds')->find($build->id);
    is($newbuild->finished, 1, "Build should be finished.");
    is($newbuild->buildstatus, 0, "Build should have buildstatus 0.");
    ok(sendNotifications(), "Notifications execute successfully.");
    subtest "Validate a run log was created" => sub {
    my $runlog = $build->runcommandlogs->find({});
    is($runlog->job_matcher, "*:*:*", "An unspecified job matcher is defaulted to *:*:*");
    is($runlog->command, 'invalid-command-this-does-not-exist', "The executed command is saved.");
    is($runlog->start_time, within(time() - 1, 2), "The start time is recent.");
    is($runlog->end_time, within(time() - 1, 2), "The end time is also recent.");
    is($runlog->exit_code, undef, "This command should not have executed.");
    is($runlog->error_number, 2, "This command failed to exec.");
    };
    done_testing;