diff options
Diffstat (limited to 'spec/lib/gitlab/redis')
-rw-r--r-- | spec/lib/gitlab/redis/cache_spec.rb | 17 | ||||
-rw-r--r-- | spec/lib/gitlab/redis/multi_store_spec.rb | 219 | ||||
-rw-r--r-- | spec/lib/gitlab/redis/rate_limiting_spec.rb | 15 | ||||
-rw-r--r-- | spec/lib/gitlab/redis/repository_cache_spec.rb | 15 |
4 files changed, 28 insertions, 238 deletions
diff --git a/spec/lib/gitlab/redis/cache_spec.rb b/spec/lib/gitlab/redis/cache_spec.rb index 64615c4d9ad..82ff8a26199 100644 --- a/spec/lib/gitlab/redis/cache_spec.rb +++ b/spec/lib/gitlab/redis/cache_spec.rb @@ -26,22 +26,5 @@ RSpec.describe Gitlab::Redis::Cache do expect(described_class.active_support_config[:expires_in]).to eq(1.day) end - - context 'when encountering an error' do - let(:cache) { ActiveSupport::Cache::RedisCacheStore.new(**described_class.active_support_config) } - - subject { cache.read('x') } - - before do - described_class.with do |redis| - allow(redis).to receive(:get).and_raise(::Redis::CommandError) - end - end - - it 'logs error' do - expect(::Gitlab::ErrorTracking).to receive(:log_exception) - subject - end - end end end diff --git a/spec/lib/gitlab/redis/multi_store_spec.rb b/spec/lib/gitlab/redis/multi_store_spec.rb index 423a7e80ead..baf2546fc5c 100644 --- a/spec/lib/gitlab/redis/multi_store_spec.rb +++ b/spec/lib/gitlab/redis/multi_store_spec.rb @@ -210,47 +210,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do end end - RSpec.shared_examples_for 'fallback read from the non-default store' do - let(:counter) { Gitlab::Metrics::NullMetric.instance } - - before do - allow(Gitlab::Metrics).to receive(:counter).and_return(counter) - end - - it 'fallback and execute on secondary instance' do - expect(multi_store.fallback_store).to receive(name).with(*expected_args).and_call_original - - subject - end - - it 'logs the ReadFromPrimaryError' do - expect(Gitlab::ErrorTracking).to receive(:log_exception).with( - an_instance_of(Gitlab::Redis::MultiStore::ReadFromPrimaryError), - hash_including(command_name: name, instance_name: instance_name) - ) - - subject - end - - it 'increment read fallback count metrics' do - expect(counter).to receive(:increment).with(command: name, instance_name: instance_name) - - subject - end - - include_examples 'reads correct value' - - context 'when fallback read from the secondary instance raises an exception' do - before do - allow(multi_store.fallback_store).to receive(name).with(*expected_args).and_raise(StandardError) - end - - it 'fails with exception' do - expect { subject }.to raise_error(StandardError) - end - end - end - RSpec.shared_examples_for 'secondary store' do it 'execute on the secondary instance' do expect(secondary_store).to receive(name).with(*expected_args).and_call_original @@ -283,31 +242,21 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do subject end - unless params[:block] - it 'does not execute on the secondary store' do - expect(secondary_store).not_to receive(name) - - subject - end - end - include_examples 'reads correct value' end - context 'when reading from primary instance is raising an exception' do + context 'when reading from default instance is raising an exception' do before do allow(multi_store.default_store).to receive(name).with(*expected_args).and_raise(StandardError) allow(Gitlab::ErrorTracking).to receive(:log_exception) end - it 'logs the exception' do + it 'logs the exception and re-raises the error' do expect(Gitlab::ErrorTracking).to receive(:log_exception).with(an_instance_of(StandardError), hash_including(:multi_store_error_message, instance_name: instance_name, command_name: name)) - subject + expect { subject }.to raise_error(an_instance_of(StandardError)) end - - include_examples 'fallback read from the non-default store' end context 'when reading from empty default instance' do @@ -316,7 +265,9 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do multi_store.default_store.flushdb end - include_examples 'fallback read from the non-default store' + it 'does not call the fallback store' do + expect(multi_store.fallback_store).not_to receive(name) + end end context 'when the command is executed within pipelined block' do @@ -346,16 +297,16 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do end context 'when block is provided' do - it 'both stores yields to the block' do + it 'only default store yields to the block' do expect(primary_store).to receive(name).and_yield(value) - expect(secondary_store).to receive(name).and_yield(value) + expect(secondary_store).not_to receive(name).and_yield(value) subject end - it 'both stores to execute' do + it 'only default store to execute' do expect(primary_store).to receive(name).with(*expected_args).and_call_original - expect(secondary_store).to receive(name).with(*expected_args).and_call_original + expect(secondary_store).not_to receive(name).with(*expected_args).and_call_original subject end @@ -421,27 +372,19 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do subject do multi_store.mget(values) do |v| multi_store.sadd(skey, v) - multi_store.scard(skey) - end - end - - RSpec.shared_examples_for 'primary instance executes block' do - it 'ensures primary instance is executing the block' do - expect(primary_store).to receive(:send).with(:mget, values).and_call_original - expect(primary_store).to receive(:send).with(:sadd, skey, %w[1 2 3]).and_call_original - expect(primary_store).to receive(:send).with(:scard, skey).and_call_original - - expect(secondary_store).to receive(:send).with(:mget, values).and_call_original - expect(secondary_store).to receive(:send).with(:sadd, skey, %w[10 20 30]).and_call_original - expect(secondary_store).to receive(:send).with(:scard, skey).and_call_original - - subject end end context 'when using both stores' do context 'when primary instance is default store' do - it_behaves_like 'primary instance executes block' + it 'ensures primary instance is executing the block' do + expect(primary_store).to receive(:send).with(:mget, values).and_call_original + expect(primary_store).to receive(:send).with(:sadd, skey, %w[1 2 3]).and_call_original + + expect(secondary_store).not_to receive(:send) + + subject + end end context 'when secondary instance is default store' do @@ -449,8 +392,14 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do stub_feature_flags(use_primary_store_as_default_for_test_store: false) end - # multistore read still favours the primary store - it_behaves_like 'primary instance executes block' + it 'ensures secondary instance is executing the block' do + expect(primary_store).not_to receive(:send) + + expect(secondary_store).to receive(:send).with(:mget, values).and_call_original + expect(secondary_store).to receive(:send).with(:sadd, skey, %w[10 20 30]).and_call_original + + subject + end end end @@ -465,7 +414,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do expect(primary_store).to receive(:send).with(:mget, values).and_call_original expect(primary_store).to receive(:send).with(:sadd, skey, %w[1 2 3]).and_call_original - expect(primary_store).to receive(:send).with(:scard, skey).and_call_original subject end @@ -479,7 +427,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do it 'ensures only secondary instance is executing the block' do expect(secondary_store).to receive(:send).with(:mget, values).and_call_original expect(secondary_store).to receive(:send).with(:sadd, skey, %w[10 20 30]).and_call_original - expect(secondary_store).to receive(:send).with(:scard, skey).and_call_original expect(primary_store).not_to receive(:send) @@ -668,120 +615,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do end # rubocop:enable RSpec/MultipleMemoizedHelpers - context 'with ENUMERATOR_COMMANDS redis commands' do - let_it_be(:hkey) { "redis:hash" } - let_it_be(:skey) { "redis:set" } - let_it_be(:zkey) { "redis:sortedset" } - let_it_be(:rvalue) { "value1" } - let_it_be(:scan_kwargs) { { match: 'redis:hash' } } - - where(:case_name, :name, :args, :kwargs) do - 'execute :scan_each command' | :scan_each | nil | ref(:scan_kwargs) - 'execute :sscan_each command' | :sscan_each | ref(:skey) | {} - 'execute :hscan_each command' | :hscan_each | ref(:hkey) | {} - 'execute :zscan_each command' | :zscan_each | ref(:zkey) | {} - end - - before(:all) do - primary_store.hset(hkey, rvalue, 1) - primary_store.sadd?(skey, rvalue) - primary_store.zadd(zkey, 1, rvalue) - - secondary_store.hset(hkey, rvalue, 1) - secondary_store.sadd?(skey, rvalue) - secondary_store.zadd(zkey, 1, rvalue) - end - - RSpec.shared_examples_for 'enumerator commands execution' do |both_stores, default_primary| - context 'without block passed in' do - subject do - multi_store.send(name, *args, **kwargs) - end - - it 'returns an enumerator' do - expect(subject).to be_instance_of(Enumerator) - end - end - - context 'with block passed in' do - subject do - multi_store.send(name, *args, **kwargs) { |key| multi_store.incr(rvalue) } - end - - it 'returns nil' do - expect(subject).to eq(nil) - end - - it 'runs block on correct Redis instance' do - if both_stores - expect(primary_store).to receive(name).with(*expected_args).and_call_original - expect(secondary_store).to receive(name).with(*expected_args).and_call_original - - expect(primary_store).to receive(:incr).with(rvalue) - expect(secondary_store).to receive(:incr).with(rvalue) - elsif default_primary - expect(primary_store).to receive(name).with(*expected_args).and_call_original - expect(primary_store).to receive(:incr).with(rvalue) - - expect(secondary_store).not_to receive(name) - expect(secondary_store).not_to receive(:incr).with(rvalue) - else - expect(secondary_store).to receive(name).with(*expected_args).and_call_original - expect(secondary_store).to receive(:incr).with(rvalue) - - expect(primary_store).not_to receive(name) - expect(primary_store).not_to receive(:incr).with(rvalue) - end - - subject - end - end - end - - with_them do - describe name.to_s do - let(:expected_args) { kwargs.present? ? [*args, { **kwargs }] : Array(args) } - - before do - allow(primary_store).to receive(name).and_call_original - allow(secondary_store).to receive(name).and_call_original - end - - context 'when only using 1 store' do - before do - stub_feature_flags(use_primary_and_secondary_stores_for_test_store: false) - end - - context 'when using secondary store as default' do - before do - stub_feature_flags(use_primary_store_as_default_for_test_store: false) - end - - it_behaves_like 'enumerator commands execution', false, false - end - - context 'when using primary store as default' do - it_behaves_like 'enumerator commands execution', false, true - end - end - - context 'when using both stores' do - context 'when using secondary store as default' do - before do - stub_feature_flags(use_primary_store_as_default_for_test_store: false) - end - - it_behaves_like 'enumerator commands execution', true, false - end - - context 'when using primary store as default' do - it_behaves_like 'enumerator commands execution', true, true - end - end - end - end - end - RSpec.shared_examples_for 'pipelined command' do |name| let_it_be(:key1) { "redis:{1}:key_a" } let_it_be(:value1) { "redis_value1" } diff --git a/spec/lib/gitlab/redis/rate_limiting_spec.rb b/spec/lib/gitlab/redis/rate_limiting_spec.rb index d82228426f0..0bea7f8bcb2 100644 --- a/spec/lib/gitlab/redis/rate_limiting_spec.rb +++ b/spec/lib/gitlab/redis/rate_limiting_spec.rb @@ -6,19 +6,8 @@ RSpec.describe Gitlab::Redis::RateLimiting do include_examples "redis_new_instance_shared_examples", 'rate_limiting', Gitlab::Redis::Cache describe '.cache_store' do - context 'when encountering an error' do - subject { described_class.cache_store.read('x') } - - before do - described_class.with do |redis| - allow(redis).to receive(:get).and_raise(::Redis::CommandError) - end - end - - it 'logs error' do - expect(::Gitlab::ErrorTracking).to receive(:log_exception) - subject - end + it 'uses the CACHE_NAMESPACE namespace' do + expect(described_class.cache_store.options[:namespace]).to eq(Gitlab::Redis::Cache::CACHE_NAMESPACE) end end end diff --git a/spec/lib/gitlab/redis/repository_cache_spec.rb b/spec/lib/gitlab/redis/repository_cache_spec.rb index 2c167a6eb62..8cdc4580f9e 100644 --- a/spec/lib/gitlab/redis/repository_cache_spec.rb +++ b/spec/lib/gitlab/redis/repository_cache_spec.rb @@ -17,20 +17,5 @@ RSpec.describe Gitlab::Redis::RepositoryCache, feature_category: :scalability do it 'has a default ttl of 8 hours' do expect(described_class.cache_store.options[:expires_in]).to eq(8.hours) end - - context 'when encountering an error' do - subject { described_class.cache_store.read('x') } - - before do - described_class.with do |redis| - allow(redis).to receive(:get).and_raise(::Redis::CommandError) - end - end - - it 'logs error' do - expect(::Gitlab::ErrorTracking).to receive(:log_exception) - subject - end - end end end |