hydra-notify: move StepFinished processing to an Event
[?]
Aug 12, 2021, 2:28 PM
LQEYBAEL73DCWQMK4PM6GOKIADZMHAL7O7KIIBNXN756CVOGOKDACDependencies
- [2]
GE7LFZHQhydra-notify: move buildFinished query in to the function impl - [3]
OPSWSU4Lhydra-notify: move BuildStarted processing to an Event - [4]
EKHD4I44Event: init structure and parse existing messages - [5]
OEQQ6CVTSet notificationpendingsince for dependent builds - [6]
GQGQEMMAEvent.pm: add a new_event helper to parse and construct an Event - [7]
7Q2PXRZAhydra-notify step-finished: Don't barf if the step has no log file - [8]
PXTSKX4GAdd buildQueued plugin hook - [9]
IE2PRAQUhydra-queue-runner: Send build notifications - [10]
FCTX433OAdd buildStarted plugin hook - [11]
NTEDD7T4Provide a plugin hook for when build steps finish - [12]
4ZCUCACYhydra-notify: Fix processing notifications - [13]
CQZQE32VImprove handling of Perl's block eval errors - [14]
32KJOERMTurn hydra-notify into a daemon
Change contents
- replacement in src/lib/Hydra/Event/StepFinished.pm at line 26
return bless { "build_id" => $build_id, "step_number" => $step_number, "log_path" => $log_path }, $self;$log_path = undef if $log_path eq "-";return bless {"build_id" => $build_id,"step_number" => $step_number,"log_path" => $log_path,"step" => undef,}, $self;}sub load {my ($self, $db) = @_;if (!defined($self->{"step"})) {my $build = $db->resultset('Builds')->find($self->{"build_id"})or die "build $self->{'build_id'} does not exist\n";$self->{"step"} = $build->buildsteps->find({stepnr => $self->{"step_number"}})or die "step $self->{'step_number'} does not exist\n";}}sub execute {my ($self, $db, $plugin) = @_;$self->load($db);$plugin->stepFinished($self->{"step"}, $self->{"log_path"});return 1; - edit in src/script/hydra-notify at line 77
sub stepFinished {my ($buildId, $stepNr, $logPath) = @_; - edit in src/script/hydra-notify at line 78[4.474]→[4.2129:2236](∅→∅),[4.2236]→[4.4230:4231](∅→∅),[4.4230]→[4.4230:4231](∅→∅),[4.59]→[4.4302:4411](∅→∅),[4.4302]→[4.4302:4411](∅→∅),[4.4411]→[4.2237:2279](∅→∅),[4.131]→[4.4449:4486](∅→∅),[4.2279]→[4.4449:4486](∅→∅),[4.4449]→[4.4449:4486](∅→∅),[4.4486]→[4.1034:1201](∅→∅),[4.1201]→[4.4618:4634](∅→∅),[4.4618]→[4.4618:4634](∅→∅),[4.1903]→[4.3830:3833](∅→∅),[4.4634]→[4.3830:3833](∅→∅),[4.3830]→[4.3830:3833](∅→∅)
my $build = $db->resultset('Builds')->find($buildId)or die "build $buildId does not exist\n";my $step = $build->buildsteps->find({stepnr => $stepNr})or die "step $stepNr does not exist\n";$logPath = undef if $logPath eq "-";foreach my $plugin (@plugins) {eval {$plugin->stepFinished($step, $logPath);1;} or do {print STDERR "error with $plugin->stepFinished: $@\n";}}} - replacement in src/script/hydra-notify at line 101
if ($channelName eq "build_started") {if ($channelName eq "build_started" || $channelName eq "step_finished" ) { - edit in src/script/hydra-notify at line 107
} elsif ($channelName eq "step_finished") {stepFinished(int($payload[0]), int($payload[1])); - file addition: StepFinished.t[3.587]
use strict;use Setup;my %ctx = test_init();require Hydra::Schema;require Hydra::Model::DB;use Hydra::Event;use Hydra::Event::BuildStarted;use Test2::V0;use Test2::Tools::Exception;use Test2::Tools::Mock qw(mock_obj);my $db = Hydra::Model::DB->new;hydra_setup($db);my $project = $db->resultset('Projects')->create({name => "tests", displayname => "", owner => "root"});my $jobset = createBaseJobset("basic", "basic.nix", $ctx{jobsdir});ok(evalSucceeds($jobset), "Evaluating jobs/basic.nix should exit with return code 0");is(nrQueuedBuildsForJobset($jobset), 3, "Evaluating jobs/basic.nix should result in 3 builds");for my $build (queuedBuildsForJobset($jobset)) {ok(runBuild($build), "Build '".$build->job."' from jobs/basic.nix should exit with return code 0");}subtest "Parsing step_finished" => sub {like(dies { Hydra::Event::parse_payload("step_finished", "") },qr/three arguments/,"empty payload");like(dies { Hydra::Event::parse_payload("step_finished", "abc123") },qr/three arguments/,"one argument");like(dies { Hydra::Event::parse_payload("step_finished", "abc123\tabc123") },qr/three arguments/,"two arguments");like(dies { Hydra::Event::parse_payload("step_finished", "abc123\tabc123\tabc123\tabc123") },qr/three arguments/,"four arguments");like(dies { Hydra::Event::parse_payload("step_finished", "abc123\t123\t/path/to/log") },qr/should be an integer/,"not an integer: first position");like(dies { Hydra::Event::parse_payload("step_finished", "123\tabc123\t/path/to/log") },qr/should be an integer/,"not an integer: second argument");is(Hydra::Event::parse_payload("step_finished", "123\t456\t/path/to/logfile"),Hydra::Event::StepFinished->new(123, 456, "/path/to/logfile"));};subtest "load" => sub {my $step = $db->resultset('BuildSteps')->search({ },{ limit => 1 })->next;my $build = $step->build;my $event = Hydra::Event::StepFinished->new($build->id, $step->stepnr, "/foo/bar/baz");$event->load($db);is($event->{"step"}->get_column("build"), $build->id, "The build record matches.");# Create a fake "plugin" with a stepFinished sub, the sub sets this# "global" passedStep, passedLogPath variables.my $passedStep;my $passedLogPath;my $plugin = {};my $mock = mock_obj $plugin => (add => ["stepFinished" => sub {my ($self, $step, $log_path) = @_;$passedStep = $step;$passedLogPath = $log_path;}]);$event->execute($db, $plugin);is($passedStep->get_column("build"), $build->id, "The plugin's stepFinished hook is called with a step from the expected build");is($passedStep->stepnr, $step->stepnr, "The plugin's stepFinished hook is called with the proper step of the build");is($passedLogPath, "/foo/bar/baz", "The plugin's stepFinished hook is called with the proper log path");};done_testing; - edit in t/Event.t at line 4
use Hydra::Event::StepFinished; - edit in t/Event.t at line 15
subtest "Payload type: step_finished" => sub {like(dies { Hydra::Event::parse_payload("step_finished", "") },qr/three arguments/,"empty payload");like(dies { Hydra::Event::parse_payload("step_finished", "abc123") },qr/three arguments/,"one argument");like(dies { Hydra::Event::parse_payload("step_finished", "abc123\tabc123") },qr/three arguments/,"two arguments");like(dies { Hydra::Event::parse_payload("step_finished", "abc123\tabc123\tabc123\tabc123") },qr/three arguments/,"four arguments");like(dies { Hydra::Event::parse_payload("step_finished", "abc123\t123\t/path/to/log") },qr/should be an integer/,"not an integer: first position");like(dies { Hydra::Event::parse_payload("step_finished", "123\tabc123\t/path/to/log") },qr/should be an integer/,"not an integer: second argument");is(Hydra::Event::parse_payload("step_finished", "123\t456\t/path/to/logfile"),Hydra::Event::StepFinished->new(123, 456, "/path/to/logfile"));};