summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/container_repository/tags/cache_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/container_repository/tags/cache_spec.rb')
-rw-r--r--spec/lib/gitlab/container_repository/tags/cache_spec.rb133
1 files changed, 133 insertions, 0 deletions
diff --git a/spec/lib/gitlab/container_repository/tags/cache_spec.rb b/spec/lib/gitlab/container_repository/tags/cache_spec.rb
new file mode 100644
index 00000000000..f84c1ce173f
--- /dev/null
+++ b/spec/lib/gitlab/container_repository/tags/cache_spec.rb
@@ -0,0 +1,133 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Gitlab::ContainerRepository::Tags::Cache, :clean_gitlab_redis_cache do
+ let_it_be(:dummy_tag_class) { Struct.new(:name, :created_at) }
+ let_it_be(:repository) { create(:container_repository) }
+
+ let(:tags) { create_tags(5) }
+ let(:service) { described_class.new(repository) }
+
+ shared_examples 'not interacting with redis' do
+ it 'does not interact with redis' do
+ expect(::Gitlab::Redis::Cache).not_to receive(:with)
+
+ subject
+ end
+ end
+
+ describe '#populate' do
+ subject { service.populate(tags) }
+
+ context 'with tags' do
+ it 'gets values from redis' do
+ expect(::Gitlab::Redis::Cache).to receive(:with).and_call_original
+
+ expect(subject).to eq(0)
+
+ tags.each { |t| expect(t.created_at).to eq(nil) }
+ end
+
+ context 'with cached values' do
+ let(:cached_tags) { tags.first(2) }
+
+ before do
+ ::Gitlab::Redis::Cache.with do |redis|
+ cached_tags.each do |tag|
+ redis.set(cache_key(tag), rfc3339(10.days.ago))
+ end
+ end
+ end
+
+ it 'gets values from redis' do
+ expect(::Gitlab::Redis::Cache).to receive(:with).and_call_original
+
+ expect(subject).to eq(2)
+
+ cached_tags.each { |t| expect(t.created_at).not_to eq(nil) }
+ (tags - cached_tags).each { |t| expect(t.created_at).to eq(nil) }
+ end
+ end
+ end
+
+ context 'with no tags' do
+ let(:tags) { [] }
+
+ it_behaves_like 'not interacting with redis'
+ end
+ end
+
+ describe '#insert' do
+ let(:max_ttl) { 90.days }
+
+ subject { service.insert(tags, max_ttl) }
+
+ context 'with tags' do
+ let(:tag) { tags.first }
+ let(:ttl) { 90.days - 3.days }
+
+ before do
+ travel_to(Time.zone.local(2021, 9, 2, 12, 0, 0))
+
+ tag.created_at = DateTime.rfc3339(3.days.ago.rfc3339)
+ end
+
+ after do
+ travel_back
+ end
+
+ it 'inserts values in redis' do
+ ::Gitlab::Redis::Cache.with do |redis|
+ expect(redis)
+ .to receive(:set)
+ .with(cache_key(tag), rfc3339(tag.created_at), ex: ttl.to_i)
+ .and_call_original
+ end
+
+ subject
+ end
+
+ context 'with some of them already cached' do
+ let(:tag) { tags.first }
+
+ before do
+ ::Gitlab::Redis::Cache.with do |redis|
+ redis.set(cache_key(tag), rfc3339(10.days.ago))
+ end
+ service.populate(tags)
+ end
+
+ it_behaves_like 'not interacting with redis'
+ end
+ end
+
+ context 'with no tags' do
+ let(:tags) { [] }
+
+ it_behaves_like 'not interacting with redis'
+ end
+
+ context 'with no expires_in' do
+ let(:max_ttl) { nil }
+
+ it_behaves_like 'not interacting with redis'
+ end
+ end
+
+ def create_tags(size)
+ Array.new(size) do |i|
+ dummy_tag_class.new("Tag #{i}", nil)
+ end
+ end
+
+ def cache_key(tag)
+ "container_repository:{#{repository.id}}:tag:#{tag.name}:created_at"
+ end
+
+ def rfc3339(date_time)
+ # DateTime rfc3339 is different ActiveSupport::TimeWithZone rfc3339
+ # The caching will use DateTime rfc3339
+ DateTime.rfc3339(date_time.rfc3339).rfc3339
+ end
+end