memcached 0.11 → 0.12
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +3 -1
- data/COMPATIBILITY +1 -0
- data/README +3 -5
- data/ext/extconf.rb +14 -10
- data/ext/rlibmemcached.i +1 -1
- data/ext/rlibmemcached_wrap.c +1417 -379
- data/lib/memcached/behaviors.rb +1 -1
- data/lib/memcached/exceptions.rb +6 -13
- data/lib/memcached/memcached.rb +149 -115
- data/lib/memcached/rails.rb +34 -13
- data/memcached.gemspec +34 -104
- data/test/unit/memcached_test.rb +249 -163
- data/test/unit/rails_test.rb +1 -1
- metadata +4 -4
- metadata.gz.sig +1 -2
data/lib/memcached/rails.rb
CHANGED
@@ -9,13 +9,19 @@ class Memcached
|
|
9
9
|
DEFAULTS = {}
|
10
10
|
|
11
11
|
# See Memcached#new for details.
|
12
|
-
def initialize(
|
12
|
+
def initialize(*args)
|
13
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
14
|
+
servers = Array(
|
15
|
+
args.any? ? args.unshift : opts.delete(:servers)
|
16
|
+
).flatten.compact
|
17
|
+
|
18
|
+
opts[:prefix_key] ||= opts[:namespace]
|
13
19
|
super(servers, DEFAULTS.merge(opts))
|
14
20
|
end
|
15
21
|
|
16
22
|
# Wraps Memcached#get so that it doesn't raise. This has the side-effect of preventing you from
|
17
23
|
# storing <tt>nil</tt> values.
|
18
|
-
def get(key, raw
|
24
|
+
def get(key, raw=false)
|
19
25
|
super(key, !raw)
|
20
26
|
rescue NotFound
|
21
27
|
end
|
@@ -26,13 +32,33 @@ class Memcached
|
|
26
32
|
end
|
27
33
|
|
28
34
|
# Wraps Memcached#set.
|
29
|
-
def set(key, value, ttl
|
35
|
+
def set(key, value, ttl=nil, raw=false)
|
36
|
+
super(key, value, ttl, !raw)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Wraps Memcached#add so that it doesn't raise.
|
40
|
+
def add(key, value, ttl=nil, raw=false)
|
30
41
|
super(key, value, ttl, !raw)
|
42
|
+
true
|
43
|
+
rescue NotStored
|
44
|
+
false
|
31
45
|
end
|
32
46
|
|
33
47
|
# Wraps Memcached#delete so that it doesn't raise.
|
34
48
|
def delete(key)
|
35
|
-
super
|
49
|
+
super
|
50
|
+
rescue NotFound
|
51
|
+
end
|
52
|
+
|
53
|
+
# Wraps Memcached#incr so that it doesn't raise.
|
54
|
+
def incr(*args)
|
55
|
+
super
|
56
|
+
rescue NotFound
|
57
|
+
end
|
58
|
+
|
59
|
+
# Wraps Memcached#decr so that it doesn't raise.
|
60
|
+
def decr(*args)
|
61
|
+
super
|
36
62
|
rescue NotFound
|
37
63
|
end
|
38
64
|
|
@@ -40,16 +66,11 @@ class Memcached
|
|
40
66
|
def namespace
|
41
67
|
options[:prefix_key]
|
42
68
|
end
|
69
|
+
|
70
|
+
alias :flush_all :flush
|
43
71
|
|
44
|
-
|
45
|
-
|
46
|
-
get key
|
47
|
-
end
|
48
|
-
|
49
|
-
# Alias for Memcached#set.
|
50
|
-
def []=(key, value)
|
51
|
-
set key, value
|
52
|
-
end
|
72
|
+
alias :"[]" :get
|
73
|
+
alias :"[]=" :set
|
53
74
|
|
54
75
|
end
|
55
76
|
end
|
data/memcached.gemspec
CHANGED
@@ -1,108 +1,38 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
1
2
|
|
2
|
-
|
3
|
-
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{memcached}
|
5
|
+
s.version = "0.12"
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
- - ">="
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: "0"
|
26
|
-
version:
|
27
|
-
description: An interface to the libmemcached C client.
|
28
|
-
email: ""
|
29
|
-
executables: []
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Evan Weaver"]
|
9
|
+
s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
|
10
|
+
s.date = %q{2008-12-02}
|
11
|
+
s.description = %q{An interface to the libmemcached C client.}
|
12
|
+
s.email = %q{}
|
13
|
+
s.extensions = ["ext/extconf.rb"]
|
14
|
+
s.extra_rdoc_files = ["BENCHMARKS", "CHANGELOG", "COMPATIBILITY", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "lib/memcached.rb", "LICENSE", "README", "TODO"]
|
15
|
+
s.files = ["BENCHMARKS", "CHANGELOG", "COMPATIBILITY", "ext/extconf.rb", "ext/rlibmemcached.i", "ext/rlibmemcached_wrap.c", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/integer.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "lib/memcached.rb", "LICENSE", "Manifest", "Rakefile", "README", "test/profile/benchmark.rb", "test/profile/profile.rb", "test/profile/valgrind.rb", "test/setup.rb", "test/teardown.rb", "test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb", "TODO", "memcached.gemspec"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/memcached/}
|
18
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Memcached", "--main", "README"]
|
19
|
+
s.require_paths = ["lib", "ext"]
|
20
|
+
s.rubyforge_project = %q{fauna}
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.signing_key = %q{/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-private_key.pem}
|
23
|
+
s.summary = %q{An interface to the libmemcached C client.}
|
24
|
+
s.test_files = ["test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb"]
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
- BENCHMARKS
|
35
|
-
- CHANGELOG
|
36
|
-
- COMPATIBILITY
|
37
|
-
- lib/memcached/behaviors.rb
|
38
|
-
- lib/memcached/exceptions.rb
|
39
|
-
- lib/memcached/memcached.rb
|
40
|
-
- lib/memcached/rails.rb
|
41
|
-
- lib/memcached.rb
|
42
|
-
- LICENSE
|
43
|
-
- README
|
44
|
-
- TODO
|
45
|
-
files:
|
46
|
-
- BENCHMARKS
|
47
|
-
- CHANGELOG
|
48
|
-
- COMPATIBILITY
|
49
|
-
- ext/extconf.rb
|
50
|
-
- ext/rlibmemcached.i
|
51
|
-
- ext/rlibmemcached_wrap.c
|
52
|
-
- lib/memcached/behaviors.rb
|
53
|
-
- lib/memcached/exceptions.rb
|
54
|
-
- lib/memcached/integer.rb
|
55
|
-
- lib/memcached/memcached.rb
|
56
|
-
- lib/memcached/rails.rb
|
57
|
-
- lib/memcached.rb
|
58
|
-
- LICENSE
|
59
|
-
- Manifest
|
60
|
-
- Rakefile
|
61
|
-
- README
|
62
|
-
- test/profile/benchmark.rb
|
63
|
-
- test/profile/profile.rb
|
64
|
-
- test/profile/valgrind.rb
|
65
|
-
- test/setup.rb
|
66
|
-
- test/teardown.rb
|
67
|
-
- test/test_helper.rb
|
68
|
-
- test/unit/binding_test.rb
|
69
|
-
- test/unit/memcached_test.rb
|
70
|
-
- test/unit/rails_test.rb
|
71
|
-
- TODO
|
72
|
-
- memcached.gemspec
|
73
|
-
has_rdoc: true
|
74
|
-
homepage: http://blog.evanweaver.com/files/doc/fauna/memcached/
|
75
|
-
post_install_message:
|
76
|
-
rdoc_options:
|
77
|
-
- --line-numbers
|
78
|
-
- --inline-source
|
79
|
-
- --title
|
80
|
-
- Memcached
|
81
|
-
- --main
|
82
|
-
- README
|
83
|
-
require_paths:
|
84
|
-
- lib
|
85
|
-
- ext
|
86
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - ">="
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: "0"
|
91
|
-
version:
|
92
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: "1.2"
|
97
|
-
version:
|
98
|
-
requirements: []
|
26
|
+
if s.respond_to? :specification_version then
|
27
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
28
|
+
s.specification_version = 2
|
99
29
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
30
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
31
|
+
s.add_development_dependency(%q<echoe>, [">= 0"])
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
34
|
+
end
|
35
|
+
else
|
36
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
37
|
+
end
|
38
|
+
end
|
data/test/unit/memcached_test.rb
CHANGED
@@ -1,25 +1,27 @@
|
|
1
1
|
|
2
2
|
require "#{File.dirname(__FILE__)}/../test_helper"
|
3
|
+
require 'socket'
|
4
|
+
require 'benchmark'
|
3
5
|
|
4
6
|
class MemcachedTest < Test::Unit::TestCase
|
5
7
|
|
6
8
|
def setup
|
7
9
|
@servers = ['localhost:43042', 'localhost:43043']
|
8
10
|
|
9
|
-
# Maximum allowed prefix key size
|
10
|
-
@prefix_key = 'prefix_key_'
|
11
|
-
|
12
|
-
@options = {
|
13
|
-
:prefix_key => @prefix_key,
|
11
|
+
# Maximum allowed prefix key size for :hash_with_prefix_key_key => false
|
12
|
+
@prefix_key = 'prefix_key_'
|
13
|
+
|
14
|
+
@options = {
|
15
|
+
:prefix_key => @prefix_key,
|
14
16
|
:hash => :default,
|
15
17
|
:distribution => :modula
|
16
18
|
}
|
17
19
|
@cache = Memcached.new(@servers, @options)
|
18
|
-
|
20
|
+
|
19
21
|
@nb_options = {
|
20
|
-
:prefix_key => @prefix_key,
|
21
|
-
:no_block => true,
|
22
|
-
:buffer_requests => true,
|
22
|
+
:prefix_key => @prefix_key,
|
23
|
+
:no_block => true,
|
24
|
+
:buffer_requests => true,
|
23
25
|
:hash => :default
|
24
26
|
}
|
25
27
|
@nb_cache = Memcached.new(@servers, @nb_options)
|
@@ -27,7 +29,7 @@ class MemcachedTest < Test::Unit::TestCase
|
|
27
29
|
@value = OpenStruct.new(:a => 1, :b => 2, :c => GenericClass)
|
28
30
|
@marshalled_value = Marshal.dump(@value)
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
# Initialize
|
32
34
|
|
33
35
|
def test_initialize
|
@@ -38,32 +40,48 @@ class MemcachedTest < Test::Unit::TestCase
|
|
38
40
|
assert_equal 'localhost', cache.send(:server_structs).last.hostname
|
39
41
|
assert_equal 43043, cache.send(:server_structs).last.port
|
40
42
|
end
|
41
|
-
|
43
|
+
|
42
44
|
def test_initialize_with_ip_addresses
|
43
|
-
cache = Memcached.new ['127.0.0.1:43042', '127.0.0.1:43043']
|
45
|
+
cache = Memcached.new ['127.0.0.1:43042', '127.0.0.1:43043']
|
44
46
|
assert_equal '127.0.0.1', cache.send(:server_structs).first.hostname
|
45
47
|
assert_equal '127.0.0.1', cache.send(:server_structs).last.hostname
|
46
48
|
end
|
47
|
-
|
49
|
+
|
48
50
|
def test_initialize_without_port
|
49
|
-
cache = Memcached.new ['localhost']
|
51
|
+
cache = Memcached.new ['localhost']
|
50
52
|
assert_equal 'localhost', cache.send(:server_structs).first.hostname
|
51
53
|
assert_equal 11211, cache.send(:server_structs).first.port
|
52
54
|
end
|
53
55
|
|
56
|
+
def test_initialize_with_ports_and_weights
|
57
|
+
cache = Memcached.new ['localhost:43042:2', 'localhost:43043:10']
|
58
|
+
assert_equal 2, cache.send(:server_structs).first.weight
|
59
|
+
assert_equal 43043, cache.send(:server_structs).last.port
|
60
|
+
assert_equal 10, cache.send(:server_structs).last.weight
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_initialize_with_hostname_only
|
64
|
+
addresses = (1..8).map { |i| "app-cache-%02d" % i }
|
65
|
+
cache = Memcached.new(addresses)
|
66
|
+
addresses.each_with_index do |address, index|
|
67
|
+
assert_equal address, cache.send(:server_structs)[index].hostname
|
68
|
+
assert_equal 11211, cache.send(:server_structs)[index].port
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
54
72
|
def test_options_are_set
|
55
73
|
Memcached::DEFAULTS.merge(@nb_options).each do |key, expected|
|
56
74
|
value = @nb_cache.options[key]
|
57
75
|
assert(expected == value, "#{key} should be #{expected} but was #{value}")
|
58
76
|
end
|
59
77
|
end
|
60
|
-
|
78
|
+
|
61
79
|
def test_options_are_frozen
|
62
80
|
assert_raise(TypeError) do
|
63
81
|
@cache.options[:no_block] = true
|
64
82
|
end
|
65
83
|
end
|
66
|
-
|
84
|
+
|
67
85
|
def test_behaviors_are_set
|
68
86
|
Memcached::BEHAVIORS.keys.each do |key, value|
|
69
87
|
assert_not_nil @cache.send(:get_behavior, key)
|
@@ -75,37 +93,34 @@ class MemcachedTest < Test::Unit::TestCase
|
|
75
93
|
assert_raise(ArgumentError) { Memcached.new "localhost:memcached" }
|
76
94
|
assert_raise(ArgumentError) { Memcached.new "local host:43043:1" }
|
77
95
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
cache.set(key, @value)
|
87
|
-
assert_equal @value, cache.get(key)
|
88
|
-
end
|
96
|
+
|
97
|
+
def test_initialize_with_resolvable_hosts
|
98
|
+
host = `hostname`.chomp
|
99
|
+
cache = Memcached.new ["#{host}:43042"]
|
100
|
+
assert_equal host, cache.send(:server_structs).first.hostname
|
101
|
+
|
102
|
+
cache.set(key, @value)
|
103
|
+
assert_equal @value, cache.get(key)
|
89
104
|
end
|
90
|
-
|
105
|
+
|
91
106
|
def test_initialize_with_invalid_options
|
92
|
-
assert_raise(ArgumentError) do
|
107
|
+
assert_raise(ArgumentError) do
|
93
108
|
Memcached.new @servers, :sort_hosts => true, :distribution => :consistent
|
94
109
|
end
|
95
110
|
end
|
96
111
|
|
97
112
|
def test_initialize_with_invalid_prefix_key
|
98
|
-
assert_raise(ArgumentError) do
|
99
|
-
Memcached.new @servers, :prefix_key => "
|
113
|
+
assert_raise(ArgumentError) do
|
114
|
+
Memcached.new @servers, :prefix_key => "x" * 128
|
100
115
|
end
|
101
116
|
end
|
102
|
-
|
117
|
+
|
103
118
|
def test_initialize_without_prefix_key
|
104
119
|
cache = Memcached.new @servers
|
105
120
|
assert_equal nil, cache.options[:prefix_key]
|
106
121
|
assert_equal 2, cache.send(:server_structs).size
|
107
122
|
end
|
108
|
-
|
123
|
+
|
109
124
|
def test_initialize_negative_behavior
|
110
125
|
cache = Memcached.new @servers,
|
111
126
|
:buffer_requests => false
|
@@ -113,10 +128,10 @@ class MemcachedTest < Test::Unit::TestCase
|
|
113
128
|
cache.set key, @value
|
114
129
|
end
|
115
130
|
end
|
116
|
-
|
117
|
-
def
|
131
|
+
|
132
|
+
def test_initialize_without_backtraces
|
118
133
|
cache = Memcached.new @servers,
|
119
|
-
:
|
134
|
+
:show_backtraces => false
|
120
135
|
cache.delete key rescue
|
121
136
|
begin
|
122
137
|
cache.get key
|
@@ -125,24 +140,24 @@ class MemcachedTest < Test::Unit::TestCase
|
|
125
140
|
end
|
126
141
|
end
|
127
142
|
|
128
|
-
def
|
143
|
+
def test_initialize_with_backtraces
|
129
144
|
cache = Memcached.new @servers,
|
130
|
-
:
|
145
|
+
:show_backtraces => true
|
131
146
|
cache.delete key rescue
|
132
147
|
begin
|
133
148
|
cache.get key
|
134
149
|
rescue Memcached::NotFound => e
|
135
150
|
assert !e.backtrace.empty?
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
139
154
|
def test_initialize_sort_hosts
|
140
155
|
# Original
|
141
156
|
cache = Memcached.new(@servers.sort,
|
142
157
|
:sort_hosts => false,
|
143
158
|
:distribution => :modula
|
144
159
|
)
|
145
|
-
assert_equal @servers.sort,
|
160
|
+
assert_equal @servers.sort,
|
146
161
|
cache.servers
|
147
162
|
|
148
163
|
# Original with sort_hosts
|
@@ -150,26 +165,26 @@ class MemcachedTest < Test::Unit::TestCase
|
|
150
165
|
:sort_hosts => true,
|
151
166
|
:distribution => :modula
|
152
167
|
)
|
153
|
-
assert_equal @servers.sort,
|
168
|
+
assert_equal @servers.sort,
|
154
169
|
cache.servers
|
155
|
-
|
156
|
-
# Reversed
|
170
|
+
|
171
|
+
# Reversed
|
157
172
|
cache = Memcached.new(@servers.sort.reverse,
|
158
173
|
:sort_hosts => false,
|
159
174
|
:distribution => :modula
|
160
175
|
)
|
161
|
-
assert_equal @servers.sort.reverse,
|
176
|
+
assert_equal @servers.sort.reverse,
|
162
177
|
cache.servers
|
163
|
-
|
178
|
+
|
164
179
|
# Reversed with sort_hosts
|
165
180
|
cache = Memcached.new(@servers.sort.reverse,
|
166
181
|
:sort_hosts => true,
|
167
182
|
:distribution => :modula
|
168
183
|
)
|
169
|
-
assert_equal @servers.sort,
|
184
|
+
assert_equal @servers.sort,
|
170
185
|
cache.servers
|
171
186
|
end
|
172
|
-
|
187
|
+
|
173
188
|
def test_initialize_single_server
|
174
189
|
cache = Memcached.new 'localhost:43042'
|
175
190
|
assert_equal nil, cache.options[:prefix_key]
|
@@ -179,9 +194,9 @@ class MemcachedTest < Test::Unit::TestCase
|
|
179
194
|
def test_initialize_strange_argument
|
180
195
|
assert_raise(ArgumentError) { Memcached.new 1 }
|
181
196
|
end
|
182
|
-
|
197
|
+
|
183
198
|
# Get
|
184
|
-
|
199
|
+
|
185
200
|
def test_get
|
186
201
|
@cache.set key, @value
|
187
202
|
result = @cache.get key
|
@@ -193,33 +208,60 @@ class MemcachedTest < Test::Unit::TestCase
|
|
193
208
|
result = @cache.get key
|
194
209
|
assert_equal nil, result
|
195
210
|
end
|
196
|
-
|
211
|
+
|
197
212
|
def test_get_missing
|
198
213
|
@cache.delete key rescue nil
|
199
214
|
assert_raise(Memcached::NotFound) do
|
200
215
|
result = @cache.get key
|
201
216
|
end
|
202
217
|
end
|
203
|
-
|
218
|
+
|
219
|
+
def test_get_with_server_timeout
|
220
|
+
socket = stub_server 43047
|
221
|
+
cache = Memcached.new(
|
222
|
+
"localhost:43047:1",
|
223
|
+
:timeout => 0.5
|
224
|
+
)
|
225
|
+
assert 0.49 < (Benchmark.measure do
|
226
|
+
assert_raise(Memcached::UnknownReadFailure) do
|
227
|
+
result = cache.get key
|
228
|
+
end
|
229
|
+
end).real
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_get_with_no_block_server_timeout
|
233
|
+
socket = stub_server 43048
|
234
|
+
cache = Memcached.new(
|
235
|
+
"localhost:43048:1",
|
236
|
+
:no_block => true,
|
237
|
+
:timeout => 0.25
|
238
|
+
)
|
239
|
+
assert 0.24 < (Benchmark.measure do
|
240
|
+
assert_raise(Memcached::UnknownReadFailure) do
|
241
|
+
result = cache.get key
|
242
|
+
end
|
243
|
+
end).real
|
244
|
+
end
|
245
|
+
|
204
246
|
def test_get_with_prefix_key
|
205
247
|
# Prefix_key
|
206
248
|
cache = Memcached.new(
|
207
249
|
# We can only use one server because the key is hashed separately from the prefix key
|
208
250
|
@servers.first,
|
209
|
-
:prefix_key => @prefix_key,
|
251
|
+
:prefix_key => @prefix_key,
|
210
252
|
:hash => :default,
|
211
253
|
:distribution => :modula
|
212
254
|
)
|
213
255
|
cache.set key, @value
|
214
256
|
assert_equal @value, cache.get(key)
|
215
|
-
|
257
|
+
|
216
258
|
# No prefix_key specified
|
217
259
|
cache = Memcached.new(
|
218
260
|
@servers.first,
|
219
261
|
:hash => :default,
|
220
262
|
:distribution => :modula
|
221
263
|
)
|
222
|
-
assert_nothing_raised do
|
264
|
+
assert_nothing_raised do
|
223
265
|
assert_equal @value, cache.get("#{@prefix_key}#{key}")
|
224
266
|
end
|
225
267
|
end
|
@@ -229,11 +271,11 @@ class MemcachedTest < Test::Unit::TestCase
|
|
229
271
|
@cache.set key, value
|
230
272
|
result = @cache.get key, false
|
231
273
|
non_wrapped_result = Rlibmemcached.memcached_get(
|
232
|
-
@cache.instance_variable_get("@struct"),
|
274
|
+
@cache.instance_variable_get("@struct"),
|
233
275
|
key
|
234
276
|
).first
|
235
|
-
assert result.size > non_wrapped_result.size
|
236
|
-
end
|
277
|
+
assert result.size > non_wrapped_result.size
|
278
|
+
end
|
237
279
|
|
238
280
|
def test_get_multi
|
239
281
|
@cache.set "#{key}_1", 1
|
@@ -241,33 +283,33 @@ class MemcachedTest < Test::Unit::TestCase
|
|
241
283
|
assert_equal({"#{key}_1" => 1, "#{key}_2" => 2},
|
242
284
|
@cache.get(["#{key}_1", "#{key}_2"]))
|
243
285
|
end
|
244
|
-
|
286
|
+
|
245
287
|
def test_get_multi_missing
|
246
288
|
@cache.set "#{key}_1", 1
|
247
289
|
@cache.delete "#{key}_2" rescue nil
|
248
290
|
@cache.set "#{key}_3", 3
|
249
|
-
@cache.delete "#{key}_4" rescue nil
|
291
|
+
@cache.delete "#{key}_4" rescue nil
|
250
292
|
assert_equal(
|
251
|
-
{"test_get_multi_missing_3"=>3, "test_get_multi_missing_1"=>1},
|
293
|
+
{"test_get_multi_missing_3"=>3, "test_get_multi_missing_1"=>1},
|
252
294
|
@cache.get(["#{key}_1", "#{key}_2", "#{key}_3", "#{key}_4"])
|
253
295
|
)
|
254
296
|
end
|
255
|
-
|
297
|
+
|
256
298
|
def test_get_multi_completely_missing
|
257
299
|
@cache.delete "#{key}_1" rescue nil
|
258
|
-
@cache.delete "#{key}_2" rescue nil
|
300
|
+
@cache.delete "#{key}_2" rescue nil
|
259
301
|
assert_equal(
|
260
302
|
{},
|
261
303
|
@cache.get(["#{key}_1", "#{key}_2"])
|
262
304
|
)
|
263
|
-
end
|
305
|
+
end
|
264
306
|
|
265
307
|
def test_set_and_get_unmarshalled
|
266
308
|
@cache.set key, @value
|
267
309
|
result = @cache.get key, false
|
268
310
|
assert_equal @marshalled_value, result
|
269
311
|
end
|
270
|
-
|
312
|
+
|
271
313
|
def test_get_multi_unmarshalled
|
272
314
|
@cache.set "#{key}_1", 1, 0, false
|
273
315
|
@cache.set "#{key}_2", 2, 0, false
|
@@ -276,7 +318,7 @@ class MemcachedTest < Test::Unit::TestCase
|
|
276
318
|
@cache.get(["#{key}_1", "#{key}_2"], false)
|
277
319
|
)
|
278
320
|
end
|
279
|
-
|
321
|
+
|
280
322
|
def test_get_multi_mixed_marshalling
|
281
323
|
@cache.set "#{key}_1", 1
|
282
324
|
@cache.set "#{key}_2", 2, 0, false
|
@@ -286,7 +328,22 @@ class MemcachedTest < Test::Unit::TestCase
|
|
286
328
|
assert_raise(ArgumentError) do
|
287
329
|
@cache.get(["#{key}_1", "#{key}_2"])
|
288
330
|
end
|
289
|
-
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_get_with_random_distribution
|
334
|
+
cache = Memcached.new(@servers, :distribution => :random)
|
335
|
+
cache.set key, @value
|
336
|
+
|
337
|
+
hits = (0..10).to_a.map do
|
338
|
+
begin
|
339
|
+
cache.get(key)
|
340
|
+
rescue Memcached::NotFound
|
341
|
+
end
|
342
|
+
end.compact.size
|
343
|
+
|
344
|
+
assert 0 < hits
|
345
|
+
assert 10 > hits
|
346
|
+
end
|
290
347
|
|
291
348
|
# Set
|
292
349
|
|
@@ -295,7 +352,7 @@ class MemcachedTest < Test::Unit::TestCase
|
|
295
352
|
@cache.set(key, @value)
|
296
353
|
end
|
297
354
|
end
|
298
|
-
|
355
|
+
|
299
356
|
def test_set_expiry
|
300
357
|
@cache.set key, @value, 1
|
301
358
|
assert_nothing_raised do
|
@@ -306,16 +363,31 @@ class MemcachedTest < Test::Unit::TestCase
|
|
306
363
|
@cache.get key
|
307
364
|
end
|
308
365
|
end
|
309
|
-
|
366
|
+
|
367
|
+
def test_set_with_default_ttl
|
368
|
+
cache = Memcached.new(
|
369
|
+
@servers,
|
370
|
+
:default_ttl => 1
|
371
|
+
)
|
372
|
+
cache.set key, @value
|
373
|
+
assert_nothing_raised do
|
374
|
+
cache.get key
|
375
|
+
end
|
376
|
+
sleep(2)
|
377
|
+
assert_raise(Memcached::NotFound) do
|
378
|
+
cache.get key
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
310
382
|
# Delete
|
311
|
-
|
383
|
+
|
312
384
|
def test_delete
|
313
385
|
@cache.set key, @value
|
314
386
|
@cache.delete key
|
315
387
|
assert_raise(Memcached::NotFound) do
|
316
388
|
@cache.get key
|
317
389
|
end
|
318
|
-
end
|
390
|
+
end
|
319
391
|
|
320
392
|
def test_missing_delete
|
321
393
|
@cache.delete key rescue nil
|
@@ -323,19 +395,19 @@ class MemcachedTest < Test::Unit::TestCase
|
|
323
395
|
@cache.delete key
|
324
396
|
end
|
325
397
|
end
|
326
|
-
|
398
|
+
|
327
399
|
# Flush
|
328
|
-
|
400
|
+
|
329
401
|
def test_flush
|
330
402
|
@cache.set key, @value
|
331
|
-
assert_equal @value,
|
403
|
+
assert_equal @value,
|
332
404
|
@cache.get(key)
|
333
405
|
@cache.flush
|
334
|
-
assert_raise(Memcached::NotFound) do
|
406
|
+
assert_raise(Memcached::NotFound) do
|
335
407
|
@cache.get key
|
336
408
|
end
|
337
409
|
end
|
338
|
-
|
410
|
+
|
339
411
|
# Add
|
340
412
|
|
341
413
|
def test_add
|
@@ -360,7 +432,7 @@ class MemcachedTest < Test::Unit::TestCase
|
|
360
432
|
sleep(1)
|
361
433
|
assert_raise(Memcached::NotFound) do
|
362
434
|
@cache.get key
|
363
|
-
end
|
435
|
+
end
|
364
436
|
end
|
365
437
|
|
366
438
|
def test_unmarshalled_add
|
@@ -369,14 +441,14 @@ class MemcachedTest < Test::Unit::TestCase
|
|
369
441
|
assert_equal @marshalled_value, @cache.get(key, false)
|
370
442
|
assert_equal @value, @cache.get(key)
|
371
443
|
end
|
372
|
-
|
444
|
+
|
373
445
|
# Increment and decrement
|
374
446
|
|
375
447
|
def test_increment
|
376
448
|
@cache.set key, 10, 0, false
|
377
449
|
assert_equal 11, @cache.increment(key)
|
378
450
|
end
|
379
|
-
|
451
|
+
|
380
452
|
def test_increment_offset
|
381
453
|
@cache.set key, 10, 0, false
|
382
454
|
assert_equal 15, @cache.increment(key, 5)
|
@@ -393,11 +465,11 @@ class MemcachedTest < Test::Unit::TestCase
|
|
393
465
|
@cache.set key, 10, 0, false
|
394
466
|
assert_equal 9, @cache.decrement(key)
|
395
467
|
end
|
396
|
-
|
468
|
+
|
397
469
|
def test_decrement_offset
|
398
470
|
@cache.set key, 10, 0, false
|
399
471
|
assert_equal 5, @cache.decrement(key, 5)
|
400
|
-
end
|
472
|
+
end
|
401
473
|
|
402
474
|
def test_missing_decrement
|
403
475
|
@cache.delete key rescue nil
|
@@ -405,9 +477,9 @@ class MemcachedTest < Test::Unit::TestCase
|
|
405
477
|
@cache.decrement key
|
406
478
|
end
|
407
479
|
end
|
408
|
-
|
480
|
+
|
409
481
|
# Replace
|
410
|
-
|
482
|
+
|
411
483
|
def test_replace
|
412
484
|
@cache.set key, nil
|
413
485
|
assert_nothing_raised do
|
@@ -421,11 +493,11 @@ class MemcachedTest < Test::Unit::TestCase
|
|
421
493
|
assert_raise(Memcached::NotStored) do
|
422
494
|
@cache.replace key, @value
|
423
495
|
end
|
424
|
-
assert_raise(Memcached::NotFound) do
|
425
|
-
assert_equal @value, @cache.get(key)
|
496
|
+
assert_raise(Memcached::NotFound) do
|
497
|
+
assert_equal @value, @cache.get(key)
|
426
498
|
end
|
427
499
|
end
|
428
|
-
|
500
|
+
|
429
501
|
# Append and prepend
|
430
502
|
|
431
503
|
def test_append
|
@@ -441,8 +513,8 @@ class MemcachedTest < Test::Unit::TestCase
|
|
441
513
|
assert_raise(Memcached::NotStored) do
|
442
514
|
@cache.append key, "end"
|
443
515
|
end
|
444
|
-
assert_raise(Memcached::NotFound) do
|
445
|
-
assert_equal @value, @cache.get(key)
|
516
|
+
assert_raise(Memcached::NotFound) do
|
517
|
+
assert_equal @value, @cache.get(key)
|
446
518
|
end
|
447
519
|
end
|
448
520
|
|
@@ -459,17 +531,17 @@ class MemcachedTest < Test::Unit::TestCase
|
|
459
531
|
assert_raise(Memcached::NotStored) do
|
460
532
|
@cache.prepend key, "end"
|
461
533
|
end
|
462
|
-
assert_raise(Memcached::NotFound) do
|
463
|
-
assert_equal @value, @cache.get(key)
|
534
|
+
assert_raise(Memcached::NotFound) do
|
535
|
+
assert_equal @value, @cache.get(key)
|
464
536
|
end
|
465
537
|
end
|
466
538
|
|
467
539
|
def test_cas
|
468
540
|
cache = Memcached.new(
|
469
|
-
@servers,
|
470
|
-
:prefix_key => @prefix_key,
|
541
|
+
@servers,
|
542
|
+
:prefix_key => @prefix_key,
|
471
543
|
:support_cas => true
|
472
|
-
)
|
544
|
+
)
|
473
545
|
value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
|
474
546
|
|
475
547
|
# Existing set
|
@@ -479,20 +551,20 @@ class MemcachedTest < Test::Unit::TestCase
|
|
479
551
|
value2
|
480
552
|
end
|
481
553
|
assert_equal value2, cache.get(key)
|
482
|
-
|
554
|
+
|
483
555
|
# Existing test without marshalling
|
484
556
|
cache.set(key, "foo", 0, false)
|
485
557
|
cache.cas(key, 0, false) do |current|
|
486
558
|
"#{current}bar"
|
487
559
|
end
|
488
560
|
assert_equal "foobar", cache.get(key, false)
|
489
|
-
|
561
|
+
|
490
562
|
# Missing set
|
491
563
|
cache.delete key
|
492
564
|
assert_raises(Memcached::NotFound) do
|
493
565
|
cache.cas(key) {}
|
494
566
|
end
|
495
|
-
|
567
|
+
|
496
568
|
# Conflicting set
|
497
569
|
cache.set key, @value
|
498
570
|
assert_raises(Memcached::ConnectionDataExists) do
|
@@ -502,9 +574,9 @@ class MemcachedTest < Test::Unit::TestCase
|
|
502
574
|
end
|
503
575
|
end
|
504
576
|
end
|
505
|
-
|
577
|
+
|
506
578
|
# Error states
|
507
|
-
|
579
|
+
|
508
580
|
def test_key_with_spaces
|
509
581
|
key = "i have a space"
|
510
582
|
assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
|
@@ -514,7 +586,7 @@ class MemcachedTest < Test::Unit::TestCase
|
|
514
586
|
@cache.get(key)
|
515
587
|
end
|
516
588
|
end
|
517
|
-
|
589
|
+
|
518
590
|
def test_key_with_null
|
519
591
|
key = "with\000null"
|
520
592
|
assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
|
@@ -527,8 +599,8 @@ class MemcachedTest < Test::Unit::TestCase
|
|
527
599
|
assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
|
528
600
|
response = @cache.get([key])
|
529
601
|
end
|
530
|
-
end
|
531
|
-
|
602
|
+
end
|
603
|
+
|
532
604
|
def test_key_with_invalid_control_characters
|
533
605
|
key = "ch\303\242teau"
|
534
606
|
assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
|
@@ -542,7 +614,7 @@ class MemcachedTest < Test::Unit::TestCase
|
|
542
614
|
response = @cache.get([key])
|
543
615
|
end
|
544
616
|
end
|
545
|
-
|
617
|
+
|
546
618
|
def test_key_too_long
|
547
619
|
key = "x"*251
|
548
620
|
assert_raises(Memcached::ClientError) do
|
@@ -551,18 +623,18 @@ class MemcachedTest < Test::Unit::TestCase
|
|
551
623
|
assert_raises(Memcached::ClientError) do
|
552
624
|
@cache.get(key)
|
553
625
|
end
|
554
|
-
|
626
|
+
|
555
627
|
assert_raises(Memcached::ClientError) do
|
556
628
|
@cache.get([key])
|
557
629
|
end
|
558
|
-
end
|
630
|
+
end
|
559
631
|
|
560
632
|
def test_set_object_too_large
|
561
633
|
assert_raise(Memcached::ServerError) do
|
562
634
|
@cache.set key, "I'm big" * 1000000
|
563
635
|
end
|
564
636
|
end
|
565
|
-
|
637
|
+
|
566
638
|
# Stats
|
567
639
|
|
568
640
|
def test_stats
|
@@ -571,25 +643,25 @@ class MemcachedTest < Test::Unit::TestCase
|
|
571
643
|
assert_instance_of Fixnum, stats[:pid].first
|
572
644
|
assert_instance_of String, stats[:version].first
|
573
645
|
end
|
574
|
-
|
646
|
+
|
575
647
|
# Clone
|
576
|
-
|
648
|
+
|
577
649
|
def test_clone
|
578
650
|
cache = @cache.clone
|
579
651
|
assert_equal cache.servers, @cache.servers
|
580
652
|
assert_not_equal cache, @cache
|
581
|
-
|
653
|
+
|
582
654
|
# Definitely check that the structs are unlinked
|
583
655
|
assert_not_equal @cache.instance_variable_get('@struct').object_id,
|
584
656
|
cache.instance_variable_get('@struct').object_id
|
585
|
-
|
657
|
+
|
586
658
|
assert_nothing_raised do
|
587
659
|
@cache.set key, @value
|
588
660
|
end
|
589
661
|
end
|
590
|
-
|
662
|
+
|
591
663
|
# Non-blocking IO
|
592
|
-
|
664
|
+
|
593
665
|
def test_buffered_requests_return_value
|
594
666
|
cache = Memcached.new @servers,
|
595
667
|
:buffer_requests => true
|
@@ -597,13 +669,13 @@ class MemcachedTest < Test::Unit::TestCase
|
|
597
669
|
cache.set key, @value
|
598
670
|
end
|
599
671
|
ret = Rlibmemcached.memcached_set(
|
600
|
-
cache.instance_variable_get("@struct"),
|
601
|
-
key,
|
602
|
-
@marshalled_value,
|
603
|
-
0,
|
672
|
+
cache.instance_variable_get("@struct"),
|
673
|
+
key,
|
674
|
+
@marshalled_value,
|
675
|
+
0,
|
604
676
|
Memcached::FLAGS
|
605
677
|
)
|
606
|
-
assert_equal
|
678
|
+
assert_equal Rlibmemcached::MEMCACHED_BUFFERED, ret
|
607
679
|
end
|
608
680
|
|
609
681
|
def test_no_block_return_value
|
@@ -611,71 +683,79 @@ class MemcachedTest < Test::Unit::TestCase
|
|
611
683
|
@nb_cache.set key, @value
|
612
684
|
end
|
613
685
|
ret = Rlibmemcached.memcached_set(
|
614
|
-
@nb_cache.instance_variable_get("@struct"),
|
615
|
-
key,
|
616
|
-
@marshalled_value,
|
617
|
-
0,
|
686
|
+
@nb_cache.instance_variable_get("@struct"),
|
687
|
+
key,
|
688
|
+
@marshalled_value,
|
689
|
+
0,
|
618
690
|
Memcached::FLAGS
|
619
691
|
)
|
620
|
-
assert_equal
|
692
|
+
assert_equal Rlibmemcached::MEMCACHED_BUFFERED, ret
|
621
693
|
end
|
622
694
|
|
695
|
+
def test_no_block_get
|
696
|
+
@nb_cache.set key, @value
|
697
|
+
assert_equal @value,
|
698
|
+
@nb_cache.get(key)
|
699
|
+
end
|
700
|
+
|
623
701
|
def test_no_block_missing_delete
|
624
702
|
@nb_cache.delete key rescue nil
|
625
703
|
assert_nothing_raised do
|
626
704
|
@nb_cache.delete key
|
627
705
|
end
|
628
|
-
end
|
706
|
+
end
|
629
707
|
|
630
708
|
def test_no_block_set_invalid_key
|
631
709
|
assert_raises(Memcached::ABadKeyWasProvidedOrCharactersOutOfRange) do
|
632
710
|
@nb_cache.set "I'm so bad", @value
|
633
711
|
end
|
634
|
-
end
|
712
|
+
end
|
635
713
|
|
636
714
|
def test_no_block_set_object_too_large
|
637
715
|
assert_nothing_raised do
|
638
716
|
@nb_cache.set key, "I'm big" * 1000000
|
639
717
|
end
|
640
718
|
end
|
641
|
-
|
719
|
+
|
642
720
|
def test_no_block_existing_add
|
643
721
|
# Should still raise
|
644
722
|
@nb_cache.set key, @value
|
645
723
|
assert_raise(Memcached::NotStored) do
|
646
724
|
@nb_cache.add key, @value
|
647
725
|
end
|
648
|
-
end
|
649
|
-
|
726
|
+
end
|
727
|
+
|
650
728
|
# Server removal and consistent hashing
|
651
|
-
|
652
|
-
def
|
729
|
+
|
730
|
+
def test_dying_server
|
731
|
+
socket = stub_server 43041
|
653
732
|
cache = Memcached.new(
|
654
|
-
[@servers.last, 'localhost:43041'],
|
733
|
+
[@servers.last, 'localhost:43041'],
|
655
734
|
:prefix_key => @prefix_key,
|
656
735
|
:failover => true,
|
736
|
+
:hash_with_prefix_key => false,
|
657
737
|
:hash => :md5
|
658
738
|
)
|
659
|
-
|
739
|
+
|
660
740
|
# Hit first server
|
661
|
-
|
662
|
-
cache.set(
|
663
|
-
cache.get(
|
664
|
-
|
741
|
+
key1 = 'test_missing_server6'
|
742
|
+
cache.set(key1, @value)
|
743
|
+
cache.get(key1) == @value
|
744
|
+
|
665
745
|
# Hit second server
|
666
|
-
|
667
|
-
assert_raise(Memcached::
|
668
|
-
cache.set(
|
669
|
-
cache.get(
|
670
|
-
end
|
746
|
+
key2 = 'test_missing_server'
|
747
|
+
assert_raise(Memcached::UnknownReadFailure) do
|
748
|
+
cache.set(key2, @value)
|
749
|
+
cache.get(key2)
|
750
|
+
end
|
671
751
|
|
672
752
|
# Hit first server on retry
|
673
753
|
assert_nothing_raised do
|
674
|
-
cache.set(
|
675
|
-
cache.get(
|
676
|
-
end
|
754
|
+
cache.set(key2, @value)
|
755
|
+
cache.get(key2)
|
756
|
+
end
|
677
757
|
end
|
678
|
-
|
758
|
+
|
679
759
|
def test_sweep_servers_with_missing_server_first
|
680
760
|
cache = Memcached.new(['127.0.0.1:00000'] + @servers)
|
681
761
|
assert_nothing_raised do
|
@@ -686,24 +766,24 @@ class MemcachedTest < Test::Unit::TestCase
|
|
686
766
|
def test_consistent_hashing
|
687
767
|
|
688
768
|
keys = %w(EN6qtgMW n6Oz2W4I ss4A8Brr QShqFLZt Y3hgP9bs CokDD4OD Nd3iTSE1 24vBV4AU H9XBUQs5 E5j8vUq1 AzSh8fva PYBlK2Pi Ke3TgZ4I AyAIYanO oxj8Xhyd eBFnE6Bt yZyTikWQ pwGoU7Pw 2UNDkKRN qMJzkgo2 keFXbQXq pBl2QnIg ApRl3mWY wmalTJW1 TLueug8M wPQL4Qfg uACwus23 nmOk9R6w lwgZJrzJ v1UJtKdG RK629Cra U2UXFRqr d9OQLNl8 KAm1K3m5 Z13gKZ1v tNVai1nT LhpVXuVx pRib1Itj I1oLUob7 Z1nUsd5Q ZOwHehUa aXpFX29U ZsnqxlGz ivQRjOdb mB3iBEAj)
|
689
|
-
|
769
|
+
|
690
770
|
# Five servers
|
691
771
|
cache = Memcached.new(
|
692
|
-
@servers + ['localhost:43044', 'localhost:43045', 'localhost:43046'],
|
772
|
+
@servers + ['localhost:43044', 'localhost:43045', 'localhost:43046'],
|
693
773
|
:prefix_key => @prefix_key
|
694
|
-
)
|
695
|
-
|
696
|
-
cache.flush
|
774
|
+
)
|
775
|
+
|
776
|
+
cache.flush
|
697
777
|
keys.each do |key|
|
698
778
|
cache.set(key, @value)
|
699
|
-
end
|
779
|
+
end
|
700
780
|
|
701
781
|
# Pull a server
|
702
782
|
cache = Memcached.new(
|
703
783
|
@servers + ['localhost:43044', 'localhost:43046'],
|
704
784
|
:prefix_key => @prefix_key
|
705
785
|
)
|
706
|
-
|
786
|
+
|
707
787
|
failed = 0
|
708
788
|
keys.each_with_index do |key, i|
|
709
789
|
begin
|
@@ -713,15 +793,15 @@ class MemcachedTest < Test::Unit::TestCase
|
|
713
793
|
end
|
714
794
|
end
|
715
795
|
|
716
|
-
assert(failed < keys.size / 3, "#{failed} failed out of #{keys.size}")
|
796
|
+
assert(failed < keys.size / 3, "#{failed} failed out of #{keys.size}")
|
717
797
|
end
|
718
798
|
|
719
799
|
# Concurrency
|
720
|
-
|
800
|
+
|
721
801
|
def test_thread_contention
|
722
802
|
threads = []
|
723
803
|
4.times do |index|
|
724
|
-
threads << Thread.new do
|
804
|
+
threads << Thread.new do
|
725
805
|
cache = @cache.clone
|
726
806
|
assert_nothing_raised do
|
727
807
|
cache.set("test_thread_contention_#{index}", index)
|
@@ -731,23 +811,29 @@ class MemcachedTest < Test::Unit::TestCase
|
|
731
811
|
end
|
732
812
|
threads.each {|thread| thread.join}
|
733
813
|
end
|
734
|
-
|
814
|
+
|
735
815
|
# Memory cleanup
|
736
|
-
|
816
|
+
|
737
817
|
def test_reset
|
738
818
|
original_struct = @cache.instance_variable_get("@struct")
|
739
819
|
assert_nothing_raised do
|
740
820
|
@cache.reset
|
741
|
-
end
|
742
|
-
assert_not_equal original_struct,
|
743
|
-
@cache.instance_variable_get("@struct")
|
821
|
+
end
|
822
|
+
assert_not_equal original_struct,
|
823
|
+
@cache.instance_variable_get("@struct")
|
744
824
|
end
|
745
|
-
|
825
|
+
|
746
826
|
private
|
747
|
-
|
827
|
+
|
748
828
|
def key
|
749
|
-
caller.first[/`(.*)'/, 1]
|
829
|
+
caller.first[/`(.*)'/, 1] # '
|
750
830
|
end
|
751
|
-
|
831
|
+
|
832
|
+
def stub_server(port)
|
833
|
+
socket = TCPServer.new('127.0.0.1', port)
|
834
|
+
Thread.new { socket.accept }
|
835
|
+
socket
|
836
|
+
end
|
837
|
+
|
752
838
|
end
|
753
839
|
|