google-gax 0.1.1

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.
@@ -0,0 +1,34 @@
1
+ # Copyright 2016, 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
+ module Google
31
+ module Gax
32
+ VERSION = '0.1.1'.freeze
33
+ end
34
+ end
@@ -0,0 +1,232 @@
1
+ # Copyright 2016, 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/api_callable'
31
+ require 'google/gax'
32
+
33
+ class CustomException < StandardError
34
+ attr_reader :code
35
+
36
+ def initialize(msg, code)
37
+ super(msg)
38
+ @code = code
39
+ end
40
+ end
41
+
42
+ FAKE_STATUS_CODE_1 = :FAKE_STATUS_CODE_1
43
+ FAKE_STATUS_CODE_2 = :FAKE_STATUS_CODE_2
44
+
45
+ describe Google::Gax do
46
+ CallSettings = Google::Gax::CallSettings
47
+
48
+ describe 'create_api_call' do
49
+ it 'calls api call' do
50
+ settings = CallSettings.new
51
+ timeout_arg = nil
52
+ func = proc do |timeout: nil|
53
+ timeout_arg = timeout
54
+ 42
55
+ end
56
+ my_callable = Google::Gax.create_api_call(func, settings)
57
+ expect(my_callable.call(nil)).to eq(42)
58
+ expect(timeout_arg).to_not be_nil
59
+ end
60
+ end
61
+
62
+ describe 'page streaming' do
63
+ page_size = 3
64
+ pages_to_stream = 5
65
+
66
+ page_descriptor = Google::Gax::PageDescriptor.new(
67
+ 'page_token', 'next_page_token', 'nums')
68
+ settings = CallSettings.new(page_descriptor: page_descriptor)
69
+ timeout_arg = nil
70
+ func = proc do |request, timeout: nil|
71
+ timeout_arg = timeout
72
+ page_token = request['page_token']
73
+ if page_token > 0 && page_token < page_size * pages_to_stream
74
+ { 'nums' => (page_token...(page_token + page_size)),
75
+ 'next_page_token' => page_token + page_size }
76
+ elsif page_token >= page_size * pages_to_stream
77
+ { 'nums' => [] }
78
+ else
79
+ { 'nums' => 0...page_size, 'next_page_token' => page_size }
80
+ end
81
+ end
82
+
83
+ it 'iterates over elements' do
84
+ my_callable = Google::Gax.create_api_call(func, settings)
85
+ expect(my_callable.call('page_token' => 0).to_a).to eq(
86
+ (0...(page_size * pages_to_stream)).to_a)
87
+ expect(timeout_arg).to_not be_nil
88
+ end
89
+
90
+ it 'offers interface for pages' do
91
+ my_callable = Google::Gax.create_api_call(func, settings)
92
+ stream = my_callable.call('page_token' => 0)
93
+ page = stream.page
94
+ expect(page.to_a).to eq((0...page_size).to_a)
95
+ expect(page.next_page_token?).to be_truthy
96
+ page = stream.next_page
97
+ expect(page.to_a).to eq((page_size...(page_size * 2)).to_a)
98
+
99
+ stream = my_callable.call('page_token' => 0)
100
+ expect(stream.enum_for(:each_page).to_a.size).to eq(pages_to_stream + 1)
101
+ end
102
+ end
103
+
104
+ describe 'retryable' do
105
+ RetryOptions = Google::Gax::RetryOptions
106
+ BackoffSettings = Google::Gax::BackoffSettings
107
+
108
+ retry_options = RetryOptions.new(
109
+ [FAKE_STATUS_CODE_1], BackoffSettings.new(0, 0, 0, 0, 0, 0, 1))
110
+ settings = CallSettings.new(timeout: 0, retry_options: retry_options)
111
+
112
+ it 'retries the API call' do
113
+ time_now = Time.now
114
+ allow(Time).to receive(:now).and_return(time_now)
115
+
116
+ to_attempt = 3
117
+
118
+ timeout_arg = nil
119
+ func = proc do |timeout: nil|
120
+ timeout_arg = timeout
121
+ to_attempt -= 1
122
+ raise CustomException.new('', FAKE_STATUS_CODE_1) if to_attempt > 0
123
+ 1729
124
+ end
125
+ my_callable = Google::Gax.create_api_call(func, settings)
126
+ expect(my_callable.call).to eq(1729)
127
+ expect(to_attempt).to eq(0)
128
+ expect(timeout_arg).to_not be_nil
129
+ end
130
+
131
+ it 'doesn\'t retry if no codes' do
132
+ retry_options = RetryOptions.new([],
133
+ BackoffSettings.new(1, 2, 3, 4, 5, 6, 7))
134
+
135
+ call_count = 0
136
+ func = proc do
137
+ call_count += 1
138
+ raise CustomException.new('', FAKE_STATUS_CODE_1)
139
+ end
140
+ my_callable = Google::Gax.create_api_call(
141
+ func, CallSettings.new(timeout: 0, retry_options: retry_options))
142
+ expect { my_callable.call }.to raise_error(Google::Gax::RetryError)
143
+ expect(call_count).to eq(1)
144
+ end
145
+
146
+ it 'aborts retries' do
147
+ func = proc { raise CustomException.new('', FAKE_STATUS_CODE_1) }
148
+ my_callable = Google::Gax.create_api_call(func, settings)
149
+ begin
150
+ my_callable.call
151
+ expect(true).to be false # should not reach to this line.
152
+ rescue Google::Gax::RetryError => exc
153
+ expect(exc.cause).to be_a(CustomException)
154
+ end
155
+ end
156
+
157
+ it 'times out' do
158
+ to_attempt = 3
159
+ call_count = 0
160
+
161
+ time_now = Time.now
162
+ allow(Time).to receive(:now).exactly(4).times.and_return(
163
+ *([time_now] * to_attempt + [time_now + 2]))
164
+
165
+ func = proc do
166
+ call_count += 1
167
+ raise CustomException.new('', FAKE_STATUS_CODE_1)
168
+ end
169
+
170
+ my_callable = Google::Gax.create_api_call(func, settings)
171
+ begin
172
+ my_callable.call
173
+ except(true).to be false # should not reach to this line.
174
+ rescue Google::Gax::RetryError => exc
175
+ expect(exc.cause).to be_a(CustomException)
176
+ end
177
+ expect(call_count).to eq(to_attempt)
178
+ end
179
+
180
+ it 'aborts on unexpected exception' do
181
+ call_count = 0
182
+ func = proc do
183
+ call_count += 1
184
+ raise CustomException.new('', FAKE_STATUS_CODE_2)
185
+ end
186
+ my_callable = Google::Gax.create_api_call(func, settings)
187
+ expect { my_callable.call }.to raise_error(Google::Gax::RetryError)
188
+ expect(call_count).to eq(1)
189
+ end
190
+
191
+ it 'does not retry even when no responses' do
192
+ func = proc { nil }
193
+ my_callable = Google::Gax.create_api_call(func, settings)
194
+ expect(my_callable.call).to be_nil
195
+ end
196
+
197
+ it 'retries with exponential backoff' do
198
+ time_now = Time.now
199
+ start_time = time_now
200
+ incr_time = proc { |secs| time_now += secs }
201
+ call_count = 0
202
+ func = proc do |_, timeout: nil|
203
+ call_count += 1
204
+ incr_time.call(timeout)
205
+ raise CustomException.new(timeout.to_s, FAKE_STATUS_CODE_1)
206
+ end
207
+
208
+ allow(Time).to receive(:now) { time_now }
209
+ allow(Kernel).to receive(:sleep) { |secs| incr_time.call(secs) }
210
+ backoff = BackoffSettings.new(3, 2, 24, 5, 2, 80, 2500)
211
+ retry_options = RetryOptions.new([FAKE_STATUS_CODE_1], backoff)
212
+ my_callable = Google::Gax.create_api_call(
213
+ func, CallSettings.new(timeout: 0, retry_options: retry_options))
214
+
215
+ begin
216
+ my_callable.call(0)
217
+ expect(true).to be false # should not reach to this line.
218
+ rescue Google::Gax::RetryError => exc
219
+ expect(exc.cause).to be_a(CustomException)
220
+ end
221
+ expect(time_now - start_time).to be >= (
222
+ backoff.total_timeout_millis / 1000.0)
223
+
224
+ calls_lower_bound = backoff.total_timeout_millis / (
225
+ backoff.max_retry_delay_millis + backoff.max_rpc_timeout_millis)
226
+ calls_upper_bound = (backoff.total_timeout_millis /
227
+ backoff.initial_retry_delay_millis)
228
+ expect(call_count).to be > calls_lower_bound
229
+ expect(call_count).to be < calls_upper_bound
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,159 @@
1
+ # Copyright 2016, 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/path_template'
31
+ require 'rly'
32
+
33
+ describe Google::Gax::PathTemplate do
34
+ PathTemplate = Google::Gax::PathTemplate
35
+
36
+ def symbolize_keys(a_hash)
37
+ Hash[a_hash.map { |(k, v)| [k.to_sym, v] }]
38
+ end
39
+
40
+ def runtime_error
41
+ raise_error RuntimeError
42
+ end
43
+
44
+ describe 'method `initialize`' do
45
+ it 'computes the length correctly' do
46
+ a_template = PathTemplate.new('a/b/**/*/{a=hello/world}')
47
+ expect(a_template.size).to eq(6)
48
+ end
49
+
50
+ it 'should fail on invalid tokens' do
51
+ expect { PathTemplate.new('hello/wor* ld') }.to runtime_error
52
+ end
53
+
54
+ it 'should fail when multiple path wildcards' do
55
+ expect { PathTemplate.new('buckets/*/**/**/objects/*') }.to runtime_error
56
+ end
57
+
58
+ it 'should fail on inner binding' do
59
+ expect { PathTemplate.new('buckets/{hello={world}}') }.to runtime_error
60
+ end
61
+
62
+ it 'should fail unexpected eof' do
63
+ expect { PathTemplate.new('a/{hello=world') }.to runtime_error
64
+ end
65
+ end
66
+
67
+ describe 'method `match`' do
68
+ it 'should fail on impossible match' do
69
+ template = PathTemplate.new('hello/world')
70
+ expect { template.match('hello') }.to raise_error(ArgumentError)
71
+ expect { template.match('hello/world/fail') }.to raise_error(
72
+ ArgumentError)
73
+ end
74
+
75
+ it 'should fail on mismatched literal' do
76
+ template = PathTemplate.new('hello/world')
77
+ expect { template.match('hello/world2') }.to raise_error(ArgumentError)
78
+ end
79
+
80
+ it 'should match atomic resource name' do
81
+ template = PathTemplate.new('buckets/*/*/objects/*')
82
+ want = { '$0' => 'f', '$1' => 'o', '$2' => 'bar' }
83
+ expect(template.match('buckets/f/o/objects/bar')).to eq(want)
84
+
85
+ template = PathTemplate.new('/buckets/{hello}')
86
+ want = { 'hello' => 'world' }
87
+ expect(template.match('buckets/world')).to eq(want)
88
+
89
+ template = PathTemplate.new('/buckets/{hello=*}')
90
+ expect(template.match('buckets/world')).to eq(want)
91
+ end
92
+
93
+ it 'should match escaped chars' do
94
+ template = PathTemplate.new('buckets/*/objects')
95
+ want = { '$0' => 'hello%2F%2Bworld' }
96
+ expect(template.match('buckets/hello%2F%2Bworld/objects')).to eq(want)
97
+ end
98
+
99
+ it 'should match template with unbounded wildcard' do
100
+ template = PathTemplate.new('buckets/*/objects/**')
101
+ want = { '$0' => 'foo', '$1' => 'bar/baz' }
102
+ expect(template.match('buckets/foo/objects/bar/baz')).to eq(want)
103
+ end
104
+
105
+ it 'should match with unbound in the middle' do
106
+ template = PathTemplate.new('bar/**/foo/*')
107
+ want = { '$0' => 'foo/foo', '$1' => 'bar' }
108
+ expect(template.match('bar/foo/foo/foo/bar')).to eq(want)
109
+ end
110
+ end
111
+
112
+ describe 'method `render`' do
113
+ it 'should render atomic resource' do
114
+ template = PathTemplate.new('buckets/*/*/*/objects/*')
115
+ params = symbolize_keys(
116
+ '$0' => 'f',
117
+ '$1' => 'o',
118
+ '$2' => 'o',
119
+ '$3' => 'google.com:a-b'
120
+ )
121
+
122
+ want = 'buckets/f/o/o/objects/google.com:a-b'
123
+ expect(template.render(params)).to eq(want)
124
+ end
125
+
126
+ it 'should fail when there are too few variables' do
127
+ template = PathTemplate.new('buckets/*/*/*/objects/*')
128
+ params = symbolize_keys(
129
+ '$0' => 'f',
130
+ '$1' => 'o',
131
+ '$2' => 'o'
132
+ )
133
+ testf = proc { template.render(**params) }
134
+ expect(testf).to raise_error ArgumentError
135
+ end
136
+
137
+ it 'should succeed with unbound in the middle' do
138
+ template = PathTemplate.new('bar/**/foo/*')
139
+ params = symbolize_keys('$0' => '1/2', '$1' => '3')
140
+ want = 'bar/1/2/foo/3'
141
+ expect(template.render(**params)).to eq(want)
142
+ end
143
+ end
144
+
145
+ describe 'method `to_s`' do
146
+ tests = {
147
+ 'bar/**/foo/*' => 'bar/{$0=**}/foo/{$1=*}',
148
+ 'buckets/*/objects/*' => 'buckets/{$0=*}/objects/{$1=*}',
149
+ '/buckets/{hello}' => 'buckets/{hello=*}',
150
+ '/buckets/{hello=what}/{world}' => 'buckets/{hello=what}/{world=*}',
151
+ '/buckets/helloazAZ09-.~_what' => 'buckets/helloazAZ09-.~_what'
152
+ }
153
+ tests.each do |t, want|
154
+ it "should render method #{t} ok" do
155
+ expect(PathTemplate.new(t).to_s).to eq(want)
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,134 @@
1
+ # Copyright 2016, 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/settings'
31
+ require 'google/gax'
32
+
33
+ SERVICE_NAME = 'test.interface.v1.api'.freeze
34
+
35
+ A_CONFIG = {
36
+ 'interfaces' => {
37
+ SERVICE_NAME => {
38
+ 'retry_codes' => {
39
+ 'foo_retry' => %w(code_a code_b),
40
+ 'bar_retry' => %w(code_c)
41
+ },
42
+ 'retry_params' => {
43
+ 'default' => {
44
+ 'initial_retry_delay_millis' => 100,
45
+ 'retry_delay_multiplier' => 1.2,
46
+ 'max_retry_delay_millis' => 1000,
47
+ 'initial_rpc_timeout_millis' => 300,
48
+ 'rpc_timeout_multiplier' => 1.3,
49
+ 'max_rpc_timeout_millis' => 3000,
50
+ 'total_timeout_millis' => 30_000
51
+ }
52
+ },
53
+ 'methods' => {
54
+ # Note that GAX should normalize this to snake case
55
+ 'BundlingMethod' => {
56
+ 'retry_codes_name' => 'foo_retry',
57
+ 'retry_params_name' => 'default',
58
+ 'bundling' => {
59
+ 'element_count_threshold' => 6,
60
+ 'element_count_limit' => 10
61
+ }
62
+ },
63
+ 'PageStreamingMethod' => {
64
+ 'retry_codes_name' => 'bar_retry',
65
+ 'retry_params_name' => 'default'
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }.freeze
71
+
72
+ PAGE_DESCRIPTORS = {
73
+ 'page_streaming_method' => Google::Gax::PageDescriptor.new(
74
+ 'page_token', 'next_page_token', 'page_streams')
75
+ }.freeze
76
+
77
+ BUNDLE_DESCRIPTORS = {
78
+ 'bundling_method' => Google::Gax::BundleDescriptor.new('bundled_field', [])
79
+ }.freeze
80
+
81
+ RETRY_DICT = {
82
+ 'code_a' => 1,
83
+ 'code_b' => 2,
84
+ 'code_c' => 3
85
+ }.freeze
86
+
87
+ describe Google::Gax do
88
+ it 'creates settings' do
89
+ defaults = Google::Gax.construct_settings(
90
+ SERVICE_NAME, A_CONFIG, {}, {}, RETRY_DICT, 30,
91
+ bundle_descriptors: BUNDLE_DESCRIPTORS,
92
+ page_descriptors: PAGE_DESCRIPTORS)
93
+ settings = defaults['bundling_method']
94
+ expect(settings.timeout).to be(30)
95
+ # TODO: uncomment this when bundling is added.
96
+ # expect(settings.bundler).to be_a(Google::Gax::Executor)
97
+ expect(settings.bundle_descriptor).to be_a(Google::Gax::BundleDescriptor)
98
+ expect(settings.page_descriptor).to be_nil
99
+ expect(settings.retry_options).to be_a(Google::Gax::RetryOptions)
100
+ expect(settings.retry_options.retry_codes).to be_a(Array)
101
+ expect(settings.retry_options.backoff_settings).to be_a(
102
+ Google::Gax::BackoffSettings)
103
+
104
+ settings = defaults['page_streaming_method']
105
+ expect(settings.timeout).to be(30)
106
+ expect(settings.bundler).to be_nil
107
+ expect(settings.bundle_descriptor).to be_nil
108
+ expect(settings.page_descriptor).to be_a(Google::Gax::PageDescriptor)
109
+ expect(settings.retry_options).to be_a(Google::Gax::RetryOptions)
110
+ expect(settings.retry_options.retry_codes).to be_a(Array)
111
+ expect(settings.retry_options.backoff_settings).to be_a(
112
+ Google::Gax::BackoffSettings)
113
+ end
114
+
115
+ it 'overrides settings' do
116
+ bundling_override = { 'bundling_method' => nil }
117
+ retry_override = { 'page_streaming_method' => nil }
118
+ defaults = Google::Gax.construct_settings(
119
+ SERVICE_NAME, A_CONFIG, bundling_override, retry_override,
120
+ RETRY_DICT, 30,
121
+ bundle_descriptors: BUNDLE_DESCRIPTORS,
122
+ page_descriptors: PAGE_DESCRIPTORS)
123
+
124
+ settings = defaults['bundling_method']
125
+ expect(settings.timeout).to be(30)
126
+ expect(settings.bundler).to be_nil
127
+ expect(settings.page_descriptor).to be_nil
128
+
129
+ settings = defaults['page_streaming_method']
130
+ expect(settings.timeout).to be(30)
131
+ expect(settings.page_descriptor).to be_a(Google::Gax::PageDescriptor)
132
+ expect(settings.retry_options).to be_nil
133
+ end
134
+ end