diff options
Diffstat (limited to 'spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb')
-rw-r--r-- | spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb | 75 |
1 files changed, 44 insertions, 31 deletions
diff --git a/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb b/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb index a20bb794095..f98be12523d 100644 --- a/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb +++ b/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb @@ -14,13 +14,14 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| counter_attributes.each do |attribute| describe attribute do describe '#increment_counter', :redis do - let(:increment) { 10 } + let(:amount) { 10 } + let(:increment) { Gitlab::Counters::Increment.new(amount: amount) } let(:counter_key) { model.counter(attribute).key } subject { model.increment_counter(attribute, increment) } context 'when attribute is a counter attribute' do - where(:increment) { [10, -3] } + where(:amount) { [10, -3] } with_them do it 'increments the counter in Redis and logs it' do @@ -29,8 +30,8 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| message: 'Increment counter attribute', attribute: attribute, project_id: model.project_id, - increment: increment, - new_counter_value: 0 + increment, + increment: amount, + new_counter_value: 0 + amount, current_db_value: model.read_attribute(attribute), 'correlation_id' => an_instance_of(String), 'meta.feature_category' => 'test', @@ -42,7 +43,7 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| Gitlab::Redis::SharedState.with do |redis| counter = redis.get(counter_key) - expect(counter).to eq(increment.to_s) + expect(counter).to eq(amount.to_s) end end @@ -59,8 +60,8 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| end end - context 'when increment is 0' do - let(:increment) { 0 } + context 'when increment amount is 0' do + let(:amount) { 0 } it 'does nothing' do expect(FlushCounterIncrementsWorker).not_to receive(:perform_in) @@ -71,37 +72,49 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| end end end - end - end - describe '#reset_counter!' do - let(:attribute) { counter_attributes.first } - let(:counter_key) { model.counter(attribute).key } + describe '#bulk_increment_counter', :redis do + let(:increments) { [Gitlab::Counters::Increment.new(amount: 10), Gitlab::Counters::Increment.new(amount: 5)] } + let(:total_amount) { increments.sum(&:amount) } + let(:counter_key) { model.counter(attribute).key } - before do - model.update!(attribute => 123) - model.increment_counter(attribute, 10) - end + subject { model.bulk_increment_counter(attribute, increments) } - subject { model.reset_counter!(attribute) } + context 'when attribute is a counter attribute' do + it 'increments the counter in Redis and logs it' do + expect(Gitlab::AppLogger).to receive(:info).with( + hash_including( + message: 'Increment counter attribute', + attribute: attribute, + project_id: model.project_id, + increment: total_amount, + new_counter_value: 0 + total_amount, + current_db_value: model.read_attribute(attribute), + 'correlation_id' => an_instance_of(String), + 'meta.feature_category' => 'test', + 'meta.caller_id' => 'caller' + ) + ) - it 'resets the attribute value to 0 and clears existing counter', :aggregate_failures do - expect { subject }.to change { model.reload.send(attribute) }.from(123).to(0) + subject - Gitlab::Redis::SharedState.with do |redis| - key_exists = redis.exists?(counter_key) - expect(key_exists).to be_falsey - end - end + Gitlab::Redis::SharedState.with do |redis| + counter = redis.get(counter_key) + expect(counter).to eq(total_amount.to_s) + end + end - it_behaves_like 'obtaining lease to update database' do - context 'when the execution raises error' do - before do - allow(model).to receive(:update!).and_raise(StandardError, 'Something went wrong') - end + it 'does not increment the counter for the record' do + expect { subject }.not_to change { model.reset.read_attribute(attribute) } + end - it 'reraises error' do - expect { subject }.to raise_error(StandardError, 'Something went wrong') + it 'schedules a worker to flush counter increments asynchronously' do + expect(FlushCounterIncrementsWorker).to receive(:perform_in) + .with(Gitlab::Counters::BufferedCounter::WORKER_DELAY, model.class.name, model.id, attribute) + .and_call_original + + subject + end end end end |