memcache-client 1.5.0 → 1.6.2
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.
- data/History.txt +71 -0
- data/LICENSE.txt +2 -2
- data/README.rdoc +43 -0
- data/Rakefile +20 -13
- data/ext/memcache/binary_search.c +54 -0
- data/ext/memcache/extconf.rb +5 -0
- data/lib/continuum.rb +46 -0
- data/lib/memcache.rb +335 -244
- data/lib/memcache_util.rb +20 -8
- data/test/test_mem_cache.rb +259 -53
- metadata +46 -87
- data.tar.gz.sig +0 -0
- data/Manifest.txt +0 -8
- data/README.txt +0 -54
- metadata.gz.sig +0 -0
data/lib/memcache_util.rb
CHANGED
@@ -3,7 +3,19 @@
|
|
3
3
|
# methods silently ignore MemCache errors.
|
4
4
|
|
5
5
|
module Cache
|
6
|
-
|
6
|
+
|
7
|
+
##
|
8
|
+
# Try to return a logger object that does not rely
|
9
|
+
# on ActiveRecord for logging.
|
10
|
+
def self.logger
|
11
|
+
@logger ||= if defined? Rails.logger # Rails 2.1 +
|
12
|
+
Rails.logger
|
13
|
+
elsif defined? RAILS_DEFAULT_LOGGER # Rails 1.2.2 +
|
14
|
+
RAILS_DEFAULT_LOGGER
|
15
|
+
else
|
16
|
+
ActiveRecord::Base.logger # ... very old Rails.
|
17
|
+
end
|
18
|
+
end
|
7
19
|
##
|
8
20
|
# Returns the object at +key+ from the cache if successful, or nil if either
|
9
21
|
# the object is not in the cache or if there was an error attermpting to
|
@@ -17,14 +29,14 @@ module Cache
|
|
17
29
|
start_time = Time.now
|
18
30
|
value = CACHE.get key
|
19
31
|
elapsed = Time.now - start_time
|
20
|
-
|
32
|
+
logger.debug('MemCache Get (%0.6f) %s' % [elapsed, key])
|
21
33
|
if value.nil? and block_given? then
|
22
34
|
value = yield
|
23
35
|
add key, value, expiry
|
24
36
|
end
|
25
37
|
value
|
26
38
|
rescue MemCache::MemCacheError => err
|
27
|
-
|
39
|
+
logger.debug "MemCache Error: #{err.message}"
|
28
40
|
if block_given? then
|
29
41
|
value = yield
|
30
42
|
put key, value, expiry
|
@@ -40,7 +52,7 @@ module Cache
|
|
40
52
|
start_time = Time.now
|
41
53
|
CACHE.set key, value, expiry
|
42
54
|
elapsed = Time.now - start_time
|
43
|
-
|
55
|
+
logger.debug('MemCache Set (%0.6f) %s' % [elapsed, key])
|
44
56
|
value
|
45
57
|
rescue MemCache::MemCacheError => err
|
46
58
|
ActiveRecord::Base.logger.debug "MemCache Error: #{err.message}"
|
@@ -55,7 +67,7 @@ module Cache
|
|
55
67
|
start_time = Time.now
|
56
68
|
response = CACHE.add key, value, expiry
|
57
69
|
elapsed = Time.now - start_time
|
58
|
-
|
70
|
+
logger.debug('MemCache Add (%0.6f) %s' % [elapsed, key])
|
59
71
|
(response == "STORED\r\n") ? value : nil
|
60
72
|
rescue MemCache::MemCacheError => err
|
61
73
|
ActiveRecord::Base.logger.debug "MemCache Error: #{err.message}"
|
@@ -69,11 +81,11 @@ module Cache
|
|
69
81
|
start_time = Time.now
|
70
82
|
CACHE.delete key, delay
|
71
83
|
elapsed = Time.now - start_time
|
72
|
-
|
84
|
+
logger.debug('MemCache Delete (%0.6f) %s' %
|
73
85
|
[elapsed, key])
|
74
86
|
nil
|
75
87
|
rescue MemCache::MemCacheError => err
|
76
|
-
|
88
|
+
logger.debug "MemCache Error: #{err.message}"
|
77
89
|
nil
|
78
90
|
end
|
79
91
|
|
@@ -82,7 +94,7 @@ module Cache
|
|
82
94
|
|
83
95
|
def self.reset
|
84
96
|
CACHE.reset
|
85
|
-
|
97
|
+
logger.debug 'MemCache Connections Reset'
|
86
98
|
nil
|
87
99
|
end
|
88
100
|
|
data/test/test_mem_cache.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'logger'
|
1
3
|
require 'stringio'
|
2
4
|
require 'test/unit'
|
3
5
|
require 'rubygems'
|
4
|
-
|
6
|
+
begin
|
7
|
+
gem 'flexmock'
|
8
|
+
require 'flexmock/test_unit'
|
9
|
+
rescue LoadError => e
|
10
|
+
puts "Some tests require flexmock, please run `gem install flexmock`"
|
11
|
+
end
|
5
12
|
|
6
13
|
$TESTING = true
|
7
14
|
|
8
|
-
require 'memcache'
|
15
|
+
require File.dirname(__FILE__) + '/../lib/memcache'
|
9
16
|
|
10
17
|
class MemCache
|
11
18
|
|
@@ -36,22 +43,67 @@ class FakeSocket
|
|
36
43
|
|
37
44
|
end
|
38
45
|
|
46
|
+
class Test::Unit::TestCase
|
47
|
+
def requirement(bool, msg)
|
48
|
+
if bool
|
49
|
+
yield
|
50
|
+
else
|
51
|
+
puts msg
|
52
|
+
assert true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def memcached_running?
|
57
|
+
TCPSocket.new('localhost', 11211) rescue false
|
58
|
+
end
|
59
|
+
|
60
|
+
def xprofile(name, &block)
|
61
|
+
a = Time.now
|
62
|
+
block.call
|
63
|
+
Time.now - a
|
64
|
+
end
|
65
|
+
|
66
|
+
def profile(name, &block)
|
67
|
+
require 'ruby-prof'
|
68
|
+
a = Time.now
|
69
|
+
result = RubyProf.profile(&block)
|
70
|
+
time = Time.now - a
|
71
|
+
printer = RubyProf::GraphHtmlPrinter.new(result)
|
72
|
+
File.open("#{name}.html", 'w') do |f|
|
73
|
+
printer.print(f, :min_percent=>1)
|
74
|
+
end
|
75
|
+
time
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
39
80
|
class FakeServer
|
40
81
|
|
41
|
-
attr_reader :host, :port, :socket
|
82
|
+
attr_reader :host, :port, :socket, :weight, :multithread, :status
|
42
83
|
|
43
84
|
def initialize(socket = nil)
|
44
85
|
@closed = false
|
45
86
|
@host = 'example.com'
|
46
87
|
@port = 11211
|
47
88
|
@socket = socket || FakeSocket.new
|
89
|
+
@weight = 1
|
90
|
+
@multithread = false
|
91
|
+
@status = "CONNECTED"
|
48
92
|
end
|
49
93
|
|
50
94
|
def close
|
95
|
+
# begin
|
96
|
+
# raise "Already closed"
|
97
|
+
# rescue => e
|
98
|
+
# puts e.backtrace.join("\n")
|
99
|
+
# end
|
51
100
|
@closed = true
|
101
|
+
@socket = nil
|
102
|
+
@status = "NOT CONNECTED"
|
52
103
|
end
|
53
104
|
|
54
105
|
def alive?
|
106
|
+
# puts "I'm #{@closed ? 'dead' : 'alive'}"
|
55
107
|
!@closed
|
56
108
|
end
|
57
109
|
|
@@ -63,6 +115,126 @@ class TestMemCache < Test::Unit::TestCase
|
|
63
115
|
@cache = MemCache.new 'localhost:1', :namespace => 'my_namespace'
|
64
116
|
end
|
65
117
|
|
118
|
+
def test_performance
|
119
|
+
requirement(memcached_running?, 'A real memcached server must be running for performance testing') do
|
120
|
+
host = Socket.gethostname
|
121
|
+
|
122
|
+
cache = MemCache.new(['localhost:11211',"#{host}:11211"])
|
123
|
+
cache.add('a', 1, 120)
|
124
|
+
with = xprofile 'get' do
|
125
|
+
1000.times do
|
126
|
+
cache.get('a')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
puts ''
|
130
|
+
puts "1000 gets with socket timeout: #{with} sec"
|
131
|
+
|
132
|
+
cache = MemCache.new(['localhost:11211',"#{host}:11211"], :timeout => nil)
|
133
|
+
cache.add('a', 1, 120)
|
134
|
+
without = xprofile 'get' do
|
135
|
+
1000.times do
|
136
|
+
cache.get('a')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
puts "1000 gets without socket timeout: #{without} sec"
|
140
|
+
|
141
|
+
assert without < with
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_consistent_hashing
|
146
|
+
requirement(self.respond_to?(:flexmock), 'Flexmock is required to run this test') do
|
147
|
+
|
148
|
+
flexmock(MemCache::Server).new_instances.should_receive(:alive?).and_return(true)
|
149
|
+
|
150
|
+
# Setup a continuum of two servers
|
151
|
+
@cache.servers = ['mike1', 'mike2', 'mike3']
|
152
|
+
|
153
|
+
keys = []
|
154
|
+
1000.times do |idx|
|
155
|
+
keys << idx.to_s
|
156
|
+
end
|
157
|
+
|
158
|
+
before_continuum = keys.map {|key| @cache.get_server_for_key(key) }
|
159
|
+
|
160
|
+
@cache.servers = ['mike1', 'mike2', 'mike3', 'mike4']
|
161
|
+
|
162
|
+
after_continuum = keys.map {|key| @cache.get_server_for_key(key) }
|
163
|
+
|
164
|
+
same_count = before_continuum.zip(after_continuum).find_all {|a| a[0].host == a[1].host }.size
|
165
|
+
|
166
|
+
# With continuum, we should see about 75% of the keys map to the same server
|
167
|
+
# With modulo, we would see about 25%.
|
168
|
+
assert same_count > 700
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_get_multi_with_server_failure
|
173
|
+
@cache = MemCache.new 'localhost:1', :namespace => 'my_namespace', :logger => nil #Logger.new(STDOUT)
|
174
|
+
s1 = FakeServer.new
|
175
|
+
s2 = FakeServer.new
|
176
|
+
|
177
|
+
# Write two messages to the socket to test failover
|
178
|
+
s1.socket.data.write "VALUE my_namespace:a 0 14\r\n\004\b\"\0170123456789\r\nEND\r\n"
|
179
|
+
s1.socket.data.rewind
|
180
|
+
s2.socket.data.write "bogus response\r\nbogus response\r\n"
|
181
|
+
s2.socket.data.rewind
|
182
|
+
|
183
|
+
@cache.servers = [s1, s2]
|
184
|
+
|
185
|
+
assert s1.alive?
|
186
|
+
assert s2.alive?
|
187
|
+
# a maps to s1, the rest map to s2
|
188
|
+
value = @cache.get_multi(['foo', 'bar', 'a', 'b', 'c'])
|
189
|
+
assert_equal({'a'=>'0123456789'}, value)
|
190
|
+
assert s1.alive?
|
191
|
+
assert !s2.alive?
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_cache_get_with_failover
|
195
|
+
@cache = MemCache.new 'localhost:1', :namespace => 'my_namespace', :logger => nil#Logger.new(STDOUT)
|
196
|
+
s1 = FakeServer.new
|
197
|
+
s2 = FakeServer.new
|
198
|
+
|
199
|
+
# Write two messages to the socket to test failover
|
200
|
+
s1.socket.data.write "VALUE foo 0 14\r\n\004\b\"\0170123456789\r\n"
|
201
|
+
s1.socket.data.rewind
|
202
|
+
s2.socket.data.write "bogus response\r\nbogus response\r\n"
|
203
|
+
s2.socket.data.rewind
|
204
|
+
|
205
|
+
@cache.instance_variable_set(:@failover, true)
|
206
|
+
@cache.servers = [s1, s2]
|
207
|
+
|
208
|
+
assert s1.alive?
|
209
|
+
assert s2.alive?
|
210
|
+
@cache.get('foo')
|
211
|
+
assert s1.alive?
|
212
|
+
assert !s2.alive?
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_cache_get_without_failover
|
216
|
+
s1 = FakeServer.new
|
217
|
+
s2 = FakeServer.new
|
218
|
+
|
219
|
+
s1.socket.data.write "VALUE foo 0 14\r\n\004\b\"\0170123456789\r\n"
|
220
|
+
s1.socket.data.rewind
|
221
|
+
s2.socket.data.write "bogus response\r\nbogus response\r\n"
|
222
|
+
s2.socket.data.rewind
|
223
|
+
|
224
|
+
@cache.instance_variable_set(:@failover, false)
|
225
|
+
@cache.servers = [s1, s2]
|
226
|
+
|
227
|
+
assert s1.alive?
|
228
|
+
assert s2.alive?
|
229
|
+
e = assert_raise MemCache::MemCacheError do
|
230
|
+
@cache.get('foo')
|
231
|
+
end
|
232
|
+
assert s1.alive?
|
233
|
+
assert !s2.alive?
|
234
|
+
|
235
|
+
assert_equal "No servers available", e.message
|
236
|
+
end
|
237
|
+
|
66
238
|
def test_cache_get
|
67
239
|
server = util_setup_fake_server
|
68
240
|
|
@@ -77,31 +249,30 @@ class TestMemCache < Test::Unit::TestCase
|
|
77
249
|
server = util_setup_fake_server
|
78
250
|
server.socket.data.string = ''
|
79
251
|
|
80
|
-
e = assert_raise
|
252
|
+
e = assert_raise IndexError do
|
81
253
|
@cache.cache_get server, 'my_namespace:key'
|
82
254
|
end
|
83
255
|
|
84
|
-
assert_equal "
|
256
|
+
assert_equal "No connection to server (NOT CONNECTED)", e.message
|
85
257
|
end
|
86
258
|
|
87
259
|
def test_cache_get_bad_state
|
88
260
|
server = FakeServer.new
|
89
|
-
|
261
|
+
|
262
|
+
# Write two messages to the socket to test failover
|
263
|
+
server.socket.data.write "bogus response\r\nbogus response\r\n"
|
90
264
|
server.socket.data.rewind
|
91
265
|
|
92
266
|
@cache.servers = []
|
93
267
|
@cache.servers << server
|
94
268
|
|
95
|
-
e = assert_raise
|
269
|
+
e = assert_raise IndexError do
|
96
270
|
@cache.cache_get(server, 'my_namespace:key')
|
97
271
|
end
|
98
272
|
|
99
|
-
|
100
|
-
|
101
|
-
deny server.alive?
|
273
|
+
assert_match /#{Regexp.quote 'No connection to server (NOT CONNECTED)'}/, e.message
|
102
274
|
|
103
|
-
|
104
|
-
server.socket.written.string
|
275
|
+
assert !server.alive?
|
105
276
|
end
|
106
277
|
|
107
278
|
def test_cache_get_miss
|
@@ -136,36 +307,30 @@ class TestMemCache < Test::Unit::TestCase
|
|
136
307
|
server = util_setup_fake_server
|
137
308
|
server.socket.data.string = ''
|
138
309
|
|
139
|
-
e = assert_raise
|
310
|
+
e = assert_raise IndexError do
|
140
311
|
@cache.cache_get_multi server, 'my_namespace:key'
|
141
312
|
end
|
142
313
|
|
143
|
-
assert_equal "
|
314
|
+
assert_equal "No connection to server (NOT CONNECTED)", e.message
|
144
315
|
end
|
145
316
|
|
146
317
|
def test_cache_get_multi_bad_state
|
147
318
|
server = FakeServer.new
|
148
|
-
|
319
|
+
|
320
|
+
# Write two messages to the socket to test failover
|
321
|
+
server.socket.data.write "bogus response\r\nbogus response\r\n"
|
149
322
|
server.socket.data.rewind
|
150
323
|
|
151
324
|
@cache.servers = []
|
152
325
|
@cache.servers << server
|
153
326
|
|
154
|
-
e = assert_raise
|
327
|
+
e = assert_raise IndexError do
|
155
328
|
@cache.cache_get_multi server, 'my_namespace:key'
|
156
329
|
end
|
157
330
|
|
158
|
-
|
159
|
-
|
160
|
-
deny server.alive?
|
161
|
-
|
162
|
-
assert_equal "get my_namespace:key\r\n",
|
163
|
-
server.socket.written.string
|
164
|
-
end
|
331
|
+
assert_match /#{Regexp.quote 'No connection to server (NOT CONNECTED)'}/, e.message
|
165
332
|
|
166
|
-
|
167
|
-
assert_equal 0, ''.crc32_ITU_T
|
168
|
-
assert_equal 1260851911, 'my_namespace:key'.crc32_ITU_T
|
333
|
+
assert !server.alive?
|
169
334
|
end
|
170
335
|
|
171
336
|
def test_initialize
|
@@ -216,7 +381,7 @@ class TestMemCache < Test::Unit::TestCase
|
|
216
381
|
assert_equal 'my_namespace', cache.namespace
|
217
382
|
assert_equal true, cache.readonly?
|
218
383
|
assert_equal false, cache.servers.empty?
|
219
|
-
|
384
|
+
assert !cache.instance_variable_get(:@continuum).empty?
|
220
385
|
end
|
221
386
|
|
222
387
|
def test_initialize_too_many_args
|
@@ -328,7 +493,7 @@ class TestMemCache < Test::Unit::TestCase
|
|
328
493
|
@cache.get 'key'
|
329
494
|
end
|
330
495
|
|
331
|
-
|
496
|
+
assert_match /^No connection to server/, e.message
|
332
497
|
end
|
333
498
|
|
334
499
|
def test_get_no_servers
|
@@ -390,12 +555,15 @@ class TestMemCache < Test::Unit::TestCase
|
|
390
555
|
def test_get_server_for_key_multiple
|
391
556
|
s1 = util_setup_server @cache, 'one.example.com', ''
|
392
557
|
s2 = util_setup_server @cache, 'two.example.com', ''
|
393
|
-
@cache.
|
394
|
-
@cache.instance_variable_set :@buckets, [s1, s2]
|
558
|
+
@cache.servers = [s1, s2]
|
395
559
|
|
396
560
|
server = @cache.get_server_for_key 'keya'
|
397
561
|
assert_equal 'two.example.com', server.host
|
398
562
|
server = @cache.get_server_for_key 'keyb'
|
563
|
+
assert_equal 'two.example.com', server.host
|
564
|
+
server = @cache.get_server_for_key 'keyc'
|
565
|
+
assert_equal 'two.example.com', server.host
|
566
|
+
server = @cache.get_server_for_key 'keyd'
|
399
567
|
assert_equal 'one.example.com', server.host
|
400
568
|
end
|
401
569
|
|
@@ -486,14 +654,6 @@ class TestMemCache < Test::Unit::TestCase
|
|
486
654
|
assert_equal [server], @cache.servers
|
487
655
|
end
|
488
656
|
|
489
|
-
def test_servers_equals_type_error
|
490
|
-
e = assert_raise TypeError do
|
491
|
-
@cache.servers = [Object.new]
|
492
|
-
end
|
493
|
-
|
494
|
-
assert_equal 'cannot convert Object into MemCache::Server', e.message
|
495
|
-
end
|
496
|
-
|
497
657
|
def test_set
|
498
658
|
server = FakeServer.new
|
499
659
|
server.socket.data.write "STORED\r\n"
|
@@ -503,7 +663,9 @@ class TestMemCache < Test::Unit::TestCase
|
|
503
663
|
|
504
664
|
@cache.set 'key', 'value'
|
505
665
|
|
506
|
-
|
666
|
+
dumped = Marshal.dump('value')
|
667
|
+
expected = "set my_namespace:key 0 0 #{dumped.length}\r\n#{dumped}\r\n"
|
668
|
+
# expected = "set my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
|
507
669
|
assert_equal expected, server.socket.written.string
|
508
670
|
end
|
509
671
|
|
@@ -516,7 +678,8 @@ class TestMemCache < Test::Unit::TestCase
|
|
516
678
|
|
517
679
|
@cache.set 'key', 'value', 5
|
518
680
|
|
519
|
-
|
681
|
+
dumped = Marshal.dump('value')
|
682
|
+
expected = "set my_namespace:key 0 5 #{dumped.length}\r\n#{dumped}\r\n"
|
520
683
|
assert_equal expected, server.socket.written.string
|
521
684
|
end
|
522
685
|
|
@@ -545,8 +708,11 @@ class TestMemCache < Test::Unit::TestCase
|
|
545
708
|
|
546
709
|
def test_set_too_big
|
547
710
|
server = FakeServer.new
|
548
|
-
|
711
|
+
|
712
|
+
# Write two messages to the socket to test failover
|
713
|
+
server.socket.data.write "SERVER_ERROR\r\nSERVER_ERROR object too large for cache\r\n"
|
549
714
|
server.socket.data.rewind
|
715
|
+
|
550
716
|
@cache.servers = []
|
551
717
|
@cache.servers << server
|
552
718
|
|
@@ -554,7 +720,7 @@ class TestMemCache < Test::Unit::TestCase
|
|
554
720
|
@cache.set 'key', 'v'
|
555
721
|
end
|
556
722
|
|
557
|
-
|
723
|
+
assert_match /object too large for cache/, e.message
|
558
724
|
end
|
559
725
|
|
560
726
|
def test_add
|
@@ -565,8 +731,10 @@ class TestMemCache < Test::Unit::TestCase
|
|
565
731
|
@cache.servers << server
|
566
732
|
|
567
733
|
@cache.add 'key', 'value'
|
734
|
+
|
735
|
+
dumped = Marshal.dump('value')
|
568
736
|
|
569
|
-
expected = "add my_namespace:key 0 0
|
737
|
+
expected = "add my_namespace:key 0 0 #{dumped.length}\r\n#{dumped}\r\n"
|
570
738
|
assert_equal expected, server.socket.written.string
|
571
739
|
end
|
572
740
|
|
@@ -579,7 +747,8 @@ class TestMemCache < Test::Unit::TestCase
|
|
579
747
|
|
580
748
|
@cache.add 'key', 'value'
|
581
749
|
|
582
|
-
|
750
|
+
dumped = Marshal.dump('value')
|
751
|
+
expected = "add my_namespace:key 0 0 #{dumped.length}\r\n#{dumped}\r\n"
|
583
752
|
assert_equal expected, server.socket.written.string
|
584
753
|
end
|
585
754
|
|
@@ -592,7 +761,8 @@ class TestMemCache < Test::Unit::TestCase
|
|
592
761
|
|
593
762
|
@cache.add 'key', 'value', 5
|
594
763
|
|
595
|
-
|
764
|
+
dumped = Marshal.dump('value')
|
765
|
+
expected = "add my_namespace:key 0 5 #{dumped.length}\r\n#{dumped}\r\n"
|
596
766
|
assert_equal expected, server.socket.written.string
|
597
767
|
end
|
598
768
|
|
@@ -609,6 +779,19 @@ class TestMemCache < Test::Unit::TestCase
|
|
609
779
|
assert_equal expected, server.socket.written.string
|
610
780
|
end
|
611
781
|
|
782
|
+
def test_add_raw_int
|
783
|
+
server = FakeServer.new
|
784
|
+
server.socket.data.write "STORED\r\n"
|
785
|
+
server.socket.data.rewind
|
786
|
+
@cache.servers = []
|
787
|
+
@cache.servers << server
|
788
|
+
|
789
|
+
@cache.add 'key', 12, 0, true
|
790
|
+
|
791
|
+
expected = "add my_namespace:key 0 0 2\r\n12\r\n"
|
792
|
+
assert_equal expected, server.socket.written.string
|
793
|
+
end
|
794
|
+
|
612
795
|
def test_add_readonly
|
613
796
|
cache = MemCache.new :readonly => true
|
614
797
|
|
@@ -655,11 +838,12 @@ class TestMemCache < Test::Unit::TestCase
|
|
655
838
|
|
656
839
|
def test_flush_all_failure
|
657
840
|
socket = FakeSocket.new
|
658
|
-
|
841
|
+
|
842
|
+
# Write two messages to the socket to test failover
|
843
|
+
socket.data.write "ERROR\r\nERROR\r\n"
|
659
844
|
socket.data.rewind
|
845
|
+
|
660
846
|
server = FakeServer.new socket
|
661
|
-
def server.host() "localhost"; end
|
662
|
-
def server.port() 11211; end
|
663
847
|
|
664
848
|
@cache.servers = []
|
665
849
|
@cache.servers << server
|
@@ -668,7 +852,7 @@ class TestMemCache < Test::Unit::TestCase
|
|
668
852
|
@cache.flush_all
|
669
853
|
end
|
670
854
|
|
671
|
-
|
855
|
+
assert_match /flush_all\r\n/, socket.written.string
|
672
856
|
end
|
673
857
|
|
674
858
|
def test_stats
|
@@ -697,24 +881,46 @@ class TestMemCache < Test::Unit::TestCase
|
|
697
881
|
cache = MemCache.new :multithread => true,
|
698
882
|
:namespace => 'my_namespace',
|
699
883
|
:readonly => false
|
700
|
-
|
701
|
-
|
884
|
+
|
885
|
+
server = FakeServer.new
|
886
|
+
server.socket.data.write "STORED\r\n"
|
887
|
+
server.socket.data.rewind
|
888
|
+
|
889
|
+
cache.servers = []
|
890
|
+
cache.servers << server
|
891
|
+
|
892
|
+
assert cache.multithread
|
702
893
|
|
703
894
|
assert_nothing_raised do
|
704
895
|
cache.set "test", "test value"
|
705
896
|
end
|
897
|
+
|
898
|
+
output = server.socket.written.string
|
899
|
+
assert_match /set my_namespace:test/, output
|
900
|
+
assert_match /test value/, output
|
706
901
|
end
|
707
902
|
|
708
903
|
def test_basic_unthreaded_operations_should_work
|
709
904
|
cache = MemCache.new :multithread => false,
|
710
905
|
:namespace => 'my_namespace',
|
711
906
|
:readonly => false
|
712
|
-
|
713
|
-
|
907
|
+
|
908
|
+
server = FakeServer.new
|
909
|
+
server.socket.data.write "STORED\r\n"
|
910
|
+
server.socket.data.rewind
|
911
|
+
|
912
|
+
cache.servers = []
|
913
|
+
cache.servers << server
|
914
|
+
|
915
|
+
assert !cache.multithread
|
714
916
|
|
715
917
|
assert_nothing_raised do
|
716
918
|
cache.set "test", "test value"
|
717
919
|
end
|
920
|
+
|
921
|
+
output = server.socket.written.string
|
922
|
+
assert_match /set my_namespace:test/, output
|
923
|
+
assert_match /test value/, output
|
718
924
|
end
|
719
925
|
|
720
926
|
def util_setup_fake_server
|