twirl 0.1.0
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/.gitignore +17 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +75 -0
- data/Rakefile +1 -0
- data/examples/server.rb +37 -0
- data/lib/twirl.rb +8 -0
- data/lib/twirl/cluster.rb +317 -0
- data/lib/twirl/instrumentation/log_subscriber.rb +35 -0
- data/lib/twirl/instrumentation/statsd.rb +6 -0
- data/lib/twirl/instrumentation/statsd_subscriber.rb +28 -0
- data/lib/twirl/instrumentation/subscriber.rb +60 -0
- data/lib/twirl/instrumenters/memory.rb +26 -0
- data/lib/twirl/instrumenters/noop.rb +9 -0
- data/lib/twirl/item.rb +49 -0
- data/lib/twirl/server.rb +253 -0
- data/lib/twirl/version.rb +3 -0
- data/script/bootstrap +21 -0
- data/script/kestrel +34 -0
- data/script/release +42 -0
- data/script/test +25 -0
- data/script/watch +29 -0
- data/test/cluster_test.rb +469 -0
- data/test/helper.rb +65 -0
- data/test/instrumentation/log_subscriber_test.rb +51 -0
- data/test/instrumentation/statsd_test.rb +173 -0
- data/test/instrumenters/memory_test.rb +22 -0
- data/test/instrumenters/noop_test.rb +16 -0
- data/test/integration/cluster_test.rb +199 -0
- data/test/item_test.rb +43 -0
- data/test/support/fake_udp_socket.rb +27 -0
- data/test/twirl_test.rb +11 -0
- data/twirl.gemspec +23 -0
- metadata +121 -0
data/test/helper.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require_relative "support/fake_udp_socket"
|
3
|
+
require "twirl/instrumenters/noop"
|
4
|
+
|
5
|
+
module ClusterTestHelpers
|
6
|
+
def build(what, *args)
|
7
|
+
send "build_#{what}", *args
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def build_item(key, value, client, instrumenter = nil)
|
13
|
+
Twirl::Item.new(key, value, client, instrumenter)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Builds a cluster that will connect to what script/kestrel starts.
|
17
|
+
def build_cluster(options = {})
|
18
|
+
clients = [
|
19
|
+
KJess::Client.new(host: "localhost", port: 9444),
|
20
|
+
KJess::Client.new(host: "localhost", port: 9544),
|
21
|
+
]
|
22
|
+
queue_names = Array(options.delete(:queues))
|
23
|
+
Twirl::Cluster.new(clients, options).tap { |cluster|
|
24
|
+
queue_names.each { |queue_name|
|
25
|
+
cluster.each { |client|
|
26
|
+
client.flush queue_name
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_mock_cluster(options = {})
|
33
|
+
number_of_clients = options.delete(:number_of_clients) || 3
|
34
|
+
clients = number_of_clients.times.map { Minitest::Mock.new }
|
35
|
+
|
36
|
+
Twirl::Cluster.new clients, options
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module StatsdTestHelpers
|
41
|
+
def assert_timer(socket, metric)
|
42
|
+
regex = /#{Regexp.escape metric}\:\d+\|ms/
|
43
|
+
assert socket.buffer.detect { |op| op.first =~ regex },
|
44
|
+
"Timer #{metric} was not found in #{socket.buffer.inspect}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_counter(socket, metric)
|
48
|
+
assert socket.buffer.detect { |op| op.first == "#{metric}:1|c" },
|
49
|
+
"Counter #{metric} was not found in #{socket.buffer.inspect}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def assert_no_timer(socket, metric)
|
53
|
+
regex = /#{Regexp.escape metric}\:\d+\|ms/
|
54
|
+
assert_nil socket.buffer.detect { |op| op.first =~ regex },
|
55
|
+
"Timer #{metric} was found in #{socket.buffer.inspect}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def assert_no_counter(socket, metric)
|
59
|
+
assert_nil socket.buffer.detect { |op| op.first == "#{metric}:1|c" },
|
60
|
+
"Counter #{metric} was found in #{socket.buffer.inspect}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
Minitest::Test.send :include, ClusterTestHelpers
|
65
|
+
Minitest::Test.send :include, StatsdTestHelpers
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "logger"
|
3
|
+
require "twirl/instrumentation/log_subscriber"
|
4
|
+
|
5
|
+
class LogSubscriberInstrumentationTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@cluster = build(:cluster, {
|
8
|
+
instrumenter: ActiveSupport::Notifications,
|
9
|
+
queues: %w(testing),
|
10
|
+
})
|
11
|
+
@io = StringIO.new
|
12
|
+
logger = Logger.new(@io)
|
13
|
+
logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" }
|
14
|
+
Twirl::Instrumentation::LogSubscriber.logger = logger
|
15
|
+
end
|
16
|
+
|
17
|
+
def log
|
18
|
+
@io.string
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
Twirl::Instrumentation::LogSubscriber.logger = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_set
|
26
|
+
@cluster.set "testing", "data"
|
27
|
+
line = find_line("Twirl op(set)")
|
28
|
+
assert_match %r{queue_name=testing bytes=4}, line
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_get
|
32
|
+
@cluster.set "testing", "data"
|
33
|
+
@cluster.get "testing"
|
34
|
+
line = find_line("Twirl op(get)")
|
35
|
+
assert_match %r{queue_name=testing bytes=4}, line
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_reserve
|
39
|
+
@cluster.set "testing", "data"
|
40
|
+
@cluster.reserve "testing"
|
41
|
+
line = find_line("Twirl op(reserve)")
|
42
|
+
assert_match %r{queue_name=testing bytes=4}, line
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_line(str)
|
46
|
+
regex = /#{Regexp.escape(str)}/
|
47
|
+
lines = log.split("\n")
|
48
|
+
lines.detect { |line| line =~ regex } ||
|
49
|
+
raise("Could not find line matching #{str.inspect} in #{lines.inspect}")
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "twirl/instrumentation/statsd"
|
3
|
+
|
4
|
+
class StatsdInstrumentationTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
@statsd = Statsd.new
|
7
|
+
@socket = FakeUDPSocket.new
|
8
|
+
@cluster = build(:cluster, {
|
9
|
+
instrumenter: ActiveSupport::Notifications,
|
10
|
+
queues: %w(testing),
|
11
|
+
})
|
12
|
+
Thread.current[:statsd_socket] = @socket
|
13
|
+
Twirl::Instrumentation::StatsdSubscriber.client = @statsd
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
Thread.current[:statsd_socket] = nil
|
18
|
+
Twirl::Instrumentation::StatsdSubscriber.client = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_set
|
22
|
+
@cluster.set "testing", "data"
|
23
|
+
assert_timer @socket, "twirl.op_set"
|
24
|
+
assert_timer @socket, "twirl.queue_testing_op_set"
|
25
|
+
assert_counter @socket, "twirl.bytes_op_set"
|
26
|
+
assert_counter @socket, "twirl.bytes_queue_testing_op_set"
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_get
|
30
|
+
@cluster.set "testing", "data"
|
31
|
+
@cluster.get "testing"
|
32
|
+
assert_timer @socket, "twirl.op_get"
|
33
|
+
assert_timer @socket, "twirl.queue_testing_op_get"
|
34
|
+
assert_counter @socket, "twirl.bytes_op_get"
|
35
|
+
assert_counter @socket, "twirl.bytes_queue_testing_op_get"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_item_close
|
39
|
+
@cluster.set "testing", "data"
|
40
|
+
item = @cluster.reserve("testing")
|
41
|
+
item.close
|
42
|
+
assert_timer @socket, "twirl.op_item_close"
|
43
|
+
assert_timer @socket, "twirl.queue_testing_op_item_close"
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_item_abort
|
47
|
+
@cluster.set "testing", "data"
|
48
|
+
item = @cluster.reserve("testing")
|
49
|
+
item.abort
|
50
|
+
assert_timer @socket, "twirl.op_item_abort"
|
51
|
+
assert_timer @socket, "twirl.queue_testing_op_item_abort"
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_reserve
|
55
|
+
@cluster.set "testing", "data"
|
56
|
+
@cluster.reserve "testing"
|
57
|
+
assert_timer @socket, "twirl.op_reserve"
|
58
|
+
assert_timer @socket, "twirl.queue_testing_op_reserve"
|
59
|
+
assert_counter @socket, "twirl.bytes_op_reserve"
|
60
|
+
assert_counter @socket, "twirl.bytes_queue_testing_op_reserve"
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_peek
|
64
|
+
@cluster.set "testing", "data"
|
65
|
+
@cluster.peek "testing"
|
66
|
+
assert_timer @socket, "twirl.op_peek"
|
67
|
+
assert_timer @socket, "twirl.queue_testing_op_peek"
|
68
|
+
assert_counter @socket, "twirl.bytes_op_peek"
|
69
|
+
assert_counter @socket, "twirl.bytes_queue_testing_op_peek"
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_delete
|
73
|
+
@cluster.delete "testing"
|
74
|
+
assert_timer @socket, "twirl.op_delete"
|
75
|
+
assert_timer @socket, "twirl.queue_testing_op_delete"
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_flush
|
79
|
+
@cluster.flush "testing"
|
80
|
+
assert_timer @socket, "twirl.op_flush"
|
81
|
+
assert_timer @socket, "twirl.queue_testing_op_flush"
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_flush_all
|
85
|
+
@cluster.flush_all
|
86
|
+
assert_timer @socket, "twirl.op_flush_all"
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_version
|
90
|
+
@cluster.version
|
91
|
+
assert_timer @socket, "twirl.op_version"
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_ping
|
95
|
+
@cluster.ping
|
96
|
+
assert_timer @socket, "twirl.op_ping"
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_quit
|
100
|
+
@cluster.quit
|
101
|
+
assert_timer @socket, "twirl.op_quit"
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_stats
|
105
|
+
@cluster.stats
|
106
|
+
assert_timer @socket, "twirl.op_stats"
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_disconnect
|
110
|
+
@cluster.disconnect
|
111
|
+
assert_timer @socket, "twirl.op_disconnect"
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_rotate
|
115
|
+
cluster = build(:cluster, {
|
116
|
+
commands_per_client: 1,
|
117
|
+
instrumenter: ActiveSupport::Notifications,
|
118
|
+
})
|
119
|
+
|
120
|
+
# set data to avoid nil rotation
|
121
|
+
cluster[0].set "testing", "data"
|
122
|
+
cluster[1].set "testing", "data"
|
123
|
+
cluster.get("testing")
|
124
|
+
cluster.get("testing")
|
125
|
+
|
126
|
+
assert_counter @socket, "twirl.op_rotate"
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_get_nil_instruments_rotate
|
130
|
+
@cluster.get("testing")
|
131
|
+
@cluster.get("testing")
|
132
|
+
|
133
|
+
assert_counter @socket, "twirl.op_rotate"
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_get_retries_instrumented
|
137
|
+
@cluster.get("testing")
|
138
|
+
assert_no_timer @socket, "twirl.retries_op_get"
|
139
|
+
|
140
|
+
# force all clients to error
|
141
|
+
@cluster.each do |client|
|
142
|
+
def client.get(*args)
|
143
|
+
raise KJess::NetworkError
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
begin
|
148
|
+
@cluster.get("testing")
|
149
|
+
flunk "Should raise error and not get here."
|
150
|
+
rescue KJess::NetworkError
|
151
|
+
assert_counter @socket, "twirl.retries_op_get"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_set_retries_instrumented
|
156
|
+
@cluster.set("testing", "data")
|
157
|
+
assert_no_timer @socket, "twirl.retries_op_set"
|
158
|
+
|
159
|
+
# force all clients to error
|
160
|
+
@cluster.each do |client|
|
161
|
+
def client.set(*args)
|
162
|
+
raise KJess::NetworkError
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
begin
|
167
|
+
@cluster.set("testing", "data")
|
168
|
+
flunk "Should raise error and not get here."
|
169
|
+
rescue KJess::NetworkError
|
170
|
+
assert_counter @socket, "twirl.retries_op_set"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "twirl/instrumenters/memory"
|
3
|
+
|
4
|
+
class MemoryInstrumenterTest < Minitest::Test
|
5
|
+
def test_initialize
|
6
|
+
instrumentor = Twirl::Instrumenters::Memory.new
|
7
|
+
assert_equal [], instrumentor.events
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_instrument
|
11
|
+
instrumentor = Twirl::Instrumenters::Memory.new
|
12
|
+
name = 'user.signup'
|
13
|
+
payload = {:email => 'john@doe.com'}
|
14
|
+
block_result = :yielded
|
15
|
+
|
16
|
+
result = instrumentor.instrument(name, payload) { block_result }
|
17
|
+
assert_equal block_result, result
|
18
|
+
|
19
|
+
event = Twirl::Instrumenters::Memory::Event.new(name, payload, block_result)
|
20
|
+
assert_equal [event], instrumentor.events
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "twirl/instrumenters/noop"
|
3
|
+
|
4
|
+
class NoopInstrumenterTest < Minitest::Test
|
5
|
+
def test_instrument
|
6
|
+
yielded = false
|
7
|
+
Twirl::Instrumenters::Noop.instrument(:foo) { yielded = true }
|
8
|
+
assert yielded
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_instrument_with_payload
|
12
|
+
yielded = false
|
13
|
+
Twirl::Instrumenters::Noop.instrument(:foo, pay: :load) { yielded = true }
|
14
|
+
assert yielded
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "twirl/cluster"
|
3
|
+
|
4
|
+
class ClusterIntegrationTest < Minitest::Test
|
5
|
+
def test_set
|
6
|
+
cluster = build(:cluster, queues: %w(testing))
|
7
|
+
client = cluster[0]
|
8
|
+
cluster.set("testing", "data")
|
9
|
+
assert_equal "data", client.get("testing")
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_set_rotates
|
13
|
+
cluster = build(:cluster, commands_per_client: 1, queues: %w(testing))
|
14
|
+
client1 = cluster[0]
|
15
|
+
client2 = cluster[1]
|
16
|
+
cluster.set("testing", "data1")
|
17
|
+
cluster.set("testing", "data2")
|
18
|
+
cluster.set("testing", "data3")
|
19
|
+
cluster.set("testing", "data4")
|
20
|
+
|
21
|
+
results = []
|
22
|
+
assert_equal "data1", client1.get("testing")
|
23
|
+
assert_equal "data2", client2.get("testing")
|
24
|
+
assert_equal "data3", client1.get("testing")
|
25
|
+
assert_equal "data4", client2.get("testing")
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_get
|
29
|
+
cluster = build(:cluster, queues: %w(testing))
|
30
|
+
client1 = cluster[0]
|
31
|
+
client2 = cluster[1]
|
32
|
+
|
33
|
+
client1.set("testing", "data1")
|
34
|
+
client1.set("testing", "data2")
|
35
|
+
client2.set("testing", "data3")
|
36
|
+
|
37
|
+
results = []
|
38
|
+
results << cluster.get("testing")
|
39
|
+
results << cluster.get("testing")
|
40
|
+
results << cluster.get("testing")
|
41
|
+
results << cluster.get("testing")
|
42
|
+
results << cluster.get("testing")
|
43
|
+
|
44
|
+
assert_equal ["data1", "data2", nil, "data3", nil], results.map { |result| result.value if result }
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_get_when_item_reserved_raises_error
|
48
|
+
cluster = build(:cluster, queues: %w(testing))
|
49
|
+
client1 = cluster[0]
|
50
|
+
|
51
|
+
client1.set("testing", "data1")
|
52
|
+
cluster.get("testing", open: true)
|
53
|
+
|
54
|
+
assert_raises KJess::ClientError do
|
55
|
+
cluster.get("testing")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_reserve_with_item_close_and_item_abort
|
60
|
+
cluster = build(:cluster, queues: %w(testing))
|
61
|
+
client1 = cluster[0]
|
62
|
+
client2 = cluster[1]
|
63
|
+
|
64
|
+
client1.set("testing", "data1")
|
65
|
+
client2.set("testing", "data2")
|
66
|
+
|
67
|
+
item = cluster.reserve("testing")
|
68
|
+
assert_equal "data1", item.value
|
69
|
+
|
70
|
+
item.abort
|
71
|
+
item = cluster.reserve("testing")
|
72
|
+
assert_equal "data1", item.value
|
73
|
+
|
74
|
+
item.close
|
75
|
+
cluster.reserve("testing") # => nil, then rotate
|
76
|
+
item = cluster.reserve("testing")
|
77
|
+
assert_equal "data2", item.value
|
78
|
+
|
79
|
+
cluster.rotate_for_next_op # force rotation to client1
|
80
|
+
assert_nil cluster.reserve("testing") # client1 returns nil
|
81
|
+
item.close # close item hopefully with client2
|
82
|
+
assert_nil client2.get("testing") # make sure that client2 queue is empty
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_peek
|
86
|
+
cluster = build(:cluster, queues: %w(testing))
|
87
|
+
client1 = cluster[0]
|
88
|
+
client2 = cluster[1]
|
89
|
+
|
90
|
+
client1.set("testing", "data")
|
91
|
+
|
92
|
+
item = Twirl::Item.new("testing", "data", client1)
|
93
|
+
assert_equal item, cluster.peek("testing")
|
94
|
+
assert_equal "data", client1.get("testing")
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_peek_with_no_items
|
98
|
+
cluster = build(:cluster, queues: %w(testing))
|
99
|
+
assert_nil cluster.peek("testing")
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_version
|
103
|
+
cluster = build(:cluster)
|
104
|
+
expected = {
|
105
|
+
"localhost:9444" => "2.4.1",
|
106
|
+
"localhost:9544" => "2.4.1",
|
107
|
+
}
|
108
|
+
|
109
|
+
assert_equal expected, cluster.version
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_flush
|
113
|
+
cluster = build(:cluster, queues: %w(testing))
|
114
|
+
cluster.each do |client|
|
115
|
+
client.set("testing", "data")
|
116
|
+
end
|
117
|
+
cluster.flush("testing")
|
118
|
+
|
119
|
+
cluster.each do |client|
|
120
|
+
assert_nil client.get("testing")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_flush
|
125
|
+
cluster = build(:cluster, queues: %w(testing))
|
126
|
+
cluster.each { |client| client.set("testing", "data") }
|
127
|
+
cluster.flush("testing")
|
128
|
+
|
129
|
+
cluster.each do |client|
|
130
|
+
assert_nil client.get("testing")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_flush_all
|
135
|
+
cluster = build(:cluster, queues: %w(testing))
|
136
|
+
cluster.each { |client| client.set("testing", "data") }
|
137
|
+
cluster.flush_all
|
138
|
+
|
139
|
+
cluster.each do |client|
|
140
|
+
assert_nil client.get("testing")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_disconnect
|
145
|
+
cluster = build(:cluster)
|
146
|
+
cluster.each(&:ping)
|
147
|
+
expected = [true] * cluster.size
|
148
|
+
assert_equal expected, cluster.map(&:connected?)
|
149
|
+
cluster.disconnect
|
150
|
+
expected = [false] * cluster.size
|
151
|
+
assert_equal expected, cluster.map(&:connected?)
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_quit
|
155
|
+
cluster = build(:cluster)
|
156
|
+
cluster.each(&:ping)
|
157
|
+
expected = [true] * cluster.size
|
158
|
+
assert_equal expected, cluster.map(&:connected?)
|
159
|
+
cluster.quit
|
160
|
+
expected = [false] * cluster.size
|
161
|
+
assert_equal expected, cluster.map(&:connected?)
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_delete
|
165
|
+
cluster = build(:cluster)
|
166
|
+
cluster.each do |client|
|
167
|
+
client.delete("testing")
|
168
|
+
client.set("testing", "data")
|
169
|
+
assert_instance_of Hash, client.queue_stats("testing")
|
170
|
+
end
|
171
|
+
cluster.delete("testing")
|
172
|
+
cluster.each do |client|
|
173
|
+
assert_nil client.queue_stats("testing")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_ping
|
178
|
+
cluster = build(:cluster)
|
179
|
+
expected = {
|
180
|
+
"localhost:9444" => true,
|
181
|
+
"localhost:9544" => true,
|
182
|
+
}
|
183
|
+
|
184
|
+
assert_equal expected, cluster.ping
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_stats
|
188
|
+
cluster = build(:cluster)
|
189
|
+
result = cluster.stats
|
190
|
+
assert_equal [
|
191
|
+
"localhost:9444",
|
192
|
+
"localhost:9544",
|
193
|
+
], result.keys.sort
|
194
|
+
|
195
|
+
result.values.each do |value|
|
196
|
+
assert_instance_of Hash, value
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|