google-gax 0.8.4 → 0.8.5

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: 7fb40d292b456b41ebc200bcffb22da7e4ca50da
4
- data.tar.gz: b9fcf56ab01370e96b5994882ebb920269d40a73
3
+ metadata.gz: 798b058e269c1439eae63e4902b7558b5be005c0
4
+ data.tar.gz: 3ee51d01d9addb3d2edb034efb196478fcf0c4ae
5
5
  SHA512:
6
- metadata.gz: 721417435023acd011e44287fa6d4cbeabc98b45f411f5d87bdd4a3bc672ea92d991e29957fadfa394d98b4d5696ca88cc55ed837ccbebc7513e934ae1d58cca
7
- data.tar.gz: dda6c253c18408035897de6c50724609e03f3d7cfa799c2d246b981ad950c9a5313379da769723ea1f8c55f46192ee70f6d6528973cacf3db44ad7397c860c9d
6
+ metadata.gz: 84f4d99c7830db006033237c1f92f3de3b7d8dc4a43e4357b182f0cfabc52df76e6c7d3f0863ce6b89307221c31c3a50cf39573d116e8b4e78d28e42e4a11fb3
7
+ data.tar.gz: 95ab0e0670ba6eeb51cc6a2a98ba93f4beda3246be5ac43a9e6b3b344aedb9a369d6d01ccb32710f56ac34797a1f22d2d7ecb28f9beb221753f2af8d636c3835
data/lib/google/gax.rb CHANGED
@@ -29,6 +29,7 @@
29
29
 
30
30
  require 'google/gax/api_callable'
31
31
  require 'google/gax/constants'
32
+ require 'google/gax/credentials'
32
33
  require 'google/gax/errors'
33
34
  require 'google/gax/path_template'
34
35
  require 'google/gax/settings'
