torquebox-cache 2.0.0.beta1-java

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.
@@ -0,0 +1,93 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require File.dirname(__FILE__) + '/spec_helper'
18
+ require 'cache_listener'
19
+
20
+ describe TorqueBox::Infinispan::CacheListener do
21
+ before :each do
22
+ @cache = TorqueBox::Infinispan::Cache.new( :name => 'foo-cache' )
23
+ end
24
+
25
+ after :each do
26
+ @cache.clear
27
+ end
28
+
29
+ it "the cache should accept listeners" do
30
+ @cache.should respond_to :add_listener
31
+ end
32
+
33
+ it "should notify when an entry is added to the cache" do
34
+ listener = TestListener.new
35
+ @cache.add_listener( listener )
36
+ listener.should_receive( :cache_entry_created ).at_least :once
37
+ @cache.put("akey", "avalue")
38
+ end
39
+
40
+ it "should notify when an entry is deleted from the cache" do
41
+ listener = TestListener.new
42
+ @cache.add_listener( listener )
43
+ @cache.put("akey", "avalue")
44
+ listener.should_receive( :cache_entry_removed ).at_least :once
45
+ @cache.remove("akey")
46
+ end
47
+
48
+ it "should notify when an entry is retrieved from the cache" do
49
+ listener = TestListener.new
50
+ @cache.add_listener( listener )
51
+ @cache.put("akey", "avalue")
52
+ listener.should_receive( :cache_entry_visited ).at_least :once
53
+ @cache.get("akey")
54
+ end
55
+
56
+ it "should notify when an entry is modified in the cache" do
57
+ listener = TestListener.new
58
+ @cache.add_listener( listener )
59
+ @cache.put("akey", "avalue")
60
+ listener.should_receive( :cache_entry_modified ).at_least :once
61
+ @cache.put("akey", "another value")
62
+ end
63
+
64
+ it "should notify when an entry is activated in the cache" do
65
+ pending "Figuring out why this doesn't work"
66
+ listener = TestListener.new
67
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'foo-cache', :persist=>true )
68
+ cache.add_listener( listener )
69
+ cache.put("akey", "avalue")
70
+ cache.evict("akey")
71
+ listener.should_receive( :cache_entry_activated ).at_least :once
72
+ cache.get("akey")
73
+ end
74
+
75
+ it "should notify when an entry is evicted in the cache" do
76
+ listener = TestListener.new
77
+ @cache.add_listener( listener )
78
+ @cache.put("akey", "avalue")
79
+ listener.should_receive( :cache_entry_evicted ).at_least :once
80
+ @cache.evict( "akey" )
81
+ end
82
+
83
+ end
84
+
85
+ class TestListener < TorqueBox::Infinispan::CacheListener
86
+ def cache_entry_created(entry) ; end
87
+ def cache_entry_removed(entry) ; end
88
+ def cache_entry_visited(entry) ; end
89
+ def cache_entry_modified(entry) ; end
90
+ def cache_entry_evicted(entry) ; end
91
+ def cache_entry_activated(entry) ; end
92
+ end
93
+
@@ -0,0 +1,361 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require File.dirname(__FILE__) + '/spec_helper'
18
+
19
+ describe TorqueBox::Infinispan::Cache do
20
+ before :each do
21
+ @cache = TorqueBox::Infinispan::Cache.new( :name => 'foo-cache' )
22
+ end
23
+
24
+ after :each do
25
+ @cache.clear
26
+ end
27
+
28
+ it "should have a name" do
29
+ @cache.name.should == 'foo-cache'
30
+ end
31
+
32
+ it "should reuse existing cache managers for an extant local cache" do
33
+ TorqueBox::Infinispan::Cache.should_receive( :find_local_manager ).with( 'foo-cache' )
34
+ TorqueBox::Infinispan::Cache.new( :name => 'foo-cache' )
35
+ end
36
+
37
+ it "should respond to clustering_mode" do
38
+ @cache.should respond_to( :clustering_mode )
39
+ end
40
+
41
+ it "should accept and return strings" do
42
+ @cache.put('foo', 'bar').should be_true
43
+ @cache.get('foo').should == 'bar'
44
+ end
45
+
46
+ it "should accept and return ruby objects" do
47
+ heffalump = Snuffleuffagus.new(100, 'snuffle')
48
+ @cache.put('heffalump', heffalump).should be_true
49
+ rheffalump = @cache.get('heffalump')
50
+ rheffalump.name.should == heffalump.name
51
+ rheffalump.id.should == heffalump.id
52
+ end
53
+
54
+ it "should return all keys" do
55
+ @cache.put('one', 1)
56
+ @cache.put('two', 2)
57
+ @cache.put('three', 3)
58
+ keys = @cache.keys
59
+ keys.length.should == 3
60
+ keys.include?('one').should be_true
61
+ keys.include?('two').should be_true
62
+ keys.include?('three').should be_true
63
+ end
64
+
65
+ it "should allow removal of a key/value" do
66
+ @cache.put('foo', 'bar')
67
+ @cache.keys.length.should == 1
68
+ @cache.remove('foo').should be_true
69
+ @cache.keys.length.should == 0
70
+ end
71
+
72
+ it "should only insert on put_if_absent if the key is not already in the cache" do
73
+ @cache.put_if_absent('foo', 'bar').should be_true
74
+ @cache.put_if_absent('foo', 'foobar')
75
+ @cache.get('foo').should == 'bar'
76
+ end
77
+
78
+ it "should clear" do
79
+ @cache.clear.should be_true
80
+ end
81
+
82
+ it "should replace existing string values" do
83
+ key = 'thekey'
84
+ current_value = '{value:1}'
85
+ new_value = '{value:2}'
86
+ @cache.put(key, current_value)
87
+ @cache.get(key).should == current_value
88
+ @cache.replace(key, current_value, new_value)
89
+ @cache.get(key).should == new_value
90
+ end
91
+
92
+ it "should replace existing ruby object values" do
93
+ key = 'thekey'
94
+ current_value = Snuffleuffagus.new(1, 'foo')
95
+ new_value = Snuffleuffagus.new(2, 'bar')
96
+ @cache.put(key, current_value)
97
+ @cache.get(key).should == current_value
98
+ @cache.replace(key, current_value, new_value)
99
+ @cache.get(key).name.should == new_value.name
100
+ end
101
+
102
+ it "should not replace existing string values if the expected value is different" do
103
+ key = 'string key'
104
+ current_value = '{value:1}'
105
+ new_value = '{value:2}'
106
+ @cache.put(key, current_value)
107
+ @cache.get(key).should == current_value
108
+ @cache.replace(key, 'something else', new_value)
109
+ @cache.get(key).should == current_value
110
+ end
111
+
112
+ it "should not replace existing ruby object values if the expected value is different" do
113
+ key = 'ruby object key'
114
+ current_value = Snuffleuffagus.new(1, 'foo')
115
+ new_value = Snuffleuffagus.new(2, 'bar')
116
+ @cache.put(key, current_value)
117
+ @cache.get(key).should == current_value
118
+ @cache.replace(key, new_value, new_value)
119
+ @cache.get(key).should == current_value
120
+ end
121
+
122
+ it "should store java objects" do
123
+ entry = java.util.HashMap.new
124
+ entry.put( "Snuffleuffagus", "{color: brown}" )
125
+ @cache.put('Snuffleuffagus/1', entry)
126
+ @cache.get('Snuffleuffagus/1').should_not be_nil
127
+ end
128
+
129
+ it "should increment a sequence" do
130
+ puts "AAAA"
131
+ @cache.increment("My Sequence Name", 1).should == 1
132
+ puts "BBBB"
133
+ @cache.increment("My Sequence Name", 1).should == 2
134
+ end
135
+
136
+ it "should increment a sequence by a user-specified amount" do
137
+ @cache.increment("My Sequence Name", 9).should == 9
138
+ @cache.increment("My Sequence Name", 9).should == 18
139
+ end
140
+
141
+ it "should store and retrieve false values" do
142
+ @cache.put('a false value', false)
143
+ @cache.contains_key?('a false value').should be_true
144
+ @cache.get('a false value').should be_false
145
+ end
146
+
147
+ it "should store and retrieve nil values" do
148
+ pending
149
+ @cache.put('a nil value', nil)
150
+ @cache.contains_key?('a nil value').should be_true
151
+ @cache.get('a nil value').should be_nil
152
+ end
153
+
154
+ it "should expire entries based on provided expiry durations" do
155
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'expiring-cache' )
156
+ cache.put("foo", "bar", 0.1)
157
+ sleep 1
158
+ cache.get("foo").should be_nil
159
+ end
160
+
161
+ describe "with JTA transactions" do
162
+
163
+ it "should should be transactional by default" do
164
+ @cache.transactional?.should be_true
165
+ @cache.transaction_mode.should == org.infinispan.transaction.TransactionMode::TRANSACTIONAL
166
+ end
167
+
168
+ it "should support non-transactional mode" do
169
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'non-transactional-cache', :transaction_mode => false )
170
+ cache.transactional?.should be_false
171
+ cache.transaction_mode.should == org.infinispan.transaction.TransactionMode::NON_TRANSACTIONAL
172
+ begin
173
+ cache.transaction do
174
+ cache.put "key1", "G"
175
+ raise "An exception"
176
+ cache.put "key2", "C"
177
+ end
178
+ rescue Exception => e
179
+ e.message.should == "An exception"
180
+ cache.get("key1").should == "G"
181
+ cache.get("key2").should be_nil
182
+ end
183
+ cache.stop
184
+ end
185
+
186
+ it "should use optimisitic locking mode by default" do
187
+ @cache.locking_mode.should == org.infinispan.transaction.LockingMode::OPTIMISTIC
188
+ end
189
+
190
+ it "should support pessimistic locking mode" do
191
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'non-transactional-cache', :locking_mode => :pessimistic )
192
+ cache.locking_mode.should == org.infinispan.transaction.LockingMode::PESSIMISTIC
193
+ cache.stop
194
+ end
195
+
196
+ it "should accept transactional blocks" do
197
+ @cache.transaction do |cache|
198
+ cache.put('Frankie', 'Vallie')
199
+ end
200
+ @cache.get('Frankie').should == 'Vallie'
201
+ end
202
+
203
+ it "should behave like a transaction" do
204
+ begin
205
+ @cache.transaction do |cache|
206
+ cache.put('Tommy', 'Dorsey')
207
+ cache.put('Elvis', 'Presley')
208
+ raise "yikes!"
209
+ end
210
+ rescue
211
+ end
212
+ @cache.get('Tommy').should be_nil
213
+ @cache.get('Elvis').should be_nil
214
+ end
215
+
216
+ it "should handle multiple transactions" do
217
+ begin
218
+ @cache.transaction do |cache|
219
+ cache.put('Tommy', 'Dorsey')
220
+ raise "yikes!"
221
+ cache.put('Elvis', 'Presley')
222
+ end
223
+ rescue
224
+ end
225
+ @cache.get('Tommy').should be_nil
226
+ @cache.get('Elvis').should be_nil
227
+ @cache.transaction do |cache|
228
+ cache.put('Tommy', 'Dorsey')
229
+ cache.put('Elvis', 'Presley')
230
+ end
231
+ @cache.get('Tommy').should == 'Dorsey'
232
+ @cache.get('Elvis').should == 'Presley'
233
+ end
234
+ end
235
+
236
+ describe "with persistence" do
237
+ before(:all) do
238
+ @default_dir = File.join(File.dirname(__FILE__), '..', 'Infinispan-FileCacheStore')
239
+ @configured_dir = File.join( File.dirname(__FILE__), '..', random_string + "-persisted.cache" )
240
+ @date_cfg_dir = File.join( File.dirname(__FILE__), '..', random_string + "-persisted-date.cache" )
241
+ @index_dir = File.join( File.dirname(__FILE__), '..', 'java.util.HashMap' )
242
+ FileUtils.mkdir @configured_dir
243
+ FileUtils.mkdir @date_cfg_dir
244
+ end
245
+
246
+ after(:all) do
247
+ FileUtils.rm_rf @default_dir
248
+ FileUtils.rm_rf @configured_dir
249
+ FileUtils.rm_rf @date_cfg_dir
250
+ FileUtils.rm_rf @index_dir if File.exist?( @index_dir )
251
+ end
252
+
253
+ it "should persist the data with a default directory" do
254
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'persisted-cache', :persist => true )
255
+ entry = java.util.HashMap.new
256
+ entry.put( "Hello", "world" )
257
+ cache.put('foo', entry)
258
+ File.exist?(@default_dir).should be_true
259
+ end
260
+
261
+ it "should persist the data with a configured directory" do
262
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'persisted-date-cache', :persist => @configured_dir.to_s )
263
+ entry = java.util.HashMap.new
264
+ entry.put( "Hello", "world" )
265
+ cache.put('foo', entry)
266
+ File.exist?("#{@configured_dir.to_s}/persisted-date-cache").should be_true
267
+ end
268
+
269
+ it "should persist dates with a configured directory" do
270
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'persisted-configured-date-cache', :persist => @date_cfg_dir.to_s )
271
+ entry = java.util.Date.new
272
+ cache.put('foo', entry).should be_true
273
+ File.exist?("#{@date_cfg_dir.to_s}/persisted-configured-date-cache").should be_true
274
+ end
275
+
276
+ it "should evict keys from the heap" do
277
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'foo-cache' )
278
+ cache.put("akey", "avalue")
279
+ cache.evict( "akey" )
280
+ # when cache is in-memory only, the key should return nil
281
+ cache.get( "akey" ).should == nil
282
+ end
283
+
284
+ it "should only evict keys from the heap, not persistent storage" do
285
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'evict-cache', :persist=>true )
286
+ cache.put("akey", "avalue")
287
+ cache.evict( "akey" )
288
+ cache.get( "akey" ).should == "avalue"
289
+ end
290
+
291
+ it "should expire entries based on provided expiry durations" do
292
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'expiring-cache', :persist=>true )
293
+ cache.put("foo", "bar", 0.1)
294
+ sleep 1
295
+ cache.get("foo").should be_nil
296
+ end
297
+
298
+ it "should handle transactions" do
299
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'foo-cache', :persist=>true )
300
+ begin
301
+ @cache.transaction do
302
+ cache.put('Tommy', 'Dorsey')
303
+ cache.put('Elvis', 'Presley')
304
+ raise "yikes!"
305
+ end
306
+ rescue
307
+ end
308
+ @cache.get('Tommy').should be_nil
309
+ @cache.get('Elvis').should be_nil
310
+ end
311
+
312
+ it "should handle multiple transactions" do
313
+ cache = TorqueBox::Infinispan::Cache.new( :name => 'foo-cache', :persist=>true )
314
+ begin
315
+ cache.transaction do |cache|
316
+ cache.put('Tommy', 'Dorsey')
317
+ raise "yikes!"
318
+ cache.put('Elvis', 'Presley')
319
+ end
320
+ rescue
321
+ end
322
+ cache.get('Tommy').should be_nil
323
+ cache.get('Elvis').should be_nil
324
+ cache.transaction do
325
+ cache.put('Tommy', 'Dorsey')
326
+ cache.put('Elvis', 'Presley')
327
+ end
328
+ cache.get('Tommy').should == 'Dorsey'
329
+ cache.get('Elvis').should == 'Presley'
330
+ end
331
+ end
332
+
333
+ describe "with search" do
334
+ before :each do
335
+ @cache = TorqueBox::Infinispan::Cache.new( :name => 'foo-cache' )
336
+ end
337
+
338
+ it "should ask the cache for the search managager" do
339
+ @cache.should_receive :search_manager
340
+ Infinispan::Search.new(@cache, lambda{|v|v})
341
+ end
342
+
343
+ after :each do
344
+ @cache.clear
345
+ end
346
+ end
347
+
348
+ end
349
+
350
+ class Snuffleuffagus
351
+ attr_accessor :id, :name
352
+
353
+ def initialize(id=1, name=:default)
354
+ @id = id
355
+ @name = name
356
+ end
357
+
358
+ def ==(other)
359
+ (@id == other.id) && (@name == other.name)
360
+ end
361
+ end