summaryrefslogtreecommitdiff
path: root/spec/models/container_repository_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/container_repository_spec.rb')
-rw-r--r--spec/models/container_repository_spec.rb33
1 files changed, 31 insertions, 2 deletions
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index 846dfb30928..51fdbfebd3a 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -223,9 +223,9 @@ RSpec.describe ContainerRepository do
end
end
- describe '.create_from_path!' do
+ describe '.find_or_create_from_path' do
let(:repository) do
- described_class.create_from_path!(ContainerRegistry::Path.new(path))
+ described_class.find_or_create_from_path(ContainerRegistry::Path.new(path))
end
let(:repository_path) { ContainerRegistry::Path.new(path) }
@@ -291,6 +291,35 @@ RSpec.describe ContainerRepository do
expect(repository.id).to eq(container_repository.id)
end
end
+
+ context 'when many of the same repository are created at the same time' do
+ let(:path) { ContainerRegistry::Path.new(project.full_path + '/some/image') }
+
+ it 'does not throw validation errors and only creates one repository' do
+ expect { repository_creation_race(path) }.to change { ContainerRepository.count }.by(1)
+ end
+
+ it 'retrieves a persisted repository for all concurrent calls' do
+ repositories = repository_creation_race(path).map(&:value)
+
+ expect(repositories).to all(be_persisted)
+ end
+ end
+
+ def repository_creation_race(path)
+ # create a race condition - structure from https://blog.arkency.com/2015/09/testing-race-conditions/
+ wait_for_it = true
+
+ threads = Array.new(10) do |i|
+ Thread.new do
+ true while wait_for_it
+
+ ::ContainerRepository.find_or_create_from_path(path)
+ end
+ end
+ wait_for_it = false
+ threads.each(&:join)
+ end
end
describe '.build_root_repository' do