etcdv3 0.7.0 → 0.8.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 +21 -2
- data/lib/etcdv3/auth.rb +41 -33
- data/lib/etcdv3/connection.rb +3 -2
- data/lib/etcdv3/connection_wrapper.rb +4 -3
- data/lib/etcdv3/kv.rb +14 -8
- data/lib/etcdv3/lease.rb +12 -9
- data/lib/etcdv3/maintenance.rb +1 -1
- data/lib/etcdv3/version.rb +1 -1
- data/lib/etcdv3/watch.rb +1 -1
- data/lib/etcdv3.rb +54 -44
- data/spec/etcdv3/auth_spec.rb +26 -2
- data/spec/etcdv3/connection_spec.rb +2 -2
- data/spec/etcdv3/connection_wrapper_spec.rb +2 -2
- data/spec/etcdv3/kv_spec.rb +13 -4
- data/spec/etcdv3/lease_spec.rb +15 -4
- data/spec/etcdv3_spec.rb +99 -6
- data/spec/helpers/connections.rb +6 -2
- data/spec/helpers/shared_examples_for_timeout.rb +43 -0
- data/spec/spec_helper.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 548056c69c835ad0572929605d5d7e5660c5fcb3
|
4
|
+
data.tar.gz: b619d3ece12e977d1b4de36f82582f748e88c1ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a009124afa1bd5d169ca16f453aa99972cd56c9f538e2b03cfd48f0fab5a5c6622c075ce24da2265a99c0c6390807a0800c398e01068de72d10702f3c4345cda
|
7
|
+
data.tar.gz: 81593332c0d9f8460714c1a7b74d2cea5e4a9d22254bdf8a37a4a23dece3ca6555e4f2b69e4a20227536309765a986889d4f567affb29a6af5d6e686b6a3d5a2
|
data/README.md
CHANGED
@@ -29,6 +29,9 @@ conn = Etcdv3.new(endpoints: 'https://hostname:port', user: 'root', password: 'm
|
|
29
29
|
# Secure connection specifying custom certificates
|
30
30
|
# Coming soon...
|
31
31
|
|
32
|
+
# Per-request timeouts
|
33
|
+
conn = Etcdv3.new(endpoints: 'https://hostname:port', command_timeout: 5) # seconds
|
34
|
+
|
32
35
|
```
|
33
36
|
**High Availability**
|
34
37
|
|
@@ -170,11 +173,27 @@ conn.alarm_list
|
|
170
173
|
conn.alarm_deactivate
|
171
174
|
```
|
172
175
|
|
176
|
+
## Timeouts
|
177
|
+
|
178
|
+
The default timeout for all requests is 120 seconds. A timeout can be set on the connection:
|
179
|
+
|
173
180
|
```ruby
|
174
|
-
#
|
175
|
-
conn = Etcdv3.new(endpoints: 'http://127.0.0.1:2379, http://127.0.0.1:2389, http://127.0.0.1:2399')
|
181
|
+
conn = Etcdv3.new(endpoints: 'https://hostname:port', command_timeout: 5) # seconds
|
176
182
|
```
|
177
183
|
|
184
|
+
Or a timeout can be set on an individual request.
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
conn = Etcdv3.new(endpoints: 'https://hostname:port', command_timeout: 5)
|
188
|
+
conn.get("foo", timeout: 2) # Timeout of 2 seconds
|
189
|
+
```
|
190
|
+
|
191
|
+
This timeout applies to and can be set when:
|
192
|
+
- Adding, Fetching and Deleting keys
|
193
|
+
- User, Role, and Authentication Management
|
194
|
+
- Leases
|
195
|
+
- Transactions
|
196
|
+
|
178
197
|
## Contributing
|
179
198
|
|
180
199
|
If you're looking to get involved, [Fork the project](https://github.com/davissp14/etcdv3-ruby) and send pull requests.
|
data/lib/etcdv3/auth.rb
CHANGED
@@ -8,37 +8,38 @@ class Etcdv3
|
|
8
8
|
:readwrite => Authpb::Permission::Type::READWRITE
|
9
9
|
}
|
10
10
|
|
11
|
-
def initialize(hostname, credentials, metadata = {})
|
11
|
+
def initialize(hostname, credentials, timeout, metadata = {})
|
12
12
|
@stub = Etcdserverpb::Auth::Stub.new(hostname, credentials)
|
13
|
+
@timeout = timeout
|
13
14
|
@metadata = metadata
|
14
15
|
end
|
15
16
|
|
16
|
-
def auth_enable
|
17
|
+
def auth_enable(timeout: nil)
|
17
18
|
request = Etcdserverpb::AuthEnableRequest.new
|
18
|
-
@stub.auth_enable(request)
|
19
|
+
@stub.auth_enable(request, deadline: deadline(timeout))
|
19
20
|
end
|
20
21
|
|
21
|
-
def auth_disable
|
22
|
+
def auth_disable(timeout: nil)
|
22
23
|
request = Etcdserverpb::AuthDisableRequest.new
|
23
|
-
@stub.auth_disable(request, metadata: @metadata)
|
24
|
+
@stub.auth_disable(request, metadata: @metadata, deadline: deadline(timeout))
|
24
25
|
end
|
25
26
|
|
26
|
-
def role_add(name)
|
27
|
+
def role_add(name, timeout: nil)
|
27
28
|
request = Etcdserverpb::AuthRoleAddRequest.new(name: name)
|
28
|
-
@stub.role_add(request, metadata: @metadata)
|
29
|
+
@stub.role_add(request, metadata: @metadata, deadline: deadline(timeout))
|
29
30
|
end
|
30
31
|
|
31
|
-
def role_get(name)
|
32
|
+
def role_get(name, timeout: nil)
|
32
33
|
request = Etcdserverpb::AuthRoleGetRequest.new(role: name)
|
33
|
-
@stub.role_get(request, metadata: @metadata)
|
34
|
+
@stub.role_get(request, metadata: @metadata, deadline: deadline(timeout))
|
34
35
|
end
|
35
36
|
|
36
|
-
def role_delete(name)
|
37
|
+
def role_delete(name, timeout: nil)
|
37
38
|
request = Etcdserverpb::AuthRoleDeleteRequest.new(role: name)
|
38
|
-
@stub.role_delete(request, metadata: @metadata)
|
39
|
+
@stub.role_delete(request, metadata: @metadata, deadline: deadline(timeout))
|
39
40
|
end
|
40
41
|
|
41
|
-
def role_grant_permission(name, permission, key, range_end)
|
42
|
+
def role_grant_permission(name, permission, key, range_end, timeout: nil)
|
42
43
|
permission = Authpb::Permission.new(
|
43
44
|
permType: Etcdv3::Auth::PERMISSIONS[permission], key: key, range_end: range_end
|
44
45
|
)
|
@@ -47,74 +48,81 @@ class Etcdv3
|
|
47
48
|
name: name,
|
48
49
|
perm: permission
|
49
50
|
),
|
50
|
-
metadata: @metadata
|
51
|
+
metadata: @metadata,
|
52
|
+
deadline: deadline(timeout)
|
51
53
|
)
|
52
54
|
end
|
53
55
|
|
54
|
-
def role_revoke_permission(name, permission, key, range_end)
|
56
|
+
def role_revoke_permission(name, permission, key, range_end, timeout: nil)
|
55
57
|
@stub.role_revoke_permission(
|
56
58
|
Etcdserverpb::AuthRoleRevokePermissionRequest.new(
|
57
59
|
role: name,
|
58
60
|
key: key,
|
59
61
|
range_end: range_end
|
60
62
|
),
|
61
|
-
metadata: @metadata
|
63
|
+
metadata: @metadata,
|
64
|
+
deadline: deadline(timeout)
|
62
65
|
)
|
63
66
|
end
|
64
67
|
|
65
|
-
def role_list
|
68
|
+
def role_list(timeout: nil)
|
66
69
|
request = Etcdserverpb::AuthRoleListRequest.new
|
67
|
-
@stub.role_list(request, metadata: @metadata)
|
70
|
+
@stub.role_list(request, metadata: @metadata, deadline: deadline(timeout))
|
68
71
|
end
|
69
72
|
|
70
|
-
def user_list
|
73
|
+
def user_list(timeout: nil)
|
71
74
|
request = Etcdserverpb::AuthUserListRequest.new
|
72
|
-
@stub.user_list(request, metadata: @metadata)
|
75
|
+
@stub.user_list(request, metadata: @metadata, deadline: deadline(timeout))
|
73
76
|
end
|
74
77
|
|
75
|
-
def user_add(user, password)
|
78
|
+
def user_add(user, password, timeout: nil)
|
76
79
|
request = Etcdserverpb::AuthUserAddRequest.new(
|
77
80
|
name: user,
|
78
81
|
password: password
|
79
82
|
)
|
80
|
-
@stub.user_add(request, metadata: @metadata)
|
83
|
+
@stub.user_add(request, metadata: @metadata, deadline: deadline(timeout))
|
81
84
|
end
|
82
85
|
|
83
|
-
def user_delete(user)
|
86
|
+
def user_delete(user, timeout: nil)
|
84
87
|
request = Etcdserverpb::AuthUserDeleteRequest.new(name: user)
|
85
|
-
@stub.user_delete(request, metadata: @metadata)
|
88
|
+
@stub.user_delete(request, metadata: @metadata, deadline: deadline(timeout))
|
86
89
|
end
|
87
90
|
|
88
|
-
def user_get(user)
|
91
|
+
def user_get(user, timeout: nil)
|
89
92
|
request = Etcdserverpb::AuthUserGetRequest.new(name: user)
|
90
|
-
@stub.user_get(request, metadata: @metadata)
|
93
|
+
@stub.user_get(request, metadata: @metadata, deadline: deadline(timeout))
|
91
94
|
end
|
92
95
|
|
93
|
-
def user_change_password(user, new_password)
|
96
|
+
def user_change_password(user, new_password, timeout: nil)
|
94
97
|
request = Etcdserverpb::AuthUserChangePasswordRequest.new(
|
95
98
|
name: user,
|
96
99
|
password: new_password
|
97
100
|
)
|
98
|
-
@stub.user_change_password(request, metadata: @metadata)
|
101
|
+
@stub.user_change_password(request, metadata: @metadata, deadline: deadline(timeout))
|
99
102
|
end
|
100
103
|
|
101
|
-
def user_grant_role(user, role)
|
104
|
+
def user_grant_role(user, role, timeout: nil)
|
102
105
|
request = Etcdserverpb::AuthUserGrantRoleRequest.new(user: user, role: role)
|
103
|
-
@stub.user_grant_role(request, metadata: @metadata)
|
106
|
+
@stub.user_grant_role(request, metadata: @metadata, deadline: deadline(timeout))
|
104
107
|
end
|
105
108
|
|
106
|
-
def user_revoke_role(user, role)
|
109
|
+
def user_revoke_role(user, role, timeout: nil)
|
107
110
|
request = Etcdserverpb::AuthUserRevokeRoleRequest.new(name: user, role: role)
|
108
|
-
@stub.user_revoke_role(request, metadata: @metadata)
|
111
|
+
@stub.user_revoke_role(request, metadata: @metadata, deadline: deadline(timeout))
|
109
112
|
end
|
110
113
|
|
111
|
-
def generate_token(user, password)
|
114
|
+
def generate_token(user, password, timeout: nil)
|
112
115
|
request = Etcdserverpb::AuthenticateRequest.new(
|
113
116
|
name: user,
|
114
117
|
password: password
|
115
118
|
)
|
116
|
-
@stub.authenticate(request).token
|
119
|
+
@stub.authenticate(request, deadline: deadline(timeout)).token
|
117
120
|
end
|
118
121
|
|
122
|
+
private
|
123
|
+
|
124
|
+
def deadline(timeout)
|
125
|
+
Time.now.to_f + (timeout || @timeout)
|
126
|
+
end
|
119
127
|
end
|
120
128
|
end
|
data/lib/etcdv3/connection.rb
CHANGED
@@ -11,10 +11,11 @@ class Etcdv3
|
|
11
11
|
|
12
12
|
attr_reader :endpoint, :hostname, :handlers, :credentials
|
13
13
|
|
14
|
-
def initialize(url, metadata={})
|
14
|
+
def initialize(url, timeout, metadata={})
|
15
15
|
@endpoint = URI(url)
|
16
16
|
@hostname = "#{@endpoint.hostname}:#{@endpoint.port}"
|
17
17
|
@credentials = resolve_credentials
|
18
|
+
@timeout = timeout
|
18
19
|
@handlers = handler_map(metadata)
|
19
20
|
end
|
20
21
|
|
@@ -31,7 +32,7 @@ class Etcdv3
|
|
31
32
|
def handler_map(metadata={})
|
32
33
|
Hash[
|
33
34
|
HANDLERS.map do |key, klass|
|
34
|
-
[key, klass.new("#{@hostname}", @credentials, metadata)]
|
35
|
+
[key, klass.new("#{@hostname}", @credentials, @timeout, metadata)]
|
35
36
|
end
|
36
37
|
]
|
37
38
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
class Etcdv3
|
2
2
|
class ConnectionWrapper
|
3
3
|
|
4
|
-
attr_accessor :connection, :endpoints, :user, :password, :token
|
4
|
+
attr_accessor :connection, :endpoints, :user, :password, :token, :timeout
|
5
5
|
|
6
|
-
def initialize(endpoints)
|
6
|
+
def initialize(timeout, *endpoints)
|
7
7
|
@user, @password, @token = nil, nil, nil
|
8
|
-
@
|
8
|
+
@timeout = timeout
|
9
|
+
@endpoints = endpoints.map{|endpoint| Etcdv3::Connection.new(endpoint, @timeout) }
|
9
10
|
@connection = @endpoints.first
|
10
11
|
end
|
11
12
|
|
data/lib/etcdv3/kv.rb
CHANGED
@@ -3,24 +3,26 @@ class Etcdv3
|
|
3
3
|
class KV
|
4
4
|
include Etcdv3::KV::Requests
|
5
5
|
|
6
|
-
def initialize(hostname, credentials, metadata={})
|
6
|
+
def initialize(hostname, credentials, timeout, metadata={})
|
7
7
|
@stub = Etcdserverpb::KV::Stub.new(hostname, credentials)
|
8
|
+
@timeout = timeout
|
8
9
|
@metadata = metadata
|
9
10
|
end
|
10
11
|
|
11
12
|
def get(key, opts={})
|
12
|
-
|
13
|
+
timeout = opts.delete(:timeout)
|
14
|
+
@stub.range(get_request(key, opts), metadata: @metadata, deadline: deadline(timeout))
|
13
15
|
end
|
14
16
|
|
15
|
-
def del(key, range_end
|
16
|
-
@stub.delete_range(del_request(key, range_end), metadata: @metadata)
|
17
|
+
def del(key, range_end: '', timeout: nil)
|
18
|
+
@stub.delete_range(del_request(key, range_end), metadata: @metadata, deadline: deadline(timeout))
|
17
19
|
end
|
18
20
|
|
19
|
-
def put(key, value, lease
|
20
|
-
@stub.put(put_request(key, value, lease), metadata: @metadata)
|
21
|
+
def put(key, value, lease: nil, timeout: nil)
|
22
|
+
@stub.put(put_request(key, value, lease), metadata: @metadata, deadline: deadline(timeout))
|
21
23
|
end
|
22
24
|
|
23
|
-
def transaction(block)
|
25
|
+
def transaction(block, timeout: nil)
|
24
26
|
txn = Etcdv3::KV::Transaction.new
|
25
27
|
block.call(txn)
|
26
28
|
request = Etcdserverpb::TxnRequest.new(
|
@@ -28,11 +30,15 @@ class Etcdv3
|
|
28
30
|
success: generate_request_ops(txn.success),
|
29
31
|
failure: generate_request_ops(txn.failure)
|
30
32
|
)
|
31
|
-
@stub.txn(request)
|
33
|
+
@stub.txn(request, metadata: @metadata, deadline: deadline(timeout))
|
32
34
|
end
|
33
35
|
|
34
36
|
private
|
35
37
|
|
38
|
+
def deadline(timeout)
|
39
|
+
Time.now.to_f + (timeout || @timeout)
|
40
|
+
end
|
41
|
+
|
36
42
|
def generate_request_ops(requests)
|
37
43
|
requests.map do |request|
|
38
44
|
if request.is_a?(Etcdserverpb::RangeRequest)
|
data/lib/etcdv3/lease.rb
CHANGED
@@ -1,27 +1,30 @@
|
|
1
|
-
|
2
1
|
class Etcdv3
|
3
2
|
class Lease
|
4
|
-
def initialize(hostname, credentials, metadata={})
|
3
|
+
def initialize(hostname, credentials, timeout, metadata={})
|
5
4
|
@stub = Etcdserverpb::Lease::Stub.new(hostname, credentials)
|
5
|
+
@timeout = timeout
|
6
6
|
@metadata = metadata
|
7
7
|
end
|
8
8
|
|
9
|
-
def lease_grant(ttl)
|
9
|
+
def lease_grant(ttl, timeout: nil)
|
10
10
|
request = Etcdserverpb::LeaseGrantRequest.new(TTL: ttl)
|
11
|
-
@stub.lease_grant(request, metadata: @metadata)
|
11
|
+
@stub.lease_grant(request, metadata: @metadata, deadline: deadline(timeout))
|
12
12
|
end
|
13
13
|
|
14
|
-
def lease_revoke(id)
|
14
|
+
def lease_revoke(id, timeout: nil)
|
15
15
|
request = Etcdserverpb::LeaseRevokeRequest.new(ID: id)
|
16
|
-
@stub.lease_revoke(request, metadata: @metadata)
|
16
|
+
@stub.lease_revoke(request, metadata: @metadata, deadline: deadline(timeout))
|
17
17
|
end
|
18
18
|
|
19
|
-
def lease_ttl(id)
|
19
|
+
def lease_ttl(id, timeout: nil)
|
20
20
|
request = Etcdserverpb::LeaseTimeToLiveRequest.new(ID: id, keys: true)
|
21
|
-
@stub.lease_time_to_live(request, metadata: @metadata)
|
21
|
+
@stub.lease_time_to_live(request, metadata: @metadata, deadline: deadline(timeout))
|
22
22
|
end
|
23
23
|
|
24
|
+
private
|
24
25
|
|
25
|
-
|
26
|
+
def deadline(timeout)
|
27
|
+
Time.now.to_f + (timeout || @timeout)
|
28
|
+
end
|
26
29
|
end
|
27
30
|
end
|
data/lib/etcdv3/maintenance.rb
CHANGED
@@ -12,7 +12,7 @@ class Etcdv3
|
|
12
12
|
deactivate: 2
|
13
13
|
}
|
14
14
|
|
15
|
-
def initialize(hostname, credentials, metadata = {})
|
15
|
+
def initialize(hostname, credentials, _timeout, metadata = {})
|
16
16
|
@stub = Etcdserverpb::Maintenance::Stub.new(hostname, credentials)
|
17
17
|
@metadata = metadata
|
18
18
|
end
|
data/lib/etcdv3/version.rb
CHANGED
data/lib/etcdv3/watch.rb
CHANGED
data/lib/etcdv3.rb
CHANGED
@@ -16,11 +16,13 @@ class Etcdv3
|
|
16
16
|
extend Forwardable
|
17
17
|
def_delegators :@conn, :user, :password, :token, :endpoints, :authenticate
|
18
18
|
|
19
|
-
attr_reader :conn, :options
|
19
|
+
attr_reader :conn, :credentials, :options
|
20
|
+
DEFAULT_TIMEOUT = 120
|
20
21
|
|
21
22
|
def initialize(options = {})
|
22
23
|
@options = options
|
23
|
-
@
|
24
|
+
@timeout = options[:command_timeout] || DEFAULT_TIMEOUT
|
25
|
+
@conn = ConnectionWrapper.new(@timeout, *sanitized_endpoints)
|
24
26
|
warn "WARNING: `url` is deprecated. Please use `endpoints` instead." if @options.key?(:url)
|
25
27
|
authenticate(@options[:user], @options[:password]) if @options.key?(:user)
|
26
28
|
end
|
@@ -51,15 +53,15 @@ class Etcdv3
|
|
51
53
|
end
|
52
54
|
|
53
55
|
# Enables authentication.
|
54
|
-
def auth_enable
|
55
|
-
@conn.handle(:auth, 'auth_enable')
|
56
|
+
def auth_enable(timeout: nil)
|
57
|
+
@conn.handle(:auth, 'auth_enable', [timeout: timeout])
|
56
58
|
true
|
57
59
|
end
|
58
60
|
|
59
61
|
# Disables authentication.
|
60
62
|
# This will clear any active auth / token data.
|
61
|
-
def auth_disable
|
62
|
-
@conn.handle(:auth, 'auth_disable')
|
63
|
+
def auth_disable(timeout: nil)
|
64
|
+
@conn.handle(:auth, 'auth_disable', [timeout: timeout])
|
63
65
|
@conn.clear_authentication
|
64
66
|
true
|
65
67
|
end
|
@@ -77,97 +79,105 @@ class Etcdv3
|
|
77
79
|
# optional :max_mod_revision - integer
|
78
80
|
# optional :min_create_revision - integer
|
79
81
|
# optional :max_create_revision - integer
|
82
|
+
# optional :timeout - integer
|
80
83
|
def get(key, opts={})
|
81
84
|
@conn.handle(:kv, 'get', [key, opts])
|
82
85
|
end
|
83
86
|
|
84
87
|
# Inserts a new key.
|
85
|
-
|
86
|
-
|
88
|
+
# key - string
|
89
|
+
# value - string
|
90
|
+
# optional :lease - integer
|
91
|
+
# optional :timeout - integer
|
92
|
+
def put(key, value, opts={})
|
93
|
+
@conn.handle(:kv, 'put', [key, value, opts])
|
87
94
|
end
|
88
95
|
|
89
96
|
# Deletes a specified key
|
90
|
-
|
91
|
-
|
97
|
+
# key - string
|
98
|
+
# optional :range_end - string
|
99
|
+
# optional :timeout - integer
|
100
|
+
def del(key, opts={})
|
101
|
+
@conn.handle(:kv, 'del', [key, opts])
|
92
102
|
end
|
93
103
|
|
94
104
|
# Grant a lease with a specified TTL
|
95
|
-
def lease_grant(ttl)
|
96
|
-
@conn.handle(:lease, 'lease_grant', [ttl])
|
105
|
+
def lease_grant(ttl, timeout: nil)
|
106
|
+
@conn.handle(:lease, 'lease_grant', [ttl, timeout: timeout])
|
97
107
|
end
|
98
108
|
|
99
109
|
# Revokes lease and delete all attached keys
|
100
|
-
def lease_revoke(id)
|
101
|
-
@conn.handle(:lease, 'lease_revoke', [id])
|
110
|
+
def lease_revoke(id, timeout: nil)
|
111
|
+
@conn.handle(:lease, 'lease_revoke', [id, timeout: timeout])
|
102
112
|
end
|
103
113
|
|
104
114
|
# Returns information regarding the current state of the lease
|
105
|
-
def lease_ttl(id)
|
106
|
-
@conn.handle(:lease, 'lease_ttl', [id])
|
115
|
+
def lease_ttl(id, timeout: nil)
|
116
|
+
@conn.handle(:lease, 'lease_ttl', [id, timeout: timeout])
|
107
117
|
end
|
108
118
|
|
109
119
|
# List all roles.
|
110
|
-
def role_list
|
111
|
-
@conn.handle(:auth, 'role_list')
|
120
|
+
def role_list(timeout: nil)
|
121
|
+
@conn.handle(:auth, 'role_list', [timeout: timeout])
|
112
122
|
end
|
113
123
|
|
114
124
|
# Add role with specified name.
|
115
|
-
def role_add(name)
|
116
|
-
@conn.handle(:auth, 'role_add', [name])
|
125
|
+
def role_add(name, timeout: nil)
|
126
|
+
@conn.handle(:auth, 'role_add', [name, timeout: timeout])
|
117
127
|
end
|
118
128
|
|
119
129
|
# Fetches a specified role.
|
120
|
-
def role_get(name)
|
121
|
-
@conn.handle(:auth, 'role_get', [name])
|
130
|
+
def role_get(name, timeout: nil)
|
131
|
+
@conn.handle(:auth, 'role_get', [name, timeout: timeout])
|
122
132
|
end
|
123
133
|
|
124
134
|
# Delete role.
|
125
|
-
def role_delete(name)
|
126
|
-
@conn.handle(:auth, 'role_delete', [name])
|
135
|
+
def role_delete(name, timeout: nil)
|
136
|
+
@conn.handle(:auth, 'role_delete', [name, timeout: timeout])
|
127
137
|
end
|
128
138
|
|
129
139
|
# Grants a new permission to an existing role.
|
130
|
-
def role_grant_permission(name, permission, key, range_end
|
131
|
-
@conn.handle(:auth, 'role_grant_permission', [name, permission, key, range_end])
|
140
|
+
def role_grant_permission(name, permission, key, range_end: '', timeout: nil)
|
141
|
+
@conn.handle(:auth, 'role_grant_permission', [name, permission, key, range_end, timeout: timeout])
|
132
142
|
end
|
133
143
|
|
134
|
-
def role_revoke_permission(name, permission, key, range_end
|
135
|
-
@conn.handle(:auth, 'role_revoke_permission', [name, permission, key, range_end])
|
144
|
+
def role_revoke_permission(name, permission, key, range_end: '', timeout: nil)
|
145
|
+
@conn.handle(:auth, 'role_revoke_permission', [name, permission, key, range_end, timeout: timeout])
|
136
146
|
end
|
137
147
|
|
138
148
|
# Fetch specified user
|
139
|
-
def user_get(user)
|
140
|
-
@conn.handle(:auth, 'user_get', [user])
|
149
|
+
def user_get(user, timeout: nil)
|
150
|
+
@conn.handle(:auth, 'user_get', [user, timeout: timeout])
|
141
151
|
end
|
142
152
|
|
143
153
|
# Creates new user.
|
144
|
-
def user_add(user, password)
|
145
|
-
@conn.handle(:auth, 'user_add', [user, password])
|
154
|
+
def user_add(user, password, timeout: nil)
|
155
|
+
@conn.handle(:auth, 'user_add', [user, password, timeout: timeout])
|
146
156
|
end
|
147
157
|
|
148
158
|
# Delete specified user.
|
149
|
-
def user_delete(user)
|
150
|
-
@conn.handle(:auth, 'user_delete', [user])
|
159
|
+
def user_delete(user, timeout: nil)
|
160
|
+
@conn.handle(:auth, 'user_delete', [user, timeout: timeout])
|
151
161
|
end
|
152
162
|
|
153
163
|
# Changes the specified users password.
|
154
|
-
def user_change_password(user, new_password)
|
155
|
-
@conn.handle(:auth, 'user_change_password', [user, new_password])
|
164
|
+
def user_change_password(user, new_password, timeout: nil)
|
165
|
+
@conn.handle(:auth, 'user_change_password', [user, new_password, timeout: timeout])
|
156
166
|
end
|
157
167
|
|
158
168
|
# List all users.
|
159
|
-
def user_list
|
160
|
-
@conn.handle(:auth, 'user_list')
|
169
|
+
def user_list(timeout: nil)
|
170
|
+
@conn.handle(:auth, 'user_list', [timeout: timeout])
|
161
171
|
end
|
162
172
|
|
163
173
|
# Grants role to an existing user.
|
164
|
-
def user_grant_role(user, role)
|
165
|
-
@conn.handle(:auth, 'user_grant_role', [user, role])
|
174
|
+
def user_grant_role(user, role, timeout: nil)
|
175
|
+
@conn.handle(:auth, 'user_grant_role', [user, role, timeout: timeout])
|
166
176
|
end
|
167
177
|
|
168
178
|
# Revokes role from a specified user.
|
169
|
-
def user_revoke_role(user, role)
|
170
|
-
@conn.handle(:auth, 'user_revoke_role', [user, role])
|
179
|
+
def user_revoke_role(user, role, timeout: nil)
|
180
|
+
@conn.handle(:auth, 'user_revoke_role', [user, role, timeout: timeout])
|
171
181
|
end
|
172
182
|
|
173
183
|
# Watches for changes on a specified key range.
|
@@ -175,8 +185,8 @@ class Etcdv3
|
|
175
185
|
@conn.handle(:watch, 'watch', [key, range_end, block])
|
176
186
|
end
|
177
187
|
|
178
|
-
def transaction(&block)
|
179
|
-
@conn.handle(:kv, 'transaction', [block])
|
188
|
+
def transaction(timeout: timeout, &block)
|
189
|
+
@conn.handle(:kv, 'transaction', [block, timeout: timeout])
|
180
190
|
end
|
181
191
|
|
182
192
|
private
|
data/spec/etcdv3/auth_spec.rb
CHANGED
@@ -2,7 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Etcdv3::Auth do
|
4
4
|
|
5
|
-
let(:stub) { local_stub(Etcdv3::Auth) }
|
5
|
+
let(:stub) { local_stub(Etcdv3::Auth, 1) }
|
6
|
+
|
7
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :auth_disable, :auth_disable
|
6
8
|
|
7
9
|
describe '#user_add' do
|
8
10
|
after { stub.user_delete('boom') }
|
@@ -14,17 +16,21 @@ describe Etcdv3::Auth do
|
|
14
16
|
before { stub.user_add('user_get', 'password') }
|
15
17
|
after { stub.user_delete('user_get') }
|
16
18
|
subject { stub.user_get('user_get') }
|
19
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :user_get, :user_get, 'user_get'
|
17
20
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserGetResponse) }
|
18
21
|
end
|
19
22
|
|
20
23
|
describe '#user_list' do
|
21
24
|
subject { stub.user_list }
|
25
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :user_list, :user_list
|
22
26
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserListResponse) }
|
23
27
|
end
|
24
28
|
|
25
29
|
describe '#user_delete' do
|
26
30
|
before { stub.user_add('user_delete', 'test') }
|
27
31
|
subject { stub.user_delete('user_delete') }
|
32
|
+
after { stub.user_delete('user_delete') rescue nil }
|
33
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :user_delete, :user_delete, 'user_delete'
|
28
34
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserDeleteResponse) }
|
29
35
|
end
|
30
36
|
|
@@ -32,6 +38,7 @@ describe Etcdv3::Auth do
|
|
32
38
|
before { stub.user_add('grant_user', 'test') }
|
33
39
|
after { stub.user_delete('grant_user') }
|
34
40
|
subject { stub.user_grant_role('grant_user', 'root') }
|
41
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :user_grant_role, :user_grant_role, 'grant_user', 'root'
|
35
42
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserGrantRoleResponse) }
|
36
43
|
end
|
37
44
|
|
@@ -42,16 +49,21 @@ describe Etcdv3::Auth do
|
|
42
49
|
end
|
43
50
|
after { stub.user_delete('revoke_user') }
|
44
51
|
subject { stub.user_revoke_role('revoke_user', 'root') }
|
52
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :user_revoke_role, :user_revoke_role, 'revoke_user', 'root'
|
45
53
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserRevokeRoleResponse) }
|
46
54
|
end
|
47
55
|
|
48
56
|
describe '#role_add' do
|
49
|
-
after { stub.role_delete('role_add') }
|
50
57
|
subject { stub.role_add('role_add') }
|
51
58
|
it 'adds a role' do
|
52
59
|
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleAddResponse)
|
53
60
|
expect(stub.role_list.roles).to include('role_add')
|
54
61
|
end
|
62
|
+
describe "timeouts of role_add" do
|
63
|
+
after { stub.role_delete('role_add') rescue nil }
|
64
|
+
before { stub.role_delete('role_add') rescue nil }
|
65
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :role_add, :role_add, 'role_add'
|
66
|
+
end
|
55
67
|
end
|
56
68
|
|
57
69
|
describe '#role_get' do
|
@@ -59,19 +71,26 @@ describe Etcdv3::Auth do
|
|
59
71
|
after { stub.role_delete('role_get') }
|
60
72
|
subject { stub.role_get('role_get') }
|
61
73
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthRoleGetResponse) }
|
74
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :role_get, :role_get, 'role_get'
|
62
75
|
end
|
63
76
|
|
64
77
|
describe '#role_delete' do
|
65
78
|
before { stub.role_add('role_delete') }
|
66
79
|
subject { stub.role_delete('role_delete') }
|
80
|
+
|
67
81
|
it 'deletes role' do
|
68
82
|
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleDeleteResponse)
|
69
83
|
expect(stub.role_list.roles).to_not include('role_delete')
|
70
84
|
end
|
85
|
+
describe "timeouts of role_delete" do
|
86
|
+
after { stub.role_delete 'role_delete' rescue nil }
|
87
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :role_delete, :role_delete, 'role_delete'
|
88
|
+
end
|
71
89
|
end
|
72
90
|
|
73
91
|
describe '#role_list' do
|
74
92
|
subject { stub.role_list }
|
93
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :role_list, :role_list
|
75
94
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthRoleListResponse) }
|
76
95
|
end
|
77
96
|
|
@@ -79,6 +98,7 @@ describe Etcdv3::Auth do
|
|
79
98
|
before { stub.role_add('grant_perm') }
|
80
99
|
after { stub.role_delete('grant_perm') }
|
81
100
|
subject { stub.role_grant_permission('grant_perm', :write, 'c', 'cc') }
|
101
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :role_grant_permission, :role_grant_permission, 'grant_perm', :write, 'c', 'cc'
|
82
102
|
it 'sets permission' do
|
83
103
|
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleGrantPermissionResponse)
|
84
104
|
end
|
@@ -91,6 +111,9 @@ describe Etcdv3::Auth do
|
|
91
111
|
end
|
92
112
|
after { stub.role_delete('myrole') }
|
93
113
|
subject { stub.role_revoke_permission('myrole', :write, 'c', 'cc') }
|
114
|
+
|
115
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :role_revoke_permission, :role_revoke_permission, 'myrole', :write, 'c', 'cc'
|
116
|
+
|
94
117
|
it 'revokes permission' do
|
95
118
|
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleRevokePermissionResponse)
|
96
119
|
expect(stub.role_get('myrole').perm.size).to eq(0)
|
@@ -101,6 +124,7 @@ describe Etcdv3::Auth do
|
|
101
124
|
before { stub.user_add('myuser', 'test') }
|
102
125
|
after { stub.user_delete('myuser') }
|
103
126
|
subject { stub.user_change_password('myuser', 'boom') }
|
127
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :user_change_password, :user_change_password, 'myuser', 'boom'
|
104
128
|
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserChangePasswordResponse) }
|
105
129
|
end
|
106
130
|
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Etcdv3::Connection do
|
4
4
|
|
5
5
|
describe '#initialize - without metadata' do
|
6
|
-
subject { Etcdv3::Connection.new('http://localhost:2379') }
|
6
|
+
subject { Etcdv3::Connection.new('http://localhost:2379', 10) }
|
7
7
|
|
8
8
|
it { is_expected.to have_attributes(endpoint: URI('http://localhost:2379')) }
|
9
9
|
it { is_expected.to have_attributes(credentials: :this_channel_is_insecure) }
|
@@ -22,7 +22,7 @@ describe Etcdv3::Connection do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
describe '#initialize - with metadata' do
|
25
|
-
subject { Etcdv3::Connection.new('http://localhost:2379', token: 'token123') }
|
25
|
+
subject { Etcdv3::Connection.new('http://localhost:2379', 10, token: 'token123') }
|
26
26
|
|
27
27
|
[:kv, :maintenance, :lease, :watch, :auth].each do |handler|
|
28
28
|
let(:handler_stub) { subject.handlers[handler].instance_variable_get(:@stub) }
|
@@ -5,7 +5,7 @@ describe Etcdv3::ConnectionWrapper do
|
|
5
5
|
let(:endpoints) { ['http://localhost:2379', 'http://localhost:2389'] }
|
6
6
|
|
7
7
|
describe '#initialize' do
|
8
|
-
subject { Etcdv3::ConnectionWrapper.new(endpoints) }
|
8
|
+
subject { Etcdv3::ConnectionWrapper.new(10, *endpoints) }
|
9
9
|
it { is_expected.to have_attributes(user: nil, password: nil, token: nil) }
|
10
10
|
it 'sets hostnames in correct order' do
|
11
11
|
expect(subject.endpoints.map(&:hostname)).to eq(['localhost:2379', 'localhost:2389'])
|
@@ -16,7 +16,7 @@ describe Etcdv3::ConnectionWrapper do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe "#rotate_connection_endpoint" do
|
19
|
-
subject { Etcdv3::ConnectionWrapper.new(endpoints) }
|
19
|
+
subject { Etcdv3::ConnectionWrapper.new(10, *endpoints) }
|
20
20
|
before do
|
21
21
|
subject.rotate_connection_endpoint
|
22
22
|
end
|
data/spec/etcdv3/kv_spec.rb
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Etcdv3::KV do
|
4
|
-
let(:stub) { local_stub(Etcdv3::KV) }
|
5
|
-
let(:lease_stub) { local_stub(Etcdv3::Lease) }
|
4
|
+
let(:stub) { local_stub(Etcdv3::KV, 1) }
|
5
|
+
let(:lease_stub) { local_stub(Etcdv3::Lease, 1) }
|
6
|
+
|
7
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :get, :range, "key"
|
8
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :del, :delete_range, "key"
|
9
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :put, :put, "key", "val"
|
10
|
+
|
11
|
+
it "should timeout transactions" do
|
12
|
+
stub = local_stub(Etcdv3::KV, 0)
|
13
|
+
expect { stub.transaction(Proc.new { nil }) }.to raise_error(GRPC::DeadlineExceeded)
|
14
|
+
end
|
6
15
|
|
7
16
|
describe '#put' do
|
8
17
|
context 'without lease' do
|
@@ -12,7 +21,7 @@ describe Etcdv3::KV do
|
|
12
21
|
|
13
22
|
context 'with lease' do
|
14
23
|
let(:lease_id) { lease_stub.lease_grant(1)['ID'] }
|
15
|
-
subject { stub.put('lease', 'test', lease_id) }
|
24
|
+
subject { stub.put('lease', 'test', lease: lease_id) }
|
16
25
|
it { is_expected.to be_an_instance_of(Etcdserverpb::PutResponse) }
|
17
26
|
end
|
18
27
|
end
|
@@ -28,7 +37,7 @@ describe Etcdv3::KV do
|
|
28
37
|
it { is_expected.to be_an_instance_of(Etcdserverpb::DeleteRangeResponse) }
|
29
38
|
end
|
30
39
|
context 'del with range' do
|
31
|
-
subject { stub.del('test', 'testtt') }
|
40
|
+
subject { stub.del('test', range_end: 'testtt') }
|
32
41
|
it { is_expected.to be_an_instance_of(Etcdserverpb::DeleteRangeResponse) }
|
33
42
|
end
|
34
43
|
end
|
data/spec/etcdv3/lease_spec.rb
CHANGED
@@ -2,8 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Etcdv3::Lease do
|
4
4
|
|
5
|
-
let(:stub) { local_stub(Etcdv3::Lease) }
|
5
|
+
let(:stub) { local_stub(Etcdv3::Lease, 5) }
|
6
6
|
|
7
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :lease_grant, :lease_grant, 10
|
7
8
|
describe '#lease_grant' do
|
8
9
|
subject { stub.lease_grant(10) }
|
9
10
|
it 'grants lease' do
|
@@ -16,12 +17,22 @@ describe Etcdv3::Lease do
|
|
16
17
|
let(:id) { stub.lease_grant(60)['ID'] }
|
17
18
|
subject { stub.lease_revoke(id) }
|
18
19
|
it { is_expected.to be_an_instance_of(Etcdserverpb::LeaseRevokeResponse) }
|
20
|
+
|
21
|
+
it 'raises a GRPC:DeadlineExceeded if the request takes too long' do
|
22
|
+
stub = local_stub(Etcdv3::Lease, 0)
|
23
|
+
expect { stub.lease_revoke(id) }.to raise_error(GRPC::DeadlineExceeded)
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
describe '#lease_ttl' do
|
22
|
-
let(:
|
23
|
-
|
28
|
+
let(:stub) { local_stub(Etcdv3::Lease, 1) }
|
29
|
+
let(:lease_id) { stub.lease_grant(10)['ID'] }
|
30
|
+
subject { stub.lease_ttl(lease_id) }
|
24
31
|
it { is_expected.to be_an_instance_of(Etcdserverpb::LeaseTimeToLiveResponse) }
|
25
|
-
end
|
26
32
|
|
33
|
+
it 'raises a GRPC:DeadlineExceeded if the request takes too long' do
|
34
|
+
stub = local_stub(Etcdv3::Lease, 0)
|
35
|
+
expect { stub.lease_ttl(lease_id) }.to raise_error(GRPC::DeadlineExceeded)
|
36
|
+
end
|
37
|
+
end
|
27
38
|
end
|
data/spec/etcdv3_spec.rb
CHANGED
@@ -30,6 +30,19 @@ describe Etcdv3 do
|
|
30
30
|
expect{ auth_conn }.to_not raise_error
|
31
31
|
end
|
32
32
|
end
|
33
|
+
context 'with a timeout' do
|
34
|
+
it "sets the timeout in the kv handler" do
|
35
|
+
etcd = local_connection_with_timeout(1.5)
|
36
|
+
kv_handler = etcd.conn.connection.instance_variable_get("@handlers")[:kv]
|
37
|
+
expect(kv_handler.instance_variable_get "@timeout").to eq(1.5)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sets a default timeout" do
|
41
|
+
etcd = local_connection
|
42
|
+
kv_handler = etcd.conn.connection.instance_variable_get("@handlers")[:kv]
|
43
|
+
expect(kv_handler.instance_variable_get "@timeout").to eq(120)
|
44
|
+
end
|
45
|
+
end
|
33
46
|
end
|
34
47
|
|
35
48
|
describe '#version' do
|
@@ -87,11 +100,13 @@ describe Etcdv3 do
|
|
87
100
|
end
|
88
101
|
it { is_expected.to be_empty }
|
89
102
|
end
|
103
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :get, 'apple'
|
90
104
|
end
|
91
105
|
|
92
106
|
describe '#put' do
|
93
107
|
subject { conn.put('test', 'value') }
|
94
108
|
it { is_expected.to_not be_nil }
|
109
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :put, 'test', 'value'
|
95
110
|
end
|
96
111
|
|
97
112
|
describe '#del' do
|
@@ -108,35 +123,63 @@ describe Etcdv3 do
|
|
108
123
|
subject { conn.del('test', range_end: 'testtt') }
|
109
124
|
it { is_expected.to_not be_nil }
|
110
125
|
end
|
126
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :del, 'test'
|
111
127
|
end
|
112
128
|
|
113
129
|
describe '#lease_grant' do
|
114
130
|
subject { conn.lease_grant(2) }
|
115
131
|
it { is_expected.to_not be_nil }
|
132
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :lease_grant, 2
|
116
133
|
end
|
117
134
|
|
118
135
|
describe '#lease_revoke' do
|
119
136
|
let!(:lease_id) { conn.lease_grant(2)['ID'] }
|
120
137
|
subject { conn.lease_revoke(lease_id) }
|
121
138
|
it { is_expected.to_not be_nil }
|
139
|
+
it "raises a GRPC::DeadlineExceeded exception when it takes too long" do
|
140
|
+
expect do
|
141
|
+
conn.lease_revoke(lease_id, timeout: 0)
|
142
|
+
end.to raise_exception(GRPC::DeadlineExceeded)
|
143
|
+
end
|
144
|
+
it "accepts a timeout" do
|
145
|
+
expect{ conn.lease_revoke(lease_id, timeout: 10) }.to_not raise_exception
|
146
|
+
end
|
122
147
|
end
|
123
148
|
|
124
149
|
describe '#lease_ttl' do
|
125
150
|
let!(:lease_id) { conn.lease_grant(2)['ID'] }
|
126
151
|
subject { conn.lease_ttl(lease_id) }
|
127
152
|
it { is_expected.to_not be_nil }
|
153
|
+
it "raises a GRPC::DeadlineExceeded exception when it takes too long" do
|
154
|
+
expect do
|
155
|
+
conn.lease_ttl(lease_id, timeout: 0)
|
156
|
+
end.to raise_exception(GRPC::DeadlineExceeded)
|
157
|
+
end
|
158
|
+
it "accepts a timeout" do
|
159
|
+
expect{ conn.lease_ttl(lease_id, timeout: 10) }.to_not raise_exception
|
160
|
+
end
|
128
161
|
end
|
129
162
|
|
130
163
|
describe '#user_add' do
|
131
|
-
after { conn.user_delete('test') }
|
164
|
+
after { conn.user_delete('test') rescue nil }
|
132
165
|
subject { conn.user_add('test', 'user') }
|
133
166
|
it { is_expected.to_not be_nil }
|
167
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :user_add, 'test', 'user'
|
134
168
|
end
|
135
169
|
|
136
|
-
describe '#
|
170
|
+
describe '#user_get' do
|
171
|
+
after { conn.user_delete('test') rescue nil }
|
137
172
|
before { conn.user_add('test', 'user') }
|
173
|
+
subject { conn.user_get('test') }
|
174
|
+
it { is_expected.to_not be_nil }
|
175
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :user_get, 'test'
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#user_delete' do
|
179
|
+
before { conn.user_add('test', 'user') rescue nil }
|
138
180
|
subject { conn.user_delete('test') }
|
139
181
|
it { is_expected.to_not be_nil }
|
182
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :user_delete, 'test'
|
140
183
|
end
|
141
184
|
|
142
185
|
describe '#user_change_password' do
|
@@ -144,49 +187,78 @@ describe Etcdv3 do
|
|
144
187
|
after { conn.user_delete('change_user') }
|
145
188
|
subject { conn.user_change_password('change_user', 'new_pass') }
|
146
189
|
it { is_expected.to_not be_nil }
|
190
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :user_change_password, 'change_user', 'new_pass'
|
147
191
|
end
|
148
192
|
|
149
193
|
describe '#user_list' do
|
150
194
|
subject { conn.user_list }
|
151
195
|
it { is_expected.to_not be_nil }
|
196
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :user_list
|
152
197
|
end
|
153
198
|
|
154
199
|
describe '#role_list' do
|
155
200
|
subject { conn.role_list }
|
156
201
|
it { is_expected.to_not be_nil }
|
202
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :role_list
|
157
203
|
end
|
158
204
|
|
159
205
|
describe '#role_add' do
|
160
206
|
subject { conn.role_add('role_add') }
|
161
207
|
it { is_expected.to_not be_nil }
|
208
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :role_add, 'role'
|
209
|
+
end
|
210
|
+
|
211
|
+
describe '#role_get' do
|
212
|
+
before { conn.role_add('role_get') }
|
213
|
+
after { conn.role_delete('role_get') }
|
214
|
+
subject { conn.role_get('role_get') }
|
215
|
+
it { is_expected.to_not be_nil }
|
216
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :role_get, 'role_get'
|
162
217
|
end
|
163
218
|
|
164
219
|
describe '#role_delete' do
|
165
220
|
before { conn.role_add('role_delete') }
|
221
|
+
after { conn.role_delete('role_delete') rescue nil }
|
166
222
|
subject { conn.role_delete('role_delete') }
|
167
223
|
it { is_expected.to_not be_nil }
|
224
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :role_delete, 'role_delete'
|
168
225
|
end
|
169
226
|
|
170
227
|
describe '#user_grant_role' do
|
171
228
|
before { conn.user_add('grant_me', 'pass') }
|
229
|
+
after { conn.user_delete('grant_me') rescue nil}
|
172
230
|
subject { conn.user_grant_role('grant_me', 'root') }
|
173
231
|
it { is_expected.to_not be_nil }
|
232
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :user_grant_role, 'grant_me', 'root'
|
174
233
|
end
|
175
234
|
|
176
235
|
describe '#user_revoke_role' do
|
236
|
+
before { conn.user_add('grant_me', 'pass') }
|
237
|
+
before { conn.user_grant_role('grant_me', 'root') }
|
238
|
+
after { conn.user_delete('grant_me') rescue nil}
|
177
239
|
subject { conn.user_revoke_role('grant_me', 'root') }
|
178
240
|
it { is_expected.to_not be_nil }
|
241
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :user_revoke_role, 'grant_me', 'root'
|
179
242
|
end
|
180
243
|
|
181
244
|
describe '#role_grant_permission' do
|
182
245
|
before { conn.role_add('grant') }
|
183
|
-
|
246
|
+
after { conn.role_delete('grant') }
|
247
|
+
subject { conn.role_grant_permission('grant', :readwrite, 'a', {range_end: 'Z'}) }
|
184
248
|
it { is_expected.to_not be_nil }
|
249
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :role_grant_permission, 'grant', :readwrite, 'a'
|
185
250
|
end
|
186
251
|
|
187
|
-
describe '#
|
188
|
-
|
252
|
+
describe '#role_revoke_permission' do
|
253
|
+
before { conn.role_add('grant') }
|
254
|
+
before { conn.role_grant_permission('grant', :readwrite, 'a', range_end: 'Z') }
|
255
|
+
after { conn.role_delete('grant') }
|
256
|
+
subject { conn.role_revoke_permission('grant', :readwrite, 'a', range_end: 'Z') }
|
189
257
|
it { is_expected.to_not be_nil }
|
258
|
+
describe "the timeouts" do
|
259
|
+
before { conn.role_grant_permission('grant', :readwrite, 'a') }
|
260
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :role_revoke_permission, 'grant', :readwrite, 'a'
|
261
|
+
end
|
190
262
|
end
|
191
263
|
|
192
264
|
describe '#auth_disable' do
|
@@ -197,8 +269,10 @@ describe Etcdv3 do
|
|
197
269
|
conn.authenticate('root', 'test')
|
198
270
|
end
|
199
271
|
after { conn.user_delete('root') }
|
272
|
+
after { conn.auth_disable }
|
200
273
|
subject { conn.auth_disable }
|
201
274
|
it { is_expected.to eq(true) }
|
275
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :auth_disable
|
202
276
|
end
|
203
277
|
|
204
278
|
describe '#auth_enable' do
|
@@ -207,12 +281,13 @@ describe Etcdv3 do
|
|
207
281
|
conn.user_grant_role('root', 'root')
|
208
282
|
end
|
209
283
|
after do
|
210
|
-
conn.authenticate('root', 'test')
|
284
|
+
conn.authenticate('root', 'test') rescue nil
|
211
285
|
conn.auth_disable
|
212
286
|
conn.user_delete('root')
|
213
287
|
end
|
214
288
|
subject { conn.auth_enable }
|
215
289
|
it { is_expected.to eq(true) }
|
290
|
+
it_should_behave_like "Etcdv3 instance using a timeout", :auth_enable
|
216
291
|
end
|
217
292
|
|
218
293
|
describe "#authenticate" do
|
@@ -263,6 +338,24 @@ describe Etcdv3 do
|
|
263
338
|
it 'sets correct key' do
|
264
339
|
expect(conn.get('txn-test').kvs.first.value).to eq('success')
|
265
340
|
end
|
341
|
+
it "raises a GRPC::DeadlineExceeded exception when it takes too long" do
|
342
|
+
expect do
|
343
|
+
conn.transaction(timeout: 0) do |txn|
|
344
|
+
txn.compare = [ txn.value('txn', :equal, 'value') ]
|
345
|
+
txn.success = [ txn.put('txn-test', 'success') ]
|
346
|
+
txn.failure = [ txn.put('txn-test', 'failed') ]
|
347
|
+
end
|
348
|
+
end.to raise_exception(GRPC::DeadlineExceeded)
|
349
|
+
end
|
350
|
+
it "accepts a timeout" do
|
351
|
+
expect do
|
352
|
+
conn.transaction(timeout: 1) do |txn|
|
353
|
+
txn.compare = [ txn.value('txn', :equal, 'value') ]
|
354
|
+
txn.success = [ txn.put('txn-test', 'success') ]
|
355
|
+
txn.failure = [ txn.put('txn-test', 'failed') ]
|
356
|
+
end
|
357
|
+
end.to_not raise_exception
|
358
|
+
end
|
266
359
|
end
|
267
360
|
context "success, value with lease" do
|
268
361
|
let!(:lease_id) { conn.lease_grant(2)['ID'] }
|
data/spec/helpers/connections.rb
CHANGED
@@ -9,8 +9,12 @@ module Helpers
|
|
9
9
|
Etcdv3.new(endpoints: endpoints)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def local_connection_with_timeout(timeout)
|
13
|
+
Etcdv3.new(endpoints: "http://#{local_url}", command_timeout: timeout)
|
14
|
+
end
|
15
|
+
|
16
|
+
def local_stub(interface, timeout=nil)
|
17
|
+
interface.new(local_url, :this_channel_is_insecure, timeout, {})
|
14
18
|
end
|
15
19
|
|
16
20
|
def local_url
|
@@ -0,0 +1,43 @@
|
|
1
|
+
shared_examples_for "a method with a GRPC timeout" do |stub_class, method_name, expectation_target, *args|
|
2
|
+
context "#{stub_class} timeouts for #{method_name}" do
|
3
|
+
let(:handler) { local_stub(stub_class, 5) }
|
4
|
+
let(:client_stub) { handler.instance_variable_get "@stub"}
|
5
|
+
it 'uses the timeout value' do
|
6
|
+
start_time = Time.now
|
7
|
+
deadline_time = start_time.to_f + 5
|
8
|
+
allow(Time).to receive(:now).and_return(start_time)
|
9
|
+
|
10
|
+
expect(client_stub).to receive(expectation_target).with(anything, hash_including(deadline: deadline_time)).and_call_original
|
11
|
+
|
12
|
+
handler.public_send(method_name, *args)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can have a seperate timeout passed in" do
|
16
|
+
start_time = Time.now
|
17
|
+
deadline_time = start_time.to_f + 1
|
18
|
+
allow(Time).to receive(:now).and_return(start_time)
|
19
|
+
expect(client_stub).to receive(expectation_target).with(anything, hash_including(deadline: deadline_time)).and_call_original
|
20
|
+
handler.public_send(method_name, *args, timeout: 1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'raises a GRPC:DeadlineExceeded if the request takes too long' do
|
24
|
+
handler = local_stub(stub_class, 0)
|
25
|
+
expect {handler.public_send(method_name, *args)}.to raise_error(GRPC::DeadlineExceeded)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
shared_examples_for "Etcdv3 instance using a timeout" do |command, *args|
|
31
|
+
it "raises a GRPC::DeadlineExceeded exception when it takes too long" do
|
32
|
+
expect do
|
33
|
+
test_args = args.dup
|
34
|
+
test_args.push({timeout: 0})
|
35
|
+
conn.public_send(command, *test_args)
|
36
|
+
end.to raise_exception(GRPC::DeadlineExceeded)
|
37
|
+
end
|
38
|
+
it "accepts a timeout" do
|
39
|
+
test_args = args.dup
|
40
|
+
test_args.push({timeout: 10})
|
41
|
+
expect{ conn.public_send(command, *test_args) }.to_not raise_exception
|
42
|
+
end
|
43
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: etcdv3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shaun Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- spec/etcdv3/maintenance_spec.rb
|
82
82
|
- spec/etcdv3_spec.rb
|
83
83
|
- spec/helpers/connections.rb
|
84
|
+
- spec/helpers/shared_examples_for_timeout.rb
|
84
85
|
- spec/helpers/test_instance.rb
|
85
86
|
- spec/spec_helper.rb
|
86
87
|
homepage: https://github.com/davissp14/etcdv3-ruby
|
@@ -116,5 +117,6 @@ test_files:
|
|
116
117
|
- spec/etcdv3/maintenance_spec.rb
|
117
118
|
- spec/etcdv3_spec.rb
|
118
119
|
- spec/helpers/connections.rb
|
120
|
+
- spec/helpers/shared_examples_for_timeout.rb
|
119
121
|
- spec/helpers/test_instance.rb
|
120
122
|
- spec/spec_helper.rb
|