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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee9b93afa5a82fab266b356a684bd201168046ae
4
- data.tar.gz: 9b47ef6e8dd0d1caf32ec0b8453d55f771142e56
3
+ metadata.gz: 548056c69c835ad0572929605d5d7e5660c5fcb3
4
+ data.tar.gz: b619d3ece12e977d1b4de36f82582f748e88c1ce
5
5
  SHA512:
6
- metadata.gz: bf58b24446932842b4984452443fdc71b38610f8764d74875ef6bf6ef66fb8e85db268686c1546b4f8fe49414e19225b68477787177282a0ccf94cb1276a2c17
7
- data.tar.gz: 4b1facb0dbc8a96bc1462a5053e96db38ffa781609048a19b742490f3dd0dc0e53983e2788164a96470c2ab3ea4a42fae469c698e134e89703f30cdd3c3fae0a
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
- # Example
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
@@ -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
- @endpoints = endpoints.map{|endpoint| Etcdv3::Connection.new(endpoint) }
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
- @stub.range(get_request(key, opts), metadata: @metadata)
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=nil)
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  class Etcdv3
2
- VERSION = '0.7.0'.freeze
2
+ VERSION = '0.8.0'.freeze
3
3
  end
data/lib/etcdv3/watch.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  class Etcdv3
2
2
  class Watch
3
3
 
4
- def initialize(hostname, credentials, metadata = {})
4
+ def initialize(hostname, credentials, _timeout, metadata = {})
5
5
  @stub = Etcdserverpb::Watch::Stub.new(hostname, credentials)
6
6
  @metadata = metadata
7
7
  end
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
- @conn = ConnectionWrapper.new(sanitized_endpoints)
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
- def put(key, value, lease_id: nil)
86
- @conn.handle(:kv, 'put', [key, value, lease_id])
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
- def del(key, range_end: '')
91
- @conn.handle(:kv, 'del', [key, range_end])
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
@@ -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
@@ -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
@@ -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(:id) { stub.lease_grant(10)['ID'] }
23
- subject { stub.lease_ttl(id) }
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 '#user_delete' do
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
- subject { conn.role_grant_permission('grant', :readwrite, 'a', 'Z') }
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 '#revoke_permission_to_role' do
188
- subject { conn.role_revoke_permission('grant', :readwrite, 'a', 'Z') }
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'] }
@@ -9,8 +9,12 @@ module Helpers
9
9
  Etcdv3.new(endpoints: endpoints)
10
10
  end
11
11
 
12
- def local_stub(interface)
13
- interface.new(local_url, :this_channel_is_insecure, {})
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
@@ -6,6 +6,7 @@ require 'simplecov'
6
6
  require 'codecov'
7
7
  require 'helpers/test_instance'
8
8
  require 'helpers/connections'
9
+ require 'helpers/shared_examples_for_timeout'
9
10
 
10
11
  SimpleCov.start
11
12
  SimpleCov.formatter = SimpleCov::Formatter::Codecov
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.7.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-09-17 00:00:00.000000000 Z
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