debian-mirror-gitlab/spec/lib/gitlab/cache/client_spec.rb
2023-05-27 22:25:52 +05:30

165 lines
4.3 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Cache::Client, feature_category: :source_code_management do
subject(:client) { described_class.new(metadata, backend: backend) }
let(:backend) { Rails.cache }
let(:metadata) do
Gitlab::Cache::Metadata.new(
caller_id: caller_id,
cache_identifier: cache_identifier,
feature_category: feature_category,
backing_resource: backing_resource
)
end
let(:caller_id) { 'caller-id' }
let(:cache_identifier) { 'MyClass#cache' }
let(:feature_category) { :source_code_management }
let(:backing_resource) { :cpu }
let(:metadata_mock) do
Gitlab::Cache::Metadata.new(
cache_identifier: cache_identifier,
feature_category: feature_category
)
end
let(:metrics_mock) { Gitlab::Cache::Metrics.new(metadata_mock) }
describe '.build_with_metadata' do
it 'builds a cache client with metrics support' do
attributes = {
caller_id: caller_id,
cache_identifier: cache_identifier,
feature_category: feature_category,
backing_resource: backing_resource
}
instance = described_class.build_with_metadata(**attributes)
expect(instance).to be_a(described_class)
expect(instance.metadata).to have_attributes(**attributes)
end
end
describe 'Methods', :use_clean_rails_memory_store_caching do
let(:expected_key) { 'key' }
before do
allow(Gitlab::Cache::Metrics).to receive(:new).and_return(metrics_mock)
end
describe '#read' do
context 'when key does not exist' do
it 'returns nil' do
expect(client.read('key')).to be_nil
end
it 'increments cache miss' do
expect(metrics_mock).to receive(:increment_cache_miss)
client.read('key')
end
end
context 'when key exists' do
before do
backend.write(expected_key, 'value')
end
it 'returns key value' do
expect(client.read('key')).to eq('value')
end
it 'increments cache hit' do
expect(metrics_mock).to receive(:increment_cache_hit)
client.read('key')
end
end
end
describe '#write' do
it 'calls backend "#write" method with the expected key' do
expect(backend).to receive(:write).with(expected_key, 'value')
client.write('key', 'value')
end
end
describe '#exist?' do
it 'calls backend "#exist?" method with the expected key' do
expect(backend).to receive(:exist?).with(expected_key)
client.exist?('key')
end
end
describe '#delete' do
it 'calls backend "#delete" method with the expected key' do
expect(backend).to receive(:delete).with(expected_key)
client.delete('key')
end
end
# rubocop:disable Style/RedundantFetchBlock
describe '#fetch' do
it 'creates key in the specific format' do
client.fetch('key') { 'value' }
expect(backend.fetch(expected_key)).to eq('value')
end
it 'yields the block once' do
expect { |b| client.fetch('key', &b) }.to yield_control.once
end
context 'when key already exists' do
before do
backend.write(expected_key, 'value')
end
it 'does not redefine the value' do
expect(client.fetch('key') { 'new-value' }).to eq('value')
end
it 'increments a cache hit' do
expect(metrics_mock).to receive(:increment_cache_hit)
client.fetch('key')
end
it 'does not measure the cache generation time' do
expect(metrics_mock).not_to receive(:observe_cache_generation)
client.fetch('key') { 'new-value' }
end
end
context 'when key does not exist' do
it 'caches the key' do
expect(client.fetch('key') { 'value' }).to eq('value')
expect(client.fetch('key')).to eq('value')
end
it 'increments a cache miss' do
expect(metrics_mock).to receive(:increment_cache_miss)
client.fetch('key')
end
it 'measures the cache generation time' do
expect(metrics_mock).to receive(:observe_cache_generation)
client.fetch('key') { 'value' }
end
end
end
end
# rubocop:enable Style/RedundantFetchBlock
end