mcmire-cache 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/.gitignore +7 -0
  2. data/CHANGELOG +21 -0
  3. data/Gemfile +22 -0
  4. data/README.md +229 -0
  5. data/Rakefile +41 -0
  6. data/benchmarks/afterrefactor.txt +86 -0
  7. data/benchmarks/midrefactor.txt +89 -0
  8. data/benchmarks/v0.0.2.txt +95 -0
  9. data/benchmarks/v0.0.3.txt +96 -0
  10. data/benchmarks/v0.1.2.txt +94 -0
  11. data/benchmarks/v0.2.1.txt +94 -0
  12. data/benchmarks/v0.2.2.txt +94 -0
  13. data/lib/cache.rb +233 -0
  14. data/lib/cache/active_support_cache_dalli_store.rb +15 -0
  15. data/lib/cache/active_support_cache_file_store.rb +11 -0
  16. data/lib/cache/active_support_cache_memory_store.rb +11 -0
  17. data/lib/cache/active_support_cache_store.rb +37 -0
  18. data/lib/cache/config.rb +27 -0
  19. data/lib/cache/dalli_client.rb +54 -0
  20. data/lib/cache/mem_cache.rb +46 -0
  21. data/lib/cache/memcached.rb +54 -0
  22. data/lib/cache/memcached_rails.rb +34 -0
  23. data/lib/cache/nothing.rb +20 -0
  24. data/lib/cache/redis.rb +44 -0
  25. data/lib/cache/redis_namespace.rb +7 -0
  26. data/lib/cache/version.rb +3 -0
  27. data/mcmire-cache.gemspec +22 -0
  28. data/test/helper.rb +29 -0
  29. data/test/profile/benchmark.rb +258 -0
  30. data/test/shared_tests.rb +169 -0
  31. data/test/test_active_support_cache_dalli_store.rb +77 -0
  32. data/test/test_active_support_cache_file_store.rb +19 -0
  33. data/test/test_active_support_cache_memory_store.rb +12 -0
  34. data/test/test_dalli_client.rb +70 -0
  35. data/test/test_mem_cache.rb +64 -0
  36. data/test/test_memcached.rb +64 -0
  37. data/test/test_memcached_rails.rb +61 -0
  38. data/test/test_memcached_with_binary.rb +17 -0
  39. data/test/test_missing_driver.rb +16 -0
  40. data/test/test_nothing.rb +147 -0
  41. data/test/test_redis.rb +60 -0
  42. data/test/test_redis_namespace.rb +64 -0
  43. metadata +108 -0
