torquebox-cache 2.0.0.beta1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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