jmoses-couchbase 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +15 -0
  2. data/.travis.yml +22 -0
  3. data/.yardopts +5 -0
  4. data/CONTRIBUTING.markdown +75 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +201 -0
  7. data/Makefile +3 -0
  8. data/README.markdown +665 -0
  9. data/RELEASE_NOTES.markdown +819 -0
  10. data/Rakefile +20 -0
  11. data/couchbase.gemspec +49 -0
  12. data/examples/chat-em/Gemfile +7 -0
  13. data/examples/chat-em/README.markdown +45 -0
  14. data/examples/chat-em/server.rb +82 -0
  15. data/examples/chat-goliath-grape/Gemfile +5 -0
  16. data/examples/chat-goliath-grape/README.markdown +50 -0
  17. data/examples/chat-goliath-grape/app.rb +67 -0
  18. data/examples/chat-goliath-grape/config/app.rb +20 -0
  19. data/examples/transcoders/Gemfile +3 -0
  20. data/examples/transcoders/README.markdown +59 -0
  21. data/examples/transcoders/cb-zcat +40 -0
  22. data/examples/transcoders/cb-zcp +45 -0
  23. data/examples/transcoders/gzip_transcoder.rb +49 -0
  24. data/examples/transcoders/options.rb +54 -0
  25. data/ext/couchbase_ext/.gitignore +4 -0
  26. data/ext/couchbase_ext/arguments.c +956 -0
  27. data/ext/couchbase_ext/arithmetic.c +316 -0
  28. data/ext/couchbase_ext/bucket.c +1373 -0
  29. data/ext/couchbase_ext/context.c +65 -0
  30. data/ext/couchbase_ext/couchbase_ext.c +1364 -0
  31. data/ext/couchbase_ext/couchbase_ext.h +644 -0
  32. data/ext/couchbase_ext/delete.c +163 -0
  33. data/ext/couchbase_ext/eventmachine_plugin.c +452 -0
  34. data/ext/couchbase_ext/extconf.rb +169 -0
  35. data/ext/couchbase_ext/get.c +316 -0
  36. data/ext/couchbase_ext/gethrtime.c +129 -0
  37. data/ext/couchbase_ext/http.c +432 -0
  38. data/ext/couchbase_ext/multithread_plugin.c +1090 -0
  39. data/ext/couchbase_ext/observe.c +171 -0
  40. data/ext/couchbase_ext/plugin_common.c +171 -0
  41. data/ext/couchbase_ext/result.c +129 -0
  42. data/ext/couchbase_ext/stats.c +163 -0
  43. data/ext/couchbase_ext/store.c +542 -0
  44. data/ext/couchbase_ext/timer.c +192 -0
  45. data/ext/couchbase_ext/touch.c +186 -0
  46. data/ext/couchbase_ext/unlock.c +176 -0
  47. data/ext/couchbase_ext/utils.c +551 -0
  48. data/ext/couchbase_ext/version.c +142 -0
  49. data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
  50. data/lib/active_support/cache/couchbase_store.rb +430 -0
  51. data/lib/couchbase.rb +155 -0
  52. data/lib/couchbase/bucket.rb +457 -0
  53. data/lib/couchbase/cluster.rb +119 -0
  54. data/lib/couchbase/connection_pool.rb +58 -0
  55. data/lib/couchbase/constants.rb +12 -0
  56. data/lib/couchbase/result.rb +26 -0
  57. data/lib/couchbase/transcoder.rb +120 -0
  58. data/lib/couchbase/utils.rb +62 -0
  59. data/lib/couchbase/version.rb +21 -0
  60. data/lib/couchbase/view.rb +506 -0
  61. data/lib/couchbase/view_row.rb +272 -0
  62. data/lib/ext/multi_json_fix.rb +56 -0
  63. data/lib/rack/session/couchbase.rb +108 -0
  64. data/tasks/benchmark.rake +6 -0
  65. data/tasks/compile.rake +160 -0
  66. data/tasks/test.rake +100 -0
  67. data/tasks/util.rake +21 -0
  68. data/test/profile/.gitignore +1 -0
  69. data/test/profile/Gemfile +6 -0
  70. data/test/profile/benchmark.rb +195 -0
  71. data/test/setup.rb +178 -0
  72. data/test/test_arithmetic.rb +185 -0
  73. data/test/test_async.rb +316 -0
  74. data/test/test_bucket.rb +276 -0
  75. data/test/test_cas.rb +235 -0
  76. data/test/test_couchbase.rb +77 -0
  77. data/test/test_couchbase_connection_pool.rb +77 -0
  78. data/test/test_couchbase_rails_cache_store.rb +361 -0
  79. data/test/test_delete.rb +120 -0
  80. data/test/test_errors.rb +82 -0
  81. data/test/test_eventmachine.rb +70 -0
  82. data/test/test_format.rb +164 -0
  83. data/test/test_get.rb +407 -0
  84. data/test/test_stats.rb +57 -0
  85. data/test/test_store.rb +216 -0
  86. data/test/test_timer.rb +42 -0
  87. data/test/test_touch.rb +97 -0
  88. data/test/test_unlock.rb +119 -0
  89. data/test/test_utils.rb +58 -0
  90. data/test/test_version.rb +52 -0
  91. metadata +353 -0
