1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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
|