diff options
Diffstat (limited to 'spec/workers/redis_migration_worker_spec.rb')
-rw-r--r-- | spec/workers/redis_migration_worker_spec.rb | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/spec/workers/redis_migration_worker_spec.rb b/spec/workers/redis_migration_worker_spec.rb new file mode 100644 index 00000000000..ad0186e929d --- /dev/null +++ b/spec/workers/redis_migration_worker_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe RedisMigrationWorker, :clean_gitlab_redis_shared_state, feature_category: :redis do + describe '.fetch_migrator!' do + it 'raise error if class does not exist' do + expect { described_class.fetch_migrator!('UnknownClass') }.to raise_error(NotImplementedError) + end + + context 'when class exists' do + it 'returns an instance' do + expect( + described_class.fetch_migrator!('BackfillProjectPipelineStatusTtl') + ).to be_a Gitlab::BackgroundMigration::Redis::BackfillProjectPipelineStatusTtl + end + end + end + + describe '#perform' do + let(:job_class_name) { 'SampleJob' } + let(:migrator_class) do + Class.new do + def perform(keys) + keys.each { |key| redis.set(key, "adjusted", ex: 10) } + end + + def scan_match_pattern + 'sample:*:pattern' + end + + def redis + ::Redis.new(::Gitlab::Redis::Cache.params) + end + end + end + + let(:migrator) { migrator_class.new } + + before do + allow(described_class).to receive(:fetch_migrator!).with(job_class_name).and_return(migrator) + + 100.times do |i| + migrator.redis.set("sample:#{i}:pattern", i) + end + end + + it 'runs migration logic on scanned keys' do + expect(migrator).to receive(:perform) + + subject.perform(job_class_name, '0') + end + + context 'when job exceeds deadline' do + before do + # stub Time.now to force the 3rd invocation to timeout + now = Time.now # rubocop:disable Rails/TimeZone + allow(Time).to receive(:now).and_return(now, now, now + 5.minutes) + end + + it 'enqueues another job and returns' do + expect(described_class).to receive(:perform_async) + + # use smaller scan_size to ensure multiple scans are required + subject.perform(job_class_name, '0', { scan_size: 10 }) + end + end + + it_behaves_like 'an idempotent worker' do + let(:job_args) { [job_class_name, '0'] } + end + end +end |