villein 0.0.2 → 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.
- 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
|
|