etcd-rb 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/lib/etcd/client/failover.rb +6 -11
- data/lib/etcd/client/observing.rb +2 -2
- data/lib/etcd/client/protocol.rb +40 -30
- data/lib/etcd/cluster.rb +6 -12
- data/lib/etcd/constants.rb +4 -4
- data/lib/etcd/heartbeat.rb +2 -2
- data/lib/etcd/loggable.rb +1 -1
- data/lib/etcd/node.rb +27 -10
- data/lib/etcd/observer.rb +3 -2
- data/lib/etcd/version.rb +2 -2
- data/spec/etcd/client_spec.rb +51 -49
- data/spec/etcd/cluster_spec.rb +22 -32
- data/spec/etcd/node_spec.rb +24 -12
- data/spec/etcd/observer_spec.rb +48 -48
- data/spec/integration/etcd_spec.rb +29 -16
- data/spec/resources/cluster_controller.rb +2 -2
- data/spec/support/client_helper.rb +6 -2
- data/spec/support/cluster_helper.rb +28 -30
- metadata +3 -3
data/spec/etcd/cluster_spec.rb
CHANGED
@@ -15,35 +15,24 @@ module Etcd
|
|
15
15
|
it "returns parsed data" do
|
16
16
|
with_stubbed_status(cluster_uri) do
|
17
17
|
res = Etcd::Cluster.cluster_status(cluster_uri)
|
18
|
-
res[0][:name].should
|
18
|
+
res[0][:name].should eq("node1")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
describe '#parse_cluster_status' do
|
24
|
-
it "works with correct parsed json" do
|
25
|
-
res = Etcd::Cluster.parse_cluster_status(status_data)
|
26
|
-
res[0].should == {
|
27
|
-
:name => "node1",
|
28
|
-
:raft => "http://127.0.0.1:7001",
|
29
|
-
:etcd => "http://127.0.0.1:4001",
|
30
|
-
}
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
23
|
describe '#nodes_from_uri' do
|
35
24
|
it "returns node instances created from uri" do
|
36
25
|
with_stubbed_status(cluster_uri) do
|
37
26
|
nodes = Etcd::Cluster.nodes_from_uri(cluster_uri)
|
38
|
-
nodes.size.should
|
39
|
-
nodes.first.class.should
|
27
|
+
nodes.size.should eq(3)
|
28
|
+
nodes.first.class.should eq(Etcd::Node)
|
40
29
|
end
|
41
30
|
end
|
42
31
|
|
43
32
|
it "but those instances have no real status yet" do
|
44
33
|
with_stubbed_status(cluster_uri) do
|
45
34
|
nodes = Etcd::Cluster.nodes_from_uri(cluster_uri)
|
46
|
-
nodes.size.should
|
35
|
+
nodes.size.should eq(3)
|
47
36
|
nodes.first.status == :unknown
|
48
37
|
end
|
49
38
|
end
|
@@ -55,9 +44,10 @@ module Etcd
|
|
55
44
|
with_stubbed_status(cluster_uri) do
|
56
45
|
with_stubbed_leaders(healthy_cluster_config) do
|
57
46
|
cluster = Etcd::Cluster.init_from_uris(cluster_uri)
|
47
|
+
puts "nodes: #{cluster}"
|
58
48
|
nodes = cluster.nodes
|
59
|
-
nodes.size.should
|
60
|
-
nodes.map{|x| x.status}.uniq.should
|
49
|
+
nodes.size.should eq(3)
|
50
|
+
nodes.map{|x| x.status}.uniq.should eq([:running])
|
61
51
|
end
|
62
52
|
end
|
63
53
|
end
|
@@ -67,7 +57,7 @@ module Etcd
|
|
67
57
|
with_stubbed_leaders(healthy_cluster_config) do
|
68
58
|
cluster = Etcd::Cluster.init_from_uris(cluster_uri)
|
69
59
|
leader = cluster.leader
|
70
|
-
leader.
|
60
|
+
expect(leader.client_urls.first).to eq(cluster_uri)
|
71
61
|
end
|
72
62
|
end
|
73
63
|
end
|
@@ -80,8 +70,8 @@ module Etcd
|
|
80
70
|
with_stubbed_leaders(one_down_cluster_config) do
|
81
71
|
cluster = Etcd::Cluster.init_from_uris(cluster_uri)
|
82
72
|
nodes = cluster.nodes
|
83
|
-
nodes.size.should
|
84
|
-
nodes.map{|x| x.status}.uniq.should
|
73
|
+
nodes.size.should eq(3)
|
74
|
+
nodes.map{|x| x.status}.uniq.should eq([:running, :down])
|
85
75
|
end
|
86
76
|
end
|
87
77
|
end
|
@@ -93,7 +83,7 @@ module Etcd
|
|
93
83
|
describe '#new' do
|
94
84
|
it "will not request any info on initialization" do
|
95
85
|
cluster = Etcd::Cluster.new(cluster_uri)
|
96
|
-
WebMock.should_not have_requested(:get, "http://127.0.0.1:4001/
|
86
|
+
WebMock.should_not have_requested(:get, "http://127.0.0.1:4001/v2/members/")
|
97
87
|
end
|
98
88
|
end
|
99
89
|
|
@@ -103,7 +93,7 @@ module Etcd
|
|
103
93
|
with_stubbed_leaders(healthy_cluster_config) do
|
104
94
|
cluster = Etcd::Cluster.new(cluster_uri)
|
105
95
|
nodes = cluster.nodes
|
106
|
-
nodes.size.should
|
96
|
+
nodes.size.should eq(3)
|
107
97
|
end
|
108
98
|
end
|
109
99
|
end
|
@@ -113,13 +103,13 @@ module Etcd
|
|
113
103
|
with_stubbed_leaders(healthy_cluster_config) do
|
114
104
|
cluster = Etcd::Cluster.new(cluster_uri)
|
115
105
|
nodes = cluster.nodes
|
116
|
-
nodes.map{|x| x.status}.uniq.should
|
106
|
+
nodes.map{|x| x.status}.uniq.should eq([:running])
|
117
107
|
with_stubbed_leaders(one_down_cluster_config) do
|
118
108
|
nodes = cluster.nodes
|
119
109
|
nodes.map{|x| x.status}.uniq.should_not == [:running, :down]
|
120
110
|
# now update for real
|
121
111
|
nodes = cluster.update_status
|
122
|
-
nodes.map{|x| x.status}.uniq.should
|
112
|
+
nodes.map{|x| x.status}.uniq.should eq([:running, :down])
|
123
113
|
end
|
124
114
|
end
|
125
115
|
end
|
@@ -133,11 +123,11 @@ module Etcd
|
|
133
123
|
with_stubbed_leaders(healthy_cluster_config) do
|
134
124
|
cluster = Etcd::Cluster.new(cluster_uri)
|
135
125
|
nodes = cluster.update_status
|
136
|
-
nodes.size.should
|
137
|
-
nodes.map{|x| x.status}.uniq.should
|
126
|
+
nodes.size.should eq(3)
|
127
|
+
nodes.map{|x| x.status}.uniq.should eq([:running])
|
138
128
|
with_stubbed_leaders(one_down_cluster_config) do
|
139
129
|
nodes = cluster.update_status
|
140
|
-
nodes.map{|x| x.status}.uniq.should
|
130
|
+
nodes.map{|x| x.status}.uniq.should eq([:running, :down])
|
141
131
|
end
|
142
132
|
end
|
143
133
|
end
|
@@ -151,8 +141,8 @@ module Etcd
|
|
151
141
|
with_stubbed_leaders(healthy_cluster_config) do
|
152
142
|
cluster = Etcd::Cluster.new(cluster_uri)
|
153
143
|
leader = cluster.leader
|
154
|
-
leader.
|
155
|
-
leader.is_leader.
|
144
|
+
expect(leader.client_urls.first).to eq(cluster_uri)
|
145
|
+
expect(leader.is_leader).to eq(true)
|
156
146
|
end
|
157
147
|
end
|
158
148
|
end
|
@@ -161,10 +151,10 @@ module Etcd
|
|
161
151
|
with_stubbed_status(cluster_uri) do
|
162
152
|
with_stubbed_leaders(healthy_cluster_config) do
|
163
153
|
cluster = Etcd::Cluster.new(cluster_uri)
|
164
|
-
cluster.leader.
|
154
|
+
expect(cluster.leader.client_urls.first).to eq(cluster_uri)
|
165
155
|
with_stubbed_leaders(healthy_cluster_changed_leader_config) do
|
166
|
-
nodes
|
167
|
-
cluster.leader.
|
156
|
+
nodes = cluster.update_status
|
157
|
+
expect(cluster.leader.client_urls.first).to eq("http://127.0.0.1:4002")
|
168
158
|
end
|
169
159
|
end
|
170
160
|
end
|
data/spec/etcd/node_spec.rb
CHANGED
@@ -1,23 +1,35 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
|
5
4
|
module Etcd
|
6
5
|
describe Node do
|
7
6
|
|
7
|
+
let :node_data do
|
8
|
+
[
|
9
|
+
{"id" => "14306b09b8d69fc4","name" => "node1","peerURLs"=> ["http://127.0.0.1:7001"],"clientURLs" => ["http://127.0.0.1:4001"]},
|
10
|
+
{"id" => "d2356cd527a56a4","name" => "node2","peerURLs" => ["http://127.0.0.1:7002"],"clientURLs" => ["http://127.0.0.1:4002"]}
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
8
14
|
def default_node(opts = {})
|
9
|
-
|
10
|
-
Etcd::Node.new(
|
15
|
+
data = Etcd::Node.parse_node_data(node_data[0])
|
16
|
+
Etcd::Node.new(data.merge(opts))
|
11
17
|
end
|
12
18
|
|
13
19
|
describe '#initialize' do
|
14
20
|
it "works with all required parameters" do
|
15
|
-
default_node({}).should_not
|
21
|
+
default_node({}).should_not be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "raises if :client_urls is missing" do
|
25
|
+
expect {
|
26
|
+
default_node({:client_urls => nil})
|
27
|
+
}.to raise_error(ArgumentError)
|
16
28
|
end
|
17
29
|
|
18
|
-
it "raises if :
|
30
|
+
it "raises if :id is missing" do
|
19
31
|
expect {
|
20
|
-
default_node({:
|
32
|
+
default_node({:id => nil})
|
21
33
|
}.to raise_error(ArgumentError)
|
22
34
|
end
|
23
35
|
end
|
@@ -25,31 +37,31 @@ module Etcd
|
|
25
37
|
describe '#update_status' do
|
26
38
|
it "sets status :running if alive" do
|
27
39
|
node = default_node
|
28
|
-
stub_request(:get, node.leader_uri).to_return(body: node.
|
40
|
+
stub_request(:get, node.leader_uri).to_return(body: node.to_json)
|
29
41
|
node.update_status
|
30
|
-
node.status.should
|
42
|
+
node.status.should eq(:running)
|
31
43
|
end
|
32
44
|
|
33
45
|
it "sets status :down if down" do
|
34
46
|
node = default_node
|
35
47
|
stub_request(:get, node.leader_uri).to_timeout
|
36
48
|
node.update_status
|
37
|
-
node.status.should
|
49
|
+
node.status.should eq(:down)
|
38
50
|
end
|
39
51
|
|
40
52
|
it "marks leader-flag if leader" do
|
41
53
|
node = default_node
|
42
|
-
stub_request(:get, node.leader_uri).to_return(body: node.
|
54
|
+
stub_request(:get, node.leader_uri).to_return(body: node.to_json)
|
43
55
|
node.update_status
|
44
56
|
node.is_leader.should eq(true)
|
45
57
|
end
|
46
58
|
|
47
59
|
it "marks leader-flag as :false if leader looses leadership" do
|
48
60
|
node = default_node
|
49
|
-
stub_request(:get, node.leader_uri).to_return(body: node.
|
61
|
+
stub_request(:get, node.leader_uri).to_return(body: node.to_json)
|
50
62
|
node.update_status
|
51
63
|
node.is_leader.should eq(true)
|
52
|
-
stub_request(:get, node.leader_uri).to_return(body:
|
64
|
+
stub_request(:get, node.leader_uri).to_return(body: node_data[1].to_json)
|
53
65
|
node.update_status
|
54
66
|
node.is_leader.should eq(false)
|
55
67
|
end
|
data/spec/etcd/observer_spec.rb
CHANGED
@@ -7,7 +7,7 @@ module Etcd
|
|
7
7
|
include ClientHelper
|
8
8
|
|
9
9
|
def base_uri
|
10
|
-
"http://127.0.0.1:4001/
|
10
|
+
"http://127.0.0.1:4001/v2"
|
11
11
|
end
|
12
12
|
|
13
13
|
let :client do
|
@@ -16,95 +16,95 @@ module Etcd
|
|
16
16
|
|
17
17
|
describe '#watch' do
|
18
18
|
it 'sends a GET request for a watch of a key prefix' do
|
19
|
-
stub_request(:get, "#{base_uri}/
|
19
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {wait: 'true'}).to_return(body: MultiJson.dump({}))
|
20
20
|
client.watch('/foo') { }
|
21
|
-
WebMock.should have_requested(:get, "#{base_uri}/
|
21
|
+
WebMock.should have_requested(:get, "#{base_uri}/keys/foo").with(query: {wait: 'true'})
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'sends a GET request for a watch of a key prefix from a specified index' do
|
25
|
-
stub_request(:
|
25
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true', 'index' => 3}).to_return(body: MultiJson.dump({}))
|
26
26
|
client.watch('/foo', index: 3) { }
|
27
|
-
WebMock.should have_requested(:
|
27
|
+
WebMock.should have_requested(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true', 'index' => 3})
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'yields the value' do
|
31
|
-
body = MultiJson.dump({'value' => 'bar'})
|
32
|
-
stub_request(:get, "#{base_uri}/
|
31
|
+
body = MultiJson.dump({'node' => {'value' => 'bar'}})
|
32
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: body)
|
33
33
|
value = nil
|
34
34
|
client.watch('/foo') do |v|
|
35
35
|
value = v
|
36
36
|
end
|
37
|
-
value.should
|
37
|
+
value.should eq('bar')
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'yields the changed key' do
|
41
|
-
body = MultiJson.dump({'key' => '/foo/bar', 'value' => 'bar'})
|
42
|
-
stub_request(:get, "#{base_uri}/
|
41
|
+
body = MultiJson.dump({'node' => {'key' => '/foo/bar', 'value' => 'bar'}})
|
42
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: body)
|
43
43
|
key = nil
|
44
44
|
client.watch('/foo') do |_, k|
|
45
45
|
key = k
|
46
46
|
end
|
47
|
-
key.should
|
47
|
+
key.should eq('/foo/bar')
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'yields info about the key, when it is a new key' do
|
51
|
-
body = MultiJson.dump({'action' => 'SET', 'key' => '/foo/bar', 'value' => 'bar', 'index' => 3
|
52
|
-
stub_request(:get, "#{base_uri}/
|
51
|
+
body = MultiJson.dump({'action' => 'SET', 'node' => {'key' => '/foo/bar', 'value' => 'bar', 'index' => 3}})
|
52
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: body)
|
53
53
|
info = nil
|
54
54
|
client.watch('/foo') do |_, _, i|
|
55
55
|
info = i
|
56
56
|
end
|
57
|
-
info[:action].should
|
58
|
-
info[:key].should
|
59
|
-
info[:value].should
|
60
|
-
info[:index].should
|
57
|
+
info[:action].should eq(:set)
|
58
|
+
info[:key].should eq('/foo/bar')
|
59
|
+
info[:value].should eq('bar')
|
60
|
+
info[:index].should eq(3)
|
61
61
|
info[:new_key].should eq(true)
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'yields info about the key, when the key was changed' do
|
65
|
-
body = MultiJson.dump({'action' => '
|
66
|
-
stub_request(:get, "#{base_uri}/
|
65
|
+
body = MultiJson.dump({'action' => 'set', 'node' => {'key' => '/foo/bar', 'value' => 'bar', 'index' => 3}, 'prevNode' => {'value' => 'baz'}})
|
66
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: body)
|
67
67
|
info = nil
|
68
68
|
client.watch('/foo') do |_, _, i|
|
69
69
|
info = i
|
70
70
|
end
|
71
|
-
info[:action].should
|
72
|
-
info[:key].should
|
73
|
-
info[:value].should
|
74
|
-
info[:index].should
|
75
|
-
info[:previous_value].should
|
71
|
+
info[:action].should eq(:set)
|
72
|
+
info[:key].should eq('/foo/bar')
|
73
|
+
info[:value].should eq('bar')
|
74
|
+
info[:index].should eq(3)
|
75
|
+
info[:previous_value].should eq('baz')
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'yields info about the key, when the key has a TTL' do
|
79
|
-
body = MultiJson.dump({'action' => '
|
80
|
-
stub_request(:get, "#{base_uri}/
|
79
|
+
body = MultiJson.dump({'action' => 'set', 'node' => {'key' => '/foo/bar', 'value' => 'bar', 'index' => 3, 'expiration' => '2013-12-11T12:09:08.123+02:00', 'ttl' => 7}})
|
80
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: body)
|
81
81
|
info = nil
|
82
82
|
client.watch('/foo') do |_, _, i|
|
83
83
|
info = i
|
84
84
|
end
|
85
|
-
info[:action].should
|
86
|
-
info[:key].should
|
87
|
-
info[:value].should
|
88
|
-
info[:index].should
|
85
|
+
info[:action].should eq(:set)
|
86
|
+
info[:key].should eq('/foo/bar')
|
87
|
+
info[:value].should eq('bar')
|
88
|
+
info[:index].should eq(3)
|
89
89
|
# rounding because of ruby 2.0 time parsing bug @see https://gist.github.com/mindreframer/6746829
|
90
|
-
info[:expiration].to_f.round.should
|
91
|
-
info[:ttl].should
|
90
|
+
info[:expiration].to_f.round.should eq((Time.utc(2013, 12, 11, 10, 9, 8) + 0.123).to_f.round)
|
91
|
+
info[:ttl].should eq(7)
|
92
92
|
end
|
93
93
|
|
94
94
|
it 'returns the return value of the block' do
|
95
|
-
body = MultiJson.dump({'action' => '
|
96
|
-
stub_request(:get, "#{base_uri}/
|
95
|
+
body = MultiJson.dump({'action' => 'set', 'node' => {'key' => '/foo/bar', 'value' => 'bar', 'index' => 3, 'expiration' => '2013-12-11T12:09:08.123+02:00', 'ttl' => 7}})
|
96
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: body)
|
97
97
|
return_value = client.watch('/foo') do |_, k, _|
|
98
98
|
k
|
99
99
|
end
|
100
|
-
return_value.should
|
100
|
+
return_value.should eq('/foo/bar')
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
104
|
|
105
105
|
describe '#observe' do
|
106
106
|
it 'watches the specified key prefix' do
|
107
|
-
stub_request(:get, "#{base_uri}/
|
107
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: MultiJson.dump({'node' => {}}))
|
108
108
|
barrier = Queue.new
|
109
109
|
observer = client.observe('/foo') do
|
110
110
|
barrier << :ping
|
@@ -112,12 +112,12 @@ module Etcd
|
|
112
112
|
observer.join
|
113
113
|
end
|
114
114
|
barrier.pop
|
115
|
-
WebMock.should have_requested(:get, "#{base_uri}/
|
115
|
+
WebMock.should have_requested(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'})
|
116
116
|
end
|
117
117
|
|
118
118
|
it 're-watches the prefix with the (last seen index + 1) immediately' do
|
119
|
-
stub_request(:get, "#{base_uri}/
|
120
|
-
stub_request(:
|
119
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: MultiJson.dump({'node' => {'index' => 3}}))
|
120
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true', 'index' => 4}).to_return(body: MultiJson.dump({'node' => {'index' => 4}}))
|
121
121
|
barrier = Queue.new
|
122
122
|
observer = client.observe('/foo') do |_, _, info|
|
123
123
|
if info[:index] == 4
|
@@ -127,14 +127,14 @@ module Etcd
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
barrier.pop
|
130
|
-
WebMock.should have_requested(:get, "#{base_uri}/
|
131
|
-
WebMock.should have_requested(:
|
130
|
+
WebMock.should have_requested(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'})
|
131
|
+
WebMock.should have_requested(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true', 'index' => 4})
|
132
132
|
end
|
133
133
|
|
134
134
|
it 'yields the value, key and info to the block given' do
|
135
|
-
stub_request(:get, "#{base_uri}/
|
136
|
-
stub_request(:
|
137
|
-
stub_request(:
|
135
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true'}).to_return(body: MultiJson.dump({'action' => 'set', 'node' => {'key' => '/foo/bar', 'value' => 'bar', 'index' => 3}}))
|
136
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true', 'index' => 4}).to_return(body: MultiJson.dump({'action' => 'delete', 'node' => {'key' => '/foo/baz', 'value' => 'foo', 'index' => 4}, 'prevNode' => {}}))
|
137
|
+
stub_request(:get, "#{base_uri}/keys/foo").with(query: {'wait' => 'true', 'index' => 5}).to_return(body: MultiJson.dump({'action' => 'set', 'node' => {'key' => '/foo/bar', 'value' => 'hello', 'index' => 5}, 'prevNode' => {}}))
|
138
138
|
barrier = Queue.new
|
139
139
|
values = []
|
140
140
|
keys = []
|
@@ -152,10 +152,10 @@ module Etcd
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
barrier.pop
|
155
|
-
values.should
|
156
|
-
keys.should
|
157
|
-
actions.should
|
158
|
-
new_keys.should
|
155
|
+
values.should eq(%w[bar foo hello])
|
156
|
+
keys.should eq(%w[/foo/bar /foo/baz /foo/bar])
|
157
|
+
actions.should eq([:set, :delete, :set])
|
158
|
+
new_keys.should eq([true, false, false])
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
@@ -6,10 +6,6 @@ require 'open-uri'
|
|
6
6
|
|
7
7
|
describe 'With real server an etcd client' do
|
8
8
|
|
9
|
-
let :client do
|
10
|
-
Etcd::Client.test_client
|
11
|
-
end
|
12
|
-
|
13
9
|
let :prefix do
|
14
10
|
"/etcd-rb/#{rand(234234)}"
|
15
11
|
end
|
@@ -23,8 +19,18 @@ describe 'With real server an etcd client' do
|
|
23
19
|
WebMock.allow_net_connect!
|
24
20
|
end
|
25
21
|
|
26
|
-
before do
|
22
|
+
before(:all) do
|
23
|
+
ClusterController.stop_cluster
|
27
24
|
ClusterController.start_cluster
|
25
|
+
sleep 2 # wait a little for the cluster to come up
|
26
|
+
end
|
27
|
+
|
28
|
+
after(:all) do
|
29
|
+
ClusterController.stop_cluster
|
30
|
+
end
|
31
|
+
|
32
|
+
let :client do
|
33
|
+
Etcd::Client.test_client
|
28
34
|
end
|
29
35
|
|
30
36
|
before do
|
@@ -37,7 +43,7 @@ describe 'With real server an etcd client' do
|
|
37
43
|
|
38
44
|
it 'sets and gets the value for a key' do
|
39
45
|
client.set(key, 'foo')
|
40
|
-
client.get(key).should
|
46
|
+
client.get(key).should eq('foo')
|
41
47
|
end
|
42
48
|
|
43
49
|
it 'sets a key with a TTL' do
|
@@ -49,8 +55,8 @@ describe 'With real server an etcd client' do
|
|
49
55
|
it 'watches for changes to a key' do
|
50
56
|
Thread.start { sleep(0.1); client.set(key, 'baz') }
|
51
57
|
new_value, info = *client.watch(key) { |v, k, info| [v, info] }
|
52
|
-
new_value.should
|
53
|
-
info[:new_key].should
|
58
|
+
new_value.should eq('baz')
|
59
|
+
info[:new_key].should eq(true)
|
54
60
|
end
|
55
61
|
|
56
62
|
it 'conditionally sets the value for a key' do
|
@@ -59,11 +65,12 @@ describe 'With real server an etcd client' do
|
|
59
65
|
client.update(key, 'qux', 'bar').should eq(true)
|
60
66
|
end
|
61
67
|
|
62
|
-
|
68
|
+
# FIXME: this test does not pass consistently. There seem to issues
|
69
|
+
# with the leader re-election handling (causing Errno::ECONNREFUSED)
|
63
70
|
it "has heartbeat, that resets observed watches" do
|
64
|
-
|
65
|
-
client
|
66
|
-
client.cluster.nodes.map(&:status).uniq.should
|
71
|
+
client = Etcd::Client.test_client(:heartbeat_freq => 0.1)
|
72
|
+
puts client.cluster.nodes.map(&:inspect)
|
73
|
+
client.cluster.nodes.map(&:status).uniq.should eq([:running])
|
67
74
|
changes = Queue.new
|
68
75
|
|
69
76
|
client.observe('/foo') do |v,k,info|
|
@@ -71,7 +78,7 @@ describe 'With real server an etcd client' do
|
|
71
78
|
changes << info
|
72
79
|
end
|
73
80
|
|
74
|
-
changes.size.should
|
81
|
+
changes.size.should eq(0)
|
75
82
|
|
76
83
|
### simulate second console
|
77
84
|
a = Thread.new do
|
@@ -83,9 +90,15 @@ describe 'With real server an etcd client' do
|
|
83
90
|
sleep 0.4
|
84
91
|
puts "2.nd try"
|
85
92
|
client.set("/foo", "barss")
|
93
|
+
sleep 0.4
|
86
94
|
end
|
87
95
|
|
88
|
-
|
89
|
-
changes.size.should
|
96
|
+
a.join
|
97
|
+
changes.size.should eq(2)
|
98
|
+
|
99
|
+
# restore cluster
|
100
|
+
ClusterController.stop_cluster
|
101
|
+
ClusterController.start_cluster
|
102
|
+
sleep 2
|
90
103
|
end
|
91
|
-
end
|
104
|
+
end
|