etcdv3 0.7.0 → 0.8.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/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
|