2019-09-30 21:07:59 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2019-09-04 21:01:54 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe Gitlab::PhabricatorImport::Cache::Map, :clean_gitlab_redis_cache do
|
|
|
|
set(:project) { create(:project) }
|
|
|
|
let(:redis) { Gitlab::Redis::Cache }
|
2020-01-01 13:55:28 +05:30
|
|
|
|
2019-09-04 21:01:54 +05:30
|
|
|
subject(:map) { described_class.new(project) }
|
|
|
|
|
|
|
|
describe '#get_gitlab_model' do
|
|
|
|
it 'returns nil if there was nothing cached for the phabricator id' do
|
|
|
|
expect(map.get_gitlab_model('does not exist')).to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the object if it was set in redis' do
|
|
|
|
issue = create(:issue, project: project)
|
|
|
|
set_in_redis('exists', issue)
|
|
|
|
|
|
|
|
expect(map.get_gitlab_model('exists')).to eq(issue)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'extends the TTL for the cache key' do
|
|
|
|
set_in_redis('extend', create(:issue, project: project)) do |redis|
|
|
|
|
redis.expire(cache_key('extend'), 10.seconds.to_i)
|
|
|
|
end
|
|
|
|
|
|
|
|
map.get_gitlab_model('extend')
|
|
|
|
|
|
|
|
ttl = redis.with { |redis| redis.ttl(cache_key('extend')) }
|
|
|
|
|
|
|
|
expect(ttl).to be > 10.seconds
|
|
|
|
end
|
2019-09-30 21:07:59 +05:30
|
|
|
|
|
|
|
it 'sets the object in redis once if a block was given and nothing was cached' do
|
|
|
|
issue = create(:issue, project: project)
|
|
|
|
|
|
|
|
expect(map.get_gitlab_model('does not exist') { issue }).to eq(issue)
|
|
|
|
|
|
|
|
expect { |b| map.get_gitlab_model('does not exist', &b) }
|
|
|
|
.not_to yield_control
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not cache `nil` objects' do
|
|
|
|
expect(map).not_to receive(:set_gitlab_model)
|
|
|
|
|
|
|
|
map.get_gitlab_model('does not exist') { nil }
|
|
|
|
end
|
2019-09-04 21:01:54 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
describe '#set_gitlab_model' do
|
|
|
|
around do |example|
|
|
|
|
Timecop.freeze { example.run }
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the class and id in redis with a ttl' do
|
|
|
|
issue = create(:issue, project: project)
|
|
|
|
|
|
|
|
map.set_gitlab_model(issue, 'it is set')
|
|
|
|
|
|
|
|
set_data, ttl = redis.with do |redis|
|
|
|
|
redis.pipelined do |p|
|
|
|
|
p.mapped_hmget(cache_key('it is set'), :classname, :database_id)
|
|
|
|
p.ttl(cache_key('it is set'))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(set_data).to eq({ classname: 'Issue', database_id: issue.id.to_s })
|
|
|
|
expect(ttl).to be_within(1.second).of(StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_in_redis(key, object)
|
|
|
|
redis.with do |redis|
|
|
|
|
redis.mapped_hmset(cache_key(key),
|
|
|
|
{ classname: object.class, database_id: object.id })
|
|
|
|
yield(redis) if block_given?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def cache_key(phabricator_id)
|
|
|
|
subject.__send__(:cache_key_for_phabricator_id, phabricator_id)
|
|
|
|
end
|
|
|
|
end
|