Skip to content

Commit

Permalink
Add test that reproduces lazy cache invalidation bug
Browse files Browse the repository at this point in the history
  • Loading branch information
jbourassa committed Jan 6, 2020
1 parent 2eaeb5c commit 28ac7a1
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 1 deletion.
2 changes: 2 additions & 0 deletions test/helpers/active_record_objects.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ def teardown_models
Object.send(:remove_const, 'Deeply')
Object.send(:remove_const, 'CustomMasterRecord')
Object.send(:remove_const, 'CustomChildRecord')
Object.send(:remove_const, 'LazyModel')
$LOADED_FEATURES.reject! { |feature| feature.include?("test/helpers/lazy_model/") }
IdentityCache.const_get(:ParentModelExpiration).send(:lazy_hooks).clear
end
end
5 changes: 4 additions & 1 deletion test/helpers/database_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ def self.create_tables
custom_master_records: [[:integer, :master_primary_key], id: false, primary_key: 'master_primary_key'],
custom_child_records: [
[:integer, :child_primary_key], [:integer, :master_id], id: false, primary_key: 'child_primary_key'
]
],
lazy_as: [[:string, :name]],
lazy_bs: [[:string, :name], [:integer, :a_id]],
lazy_cs: [[:string, :name], [:integer, :b_id]],
}

DEFAULT_CONFIG = {
Expand Down
8 changes: 8 additions & 0 deletions test/helpers/lazy_model/a.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module LazyModel
class A < ActiveRecord::Base
self.table_name = "lazy_as"
include IdentityCache
has_many :bs, class_name: "::LazyModel::B"
cache_has_many :bs, embed: true
end
end
9 changes: 9 additions & 0 deletions test/helpers/lazy_model/b.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module LazyModel
class B < ActiveRecord::Base
self.table_name = "lazy_bs"
include IdentityCache
belongs_to :a, class_name: "::LazyModel::A", inverse_of: :bs
has_one :c, class_name: "::LazyModel::C", inverse_of: :b
cache_has_one :c
end
end
7 changes: 7 additions & 0 deletions test/helpers/lazy_model/c.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module LazyModel
class C < ActiveRecord::Base
self.table_name = "lazy_cs"
include IdentityCache
belongs_to :b, class_name: "::LazyModel::B", inverse_of: :c
end
end
6 changes: 6 additions & 0 deletions test/helpers/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,9 @@ class CustomChildRecord < ActiveRecord::Base
belongs_to :custom_master_record, foreign_key: :master_id
self.primary_key = 'child_primary_key'
end

module LazyModel
autoload :A, "helpers/lazy_model/a.rb"
autoload :B, "helpers/lazy_model/b.rb"
autoload :C, "helpers/lazy_model/c.rb"
end
44 changes: 44 additions & 0 deletions test/lazy_hook_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require "test_helper"

class LazyHookTest < IdentityCache::TestCase
def test_expires_unloaded_lazy_parent_models
# Populate cache
a = LazyModel::A.create!(name: "Initial A")
b = a.bs.create!(name: "Initial B")
c = b.create_c!(name: "Initial C")

ids = {
a: a.id,
b: b.id,
c: c.id,
}

# Warm cache
LazyModel::A.fetch(ids[:a]).fetch_bs.first.fetch_c

# Clear lazyloaded code to simulate code that isn't eager loaded
reset_loaded_code
LazyModel::C.find(ids[:c]).update!(name: "Updated C")

refute(lazy_model_loaded?(:A))
refute(lazy_model_loaded?(:B))

queries = count_queries do
c = LazyModel::A.fetch(ids[:a]).fetch_bs.first.fetch_c
assert_equal("Updated C", c.name)
end

assert_equal(0, queries)
end

private

def reset_loaded_code
teardown_models
setup_models
end

def lazy_model_loaded?(name)
!LazyModel.autoload?(name)
end
end

0 comments on commit 28ac7a1

Please sign in to comment.