Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit bc49e08

Browse files
author
Derik Evangelista
authored
v3(binding): better message when unique constraint is violated (cloudfoundry#1918)
[#175012888](https://www.pivotaltracker.com/story/show/175012888)
1 parent 241e452 commit bc49e08

3 files changed

Lines changed: 20 additions & 6 deletions

File tree

app/actions/service_credential_binding_create.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ def precursor(service_instance, app: nil, name: nil, volume_mount_services_enabl
3636
}
3737
)
3838
end
39-
rescue Sequel::ValidationFailed => e
40-
already_bound! if e.message =~ /The app is already bound to the service/
39+
rescue Sequel::ValidationFailed, Sequel::UniqueConstraintViolation => e
40+
already_bound! if e.message =~ /The app is already bound to the service|unique_service_binding_service_instance_guid_app_guid/
4141
raise UnprocessableCreate.new(e.full_message)
4242
end
4343

spec/support/shared_examples/v3_service_binding_create.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
action.bind(precursor)
2020

2121
binding = precursor.reload
22-
expect(binding).to eq(binding_model.first)
22+
expect(binding).to eq(binding_model.where(guid: binding.guid).first)
2323
expect(binding.service_instance).to eq(service_instance)
2424
expect(binding.last_operation.type).to eq('create')
2525
expect(binding.last_operation.state).to eq('succeeded')

spec/unit/actions/service_credential_binding_create_spec.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require 'db_spec_helper'
1+
require 'spec_helper'
22
require 'actions/service_credential_binding_create'
33
require 'support/shared_examples/v3_service_binding_create'
44
require 'cloud_controller/user_audit_info'
@@ -26,7 +26,7 @@ module V3
2626
it 'returns a service credential binding precursor' do
2727
binding = action.precursor(service_instance, app: app, name: details[:name])
2828
expect(binding).to be
29-
expect(binding).to eq(ServiceBinding.first)
29+
expect(binding).to eq(ServiceBinding.where(guid: binding.guid).first)
3030
expect(binding.service_instance).to eq(service_instance)
3131
expect(binding.app).to eq(app)
3232
expect(binding.name).to eq(details[:name])
@@ -51,6 +51,20 @@ module V3
5151
)
5252
end
5353

54+
it 'only creates one binding when creating bindings in parallel' do
55+
errors = []
56+
threads = 3.times.map do |i|
57+
Thread.new do
58+
action.precursor(service_instance, app: app, name: "binding-#{i}")
59+
rescue => e
60+
errors << e
61+
end
62+
end
63+
threads.each(&:join)
64+
expect(errors).to have(2).items
65+
expect(errors.map(&:message).uniq).to contain_exactly('The app is already bound to the service instance')
66+
end
67+
5468
it 'raises an error when a the app and the instance are in different spaces' do
5569
another_space = Space.make
5670
another_app = AppModel.make(space: another_space)
@@ -180,7 +194,7 @@ module V3
180194
action.bind(precursor)
181195

182196
precursor.reload
183-
expect(precursor).to eq(ServiceBinding.first)
197+
expect(precursor).to eq(ServiceBinding.where(guid: precursor.guid).first)
184198
expect(precursor.credentials).to eq(details[:credentials])
185199
expect(precursor.syslog_drain_url).to eq(details[:syslog_drain_url])
186200
expect(precursor.last_operation.type).to eq('create')

0 commit comments

Comments
 (0)