etcd 0.2.0.alpha → 0.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/etcd/node.rb CHANGED
@@ -1,15 +1,16 @@
1
1
  # Encoding: utf-8
2
2
 
3
3
  module Etcd
4
+ # This class represents an etcd node
4
5
  class Node
5
-
6
6
  include Comparable
7
7
 
8
8
  attr_reader :created_index, :modified_index, :expiration, :ttl, :key, :value
9
- alias :createdIndex :created_index
10
- alias :modifiedIndex :modified_index
9
+ alias_method :createdIndex, :created_index
10
+ alias_method :modifiedIndex, :modified_index
11
11
 
12
- def initialize(opts={})
12
+ # rubocop:disable MethodLength
13
+ def initialize(opts = {})
13
14
  @created_index = opts['createdIndex']
14
15
  @modified_index = opts['modifiedIndex']
15
16
  @ttl = opts['ttl']
@@ -18,7 +19,7 @@ module Etcd
18
19
  @expiration = opts['expiration']
19
20
  @dir = opts['dir']
20
21
 
21
- if opts['dir'] and (!!opts['nodes'])
22
+ if opts['dir'] && (!!opts['nodes'])
22
23
  opts['nodes'].each do |data|
23
24
  children << Node.new(data)
24
25
  end
@@ -33,7 +34,7 @@ module Etcd
33
34
  if directory?
34
35
  @children ||= []
35
36
  else
36
- raise "This is not a directory, cant have children"
37
+ fail 'This is not a directory, cant have children'
37
38
  end
38
39
  end
39
40
 
data/lib/etcd/response.rb CHANGED
@@ -2,18 +2,18 @@
2
2
 
3
3
  require 'etcd/node'
4
4
  require 'json'
5
+ require 'forwardable'
5
6
 
6
7
  module Etcd
7
-
8
+ # manage http responses
8
9
  class Response
9
-
10
10
  extend Forwardable
11
11
 
12
12
  attr_reader :action, :node, :etcd_index, :raft_index, :raft_term
13
13
 
14
14
  def_delegators :@node, :key, :value, :directory?, :children
15
15
 
16
- def initialize(opts, headers={})
16
+ def initialize(opts, headers = {})
17
17
  @action = opts['action']
18
18
  @node = Node.new(opts['node'])
19
19
  @etcd_index = headers[:etcd_index]
@@ -23,11 +23,11 @@ module Etcd
23
23
 
24
24
  def self.from_http_response(response)
25
25
  data = JSON.parse(response.body)
26
- headers = Hash.new
26
+ headers = {}
27
27
  headers[:etcd_index] = response['X-Etcd-Index'].to_i
28
28
  headers[:raft_index] = response['X-Raft-Index'].to_i
29
29
  headers[:raft_term] = response['X-Raft-Term'].to_i
30
- response = Response.new(data, headers)
30
+ Response.new(data, headers)
31
31
  end
32
32
  end
33
33
  end
data/lib/etcd/stats.rb CHANGED
@@ -3,8 +3,8 @@
3
3
  require 'json'
4
4
 
5
5
  module Etcd
6
+ # Support stats
6
7
  module Stats
7
-
8
8
  def stats_endpoint
9
9
  version_prefix + '/stats'
10
10
  end
@@ -12,13 +12,13 @@ module Etcd
12
12
  def stats(type)
13
13
  case type
14
14
  when :leader
15
- JSON.parse(api_execute(stats_endpoint+'/leader', :get).body)
15
+ JSON.parse(api_execute(stats_endpoint + '/leader', :get).body)
16
16
  when :store
17
- JSON.parse(api_execute(stats_endpoint+'/store', :get).body)
17
+ JSON.parse(api_execute(stats_endpoint + '/store', :get).body)
18
18
  when :self
19
- JSON.parse(api_execute(stats_endpoint+'/self', :get).body)
19
+ JSON.parse(api_execute(stats_endpoint + '/self', :get).body)
20
20
  else
21
- raise ArgumentError, "Invalid stats type '#{type}'"
21
+ fail ArgumentError, "Invalid stats type '#{type}'"
22
22
  end
23
23
  end
24
24
  end
data/lib/etcd/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # Encoding: utf-8
2
-
2
+ # Version const
3
3
  module Etcd
4
- VERSION = "0.2.0.alpha"
4
+ VERSION = '0.2.0.beta.1'
5
5
  end
