Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/namespace/traversal_hierarchy_spec.rb')
-rw-r--r--spec/models/namespace/traversal_hierarchy_spec.rb56
1 files changed, 49 insertions, 7 deletions
diff --git a/spec/models/namespace/traversal_hierarchy_spec.rb b/spec/models/namespace/traversal_hierarchy_spec.rb
index 83e6d704640..b166d541171 100644
--- a/spec/models/namespace/traversal_hierarchy_spec.rb
+++ b/spec/models/namespace/traversal_hierarchy_spec.rb
@@ -43,21 +43,63 @@ RSpec.describe Namespace::TraversalHierarchy, type: :model do
end
end
+ shared_examples 'locked update query' do
+ it 'locks query with FOR UPDATE' do
+ qr = ActiveRecord::QueryRecorder.new do
+ subject
+ end
+ expect(qr.count).to eq 1
+ expect(qr.log.first).to match /FOR UPDATE/
+ end
+ end
+
describe '#incorrect_traversal_ids' do
- subject { described_class.new(root).incorrect_traversal_ids }
+ let!(:hierarchy) { described_class.new(root) }
+
+ subject { hierarchy.incorrect_traversal_ids }
+
+ before do
+ Namespace.update_all(traversal_ids: [])
+ end
it { is_expected.to match_array Namespace.all }
+
+ context 'when lock is true' do
+ subject { hierarchy.incorrect_traversal_ids(lock: true).load }
+
+ it_behaves_like 'locked update query'
+ end
end
describe '#sync_traversal_ids!' do
- let(:hierarchy) { described_class.new(root) }
+ let!(:hierarchy) { described_class.new(root) }
- before do
- hierarchy.sync_traversal_ids!
- root.reload
- end
+ subject { hierarchy.sync_traversal_ids! }
- it_behaves_like 'hierarchy with traversal_ids'
it { expect(hierarchy.incorrect_traversal_ids).to be_empty }
+
+ it_behaves_like 'hierarchy with traversal_ids'
+ it_behaves_like 'locked update query'
+
+ context 'when deadlocked' do
+ before do
+ connection_double = double(:connection)
+
+ allow(Namespace).to receive(:connection).and_return(connection_double)
+ allow(connection_double).to receive(:exec_query) { raise ActiveRecord::Deadlocked.new }
+ end
+
+ it { expect { subject }.to raise_error(ActiveRecord::Deadlocked) }
+
+ it 'increment db_deadlock counter' do
+ expect { subject rescue nil }.to change { db_deadlock_total('Namespace#sync_traversal_ids!') }.by(1)
+ end
+ end
+ end
+
+ def db_deadlock_total(source)
+ Gitlab::Metrics
+ .counter(:db_deadlock, 'Counts the times we have deadlocked in the database')
+ .get(source: source)
end
end