summaryrefslogtreecommitdiff
path: root/spec/models/internal_id_spec.rb
diff options
context:
space:
mode:
authorAndreas Brandl <abrandl@gitlab.com>2018-04-16 11:19:56 +0200
committerAndreas Brandl <abrandl@gitlab.com>2018-04-16 13:59:20 +0200
commit14acbf245582a1821896b94b567c5ca8ba064d4a (patch)
treecb07cd7ba1e7ec7c482a70f5c129813cc9f9fecc /spec/models/internal_id_spec.rb
parentc3e26860be156314e733a6dfb986c91fc55766f5 (diff)
downloadgitlab-ce-14acbf245582a1821896b94b567c5ca8ba064d4a.tar.gz
Double-check next value for internal ids.
This is useful for a transition period to migrate away from `NoninternalAtomicId`. In a situation where both the old and new code to generate a iid value is run at the same time (for example, during a deploy different nodes may serve both versions), this will lead to problems regarding the correct `last_value`. That is, what we track in `InternalId` may get out of sync with the maximum iid present for issues. With this change, we double-check that and correct the `last_value` with the maximum iid found in issues if necessary. This is subject to be removed with the 10.8 release and tracked over here: https://gitlab.com/gitlab-org/gitlab-ce/issues/45389 Closes #45269.
Diffstat (limited to 'spec/models/internal_id_spec.rb')
-rw-r--r--spec/models/internal_id_spec.rb37
1 files changed, 35 insertions, 2 deletions
diff --git a/spec/models/internal_id_spec.rb b/spec/models/internal_id_spec.rb
index 581fd0293cc..8ef91e8fab5 100644
--- a/spec/models/internal_id_spec.rb
+++ b/spec/models/internal_id_spec.rb
@@ -5,7 +5,7 @@ describe InternalId do
let(:usage) { :issues }
let(:issue) { build(:issue, project: project) }
let(:scope) { { project: project } }
- let(:init) { ->(s) { s.project.issues.size } }
+ let(:init) { ->(s) { s.project.issues.maximum(:iid) } }
context 'validations' do
it { is_expected.to validate_presence_of(:usage) }
@@ -39,6 +39,29 @@ describe InternalId do
end
end
+ context 'with an InternalId record present and existing issues with a higher internal id' do
+ # This can happen if the old NonatomicInternalId is still in use
+ before do
+ issues = Array.new(rand(1..10)).map { create(:issue, project: project) }
+
+ issue = issues.last
+ issue.iid = issues.map { |i| i.iid }.max + 1
+ issue.save
+ end
+
+ let(:maximum_iid) { project.issues.map { |i| i.iid }.max }
+
+ it 'updates last_value to the maximum internal id present' do
+ subject
+
+ expect(described_class.find_by(project: project, usage: described_class.usages[usage.to_s]).last_value).to eq(maximum_iid + 1)
+ end
+
+ it 'returns next internal id correctly' do
+ expect(subject).to eq(maximum_iid + 1)
+ end
+ end
+
context 'with concurrent inserts on table' do
it 'looks up the record if it was created concurrently' do
args = { **scope, usage: described_class.usages[usage.to_s] }
@@ -81,7 +104,8 @@ describe InternalId do
describe '#increment_and_save!' do
let(:id) { create(:internal_id) }
- subject { id.increment_and_save! }
+ let(:maximum_iid) { nil }
+ subject { id.increment_and_save!(maximum_iid) }
it 'returns incremented iid' do
value = id.last_value
@@ -102,5 +126,14 @@ describe InternalId do
expect(subject).to eq(1)
end
end
+
+ context 'with maximum_iid given' do
+ let(:id) { create(:internal_id, last_value: 1) }
+ let(:maximum_iid) { id.last_value + 10 }
+
+ it 'returns maximum_iid instead' do
+ expect(subject).to eq(12)
+ end
+ end
end
end