summaryrefslogtreecommitdiff
path: root/spec/models/namespace
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/namespace')
-rw-r--r--spec/models/namespace/admin_note_spec.rb16
-rw-r--r--spec/models/namespace/traversal_hierarchy_spec.rb56
2 files changed, 65 insertions, 7 deletions
diff --git a/spec/models/namespace/admin_note_spec.rb b/spec/models/namespace/admin_note_spec.rb
new file mode 100644
index 00000000000..65ba1f61416
--- /dev/null
+++ b/spec/models/namespace/admin_note_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Namespace::AdminNote, type: :model do
+ let!(:namespace) { create(:namespace) }
+
+ describe 'associations' do
+ it { is_expected.to belong_to :namespace }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:namespace) }
+ it { is_expected.to validate_length_of(:note).is_at_most(1000) }
+ end
+end
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