@@ -0,0 +1,77 @@
1
+ require 'helper'
2
+
3
+ require 'dalli'
4
+ require 'active_support/cache/dalli_store'
5
+ require 'active_support/cache'
6
+
7
+ class TestActiveSupportCacheDalliStore < TestCase
8
+ def raw_client_class
9
+ ActiveSupport::Cache::DalliStore
10
+ end
11
+
12
+ def raw_client
13
+ raw_client_class.new ['localhost:11211']
14
+ end
15
+
16
+ include SharedTests
17
+
18
+ def get_ring_object_id
19
+ hidden_dalli_client = cache.metal.instance_variable_get :@data
20
+ hidden_dalli_client.instance_variable_get(:@ring).object_id
21
+ end
22
+
23
+ def test_treats_as_thread_safe
24
+ # make sure ring is initialized
25
+ cache.get 'hi'
26
+
27
+ # get the main thread's ring
28
+ main_thread_ring_id = get_ring_object_id
29
+
30
+ # sanity check that it's not changing every time
31
+ cache.get 'hi'
32
+ assert_equal main_thread_ring_id, get_ring_object_id
33
+
34
+ # create a new thread and get its ring
35
+ new_thread_ring_id = Thread.new { cache.get 'hi'; get_ring_object_id }.value
36
+
37
+ # make sure the ring was reinitialized
38
+ assert_equal main_thread_ring_id, new_thread_ring_id
39
+ end
40
+
41
+ def test_treats_as_not_fork_safe
42
+ # make sure ring is initialized
43
+ cache.get 'hi'
44
+
45
+ # get the main thread's ring
46
+ parent_process_ring_id = get_ring_object_id
47
+
48
+ # sanity check that it's not changing every time
49
+ cache.get 'hi'
50
+ assert_equal parent_process_ring_id, get_ring_object_id
51
+
52
+ # fork a new process
53
+ pid = Kernel.fork do
54
+ cache.get 'hi'
55
+ raise "Didn't split!" if parent_process_ring_id == get_ring_object_id
56
+ end
57
+ Process.wait pid
58
+
59
+ # make sure it didn't raise
60
+ assert $?.success?
61
+ end
62
+
63
+ def test_set_with_default_dalli_ttl
64
+ cache = Cache.new(ActiveSupport::Cache::DalliStore.new(:expires_in => 1))
65
+ cache.set('foo', 'bar')
66
+ sleep 2
67
+ assert_equal nil, cache.get('foo')
68
+ end
69
+
70
+ def test_fetch_with_default_dalli_ttl
71
+ cache = Cache.new(ActiveSupport::Cache::DalliStore.new(:expires_in => 1))
72
+ cache.fetch('foo') { 'bar' }
73
+ sleep 2
74
+ assert_equal nil, cache.fetch('foo')
75
+ assert_equal 'different', cache.fetch('foo') { 'different' }
76
+ end
77
+ end
@@ -0,0 +1,19 @@
1
+ require 'helper'
2
+ require 'tmpdir'
3
+ require 'fileutils'
4
+
5
+ require 'active_support/cache'
6
+
7
+ class TestActiveSupportCacheFileStore < TestCase
8
+ def raw_client_class
9
+ ActiveSupport::Cache::FileStore
10
+ end
11
+
12
+ def raw_client
13
+ tmpdir = File.join(Dir.tmpdir, "Cache-TestActiveSupportCacheFileStore-#{rand(1e11)}")
14
+ FileUtils.mkdir_p tmpdir
15
+ raw_client_class.new tmpdir
16
+ end
17
+
18
+ include SharedTests
19
+ end
@@ -0,0 +1,12 @@
1
+ require 'helper'
2
+
3
+ require 'active_support/cache'
4
+
5
+ class TestActiveSupportCacheMemoryStore < TestCase
6
+ def raw_client_class
7
+ ActiveSupport::Cache::MemoryStore
8
+ end
9
+
10
+ include SharedTests
11
+ end
12
+
@@ -0,0 +1,70 @@
1
+ require 'helper'
2
+
3
+ require 'dalli'
4
+
5
+ class TestDalliClient < TestCase
6
+ def raw_client_class
7
+ Dalli::Client
8
+ end
9
+
10
+ include SharedTests
11
+
12
+ def get_ring_object_id
13
+ cache.metal.instance_variable_get(:@ring).object_id
14
+ end
15
+
16
+ def test_treats_as_thread_safe
17
+ # make sure ring is initialized
18
+ cache.get 'hi'
19
+
20
+ # get the main thread's ring
21
+ main_thread_ring_id = get_ring_object_id
22
+
23
+ # sanity check that it's not changing every time
24
+ cache.get 'hi'
25
+ assert_equal main_thread_ring_id, get_ring_object_id
26
+
27
+ # create a new thread and get its ring
28
+ new_thread_ring_id = Thread.new { cache.get 'hi'; get_ring_object_id }.value
29
+
30
+ # make sure the ring was reinitialized
31
+ assert_equal main_thread_ring_id, new_thread_ring_id
32
+ end
33
+
34
+ def test_treats_as_not_fork_safe
35
+ # make sure ring is initialized
36
+ cache.get 'hi'
37
+
38
+ # get the main thread's ring
39
+ parent_process_ring_id = get_ring_object_id
40
+
41
+ # sanity check that it's not changing every time
42
+ cache.get 'hi'
43
+ assert_equal parent_process_ring_id, get_ring_object_id
44
+
45
+ # fork a new process
46
+ pid = Kernel.fork do
47
+ cache.get 'hi'
48
+ raise "Didn't split!" if parent_process_ring_id == get_ring_object_id
49
+ end
50
+ Process.wait pid
51
+
52
+ # make sure it didn't raise
53
+ assert $?.success?
54
+ end
55
+
56
+ def test_set_with_default_dalli_ttl
57
+ cache = Cache.new(Dalli::Client.new(nil, :expires_in => 1))
58
+ cache.set('foo', 'bar')
59
+ sleep 2
60
+ assert_equal nil, cache.get('foo')
61
+ end
62
+
63
+ def test_fetch_with_default_dalli_ttl
64
+ cache = Cache.new(Dalli::Client.new(nil, :expires_in => 1))
65
+ cache.fetch('foo') { 'bar' }
66
+ sleep 2
67
+ assert_equal nil, cache.fetch('foo')
68
+ assert_equal 'different', cache.fetch('foo') { 'different' }
69
+ end
70
+ end
@@ -0,0 +1,64 @@
1
+ require 'helper'
2
+
3
+ # the famous memcache-client
4
+ require 'memcache'
5
+
6
+ class TestMemCache < TestCase
7
+ def self.startup
8
+ MemCache
9
+ end
10
+
11
+ def raw_client_class
12
+ MemCache
13
+ end
14
+
15
+ def raw_client
16
+ raw_client_class.new ['localhost:11211']
17
+ end
18
+
19
+ include SharedTests
20
+
21
+ def get_server_status_ids
22
+ cache.metal.instance_variable_get(:@servers).map { |s| s.status.object_id }
23
+ end
24
+
25
+ def test_treats_as_thread_safe
26
+ # make sure servers are connected
27
+ cache.get 'hi'
28
+
29
+ # get the object ids
30
+ main_thread_server_status_ids = get_server_status_ids
31
+
32
+ # sanity check that it's not changing every time
33
+ cache.get 'hi'
34
+ assert_equal main_thread_server_status_ids, get_server_status_ids
35
+
36
+ # create a new thread and get its server ids
37
+ new_thread_server_status_ids = Thread.new { cache.get 'hi'; get_server_status_ids }.value
38
+
39
+ # make sure the server ids was reinitialized
40
+ assert_equal main_thread_server_status_ids, new_thread_server_status_ids
41
+ end
42
+
43
+ def test_treats_as_not_fork_safe
44
+ # make sure server ids is initialized
45
+ cache.get 'hi'
46
+
47
+ # get the main thread's server ids
48
+ parent_process_server_status_ids = get_server_status_ids
49
+
50
+ # sanity check that it's not changing every time
51
+ cache.get 'hi'
52
+ assert_equal parent_process_server_status_ids, get_server_status_ids
53
+
54
+ # fork a new process
55
+ pid = Kernel.fork do
56
+ cache.get 'hi'
57
+ raise "Didn't split!" if parent_process_server_status_ids == get_server_status_ids
58
+ end
59
+ Process.wait pid
60
+
61
+ # make sure it didn't raise
62
+ assert $?.success?
63
+ end
64
+ end
@@ -0,0 +1,64 @@
1
+ require 'helper'
2
+
3
+ unless RUBY_PLATFORM == 'java'
4
+ require 'memcached'
5
+
6
+ class TestMemcached < TestCase
7
+ def raw_client_class
8
+ Memcached
9
+ end
10
+
11
+ def raw_client
12
+ raw_client_class.new 'localhost:11211', :support_cas => true
13
+ end
14
+
15
+ include SharedTests
16
+
17
+ def get_bare_id
18
+ cache.thread_metal.object_id
19
+ end
20
+
21
+ def test_treats_as_not_thread_safe
22
+ # make sure bare client is initialized
23
+ cache.get 'hi'
24
+
25
+ # get the main thread's bare client
26
+ main_thread_bare_id = get_bare_id
27
+
28
+ # sanity check that it's not changing every time
29
+ cache.get 'hi'
30
+ assert_equal main_thread_bare_id, get_bare_id
31
+
32
+ # create a new thread and get its bare client
33
+ new_thread_bare_id = Thread.new { cache.get 'hi'; get_bare_id }.value
34
+
35
+ # make sure the bare client was reinitialized
36
+ assert(main_thread_bare_id != new_thread_bare_id)
37
+
38
+ # make sure the main thread's client wasn't messed with
39
+ assert_equal main_thread_bare_id, get_bare_id
40
+ end
41
+
42
+ def test_treats_as_not_fork_safe
43
+ # make sure bare client is initialized
44
+ cache.get 'hi'
45
+
46
+ # get the main process's bare client
47
+ parent_process_bare_id = get_bare_id
48
+
49
+ # sanity check that it's not changing every time
50
+ cache.get 'hi'
51
+ assert_equal parent_process_bare_id, get_bare_id
52
+
53
+ # fork a new process
54
+ pid = Kernel.fork do
55
+ cache.get 'hi'
56
+ raise "Didn't split!" if parent_process_bare_id == get_bare_id
57
+ end
58
+ Process.wait pid
59
+
60
+ # make sure it didn't raise
61
+ assert $?.success?
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,61 @@
1
+ require 'helper'
2
+
3
+ unless RUBY_PLATFORM == 'java'
4
+ require 'memcached'
5
+
6
+ class TestMemcachedRails < TestCase
7
+ def raw_client_class
8
+ Memcached::Rails
9
+ end
10
+
11
+ def raw_client
12
+ raw_client_class.new 'localhost:11211', :support_cas => true
13
+ end
14
+
15
+ include SharedTests
16
+
17
+ def get_bare_id
18
+ cache.thread_metal.object_id
19
+ end
20
+
21
+ def test_treats_as_not_thread_safe
22
+ # make sure bare client is initialized
23
+ cache.get 'hi'
24
+
25
+ # get the main thread's bare client
26
+ main_thread_bare_id = get_bare_id
27
+
28
+ # sanity check that it's not changing every time
29
+ cache.get 'hi'
30
+ assert_equal main_thread_bare_id, get_bare_id
31
+
32
+ # create a new thread and get its bare client
33
+ new_thread_bare_id = Thread.new { cache.get 'hi'; get_bare_id }.value
34
+
35
+ # make sure the bare client was reinitialized
36
+ assert(main_thread_bare_id != new_thread_bare_id)
37
+ end
38
+
39
+ def test_treats_as_not_fork_safe
40
+ # make sure bare client is initialized
41
+ cache.get 'hi'
42
+
43
+ # get the main process's bare client
44
+ parent_process_bare_id = get_bare_id
45
+
46
+ # sanity check that it's not changing every time
47
+ cache.get 'hi'
48
+ assert_equal parent_process_bare_id, get_bare_id
49
+
50
+ # fork a new process
51
+ pid = Kernel.fork do
52
+ cache.get 'hi'
53
+ raise "Didn't split!" if parent_process_bare_id == get_bare_id
54
+ end
55
+ Process.wait pid
56
+
57
+ # make sure it didn't raise
58
+ assert $?.success?
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,17 @@
1
+ require 'helper'
2
+
3
+ unless RUBY_PLATFORM == 'java'
4
+ require 'memcached'
5
+
6
+ class TestMemcachedWithBinary < TestCase
7
+ def raw_client_class
8
+ Memcached
9
+ end
10
+
11
+ def raw_client
12
+ raw_client_class.new 'localhost:11211', :support_cas => true, :binary => true
13
+ end
14
+
15
+ include SharedTests
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+
2
+ require 'helper'
3
+
4
+ class TestMissingDriver < TestCase
5
+ class FooClient; end
6
+
7
+ def raw_client_class
8
+ FooClient
9
+ end
10
+
11
+ def test_missing_driver
12
+ assert_raises(Cache::DriverNotFound) do
13
+ Cache.new(raw_client)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,147 @@
1
+
2
+ require 'helper'
3
+
4
+ class TestNothing < TestCase
5
+ def raw_client
6
+ :nothing
7
+ end
8
+
9
+ def test_get
10
+ assert_equal nil, cache.get('hello')
11
+ cache.set 'hello', 'world'
12
+ assert_equal nil, cache.get('hello')
13
+ end
14
+
15
+ def test_set
16
+ assert_nothing_raised do
17
+ cache.set 'hello', 'world'
18
+ end
19
+ end
20
+
21
+ def test_set_with_ttl
22
+ cache.set 'hello', 'world', 1
23
+ assert_equal nil, cache.get('hello')
24
+ sleep 2
25
+ assert_equal nil, cache.get('hello')
26
+ end
27
+
28
+ def test_set_with_zero_ttl_meaning_eternal
29
+ cache.set 'hello', 'world', 0
30
+ assert_equal nil, cache.get('hello')
31
+ sleep 1
32
+ assert_equal nil, cache.get('hello')
33
+ end
34
+
35
+ def test_delete
36
+ cache.set 'hello', 'world'
37
+ assert_equal nil, cache.get('hello')
38
+ cache.delete 'hello'
39
+ assert_equal nil, cache.get('hello')
40
+ end
41
+
42
+ def test_flush
43
+ cache.set 'hello', 'world'
44
+ assert !cache.exist?('hello')
45
+ end
46
+
47
+ def test_exist
48
+ assert !cache.exist?('hello')
49
+ cache.set 'hello', 'world'
50
+ assert !cache.exist?('hello')
51
+ end
52
+
53
+ def test_exists
54
+ assert !cache.exists?('hello')
55
+ cache.set 'hello', 'world'
56
+ assert !cache.exists?('hello')
57
+ end
58
+
59
+ def test_fetch
60
+ assert_equal nil, cache.fetch('hello')
61
+ assert_equal 'world', cache.fetch('hello') { 'world' }
62
+ end
63
+
64
+ def test_fetch_with_false_boolean
65
+ assert_equal nil, cache.fetch('hello')
66
+ assert_equal false, cache.fetch('hello') { false }
67
+ end
68
+
69
+ def test_fetch_with_expires_in
70
+ assert_equal 'world', cache.fetch('hello', :expires_in => 5) { 'world' }
71
+ end
72
+
73
+ def test_fetch_with_expires_in_stringified
74
+ assert_equal 'world', cache.fetch('hello', 'expires_in' => 5) { 'world' }
75
+ end
76
+
77
+ def test_fetch_with_ignored_options
78
+ assert_equal 'world', cache.fetch('hello', :foo => 'bar') { 'world' }
79
+ end
80
+
81
+ def test_cas
82
+ toggle = lambda do |current|
83
+ current == 'on' ? 'off' : 'on'
84
+ end
85
+
86
+ cache.set 'lights', 'on'
87
+ assert_equal nil, cache.get('lights')
88
+ cache.cas 'lights', &toggle
89
+ assert_equal nil, cache.get('lights')
90
+ cache.cas 'lights', &toggle
91
+ assert_equal nil, cache.get('lights')
92
+ cache.cas 'lights', &toggle
93
+ assert_equal nil, cache.get('lights')
94
+ end
95
+
96
+ def test_write
97
+ cache.write 'hello', 'world'
98
+ assert_equal nil, cache.get('hello')
99
+ end
100
+
101
+ def test_write_with_expires_in
102
+ cache.write 'hello', 'world', :expires_in => 1
103
+ assert_equal nil, cache.get('hello')
104
+ sleep 2
105
+ assert_equal nil, cache.get('hello')
106
+ end
107
+
108
+ def test_write_with_ignored_options
109
+ cache.write 'hello', 'world', :foobar => 'bazboo'
110
+ assert_equal nil, cache.get('hello')
111
+ end
112
+
113
+ def test_read
114
+ cache.set 'hello', 'world'
115
+ assert_equal nil, cache.read('hello')
116
+ end
117
+
118
+ def test_increment
119
+ assert !cache.exist?('high-fives')
120
+ assert_equal 1, cache.increment('high-fives')
121
+ assert_equal nil, cache.get('high-fives')
122
+ assert_equal 1, cache.increment('high-fives')
123
+ assert_equal nil, cache.get('high-fives')
124
+ end
125
+
126
+ def test_decrement
127
+ assert !cache.exist?('high-fives')
128
+ assert_equal -1, cache.decrement('high-fives')
129
+ assert_equal nil, cache.get('high-fives')
130
+ assert_equal -1, cache.decrement('high-fives')
131
+ assert_equal nil, cache.get('high-fives')
132
+ end
133
+
134
+ def test_get_multi
135
+ cache.set 'hello', 'world'
136
+ cache.set 'privyet', 'mir'
137
+ assert_equal({}, cache.get_multi('hello', 'privyet', 'yoyoyo'))
138
+ end
139
+
140
+ # https://github.com/fauna/memcached/pull/50
141
+ def test_get_set_behavior
142
+ cache.flush
143
+ cache.get 'get_set'
144
+ cache.set 'get_set', 'go'
145
+ assert_equal nil, cache.get('get_set')
146
+ end
147
+ end