gitlab-org--gitlab-foss/spec/lib/gitlab/query_limiting/transaction_spec.rb
Yorick Peterse cca61980d5
Track and act upon the number of executed queries
This ensures that we have more visibility in the number of SQL queries
that are executed in web requests. The current threshold is hardcoded to
100 as we will rarely (maybe once or twice) change it.

In production and development we use Sentry if enabled, in the test
environment we raise an error. This feature is also only enabled in
production/staging when running on GitLab.com as it's not very useful to
other users.
2018-02-01 17:00:46 +01:00

144 lines
3.8 KiB
Ruby

require 'spec_helper'
describe Gitlab::QueryLimiting::Transaction do
after do
Thread.current[described_class::THREAD_KEY] = nil
end
describe '.current' do
it 'returns nil when there is no transaction' do
expect(described_class.current).to be_nil
end
it 'returns the transaction when present' do
Thread.current[described_class::THREAD_KEY] = described_class.new
expect(described_class.current).to be_an_instance_of(described_class)
end
end
describe '.run' do
it 'runs a transaction and returns it and its return value' do
trans, ret = described_class.run do
10
end
expect(trans).to be_an_instance_of(described_class)
expect(ret).to eq(10)
end
it 'removes the transaction from the current thread upon completion' do
described_class.run do
10
end
expect(Thread.current[described_class::THREAD_KEY]).to be_nil
end
end
describe '#act_upon_results' do
context 'when the query threshold is not exceeded' do
it 'does nothing' do
trans = described_class.new
expect(trans).not_to receive(:raise)
trans.act_upon_results
end
end
context 'when the query threshold is exceeded' do
let(:transaction) do
trans = described_class.new
trans.count = described_class::THRESHOLD + 1
trans
end
it 'raises an error when this is enabled' do
expect { transaction.act_upon_results }
.to raise_error(described_class::ThresholdExceededError)
end
it 'reports the error in Sentry if raising an error is disabled' do
expect(transaction)
.to receive(:raise_error?)
.and_return(false)
expect(Raven)
.to receive(:capture_exception)
.with(an_instance_of(described_class::ThresholdExceededError))
transaction.act_upon_results
end
end
end
describe '#increment' do
it 'increments the number of executed queries' do
transaction = described_class.new
expect(transaction.count).to be_zero
transaction.increment
expect(transaction.count).to eq(1)
end
end
describe '#raise_error?' do
it 'returns true in a test environment' do
transaction = described_class.new
expect(transaction.raise_error?).to eq(true)
end
it 'returns false in a production environment' do
transaction = described_class.new
expect(Rails.env)
.to receive(:test?)
.and_return(false)
expect(transaction.raise_error?).to eq(false)
end
end
describe '#threshold_exceeded?' do
it 'returns false when the threshold is not exceeded' do
transaction = described_class.new
expect(transaction.threshold_exceeded?).to eq(false)
end
it 'returns true when the threshold is exceeded' do
transaction = described_class.new
transaction.count = described_class::THRESHOLD + 1
expect(transaction.threshold_exceeded?).to eq(true)
end
end
describe '#error_message' do
it 'returns the error message to display when the threshold is exceeded' do
transaction = described_class.new
transaction.count = max = described_class::THRESHOLD
expect(transaction.error_message).to eq(
"Too many SQL queries were executed: a maximum of #{max} " \
"is allowed but #{max} SQL queries were executed"
)
end
it 'includes the action name in the error message when present' do
transaction = described_class.new
transaction.count = max = described_class::THRESHOLD
transaction.action = 'UsersController#show'
expect(transaction.error_message).to eq(
"Too many SQL queries were executed in UsersController#show: " \
"a maximum of #{max} is allowed but #{max} SQL queries were executed"
)
end
end
end