Ruby-MemCache 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/test.rb ADDED
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Test suite for Arrow
4
+ #
5
+ #
6
+
7
+ BEGIN {
8
+ basedir = File::dirname( File::expand_path(__FILE__) )
9
+ $LOAD_PATH.unshift "#{basedir}/lib", "#{basedir}/tests"
10
+
11
+ require "#{basedir}/utils"
12
+ include UtilityFunctions
13
+ }
14
+
15
+ verboseOff {
16
+ require 'mctestcase'
17
+ require 'find'
18
+ require 'test/unit'
19
+ require 'test/unit/testsuite'
20
+ require 'test/unit/ui/console/testrunner'
21
+ require 'optparse'
22
+ }
23
+
24
+ # Turn off output buffering
25
+ $stderr.sync = $stdout.sync = true
26
+ $DebugPattern = nil
27
+ $Memcached = true
28
+
29
+ # Initialize variables
30
+ safelevel = 0
31
+ patterns = []
32
+ requires = []
33
+
34
+ # Parse command-line switches
35
+ ARGV.options {|oparser|
36
+ oparser.banner = "Usage: #$0 [options] [TARGETS]\n"
37
+
38
+ oparser.on( "--debug[=PATTERN]", "-d[=PATTERN]", String,
39
+ "Turn debugging on (for tests which match PATTERN)" ) {|arg|
40
+ if arg
41
+ if $DebugPattern
42
+ $DebugPattern = Regexp::union( $DebugPattern, Regexp::new(arg) )
43
+ else
44
+ $DebugPattern = Regexp::new( arg )
45
+ end
46
+ puts "Turned debugging on for %p." % $DebugPattern
47
+ else
48
+ $DEBUG = true
49
+ debugMsg "Turned debugging on globally."
50
+ end
51
+ }
52
+
53
+ oparser.on( "--verbose", "-v", TrueClass, "Make progress verbose" ) {
54
+ $VERBOSE = true
55
+ debugMsg "Turned verbose on."
56
+ }
57
+
58
+ oparser.on( "--no-memcached", "-n", TrueClass,
59
+ "Skip the tests which require a running memcached." ) {
60
+ $Memcached = false
61
+ debugMsg "Skipping memcached-based tests"
62
+ }
63
+
64
+ # Handle the 'help' option
65
+ oparser.on( "--help", "-h", "Display this text." ) {
66
+ $stderr.puts oparser
67
+ exit!(0)
68
+ }
69
+
70
+ oparser.parse!
71
+ }
72
+
73
+ # Parse test patterns
74
+ ARGV.each {|pat| patterns << Regexp::new( pat, Regexp::IGNORECASE )}
75
+ $stderr.puts "#{patterns.length} patterns given on the command line"
76
+
77
+ ### Load all the tests from the tests dir
78
+ Find.find("tests") {|file|
79
+ Find.prune if /\/\./ =~ file or /~$/ =~ file
80
+ Find.prune if /TEMPLATE/ =~ file
81
+ next if File.stat( file ).directory?
82
+
83
+ unless patterns.empty?
84
+ Find.prune unless patterns.find {|pat| pat =~ file}
85
+ end
86
+
87
+ debugMsg "Considering '%s': " % file
88
+ next unless file =~ /\.tests.rb$/
89
+ debugMsg "Requiring '%s'..." % file
90
+ require "#{file}"
91
+ requires << file
92
+ }
93
+
94
+ $stderr.puts "Required #{requires.length} files."
95
+ unless patterns.empty?
96
+ $stderr.puts "[" + requires.sort.join( ", " ) + "]"
97
+ end
98
+
99
+ # Build the test suite
100
+ class MemCacheTests
101
+ class << self
102
+ def suite
103
+ suite = Test::Unit::TestSuite.new( "MemCache" )
104
+
105
+ if suite.respond_to?( :add )
106
+ ObjectSpace.each_object( Class ) {|klass|
107
+ suite.add( klass.suite ) if klass < MemCache::TestCase
108
+ }
109
+ else
110
+ ObjectSpace.each_object( Class ) {|klass|
111
+ suite << klass.suite if klass < MemCache::TestCase
112
+ }
113
+ end
114
+
115
+ return suite
116
+ end
117
+ end
118
+ end
119
+
120
+ # Run tests
121
+ $SAFE = safelevel
122
+ Test::Unit::UI::Console::TestRunner.new( MemCacheTests ).start
123
+
124
+
125
+
126
+
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/ruby -w
2
+ #
3
+ # Unit test for error-handling
4
+ # $Id: errorhandling.tests.rb 20 2004-10-05 05:40:52Z ged $
5
+ #
6
+ # Copyright (c) 2004 RubyCrafters, LLC. Most rights reserved.
7
+ #
8
+ # This work is licensed under the Creative Commons Attribution-ShareAlike
9
+ # License. To view a copy of this license, visit
10
+ # http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative
11
+ # Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
12
+ #
13
+ #
14
+
15
+ unless defined? MemCache::TestCase
16
+ testsdir = File::dirname( File::expand_path(__FILE__) )
17
+ basedir = File::dirname( testsdir )
18
+ $LOAD_PATH.unshift "#{basedir}/lib" unless
19
+ $LOAD_PATH.include?( "#{basedir}/lib" )
20
+ $LOAD_PATH.unshift "#{basedir}/tests" unless
21
+ $LOAD_PATH.include?( "#{basedir}/tests" )
22
+
23
+ require 'mctestcase'
24
+ end
25
+
26
+
27
+ ### Collection of tests for the M class.
28
+ class MemCache::ErrorHandlingTestCase < MemCache::TestCase
29
+
30
+ ConnectErrorServer = 'localhost:61654'
31
+
32
+ ### Set up memcache instance or skip
33
+ def setup
34
+ if @config
35
+ server = [ @config[:server], @config[:port] ].join(":")
36
+ @memcache = MemCache::new( server )
37
+ @memcache.clear
38
+ @memcache.debug = $DEBUG
39
+ else
40
+ skip( "No memcached to test against." )
41
+ end
42
+
43
+ super
44
+ end
45
+
46
+
47
+ #################################################################
48
+ ### T E S T S
49
+ #################################################################
50
+
51
+ def test_00_connection_error
52
+ printTestHeader "ErrorHandling: Connection error"
53
+
54
+ # Test to be sure connection errors result in servers being marked dead.
55
+ cache = MemCache::new( ConnectErrorServer )
56
+ server = cache.method(:get_server).call( :any_key_should_work )
57
+
58
+ assert !server.alive?, "Server should be dead"
59
+ end
60
+
61
+
62
+ def test_10_general_error
63
+ printTestHeader "ErrorHandling: General error"
64
+ rval = nil
65
+
66
+ # Grab the server object that the cache will use (:foo is an arbitrary
67
+ # key to hash on -- in theory anything should work).
68
+ server = @memcache.method( :get_server ).call( :foo )
69
+
70
+ # Now send an illegal command directly via #send and expect an
71
+ # "ERROR\r\n" message to be sent back and an exception to be raised
72
+ # because of it.
73
+ assert_raises( MemCache::InternalError ) {
74
+ @memcache.method( :send ).call( server => "bargle" )
75
+ }
76
+ end
77
+
78
+
79
+
80
+ ### Test to be sure the error strings can be get/set without triggering
81
+ ### exceptions (tests the error-condition matching code).
82
+ def test_99_false_positive
83
+ printTestHeader "ErrorHandling: False positives"
84
+ rval = nil
85
+
86
+ strings = {
87
+ :general => "ERROR\r\n",
88
+ :server => "SERVER_ERROR false positive\r\n",
89
+ :client => "CLIENT_ERROR false positive\r\n",
90
+ }
91
+
92
+ # Set key and value
93
+ strings.each do |key, str|
94
+
95
+ # Key
96
+ debugMsg "Setting %p = %p" % [ str, key ]
97
+ assert_nothing_raised { @memcache[ str ] = key }
98
+
99
+ # Value
100
+ debugMsg "Setting %p = %p" % [ key, str ]
101
+ assert_nothing_raised { @memcache[ key ] = str }
102
+ end
103
+
104
+ # Get key and value
105
+ strings.each do |key, str|
106
+
107
+ # Key
108
+ debugMsg "Fetching %p" % [ str ]
109
+ assert_nothing_raised { rval = @memcache[ str ] }
110
+ assert_nil_or_equal key, rval, "Error message as key"
111
+
112
+ # Value
113
+ debugMsg "Fetching %p" % [ key ]
114
+ assert_nothing_raised { rval = @memcache[ key ] }
115
+ assert_nil_or_equal str, rval, "Symbol as key"
116
+ end
117
+ end
118
+
119
+ end
120
+
@@ -0,0 +1,365 @@
1
+ #!/usr/bin/ruby -w
2
+ #
3
+ # Unit test for the get/set operations on the MemCache class
4
+ # $Id: getset.tests.rb 30 2004-11-13 17:32:06Z ged $
5
+ #
6
+ # Copyright (c) 2004 RubyCrafters, LLC. Most rights reserved.
7
+ #
8
+ # This work is licensed under the Creative Commons Attribution-ShareAlike
9
+ # License. To view a copy of this license, visit
10
+ # http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative
11
+ # Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
12
+ #
13
+ #
14
+
15
+ unless defined? MemCache::TestCase
16
+ testsdir = File::dirname( File::expand_path(__FILE__) )
17
+ basedir = File::dirname( testsdir )
18
+ $LOAD_PATH.unshift "#{basedir}/lib" unless
19
+ $LOAD_PATH.include?( "#{basedir}/lib" )
20
+ $LOAD_PATH.unshift "#{basedir}/tests" unless
21
+ $LOAD_PATH.include?( "#{basedir}/tests" )
22
+
23
+ require 'mctestcase'
24
+ end
25
+
26
+
27
+ ### Collection of tests for the MemCache class.
28
+ class MemCacheTestCase < MemCache::TestCase
29
+
30
+
31
+ TestDataMatrix = {
32
+ 'alooo' => 'bar',
33
+ :foo => [:bar, :baz, :boing],
34
+ {:ark => 1} => "giraffe of doom",
35
+ Time::now => 0,
36
+ "INDIGO" => :i,
37
+ 23.12 => "quickly accelerated",
38
+ }
39
+
40
+
41
+ ### Set up memcache instance or skip
42
+ def setup
43
+ if @config
44
+ server = [ @config[:server], @config[:port] ].join(":")
45
+ @memcache = MemCache::new( server )
46
+ @memcache.clear
47
+ @memcache.debug = $DEBUG
48
+ else
49
+ skip( "No memcached to test against." )
50
+ end
51
+
52
+ super
53
+ end
54
+
55
+
56
+
57
+ #################################################################
58
+ ### T E S T S
59
+ #################################################################
60
+
61
+ ### Test setting via #set, get via #get
62
+ def test_10_getset_methods
63
+ printTestHeader "Get/Set; Methods"
64
+ rval = obj = nil
65
+
66
+ # Set without expiration
67
+ TestDataMatrix.each do |key, val|
68
+ assert_nothing_raised { rval = @memcache.set(key, val) }
69
+ assert_equal true, rval, "For set(%p, %p)" % [key,val]
70
+ end
71
+
72
+ # Set with expiration
73
+ TestDataMatrix.each do |key, val|
74
+ assert_nothing_raised { rval = @memcache.set(key, val, 3600) }
75
+ assert_equal true, rval, "For set( %p, %p, 3600 )" % [key,val]
76
+ end
77
+
78
+ # Get
79
+ TestDataMatrix.each do |key, val|
80
+ assert_nothing_raised { rval = @memcache.get(key) }
81
+ assert_nil_or_equal val, rval
82
+ end
83
+ end
84
+
85
+
86
+ ### Test setting via #[]=, get via #[]
87
+ def test_20_index_methods
88
+ printTestHeader "Get/Set: Index Methods"
89
+ rval = obj = nil
90
+
91
+ # Set
92
+ TestDataMatrix.each do |key, val|
93
+ assert_nothing_raised { rval = (@memcache[ key ] = val) }
94
+ assert_equal val, rval, "For [%p]=%p" % [key,val]
95
+ end
96
+
97
+ # Get
98
+ TestDataMatrix.each do |key, val|
99
+ assert_nothing_raised { rval = @memcache[ key ] }
100
+ assert_nil_or_equal val, rval, "For [%p]" % [key]
101
+ end
102
+ end
103
+
104
+
105
+ # Multi-set, multi-get
106
+ def test_30_multi_setget
107
+ printTestHeader "Get/Set: Multi-set/-get"
108
+ rval = obj = nil
109
+
110
+ keys = TestDataMatrix.keys.sort_by {|obj| obj.hash}
111
+ values = TestDataMatrix.values_at( *keys )
112
+
113
+ # Multi-set via index operator slice
114
+ assert_nothing_raised do
115
+ rval = (@memcache[ *keys ] = values)
116
+ end
117
+ assert_instance_of Array, rval
118
+
119
+ # Multi-set via #set_many
120
+ assert_nothing_raised do
121
+ rval = @memcache.set_many( TestDataMatrix )
122
+ end
123
+ assert_instance_of Array, rval
124
+
125
+ # Multi-get via index operator slice
126
+ assert_nothing_raised do
127
+ rval = @memcache[ *keys ]
128
+ end
129
+ assert_instance_of Array, rval
130
+ values.each_with_index do |val, i|
131
+ assert_nil_or_equal val, rval[i],
132
+ "For key = <%p>" % keys[i]
133
+ end
134
+
135
+ # Multi-get via get(...)
136
+ assert_nothing_raised do
137
+ rval = @memcache.get( *keys )
138
+ end
139
+ assert_instance_of Array, rval
140
+ values.each_with_index do |val, i|
141
+ assert_nil_or_equal val, rval[i],
142
+ "For key = <%p>" % keys[i]
143
+ end
144
+
145
+ end
146
+
147
+
148
+ # Delete
149
+ def test_40_delete
150
+ printTestHeader "Get/Set: Delete"
151
+ rval = obj = nil
152
+
153
+ @memcache.set_many( TestDataMatrix )
154
+
155
+ # Without expiry
156
+ TestDataMatrix.each do |key,val|
157
+ assert_nothing_raised { rval = @memcache.delete(key) }
158
+ assert_equal true, rval, "Results of #delete(%p)" % [key]
159
+
160
+ rval = @memcache.get( key )
161
+ assert_nil rval, "Get %p after #delete with no expiry" % [key]
162
+ end
163
+
164
+ # Re-delete should return false
165
+ #TestDataMatrix.each do |key,val|
166
+ # assert_nothing_raised { rval = @memcache.delete(key) }
167
+ # assert_equal false, rval, "Results of #delete(%p)" % [key]
168
+ #end
169
+
170
+ @memcache.set_many( TestDataMatrix )
171
+
172
+ # With expiry
173
+ TestDataMatrix.each do |key,val|
174
+ assert_nothing_raised { rval = @memcache.delete(key, 15) }
175
+ assert_equal true, rval, "Results of #delete(%p, 15)" % [key]
176
+
177
+ rval = @memcache.get( key )
178
+ assert_nil rval, "Get %p after #delete with expiry" % [key]
179
+ end
180
+ end
181
+
182
+
183
+ # Either 'delete' or 'add' as far as I can tell is fundamentally broken in
184
+ # memcached. Deleting an item with an expiration of '0' should, according to
185
+ # the protocol doc, cause the next 'add' to succeed:
186
+ # " The parameter <time> is optional, and, if absent, defaults to 0 (which
187
+ # means that the item will be deleted immediately and further storage
188
+ # commands with this key will succeed)."
189
+ # This however is not what happens. It instead replies 'NOT_STORED' for at
190
+ # least several seconds:
191
+ #
192
+ # The script (which can also be found in experiments/add.script):
193
+ # delete foo
194
+ # set foo 4 0 3
195
+ # bar
196
+ # delete foo
197
+ # add foo 12 0 2
198
+ # 12
199
+ # quit
200
+ #
201
+ # When run against a memcached:
202
+ # $ cat experiments/add.script | nc -vv localhost 11211
203
+ # localhost [127.0.0.1] 11211 (?) open
204
+ # NOT_FOUND
205
+ # STORED
206
+ # DELETED
207
+ # NOT_STORED
208
+ # sent 70, rcvd 40
209
+ #
210
+ # And memcached's verbose output:
211
+ # <3 server listening
212
+ # <5 new client connection
213
+ # <5 delete foo
214
+ # >5 NOT_FOUND
215
+ # <5 set foo 4 0 3
216
+ # >5 STORED
217
+ # <5 delete foo
218
+ # >5 DELETED
219
+ # <5 add foo 12 0 2
220
+ # >5 NOT_STORED
221
+ # <5 quit
222
+ # <5 connection closed.
223
+
224
+ # Add
225
+ #def test_50_add
226
+ # printTestHeader "Get/Set: Add"
227
+ # rval = obj = nil
228
+ #
229
+ # @memcache.clear
230
+ #
231
+ # # Without expiration
232
+ # TestDataMatrix.each do |key, val|
233
+ # @memcache.delete( key )
234
+ # assert_nothing_raised { rval = @memcache.add(key, val) }
235
+ # assert_equal true, rval, "First #add"
236
+ #
237
+ # assert_nothing_raised { rval = @memcache.add(key, val) }
238
+ # assert_equal false, rval, "Second #add"
239
+ # end
240
+ #
241
+ # # Get
242
+ # TestDataMatrix.each do |key, val|
243
+ # assert_nothing_raised { rval = @memcache.get(key) }
244
+ # assert_nil_or_equal val, rval
245
+ # end
246
+ #
247
+ # @memcache.clear
248
+ #
249
+ # # With expiration
250
+ # TestDataMatrix.each do |key, val|
251
+ # @memcache.delete( key )
252
+ # assert_nothing_raised { rval = @memcache.add(key, val, 3600) }
253
+ # assert_equal true, rval, "First #add"
254
+ #
255
+ # assert_nothing_raised { rval = @memcache.add(key, val, 3600) }
256
+ # assert_equal false, rval, "Second #add"
257
+ # end
258
+ #
259
+ # # Get
260
+ # TestDataMatrix.each do |key, val|
261
+ # assert_nothing_raised { rval = @memcache.get(key) }
262
+ # assert_nil_or_equal val, rval
263
+ # end
264
+ #end
265
+
266
+
267
+ # Replace
268
+ def test_60_replace
269
+ printTestHeader "Get/Set: Replace"
270
+ rval = obj = nil
271
+
272
+ @memcache.clear
273
+
274
+ # Without expiration
275
+ TestDataMatrix.each do |key, val|
276
+ @memcache.delete( key )
277
+ assert_nothing_raised { rval = @memcache.replace(key, val) }
278
+ assert_equal false, rval, "First #replace"
279
+
280
+ @memcache.set( key, "value to be replaced" )
281
+ assert_nothing_raised { rval = @memcache.replace(key, val) }
282
+ assert_equal true, rval, "Second #replace"
283
+ end
284
+
285
+ # Get
286
+ TestDataMatrix.each do |key, val|
287
+ assert_nothing_raised { rval = @memcache.get(key) }
288
+ assert_nil_or_equal val, rval
289
+ end
290
+
291
+ @memcache.clear
292
+
293
+ # With expiration
294
+ TestDataMatrix.each do |key, val|
295
+ @memcache.delete( key )
296
+ assert_nothing_raised { rval = @memcache.replace(key, val, 3600) }
297
+ assert_equal false, rval, "First #replace"
298
+
299
+ @memcache.set( key, "value to be replaced" )
300
+ assert_nothing_raised { rval = @memcache.replace(key, val, 3600) }
301
+ assert_equal true, rval, "Second #replace"
302
+ end
303
+
304
+ # Get
305
+ TestDataMatrix.each do |key, val|
306
+ assert_nothing_raised { rval = @memcache.get(key) }
307
+ assert_nil_or_equal val, rval
308
+ end
309
+ end
310
+
311
+
312
+ # Incr, decr
313
+ def test_70_incrdecr
314
+ printTestHeader "Get/Set: Replace"
315
+ rval = obj = nil
316
+
317
+ @memcache.clear
318
+ @memcache.delete( :counter )
319
+
320
+ # Incr without set should return nil
321
+ assert_nothing_raised do rval = @memcache.incr( :counter ) end
322
+ assert_nil rval, "Result of incrementing an unknown key"
323
+
324
+ # ...same with a value
325
+ assert_nothing_raised do rval = @memcache.incr( :counter, 3 ) end
326
+ assert_nil rval, "Result of incrementing an unknown key"
327
+
328
+ # Decr without set should return nil
329
+ assert_nothing_raised do rval = @memcache.decr( :counter ) end
330
+ assert_nil rval, "Result of decrementing an unknown key"
331
+
332
+ # ...same with a value
333
+ assert_nothing_raised do rval = @memcache.decr( :counter, 3 ) end
334
+ assert_nil rval, "Result of decrementing an unknown key"
335
+
336
+ @memcache.set( :counter, 0 )
337
+
338
+ # Incr after set should increment -- no value == 1
339
+ assert_nothing_raised do rval = @memcache.incr( :counter ) end
340
+ assert_equal 1, rval, "Result of incrementing without a value"
341
+
342
+ # ...and with a value
343
+ assert_nothing_raised do rval = @memcache.incr( :counter, 3 ) end
344
+ assert_equal 4, rval, "Result of incrementing with value = 3"
345
+
346
+ # Decr after set should decrement -- no value == 1
347
+ assert_nothing_raised do rval = @memcache.decr( :counter ) end
348
+ assert_equal 3, rval, "Result of decrementing without a value"
349
+
350
+ # ...and with a value
351
+ assert_nothing_raised do rval = @memcache.decr( :counter, 3 ) end
352
+ assert_equal 0, rval, "Result of decrementing with value = 3"
353
+
354
+ # Decr will not go below 0, with a value
355
+ assert_nothing_raised do rval = @memcache.decr( :counter ) end
356
+ assert_equal 0, rval, "Result of decrementing below 0 without a value"
357
+
358
+ # ...and without
359
+ assert_nothing_raised do rval = @memcache.decr( :counter, 3 ) end
360
+ assert_equal 0, rval, "Result of decrementing below 0 with value = 3"
361
+
362
+ end
363
+
364
+ end
365
+