Skip to content

Commit 028e945

Browse files
johhaphilippthun
andauthored
Fix ignored unique constraint error name (#4648)
* Fix ignored unique constraint error name Also add tests to ensure that `ignored_unique_constraint_violation_errors` is set correctly. * Add shared example for ignored_unique_constraint_violation_errors This iterates through all constraints that are listed as 'ignorable' and checks if they actually exist in the database - either as a primary key constraint or as an index. * Use 'ignored_unique_constraint_violation_errors' shared example --------- Co-authored-by: Philipp Thun <philipp.thun@sap.com>
1 parent f75acb0 commit 028e945

File tree

6 files changed

+44
-1
lines changed

6 files changed

+44
-1
lines changed

app/models/runtime/security_group.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class SecurityGroup < Sequel::Model
1212

1313
serialize_attributes :json, :rules
1414

15-
many_to_many :spaces, ignored_unique_constraint_violation_errors: %w[ignored_unique_constraint_violation_errors]
15+
many_to_many :spaces, ignored_unique_constraint_violation_errors: %w[security_groups_spaces_ids]
1616
many_to_many :staging_spaces,
1717
class: 'VCAP::CloudController::Space',
1818
join_table: 'staging_security_groups_spaces',
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
RSpec::Matchers.define :have_primary_key_constraint do |table_name, constraint_name|
2+
match do |db|
3+
!db.fetch('SELECT 1 AS one FROM information_schema.table_constraints ' \
4+
"WHERE constraint_type = 'PRIMARY KEY' " \
5+
"AND table_name = '#{table_name}' " \
6+
"AND constraint_name = '#{constraint_name}';").
7+
get(:one).nil?
8+
end
9+
end
10+
11+
RSpec.shared_examples 'ignored_unique_constraint_violation_errors' do |association, db|
12+
it 'ignores unique constraint violation errors in the many_to_many relationship definition' do
13+
constraint_names = association[:ignored_unique_constraint_violation_errors]
14+
table_name = association[:join_table]
15+
16+
constraint_names.each do |constraint_name|
17+
case constraint_name
18+
when /_pk$/ # PostgreSQL primary key
19+
next unless db.database_type == :postgres
20+
21+
expect(db).to have_primary_key_constraint(table_name, constraint_name)
22+
when /\.PRIMARY$/ # MySQL primary key
23+
next unless db.database_type == :mysql
24+
25+
tn, cn = constraint_name.split('.', 2)
26+
expect(tn.to_sym).to equal(table_name)
27+
expect(db).to have_primary_key_constraint(tn, cn)
28+
else
29+
expect(db.indexes(table_name)).to include(constraint_name.to_sym)
30+
end
31+
end
32+
end
33+
end

spec/unit/models/runtime/domain_spec.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ module VCAP::CloudController
3636
expect(domain.shared_organizations).to include(org)
3737
end
3838

39+
include_examples 'ignored_unique_constraint_violation_errors', Domain.association_reflection(:shared_organizations), Domain.db
40+
3941
context 'when the domain is a shared domain' do
4042
it 'fails validation' do
4143
domain = Domain.make(owning_organization_id: nil)

spec/unit/models/runtime/route_spec.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ module VCAP::CloudController
113113
it { is_expected.to have_associated :space, associated_instance: ->(route) { Space.make(organization: route.domain.owning_organization) } }
114114
it { is_expected.to have_associated :route_mappings, associated_instance: ->(route) { RouteMappingModel.make(app: AppModel.make(space: route.space), route: route) } }
115115

116+
include_examples 'ignored_unique_constraint_violation_errors', Route.association_reflection(:shared_spaces), Route.db
117+
116118
describe 'apps association' do
117119
let(:space) { Space.make }
118120
let(:process) { ProcessModelFactory.make(space:) }

spec/unit/models/runtime/security_group_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ def build_all_rule(attrs={})
421421

422422
expect { security_group.destroy }.not_to raise_error
423423
end
424+
425+
include_examples 'ignored_unique_constraint_violation_errors', SecurityGroup.association_reflection(:spaces), SecurityGroup.db
424426
end
425427

426428
describe 'staging_spaces' do
@@ -432,6 +434,8 @@ def build_all_rule(attrs={})
432434

433435
expect { security_group.destroy }.not_to raise_error
434436
end
437+
438+
include_examples 'ignored_unique_constraint_violation_errors', SecurityGroup.association_reflection(:staging_spaces), SecurityGroup.db
435439
end
436440
end
437441

spec/unit/models/services/service_instance_spec.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ module VCAP::CloudController
149149
UserProvidedServiceInstance.make(name: 'shared-service', space: space)
150150
end.to raise_error(Sequel::ValidationFailed, /name unique/)
151151
end
152+
153+
include_examples 'ignored_unique_constraint_violation_errors', ManagedServiceInstance.association_reflection(:shared_spaces), ManagedServiceInstance.db
152154
end
153155
end
154156
end

0 commit comments

Comments
 (0)