@@ -0,0 +1,27 @@
1
+ # Encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Etcd basic auth client' do
6
+
7
+ let(:client) do
8
+ Etcd.client(user_name: 'test', password: 'pwd')
9
+ end
10
+
11
+ it '#user_name' do
12
+ expect(client.user_name).to eq('test')
13
+ end
14
+
15
+ it '#password' do
16
+ expect(client.password).to eq('pwd')
17
+ end
18
+
19
+ it 'should set basic auth' do
20
+ Net::HTTPRequest.any_instance.should_receive(:basic_auth).with('test', 'pwd')
21
+ key = random_key
22
+ value = uuid.generate
23
+ client.set(key, value: value)
24
+ sleep 1
25
+ expect(read_only_client.get(key).value).to eq(value)
26
+ end
27
+ end
@@ -15,7 +15,7 @@ describe Etcd::Client do
15
15
  end
16
16
 
17
17
  it '#version' do
18
- expect(client.version).to match(/^etcd v0\.2\./)
18
+ expect(client.version).to match(/^etcd v?0\.\d+\.\d+(\+git)?/)
19
19
  end
20
20
 
21
21
  it '#version_prefix' do
@@ -29,14 +29,22 @@ describe Etcd::Client do
29
29
  end.to raise_error
30
30
  end
31
31
 
32
- it 'should redirect api request when allo_redirect is set'
32
+ it 'should redirect api request when allow_redirect is set' do
33
+ key = random_key
34
+ value = uuid.generate
35
+ rd_client = Etcd.client host: 'localhost', port: 4003
36
+ resp = rd_client.set(key, value: value)
37
+ resp.node.key.should eql key
38
+ resp.node.value.should eql value
39
+ client.get(key).value.should eql resp.value
40
+ end
33
41
  end
34
42
 
35
43
  context '#http header based metadata' do
36
44
  before(:all) do
37
45
  key = random_key
38
46
  value = uuid.generate
39
- @response = Etcd.client.set(key,value)
47
+ @response = Etcd.client.set(key, value: value)
40
48
  end
41
49
 
42
50
  it '#etcd_index' do
@@ -9,18 +9,60 @@ describe Etcd::Keys do
9
9
  it '#set/#get' do
10
10
  key = random_key
11
11
  value = uuid.generate
12
- client.set(key, value)
12
+ client.set(key, value: value)
13
13
  expect(client.get(key).value).to eq(value)
14
14
  end
15
15
 
16
16
  context '#exists?' do
17
17
  it 'should be true for existing keys' do
18
18
  key = random_key
19
- client.create(key, 10)
19
+ client.create(key, value: 10)
20
20
  expect(client.exists?(key)).to be_true
21
21
  end
22
22
  it 'should be true for existing keys' do
23
23
  expect(client.exists?(random_key)).to be_false
24
24
  end
25
25
  end
26
+
27
+ context 'directory' do
28
+ it 'should be able to create a directory' do
29
+ d = random_key
30
+ client.create(d, dir: true)
31
+ expect(client.get(d)).to be_true
32
+ end
33
+ context 'empty' do
34
+ it 'should be able to delete with dir flag' do
35
+ d = random_key
36
+ client.create(d, dir: true)
37
+ expect(client.delete(d, dir: true)).to be_true
38
+ end
39
+
40
+ it 'should not be able to delete without dir flag' do
41
+ d = random_key
42
+ client.create(d, dir: true)
43
+ client.create("#{d}/foobar", value: 10)
44
+ expect do
45
+ client.delete(d)
46
+ end.to raise_error(Etcd::NotFile)
47
+ end
48
+ end
49
+ context 'not empty' do
50
+ it 'should be able to delete with recursive flag' do
51
+ d = random_key
52
+ client.create(d, dir: true)
53
+ client.create("#{d}/foobar")
54
+ expect do
55
+ client.delete(d, dir: true, recursive: true)
56
+ end.to_not raise_error
57
+ end
58
+ it 'should be not able to delete without recursive flag' do
59
+ d = random_key
60
+ client.create(d, dir: true)
61
+ client.create("#{d}/foobar")
62
+ expect do
63
+ client.delete(d, dir: true)
64
+ end.to raise_error(Etcd::DirNotEmpty)
65
+ end
66
+ end
67
+ end
26
68
  end
