Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-23 06:17:13 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-23 06:17:13 +0300
commita9fa13e4ba46e00081cec1f3af332edcd1520785 (patch)
tree1d3bca7bd91d7b121633cd3536c0d31031fdb7e6 /spec/services/web_hooks
parent6adb784bf2839a2b8a73de5602cbfe617836526c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/services/web_hooks')
-rw-r--r--spec/services/web_hooks/log_execution_service_spec.rb136
1 files changed, 136 insertions, 0 deletions
diff --git a/spec/services/web_hooks/log_execution_service_spec.rb b/spec/services/web_hooks/log_execution_service_spec.rb
new file mode 100644
index 00000000000..8dceba16432
--- /dev/null
+++ b/spec/services/web_hooks/log_execution_service_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WebHooks::LogExecutionService do
+ include ExclusiveLeaseHelpers
+
+ describe '#execute' do
+ around do |example|
+ travel_to(Time.current) { example.run }
+ end
+
+ let_it_be_with_reload(:project_hook) { create(:project_hook) }
+
+ let(:response_category) { :ok }
+ let(:data) do
+ {
+ trigger: 'trigger_name',
+ url: 'https://example.com',
+ request_headers: { 'Header' => 'header value' },
+ request_data: { 'Request Data' => 'request data value' },
+ response_body: 'Response body',
+ response_status: '200',
+ execution_duration: 1.2,
+ internal_error_message: 'error message'
+ }
+ end
+
+ subject(:service) { described_class.new(hook: project_hook, log_data: data, response_category: response_category) }
+
+ it 'logs the data' do
+ expect { service.execute }.to change(::WebHookLog, :count).by(1)
+
+ expect(WebHookLog.recent.first).to have_attributes(data)
+ end
+
+ it 'updates failure state using a lease that ensures fresh state is written' do
+ service = described_class.new(hook: project_hook, log_data: data, response_category: :error)
+ WebHook.find(project_hook.id).update!(backoff_count: 1)
+
+ lease_key = "web_hooks:update_hook_failure_state:#{project_hook.id}"
+ lease = stub_exclusive_lease(lease_key, timeout: described_class::LOCK_TTL)
+
+ expect(lease).to receive(:try_obtain)
+ expect(lease).to receive(:cancel)
+ expect { service.execute }.to change { WebHook.find(project_hook.id).backoff_count }.to(2)
+ end
+
+ context 'when response_category is :ok' do
+ it 'does not increment the failure count' do
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+
+ it 'does not change the disabled_until attribute' do
+ expect { service.execute }.not_to change(project_hook, :disabled_until)
+ end
+
+ context 'when the hook had previously failed' do
+ before do
+ project_hook.update!(recent_failures: 2)
+ end
+
+ it 'resets the failure count' do
+ expect { service.execute }.to change(project_hook, :recent_failures).to(0)
+ end
+ end
+ end
+
+ context 'when response_category is :failed' do
+ let(:response_category) { :failed }
+
+ it 'increments the failure count' do
+ expect { service.execute }.to change(project_hook, :recent_failures).by(1)
+ end
+
+ it 'does not change the disabled_until attribute' do
+ expect { service.execute }.not_to change(project_hook, :disabled_until)
+ end
+
+ it 'does not allow the failure count to overflow' do
+ project_hook.update!(recent_failures: 32767)
+
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+
+ context 'when the web_hooks_disable_failed FF is disabled' do
+ before do
+ # Hook will only be executed if the flag is disabled.
+ stub_feature_flags(web_hooks_disable_failed: false)
+ end
+
+ it 'does not allow the failure count to overflow' do
+ project_hook.update!(recent_failures: 32767)
+
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+ end
+ end
+
+ context 'when response_category is :error' do
+ let(:response_category) { :error }
+
+ it 'does not increment the failure count' do
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+
+ it 'backs off' do
+ expect { service.execute }.to change(project_hook, :disabled_until)
+ end
+
+ it 'increases the backoff count' do
+ expect { service.execute }.to change(project_hook, :backoff_count).by(1)
+ end
+
+ context 'when the previous cool-off was near the maximum' do
+ before do
+ project_hook.update!(disabled_until: 5.minutes.ago, backoff_count: 8)
+ end
+
+ it 'sets the disabled_until attribute' do
+ expect { service.execute }.to change(project_hook, :disabled_until).to(1.day.from_now)
+ end
+ end
+
+ context 'when we have backed-off many many times' do
+ before do
+ project_hook.update!(disabled_until: 5.minutes.ago, backoff_count: 365)
+ end
+
+ it 'sets the disabled_until attribute' do
+ expect { service.execute }.to change(project_hook, :disabled_until).to(1.day.from_now)
+ end
+ end
+ end
+ end
+end