Skip to content

Commit b987963

Browse files
committed
Emit restart events when job restarted automatically
Send an event through the task itself after the `auto_duplicate` when the job have been process and send for restart. While the `auto_duplicate` could be used as a single point for the event's emission it interferes with other functions which also emit events independently. For instance from the API restart, it processes the payload and adds data to it, so it left as is. Using the `restart_openqa_job` from the Restart module should not duplicate the event which is emitted by the API, which also invoke `auto_duplicate`. And it should also trigger the event when the job is processed and not while is queued. That should make sure that the event is send to AMQP for jobs with `RETRY` once it is actually triggered. issue: https://progress.opensuse.org/issues/190557 Signed-off-by: Ioannis Bonatakis <[email protected]>
1 parent faa0e5c commit b987963

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

lib/OpenQA/Task/Job/Restart.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ sub restart_delay { $ENV{OPENQA_JOB_RESTART_DELAY} // 5 }
1717
sub restart_openqa_job ($minion_job, $openqa_job) {
1818
my $cloned_job_or_error = $openqa_job->auto_duplicate;
1919
my $is_ok = ref $cloned_job_or_error || $cloned_job_or_error =~ qr/(already.*clone|direct parent)/i;
20+
OpenQA::Events->singleton->emit_event('job_restart', data => {id => $openqa_job->id}) if $is_ok;
2021
$minion_job->note(
2122
ref $cloned_job_or_error
2223
? (cluster_cloned => $cloned_job_or_error->{cluster_cloned})

t/10-jobs.t

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use OpenQA::Jobs::Constants;
1919
use OpenQA::Test::Case;
2020
use Test::MockModule 'strict';
2121
use Test::Mojo;
22+
use Test::Output;
2223
use Test::Warnings qw(:report_warnings warning);
2324
use Mojo::File 'path';
2425
use Mojo::JSON qw(decode_json encode_json);
@@ -899,7 +900,8 @@ subtest 'job setting based retriggering' => sub {
899900
my $finalize_job_count_before = @{$get_jobs->('finalize_job_results')};
900901
$job->update({state => SCHEDULED, result => NONE});
901902
$job->done(result => FAILED);
902-
perform_minion_jobs($minion);
903+
stdout_like { perform_minion_jobs($minion) } qr/Job \d+ duplicated as \d+/,
904+
'check debug message from auto_duplicate';
903905
is $jobs->count, $jobs_nr + 2, 'job retriggered as it FAILED (with retry)';
904906
$job->update;
905907
$job->discard_changes;

t/api/18-job-amqp-event.t

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env perl
2+
# Copyright SUSE LLC
3+
# SPDX-License-Identifier: GPL-2.0-or-later
4+
5+
use Test::Most;
6+
use FindBin;
7+
use lib "$FindBin::Bin/../lib", "$FindBin::Bin/../../external/os-autoinst-common/lib";
8+
use Mojo::Base -signatures;
9+
use Test::Mojo;
10+
use Test::MockModule;
11+
use Test::MockObject;
12+
use OpenQA::Test::Case;
13+
use OpenQA::Test::Client 'client';
14+
use Test::Output qw(combined_like);
15+
16+
OpenQA::Test::Case->new->init_data(fixtures_glob => '01-jobs.pl 03-users.pl');
17+
my $t = client(Test::Mojo->new('OpenQA::WebAPI'));
18+
my $jobs = $t->app->schema->resultset('Jobs');
19+
20+
subtest 'Jobs should emit exactly one event' => sub {
21+
my @emitted_events;
22+
my $mock_emit = Test::MockObject->new();
23+
$mock_emit->mock(
24+
emit => sub ($self, $type, $args) {
25+
my (undef, undef, undef, $data) = @$args;
26+
push @emitted_events, {type => $type, data => $data};
27+
});
28+
# include the events emitted by OpenQA::Events->singleton->emit_event()
29+
$mock_emit->mock(
30+
# uncoverable subroutine
31+
emit_event => sub ($self, $type, %args) { # uncoverable statement
32+
push @emitted_events, {type => $type, data => $args{data}}; # uncoverable statement
33+
});
34+
35+
my $mock_events = Test::MockModule->new('OpenQA::Events');
36+
$mock_events->redefine(singleton => sub { return $mock_emit });
37+
my $scheduler_mock = Test::MockModule->new('OpenQA::Scheduler::Client');
38+
$scheduler_mock->redefine(wakeup => sub { });
39+
40+
my %params = (TEST => 'event_test', DISTRI => 'foo', VERSION => 'bar', ARCH => 'baz');
41+
$t->post_ok('/api/v1/jobs', form => \%params)->status_is(200);
42+
my $job_id = $t->tx->res->json->{id};
43+
is(scalar @emitted_events, 1, 'exactly one event was emitted on create');
44+
is($emitted_events[0]->{data}{id}, $job_id, 'job_id is emitted on event');
45+
is($emitted_events[0]->{type}, 'openqa_job_create', 'data has correct event type');
46+
47+
@emitted_events = ();
48+
combined_like { $t->post_ok('/api/v1/jobs/99926/restart?force=1')->status_is(200) } qr/Job 99926 duplicated/,
49+
'Job restarted successfully';
50+
is(scalar @emitted_events, 1, 'exactly one event was emitted on restart');
51+
is($emitted_events[0]->{data}{id}, 99926, 'job_id is emitted on event');
52+
is($emitted_events[0]->{type}, 'openqa_job_restart', 'data has correct event type');
53+
};
54+
55+
done_testing;

0 commit comments

Comments
 (0)