@@ -10,7 +10,7 @@ describe 'lock' do
10
10
 
11
11
  it 'should be able to acquire a lock' do
12
12
  expect do
13
- client.acquire_lock('/my_lock',10)
13
+ client.acquire_lock('/my_lock', 10)
14
14
  end.to_not raise_error
15
15
  end
16
16
 
@@ -23,7 +23,7 @@ describe 'lock' do
23
23
 
24
24
  it 'should be able to renew a lock based on index' do
25
25
  client.acquire_lock('/my_lock2', 10)
26
- index = client.get_lock('/my_lock2', field:'index')
26
+ index = client.get_lock('/my_lock2', field: 'index')
27
27
  expect do
28
28
  client.renew_lock('/my_lock2', 10, index: index)
29
29
  end.to_not raise_error
@@ -38,7 +38,7 @@ describe 'lock' do
38
38
 
39
39
  it 'should be able to delete a lock based on index' do
40
40
  client.acquire_lock('/my_lock4', 10)
41
- index = client.get_lock('/my_lock4', field:'index')
41
+ index = client.get_lock('/my_lock4', field: 'index')
42
42
  expect do
43
43
  client.delete_lock('/my_lock4', index: index)
44
44
  end.to_not raise_error
@@ -6,19 +6,19 @@ describe Etcd::Node do
6
6
  Etcd.client
7
7
  end
8
8
 
9
- it "should create a directory with parent key when nested keys are set" do
9
+ it 'should create a directory with parent key when nested keys are set' do
10
10
  parent = random_key
11
11
  child = random_key
12
12
  value = uuid.generate
13
- client.set(parent+child, value)
14
- expect(client.get(parent+child)).to_not be_directory
13
+ client.set(parent + child, value: value)
14
+ expect(client.get(parent + child)).to_not be_directory
15
15
  expect(client.get(parent)).to be_directory
16
16
  end
17
17
 
18
18
  context '#children' do
19
19
  it 'should raise exception when invoked against a leaf node' do
20
20
  parent = random_key
21
- client.create(random_key, 10)
21
+ client.create(random_key, value: 10)
22
22
  expect do
23
23
  client.get(random_key).children
24
24
  end.to raise_error
@@ -2,32 +2,31 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe "Etcd read only client" do
5
+ describe 'Etcd read only client' do
6
6
 
7
7
  let(:client) do
8
8
  Etcd.client
9
9
  end
10
10
 
11
- it "should not allow write" do
12
- key= random_key
13
- expect{
14
- read_only_client.set(key, uuid.generate)
15
- }.to raise_error(Net::HTTPRetriableError)
11
+ it 'should not allow write' do
12
+ key = random_key
13
+ expect do
14
+ read_only_client.set(key, value: uuid.generate)
15
+ end.to raise_error(Net::HTTPRetriableError)
16
16
  end
17
17
 
18
- it "should allow reads" do
18
+ it 'should allow reads' do
19
19
  key = random_key
20
20
  value = uuid.generate
21
- client.set(key, value)
21
+ client.set(key, value: value)
22
22
  sleep 1
23
23
  expect(read_only_client.get(key).value).to eq(value)
24
24
  end
25
25
 
26
- it "should allow watch" do
26
+ it 'should allow watch' do
27
27
  key = random_key
28
28
  value = uuid.generate
29
- index = client.set(key, value).node.modified_index
29
+ index = client.set(key, value: value).node.modified_index
30
30
  expect(read_only_client.watch(key, index: index).value).to eq(value)
31
31
  end
32
32
  end
33
-
@@ -53,10 +53,9 @@ describe 'Etcd specs for the main etcd README examples' do
53
53
  end
54
54
 
55
55
  context 'set a key named "/message"' do
56
-
57
56
 
58
57
  before(:all) do
59
- @response = Etcd.client.set('/message', 'PinkFloyd')
58
+ @response = Etcd.client.set('/message', value: 'PinkFloyd')
60
59
  end
61
60
 
62
61
  it_should_behave_like 'response with valid http headers'
@@ -70,7 +69,7 @@ describe 'Etcd specs for the main etcd README examples' do
70
69
  context 'get a key named "/message"' do
71
70
 
72
71
  before(:all) do
73
- Etcd.client.set('/message', 'PinkFloyd')
72
+ Etcd.client.set('/message', value: 'PinkFloyd')
74
73
  @response = Etcd.client.get('/message')