@@ -0,0 +1,150 @@
1
+ # Copyright 2017, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ require 'forwardable'
31
+ require 'googleauth'
32
+ require 'json'
33
+ require 'signet/oauth_2/client'
34
+
35
+ module Google
36
+ module Gax
37
+ # @private
38
+ # Represents the OAuth 2.0 signing logic.
39
+ # This class is intended to be inherited by API-specific classes
40
+ # which overrides the SCOPE constant.
41
+ class Credentials
42
+ TOKEN_CREDENTIAL_URI = 'https://accounts.google.com/o/oauth2/token'.freeze
43
+ AUDIENCE = 'https://accounts.google.com/o/oauth2/token'.freeze
44
+ SCOPE = [].freeze
45
+ PATH_ENV_VARS = [].freeze
46
+ JSON_ENV_VARS = [].freeze
47
+ DEFAULT_PATHS = [].freeze
48
+
49
+ attr_accessor :client
50
+
51
+ ##
52
+ # Delegate client methods to the client object.
53
+ extend Forwardable
54
+ def_delegators :@client,
55
+ :token_credential_uri, :audience,
56
+ :scope, :issuer, :signing_key, :updater_proc
57
+
58
+ def initialize(keyfile, scope: nil)
59
+ verify_keyfile_provided! keyfile
60
+ if keyfile.is_a? Signet::OAuth2::Client
61
+ @client = keyfile
62
+ elsif keyfile.is_a? Hash
63
+ hash = stringify_hash_keys keyfile
64
+ hash['scope'] ||= scope
65
+ @client = init_client hash
66
+ else
67
+ verify_keyfile_exists! keyfile
68
+ json = JSON.parse ::File.read(keyfile)
69
+ json['scope'] ||= scope
70
+ @client = init_client json
71
+ end
72
+ @client.fetch_access_token!
73
+ end
74
+
75
+ ##
76
+ # Returns the default credentials.
77
+ #
78
+ def self.default(scope: nil)
79
+ env = ->(v) { ENV[v] }
80
+ json = lambda do |v|
81
+ unless ENV[v].nil?
82
+ begin
83
+ JSON.parse ENV[v]
84
+ rescue
85
+ nil
86
+ end
87
+ end
88
+ end
89
+ path = ->(p) { ::File.file? p }
90
+
91
+ # First try to find keyfile file from environment variables.
92
+ self::PATH_ENV_VARS.map(&env).compact.select(&path)
93
+ .each do |file|
94
+ return new file, scope: scope
95
+ end
96
+ # Second try to find keyfile json from environment variables.
97
+ self::JSON_ENV_VARS.map(&json).compact.each do |hash|
98
+ return new hash, scope: scope
99
+ end
100
+ # Third try to find keyfile file from known file paths.
101
+ self::DEFAULT_PATHS.select(&path).each do |file|
102
+ return new file, scope: scope
103
+ end
104
+ # Finally get instantiated client from Google::Auth.
105
+ scope ||= self::SCOPE
106
+ client = Google::Auth.get_application_default scope
107
+ new client
108
+ end
109
+
110
+ protected
111
+
112
+ # Verify that the keyfile argument is provided.
113
+ def verify_keyfile_provided!(keyfile)
114
+ return unless keyfile.nil?
115
+ raise 'The keyfile passed to Google::Gax::Credentials.new was nil.'
116
+ end
117
+
118
+ # Verify that the keyfile argument is a file.
119
+ def verify_keyfile_exists!(keyfile)
120
+ exists = ::File.file? keyfile
121
+ raise "The keyfile '#{keyfile}' is not a valid file." unless exists
122
+ end
123
+
124
+ # Initializes the Signet client.
125
+ def init_client(keyfile)
126
+ client_opts = client_options keyfile
127
+ Signet::OAuth2::Client.new client_opts
128
+ end
129
+
130
+ # returns a new Hash with string keys instead of symbol keys.
131
+ def stringify_hash_keys(hash)
132
+ Hash[hash.map { |k, v| [k.to_s, v] }]
133
+ end
134
+
135
+ def client_options(options)
136
+ # Keyfile options have higher priority over constructor defaults
137
+ options['token_credential_uri'] ||= self.class::TOKEN_CREDENTIAL_URI
138
+ options['audience'] ||= self.class::AUDIENCE
139
+ options['scope'] ||= self.class::SCOPE
140
+
141
+ # client options for initializing signet client
142
+ { token_credential_uri: options['token_credential_uri'],
143
+ audience: options['audience'],
144
+ scope: Array(options['scope']),
145
+ issuer: options['client_email'],
146
+ signing_key: OpenSSL::PKey::RSA.new(options['private_key']) }
147
+ end
148
+ end
149
+ end
150
+ end
@@ -29,6 +29,7 @@
29
29
 
30
30
  require 'grpc'
31
31
  require 'googleauth'
32
+ require 'google/gax/errors'
32
33
 
33
34
  module Google
34
35
  module Gax
@@ -50,14 +51,14 @@ module Google
50
51
  #
51
52
  # @param port [Fixnum] The port on which to connect to the remote host.
52
53
  #
53
- # @param chan_creds [Grpc::Core::ChannelCredentials]
54
- # A ChannelCredentials object for use with an SSL-enabled Channel.
55
- # If nil, credentials are pulled from a default location.
56
- #
57
54
  # @param channel [Object]
58
55
  # A Channel object through which to make calls. If nil, a secure
59
56
  # channel is constructed.
60
57
  #
58
+ # @param chan_creds [Grpc::Core::ChannelCredentials]
59
+ # A ChannelCredentials object for use with an SSL-enabled Channel.
60
+ # If nil, credentials are pulled from a default location.
61
+ #
61
62
  # @param updater_proc [Proc]
62
63
  # A function that transforms the metadata for requests, e.g., to give
63
64
  # OAuth credentials.
@@ -66,32 +67,49 @@ module Google
66
67
  # The OAuth scopes for this service. This parameter is ignored if
67
68
  # a custom metadata_transformer is supplied.
68
69
  #
70
+ # @raise [ArgumentError] if a combination channel, chan_creds, and
71
+ # updater_proc are passed.
72
+ #
69
73
  # @yield [address, creds]
70
74
  # the generated gRPC method to create a stub.
71
75
  #
72
76
  # @return A gRPC client stub.
