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
         |