75
74
  end
76
75
 
@@ -85,8 +84,8 @@ describe 'Etcd specs for the main etcd README examples' do
85
84
  context 'change the value of a key named "/message"' do
86
85
 
87
86
  before(:all) do
88
- Etcd.client.set('/message', 'World')
89
- @response = Etcd.client.set('/message','PinkFloyd')
87
+ Etcd.client.set('/message', value: 'World')
88
+ @response = Etcd.client.set('/message', value: 'PinkFloyd')
90
89
  end
91
90
 
92
91
  it_should_behave_like 'response with valid http headers'
@@ -100,8 +99,8 @@ describe 'Etcd specs for the main etcd README examples' do
100
99
  context 'delete a key named "/message"' do
101
100
 
102
101
  before(:all) do
103
- Etcd.client.set('/message', 'World')
104
- Etcd.client.set('/message','PinkFloyd')
102
+ Etcd.client.set('/message', value: 'World')
103
+ Etcd.client.set('/message', value: 'PinkFloyd')
105
104
  @response = Etcd.client.delete('/message')
106
105
  end
107
106
 
@@ -116,9 +115,9 @@ describe 'Etcd specs for the main etcd README examples' do
116
115
  context 'using ttl a key named "/message"' do
117
116
 
118
117
  before(:all) do
119
- Etcd.client.set('/message', 'World')
118
+ Etcd.client.set('/message', value: 'World')
120
119
  @set_time = Time.now
121
- @response = Etcd.client.set('/message','PinkFloyd', 5)
120
+ @response = Etcd.client.set('/message', value: 'PinkFloyd', ttl: 5)
122
121
  end
123
122
 
124
123
  it_should_behave_like 'response with valid http headers'
@@ -148,11 +147,11 @@ describe 'Etcd specs for the main etcd README examples' do
148
147
  context 'waiting for a change against a key named "/message"' do
149
148
 
150
149
  before(:all) do
151
- Etcd.client.set('/message', 'foo')
150
+ Etcd.client.set('/message', value: 'foo')
152
151
  thr = Thread.new do
153
152
  @response = Etcd.client.watch('/message')
154
153
  end
155
- Etcd.client.set('/message', 'PinkFloyd')
154
+ Etcd.client.set('/message', value: 'PinkFloyd')
156
155
  thr.join
157
156
  end
158
157
 
@@ -164,7 +163,7 @@ describe 'Etcd specs for the main etcd README examples' do
164
163
  end
165
164
 
166
165
  it 'should get the exact value by specifying a waitIndex' do
167
- client.set('/message', 'someshit')
166
+ client.set('/message', value: 'someshit')
168
167
  w_response = client.watch('/message', index: @response.node.modified_index)
169
168
  expect(w_response.node.value).to eq('PinkFloyd')
170
169
  end
@@ -173,7 +172,7 @@ describe 'Etcd specs for the main etcd README examples' do
173
172
  context 'atomic in-order keys' do
174
173
 
175
174
  before(:all) do
176
- @response = Etcd.client.create_in_order('/queue', 'PinkFloyd')
175
+ @response = Etcd.client.create_in_order('/queue', value: 'PinkFloyd')
177
176
  end
178
177
 
179
178
  it_should_behave_like 'response with valid http headers'
@@ -188,8 +187,8 @@ describe 'Etcd specs for the main etcd README examples' do
188
187
  end
189
188
 
190
189
  it 'should have the child keys as monotonically increasing' do
191
- first_response = client.create_in_order('/queue', 'The Jimi Hendrix Experience')
192
- second_response = client.create_in_order('/queue', 'The Doors')
190
+ first_response = client.create_in_order('/queue', value: 'The Jimi Hendrix Experience')
191
+ second_response = client.create_in_order('/queue', value: 'The Doors')
193
192
  first_key = first_response.key.split('/').last.to_i
194
193
  second_key = second_response.key.split('/').last.to_i
195
194
  expect(first_key).to be < second_key
@@ -198,12 +197,12 @@ describe 'Etcd specs for the main etcd README examples' do
198
197
  it 'should enlist all children in sorted manner' do
199
198
  responses = []
200
199
  10.times do |n|
201
- responses << client.create_in_order('/queue', 'Deep Purple - Track #{n}')
200
+ responses << client.create_in_order('/queue', value: 'Deep Purple - Track #{n}')
202
201
  end
