From d195e545f5bb8debc49d6210a28f4f43eaa10fbd Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Mon, 20 Dec 2021 13:18:32 -0500 Subject: [PATCH] hydra-notify: listen for build_queued events --- src/lib/Hydra/Event.pm | 2 + src/lib/Hydra/Event/BuildQueued.pm | 47 ++++++++++++++++++++ src/script/hydra-notify | 1 + t/Event/BuildQueued.t | 69 ++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 src/lib/Hydra/Event/BuildQueued.pm create mode 100644 t/Event/BuildQueued.t diff --git a/src/lib/Hydra/Event.pm b/src/lib/Hydra/Event.pm index b14d74f4..938043fa 100644 --- a/src/lib/Hydra/Event.pm +++ b/src/lib/Hydra/Event.pm @@ -3,10 +3,12 @@ package Hydra::Event; use strict; use warnings; use Hydra::Event::BuildFinished; +use Hydra::Event::BuildQueued; use Hydra::Event::BuildStarted; use Hydra::Event::StepFinished; my %channels_to_events = ( + build_queued => \&Hydra::Event::BuildQueued::parse, build_started => \&Hydra::Event::BuildStarted::parse, step_finished => \&Hydra::Event::StepFinished::parse, build_finished => \&Hydra::Event::BuildFinished::parse, diff --git a/src/lib/Hydra/Event/BuildQueued.pm b/src/lib/Hydra/Event/BuildQueued.pm new file mode 100644 index 00000000..551203ad --- /dev/null +++ b/src/lib/Hydra/Event/BuildQueued.pm @@ -0,0 +1,47 @@ +package Hydra::Event::BuildQueued; + +use strict; +use warnings; + +sub parse :prototype(@) { + unless (@_ == 1) { + die "build_queued: payload takes only one argument, but ", scalar(@_), " were given"; + } + + my ($build_id) = @_; + + unless ($build_id =~ /^\d+$/) { + die "build_queued: payload argument should be an integer, but '", $build_id, "' was given" + } + + return Hydra::Event::BuildQueued->new(int($build_id)); +} + +sub new { + my ($self, $id) = @_; + return bless { + "build_id" => $id, + "build" => undef + }, $self; +} + +sub load { + my ($self, $db) = @_; + + if (!defined($self->{"build"})) { + $self->{"build"} = $db->resultset('Builds')->find($self->{"build_id"}) + or die "build $self->{'build_id'} does not exist\n"; + } +} + +sub execute { + my ($self, $db, $plugin) = @_; + + $self->load($db); + + $plugin->buildQueued($self->{"build"}); + + return 1; +} + +1; diff --git a/src/script/hydra-notify b/src/script/hydra-notify index f0ad7e6b..197652a0 100755 --- a/src/script/hydra-notify +++ b/src/script/hydra-notify @@ -93,6 +93,7 @@ my $task_dispatcher = Hydra::TaskDispatcher->new( my $dbh = $db->storage->dbh; my $listener = Hydra::PostgresListener->new($dbh); +$listener->subscribe("build_queued"); $listener->subscribe("build_started"); $listener->subscribe("build_finished"); $listener->subscribe("step_finished"); diff --git a/t/Event/BuildQueued.t b/t/Event/BuildQueued.t new file mode 100644 index 00000000..996114b9 --- /dev/null +++ b/t/Event/BuildQueued.t @@ -0,0 +1,69 @@ +use strict; +use warnings; +use Setup; +use Hydra::Event; +use Hydra::Event::BuildQueued; +use Test2::V0; +use Test2::Tools::Exception; +use Test2::Tools::Mock qw(mock_obj); + +my $ctx = test_context(); + +my $db = $ctx->db(); + +my $builds = $ctx->makeAndEvaluateJobset( + expression => "basic.nix" +); + +subtest "Parsing build_queued" => sub { + like( + dies { Hydra::Event::parse_payload("build_queued", "") }, + qr/one argument/, + "empty payload" + ); + like( + dies { Hydra::Event::parse_payload("build_queued", "abc123\tabc123") }, + qr/only one argument/, + "two arguments" + ); + + like( + dies { Hydra::Event::parse_payload("build_queued", "abc123") }, + qr/should be an integer/, + "not an integer" + ); + is( + Hydra::Event::parse_payload("build_queued", "19"), + Hydra::Event::BuildQueued->new(19), + "Valid parse" + ); +}; + +subtest "load" => sub { + my $build = $builds->{"empty_dir"}; + + my $event = Hydra::Event::BuildQueued->new($build->id); + + $event->load($db); + + is($event->{"build"}->id, $build->id, "The build record matches."); + + # Create a fake "plugin" with a buildQueued sub, the sub sets this + # global passedBuild variable. + my $passedBuild; + my $plugin = {}; + my $mock = mock_obj $plugin => ( + add => [ + "buildQueued" => sub { + my ($self, $build) = @_; + $passedBuild = $build; + } + ] + ); + + $event->execute($db, $plugin); + + is($passedBuild->id, $build->id, "The plugin's buildQueued hook is called with the proper build"); +}; + +done_testing;