117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require 'spec_helper'
 | |
| 
 | |
| # This spec only runs if a Redis Cluster is configured for Gitlab::Redis::Cache.
 | |
| # ::Redis::Cluster fetches the cluster details from the server on `initialize` and will raise
 | |
| # an error if the cluster is not found.
 | |
| #
 | |
| # An example would be the following in config/redis.yml assuming gdk is set up with redis-cluster.
 | |
| # test:
 | |
| #   cache
 | |
| #     cluster:
 | |
| #       - "redis://127.0.0.1:6003"
 | |
| #       - "redis://127.0.0.1:6004"
 | |
| #       - "redis://127.0.0.1:6005"
 | |
| RSpec.describe Gitlab::Redis::ClusterStore, :clean_gitlab_redis_cache,
 | |
|   feature_category: :redis, if: ::Gitlab::Redis::Cache.params[:nodes] do
 | |
|   let(:params) { ::Gitlab::Redis::Cache.params }
 | |
| 
 | |
|   subject(:store) { ::Redis::Store::Factory.create(params) } # rubocop:disable Rails/SaveBang -- not a rails method
 | |
| 
 | |
|   describe '.new' do
 | |
|     it 'initialises a cluster store' do
 | |
|       expect(store).to be_instance_of(::Gitlab::Redis::ClusterStore)
 | |
|     end
 | |
| 
 | |
|     it 'extends Serialization by default' do
 | |
|       expect(store.is_a?(::Redis::Store::Serialization)).to eq(true)
 | |
|     end
 | |
| 
 | |
|     it 'sets a default serializer when left empty' do
 | |
|       expect(store.instance_variable_get(:@serializer)).to eq(Marshal)
 | |
|     end
 | |
| 
 | |
|     context 'when serializer field is defined' do
 | |
|       let(:params) { ::Gitlab::Redis::Cache.params.merge(serializer: Class) }
 | |
| 
 | |
|       it 'sets serializer according to the options' do
 | |
|         expect(store.instance_variable_get(:@serializer)).to eq(Class)
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when marshalling field is defined' do
 | |
|       let(:params) { ::Gitlab::Redis::Cache.params.merge(marshalling: true, serializer: Class) }
 | |
| 
 | |
|       it 'overrides serializer with Marshal' do
 | |
|         expect(store.instance_variable_get(:@serializer)).to eq(Marshal)
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when marshalling field is false' do
 | |
|       let(:params) { ::Gitlab::Redis::Cache.params.merge(marshalling: false, serializer: Class) }
 | |
| 
 | |
|       it 'overrides serializer with Marshal' do
 | |
|         expect(store.instance_variable_get(:@serializer)).to eq(nil)
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when namespace is defined' do
 | |
|       let(:params) { ::Gitlab::Redis::Cache.params.merge(namespace: 'testing') }
 | |
| 
 | |
|       it 'extends namespace' do
 | |
|         expect(store.is_a?(::Redis::Store::Namespace)).to eq(true)
 | |
|       end
 | |
| 
 | |
|       it 'write keys with namespace' do
 | |
|         store.set('testkey', 1)
 | |
| 
 | |
|         ::Gitlab::Redis::Cache.with do |conn|
 | |
|           expect(conn.exists('testing:testkey')).to eq(1)
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#set' do
 | |
|     context 'when ttl is added' do
 | |
|       it 'writes the key and sets a ttl' do
 | |
|         expect(store.set('test', 1, expire_after: 100)).to eq('OK')
 | |
| 
 | |
|         expect(store.ttl('test')).to be > 95
 | |
|         expect(store.get('test')).to eq(1)
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when there is no ttl' do
 | |
|       it 'sets the key' do
 | |
|         expect(store.set('test', 1)).to eq('OK')
 | |
| 
 | |
|         expect(store.get('test')).to eq(1)
 | |
|         expect(store.ttl('test')).to eq(-1)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '#setnx' do
 | |
|     context 'when ttl is added' do
 | |
|       it 'writes the key if not exists and sets a ttl' do
 | |
|         expect(store.setnx('test', 1, expire_after: 100)).to eq([true, true])
 | |
|         expect(store.ttl('test')).to be > 95
 | |
|         expect(store.get('test')).to eq(1)
 | |
|         expect(store.setnx('test', 1, expire_after: 100)).to eq([false, true])
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when there is no ttl' do
 | |
|       it 'writes the key if not exists' do
 | |
|         expect(store.setnx('test', 1)).to eq(true)
 | |
|         expect(store.setnx('test', 1)).to eq(false)
 | |
| 
 | |
|         expect(store.get('test')).to eq(1)
 | |
|         expect(store.ttl('test')).to eq(-1)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 |