summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/query_limiting/transaction_spec.rb
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2018-02-09 18:12:20 +0800
committerLin Jen-Shin <godfat@godfat.org>2018-02-09 18:12:20 +0800
commit09a3b8fb655ac673a5d706548d13c26cdb53aa9f (patch)
tree1de0f5552cf1235587cc36f59c1ddc92c1a50752 /spec/lib/gitlab/query_limiting/transaction_spec.rb
parent1264e2b6e8ce53f578255e9296875947845431bf (diff)
parent7534f7a892d6e8c50475720e387b8689c94582da (diff)
downloadgitlab-ce-09a3b8fb655ac673a5d706548d13c26cdb53aa9f.tar.gz
Merge remote-tracking branch 'upstream/master' into qa-clone-with-deploy-key
* upstream/master: (466 commits) Set initial password for instance in LDAP QA test Backport EE changes to some hashed storage documentation to CE Remove allow_n_plus_1 from Git::Repository#branches_filter Bumps Gitlab Shell version to 6.0.3 Make resetting column information overridable in EE Added 'clear' button to ci lint editor Issues and merge requests in subgroups docs Update docs labels CE Refactored merge_requests/show path in dispatcher.js wording don't check against a hardcoded user name 10.5 Update the dependencies license list 10.5 Update the .gitignore, .gitlab-ci.yml, and Dockerfile templates Create update guide for 10.5 Update 10.5 source install guide Add docs for MR link in commit page Add groups to OpenID Connect claims Replaced $.get with axois.get Memoize MergeRequest#rebase_in_progress? to prevent N+1 queries in Gitaly Update style_guide_scss.md ...
Diffstat (limited to 'spec/lib/gitlab/query_limiting/transaction_spec.rb')
-rw-r--r--spec/lib/gitlab/query_limiting/transaction_spec.rb144
1 files changed, 144 insertions, 0 deletions
diff --git a/spec/lib/gitlab/query_limiting/transaction_spec.rb b/spec/lib/gitlab/query_limiting/transaction_spec.rb
new file mode 100644
index 00000000000..b4231fcd0fa
--- /dev/null
+++ b/spec/lib/gitlab/query_limiting/transaction_spec.rb
@@ -0,0 +1,144 @@
+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