beetle 0.1 → 0.2.1
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/README.rdoc +18 -8
- data/beetle.gemspec +37 -121
- data/bin/beetle +9 -0
- data/examples/README.rdoc +0 -2
- data/examples/rpc.rb +3 -2
- data/ext/mkrf_conf.rb +19 -0
- data/lib/beetle.rb +2 -2
- data/lib/beetle/base.rb +1 -8
- data/lib/beetle/client.rb +16 -14
- data/lib/beetle/commands.rb +30 -0
- data/lib/beetle/commands/configuration_client.rb +73 -0
- data/lib/beetle/commands/configuration_server.rb +85 -0
- data/lib/beetle/configuration.rb +70 -7
- data/lib/beetle/deduplication_store.rb +50 -38
- data/lib/beetle/handler.rb +2 -5
- data/lib/beetle/logging.rb +7 -0
- data/lib/beetle/message.rb +11 -13
- data/lib/beetle/publisher.rb +12 -4
- data/lib/beetle/r_c.rb +2 -1
- data/lib/beetle/redis_configuration_client.rb +136 -0
- data/lib/beetle/redis_configuration_server.rb +301 -0
- data/lib/beetle/redis_ext.rb +79 -0
- data/lib/beetle/redis_master_file.rb +35 -0
- data/lib/beetle/redis_server_info.rb +65 -0
- data/lib/beetle/subscriber.rb +4 -1
- data/test/beetle/configuration_test.rb +14 -2
- data/test/beetle/deduplication_store_test.rb +61 -43
- data/test/beetle/message_test.rb +28 -4
- data/test/beetle/publisher_test.rb +17 -3
- data/test/beetle/redis_configuration_client_test.rb +97 -0
- data/test/beetle/redis_configuration_server_test.rb +278 -0
- data/test/beetle/redis_ext_test.rb +71 -0
- data/test/beetle/redis_master_file_test.rb +39 -0
- data/test/test_helper.rb +13 -1
- metadata +162 -69
- data/.gitignore +0 -5
- data/MIT-LICENSE +0 -20
- data/Rakefile +0 -114
- data/TODO +0 -7
- data/etc/redis-master.conf +0 -189
- data/etc/redis-slave.conf +0 -189
- data/examples/redis_failover.rb +0 -65
- data/script/start_rabbit +0 -29
- data/snafu.rb +0 -55
- data/test/beetle.yml +0 -81
- data/test/beetle/bla.rb +0 -0
- data/tmp/master/.gitignore +0 -2
- data/tmp/slave/.gitignore +0 -3
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Beetle
|
4
|
+
class RedisConfigurationClientTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Beetle.config.redis_servers = "redis:0,redis:1"
|
7
|
+
@client = RedisConfigurationClient.new
|
8
|
+
Client.any_instance.stubs(:listen)
|
9
|
+
@client.stubs(:touch_master_file)
|
10
|
+
@client.stubs(:verify_redis_master_file_string)
|
11
|
+
end
|
12
|
+
|
13
|
+
test "config should return the beetle config" do
|
14
|
+
assert_equal Beetle.config, @client.config
|
15
|
+
end
|
16
|
+
|
17
|
+
test "ping message should answer with pong" do
|
18
|
+
@client.expects(:pong!)
|
19
|
+
@client.ping("token" => 1)
|
20
|
+
end
|
21
|
+
|
22
|
+
test "pong should publish a pong message" do
|
23
|
+
@client.beetle.expects(:publish)
|
24
|
+
@client.send(:pong!)
|
25
|
+
end
|
26
|
+
|
27
|
+
test "invalidation should send an invalidation message and clear the redis master file" do
|
28
|
+
@client.expects(:clear_redis_master_file)
|
29
|
+
@client.beetle.expects(:publish).with(:client_invalidated, anything)
|
30
|
+
@client.send(:invalidate!)
|
31
|
+
end
|
32
|
+
|
33
|
+
test "should ignore outdated invalidate messages" do
|
34
|
+
new_payload = {"token" => 2}
|
35
|
+
old_payload = {"token" => 1}
|
36
|
+
|
37
|
+
@client.expects(:invalidate!).once
|
38
|
+
|
39
|
+
@client.invalidate(new_payload)
|
40
|
+
@client.invalidate(old_payload)
|
41
|
+
end
|
42
|
+
|
43
|
+
test "should ignore invalidate messages when current master is still a master" do
|
44
|
+
@client.instance_variable_set :@current_master, stub(:master? => true)
|
45
|
+
@client.expects(:invalidate!).never
|
46
|
+
@client.invalidate("token" => 1)
|
47
|
+
end
|
48
|
+
|
49
|
+
test "should ignore outdated reconfigure messages" do
|
50
|
+
new_payload = {"token" => 2, "server" => "master:2"}
|
51
|
+
old_payload = {"token" => 1, "server" => "master:1"}
|
52
|
+
@client.stubs(:read_redis_master_file).returns("")
|
53
|
+
|
54
|
+
@client.expects(:write_redis_master_file).once
|
55
|
+
|
56
|
+
@client.reconfigure(new_payload)
|
57
|
+
@client.reconfigure(old_payload)
|
58
|
+
end
|
59
|
+
|
60
|
+
test "should clear redis master file if redis from master file is slave" do
|
61
|
+
@client.stubs(:redis_master_from_master_file).returns(stub(:master? => false))
|
62
|
+
@client.expects(:clear_redis_master_file)
|
63
|
+
@client.start
|
64
|
+
end
|
65
|
+
|
66
|
+
test "should clear redis master file if redis from master file is not available" do
|
67
|
+
@client.stubs(:redis_master_from_master_file).returns(nil)
|
68
|
+
@client.expects(:clear_redis_master_file)
|
69
|
+
@client.start
|
70
|
+
end
|
71
|
+
|
72
|
+
test "the dispatcher should just forward messages to the client" do
|
73
|
+
dispatcher_class = RedisConfigurationClient.class_eval "MessageDispatcher"
|
74
|
+
dispatcher_class.configuration_client = @client
|
75
|
+
dispatcher = dispatcher_class.new
|
76
|
+
payload = {"token" => 1}
|
77
|
+
dispatcher.stubs(:message).returns(stub(:data => payload.to_json, :header => stub(:routing_key=> "ping")))
|
78
|
+
@client.expects(:ping).with(payload)
|
79
|
+
dispatcher.send(:process)
|
80
|
+
end
|
81
|
+
|
82
|
+
test "determine_initial_master should return nil if there is no file" do
|
83
|
+
@client.expects(:master_file_exists?).returns(false)
|
84
|
+
assert_nil @client.send(:determine_initial_master)
|
85
|
+
assert_nil @client.current_master
|
86
|
+
end
|
87
|
+
|
88
|
+
test "determine_initial_master should instantiate a new redis if there is a file with content" do
|
89
|
+
@client.expects(:master_file_exists?).returns(true)
|
90
|
+
@client.expects(:read_redis_master_file).returns("localhost:6379")
|
91
|
+
master = @client.send(:determine_initial_master)
|
92
|
+
assert_equal "master", master.role
|
93
|
+
assert_equal master, @client.current_master
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,278 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Beetle
|
4
|
+
class RedisConfigurationServerTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Beetle.config.redis_configuration_client_ids = "rc-client-1,rc-client-2"
|
7
|
+
@server = RedisConfigurationServer.new
|
8
|
+
EventMachine.stubs(:add_timer).yields
|
9
|
+
end
|
10
|
+
|
11
|
+
test "should exit when started with less than two redis configured" do
|
12
|
+
Beetle.config.redis_servers = ""
|
13
|
+
assert_raise Beetle::ConfigurationError do
|
14
|
+
@server.start
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
test "should initialize the current token for messages to not reuse old tokens" do
|
19
|
+
sleep 0.1
|
20
|
+
later_server = RedisConfigurationServer.new
|
21
|
+
assert later_server.current_token > @server.current_token
|
22
|
+
end
|
23
|
+
|
24
|
+
test "should ignore outdated client_invalidated messages" do
|
25
|
+
@server.instance_variable_set(:@current_token, 2)
|
26
|
+
@server.client_invalidated("id" => "rc-client-1", "token" => 2)
|
27
|
+
old_token = 1.minute.ago.to_f
|
28
|
+
@server.client_invalidated("id" => "rc-client-2", "token" => 1)
|
29
|
+
|
30
|
+
assert_equal(["rc-client-1"].to_set, @server.instance_variable_get(:@client_invalidated_ids_received))
|
31
|
+
end
|
32
|
+
|
33
|
+
test "should ignore outdated pong messages" do
|
34
|
+
@server.instance_variable_set(:@current_token, 2)
|
35
|
+
@server.pong("id" => "rc-client-1", "token" => 2)
|
36
|
+
old_token = 1.minute.ago.to_f
|
37
|
+
@server.pong("id" => "rc-client-2", "token" => 1)
|
38
|
+
|
39
|
+
assert_equal(["rc-client-1"].to_set, @server.instance_variable_get(:@client_pong_ids_received))
|
40
|
+
end
|
41
|
+
|
42
|
+
test "the dispatcher should just forward messages to the server" do
|
43
|
+
dispatcher_class = RedisConfigurationServer.class_eval "MessageDispatcher"
|
44
|
+
dispatcher_class.configuration_server = @server
|
45
|
+
dispatcher = dispatcher_class.new
|
46
|
+
payload = {"token" => 1}
|
47
|
+
dispatcher.stubs(:message).returns(stub(:data => payload.to_json, :header => stub(:routing_key=> "pong")))
|
48
|
+
@server.expects(:pong).with(payload)
|
49
|
+
dispatcher.send(:process)
|
50
|
+
end
|
51
|
+
|
52
|
+
test "if a new master is available, it should be published and the available slaves should be configured" do
|
53
|
+
redis = Redis.new
|
54
|
+
other_master = Redis.new(:port => 6380)
|
55
|
+
other_master.expects(:slave_of!).with(redis.host, redis.port)
|
56
|
+
@server.stubs(:current_master).returns(redis)
|
57
|
+
@server.redis.instance_variable_set(:@server_info, {"master" => [redis, other_master], "slave" => [], "unknown" => []})
|
58
|
+
payload = @server.send(:payload_with_current_token, {"server" => redis.server})
|
59
|
+
@server.beetle.expects(:publish).with(:reconfigure, payload)
|
60
|
+
@server.master_available!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class RedisConfigurationServerInvalidationTest < Test::Unit::TestCase
|
65
|
+
def setup
|
66
|
+
Beetle.config.redis_configuration_client_ids = "rc-client-1,rc-client-2"
|
67
|
+
Beetle.config.redis_servers = "redis:0,redis:1"
|
68
|
+
@server = RedisConfigurationServer.new
|
69
|
+
@server.instance_variable_set(:@current_master, stub('redis stub', :server => 'stubbed_server', :available? => false))
|
70
|
+
@server.stubs(:verify_redis_master_file_string)
|
71
|
+
@server.beetle.stubs(:listen).yields
|
72
|
+
@server.beetle.stubs(:publish)
|
73
|
+
EM::Timer.stubs(:new).returns(true)
|
74
|
+
EventMachine.stubs(:add_periodic_timer).yields
|
75
|
+
end
|
76
|
+
|
77
|
+
test "should pause watching of the redis master when it becomes unavailable" do
|
78
|
+
@server.expects(:determine_initial_master)
|
79
|
+
EM.stubs(:add_periodic_timer).returns(stub("timer", :cancel => true))
|
80
|
+
@server.start
|
81
|
+
assert !@server.paused?
|
82
|
+
@server.master_unavailable!
|
83
|
+
assert @server.paused?
|
84
|
+
end
|
85
|
+
|
86
|
+
test "should setup an invalidation timeout" do
|
87
|
+
EM::Timer.expects(:new).yields
|
88
|
+
@server.expects(:cancel_invalidation)
|
89
|
+
@server.master_unavailable!
|
90
|
+
end
|
91
|
+
|
92
|
+
test "should continue watching after the invalidation timeout has expired" do
|
93
|
+
EM::Timer.expects(:new).yields
|
94
|
+
@server.master_unavailable!
|
95
|
+
assert !@server.paused?
|
96
|
+
end
|
97
|
+
|
98
|
+
test "should invalidate the current master after receiving all pong messages" do
|
99
|
+
EM::Timer.expects(:new).yields.returns(:timer)
|
100
|
+
@server.beetle.expects(:publish).with(:invalidate, anything)
|
101
|
+
@server.expects(:cancel_invalidation)
|
102
|
+
@server.expects(:redeem_token).with(1).twice.returns(true)
|
103
|
+
@server.pong("token" => 1, "id" => "rc-client-1")
|
104
|
+
@server.pong("token" => 1, "id" => "rc-client-2")
|
105
|
+
end
|
106
|
+
|
107
|
+
test "should switch the current master after receiving all client_invalidated messages" do
|
108
|
+
@server.expects(:redeem_token).with(1).twice.returns(true)
|
109
|
+
@server.expects(:switch_master)
|
110
|
+
@server.client_invalidated("token" => 1, "id" => "rc-client-1")
|
111
|
+
@server.client_invalidated("token" => 1, "id" => "rc-client-2")
|
112
|
+
end
|
113
|
+
|
114
|
+
test "should switch the current master immediately if there are no clients" do
|
115
|
+
@server.instance_variable_set :@client_ids, Set.new
|
116
|
+
@server.expects(:switch_master)
|
117
|
+
@server.master_unavailable!
|
118
|
+
end
|
119
|
+
|
120
|
+
test "switching the master should turn the new master candidate into a master" do
|
121
|
+
new_master = stub(:master! => nil, :server => "jo:6379")
|
122
|
+
@server.beetle.expects(:publish).with(:system_notification, anything)
|
123
|
+
@server.expects(:determine_new_master).returns(new_master)
|
124
|
+
@server.send :switch_master
|
125
|
+
assert_equal new_master, @server.current_master
|
126
|
+
end
|
127
|
+
|
128
|
+
test "switching the master should resort to the old master if no candidate can be found" do
|
129
|
+
old_master = @server.current_master
|
130
|
+
@server.beetle.expects(:publish).with(:system_notification, anything)
|
131
|
+
@server.expects(:determine_new_master).returns(nil)
|
132
|
+
@server.send :switch_master
|
133
|
+
assert_equal old_master, @server.current_master
|
134
|
+
end
|
135
|
+
|
136
|
+
test "checking the availability of redis servers should publish the available servers as long as the master is available" do
|
137
|
+
@server.expects(:master_available?).returns(true)
|
138
|
+
@server.expects(:master_available!)
|
139
|
+
@server.send(:master_watcher).send(:check_availability)
|
140
|
+
end
|
141
|
+
|
142
|
+
test "checking the availability of redis servers should call master_unavailable after trying the specified number of times" do
|
143
|
+
@server.stubs(:master_available?).returns(false)
|
144
|
+
@server.expects(:master_unavailable!)
|
145
|
+
watcher = @server.send(:master_watcher)
|
146
|
+
watcher.instance_variable_set :@master_retries, 0
|
147
|
+
watcher.send(:check_availability)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class RedisConfigurationServerInitialRedisMasterDeterminationTest < Test::Unit::TestCase
|
152
|
+
def setup
|
153
|
+
EM::Timer.stubs(:new).returns(true)
|
154
|
+
EventMachine.stubs(:add_periodic_timer).yields
|
155
|
+
@client = Client.new(Configuration.new)
|
156
|
+
@client.stubs(:listen).yields
|
157
|
+
@client.stubs(:publish)
|
158
|
+
@client.config.redis_configuration_client_ids = "rc-client-1,rc-client-2"
|
159
|
+
@server = RedisConfigurationServer.new
|
160
|
+
@server.stubs(:beetle).returns(@client)
|
161
|
+
@server.stubs(:write_redis_master_file)
|
162
|
+
@redis_master = build_master_redis_stub
|
163
|
+
@redis_slave = build_slave_redis_stub
|
164
|
+
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_master, @redis_slave))
|
165
|
+
end
|
166
|
+
|
167
|
+
test "should not try to auto-detect if the master file contains a server string" do
|
168
|
+
@server.expects(:master_file_exists?).returns(true)
|
169
|
+
@server.stubs(:read_redis_master_file).returns("foobar:0000")
|
170
|
+
|
171
|
+
@server.redis.expects(:auto_detect_master).never
|
172
|
+
@server.expects(:redis_master_from_master_file).returns(@redis_master)
|
173
|
+
@server.send(:determine_initial_master)
|
174
|
+
end
|
175
|
+
|
176
|
+
test "should try to auto-detect if the master file is empty" do
|
177
|
+
@server.expects(:master_file_exists?).returns(true)
|
178
|
+
@server.stubs(:read_redis_master_file).returns("")
|
179
|
+
|
180
|
+
@server.redis.expects(:auto_detect_master).returns(@redis_master)
|
181
|
+
@server.send(:determine_initial_master)
|
182
|
+
end
|
183
|
+
|
184
|
+
test "should try to auto-detect if the master file is not present" do
|
185
|
+
@server.expects(:master_file_exists?).returns(false)
|
186
|
+
|
187
|
+
@server.redis.expects(:auto_detect_master).returns(@redis_master)
|
188
|
+
@server.send(:determine_initial_master)
|
189
|
+
end
|
190
|
+
|
191
|
+
test "should use redis master from successful auto-detection" do
|
192
|
+
@server.expects(:master_file_exists?).returns(false)
|
193
|
+
|
194
|
+
@server.expects(:write_redis_master_file).with(@redis_master.server)
|
195
|
+
@server.send(:determine_initial_master)
|
196
|
+
assert_equal @redis_master, @server.current_master
|
197
|
+
end
|
198
|
+
|
199
|
+
test "should use redis master if master in file is the only master" do
|
200
|
+
@server.expects(:master_file_exists?).returns(true)
|
201
|
+
@server.stubs(:redis_master_from_master_file).returns(@redis_master)
|
202
|
+
|
203
|
+
@server.send(:determine_initial_master)
|
204
|
+
assert_equal @redis_master, @server.current_master
|
205
|
+
end
|
206
|
+
|
207
|
+
test "should start master switch if master in file is slave" do
|
208
|
+
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_slave))
|
209
|
+
@server.expects(:master_file_exists?).returns(true)
|
210
|
+
@server.stubs(:redis_master_from_master_file).returns(@redis_slave)
|
211
|
+
|
212
|
+
@server.expects(:master_unavailable!)
|
213
|
+
@server.send(:determine_initial_master)
|
214
|
+
end
|
215
|
+
|
216
|
+
test "should use master from master file if multiple masters are available" do
|
217
|
+
redis_master2 = build_master_redis_stub
|
218
|
+
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_master, redis_master2))
|
219
|
+
@server.expects(:master_file_exists?).returns(true)
|
220
|
+
@server.stubs(:redis_master_from_master_file).returns(@redis_master)
|
221
|
+
|
222
|
+
@server.send(:determine_initial_master)
|
223
|
+
assert_equal @redis_master, @server.current_master
|
224
|
+
end
|
225
|
+
|
226
|
+
test "should start master switch if master in file is not available" do
|
227
|
+
not_available_redis_master = build_unknown_redis_stub
|
228
|
+
@server.instance_variable_set(:@redis, build_redis_server_info(not_available_redis_master, @redis_slave))
|
229
|
+
@server.expects(:master_file_exists?).returns(true)
|
230
|
+
@server.stubs(:redis_master_from_master_file).returns(not_available_redis_master)
|
231
|
+
|
232
|
+
@server.expects(:master_unavailable!)
|
233
|
+
@server.send(:determine_initial_master)
|
234
|
+
end
|
235
|
+
|
236
|
+
test "should raise an exception if both master file and auto-detection fails" do
|
237
|
+
not_available_redis_master = build_unknown_redis_stub
|
238
|
+
not_available_redis_slave = build_unknown_redis_stub
|
239
|
+
@server.instance_variable_set(:@redis, build_redis_server_info(not_available_redis_master, not_available_redis_slave))
|
240
|
+
@server.expects(:master_file_exists?).returns(true)
|
241
|
+
@server.expects(:read_redis_master_file).returns("")
|
242
|
+
@server.redis.expects(:auto_detect_master).returns(nil)
|
243
|
+
|
244
|
+
assert_raises Beetle::NoRedisMaster do
|
245
|
+
@server.send(:determine_initial_master)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
test "should detect a new redis_master" do
|
250
|
+
not_available_redis_master = build_unknown_redis_stub
|
251
|
+
@redis_slave.expects(:slave_of?).returns(true)
|
252
|
+
@server.instance_variable_set(:@current_master, not_available_redis_master)
|
253
|
+
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_slave, not_available_redis_master))
|
254
|
+
assert_equal @redis_slave, @server.send(:determine_new_master)
|
255
|
+
end
|
256
|
+
|
257
|
+
private
|
258
|
+
|
259
|
+
def build_master_redis_stub
|
260
|
+
stub("redis master", :host => "stubbed_master", :port => 0, :server => "stubbed_master:0", :available? => true, :master? => true, :slave? => false, :role => "master")
|
261
|
+
end
|
262
|
+
|
263
|
+
def build_slave_redis_stub
|
264
|
+
stub("redis slave", :host => "stubbed_slave", :port => 0, :server => "stubbed_slave:0", :available? => true, :master? => false, :slave? => true, :role => "slave")
|
265
|
+
end
|
266
|
+
|
267
|
+
def build_unknown_redis_stub
|
268
|
+
stub("redis unknown", :host => "stubbed_unknown", :port => 0, :server => "stubbed_unknown:0", :available? => false, :master? => false, :slave? => false, :role => "unknown")
|
269
|
+
end
|
270
|
+
|
271
|
+
def build_redis_server_info(*redis_instances)
|
272
|
+
info = RedisServerInfo.new(Beetle.config, :timeout => 1)
|
273
|
+
info.instance_variable_set :@instances, redis_instances
|
274
|
+
redis_instances.each{|redis| info.send("#{redis.role}s") << redis }
|
275
|
+
info
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Beetle
|
4
|
+
|
5
|
+
class NonExistentRedisTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@r = Redis.new(:host => "localhost", :port => 6390)
|
8
|
+
end
|
9
|
+
|
10
|
+
test "should return an empty hash for the info_with_rescue call" do
|
11
|
+
assert_equal({}, @r.info_with_rescue)
|
12
|
+
end
|
13
|
+
|
14
|
+
test "should have a role of unknown" do
|
15
|
+
assert_equal "unknown", @r.role
|
16
|
+
end
|
17
|
+
|
18
|
+
test "should not be available" do
|
19
|
+
assert !@r.available?
|
20
|
+
end
|
21
|
+
|
22
|
+
test "should not be a master" do
|
23
|
+
assert !@r.master?
|
24
|
+
end
|
25
|
+
|
26
|
+
test "should not be a slave" do
|
27
|
+
assert !@r.slave?
|
28
|
+
assert !@r.slave_of?("localhost", 6379)
|
29
|
+
end
|
30
|
+
|
31
|
+
test "should not try toconnect to the redis server on inspect" do
|
32
|
+
assert_nothing_raised { @r.inspect }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class AddedRedisMethodsTest < Test::Unit::TestCase
|
37
|
+
def setup
|
38
|
+
@r = Redis.new(:host => "localhost", :port => 6390)
|
39
|
+
end
|
40
|
+
|
41
|
+
test "should return the host, port and server string" do
|
42
|
+
assert_equal "localhost", @r.host
|
43
|
+
assert_equal 6390, @r.port
|
44
|
+
assert_equal "localhost:6390", @r.server
|
45
|
+
end
|
46
|
+
|
47
|
+
test "should stop slavery" do
|
48
|
+
@r.expects(:slaveof).with("no", "one")
|
49
|
+
@r.master!
|
50
|
+
end
|
51
|
+
|
52
|
+
test "should support slavery" do
|
53
|
+
@r.expects(:slaveof).with("localhost", 6379)
|
54
|
+
@r.slave_of!("localhost", 6379)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class RedisTimeoutTest < Test::Unit::TestCase
|
59
|
+
test "should use Redis::Timer if timeout is greater 0" do
|
60
|
+
r = Redis.new(:host => "localhost", :port => 6390, :timeout => 1)
|
61
|
+
Redis::Timer.expects(:timeout).with(1).raises(Timeout::Error)
|
62
|
+
assert_equal({}, r.info_with_rescue)
|
63
|
+
end
|
64
|
+
|
65
|
+
test "should not use Redis::Timer if timeout 0" do
|
66
|
+
r = Redis.new(:host => "localhost", :port => 6390, :timeout => 0)
|
67
|
+
Redis::Timer.expects(:timeout).never
|
68
|
+
assert_equal({}, r.info_with_rescue)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Beetle
|
4
|
+
|
5
|
+
class RedisMasterFileTest < Test::Unit::TestCase
|
6
|
+
include Logging
|
7
|
+
include RedisMasterFile
|
8
|
+
|
9
|
+
def setup
|
10
|
+
File.open(master_file, "w"){|f| f.puts "localhost:6379"}
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
File.unlink(master_file) if File.exist?(master_file)
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should be able to check existence" do
|
18
|
+
assert master_file_exists?
|
19
|
+
File.unlink(master_file)
|
20
|
+
assert !master_file_exists?
|
21
|
+
end
|
22
|
+
|
23
|
+
test "should be able to read and write the master file"do
|
24
|
+
write_redis_master_file("localhost:6380")
|
25
|
+
assert_equal "localhost:6380", read_redis_master_file
|
26
|
+
end
|
27
|
+
|
28
|
+
test "should be able to clear the master file" do
|
29
|
+
logger.expects(:warn)
|
30
|
+
clear_redis_master_file
|
31
|
+
assert_equal "", read_redis_master_file
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def master_file
|
36
|
+
"/tmp/mumu.txt"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|