debian-mirror-gitlab/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb
2021-11-18 22:05:49 +05:30

191 lines
5.7 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database::LoadBalancing::SidekiqClientMiddleware do
let(:middleware) { described_class.new }
let(:worker_class) { 'TestDataConsistencyWorker' }
let(:job) { { "job_id" => "a180b47c-3fd6-41b8-81e9-34da61c3400e" } }
before do
skip_feature_flags_yaml_validation
skip_default_enabled_yaml_check
end
after do
Gitlab::Database::LoadBalancing::Session.clear_session
end
def run_middleware
middleware.call(worker_class, job, nil, nil) {}
end
describe '#call', :database_replica do
shared_context 'data consistency worker class' do |data_consistency, feature_flag|
let(:expected_consistency) { data_consistency }
let(:worker_class) do
Class.new do
def self.name
'TestDataConsistencyWorker'
end
include ApplicationWorker
data_consistency data_consistency, feature_flag: feature_flag
def perform(*args)
end
end
end
before do
stub_const('TestDataConsistencyWorker', worker_class)
end
end
shared_examples_for 'job data consistency' do
it "sets job data consistency" do
run_middleware
expect(job['worker_data_consistency']).to eq(expected_consistency)
end
end
shared_examples_for 'does not pass database locations' do
it 'does not pass database locations', :aggregate_failures do
run_middleware
expect(job['wal_locations']).to be_nil
end
include_examples 'job data consistency'
end
shared_examples_for 'mark data consistency location' do |data_consistency|
include_context 'data consistency worker class', data_consistency, :load_balancing_for_test_data_consistency_worker
let(:location) { '0/D525E3A8' }
context 'when feature flag is disabled' do
let(:expected_consistency) { :always }
before do
stub_feature_flags(load_balancing_for_test_data_consistency_worker: false)
end
include_examples 'does not pass database locations'
end
context 'when write was not performed' do
before do
allow(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary?).and_return(false)
end
it 'passes database_replica_location' do
expected_location = {}
Gitlab::Database::LoadBalancing.each_load_balancer do |lb|
expect(lb.host)
.to receive(:database_replica_location)
.and_return(location)
expected_location[lb.name] = location
end
run_middleware
expect(job['wal_locations']).to eq(expected_location)
end
include_examples 'job data consistency'
end
context 'when write was performed' do
before do
allow(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary?).and_return(true)
end
it 'passes primary write location', :aggregate_failures do
expected_location = {}
Gitlab::Database::LoadBalancing.each_load_balancer do |lb|
expect(lb)
.to receive(:primary_write_location)
.and_return(location)
expected_location[lb.name] = location
end
run_middleware
expect(job['wal_locations']).to eq(expected_location)
end
include_examples 'job data consistency'
end
end
context 'when worker cannot be constantized' do
let(:worker_class) { 'ActionMailer::MailDeliveryJob' }
let(:expected_consistency) { :always }
include_examples 'does not pass database locations'
end
context 'when worker class does not include ApplicationWorker' do
let(:worker_class) { ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper }
let(:expected_consistency) { :always }
include_examples 'does not pass database locations'
end
context 'database wal location was already provided' do
let(:old_location) { '0/D525E3A8' }
let(:new_location) { 'AB/12345' }
let(:wal_locations) { { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => old_location } }
let(:job) { { "job_id" => "a180b47c-3fd6-41b8-81e9-34da61c3400e", 'wal_locations' => wal_locations } }
before do
Gitlab::Database::LoadBalancing.each_load_balancer do |lb|
allow(lb).to receive(:primary_write_location).and_return(new_location)
allow(lb).to receive(:database_replica_location).and_return(new_location)
end
end
shared_examples_for 'does not set database location again' do |use_primary|
before do
allow(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary?).and_return(use_primary)
end
it 'does not set database locations again' do
run_middleware
expect(job['wal_locations']).to eq(wal_locations)
end
end
context "when write was performed" do
include_examples 'does not set database location again', true
end
context "when write was not performed" do
include_examples 'does not set database location again', false
end
end
context 'when worker data consistency is :always' do
include_context 'data consistency worker class', :always, :load_balancing_for_test_data_consistency_worker
include_examples 'does not pass database locations'
end
context 'when worker data consistency is :delayed' do
include_examples 'mark data consistency location', :delayed
end
context 'when worker data consistency is :sticky' do
include_examples 'mark data consistency location', :sticky
end
end
end