73
77
  def create_stub(service_path,
74
78
  port,
75
- chan_creds: nil,
76
79
  channel: nil,
80
+ chan_creds: nil,
77
81
  updater_proc: nil,
78
82
  scopes: nil)
83
+ verify_params(channel, chan_creds, updater_proc)
79
84
  address = "#{service_path}:#{port}"
80
- if channel.nil?
81
- chan_creds = GRPC::Core::ChannelCredentials.new if chan_creds.nil?
85
+ if channel
86
+ yield(address, nil, channel_override: channel)
87
+ elsif chan_creds
88
+ yield(address, chan_creds)
89
+ else
82
90
  if updater_proc.nil?
83
91
  auth_creds = Google::Auth.get_application_default(scopes)
84
92
  updater_proc = auth_creds.updater_proc
85
93
  end
86
94
  call_creds = GRPC::Core::CallCredentials.new(updater_proc)
87
- chan_creds = chan_creds.compose(call_creds)
95
+ chan_creds = GRPC::Core::ChannelCredentials.new.compose(call_creds)
88
96
  yield(address, chan_creds)
89
- else
90
- yield(address, nil, channel_override: channel)
91
97
  end
92
98
  end
93
99
 
94
100
  module_function :create_stub
101
+
102
+ def self.verify_params(channel, chan_creds, updater_proc)
103
+ if (channel && chan_creds) ||
104
+ (channel && updater_proc) ||
105
+ (chan_creds && updater_proc)
106
+ raise ArgumentError, 'Only one of channel, chan_creds, and ' \
107
+ 'updater_proc should be passed into ' \
108
+ 'Google::Gax::Grpc#create_stub.'
109
+ end
110
+ end
111
+
112
+ private_class_method :verify_params
95
113
  end
96
114
  end
97
115
  end
@@ -30,6 +30,13 @@
30
30
  module Google
31
31
  # Gax defines Google API extensions
32
32
  module Gax
33
+ # Regex used by gapic to find version files and directories.
34
+ VERSION_MATCHER = /
35
+ ([vV]\d+) # Major version eg: v1
36
+ ([pP]\d+)? # Point release eg: p2
37
+ (([aA]lpha|[bB]eta)\d*)? # Release level eg: alpha3
38
+ /x
39
+
33
40
  # Creates an instance of a protobuf message from a hash that may include
34
41
  # nested hashes. `google/protobuf` allows for the instantiation of protobuf
35
42
  # messages using hashes but does not allow for nested hashes to instantiate
@@ -29,6 +29,6 @@
29
29
 
30
30
  module Google
31
31
  module Gax
32
- VERSION = '0.8.4'.freeze
32
+ VERSION = '0.8.5'.freeze
33
33
  end
34
34
  end
