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