@@ -0,0 +1,77 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require File.join(File.dirname(__FILE__), 'setup')
19
+ require 'minitest/mock'
20
+
21
+ class TestCouchbase < MiniTest::Test
22
+
23
+ def teardown
24
+ Couchbase.reset_thread_storage!
25
+ end
26
+
27
+ def test_that_it_create_instance_of_bucket
28
+ with_mock do |mock|
29
+ assert_instance_of Couchbase::Bucket, Couchbase.new("http://#{mock.host}:#{mock.port}/pools/default")
30
+ end
31
+ end
32
+
33
+ def test_verify_connection
34
+ pid = Process.pid
35
+ assert_equal pid, Couchbase.thread_storage[:pid]
36
+ Couchbase.verify_connection!
37
+ assert_equal pid, Couchbase.thread_storage[:pid]
38
+ end
39
+
40
+ def test_verify_connection_when_process_forks
41
+ pid = Process.pid
42
+ assert_equal pid, Couchbase.thread_storage[:pid]
43
+
44
+ # stub a simulated Kernel#fork
45
+ Process.stub(:pid, Process.pid + 1) do
46
+ Couchbase.verify_connection!
47
+ refute_equal pid, Couchbase.thread_storage[:pid]
48
+ end
49
+ end
50
+
51
+ def test_new_connection_when_process_forks
52
+ with_mock do |mock|
53
+ connection_options = "http://#{mock.host}:#{mock.port}/pools/default"
54
+ Couchbase.connection_options = connection_options
55
+ old_bucket_id = Couchbase.bucket.object_id
56
+
57
+ Process.stub(:pid, Process.pid + 1) do
58
+ refute_equal old_bucket_id, Couchbase.bucket.object_id
59
+ end
60
+ end
61
+ end
62
+
63
+ def test_new_connection_has_same_configuration_options
64
+ with_mock do |mock|
65
+ connection_options = "http://#{mock.host}:#{mock.port}/pools/default"
66
+ Couchbase.connection_options = connection_options
67
+ old_bucket = Couchbase.bucket
68
+
69
+ Process.stub(:pid, Process.pid + 1) do
70
+ new_bucket = Couchbase.bucket
71
+ assert_equal old_bucket.name, new_bucket.name
72
+ assert_equal old_bucket.hostname, new_bucket.hostname
73
+ end
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,77 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2013 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ if RUBY_VERSION.to_f >= 1.9
19
+
20
+ require File.join(File.dirname(__FILE__), 'setup')
21
+ require 'couchbase/connection_pool'
22
+
23
+ class TestCouchbaseConnectionPool < MiniTest::Test
24
+
25
+ def setup
26
+ @mock = start_mock
27
+ @pool = ::Couchbase::ConnectionPool.new(5, :hostname => @mock.host, :port => @mock.port)
28
+ end
29
+
30
+ def teardown
31
+ stop_mock(@mock)
32
+ end
33
+
34
+ def test_basic_multithreaded_usage
35
+ @pool.set('foo', 'bar')
36
+
37
+ threads = []
38
+ 15.times do
39
+ threads << Thread.new do
40
+ @pool.get('foo')
41
+ end
42
+ end
43
+
44
+ result = threads.map(&:value)
45
+ result.each do |val|
46
+ assert_equal 'bar', val
47
+ end
48
+ end
49
+
50
+ def test_set_and_get
51
+ @pool.set('fiz', 'buzz')
52
+ assert_equal 'buzz', @pool.get('fiz')
53
+ end
54
+
55
+ def test_set_and_delete
56
+ @pool.set('baz', 'bar')
57
+ @pool.delete('baz')
58
+ assert_raises Couchbase::Error::NotFound do
59
+ @pool.get('baz')
60
+ end
61
+ end
62
+
63
+ def test_incr
64
+ @pool.set('counter', 0)
65
+ @pool.incr('counter', 1)
66
+ assert_equal 1, @pool.get('counter')
67
+ end
68
+
69
+ def test_decr
70
+ @pool.set('counter', 1)
71
+ @pool.decr('counter', 1)
72
+ assert_equal 0, @pool.get('counter')
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,361 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require File.join(File.dirname(__FILE__), 'setup')
19
+ require 'active_support/cache/couchbase_store'
20
+ require 'active_support/notifications'
21
+ require 'ostruct'
22
+
23
+ class TestCouchbaseRailsCacheStore < MiniTest::Test
24
+
25
+ def setup
26
+ @mock = start_mock
27
+ @foo = OpenStruct.new :payload => "foo"
28
+ @foobar = OpenStruct.new :payload => "foobar"
29
+ end
30
+
31
+ def teardown
32
+ stop_mock(@mock)
33
+ end
34
+
35
+ def store
36
+ @store ||= ActiveSupport::Cache::CouchbaseStore.new(:hostname => @mock.host,
37
+ :port => @mock.port)
38
+ end
39
+
40
+ def pool_store
41
+ @pool_store ||= ActiveSupport::Cache::CouchbaseStore.new(:hostname => @mock.host,
42
+ :port => @mock.port,
43
+ :connection_pool => 5)
44
+ end
45
+
46
+ def prefixed_store
47
+ @prefixed_store ||= ActiveSupport::Cache::CouchbaseStore.new(:hostname => @mock.host,
48
+ :port => @mock.port,
49
+ :namespace => 'v1')
50
+ end
51
+
52
+ def test_it_supported_methods
53
+ supported_methods = store.public_methods(false).map(&:to_sym)
54
+ assert supported_methods.include?(:fetch)
55
+ assert supported_methods.include?(:write)
56
+ assert supported_methods.include?(:read)
57
+ assert supported_methods.include?(:read_multi)
58
+ assert supported_methods.include?(:increment)
59
+ assert supported_methods.include?(:decrement)
60
+ assert supported_methods.include?(:exists?)
61
+ assert supported_methods.include?(:delete)
62
+ assert supported_methods.include?(:stats)
63
+ refute supported_methods.include?(:clear)
64
+ assert_raises(NotImplementedError) do
65
+ store.clear
66
+ end
67
+ refute supported_methods.include?(:cleanup)
68
+ assert_raises(NotImplementedError) do
69
+ store.cleanup
70
+ end
71
+ end
72
+
73
+ def test_it_writes_and_reads_the_data
74
+ store.write uniq_id, @foobar
75
+ assert_equal @foobar, store.read(uniq_id)
76
+ end
77
+
78
+ def test_it_writes_the_data_with_expiration_time
79
+ store.write(uniq_id, @foobar, :expires_in => 1.second)
80
+ assert_equal @foobar, store.read(uniq_id)
81
+ sleep 2
82
+ refute store.read(uniq_id)
83
+ end
84
+
85
+ def test_it_doest_write_data_if_unless_exist_option_is_true
86
+ store.write uniq_id, @foo
87
+ [:unless_exist, :unless_exists].each do |unless_exists|
88
+ store.write uniq_id, @foobar, unless_exists => true
89
+ assert_equal @foo, store.read(uniq_id)
90
+ end
91
+ end
92
+
93
+ def test_it_reads_raw_data
94
+ store.write uniq_id, @foo
95
+ expected = case RUBY_VERSION
96
+ when /^2\.0/
97
+ "\x04\bU:\x0FOpenStruct{\x06:\fpayloadI\"\bfoo\x06:\x06ET"
98
+ when /^1\.9/
99
+ "\x04\bU:\x0FOpenStruct{\x06:\fpayloadI\"\bfoo\x06:\x06EF"
100
+ else
101
+ "\004\bU:\017OpenStruct{\006:\fpayload\"\bfoo"
102
+ end
103
+ assert_equal expected, store.read(uniq_id, :raw => true)
104
+ end
105
+
106
+ def test_it_writes_raw_data
107
+ store.write uniq_id, @foobar, :raw => true
108
+ assert_equal '#<OpenStruct payload="foobar">', store.read(uniq_id, :raw => true)
109
+ end
110
+
111
+ def test_it_deletes_data
112
+ store.write uniq_id, @foo
113
+ store.delete uniq_id
114
+ refute store.read(uniq_id)
115
+ end
116
+
117
+ def test_it_verifies_existence_of_an_object_in_the_store
118
+ store.write uniq_id, @foo
119
+ assert store.exist?(uniq_id)
120
+ refute store.exist?(uniq_id(:missing))
121
+ end
122
+
123
+ def test_it_initializes_key_on_first_increment_with_zero
124
+ store.increment(uniq_id)
125
+ assert_equal 0, store.read(uniq_id)
126
+ assert_equal "0", store.read(uniq_id, :raw => true)
127
+ end
128
+
129
+ def test_it_initializes_key_on_first_decrement_with_zero
130
+ store.decrement(uniq_id)
131
+ assert_equal 0, store.read(uniq_id)
132
+ assert_equal "0", store.read(uniq_id, :raw => true)
133
+ end
134
+
135
+ def test_it_initializes_key_with_given_value_on_increment
136
+ store.increment(uniq_id, 1, :initial => 5)
137
+ assert_equal 5, store.read(uniq_id)
138
+ assert_equal "5", store.read(uniq_id, :raw => true)
139
+ end
140
+
141
+ def test_it_initializes_key_with_given_value_on_decrement
142
+ store.decrement(uniq_id, 1, :initial => 5)
143
+ assert_equal 5, store.read(uniq_id)
144
+ assert_equal "5", store.read(uniq_id, :raw => true)
145
+ end
146
+
147
+ def test_it_increments_a_key
148
+ 3.times { store.increment uniq_id }
149
+ assert_equal 2, store.read(uniq_id)
150
+ assert_equal "2", store.read(uniq_id, :raw => true)
151
+ end
152
+
153
+ def test_it_decrements_a_key
154
+ 4.times { store.increment uniq_id }
155
+ 2.times { store.decrement uniq_id }
156
+ assert_equal 1, store.read(uniq_id)
157
+ assert_equal "1", store.read(uniq_id, :raw => true)
158
+ end
159
+
160
+ def test_it_increments_a_raw_key
161
+ assert store.write(uniq_id, 1, :raw => true)
162
+ store.increment(uniq_id, 2)
163
+ assert_equal 3, store.read(uniq_id, :raw => true).to_i
164
+ end
165
+
166
+ def test_it_decrements_a_raw_key
167
+ assert store.write(uniq_id, 3, :raw => true)
168
+ store.decrement(uniq_id, 2)
169
+ assert_equal 1, store.read(uniq_id, :raw => true).to_i
170
+ end
171
+
172
+ def test_it_increments_a_key_by_given_value
173
+ store.write(uniq_id, 0, :raw => true)
174
+ store.increment uniq_id, 3
175
+ assert_equal 3, store.read(uniq_id, :raw => true).to_i
176
+ end
177
+
178
+ def test_it_decrements_a_key_by_given_value
179
+ store.write(uniq_id, 0, :raw => true)
180
+ 3.times { store.increment uniq_id }
181
+ store.decrement uniq_id, 2
182
+ assert_equal 1, store.read(uniq_id, :raw => true).to_i
183
+ end
184
+
185
+ def test_it_provides_store_stats
186
+ refute store.stats.empty?
187
+ end
188
+
189
+ def test_it_fetches_data
190
+ assert store.write(uniq_id, @foo)
191
+ assert_equal @foo, store.fetch(uniq_id)
192
+ refute store.fetch("rub-a-dub")
193
+ store.fetch("rub-a-dub") { "Flora de Cana" }
194
+ assert_equal "Flora de Cana", store.fetch("rub-a-dub")
195
+ store.fetch(uniq_id, :force => true) # force cache miss
196
+ store.fetch(uniq_id, :force => true, :expires_in => 1.second) { @foobar }
197
+ assert_equal @foobar, store.fetch(uniq_id)
198
+ sleep 2
199
+ refute store.fetch(uniq_id)
200
+ end
201
+
202
+ def test_it_reads_multiple_keys
203
+ assert store.write(uniq_id(1), @foo)
204
+ assert store.write(uniq_id(2), "foo")
205
+ result = store.read_multi uniq_id(1), uniq_id(2)
206
+ assert_equal @foo, result[uniq_id(1)]
207
+ assert_equal "foo", result[uniq_id(2)]
208
+ end
209
+
210
+ def test_it_reads_multiple_keys_and_returns_only_the_matched_ones
211
+ assert store.write(uniq_id, @foo)
212
+ result = store.read_multi uniq_id, uniq_id(:missing)
213
+ assert result[uniq_id]
214
+ refute result[uniq_id(:missing)]
215
+ end
216
+
217
+ def test_it_notifies_on_fetch
218
+ collect_notifications do
219
+ store.fetch(uniq_id) { "foo" }
220
+ end
221
+
222
+ read, generate, write = @events
223
+
224
+ assert_equal 'cache_read.active_support', read.name
225
+ assert_equal({:key => uniq_id, :super_operation => :fetch}, read.payload)
226
+
227
+ assert_equal 'cache_generate.active_support', generate.name
228
+ assert_equal({:key => uniq_id}, generate.payload)
229
+
230
+ assert_equal 'cache_write.active_support', write.name
231
+ assert_equal({:key => uniq_id}, write.payload)
232
+ end
233
+
234
+ def test_it_notifies_on_read
235
+ collect_notifications do
236
+ store.read uniq_id
237
+ end
238
+
239
+ read = @events.first
240
+ assert_equal 'cache_read.active_support', read.name
241
+ assert_equal({:key => uniq_id, :hit => false}, read.payload)
242
+ end
243
+
244
+ def test_it_notifies_on_write
245
+ collect_notifications do
246
+ store.write uniq_id, "foo"
247
+ end
248
+
249
+ write = @events.first
250
+ assert_equal 'cache_write.active_support', write.name
251
+ assert_equal({:key => uniq_id}, write.payload)
252
+ end
253
+
254
+ def test_it_notifies_on_delete
255
+ collect_notifications do
256
+ store.delete uniq_id
257
+ end
258
+
259
+ delete = @events.first
260
+ assert_equal 'cache_delete.active_support', delete.name
261
+ assert_equal({:key => uniq_id}, delete.payload)
262
+ end
263
+
264
+ def test_it_notifies_on_exist?
265
+ collect_notifications do
266
+ store.exist? uniq_id
267
+ end
268
+
269
+ exist = @events.first
270
+ assert_equal 'cache_exists?.active_support', exist.name
271
+ assert_equal({:key => uniq_id}, exist.payload)
272
+ end
273
+
274
+ def test_it_notifies_on_increment
275
+ collect_notifications do
276
+ store.increment uniq_id
277
+ end
278
+
279
+ increment = @events.first
280
+ assert_equal 'cache_increment.active_support', increment.name
281
+ assert_equal({:key => uniq_id, :amount => 1, :create => true}, increment.payload)
282
+ end
283
+
284
+ def test_it_notifies_on_decrement
285
+ collect_notifications do
286
+ store.decrement uniq_id
287
+ end
288
+
289
+ decrement = @events.first
290
+ assert_equal 'cache_decrement.active_support', decrement.name
291
+ assert_equal({:key => uniq_id, :amount => 1, :create => true}, decrement.payload)
292
+ end
293
+
294
+ # Inspiration: https://github.com/mperham/dalli/blob/master/test/test_dalli.rb#L416
295
+ def test_it_is_threadsafe
296
+ workers = []
297
+
298
+ # Have a bunch of threads perform a bunch of operations at the same time.
299
+ # Verify the result of each operation to ensure the request and response
300
+ # are not intermingled between threads.
301
+ 10.times do
302
+ workers << Thread.new do
303
+ 100.times do
304
+ store.write('a', 9)
305
+ store.write('b', 11)
306
+ assert_equal 9, store.read('a')
307
+ assert_equal({ 'a' => 9, 'b' => 11 }, store.read_multi('a', 'b'))
308
+ assert_equal 11, store.read('b')
309
+ assert_equal %w(a b), store.read_multi('a', 'b', 'c').keys.sort
310
+ end
311
+ end
312
+ end
313
+
314
+ workers.each { |w| w.join }
315
+ end
316
+
317
+ def test_it_can_use_connection_pool_for_thread_safety
318
+ workers = []
319
+
320
+ 10.times do
321
+ workers << Thread.new do
322
+ 100.times do
323
+ pool_store.write('a', 9)
324
+ pool_store.write('b', 11)
325
+ assert_equal 9, pool_store.read('a')
326
+ assert_equal({ 'a' => 9, 'b' => 11 }, pool_store.read_multi('a', 'b'))
327
+ assert_equal 11, pool_store.read('b')
328
+ assert_equal %w(a b), pool_store.read_multi('a', 'b', 'c').keys.sort
329
+ end
330
+ end
331
+ end
332
+
333
+ workers.each { |w| w.join }
334
+ end
335
+
336
+ # These tests are only relevant against a real server,
337
+ # CouchbaseMock seems to accept long keys.
338
+ def test_it_can_handle_keys_longer_than_250_characters
339
+ long_key = 'a' * 260
340
+ assert store.write(long_key, 123)
341
+ assert_equal 123, store.read(long_key)
342
+ end
343
+
344
+ def test_it_can_handle_keys_longer_than_250_characters_with_a_prefix
345
+ long_key = 'a' * 249
346
+ assert prefixed_store.write(long_key, 123)
347
+ assert_equal 123, prefixed_store.read(long_key)
348
+ end
349
+
350
+ private
351
+
352
+ def collect_notifications
353
+ @events = [ ]
354
+ ActiveSupport::Cache::CouchbaseStore.instrument = true
355
+ ActiveSupport::Notifications.subscribe(/^cache_(.*)\.active_support$/) do |*args|
356
+ @events << ActiveSupport::Notifications::Event.new(*args)
357
+ end
358
+ yield
359
+ ActiveSupport::Cache::CouchbaseStore.instrument = false
360
+ end
361
+ end