@@ -0,0 +1,108 @@
1
+ # Copyright 2017, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ require 'google/gax/credentials'
31
+
32
+ # This test is testing the private class Google::Gax::Credentials. We want to
33
+ # make sure that the passed in scope propogates to the Signet object. This means
34
+ # testing the private API, which is generally frowned on.
35
+ describe Google::Gax::Credentials, :private do
36
+ let(:default_keyfile_hash) do
37
+ {
38
+ 'private_key_id' => 'testabc1234567890xyz',
39
+ 'private_key' => "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBAOyi0Hy1l4Ym2m2o71Q0TF4O9E81isZEsX0bb+Bqz1SXEaSxLiXM\nUZE8wu0eEXivXuZg6QVCW/5l+f2+9UPrdNUCAwEAAQJAJkqubA/Chj3RSL92guy3\nktzeodarLyw8gF8pOmpuRGSiEo/OLTeRUMKKD1/kX4f9sxf3qDhB4e7dulXR1co/\nIQIhAPx8kMW4XTTL6lJYd2K5GrH8uBMp8qL5ya3/XHrBgw3dAiEA7+3Iw3ULTn2I\n1J34WlJ2D5fbzMzB4FAHUNEV7Ys3f1kCIQDtUahCMChrl7+H5t9QS+xrn77lRGhs\nB50pjvy95WXpgQIhAI2joW6JzTfz8fAapb+kiJ/h9Vcs1ZN3iyoRlNFb61JZAiA8\nNy5NyNrMVwtB/lfJf1dAK/p/Bwd8LZLtgM6PapRfgw==\n-----END RSA PRIVATE KEY-----\n",
40
+ 'client_email' => 'credz-testabc1234567890xyz@developer.gserviceaccount.com',
41
+ 'client_id' => 'credz-testabc1234567890xyz.apps.googleusercontent.com',
42
+ 'type' => 'service_account'
43
+ }
44
+ end
45
+
46
+ it 'uses a default scope' do
47
+ mocked_signet = double('Signet::OAuth2::Client')
48
+ allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
49
+ allow(Signet::OAuth2::Client).to receive(:new) do |options|
50
+ expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
51
+ expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
52
+ expect(options[:scope]).to eq([])
53
+ expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
54
+ expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
55
+
56
+ mocked_signet
57
+ end
58
+
59
+ Google::Gax::Credentials.new default_keyfile_hash
60
+ end
61
+
62
+ it 'uses a custom scope' do
63
+ mocked_signet = double('Signet::OAuth2::Client')
64
+ allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
65
+ allow(Signet::OAuth2::Client).to receive(:new) do |options|
66
+ expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
67
+ expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
68
+ expect(options[:scope]).to eq(['http://example.com/scope'])
69
+ expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
70
+ expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
71
+
72
+ mocked_signet
73
+ end
74
+
75
+ Google::Gax::Credentials.new default_keyfile_hash, scope: 'http://example.com/scope'
76
+ end
77
+
78
+ it 'can be subclassed to pass in other env paths' do
79
+ TEST_PATH_ENV_VAR = 'TEST_PATH'.freeze
80
+ TEST_PATH_ENV_VAL = '/unknown/path/to/file.txt'.freeze
81
+ TEST_JSON_ENV_VAR = 'TEST_JSON_VARS'.freeze
82
+
83
+ ENV[TEST_PATH_ENV_VAR] = TEST_PATH_ENV_VAL
84
+ ENV[TEST_JSON_ENV_VAR] = JSON.generate(default_keyfile_hash)
85
+
86
+ class TestCredentials < Google::Gax::Credentials
87
+ SCOPE = 'http://example.com/scope'.freeze
88
+ PATH_ENV_VARS = [TEST_PATH_ENV_VAR].freeze
89
+ JSON_ENV_VARS = [TEST_JSON_ENV_VAR].freeze
90
+ end
91
+
92
+ allow(::File).to receive(:file?).with(TEST_PATH_ENV_VAL) { false }
93
+
94
+ mocked_signet = double('Signet::OAuth2::Client')
95
+ allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
96
+ allow(Signet::OAuth2::Client).to receive(:new) do |options|
97
+ expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
98
+ expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
99
+ expect(options[:scope]).to eq(['http://example.com/scope'])
100
+ expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
101
+ expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
102
+
103
+ mocked_signet
104
+ end
105
+
106
+ TestCredentials.default
107
+ end
108
+ end
@@ -0,0 +1,117 @@
1
+ # Copyright 2017, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ require 'google/gax/grpc'
31
+
32
+ describe Google::Gax::Grpc do
33
+ describe '#create_stub' do
34
+ it 'yields constructed channel credentials' do
35
+ mock = instance_double(GRPC::Core::ChannelCredentials)
36
+ composed_mock = instance_double(GRPC::Core::ChannelCredentials)
37
+ default_creds = instance_double(Google::Auth::ServiceAccountCredentials)
38
+ updater_proc = proc {}
39
+
40
+ allow(Google::Auth)
41
+ .to receive(:get_application_default).and_return(default_creds)
42
+ allow(default_creds).to receive(:updater_proc).and_return(updater_proc)
43
+ allow(mock).to receive(:compose).and_return(composed_mock)
44
+ allow(GRPC::Core::ChannelCredentials).to receive(:new).and_return(mock)
45
+
46
+ expect do |blk|
47
+ Google::Gax::Grpc.create_stub('service', 'port', &blk)
48
+ end.to yield_with_args('service:port', composed_mock)
49
+ end
50
+
51
+ it 'yields given channel' do
52
+ mock = instance_double(GRPC::Core::Channel)
53
+ expect do |blk|
54
+ Google::Gax::Grpc.create_stub('service', 'port', channel: mock, &blk)
55
+ end.to yield_with_args('service:port', nil, channel_override: mock)
56
+ end
57
+
58
+ it 'yields given channel credentials' do
59
+ mock = instance_double(GRPC::Core::ChannelCredentials)
60
+ expect do |blk|
61
+ Google::Gax::Grpc.create_stub('service', 'port', chan_creds: mock, &blk)
62
+ end.to yield_with_args('service:port', mock)
63
+ end
64
+
65
+ it 'yields channel credentials composed of the given updater_proc' do
66
+ chan_creds = instance_double(GRPC::Core::ChannelCredentials)
67
+ composed_chan_creds = instance_double(GRPC::Core::ChannelCredentials)
68
+ call_creds = instance_double(GRPC::Core::CallCredentials)
69
+ updater_proc = proc {}
70
+
71
+ allow(GRPC::Core::CallCredentials)
72
+ .to receive(:new).with(updater_proc).and_return(call_creds)
73
+ allow(GRPC::Core::ChannelCredentials)
74
+ .to receive(:new).and_return(chan_creds)
75
+ allow(chan_creds)
76
+ .to receive(:compose).with(call_creds).and_return(composed_chan_creds)
77
+ expect do |blk|
78
+ Google::Gax::Grpc.create_stub(
79
+ 'service', 'port', updater_proc: updater_proc, &blk
80
+ )
81
+ end.to yield_with_args('service:port', composed_chan_creds)
82
+ end
83
+
84
+ it 'raise an argument error if multiple creds are passed in' do
85
+ channel = instance_double(GRPC::Core::Channel)
86
+ chan_creds = instance_double(GRPC::Core::ChannelCredentials)
87
+ updater_proc = instance_double(Proc)
88
+
89
+ expect do |blk|
90
+ Google::Gax::Grpc.create_stub(
91
+ 'service', 'port', channel: channel, chan_creds: chan_creds, &blk
92
+ )
93
+ end.to raise_error(ArgumentError)
94
+
95
+ expect do |blk|
96
+ Google::Gax::Grpc.create_stub(
97
+ 'service', 'port', channel: channel,
98
+ updater_proc: updater_proc, &blk
99
+ )
100
+ end.to raise_error(ArgumentError)
101
+
102
+ expect do |blk|
103
+ Google::Gax::Grpc.create_stub(
104
+ 'service', 'port', chan_creds: chan_creds,
105
+ updater_proc: updater_proc, &blk
106
+ )
107
+ end.to raise_error(ArgumentError)
108
+
109
+ expect do |blk|
110
+ Google::Gax::Grpc.create_stub(
111
+ 'service', 'port', channel: channel, chan_creds: chan_creds,
112
+ updater_proc: updater_proc, &blk
113
+ )
114
+ end.to raise_error(ArgumentError)
115
+ end
116
+ end
117
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-gax
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google API Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-27 00:00:00.000000000 Z
11
+ date: 2017-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: googleauth
@@ -162,6 +162,7 @@ files:
162
162
  - lib/google/gax/api_callable.rb
163
163
  - lib/google/gax/bundling.rb
164
164
  - lib/google/gax/constants.rb
165
+ - lib/google/gax/credentials.rb
165
166
  - lib/google/gax/errors.rb
166
167
  - lib/google/gax/grpc.rb
167
168
  - lib/google/gax/operation.rb
@@ -175,6 +176,8 @@ files:
175
176
  - spec/fixtures/fixture_pb.rb
176
177
  - spec/google/gax/api_callable_spec.rb
177
178
  - spec/google/gax/bundling_spec.rb
179
+ - spec/google/gax/credentials_spec.rb
180
+ - spec/google/gax/grpc_spec.rb
178
181
  - spec/google/gax/operation_spec.rb
179
182
  - spec/google/gax/path_template_spec.rb
180
183
  - spec/google/gax/settings_spec.rb