2021-03-11 19:13:27 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
require 'spec_helper'
|
2021-03-11 19:13:27 +05:30
|
|
|
|
|
|
|
RSpec.describe Gitlab::Cluster::LifecycleEvents do
|
2023-01-13 00:05:48 +05:30
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
2021-03-11 19:13:27 +05:30
|
|
|
# we create a new instance to ensure that we do not touch existing hooks
|
|
|
|
let(:replica) { Class.new(described_class) }
|
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
before do
|
|
|
|
# disable blackout period to speed-up tests
|
|
|
|
stub_config(shutdown: { blackout_seconds: 0 })
|
|
|
|
end
|
2021-03-11 19:13:27 +05:30
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
context 'outside of clustered environments' do
|
|
|
|
where(:hook, :was_executed_immediately) do
|
|
|
|
:on_worker_start | true
|
|
|
|
:on_before_fork | false
|
|
|
|
:on_before_graceful_shutdown | false
|
|
|
|
:on_before_master_restart | false
|
|
|
|
:on_worker_stop | false
|
2021-03-11 19:13:27 +05:30
|
|
|
end
|
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
with_them do
|
|
|
|
it 'executes the given block immediately' do
|
|
|
|
was_executed = false
|
|
|
|
replica.public_send(hook, &proc { was_executed = true })
|
|
|
|
|
|
|
|
expect(was_executed).to eq(was_executed_immediately)
|
|
|
|
end
|
2021-03-11 19:13:27 +05:30
|
|
|
end
|
2023-01-13 00:05:48 +05:30
|
|
|
end
|
2021-03-11 19:13:27 +05:30
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
context 'in clustered environments' do
|
|
|
|
before do
|
|
|
|
allow(Gitlab::Runtime).to receive(:puma?).and_return(true)
|
|
|
|
replica.set_puma_options(workers: 2)
|
|
|
|
end
|
2021-03-11 19:13:27 +05:30
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
where(:hook, :execution_helper) do
|
|
|
|
:on_worker_start | :do_worker_start
|
|
|
|
:on_before_fork | :do_before_fork
|
|
|
|
:on_before_graceful_shutdown | :do_before_graceful_shutdown
|
|
|
|
:on_before_master_restart | :do_before_master_restart
|
|
|
|
:on_worker_stop | :do_worker_stop
|
|
|
|
end
|
2021-03-11 19:13:27 +05:30
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
with_them do
|
|
|
|
it 'requires explicit execution via do_* helper' do
|
|
|
|
was_executed = false
|
|
|
|
replica.public_send(hook, &proc { was_executed = true })
|
2021-03-11 19:13:27 +05:30
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
expect { replica.public_send(execution_helper) }.to change { was_executed }.from(false).to(true)
|
2021-03-11 19:13:27 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#call' do
|
|
|
|
let(:name) { :my_hooks }
|
|
|
|
|
|
|
|
subject { replica.send(:call, name, hooks) }
|
|
|
|
|
|
|
|
context 'when many hooks raise exception' do
|
|
|
|
let(:hooks) do
|
|
|
|
[
|
|
|
|
-> { raise 'Exception A' },
|
|
|
|
-> { raise 'Exception B' }
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'USE_FATAL_LIFECYCLE_EVENTS is set to default' do
|
|
|
|
it 'only first hook is executed and is fatal' do
|
|
|
|
expect(hooks[0]).to receive(:call).and_call_original
|
|
|
|
expect(hooks[1]).not_to receive(:call)
|
|
|
|
|
|
|
|
expect(Gitlab::ErrorTracking).to receive(:track_exception).and_call_original
|
|
|
|
expect(replica).to receive(:warn).with('ERROR: The hook my_hooks failed with exception (RuntimeError) "Exception A".')
|
|
|
|
|
|
|
|
expect { subject }.to raise_error(described_class::FatalError, 'Exception A')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when USE_FATAL_LIFECYCLE_EVENTS is disabled' do
|
|
|
|
before do
|
|
|
|
stub_const('Gitlab::Cluster::LifecycleEvents::USE_FATAL_LIFECYCLE_EVENTS', false)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'many hooks are executed and all exceptions are logged' do
|
|
|
|
expect(hooks[0]).to receive(:call).and_call_original
|
|
|
|
expect(hooks[1]).to receive(:call).and_call_original
|
|
|
|
|
|
|
|
expect(Gitlab::ErrorTracking).to receive(:track_exception).twice.and_call_original
|
|
|
|
expect(replica).to receive(:warn).twice.and_call_original
|
|
|
|
|
|
|
|
expect { subject }.not_to raise_error
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|