Skip to content

Commit 8106ee7

Browse files
committed
Reset Deduplicable singleton caches in schema cache tests
The deduplication code can mask bugs -- if a new field gets added to the object but without it being added to the hash/equal methods then cache loading will appear to just work in tests, but in reality be broken. Here we reset the dedup registries before testing cache loading.
1 parent c8c8a0a commit 8106ee7

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

activerecord/test/cases/connection_adapters/schema_cache_test.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ class SchemaCacheTest < ActiveRecord::TestCase
88
self.use_transactional_tests = false
99

1010
def setup
11+
@deduplicable_registries_were = deduplicable_classes.index_with do |klass|
12+
klass.registry.dup
13+
end
1114
@pool = ARUnit2Model.connection_pool
1215
@connection = ARUnit2Model.lease_connection
1316
@cache = new_bound_reflection
@@ -16,18 +19,47 @@ def setup
1619

1720
def teardown
1821
SchemaReflection.check_schema_cache_dump_version = @check_schema_cache_dump_version_was
22+
@deduplicable_registries_were.each do |klass, registry|
23+
klass.registry.clear
24+
klass.registry.merge!(registry)
25+
end
1926
end
2027

2128
def new_bound_reflection(pool = @pool)
2229
BoundSchemaReflection.new(SchemaReflection.new(nil), pool)
2330
end
2431

2532
def load_bound_reflection(filename, pool = @pool)
33+
reset_deduplicable!
2634
BoundSchemaReflection.new(SchemaReflection.new(filename), pool).tap do |cache|
2735
cache.load!
2836
end
2937
end
3038

39+
def deduplicable_classes
40+
klasses = [
41+
ActiveRecord::ConnectionAdapters::SqlTypeMetadata,
42+
ActiveRecord::ConnectionAdapters::Column,
43+
]
44+
45+
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQL)
46+
klasses << ActiveRecord::ConnectionAdapters::PostgreSQL::TypeMetadata
47+
end
48+
if defined?(ActiveRecord::ConnectionAdapters::MySQL::TypeMetadata)
49+
klasses << ActiveRecord::ConnectionAdapters::MySQL::TypeMetadata
50+
end
51+
52+
klasses.flat_map do |klass|
53+
[klass] + klass.descendants
54+
end.uniq
55+
end
56+
57+
def reset_deduplicable!
58+
deduplicable_classes.each do |klass|
59+
klass.registry.clear
60+
end
61+
end
62+
3163
def test_cached?
3264
cache = new_bound_reflection
3365
assert_not cache.cached?("courses")
@@ -38,6 +70,8 @@ def test_cached?
3870
tempfile = Tempfile.new(["schema_cache-", ".yml"])
3971
cache.dump_to(tempfile.path)
4072

73+
reset_deduplicable!
74+
4175
reflection = SchemaReflection.new(tempfile.path)
4276

4377
# `check_schema_cache_dump_version` forces us to have an active connection
@@ -60,6 +94,8 @@ def test_yaml_dump_and_load
6094
# Dump it. It should get populated before dumping.
6195
cache.dump_to(tempfile.path)
6296

97+
reset_deduplicable!
98+
6399
# Load the cache.
64100
cache = load_bound_reflection(tempfile.path)
65101

@@ -94,6 +130,8 @@ def test_yaml_dump_and_load_with_gzip
94130
# Dump it. It should get populated before dumping.
95131
cache.dump_to(tempfile.path)
96132

133+
reset_deduplicable!
134+
97135
# Unzip and load manually.
98136
cache = Zlib::GzipReader.open(tempfile.path) do |gz|
99137
YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(gz.read) : YAML.load(gz.read)

0 commit comments

Comments
 (0)