aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/test/caching_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/test/caching_test.rb')
-rw-r--r--activesupport/test/caching_test.rb1194
1 files changed, 0 insertions, 1194 deletions
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
deleted file mode 100644
index ec7d028d7e..0000000000
--- a/activesupport/test/caching_test.rb
+++ /dev/null
@@ -1,1194 +0,0 @@
-require 'logger'
-require 'abstract_unit'
-require 'active_support/cache'
-require 'dependencies_test_helpers'
-
-module ActiveSupport
- module Cache
- module Strategy
- module LocalCache
- class MiddlewareTest < ActiveSupport::TestCase
- def test_local_cache_cleared_on_close
- key = "super awesome key"
- assert_nil LocalCacheRegistry.cache_for key
- middleware = Middleware.new('<3', key).new(->(env) {
- assert LocalCacheRegistry.cache_for(key), 'should have a cache'
- [200, {}, []]
- })
- _, _, body = middleware.call({})
- assert LocalCacheRegistry.cache_for(key), 'should still have a cache'
- body.each { }
- assert LocalCacheRegistry.cache_for(key), 'should still have a cache'
- body.close
- assert_nil LocalCacheRegistry.cache_for(key)
- end
-
- def test_local_cache_cleared_on_exception
- key = "super awesome key"
- assert_nil LocalCacheRegistry.cache_for key
- middleware = Middleware.new('<3', key).new(->(env) {
- assert LocalCacheRegistry.cache_for(key), 'should have a cache'
- raise
- })
- assert_raises(RuntimeError) { middleware.call({}) }
- assert_nil LocalCacheRegistry.cache_for(key)
- end
- end
- end
- end
- end
-end
-
-class CacheKeyTest < ActiveSupport::TestCase
- def test_entry_legacy_optional_ivars
- legacy = Class.new(ActiveSupport::Cache::Entry) do
- def initialize(value, options = {})
- @value = value
- @expires_in = nil
- @created_at = nil
- super
- end
- end
-
- entry = legacy.new 'foo'
- assert_equal 'foo', entry.value
- end
-
- def test_expand_cache_key
- assert_equal '1/2/true', ActiveSupport::Cache.expand_cache_key([1, '2', true])
- assert_equal 'name/1/2/true', ActiveSupport::Cache.expand_cache_key([1, '2', true], :name)
- end
-
- def test_expand_cache_key_with_rails_cache_id
- with_env('RAILS_CACHE_ID' => 'c99') do
- assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo)
- assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key([:foo])
- assert_equal 'c99/foo/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar])
- assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key(:foo, :nm)
- assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo], :nm)
- assert_equal 'nm/c99/foo/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar], :nm)
- end
- end
-
- def test_expand_cache_key_with_rails_app_version
- with_env('RAILS_APP_VERSION' => 'rails3') do
- assert_equal 'rails3/foo', ActiveSupport::Cache.expand_cache_key(:foo)
- end
- end
-
- def test_expand_cache_key_rails_cache_id_should_win_over_rails_app_version
- with_env('RAILS_CACHE_ID' => 'c99', 'RAILS_APP_VERSION' => 'rails3') do
- assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo)
- end
- end
-
- def test_expand_cache_key_respond_to_cache_key
- key = 'foo'
- def key.cache_key
- :foo_key
- end
- assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key(key)
- end
-
- def test_expand_cache_key_array_with_something_that_responds_to_cache_key
- key = 'foo'
- def key.cache_key
- :foo_key
- end
- assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key([key])
- end
-
- def test_expand_cache_key_of_nil
- assert_equal '', ActiveSupport::Cache.expand_cache_key(nil)
- end
-
- def test_expand_cache_key_of_false
- assert_equal 'false', ActiveSupport::Cache.expand_cache_key(false)
- end
-
- def test_expand_cache_key_of_true
- assert_equal 'true', ActiveSupport::Cache.expand_cache_key(true)
- end
-
- def test_expand_cache_key_of_array_like_object
- assert_equal 'foo/bar/baz', ActiveSupport::Cache.expand_cache_key(%w{foo bar baz}.to_enum)
- end
-
- private
-
- def with_env(kv)
- old_values = {}
- kv.each { |key, value| old_values[key], ENV[key] = ENV[key], value }
- yield
- ensure
- old_values.each { |key, value| ENV[key] = value}
- end
-end
-
-class CacheStoreSettingTest < ActiveSupport::TestCase
- def test_file_fragment_cache_store
- store = ActiveSupport::Cache.lookup_store :file_store, "/path/to/cache/directory"
- assert_kind_of(ActiveSupport::Cache::FileStore, store)
- assert_equal "/path/to/cache/directory", store.cache_path
- end
-
- def test_mem_cache_fragment_cache_store
- assert_called_with(Dalli::Client, :new, [%w[localhost], {}]) do
- store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost"
- assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- end
- end
-
- def test_mem_cache_fragment_cache_store_with_given_mem_cache
- mem_cache = Dalli::Client.new
- assert_not_called(Dalli::Client, :new) do
- store = ActiveSupport::Cache.lookup_store :mem_cache_store, mem_cache
- assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- end
- end
-
- def test_mem_cache_fragment_cache_store_with_not_dalli_client
- assert_not_called(Dalli::Client, :new) do
- memcache = Object.new
- assert_raises(ArgumentError) do
- ActiveSupport::Cache.lookup_store :mem_cache_store, memcache
- end
- end
- end
-
- def test_mem_cache_fragment_cache_store_with_multiple_servers
- assert_called_with(Dalli::Client, :new, [%w[localhost 192.168.1.1], {}]) do
- store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1'
- assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- end
- end
-
- def test_mem_cache_fragment_cache_store_with_options
- assert_called_with(Dalli::Client, :new, [%w[localhost 192.168.1.1], { :timeout => 10 }]) do
- store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1', :namespace => 'foo', :timeout => 10
- assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
- assert_equal 'foo', store.options[:namespace]
- end
- end
-
- def test_object_assigned_fragment_cache_store
- store = ActiveSupport::Cache.lookup_store ActiveSupport::Cache::FileStore.new("/path/to/cache/directory")
- assert_kind_of(ActiveSupport::Cache::FileStore, store)
- assert_equal "/path/to/cache/directory", store.cache_path
- end
-end
-
-class CacheStoreNamespaceTest < ActiveSupport::TestCase
- def test_static_namespace
- cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => "tester")
- cache.write("foo", "bar")
- assert_equal "bar", cache.read("foo")
- assert_equal "bar", cache.instance_variable_get(:@data)["tester:foo"].value
- end
-
- def test_proc_namespace
- test_val = "tester"
- proc = lambda{test_val}
- cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => proc)
- cache.write("foo", "bar")
- assert_equal "bar", cache.read("foo")
- assert_equal "bar", cache.instance_variable_get(:@data)["tester:foo"].value
- end
-
- def test_delete_matched_key_start
- cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => "tester")
- cache.write("foo", "bar")
- cache.write("fu", "baz")
- cache.delete_matched(/^fo/)
- assert !cache.exist?("foo")
- assert cache.exist?("fu")
- end
-
- def test_delete_matched_key
- cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => "foo")
- cache.write("foo", "bar")
- cache.write("fu", "baz")
- cache.delete_matched(/OO/i)
- assert !cache.exist?("foo")
- assert cache.exist?("fu")
- end
-end
-
-# Tests the base functionality that should be identical across all cache stores.
-module CacheStoreBehavior
- def test_should_read_and_write_strings
- assert @cache.write('foo', 'bar')
- assert_equal 'bar', @cache.read('foo')
- end
-
- def test_should_overwrite
- @cache.write('foo', 'bar')
- @cache.write('foo', 'baz')
- assert_equal 'baz', @cache.read('foo')
- end
-
- def test_fetch_without_cache_miss
- @cache.write('foo', 'bar')
- assert_not_called(@cache, :write) do
- assert_equal 'bar', @cache.fetch('foo') { 'baz' }
- end
- end
-
- def test_fetch_with_cache_miss
- assert_called_with(@cache, :write, ['foo', 'baz', @cache.options]) do
- assert_equal 'baz', @cache.fetch('foo') { 'baz' }
- end
- end
-
- def test_fetch_with_cache_miss_passes_key_to_block
- cache_miss = false
- assert_equal 3, @cache.fetch('foo') { |key| cache_miss = true; key.length }
- assert cache_miss
-
- cache_miss = false
- assert_equal 3, @cache.fetch('foo') { |key| cache_miss = true; key.length }
- assert !cache_miss
- end
-
- def test_fetch_with_forced_cache_miss
- @cache.write('foo', 'bar')
- assert_not_called(@cache, :read) do
- assert_called_with(@cache, :write, ['foo', 'bar', @cache.options.merge(:force => true)]) do
- @cache.fetch('foo', :force => true) { 'bar' }
- end
- end
- end
-
- def test_fetch_with_cached_nil
- @cache.write('foo', nil)
- assert_not_called(@cache, :write) do
- assert_nil @cache.fetch('foo') { 'baz' }
- end
- end
-
- def test_fetch_with_forced_cache_miss_with_block
- @cache.write('foo', 'bar')
- assert_equal 'foo_bar', @cache.fetch('foo', force: true) { 'foo_bar' }
- end
-
- def test_fetch_with_forced_cache_miss_without_block
- @cache.write('foo', 'bar')
- assert_raises(ArgumentError) do
- @cache.fetch('foo', force: true)
- end
-
- assert_equal 'bar', @cache.read('foo')
- end
-
- def test_should_read_and_write_hash
- assert @cache.write('foo', {:a => "b"})
- assert_equal({:a => "b"}, @cache.read('foo'))
- end
-
- def test_should_read_and_write_integer
- assert @cache.write('foo', 1)
- assert_equal 1, @cache.read('foo')
- end
-
- def test_should_read_and_write_nil
- assert @cache.write('foo', nil)
- assert_equal nil, @cache.read('foo')
- end
-
- def test_should_read_and_write_false
- assert @cache.write('foo', false)
- assert_equal false, @cache.read('foo')
- end
-
- def test_read_multi
- @cache.write('foo', 'bar')
- @cache.write('fu', 'baz')
- @cache.write('fud', 'biz')
- assert_equal({"foo" => "bar", "fu" => "baz"}, @cache.read_multi('foo', 'fu'))
- end
-
- def test_read_multi_with_expires
- time = Time.now
- @cache.write('foo', 'bar', :expires_in => 10)
- @cache.write('fu', 'baz')
- @cache.write('fud', 'biz')
- Time.stub(:now, time + 11) do
- assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
- end
- end
-
- def test_fetch_multi
- @cache.write('foo', 'bar')
- @cache.write('fud', 'biz')
-
- values = @cache.fetch_multi('foo', 'fu', 'fud') { |value| value * 2 }
-
- assert_equal({ 'foo' => 'bar', 'fu' => 'fufu', 'fud' => 'biz' }, values)
- assert_equal('fufu', @cache.read('fu'))
- end
-
- def test_multi_with_objects
- cache_struct = Struct.new(:cache_key, :title)
- foo = cache_struct.new('foo', 'FOO!')
- bar = cache_struct.new('bar')
-
- @cache.write('bar', 'BAM!')
-
- values = @cache.fetch_multi(foo, bar) { |object| object.title }
-
- assert_equal({ foo => 'FOO!', bar => 'BAM!' }, values)
- end
-
- def test_read_and_write_compressed_small_data
- @cache.write('foo', 'bar', :compress => true)
- assert_equal 'bar', @cache.read('foo')
- end
-
- def test_read_and_write_compressed_large_data
- @cache.write('foo', 'bar', :compress => true, :compress_threshold => 2)
- assert_equal 'bar', @cache.read('foo')
- end
-
- def test_read_and_write_compressed_nil
- @cache.write('foo', nil, :compress => true)
- assert_nil @cache.read('foo')
- end
-
- def test_cache_key
- obj = Object.new
- def obj.cache_key
- :foo
- end
- @cache.write(obj, "bar")
- assert_equal "bar", @cache.read("foo")
- end
-
- def test_param_as_cache_key
- obj = Object.new
- def obj.to_param
- "foo"
- end
- @cache.write(obj, "bar")
- assert_equal "bar", @cache.read("foo")
- end
-
- def test_array_as_cache_key
- @cache.write([:fu, "foo"], "bar")
- assert_equal "bar", @cache.read("fu/foo")
- end
-
- def test_hash_as_cache_key
- @cache.write({:foo => 1, :fu => 2}, "bar")
- assert_equal "bar", @cache.read("foo=1/fu=2")
- end
-
- def test_keys_are_case_sensitive
- @cache.write("foo", "bar")
- assert_nil @cache.read("FOO")
- end
-
- def test_exist
- @cache.write('foo', 'bar')
- assert_equal true, @cache.exist?('foo')
- assert_equal false, @cache.exist?('bar')
- end
-
- def test_nil_exist
- @cache.write('foo', nil)
- assert @cache.exist?('foo')
- end
-
- def test_delete
- @cache.write('foo', 'bar')
- assert @cache.exist?('foo')
- assert @cache.delete('foo')
- assert !@cache.exist?('foo')
- end
-
- def test_original_store_objects_should_not_be_immutable
- bar = 'bar'
- @cache.write('foo', bar)
- assert_nothing_raised { bar.gsub!(/.*/, 'baz') }
- end
-
- def test_expires_in
- time = Time.local(2008, 4, 24)
-
- Time.stub(:now, time) do
- @cache.write('foo', 'bar')
- assert_equal 'bar', @cache.read('foo')
- end
-
- Time.stub(:now, time + 30) do
- assert_equal 'bar', @cache.read('foo')
- end
-
- Time.stub(:now, time + 61) do
- assert_nil @cache.read('foo')
- end
- end
-
- def test_race_condition_protection_skipped_if_not_defined
- @cache.write('foo', 'bar')
- time = @cache.send(:read_entry, @cache.send(:normalize_key, 'foo', {}), {}).expires_at
-
- Time.stub(:now, Time.at(time)) do
- result = @cache.fetch('foo') do
- assert_equal nil, @cache.read('foo')
- 'baz'
- end
- assert_equal 'baz', result
- end
- end
-
- def test_race_condition_protection_is_limited
- time = Time.now
- @cache.write('foo', 'bar', :expires_in => 60)
- Time.stub(:now, time + 71) do
- result = @cache.fetch('foo', :race_condition_ttl => 10) do
- assert_equal nil, @cache.read('foo')
- "baz"
- end
- assert_equal "baz", result
- end
- end
-
- def test_race_condition_protection_is_safe
- time = Time.now
- @cache.write('foo', 'bar', :expires_in => 60)
- Time.stub(:now, time + 61) do
- begin
- @cache.fetch('foo', :race_condition_ttl => 10) do
- assert_equal 'bar', @cache.read('foo')
- raise ArgumentError.new
- end
- rescue ArgumentError
- end
- assert_equal "bar", @cache.read('foo')
- end
- Time.stub(:now, time + 91) do
- assert_nil @cache.read('foo')
- end
- end
-
- def test_race_condition_protection
- time = Time.now
- @cache.write('foo', 'bar', :expires_in => 60)
- Time.stub(:now, time + 61) do
- result = @cache.fetch('foo', :race_condition_ttl => 10) do
- assert_equal 'bar', @cache.read('foo')
- "baz"
- end
- assert_equal "baz", result
- end
- end
-
- def test_crazy_key_characters
- crazy_key = "#/:*(<+=> )&$%@?;'\"\'`~-"
- assert @cache.write(crazy_key, "1", :raw => true)
- assert_equal "1", @cache.read(crazy_key)
- assert_equal "1", @cache.fetch(crazy_key)
- assert @cache.delete(crazy_key)
- assert_equal "2", @cache.fetch(crazy_key, :raw => true) { "2" }
- assert_equal 3, @cache.increment(crazy_key)
- assert_equal 2, @cache.decrement(crazy_key)
- end
-
- def test_really_long_keys
- key = ""
- 900.times{key << "x"}
- assert @cache.write(key, "bar")
- assert_equal "bar", @cache.read(key)
- assert_equal "bar", @cache.fetch(key)
- assert_nil @cache.read("#{key}x")
- assert_equal({key => "bar"}, @cache.read_multi(key))
- assert @cache.delete(key)
- end
-
- def test_cache_hit_instrumentation
- key = "test_key"
- @events = []
- ActiveSupport::Notifications.subscribe "cache_read.active_support" do |*args|
- @events << ActiveSupport::Notifications::Event.new(*args)
- end
- assert @cache.write(key, "1", :raw => true)
- assert @cache.fetch(key) {}
- assert_equal 1, @events.length
- assert_equal 'cache_read.active_support', @events[0].name
- assert_equal :fetch, @events[0].payload[:super_operation]
- assert @events[0].payload[:hit]
- ensure
- ActiveSupport::Notifications.unsubscribe "cache_read.active_support"
- end
-
- def test_cache_miss_instrumentation
- @events = []
- ActiveSupport::Notifications.subscribe(/^cache_(.*)\.active_support$/) do |*args|
- @events << ActiveSupport::Notifications::Event.new(*args)
- end
- assert_not @cache.fetch("bad_key") {}
- assert_equal 3, @events.length
- assert_equal 'cache_read.active_support', @events[0].name
- assert_equal 'cache_generate.active_support', @events[1].name
- assert_equal 'cache_write.active_support', @events[2].name
- assert_equal :fetch, @events[0].payload[:super_operation]
- assert_not @events[0].payload[:hit]
- ensure
- ActiveSupport::Notifications.unsubscribe "cache_read.active_support"
- end
-
- def test_can_call_deprecated_namesaced_key
- assert_deprecated "`namespaced_key` is deprecated" do
- @cache.send(:namespaced_key, 111, {})
- end
- end
-end
-
-# https://rails.lighthouseapp.com/projects/8994/tickets/6225-memcachestore-cant-deal-with-umlauts-and-special-characters
-# The error is caused by character encodings that can't be compared with ASCII-8BIT regular expressions and by special
-# characters like the umlaut in UTF-8.
-module EncodedKeyCacheBehavior
- Encoding.list.each do |encoding|
- define_method "test_#{encoding.name.underscore}_encoded_values" do
- key = "foo".force_encoding(encoding)
- assert @cache.write(key, "1", :raw => true)
- assert_equal "1", @cache.read(key)
- assert_equal "1", @cache.fetch(key)
- assert @cache.delete(key)
- assert_equal "2", @cache.fetch(key, :raw => true) { "2" }
- assert_equal 3, @cache.increment(key)
- assert_equal 2, @cache.decrement(key)
- end
- end
-
- def test_common_utf8_values
- key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
- assert @cache.write(key, "1", :raw => true)
- assert_equal "1", @cache.read(key)
- assert_equal "1", @cache.fetch(key)
- assert @cache.delete(key)
- assert_equal "2", @cache.fetch(key, :raw => true) { "2" }
- assert_equal 3, @cache.increment(key)
- assert_equal 2, @cache.decrement(key)
- end
-
- def test_retains_encoding
- key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
- assert @cache.write(key, "1", :raw => true)
- assert_equal Encoding::UTF_8, key.encoding
- end
-end
-
-module CacheDeleteMatchedBehavior
- def test_delete_matched
- @cache.write("foo", "bar")
- @cache.write("fu", "baz")
- @cache.write("foo/bar", "baz")
- @cache.write("fu/baz", "bar")
- @cache.delete_matched(/oo/)
- assert !@cache.exist?("foo")
- assert @cache.exist?("fu")
- assert !@cache.exist?("foo/bar")
- assert @cache.exist?("fu/baz")
- end
-end
-
-module CacheIncrementDecrementBehavior
- def test_increment
- @cache.write('foo', 1, :raw => true)
- assert_equal 1, @cache.read('foo').to_i
- assert_equal 2, @cache.increment('foo')
- assert_equal 2, @cache.read('foo').to_i
- assert_equal 3, @cache.increment('foo')
- assert_equal 3, @cache.read('foo').to_i
- assert_nil @cache.increment('bar')
- end
-
- def test_decrement
- @cache.write('foo', 3, :raw => true)
- assert_equal 3, @cache.read('foo').to_i
- assert_equal 2, @cache.decrement('foo')
- assert_equal 2, @cache.read('foo').to_i
- assert_equal 1, @cache.decrement('foo')
- assert_equal 1, @cache.read('foo').to_i
- assert_nil @cache.decrement('bar')
- end
-end
-
-module LocalCacheBehavior
- def test_local_writes_are_persistent_on_the_remote_cache
- retval = @cache.with_local_cache do
- @cache.write('foo', 'bar')
- end
- assert retval
- assert_equal 'bar', @cache.read('foo')
- end
-
- def test_clear_also_clears_local_cache
- @cache.with_local_cache do
- @cache.write('foo', 'bar')
- @cache.clear
- assert_nil @cache.read('foo')
- end
-
- assert_nil @cache.read('foo')
- end
-
- def test_local_cache_of_write
- @cache.with_local_cache do
- @cache.write('foo', 'bar')
- @peek.delete('foo')
- assert_equal 'bar', @cache.read('foo')
- end
- end
-
- def test_local_cache_of_read
- @cache.write('foo', 'bar')
- @cache.with_local_cache do
- assert_equal 'bar', @cache.read('foo')
- end
- end
-
- def test_local_cache_of_read_nil
- @cache.with_local_cache do
- assert_equal nil, @cache.read('foo')
- @cache.send(:bypass_local_cache) { @cache.write 'foo', 'bar' }
- assert_equal nil, @cache.read('foo')
- end
- end
-
- def test_local_cache_fetch
- @cache.with_local_cache do
- @cache.send(:local_cache).write 'foo', 'bar'
- assert_equal 'bar', @cache.send(:local_cache).fetch('foo')
- end
- end
-
- def test_local_cache_of_write_nil
- @cache.with_local_cache do
- assert @cache.write('foo', nil)
- assert_nil @cache.read('foo')
- @peek.write('foo', 'bar')
- assert_nil @cache.read('foo')
- end
- end
-
- def test_local_cache_of_delete
- @cache.with_local_cache do
- @cache.write('foo', 'bar')
- @cache.delete('foo')
- assert_nil @cache.read('foo')
- end
- end
-
- def test_local_cache_of_exist
- @cache.with_local_cache do
- @cache.write('foo', 'bar')
- @peek.delete('foo')
- assert @cache.exist?('foo')
- end
- end
-
- def test_local_cache_of_increment
- @cache.with_local_cache do
- @cache.write('foo', 1, :raw => true)
- @peek.write('foo', 2, :raw => true)
- @cache.increment('foo')
- assert_equal 3, @cache.read('foo')
- end
- end
-
- def test_local_cache_of_decrement
- @cache.with_local_cache do
- @cache.write('foo', 1, :raw => true)
- @peek.write('foo', 3, :raw => true)
- @cache.decrement('foo')
- assert_equal 2, @cache.read('foo')
- end
- end
-
- def test_middleware
- app = lambda { |env|
- result = @cache.write('foo', 'bar')
- assert_equal 'bar', @cache.read('foo') # make sure 'foo' was written
- assert result
- [200, {}, []]
- }
- app = @cache.middleware.new(app)
- app.call({})
- end
-
- def test_can_call_deprecated_set_cache_value
- @cache.with_local_cache do
- assert_deprecated "`set_cache_value` is deprecated" do
- @cache.send(:set_cache_value, 1, 'foo', :ignored, {})
- end
- assert_equal 1, @cache.read('foo')
- end
- end
-end
-
-module AutoloadingCacheBehavior
- include DependenciesTestHelpers
- def test_simple_autoloading
- with_autoloading_fixtures do
- @cache.write('foo', EM.new)
- end
-
- remove_constants(:EM)
- ActiveSupport::Dependencies.clear
-
- with_autoloading_fixtures do
- assert_kind_of EM, @cache.read('foo')
- end
-
- remove_constants(:EM)
- ActiveSupport::Dependencies.clear
- end
-
- def test_two_classes_autoloading
- with_autoloading_fixtures do
- @cache.write('foo', [EM.new, ClassFolder.new])
- end
-
- remove_constants(:EM, :ClassFolder)
- ActiveSupport::Dependencies.clear
-
- with_autoloading_fixtures do
- loaded = @cache.read('foo')
- assert_kind_of Array, loaded
- assert_equal 2, loaded.size
- assert_kind_of EM, loaded[0]
- assert_kind_of ClassFolder, loaded[1]
- end
-
- remove_constants(:EM, :ClassFolder)
- ActiveSupport::Dependencies.clear
- end
-end
-
-class FileStoreTest < ActiveSupport::TestCase
- def setup
- Dir.mkdir(cache_dir) unless File.exist?(cache_dir)
- @cache = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60)
- @peek = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60)
- @cache_with_pathname = ActiveSupport::Cache.lookup_store(:file_store, Pathname.new(cache_dir), :expires_in => 60)
-
- @buffer = StringIO.new
- @cache.logger = ActiveSupport::Logger.new(@buffer)
- end
-
- def teardown
- FileUtils.rm_r(cache_dir)
- rescue Errno::ENOENT
- end
-
- def cache_dir
- File.join(Dir.pwd, 'tmp_cache')
- end
-
- include CacheStoreBehavior
- include LocalCacheBehavior
- include CacheDeleteMatchedBehavior
- include CacheIncrementDecrementBehavior
- include AutoloadingCacheBehavior
-
- def test_clear
- gitkeep = File.join(cache_dir, ".gitkeep")
- keep = File.join(cache_dir, ".keep")
- FileUtils.touch([gitkeep, keep])
- @cache.clear
- assert File.exist?(gitkeep)
- assert File.exist?(keep)
- end
-
- def test_clear_without_cache_dir
- FileUtils.rm_r(cache_dir)
- @cache.clear
- end
-
- def test_long_keys
- @cache.write("a"*10000, 1)
- assert_equal 1, @cache.read("a"*10000)
- end
-
- def test_long_uri_encoded_keys
- @cache.write("%"*870, 1)
- assert_equal 1, @cache.read("%"*870)
- end
-
- def test_key_transformation
- key = @cache.send(:normalize_key, "views/index?id=1", {})
- assert_equal "views/index?id=1", @cache.send(:file_path_key, key)
- end
-
- def test_key_transformation_with_pathname
- FileUtils.touch(File.join(cache_dir, "foo"))
- key = @cache_with_pathname.send(:normalize_key, "views/index?id=1", {})
- assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key)
- end
-
- # Test that generated cache keys are short enough to have Tempfile stuff added to them and
- # remain valid
- def test_filename_max_size
- key = "#{'A' * ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}"
- path = @cache.send(:normalize_key, key, {})
- Dir::Tmpname.create(path) do |tmpname, n, opts|
- assert File.basename(tmpname+'.lock').length <= 255, "Temp filename too long: #{File.basename(tmpname+'.lock').length}"
- end
- end
-
- # Because file systems have a maximum filename size, filenames > max size should be split in to directories
- # If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B
- def test_key_transformation_max_filename_size
- key = "#{'A' * ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}B"
- path = @cache.send(:normalize_key, key, {})
- assert path.split('/').all? { |dir_name| dir_name.size <= ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}
- assert_equal 'B', File.basename(path)
- end
-
- # If nothing has been stored in the cache, there is a chance the cache directory does not yet exist
- # Ensure delete_matched gracefully handles this case
- def test_delete_matched_when_cache_directory_does_not_exist
- assert_nothing_raised do
- ActiveSupport::Cache::FileStore.new('/test/cache/directory').delete_matched(/does_not_exist/)
- end
- end
-
- def test_delete_does_not_delete_empty_parent_dir
- sub_cache_dir = File.join(cache_dir, 'subdir/')
- sub_cache_store = ActiveSupport::Cache::FileStore.new(sub_cache_dir)
- assert_nothing_raised do
- assert sub_cache_store.write('foo', 'bar')
- assert sub_cache_store.delete('foo')
- end
- assert File.exist?(cache_dir), "Parent of top level cache dir was deleted!"
- assert File.exist?(sub_cache_dir), "Top level cache dir was deleted!"
- assert Dir.entries(sub_cache_dir).reject {|f| ActiveSupport::Cache::FileStore::EXCLUDED_DIRS.include?(f)}.empty?
- end
-
- def test_log_exception_when_cache_read_fails
- File.stub(:exist?, -> { raise StandardError.new("failed") }) do
- @cache.send(:read_entry, "winston", {})
- assert @buffer.string.present?
- end
- end
-
- def test_cleanup_removes_all_expired_entries
- time = Time.now
- @cache.write('foo', 'bar', expires_in: 10)
- @cache.write('baz', 'qux')
- @cache.write('quux', 'corge', expires_in: 20)
- Time.stub(:now, time + 15) do
- @cache.cleanup
- assert_not @cache.exist?('foo')
- assert @cache.exist?('baz')
- assert @cache.exist?('quux')
- end
- end
-
- def test_write_with_unless_exist
- assert_equal true, @cache.write(1, "aaaaaaaaaa")
- assert_equal false, @cache.write(1, "aaaaaaaaaa", unless_exist: true)
- @cache.write(1, nil)
- assert_equal false, @cache.write(1, "aaaaaaaaaa", unless_exist: true)
- end
-
- def test_can_call_deprecated_key_file_path
- assert_deprecated "`key_file_path` is deprecated" do
- assert_equal 111, @cache.send(:key_file_path, 111)
- end
- end
-end
-
-class MemoryStoreTest < ActiveSupport::TestCase
- def setup
- @record_size = ActiveSupport::Cache.lookup_store(:memory_store).send(:cached_size, 1, ActiveSupport::Cache::Entry.new("aaaaaaaaaa"))
- @cache = ActiveSupport::Cache.lookup_store(:memory_store, :expires_in => 60, :size => @record_size * 10 + 1)
- end
-
- include CacheStoreBehavior
- include CacheDeleteMatchedBehavior
- include CacheIncrementDecrementBehavior
-
- def test_prune_size
- @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
- @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
- @cache.write(3, "cccccccccc") && sleep(0.001)
- @cache.write(4, "dddddddddd") && sleep(0.001)
- @cache.write(5, "eeeeeeeeee") && sleep(0.001)
- @cache.read(2) && sleep(0.001)
- @cache.read(4)
- @cache.prune(@record_size * 3)
- assert @cache.exist?(5)
- assert @cache.exist?(4)
- assert !@cache.exist?(3), "no entry"
- assert @cache.exist?(2)
- assert !@cache.exist?(1), "no entry"
- end
-
- def test_prune_size_on_write
- @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
- @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
- @cache.write(3, "cccccccccc") && sleep(0.001)
- @cache.write(4, "dddddddddd") && sleep(0.001)
- @cache.write(5, "eeeeeeeeee") && sleep(0.001)
- @cache.write(6, "ffffffffff") && sleep(0.001)
- @cache.write(7, "gggggggggg") && sleep(0.001)
- @cache.write(8, "hhhhhhhhhh") && sleep(0.001)
- @cache.write(9, "iiiiiiiiii") && sleep(0.001)
- @cache.write(10, "kkkkkkkkkk") && sleep(0.001)
- @cache.read(2) && sleep(0.001)
- @cache.read(4) && sleep(0.001)
- @cache.write(11, "llllllllll")
- assert @cache.exist?(11)
- assert @cache.exist?(10)
- assert @cache.exist?(9)
- assert @cache.exist?(8)
- assert @cache.exist?(7)
- assert !@cache.exist?(6), "no entry"
- assert !@cache.exist?(5), "no entry"
- assert @cache.exist?(4)
- assert !@cache.exist?(3), "no entry"
- assert @cache.exist?(2)
- assert !@cache.exist?(1), "no entry"
- end
-
- def test_prune_size_on_write_based_on_key_length
- @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
- @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
- @cache.write(3, "cccccccccc") && sleep(0.001)
- @cache.write(4, "dddddddddd") && sleep(0.001)
- @cache.write(5, "eeeeeeeeee") && sleep(0.001)
- @cache.write(6, "ffffffffff") && sleep(0.001)
- @cache.write(7, "gggggggggg") && sleep(0.001)
- @cache.write(8, "hhhhhhhhhh") && sleep(0.001)
- @cache.write(9, "iiiiiiiiii") && sleep(0.001)
- long_key = '*' * 2 * @record_size
- @cache.write(long_key, "llllllllll")
- assert @cache.exist?(long_key)
- assert @cache.exist?(9)
- assert @cache.exist?(8)
- assert @cache.exist?(7)
- assert @cache.exist?(6)
- assert !@cache.exist?(5), "no entry"
- assert !@cache.exist?(4), "no entry"
- assert !@cache.exist?(3), "no entry"
- assert !@cache.exist?(2), "no entry"
- assert !@cache.exist?(1), "no entry"
- end
-
- def test_pruning_is_capped_at_a_max_time
- def @cache.delete_entry (*args)
- sleep(0.01)
- super
- end
- @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
- @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
- @cache.write(3, "cccccccccc") && sleep(0.001)
- @cache.write(4, "dddddddddd") && sleep(0.001)
- @cache.write(5, "eeeeeeeeee") && sleep(0.001)
- @cache.prune(30, 0.001)
- assert @cache.exist?(5)
- assert @cache.exist?(4)
- assert @cache.exist?(3)
- assert @cache.exist?(2)
- assert !@cache.exist?(1)
- end
-
- def test_write_with_unless_exist
- assert_equal true, @cache.write(1, "aaaaaaaaaa")
- assert_equal false, @cache.write(1, "aaaaaaaaaa", :unless_exist => true)
- @cache.write(1, nil)
- assert_equal false, @cache.write(1, "aaaaaaaaaa", :unless_exist => true)
- end
-end
-
-class MemCacheStoreTest < ActiveSupport::TestCase
- require 'dalli'
-
- begin
- ss = Dalli::Client.new('localhost:11211').stats
- raise Dalli::DalliError unless ss['localhost:11211']
-
- MEMCACHE_UP = true
- rescue Dalli::DalliError
- $stderr.puts "Skipping memcached tests. Start memcached and try again."
- MEMCACHE_UP = false
- end
-
- def setup
- skip "memcache server is not up" unless MEMCACHE_UP
-
- @cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :expires_in => 60)
- @peek = ActiveSupport::Cache.lookup_store(:mem_cache_store)
- @data = @cache.instance_variable_get(:@data)
- @cache.clear
- @cache.silence!
- @cache.logger = ActiveSupport::Logger.new("/dev/null")
- end
-
- include CacheStoreBehavior
- include LocalCacheBehavior
- include CacheIncrementDecrementBehavior
- include EncodedKeyCacheBehavior
- include AutoloadingCacheBehavior
-
- def test_raw_values
- cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
- cache.clear
- cache.write("foo", 2)
- assert_equal "2", cache.read("foo")
- end
-
- def test_raw_values_with_marshal
- cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
- cache.clear
- cache.write("foo", Marshal.dump([]))
- assert_equal [], cache.read("foo")
- end
-
- def test_local_cache_raw_values
- cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
- cache.clear
- cache.with_local_cache do
- cache.write("foo", 2)
- assert_equal "2", cache.read("foo")
- end
- end
-
- def test_local_cache_raw_values_with_marshal
- cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
- cache.clear
- cache.with_local_cache do
- cache.write("foo", Marshal.dump([]))
- assert_equal [], cache.read("foo")
- end
- end
-
- def test_read_should_return_a_different_object_id_each_time_it_is_called
- @cache.write('foo', 'bar')
- value = @cache.read('foo')
- assert_not_equal value.object_id, @cache.read('foo').object_id
- value << 'bingo'
- assert_not_equal value, @cache.read('foo')
- end
-
- def test_can_call_deprecated_escape_key
- assert_deprecated "`escape_key` is deprecated" do
- assert_equal 111, @cache.send(:escape_key, 111)
- end
- end
-end
-
-class NullStoreTest < ActiveSupport::TestCase
- def setup
- @cache = ActiveSupport::Cache.lookup_store(:null_store)
- end
-
- def test_clear
- @cache.clear
- end
-
- def test_cleanup
- @cache.cleanup
- end
-
- def test_write
- assert_equal true, @cache.write("name", "value")
- end
-
- def test_read
- @cache.write("name", "value")
- assert_nil @cache.read("name")
- end
-
- def test_delete
- @cache.write("name", "value")
- assert_equal false, @cache.delete("name")
- end
-
- def test_increment
- @cache.write("name", 1, :raw => true)
- assert_nil @cache.increment("name")
- end
-
- def test_decrement
- @cache.write("name", 1, :raw => true)
- assert_nil @cache.increment("name")
- end
-
- def test_delete_matched
- @cache.write("name", "value")
- @cache.delete_matched(/name/)
- end
-
- def test_local_store_strategy
- @cache.with_local_cache do
- @cache.write("name", "value")
- assert_equal "value", @cache.read("name")
- @cache.delete("name")
- assert_nil @cache.read("name")
- @cache.write("name", "value")
- end
- assert_nil @cache.read("name")
- end
-end
-
-class CacheStoreLoggerTest < ActiveSupport::TestCase
- def setup
- @cache = ActiveSupport::Cache.lookup_store(:memory_store)
-
- @buffer = StringIO.new
- @cache.logger = ActiveSupport::Logger.new(@buffer)
- end
-
- def test_logging
- @cache.fetch('foo') { 'bar' }
- assert @buffer.string.present?
- end
-
- def test_log_with_string_namespace
- @cache.fetch('foo', {namespace: 'string_namespace'}) { 'bar' }
- assert_match %r{string_namespace:foo}, @buffer.string
- end
-
- def test_log_with_proc_namespace
- proc = Proc.new do
- "proc_namespace"
- end
- @cache.fetch('foo', {:namespace => proc}) { 'bar' }
- assert_match %r{proc_namespace:foo}, @buffer.string
- end
-
- def test_mute_logging
- @cache.mute { @cache.fetch('foo') { 'bar' } }
- assert @buffer.string.blank?
- end
-end
-
-class CacheEntryTest < ActiveSupport::TestCase
- def test_expired
- entry = ActiveSupport::Cache::Entry.new("value")
- assert !entry.expired?, 'entry not expired'
- entry = ActiveSupport::Cache::Entry.new("value", :expires_in => 60)
- assert !entry.expired?, 'entry not expired'
- Time.stub(:now, Time.now + 61) do
- assert entry.expired?, 'entry is expired'
- end
- end
-
- def test_compress_values
- value = "value" * 100
- entry = ActiveSupport::Cache::Entry.new(value, :compress => true, :compress_threshold => 1)
- assert_equal value, entry.value
- assert(value.bytesize > entry.size, "value is compressed")
- end
-
- def test_non_compress_values
- value = "value" * 100
- entry = ActiveSupport::Cache::Entry.new(value)
- assert_equal value, entry.value
- assert_equal value.bytesize, entry.size
- end
-end