villein 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/villein/client.rb +28 -6
- data/lib/villein/version.rb +1 -1
- data/spec/client_spec.rb +121 -24
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f55592c52186b2368ce3cdee25bc3726321ab5b
|
4
|
+
data.tar.gz: 6f20e0f243da17e2c400d1207069fe796a2022f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 202eda9a335d1239cb69f025c9239d715ca566cc710e8e2a0239bf42e1b2542b90cfea5948b65b08442770fe373b5abb2c32dbd459ca4018f8a0428f916e4f42
|
7
|
+
data.tar.gz: 320efc986bf0c185db5ce68dcecb296a5e5a4a9b97204927a61ba42c7b90f02d283150e2af9776d16555493de324dea15bc5b61c28e30f703bcc030ed8c2a5f8
|
data/lib/villein/client.rb
CHANGED
@@ -6,6 +6,19 @@ module Villein
|
|
6
6
|
# Villein::Client allows you to order existing serf agent.
|
7
7
|
# You will need RPC address and agent name to command.
|
8
8
|
class Client
|
9
|
+
|
10
|
+
##
|
11
|
+
# for serf command failures
|
12
|
+
class SerfError < Exception; end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Error for the given argument exceeds the limit of serf when setting tags and sending events.
|
16
|
+
class LengthExceedsLimitError < SerfError; end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Error for connection failures
|
20
|
+
class SerfConnectionError < SerfError; end
|
21
|
+
|
9
22
|
def initialize(rpc_addr, name: nil, serf: 'serf', silence: true)
|
10
23
|
@rpc_addr = rpc_addr
|
11
24
|
@name = name
|
@@ -56,7 +69,7 @@ module Villein
|
|
56
69
|
options.push('-tag', "#{tag}=#{val}")
|
57
70
|
end
|
58
71
|
|
59
|
-
json =
|
72
|
+
json = call_serf('members', *options)
|
60
73
|
response = JSON.parse(json)
|
61
74
|
|
62
75
|
response["members"]
|
@@ -94,14 +107,23 @@ module Villein
|
|
94
107
|
private
|
95
108
|
|
96
109
|
def call_serf(cmd, *args)
|
97
|
-
|
110
|
+
status, out = IO.popen([@serf, cmd, "-rpc-addr=#{rpc_addr}", *args, err: [:child, :out]], 'r') do |io|
|
111
|
+
_, s = Process.waitpid2(io.pid)
|
112
|
+
[s, io.read]
|
113
|
+
end
|
98
114
|
|
99
|
-
|
100
|
-
|
101
|
-
|
115
|
+
unless status.success?
|
116
|
+
case out
|
117
|
+
when /^Error connecting to Serf agent:/
|
118
|
+
raise SerfConnectionError, out.chomp
|
119
|
+
when /exceeds limit of \d+ bytes$/
|
120
|
+
raise LengthExceedsLimitError, out.chomp
|
121
|
+
else
|
122
|
+
raise SerfError, out.chomp
|
123
|
+
end
|
102
124
|
end
|
103
125
|
|
104
|
-
|
126
|
+
out
|
105
127
|
end
|
106
128
|
end
|
107
129
|
end
|
data/lib/villein/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -5,58 +5,132 @@ describe Villein::Client do
|
|
5
5
|
let(:name) { 'the-node' }
|
6
6
|
subject(:client) { described_class.new('x.x.x.x:nnnn', name: name) }
|
7
7
|
|
8
|
-
def expect_serf(cmd, *args,
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def expect_serf(cmd, *args, success: true, message: '')
|
9
|
+
if [cmd, *args].compact.empty?
|
10
|
+
expect(IO).to receive(:popen) \
|
11
|
+
.with(any_args)
|
12
|
+
.and_yield(double('io', read: message, pid: 727272))
|
13
|
+
|
14
|
+
else
|
15
|
+
expect(IO).to receive(:popen) \
|
16
|
+
.with(['serf', cmd, '-rpc-addr=x.x.x.x:nnnn', *args,
|
17
|
+
err: [:child, :out]],
|
18
|
+
'r') \
|
19
|
+
.and_yield(double('io', read: message, pid: 727272))
|
20
|
+
end
|
21
|
+
|
22
|
+
status = double('proc-status', pid: 727272, success?: success)
|
23
|
+
|
24
|
+
allow(Process).to receive(:waitpid2).with(727272).and_return([727272, status])
|
25
|
+
end
|
26
|
+
|
27
|
+
shared_examples "failure cases" do
|
28
|
+
context "when command failed" do
|
29
|
+
it "raises error" do
|
30
|
+
expect_serf(nil, success: false, message: 'err')
|
31
|
+
|
32
|
+
expect {
|
33
|
+
subject
|
34
|
+
}.to raise_error(Villein::Client::SerfError, 'err')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when connection failed" do
|
39
|
+
it "raises error" do
|
40
|
+
expect_serf(nil,
|
41
|
+
success: false,
|
42
|
+
message: 'Error connecting to Serf agent: dial tcp x.x.x.x:nnnn: connection refused')
|
43
|
+
|
44
|
+
expect {
|
45
|
+
subject
|
46
|
+
}.to raise_error(
|
47
|
+
Villein::Client::SerfConnectionError,
|
48
|
+
'Error connecting to Serf agent: dial tcp x.x.x.x:nnnn: connection refused')
|
49
|
+
end
|
50
|
+
end
|
12
51
|
end
|
13
52
|
|
14
53
|
describe "#event" do
|
54
|
+
subject { client.event('test', 'payload') }
|
55
|
+
|
15
56
|
it "sends user event" do
|
16
57
|
expect_serf('event', 'test', 'payload')
|
17
58
|
|
18
|
-
|
59
|
+
subject
|
19
60
|
end
|
20
61
|
|
21
62
|
context "with coalesce=false" do
|
63
|
+
subject { client.event('test', 'payload', coalesce: false) }
|
64
|
+
|
22
65
|
it "sends user event with the option" do
|
23
66
|
expect_serf('event', '-coalesce=false', 'test', 'payload')
|
24
67
|
|
25
|
-
|
68
|
+
subject
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
include_examples "failure cases"
|
73
|
+
|
74
|
+
context "when length exceeds limit" do
|
75
|
+
it "raises error" do
|
76
|
+
expect_serf('event', 'test', 'payload',
|
77
|
+
success: false,
|
78
|
+
message: 'Error sending event: user event exceeds limit of 256 bytes')
|
79
|
+
|
80
|
+
expect {
|
81
|
+
subject
|
82
|
+
}.to raise_error(
|
83
|
+
Villein::Client::LengthExceedsLimitError,
|
84
|
+
'Error sending event: user event exceeds limit of 256 bytes')
|
26
85
|
end
|
27
86
|
end
|
87
|
+
|
28
88
|
end
|
29
89
|
|
30
90
|
describe "#join" do
|
91
|
+
subject { client.join('y.y.y.y:nnnn') }
|
92
|
+
|
31
93
|
it "attempts to join another node" do
|
32
94
|
expect_serf('join', 'y.y.y.y:nnnn')
|
33
95
|
|
34
|
-
|
96
|
+
subject
|
35
97
|
end
|
36
98
|
|
37
99
|
context "with replay=true" do
|
100
|
+
subject { client.join('y.y.y.y:nnnn', replay: true) }
|
101
|
+
|
38
102
|
it "attempts to join another node with replaying" do
|
39
103
|
expect_serf('join', '-replay', 'y.y.y.y:nnnn')
|
40
104
|
|
41
|
-
|
105
|
+
subject
|
42
106
|
end
|
43
107
|
end
|
108
|
+
|
109
|
+
include_examples "failure cases"
|
44
110
|
end
|
45
111
|
|
46
112
|
describe "#leave" do
|
113
|
+
subject { client.leave }
|
114
|
+
|
47
115
|
it "attempts to leave from cluster" do
|
48
116
|
expect_serf('leave')
|
49
117
|
|
50
|
-
|
118
|
+
subject
|
51
119
|
end
|
120
|
+
|
121
|
+
include_examples "failure cases"
|
52
122
|
end
|
53
123
|
|
54
124
|
describe "#force_leave" do
|
125
|
+
subject { client.force_leave('the-node') }
|
126
|
+
|
55
127
|
it "attempts to remove member forcely" do
|
56
128
|
expect_serf('force-leave', 'the-node')
|
57
129
|
|
58
|
-
|
130
|
+
subject
|
59
131
|
end
|
132
|
+
|
133
|
+
include_examples "failure cases"
|
60
134
|
end
|
61
135
|
|
62
136
|
describe "#members" do
|
@@ -65,18 +139,18 @@ describe Villein::Client do
|
|
65
139
|
"tags":{"key":"val"},"status":"alive","protocol":{"max":4,"min":2,"version":4}}]}
|
66
140
|
EOJ
|
67
141
|
|
142
|
+
subject(:members) { client.members }
|
143
|
+
|
68
144
|
it "returns member list" do
|
69
|
-
|
70
|
-
.and_yield(double('io', read: json))
|
145
|
+
expect_serf('members', '-format', 'json', message: json)
|
71
146
|
|
72
|
-
expect(
|
73
|
-
expect(
|
147
|
+
expect(members).to be_a_kind_of(Array)
|
148
|
+
expect(members[0]["name"]).to eq "the-node"
|
74
149
|
end
|
75
150
|
|
76
151
|
context "with status filter" do
|
77
152
|
it "returns member list" do
|
78
|
-
|
79
|
-
.and_yield(double('io', read: json))
|
153
|
+
expect_serf('members', '-format', 'json', '-status', 'alive', message: json)
|
80
154
|
|
81
155
|
client.members(status: :alive)
|
82
156
|
end
|
@@ -84,8 +158,7 @@ describe Villein::Client do
|
|
84
158
|
|
85
159
|
context "with name filter" do
|
86
160
|
it "returns member list" do
|
87
|
-
|
88
|
-
.and_yield(double('io', read: json))
|
161
|
+
expect_serf('members', '-format', 'json', '-name', 'node', message: json)
|
89
162
|
|
90
163
|
client.members(name: 'node')
|
91
164
|
end
|
@@ -93,12 +166,13 @@ describe Villein::Client do
|
|
93
166
|
|
94
167
|
context "with tag filter" do
|
95
168
|
it "returns member list" do
|
96
|
-
|
97
|
-
.and_yield(double('io', read: json))
|
169
|
+
expect_serf('members', *%w(-format json -tag a=1 -tag b=2), message: json)
|
98
170
|
|
99
171
|
client.members(tags: {a: '1', b: '2'})
|
100
172
|
end
|
101
173
|
end
|
174
|
+
|
175
|
+
include_examples "failure cases"
|
102
176
|
end
|
103
177
|
|
104
178
|
describe "#tags" do
|
@@ -117,19 +191,41 @@ describe Villein::Client do
|
|
117
191
|
end
|
118
192
|
|
119
193
|
describe "#set_tag" do
|
194
|
+
subject { client.set_tag('newkey', 'newval') }
|
195
|
+
|
120
196
|
it "sets tag" do
|
121
197
|
expect_serf('tags', '-set', 'newkey=newval')
|
122
198
|
|
123
|
-
|
199
|
+
subject
|
200
|
+
end
|
201
|
+
|
202
|
+
include_examples "failure cases"
|
203
|
+
|
204
|
+
context "when length exceeds limit" do
|
205
|
+
it "raises error" do
|
206
|
+
expect_serf('tags', '-set', 'newkey=newval',
|
207
|
+
success: false,
|
208
|
+
message: 'Error setting tags: Encoded length of tags exceeds limit of 512 bytes')
|
209
|
+
|
210
|
+
expect {
|
211
|
+
client.set_tag('newkey', 'newval')
|
212
|
+
}.to raise_error(
|
213
|
+
Villein::Client::LengthExceedsLimitError,
|
214
|
+
'Error setting tags: Encoded length of tags exceeds limit of 512 bytes')
|
215
|
+
end
|
124
216
|
end
|
125
217
|
end
|
126
218
|
|
127
219
|
describe "#delete_tag" do
|
220
|
+
subject { client.delete_tag('newkey') }
|
221
|
+
|
128
222
|
it "deletes tag" do
|
129
223
|
expect_serf('tags', '-delete', 'newkey')
|
130
224
|
|
131
|
-
|
225
|
+
subject
|
132
226
|
end
|
227
|
+
|
228
|
+
include_examples "failure cases"
|
133
229
|
end
|
134
230
|
|
135
231
|
describe "#get_tags" do
|
@@ -141,8 +237,7 @@ describe Villein::Client do
|
|
141
237
|
"tags":{"key":"val"},"status":"alive","protocol":{"max":4,"min":2,"version":4}}]}
|
142
238
|
EOJ
|
143
239
|
|
144
|
-
|
145
|
-
.and_yield(double('io', read: json))
|
240
|
+
expect_serf('members', *%w(-format json -name the-node), message: json)
|
146
241
|
|
147
242
|
expect(tags).to be_a_kind_of(Hash)
|
148
243
|
expect(tags['key']).to eq 'val'
|
@@ -155,6 +250,8 @@ describe Villein::Client do
|
|
155
250
|
expect { tags }.to raise_error
|
156
251
|
end
|
157
252
|
end
|
253
|
+
|
254
|
+
include_examples "failure cases"
|
158
255
|
end
|
159
256
|
end
|
160
257
|
|