diff options
Diffstat (limited to 'spec/models/namespace')
-rw-r--r-- | spec/models/namespace/admin_note_spec.rb | 16 | ||||
-rw-r--r-- | spec/models/namespace/traversal_hierarchy_spec.rb | 56 |
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 |