From 95da28d201b9a9536331abe1fce6e7e571f3ff4a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 7 Feb 2024 09:53:29 -0500 Subject: [PATCH] Add common `ThreadingHelper` module for specs (#29116) --- spec/lib/request_pool_spec.rb | 14 ++++----- spec/models/account_spec.rb | 13 ++------ spec/models/concerns/account/counters_spec.rb | 30 +++++-------------- spec/rails_helper.rb | 1 + spec/services/resolve_account_service_spec.rb | 22 +++++--------- spec/support/threading_helpers.rb | 17 +++++++++++ 6 files changed, 40 insertions(+), 57 deletions(-) create mode 100644 spec/support/threading_helpers.rb diff --git a/spec/lib/request_pool_spec.rb b/spec/lib/request_pool_spec.rb index a31d07832..a82eb5a18 100644 --- a/spec/lib/request_pool_spec.rb +++ b/spec/lib/request_pool_spec.rb @@ -33,18 +33,14 @@ describe RequestPool do subject - threads = Array.new(5) do - Thread.new do - subject.with('http://example.com') do |http_client| - http_client.get('/').flush - # Nudge scheduler to yield and exercise the full pool - sleep(0.01) - end + multi_threaded_execution(5) do + subject.with('http://example.com') do |http_client| + http_client.get('/').flush + # Nudge scheduler to yield and exercise the full pool + sleep(0.01) end end - threads.map(&:join) - expect(subject.size).to be > 1 end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 7ef5ca94c..b1dca52dc 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1035,19 +1035,10 @@ RSpec.describe Account do it 'increments the count in multi-threaded an environment when account_stat is not yet initialized' do subject - increment_by = 15 - wait_for_start = true - - threads = Array.new(increment_by) do - Thread.new do - true while wait_for_start - described_class.find(subject.id).increment_count!(:followers_count) - end + multi_threaded_execution(15) do + described_class.find(subject.id).increment_count!(:followers_count) end - wait_for_start = false - threads.each(&:join) - expect(subject.reload.followers_count).to eq 15 end end diff --git a/spec/models/concerns/account/counters_spec.rb b/spec/models/concerns/account/counters_spec.rb index 2e1cd700b..3c063a2fa 100644 --- a/spec/models/concerns/account/counters_spec.rb +++ b/spec/models/concerns/account/counters_spec.rb @@ -6,6 +6,8 @@ describe Account::Counters do let!(:account) { Fabricate(:account) } describe '#increment_count!' do + let(:increment_by) { 15 } + it 'increments the count' do expect(account.followers_count).to eq 0 account.increment_count!(:followers_count) @@ -13,24 +15,17 @@ describe Account::Counters do end it 'increments the count in multi-threaded an environment' do - increment_by = 15 - wait_for_start = true - - threads = Array.new(increment_by) do - Thread.new do - true while wait_for_start - account.increment_count!(:statuses_count) - end + multi_threaded_execution(increment_by) do + account.increment_count!(:statuses_count) end - wait_for_start = false - threads.each(&:join) - expect(account.statuses_count).to eq increment_by end end describe '#decrement_count!' do + let(:decrement_by) { 10 } + it 'decrements the count' do account.followers_count = 15 account.save! @@ -40,22 +35,13 @@ describe Account::Counters do end it 'decrements the count in multi-threaded an environment' do - decrement_by = 10 - wait_for_start = true - account.statuses_count = 15 account.save! - threads = Array.new(decrement_by) do - Thread.new do - true while wait_for_start - account.decrement_count!(:statuses_count) - end + multi_threaded_execution(decrement_by) do + account.decrement_count!(:statuses_count) end - wait_for_start = false - threads.each(&:join) - expect(account.statuses_count).to eq 5 end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 512533909..cde5a439d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -86,6 +86,7 @@ RSpec.configure do |config| config.include ActiveSupport::Testing::TimeHelpers config.include Chewy::Rspec::Helpers config.include Redisable + config.include ThreadingHelpers config.include SignedRequestHelpers, type: :request config.include CommandLineHelpers, type: :cli diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index 1c4c3b401..b82e5b386 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -219,27 +219,19 @@ RSpec.describe ResolveAccountService, type: :service do end it 'processes one remote account at a time using locks' do - wait_for_start = true fail_occurred = false return_values = Concurrent::Array.new - threads = Array.new(5) do - Thread.new do - true while wait_for_start - - begin - return_values << described_class.new.call('foo@ap.example.com') - rescue ActiveRecord::RecordNotUnique - fail_occurred = true - ensure - RedisConfiguration.pool.checkin if Thread.current[:redis] - end + multi_threaded_execution(5) do + begin + return_values << described_class.new.call('foo@ap.example.com') + rescue ActiveRecord::RecordNotUnique + fail_occurred = true + ensure + RedisConfiguration.pool.checkin if Thread.current[:redis] end end - wait_for_start = false - threads.each(&:join) - expect(fail_occurred).to be false expect(return_values).to_not include(nil) end diff --git a/spec/support/threading_helpers.rb b/spec/support/threading_helpers.rb new file mode 100644 index 000000000..edf45822c --- /dev/null +++ b/spec/support/threading_helpers.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module ThreadingHelpers + def multi_threaded_execution(thread_count) + wait_for_start = true + + threads = Array.new(thread_count) do + Thread.new do + true while wait_for_start + yield + end + end + + wait_for_start = false + threads.each(&:join) + end +end