beetle 1.0.3 → 2.0.0rc1
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.
- checksums.yaml +4 -4
- data/README.rdoc +15 -7
- data/REDIS_AUTO_FAILOVER.rdoc +8 -16
- data/RELEASE_NOTES.rdoc +9 -0
- data/beetle.gemspec +22 -10
- data/features/support/system_notification_logger +29 -12
- data/features/support/test_daemons/redis.rb +1 -1
- data/features/support/test_daemons/redis_configuration_client.rb +3 -3
- data/features/support/test_daemons/redis_configuration_server.rb +2 -2
- data/lib/beetle/deduplication_store.rb +0 -66
- data/lib/beetle/message.rb +1 -1
- data/lib/beetle/publisher.rb +2 -1
- data/lib/beetle/redis_master_file.rb +0 -5
- data/lib/beetle/version.rb +1 -1
- data/test/beetle/deduplication_store_test.rb +0 -48
- data/test/beetle/message_test.rb +1 -31
- data/test/beetle/publisher_test.rb +2 -1
- metadata +165 -26
- data/bin/beetle +0 -9
- data/lib/beetle/commands.rb +0 -35
- data/lib/beetle/commands/configuration_client.rb +0 -98
- data/lib/beetle/commands/configuration_server.rb +0 -98
- data/lib/beetle/commands/garbage_collect_deduplication_store.rb +0 -52
- data/lib/beetle/redis_configuration_client.rb +0 -157
- data/lib/beetle/redis_configuration_http_server.rb +0 -152
- data/lib/beetle/redis_configuration_server.rb +0 -438
- data/lib/beetle/redis_server_info.rb +0 -66
- data/script/docker-run-beetle-tests- +0 -5
- data/test/beetle/redis_configuration_client_test.rb +0 -118
- data/test/beetle/redis_configuration_server_test.rb +0 -381
@@ -1,118 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
-
|
3
|
-
module Beetle
|
4
|
-
class RedisConfigurationClientTest < Minitest::Test
|
5
|
-
def setup
|
6
|
-
Beetle.config.redis_servers = "redis:0,redis:1"
|
7
|
-
@client = RedisConfigurationClient.new
|
8
|
-
@client.stubs(:touch_master_file)
|
9
|
-
@client.stubs(:verify_redis_master_file_string)
|
10
|
-
end
|
11
|
-
|
12
|
-
test "should send a client_started message when started" do
|
13
|
-
@client.stubs(:clear_redis_master_file)
|
14
|
-
@client.beetle.expects(:publish).with(:client_started, {:id => @client.id}.to_json)
|
15
|
-
Client.any_instance.stubs(:listen)
|
16
|
-
@client.start
|
17
|
-
end
|
18
|
-
|
19
|
-
test "should install a periodic timer which sends a heartbeat message" do
|
20
|
-
@client.stubs(:clear_redis_master_file)
|
21
|
-
@client.beetle.expects(:publish).with(:client_started, {:id => @client.id}.to_json)
|
22
|
-
@client.beetle.expects(:listen).yields
|
23
|
-
EventMachine.expects(:add_periodic_timer).with(Beetle.config.redis_failover_client_heartbeat_interval).yields
|
24
|
-
@client.beetle.expects(:publish).with(:heartbeat, {:id => @client.id}.to_json)
|
25
|
-
@client.start
|
26
|
-
end
|
27
|
-
|
28
|
-
test "config should return the beetle config" do
|
29
|
-
assert_equal Beetle.config, @client.config
|
30
|
-
end
|
31
|
-
|
32
|
-
test "ping message should answer with pong" do
|
33
|
-
@client.expects(:pong!)
|
34
|
-
@client.ping("token" => 1)
|
35
|
-
end
|
36
|
-
|
37
|
-
test "pong should publish a pong message" do
|
38
|
-
@client.beetle.expects(:publish)
|
39
|
-
@client.send(:pong!)
|
40
|
-
end
|
41
|
-
|
42
|
-
test "invalidation should send an invalidation message and clear the redis master file" do
|
43
|
-
@client.expects(:clear_redis_master_file)
|
44
|
-
@client.beetle.expects(:publish).with(:client_invalidated, anything)
|
45
|
-
@client.send(:invalidate!)
|
46
|
-
end
|
47
|
-
|
48
|
-
test "should ignore outdated invalidate messages" do
|
49
|
-
new_payload = {"token" => 2}
|
50
|
-
old_payload = {"token" => 1}
|
51
|
-
|
52
|
-
@client.expects(:invalidate!).once
|
53
|
-
|
54
|
-
@client.invalidate(new_payload)
|
55
|
-
@client.invalidate(old_payload)
|
56
|
-
end
|
57
|
-
|
58
|
-
test "should ignore invalidate messages when current master is still a master" do
|
59
|
-
@client.instance_variable_set :@current_master, stub(:master? => true)
|
60
|
-
@client.expects(:invalidate!).never
|
61
|
-
@client.invalidate("token" => 1)
|
62
|
-
end
|
63
|
-
|
64
|
-
test "should ignore outdated reconfigure messages" do
|
65
|
-
new_payload = {"token" => 2, "server" => "master:2"}
|
66
|
-
old_payload = {"token" => 1, "server" => "master:1"}
|
67
|
-
@client.stubs(:read_redis_master_file).returns("")
|
68
|
-
|
69
|
-
@client.expects(:write_redis_master_file).once
|
70
|
-
|
71
|
-
@client.reconfigure(new_payload)
|
72
|
-
@client.reconfigure(old_payload)
|
73
|
-
end
|
74
|
-
|
75
|
-
test "should clear redis master file if redis from master file is slave" do
|
76
|
-
@client.stubs(:redis_master_from_master_file).returns(stub(:master? => false))
|
77
|
-
Beetle::Client.any_instance.stubs(:publish)
|
78
|
-
@client.expects(:clear_redis_master_file)
|
79
|
-
@client.expects(:client_started!)
|
80
|
-
Client.any_instance.stubs(:listen)
|
81
|
-
@client.start
|
82
|
-
end
|
83
|
-
|
84
|
-
test "should clear redis master file if redis from master file is not available" do
|
85
|
-
@client.stubs(:redis_master_from_master_file).returns(nil)
|
86
|
-
Beetle::Client.any_instance.stubs(:publish)
|
87
|
-
@client.expects(:clear_redis_master_file)
|
88
|
-
@client.expects(:client_started!)
|
89
|
-
Client.any_instance.stubs(:listen)
|
90
|
-
@client.start
|
91
|
-
end
|
92
|
-
|
93
|
-
test "the dispatcher should just forward messages to the client" do
|
94
|
-
dispatcher_class = RedisConfigurationClient.class_eval "MessageDispatcher"
|
95
|
-
dispatcher_class.configuration_client = @client
|
96
|
-
dispatcher = dispatcher_class.new
|
97
|
-
payload = {"token" => 1}
|
98
|
-
dispatcher.stubs(:message).returns(stub(:data => payload.to_json, :header => stub(:routing_key=> "ping")))
|
99
|
-
@client.expects(:ping).with(payload)
|
100
|
-
dispatcher.send(:process)
|
101
|
-
end
|
102
|
-
|
103
|
-
test "determine_initial_master should return nil if there is no file" do
|
104
|
-
@client.expects(:master_file_exists?).returns(false)
|
105
|
-
assert_nil @client.send(:determine_initial_master)
|
106
|
-
assert_nil @client.current_master
|
107
|
-
end
|
108
|
-
|
109
|
-
test "determine_initial_master should instantiate a new redis if there is a file with content" do
|
110
|
-
@client.expects(:master_file_exists?).returns(true)
|
111
|
-
@client.expects(:read_redis_master_file).returns("localhost:6379")
|
112
|
-
master = @client.send(:determine_initial_master)
|
113
|
-
assert_equal "master", master.role
|
114
|
-
assert_equal master, @client.current_master
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
end
|
@@ -1,381 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
-
|
3
|
-
module Beetle
|
4
|
-
class RedisConfigurationServerTest < Minitest::Test
|
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_raises 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
|
-
@server.client_invalidated("id" => "rc-client-2", "token" => 1)
|
28
|
-
|
29
|
-
assert_equal(["rc-client-1"].to_set, @server.instance_variable_get(:@client_invalidated_ids_received))
|
30
|
-
end
|
31
|
-
|
32
|
-
test "should ignore outdated pong messages" do
|
33
|
-
@server.instance_variable_set(:@current_token, 2)
|
34
|
-
@server.pong("id" => "rc-client-1", "token" => 2)
|
35
|
-
@server.pong("id" => "rc-client-2", "token" => 1)
|
36
|
-
|
37
|
-
assert_equal(["rc-client-1"].to_set, @server.instance_variable_get(:@client_pong_ids_received))
|
38
|
-
end
|
39
|
-
|
40
|
-
test "the dispatcher should just forward messages to the server" do
|
41
|
-
dispatcher_class = RedisConfigurationServer.class_eval "MessageDispatcher"
|
42
|
-
dispatcher_class.configuration_server = @server
|
43
|
-
dispatcher = dispatcher_class.new
|
44
|
-
payload = {"token" => 1}
|
45
|
-
dispatcher.stubs(:message).returns(stub(:data => payload.to_json, :header => stub(:routing_key=> "pong")))
|
46
|
-
@server.expects(:pong).with(payload)
|
47
|
-
dispatcher.send(:process)
|
48
|
-
end
|
49
|
-
|
50
|
-
test "if a new master is available, it should be published and the available slaves should be configured" do
|
51
|
-
redis = Redis.new
|
52
|
-
other_master = Redis.new(:port => 6380)
|
53
|
-
other_master.expects(:slave_of!).with(redis.host, redis.port)
|
54
|
-
@server.stubs(:current_master).returns(redis)
|
55
|
-
@server.redis.instance_variable_set(:@server_info, {"master" => [redis, other_master], "slave" => [], "unknown" => []})
|
56
|
-
payload = @server.send(:payload_with_current_token, {"server" => redis.server})
|
57
|
-
@server.beetle.expects(:publish).with(:reconfigure, payload)
|
58
|
-
@server.master_available!
|
59
|
-
end
|
60
|
-
|
61
|
-
test "should be able to report current status" do
|
62
|
-
@server.expects(:unknown_client_ids).returns(Set.new ["x", "y"])
|
63
|
-
@server.expects(:unresponsive_clients).returns(["a", Time.now - 200])
|
64
|
-
assert @server.status.is_a?(Hash)
|
65
|
-
end
|
66
|
-
|
67
|
-
test "should be able to calculate unseen clients array" do
|
68
|
-
assert_equal @server.client_ids.sort, @server.unseen_client_ids
|
69
|
-
@server.send(:client_seen, "rc-client-1")
|
70
|
-
assert_equal ["rc-client-2"], @server.unseen_client_ids
|
71
|
-
@server.send(:client_seen, "rc-client-2")
|
72
|
-
assert_equal [], @server.unseen_client_ids
|
73
|
-
end
|
74
|
-
|
75
|
-
test "should not execute a conditional master switch if the current master is available" do
|
76
|
-
@server.expects(:master_available?).returns(true)
|
77
|
-
@server.expects(:paused?).returns(false)
|
78
|
-
@server.expects(:master_unavailable!).never
|
79
|
-
assert !@server.initiate_master_switch
|
80
|
-
end
|
81
|
-
|
82
|
-
test "should not execute a conditional master switch if a switch is already in progress" do
|
83
|
-
@server.expects(:master_available?).returns(false)
|
84
|
-
@server.expects(:paused?).returns(true)
|
85
|
-
@server.expects(:master_unavailable!).never
|
86
|
-
assert @server.initiate_master_switch
|
87
|
-
end
|
88
|
-
|
89
|
-
test "should execute a conditional master switch if the current master is unavailable and no switch is in progress yet" do
|
90
|
-
@server.expects(:master_available?).returns(false)
|
91
|
-
@server.expects(:master_unavailable!).once
|
92
|
-
@server.expects(:paused?).returns(false)
|
93
|
-
assert @server.initiate_master_switch
|
94
|
-
end
|
95
|
-
|
96
|
-
test "should put a limit on the number of stored unknown client ids" do
|
97
|
-
1000.times do |i|
|
98
|
-
id = i.to_s
|
99
|
-
@server.send(:client_seen, id)
|
100
|
-
@server.send(:add_unknown_client_id, id)
|
101
|
-
end
|
102
|
-
assert @server.unknown_client_ids.size < 100
|
103
|
-
assert_equal @server.unknown_client_ids.size, @server.clients_last_seen.size
|
104
|
-
end
|
105
|
-
|
106
|
-
test "should assume clients to be unresponsive after specified interval time" do
|
107
|
-
@server.send(:client_seen, "1")
|
108
|
-
@server.send(:client_seen, "2")
|
109
|
-
@server.client_dead_threshold = 0
|
110
|
-
assert_equal %w(1 2), @server.unresponsive_clients.map(&:first)
|
111
|
-
@server.client_dead_threshold = 10
|
112
|
-
assert_equal [], @server.unresponsive_clients
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
class RedisConfigurationServerInvalidationTest < Minitest::Test
|
117
|
-
def setup
|
118
|
-
Beetle.config.redis_configuration_client_ids = "rc-client-1,rc-client-2"
|
119
|
-
Beetle.config.redis_servers = "redis:0,redis:1"
|
120
|
-
@server = RedisConfigurationServer.new
|
121
|
-
@server.instance_variable_set(:@current_master, stub('redis stub', :server => 'stubbed_server', :available? => false))
|
122
|
-
@server.stubs(:verify_redis_master_file_string)
|
123
|
-
@server.beetle.stubs(:listen).yields
|
124
|
-
@server.beetle.stubs(:publish)
|
125
|
-
EM::Timer.stubs(:new).returns(true)
|
126
|
-
EventMachine.stubs(:add_periodic_timer).yields
|
127
|
-
end
|
128
|
-
|
129
|
-
test "should pause watching of the redis master when it becomes unavailable" do
|
130
|
-
@server.expects(:determine_initial_master)
|
131
|
-
EM.stubs(:add_periodic_timer).returns(stub("timer", :cancel => true))
|
132
|
-
@server.start
|
133
|
-
assert !@server.paused?
|
134
|
-
@server.master_unavailable!
|
135
|
-
assert @server.paused?
|
136
|
-
end
|
137
|
-
|
138
|
-
test "should setup an invalidation timeout" do
|
139
|
-
EM::Timer.expects(:new).yields
|
140
|
-
@server.expects(:cancel_invalidation)
|
141
|
-
@server.master_unavailable!
|
142
|
-
end
|
143
|
-
|
144
|
-
test "should continue watching after the invalidation timeout has expired" do
|
145
|
-
EM::Timer.expects(:new).yields
|
146
|
-
@server.master_unavailable!
|
147
|
-
assert !@server.paused?
|
148
|
-
end
|
149
|
-
|
150
|
-
test "should invalidate the current master after receiving all pong messages" do
|
151
|
-
EM::Timer.expects(:new).yields.returns(:timer)
|
152
|
-
@server.beetle.expects(:publish).with(:invalidate, anything)
|
153
|
-
@server.expects(:cancel_invalidation)
|
154
|
-
@server.expects(:redeem_token).with(1).twice.returns(true)
|
155
|
-
@server.pong("token" => 1, "id" => "rc-client-1")
|
156
|
-
@server.pong("token" => 1, "id" => "rc-client-2")
|
157
|
-
end
|
158
|
-
|
159
|
-
test "should switch the current master after receiving all client_invalidated messages" do
|
160
|
-
@server.expects(:redeem_token).with(1).twice.returns(true)
|
161
|
-
@server.expects(:switch_master)
|
162
|
-
@server.client_invalidated("token" => 1, "id" => "rc-client-1")
|
163
|
-
@server.client_invalidated("token" => 1, "id" => "rc-client-2")
|
164
|
-
end
|
165
|
-
|
166
|
-
test "should switch the current master immediately if there are no clients" do
|
167
|
-
@server.instance_variable_set :@client_ids, Set.new
|
168
|
-
@server.expects(:switch_master)
|
169
|
-
@server.master_unavailable!
|
170
|
-
end
|
171
|
-
|
172
|
-
test "switching the master should turn the new master candidate into a master" do
|
173
|
-
new_master = stub(:master! => nil, :server => "jo:6379")
|
174
|
-
@server.beetle.expects(:publish).with(:system_notification, anything)
|
175
|
-
@server.expects(:determine_new_master).returns(new_master)
|
176
|
-
@server.expects(:write_redis_master_file).with(new_master.server)
|
177
|
-
@server.send :switch_master
|
178
|
-
assert_equal new_master, @server.current_master
|
179
|
-
end
|
180
|
-
|
181
|
-
test "switching the master should resort to the old master if no candidate can be found" do
|
182
|
-
old_master = @server.current_master
|
183
|
-
@server.beetle.expects(:publish).with(:system_notification, anything)
|
184
|
-
@server.expects(:determine_new_master).returns(nil)
|
185
|
-
@server.send :switch_master
|
186
|
-
assert_equal old_master, @server.current_master
|
187
|
-
end
|
188
|
-
|
189
|
-
test "checking the availability of redis servers should publish the available servers as long as the master is available" do
|
190
|
-
@server.expects(:master_available?).returns(true)
|
191
|
-
@server.expects(:master_available!)
|
192
|
-
@server.send(:master_watcher).send(:check_availability)
|
193
|
-
end
|
194
|
-
|
195
|
-
test "checking the availability of redis servers should call master_unavailable after trying the specified number of times" do
|
196
|
-
@server.stubs(:master_available?).returns(false)
|
197
|
-
@server.expects(:master_unavailable!)
|
198
|
-
watcher = @server.send(:master_watcher)
|
199
|
-
watcher.instance_variable_set :@master_retries, 0
|
200
|
-
watcher.send(:check_availability)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
class RedisConfigurationServerInitialRedisMasterDeterminationTest < Minitest::Test
|
205
|
-
def setup
|
206
|
-
EM::Timer.stubs(:new).returns(true)
|
207
|
-
EventMachine.stubs(:add_periodic_timer).yields
|
208
|
-
@client = Client.new(Configuration.new)
|
209
|
-
@client.stubs(:listen).yields
|
210
|
-
@client.stubs(:publish)
|
211
|
-
@client.config.redis_configuration_client_ids = "rc-client-1,rc-client-2"
|
212
|
-
@server = RedisConfigurationServer.new
|
213
|
-
@server.stubs(:beetle).returns(@client)
|
214
|
-
@server.stubs(:write_redis_master_file)
|
215
|
-
@redis_master = build_master_redis_stub
|
216
|
-
@redis_slave = build_slave_redis_stub
|
217
|
-
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_master, @redis_slave))
|
218
|
-
end
|
219
|
-
|
220
|
-
test "should not try to auto-detect if the master file contains a server string" do
|
221
|
-
@server.expects(:master_file_exists?).returns(true)
|
222
|
-
@server.stubs(:read_redis_master_file).returns("foobar:0000")
|
223
|
-
|
224
|
-
@server.redis.expects(:auto_detect_master).never
|
225
|
-
@server.expects(:redis_master_from_master_file).returns(@redis_master)
|
226
|
-
@server.send(:determine_initial_master)
|
227
|
-
end
|
228
|
-
|
229
|
-
test "should try to auto-detect if the master file is empty" do
|
230
|
-
@server.expects(:master_file_exists?).returns(true)
|
231
|
-
@server.stubs(:read_redis_master_file).returns("")
|
232
|
-
|
233
|
-
@server.redis.expects(:auto_detect_master).returns(@redis_master)
|
234
|
-
@server.send(:determine_initial_master)
|
235
|
-
end
|
236
|
-
|
237
|
-
test "should try to auto-detect if the master file is not present" do
|
238
|
-
@server.expects(:master_file_exists?).returns(false)
|
239
|
-
|
240
|
-
@server.redis.expects(:auto_detect_master).returns(@redis_master)
|
241
|
-
@server.send(:determine_initial_master)
|
242
|
-
end
|
243
|
-
|
244
|
-
test "should use redis master from successful auto-detection" do
|
245
|
-
@server.expects(:master_file_exists?).returns(false)
|
246
|
-
|
247
|
-
@server.expects(:write_redis_master_file).with(@redis_master.server)
|
248
|
-
@server.send(:determine_initial_master)
|
249
|
-
assert_equal @redis_master, @server.current_master
|
250
|
-
end
|
251
|
-
|
252
|
-
test "should use redis master if master in file is the only master" do
|
253
|
-
@server.expects(:master_file_exists?).returns(true)
|
254
|
-
@server.stubs(:redis_master_from_master_file).returns(@redis_master)
|
255
|
-
|
256
|
-
@server.send(:determine_initial_master)
|
257
|
-
assert_equal @redis_master, @server.current_master
|
258
|
-
end
|
259
|
-
|
260
|
-
test "should start master switch if master in file is slave" do
|
261
|
-
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_slave))
|
262
|
-
@server.expects(:master_file_exists?).returns(true)
|
263
|
-
@server.stubs(:redis_master_from_master_file).returns(@redis_slave)
|
264
|
-
|
265
|
-
@server.expects(:master_unavailable!)
|
266
|
-
@server.send(:determine_initial_master)
|
267
|
-
end
|
268
|
-
|
269
|
-
test "should use master from master file if multiple masters are available" do
|
270
|
-
redis_master2 = build_master_redis_stub
|
271
|
-
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_master, redis_master2))
|
272
|
-
@server.expects(:master_file_exists?).returns(true)
|
273
|
-
@server.stubs(:redis_master_from_master_file).returns(@redis_master)
|
274
|
-
|
275
|
-
@server.send(:determine_initial_master)
|
276
|
-
assert_equal @redis_master, @server.current_master
|
277
|
-
end
|
278
|
-
|
279
|
-
test "should start master switch if master in file is not available" do
|
280
|
-
not_available_redis_master = build_unknown_redis_stub
|
281
|
-
@server.instance_variable_set(:@redis, build_redis_server_info(not_available_redis_master, @redis_slave))
|
282
|
-
@server.expects(:master_file_exists?).returns(true)
|
283
|
-
@server.stubs(:redis_master_from_master_file).returns(not_available_redis_master)
|
284
|
-
|
285
|
-
@server.expects(:master_unavailable!)
|
286
|
-
@server.send(:determine_initial_master)
|
287
|
-
end
|
288
|
-
|
289
|
-
test "should raise an exception if both master file and auto-detection fails" do
|
290
|
-
not_available_redis_master = build_unknown_redis_stub
|
291
|
-
not_available_redis_slave = build_unknown_redis_stub
|
292
|
-
@server.instance_variable_set(:@redis, build_redis_server_info(not_available_redis_master, not_available_redis_slave))
|
293
|
-
@server.expects(:master_file_exists?).returns(true)
|
294
|
-
@server.expects(:read_redis_master_file).returns("")
|
295
|
-
@server.redis.expects(:auto_detect_master).returns(nil)
|
296
|
-
|
297
|
-
assert_raises Beetle::NoRedisMaster do
|
298
|
-
@server.send(:determine_initial_master)
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
test "should detect a new redis_master" do
|
303
|
-
not_available_redis_master = build_unknown_redis_stub
|
304
|
-
@redis_slave.expects(:slave_of?).returns(true)
|
305
|
-
@server.instance_variable_set(:@current_master, not_available_redis_master)
|
306
|
-
@server.instance_variable_set(:@redis, build_redis_server_info(@redis_slave, not_available_redis_master))
|
307
|
-
assert_equal @redis_slave, @server.send(:determine_new_master)
|
308
|
-
end
|
309
|
-
|
310
|
-
private
|
311
|
-
|
312
|
-
def build_master_redis_stub
|
313
|
-
stub("redis master", :host => "stubbed_master", :port => 0, :server => "stubbed_master:0", :available? => true, :master? => true, :slave? => false, :role => "master")
|
314
|
-
end
|
315
|
-
|
316
|
-
def build_slave_redis_stub
|
317
|
-
stub("redis slave", :host => "stubbed_slave", :port => 0, :server => "stubbed_slave:0", :available? => true, :master? => false, :slave? => true, :role => "slave")
|
318
|
-
end
|
319
|
-
|
320
|
-
def build_unknown_redis_stub
|
321
|
-
stub("redis unknown", :host => "stubbed_unknown", :port => 0, :server => "stubbed_unknown:0", :available? => false, :master? => false, :slave? => false, :role => "unknown")
|
322
|
-
end
|
323
|
-
|
324
|
-
def build_redis_server_info(*redis_instances)
|
325
|
-
info = RedisServerInfo.new(Beetle.config, :timeout => 1)
|
326
|
-
info.instance_variable_set :@instances, redis_instances
|
327
|
-
redis_instances.each{|redis| info.send("#{redis.role}s") << redis }
|
328
|
-
info
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
class RedisConfigurationServerSystemNotificationTest < Minitest::Test
|
333
|
-
def setup
|
334
|
-
Beetle.config.redis_configuration_client_ids = "rc-client-1,rc-client-2"
|
335
|
-
@server = RedisConfigurationServer.new
|
336
|
-
@server.stubs(:beetle).returns(stub(:publish))
|
337
|
-
EventMachine.stubs(:add_timer).yields
|
338
|
-
end
|
339
|
-
|
340
|
-
test "should send a system notification when receiving pong message from unknown client" do
|
341
|
-
payload = {"id" => "unknown-client", "token" => @server.current_token}
|
342
|
-
msg = "Received pong message from unknown id 'unknown-client'"
|
343
|
-
@server.beetle.expects(:publish).with(:system_notification, ({:message => msg}).to_json)
|
344
|
-
@server.pong(payload)
|
345
|
-
assert @server.unknown_client_ids.include?("unknown-client")
|
346
|
-
end
|
347
|
-
|
348
|
-
test "should send a system notification when receiving client_started message from unknown client" do
|
349
|
-
payload = {"id" => "unknown-client"}
|
350
|
-
msg = "Received client_started message from unknown id 'unknown-client'"
|
351
|
-
@server.beetle.expects(:publish).with(:system_notification, ({:message => msg}).to_json)
|
352
|
-
@server.client_started(payload)
|
353
|
-
assert @server.unknown_client_ids.include?("unknown-client")
|
354
|
-
end
|
355
|
-
|
356
|
-
test "should not send a system notification when receiving a client started message from a known client" do
|
357
|
-
payload = {"id" => "rc-client-1"}
|
358
|
-
@server.beetle.expects(:publish).never
|
359
|
-
@server.expects(:add_unknown_client_id).never
|
360
|
-
@server.client_started(payload)
|
361
|
-
assert @server.clients_last_seen.include?("rc-client-1")
|
362
|
-
end
|
363
|
-
|
364
|
-
test "should send a system notification when receiving heartbeat message from unknown client" do
|
365
|
-
payload = {"id" => "unknown-client"}
|
366
|
-
msg = "Received heartbeat message from unknown id 'unknown-client'"
|
367
|
-
@server.beetle.expects(:publish).with(:system_notification, ({:message => msg}).to_json)
|
368
|
-
@server.heartbeat(payload)
|
369
|
-
assert @server.unknown_client_ids.include?("unknown-client")
|
370
|
-
end
|
371
|
-
|
372
|
-
test "should not send a system notification when receiving a heartbeat message from a known client" do
|
373
|
-
payload = {"id" => "rc-client-1"}
|
374
|
-
@server.beetle.expects(:publish).never
|
375
|
-
@server.expects(:add_unknown_client_id).never
|
376
|
-
@server.heartbeat(payload)
|
377
|
-
assert @server.clients_last_seen.include?("rc-client-1")
|
378
|
-
end
|
379
|
-
|
380
|
-
end
|
381
|
-
end
|