203
202
  directory = client.get('/queue', sorted: true)
204
203
  past_index = directory.children.index(responses.first.node)
205
204
  9.times do |n|
206
- current_index = directory.children.index(responses[n+1].node)
205
+ current_index = directory.children.index(responses[n + 1].node)
207
206
  expect(current_index).to be > past_index
208
207
  past_index = current_index
209
208
  end
@@ -230,18 +229,18 @@ describe 'Etcd specs for the main etcd README examples' do
230
229
 
231
230
  it 'will throw error if updated without setting prevExist' do
232
231
  expect do
233
- client.set('/directory', dir:true, ttl:5)
232
+ client.set('/directory', dir: true, ttl: 5)
234
233
  end.to raise_error
235
234
  end
236
235
 
237
236
  it 'can be updated by setting prevExist to true' do
238
- client.set('/directory', prevExist: true, dir:true, ttl:5)
237
+ client.set('/directory', prevExist: true, dir: true, ttl: 5)
239
238
  expect(client.get('/directory').node.ttl).to eq(5)
240
239
  end
241
240
 
242
241
  it 'watchers should get expriy notification' do
243
- client.set('/directory/a', 'Test')
244
- client.set('/directory', prevExist: true, dir:true, ttl:2)
242
+ client.set('/directory/a', value: 'Test')
243
+ client.set('/directory', prevExist: true, dir: true, ttl: 2)
245
244
  response = client.watch('/directory/a', consistent: true, timeout: 3)
246
245
  expect(response.action).to eq('expire')
247
246
  end
@@ -256,37 +255,37 @@ describe 'Etcd specs for the main etcd README examples' do
256
255
  context 'atomic compare and swap' do
257
256
 
258
257
  it 'should raise error if prevExist is passed a false' do
259
- client.set('/foo', 'one')
258
+ client.set('/foo', value: 'one')
260
259
  expect do
261
- client.set('/foo','three', prevExist: false)
260
+ client.set('/foo', value: 'three', prevExist: false)
262
261
  end.to raise_error
263
262
  end
264
263
 
265
264
  it 'should raise error is prevValue is wrong' do
266
- client.set('/foo', 'one')
265
+ client.set('/foo', value: 'one')
267
266
  expect do
268
- client.set('/foo','three', prevValue: 'two')
267
+ client.set('/foo', value: 'three', prevValue: 'two')
269
268
  end.to raise_error
270
269
  end
271
270
 
272
271
  it 'should allow setting the value when prevValue is right' do
273
- client.set('/foo', 'one')
274
- expect(client.set('/foo','three', prevValue: 'one').value).to eq('three')
272
+ client.set('/foo', value: 'one')
273
+ expect(client.set('/foo', value: 'three', prevValue: 'one').value).to eq('three')
275
274
  end
276
275
  end
277
276
  context 'directory manipulation' do
278
277
  it 'should allow creating directory' do
279
- expect(client.set('/dir',dir:true)).to be_directory
278
+ expect(client.set('/dir', dir: true)).to be_directory
280
279
  end
281
280
 
282
281
  it 'should allow listing directory' do
283
- client.set('/foo_dir/foo','bar')
282
+ client.set('/foo_dir/foo', value: 'bar')
284
283
  expect(client.get('/').children.map(&:key)).to include('/foo_dir')
285
284
  end
286
285
 
287
286
  it 'should allow recursive directory listing' do
288
287
  response = client.get('/', recursive: true)
289
- expect(response.children.find{|n|n.key=='/foo_dir'}.children).to_not be_empty
288
+ expect(response.children.find { |n|n.key == '/foo_dir' }.children).to_not be_empty
290
289
  end
291
290
 
292
291
  it 'should be able to delete empty directory without the recusrive flag' do
@@ -301,8 +300,8 @@ describe 'Etcd specs for the main etcd README examples' do
301
300
  context 'hidden nodes' do
302
301
 
303
302
  before(:all) do
304
- Etcd.client.set('/_message', 'Hello Hidden World')
305
- Etcd.client.set('/message', 'Hello World')
303
+ Etcd.client.set('/_message', value: 'Hello Hidden World')
304
+ Etcd.client.set('/message', value: 'Hello World')
306
305
  end
307
306
 
308
307
  it 'should not be visible in directory listing' do