google-gax 0.10.2 → 1.0.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/lib/google/gax/api_callable.rb +7 -6
- data/lib/google/gax/errors.rb +73 -0
- data/lib/google/gax/grpc.rb +2 -2
- data/lib/google/gax/operation.rb +1 -1
- data/lib/google/gax/path_template.rb +1 -1
- data/lib/google/gax/util.rb +36 -4
- data/lib/google/gax/version.rb +1 -1
- data/lib/google/longrunning/operations_client.rb +10 -19
- data/spec/fixtures/fixture.proto +4 -0
- data/spec/fixtures/fixture_file.txt +1 -0
- data/spec/fixtures/fixture_pb.rb +3 -0
- data/spec/google/gax/api_callable_spec.rb +2 -2
- data/spec/google/gax/bundling_spec.rb +1 -1
- data/spec/google/gax/error_spec.rb +100 -3
- data/spec/google/gax/util_spec.rb +61 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87b2e27818073928a99f7edc7a49ab31a1ff05a6
|
4
|
+
data.tar.gz: bbe86ff3f6584127ace5d22509c59bb1be0b7e60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 108eb512cbf772cb7b0fd1196b9676ef594bb7ecbdab2038f4e307e9e1d20289b7a108d4031a28545c8110468adc23c2ffbccdafa57e311a00f152a6afe32db6
|
7
|
+
data.tar.gz: 37fb30807ae24551812160303d18ead970587dacb30c53e1a01708eee42ac77e6b4ff5c68b322470c34f0e8a0f04ac98505c4ecb1aab00632bdd31a274cbdd08
|
@@ -168,7 +168,7 @@ module Google
|
|
168
168
|
# @yield [Page] Gives the pages in the stream.
|
169
169
|
# @raise [GaxError] if it's not started yet.
|
170
170
|
def each_page
|
171
|
-
raise GaxError
|
171
|
+
raise GaxError.new('not started!') unless started?
|
172
172
|
yield @page
|
173
173
|
loop do
|
174
174
|
break unless next_page?
|
@@ -254,8 +254,9 @@ module Google
|
|
254
254
|
end
|
255
255
|
begin
|
256
256
|
api_caller.call(api_call, request, this_settings)
|
257
|
-
rescue *settings.errors
|
258
|
-
|
257
|
+
rescue *settings.errors => e
|
258
|
+
error_class = Google::Gax.from_error e
|
259
|
+
raise error_class.new('RPC failed')
|
259
260
|
end
|
260
261
|
end
|
261
262
|
end
|
@@ -348,15 +349,15 @@ module Google
|
|
348
349
|
rescue => exception
|
349
350
|
unless exception.respond_to?(:code) &&
|
350
351
|
retry_options.retry_codes.include?(exception.code)
|
351
|
-
raise RetryError
|
352
|
-
'was not classified as transient'
|
352
|
+
raise RetryError.new('Exception occurred in retry method that ' \
|
353
|
+
'was not classified as transient')
|
353
354
|
end
|
354
355
|
sleep(rand(delay) / MILLIS_PER_SECOND)
|
355
356
|
now = Time.now
|
356
357
|
delay = [delay * delay_mult, max_delay].min
|
357
358
|
timeout = [timeout * timeout_mult, max_timeout, deadline - now].min
|
358
359
|
if now >= deadline
|
359
|
-
raise RetryError
|
360
|
+
raise RetryError.new('Retry total timeout exceeded with exception')
|
360
361
|
end
|
361
362
|
retry
|
362
363
|
end
|
data/lib/google/gax/errors.rb
CHANGED
@@ -71,8 +71,81 @@ module Google
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
def from_error(error)
|
75
|
+
if error.respond_to? :code
|
76
|
+
grpc_error_class_for error.code
|
77
|
+
else
|
78
|
+
GaxError
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
74
82
|
# Indicates an error during automatic GAX retrying.
|
75
83
|
class RetryError < GaxError
|
76
84
|
end
|
85
|
+
|
86
|
+
# Errors corresponding to standard HTTP/gRPC statuses.
|
87
|
+
class CanceledError < GaxError
|
88
|
+
end
|
89
|
+
|
90
|
+
class UnknownError < GaxError
|
91
|
+
end
|
92
|
+
|
93
|
+
class InvalidArgumentError < GaxError
|
94
|
+
end
|
95
|
+
|
96
|
+
class DeadlineExceededError < GaxError
|
97
|
+
end
|
98
|
+
|
99
|
+
class NotFoundError < GaxError
|
100
|
+
end
|
101
|
+
|
102
|
+
class AlreadyExistsError < GaxError
|
103
|
+
end
|
104
|
+
|
105
|
+
class PermissionDeniedError < GaxError
|
106
|
+
end
|
107
|
+
|
108
|
+
class ResourceExhaustedError < GaxError
|
109
|
+
end
|
110
|
+
|
111
|
+
class FailedPreconditionError < GaxError
|
112
|
+
end
|
113
|
+
|
114
|
+
class AbortedError < GaxError
|
115
|
+
end
|
116
|
+
|
117
|
+
class OutOfRangeError < GaxError
|
118
|
+
end
|
119
|
+
|
120
|
+
class UnimplementedError < GaxError
|
121
|
+
end
|
122
|
+
|
123
|
+
class InternalError < GaxError
|
124
|
+
end
|
125
|
+
|
126
|
+
class UnavailableError < GaxError
|
127
|
+
end
|
128
|
+
|
129
|
+
class DataLossError < GaxError
|
130
|
+
end
|
131
|
+
|
132
|
+
class UnauthenticatedError < GaxError
|
133
|
+
end
|
134
|
+
|
135
|
+
# @private Identify the subclass for a gRPC error
|
136
|
+
# Note: ported from
|
137
|
+
# https:/g/github.com/GoogleCloudPlatform/google-cloud-ruby/blob/master/google-cloud-core/lib/google/cloud/errors.rb
|
138
|
+
def self.grpc_error_class_for(grpc_error_code)
|
139
|
+
# The gRPC status code 0 is for a successful response.
|
140
|
+
# So there is no error subclass for a 0 status code, use current class.
|
141
|
+
[GaxError, CanceledError, UnknownError, InvalidArgumentError,
|
142
|
+
DeadlineExceededError, NotFoundError, AlreadyExistsError,
|
143
|
+
PermissionDeniedError, ResourceExhaustedError, FailedPreconditionError,
|
144
|
+
AbortedError, OutOfRangeError, UnimplementedError, InternalError,
|
145
|
+
UnavailableError, DataLossError,
|
146
|
+
UnauthenticatedError][grpc_error_code] || GaxError
|
147
|
+
end
|
148
|
+
|
149
|
+
module_function :from_error
|
77
150
|
end
|
78
151
|
end
|
data/lib/google/gax/grpc.rb
CHANGED
@@ -136,9 +136,9 @@ module Google
|
|
136
136
|
if (channel && chan_creds) ||
|
137
137
|
(channel && updater_proc) ||
|
138
138
|
(chan_creds && updater_proc)
|
139
|
-
raise ArgumentError
|
139
|
+
raise ArgumentError.new('Only one of channel, chan_creds, and ' \
|
140
140
|
'updater_proc should be passed into ' \
|
141
|
-
'Google::Gax::Grpc#create_stub.'
|
141
|
+
'Google::Gax::Grpc#create_stub.')
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
data/lib/google/gax/operation.rb
CHANGED
@@ -254,7 +254,7 @@ module Google
|
|
254
254
|
until done?
|
255
255
|
sleep(delay)
|
256
256
|
if Time.now >= deadline
|
257
|
-
raise RetryError
|
257
|
+
raise RetryError.new('Retry total timeout exceeded with exception')
|
258
258
|
end
|
259
259
|
delay = [delay * delay_multiplier, max_delay].min
|
260
260
|
reload!
|
@@ -175,7 +175,7 @@ module Google
|
|
175
175
|
literal_sym = segment.literal.to_sym
|
176
176
|
unless bindings.key?(literal_sym)
|
177
177
|
msg = "Value for key #{segment.literal} is not provided"
|
178
|
-
raise(
|
178
|
+
raise ArgumentError.new(msg)
|
179
179
|
end
|
180
180
|
out.concat(PathTemplate.new(bindings[literal_sym]).segments)
|
181
181
|
binding = true
|
data/lib/google/gax/util.rb
CHANGED
@@ -27,6 +27,8 @@
|
|
27
27
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
28
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
|
30
|
+
require 'google/protobuf/timestamp_pb'
|
31
|
+
|
30
32
|
module Google
|
31
33
|
# Gax defines Google API extensions
|
32
34
|
module Gax
|
@@ -54,8 +56,9 @@ module Google
|
|
54
56
|
|
55
57
|
# Sanity check: input must be a Hash
|
56
58
|
unless hash.is_a? Hash
|
57
|
-
raise ArgumentError
|
58
|
-
|
59
|
+
raise ArgumentError.new(
|
60
|
+
"Value #{hash} must be a Hash or a #{message_class.name}"
|
61
|
+
)
|
59
62
|
end
|
60
63
|
hash = coerce_submessages(hash, message_class)
|
61
64
|
message_class.new(hash)
|
@@ -79,6 +82,9 @@ module Google
|
|
79
82
|
field_descriptor = message_descriptor.lookup(key.to_s)
|
80
83
|
if field_descriptor && field_descriptor.type == :message
|
81
84
|
coerced[key] = coerce_submessage(val, field_descriptor)
|
85
|
+
elsif field_descriptor && field_descriptor.type == :bytes &&
|
86
|
+
(val.is_a?(IO) || val.is_a?(StringIO))
|
87
|
+
coerced[key] = val.binmode.read
|
82
88
|
else
|
83
89
|
# `google/protobuf` should throw an error if no field descriptor is
|
84
90
|
# found. Simply pass through.
|
@@ -101,6 +107,9 @@ module Google
|
|
101
107
|
def coerce_submessage(val, field_descriptor)
|
102
108
|
if (field_descriptor.label == :repeated) && !(map_field? field_descriptor)
|
103
109
|
coerce_array(val, field_descriptor)
|
110
|
+
elsif field_descriptor.subtype.msgclass == Google::Protobuf::Timestamp &&
|
111
|
+
val.is_a?(Time)
|
112
|
+
time_to_timestamp(val)
|
104
113
|
else
|
105
114
|
coerce(val, field_descriptor)
|
106
115
|
end
|
@@ -118,7 +127,7 @@ module Google
|
|
118
127
|
# @return [Array<Object>] The coerced version of the given values.
|
119
128
|
def coerce_array(array, field_descriptor)
|
120
129
|
unless array.is_a? Array
|
121
|
-
raise ArgumentError
|
130
|
+
raise ArgumentError.new('Value ' + array.to_s + ' must be an array')
|
122
131
|
end
|
123
132
|
array.map do |val|
|
124
133
|
coerce(val, field_descriptor)
|
@@ -150,8 +159,31 @@ module Google
|
|
150
159
|
to_proto(val, field_descriptor.subtype.msgclass)
|
151
160
|
end
|
152
161
|
|
162
|
+
# Utility for converting a Google::Protobuf::Timestamp instance to a Ruby
|
163
|
+
# time.
|
164
|
+
#
|
165
|
+
# @param timestamp [Google::Protobuf::Timestamp] The timestamp to be
|
166
|
+
# converted.
|
167
|
+
#
|
168
|
+
# @return [Time] The converted Time.
|
169
|
+
def timestamp_to_time(timestamp)
|
170
|
+
Time.at(timestamp.nanos * 10**-9 + timestamp.seconds)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Utility for converting a Ruby Time instance to a
|
174
|
+
# Google::Protobuf::Timestamp.
|
175
|
+
#
|
176
|
+
# @param time [Time] The Time to be converted.
|
177
|
+
#
|
178
|
+
# @return [Google::Protobuf::Timestamp] The converted
|
179
|
+
# Google::Protobuf::Timestamp.
|
180
|
+
def time_to_timestamp(time)
|
181
|
+
Google::Protobuf::Timestamp.new(seconds: time.to_i, nanos: time.nsec)
|
182
|
+
end
|
183
|
+
|
153
184
|
module_function :to_proto, :coerce_submessages, :coerce_submessage,
|
154
|
-
:coerce_array, :coerce, :map_field
|
185
|
+
:coerce_array, :coerce, :map_field?, :timestamp_to_time,
|
186
|
+
:time_to_timestamp
|
155
187
|
private_class_method :coerce_submessages, :coerce_submessage, :coerce_array,
|
156
188
|
:coerce, :map_field?
|
157
189
|
end
|
data/lib/google/gax/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2017, Google
|
1
|
+
# Copyright 2017, Google LLC All rights reserved.
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
4
|
# modification, are permitted provided that the following conditions are
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# copyright notice, this list of conditions and the following disclaimer
|
11
11
|
# in the documentation and/or other materials provided with the
|
12
12
|
# distribution.
|
13
|
-
# * Neither the name of Google
|
13
|
+
# * Neither the name of Google LLC nor the names of its
|
14
14
|
# contributors may be used to endorse or promote products derived from
|
15
15
|
# this software without specific prior written permission.
|
16
16
|
#
|
@@ -83,6 +83,7 @@ module Google
|
|
83
83
|
ALL_SCOPES = [
|
84
84
|
].freeze
|
85
85
|
|
86
|
+
|
86
87
|
# @param credentials [Google::Auth::Credentials, String, Hash, GRPC::Core::Channel, GRPC::Core::ChannelCredentials, Proc]
|
87
88
|
# Provides the means for authenticating requests made by the client. This parameter can
|
88
89
|
# be many types.
|
@@ -108,11 +109,6 @@ module Google
|
|
108
109
|
# @param timeout [Numeric]
|
109
110
|
# The default timeout, in seconds, for calls made through this client.
|
110
111
|
def initialize \
|
111
|
-
service_path: self.class::SERVICE_ADDRESS,
|
112
|
-
port: self.class::DEFAULT_SERVICE_PORT,
|
113
|
-
channel: nil,
|
114
|
-
chan_creds: nil,
|
115
|
-
updater_proc: nil,
|
116
112
|
credentials: nil,
|
117
113
|
scopes: ALL_SCOPES,
|
118
114
|
client_config: {},
|
@@ -125,17 +121,6 @@ module Google
|
|
125
121
|
require "google/gax/grpc"
|
126
122
|
require "google/longrunning/operations_services_pb"
|
127
123
|
|
128
|
-
if channel || chan_creds || updater_proc
|
129
|
-
warn "The `channel`, `chan_creds`, and `updater_proc` parameters will be removed " \
|
130
|
-
"on 2017/09/08"
|
131
|
-
credentials ||= channel
|
132
|
-
credentials ||= chan_creds
|
133
|
-
credentials ||= updater_proc
|
134
|
-
end
|
135
|
-
if port != DEFAULT_SERVICE_PORT
|
136
|
-
warn "the `port` parameter is deprecated and will be removed"
|
137
|
-
end
|
138
|
-
|
139
124
|
credentials ||= Google::Auth::Credentials.default(scopes: scopes)
|
140
125
|
|
141
126
|
if credentials.is_a?(String) || credentials.is_a?(Hash)
|
@@ -154,9 +139,11 @@ module Google
|
|
154
139
|
updater_proc = credentials.updater_proc
|
155
140
|
end
|
156
141
|
|
142
|
+
package_version = Gem.loaded_specs['google-gax'].version.version
|
143
|
+
|
157
144
|
google_api_client = "gl-ruby/#{RUBY_VERSION}"
|
158
145
|
google_api_client << " #{lib_name}/#{lib_version}" if lib_name
|
159
|
-
google_api_client << " gapic
|
146
|
+
google_api_client << " gapic/#{package_version} gax/#{Google::Gax::VERSION}"
|
160
147
|
google_api_client << " grpc/#{GRPC::VERSION}"
|
161
148
|
google_api_client.freeze
|
162
149
|
|
@@ -176,6 +163,10 @@ module Google
|
|
176
163
|
kwargs: headers
|
177
164
|
)
|
178
165
|
end
|
166
|
+
|
167
|
+
# Allow overriding the service path/port in subclasses.
|
168
|
+
service_path = self.class::SERVICE_ADDRESS
|
169
|
+
port = self.class::DEFAULT_SERVICE_PORT
|
179
170
|
@operations_stub = Google::Gax::Grpc.create_stub(
|
180
171
|
service_path,
|
181
172
|
port,
|
data/spec/fixtures/fixture.proto
CHANGED
@@ -15,6 +15,8 @@ syntax = "proto3";
|
|
15
15
|
|
16
16
|
package google.protobuf;
|
17
17
|
|
18
|
+
import "google/protobuf/timestamp.proto";
|
19
|
+
|
18
20
|
message Request {
|
19
21
|
string name = 1;
|
20
22
|
User user = 2;
|
@@ -29,6 +31,8 @@ message User {
|
|
29
31
|
UserType type = 2;
|
30
32
|
repeated Post posts = 3;
|
31
33
|
map<string, string> map_field = 4;
|
34
|
+
bytes bytes_field = 5;
|
35
|
+
google.protobuf.Timestamp timestamp = 6;
|
32
36
|
}
|
33
37
|
|
34
38
|
message Post {
|
@@ -0,0 +1 @@
|
|
1
|
+
This is a text file.
|
data/spec/fixtures/fixture_pb.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'google/protobuf'
|
5
5
|
|
6
|
+
require 'google/protobuf/timestamp_pb'
|
6
7
|
Google::Protobuf::DescriptorPool.generated_pool.build do
|
7
8
|
add_message "google.protobuf.Request" do
|
8
9
|
optional :name, :string, 1
|
@@ -13,6 +14,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
13
14
|
optional :type, :enum, 2, "google.protobuf.User.UserType"
|
14
15
|
repeated :posts, :message, 3, "google.protobuf.Post"
|
15
16
|
map :map_field, :string, :string, 4
|
17
|
+
optional :bytes_field, :bytes, 5
|
18
|
+
optional :timestamp, :message, 6, "google.protobuf.Timestamp"
|
16
19
|
end
|
17
20
|
add_enum "google.protobuf.User.UserType" do
|
18
21
|
value :UNSPECIFIED, 0
|
@@ -39,8 +39,8 @@ class CustomException < StandardError
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
FAKE_STATUS_CODE_1 =
|
43
|
-
FAKE_STATUS_CODE_2 =
|
42
|
+
FAKE_STATUS_CODE_1 = 1
|
43
|
+
FAKE_STATUS_CODE_2 = 2
|
44
44
|
|
45
45
|
# Google::Gax::CallSettings is private, only accessible in the module context.
|
46
46
|
# For testing purpose, this makes a toplevel ::CallSettings point to the same
|
@@ -67,7 +67,7 @@ describe Google::Gax::GaxError do
|
|
67
67
|
it 'presents GRPC::BadStatus values' do
|
68
68
|
error = wrapped_badstatus(3, 'invalid')
|
69
69
|
|
70
|
-
expect(error).to
|
70
|
+
expect(error).to be_a_kind_of(Google::Gax::GaxError)
|
71
71
|
expect(error.message).to eq('GaxError 3:invalid, caused by 3:invalid')
|
72
72
|
expect(error.code).to eq(3)
|
73
73
|
expect(error.details).to eq('invalid')
|
@@ -93,7 +93,7 @@ describe Google::Gax::GaxError do
|
|
93
93
|
'grpc-status-details-bin' => encoded_status_detail }
|
94
94
|
error = wrapped_badstatus(1, 'cancelled', metadata)
|
95
95
|
|
96
|
-
expect(error).to
|
96
|
+
expect(error).to be_a_kind_of(Google::Gax::GaxError)
|
97
97
|
expect(error.message).to eq('GaxError 1:cancelled, caused by 1:cancelled')
|
98
98
|
expect(error.code).to eq(1)
|
99
99
|
expect(error.details).to eq('cancelled')
|
@@ -108,10 +108,107 @@ describe Google::Gax::GaxError do
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
+
describe '#from_error' do
|
112
|
+
it 'identifies CanceledError' do
|
113
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(1, 'cancelled')
|
114
|
+
expect(mapped_error).to eq Google::Gax::CanceledError
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'identifies UnknownError' do
|
118
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(2, 'unknown')
|
119
|
+
expect(mapped_error).to eq Google::Gax::UnknownError
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'identifies InvalidArgumentError' do
|
123
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(3, 'invalid')
|
124
|
+
expect(mapped_error).to eq Google::Gax::InvalidArgumentError
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'identifies DeadlineExceededError' do
|
128
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(4, 'exceeded')
|
129
|
+
expect(mapped_error).to eq Google::Gax::DeadlineExceededError
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'identifies NotFoundError' do
|
133
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(5, 'not found')
|
134
|
+
expect(mapped_error).to eq Google::Gax::NotFoundError
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'identifies AlreadyExistsError' do
|
138
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(6, 'exists')
|
139
|
+
expect(mapped_error).to eq Google::Gax::AlreadyExistsError
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'identifies PermissionDeniedError' do
|
143
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(7, 'denied')
|
144
|
+
expect(mapped_error).to eq Google::Gax::PermissionDeniedError
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'identifies ResourceExhaustedError' do
|
148
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(8, 'exhausted')
|
149
|
+
expect(mapped_error).to eq Google::Gax::ResourceExhaustedError
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'identifies FailedPreconditionError' do
|
153
|
+
mapped_error =
|
154
|
+
Google::Gax.from_error GRPC::BadStatus.new(9, 'precondition')
|
155
|
+
expect(mapped_error).to eq Google::Gax::FailedPreconditionError
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'identifies AbortedError' do
|
159
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(10, 'aborted')
|
160
|
+
expect(mapped_error).to eq Google::Gax::AbortedError
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'identifies OutOfRangeError' do
|
164
|
+
mapped_error =
|
165
|
+
Google::Gax.from_error GRPC::BadStatus.new(11, 'out of range')
|
166
|
+
expect(mapped_error).to eq Google::Gax::OutOfRangeError
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'identifies UnimplementedError' do
|
170
|
+
mapped_error =
|
171
|
+
Google::Gax.from_error GRPC::BadStatus.new(12, 'unimplemented')
|
172
|
+
expect(mapped_error).to eq Google::Gax::UnimplementedError
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'identifies InternalError' do
|
176
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(13, 'internal')
|
177
|
+
expect(mapped_error).to eq Google::Gax::InternalError
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'identifies UnavailableError' do
|
181
|
+
mapped_error =
|
182
|
+
Google::Gax.from_error GRPC::BadStatus.new(14, 'unavailable')
|
183
|
+
expect(mapped_error).to eq Google::Gax::UnavailableError
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'identifies DataLossError' do
|
187
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(15, 'data loss')
|
188
|
+
expect(mapped_error).to eq Google::Gax::DataLossError
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'identifies UnauthenticatedError' do
|
192
|
+
mapped_error =
|
193
|
+
Google::Gax.from_error GRPC::BadStatus.new(16, 'unauthenticated')
|
194
|
+
expect(mapped_error).to eq Google::Gax::UnauthenticatedError
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'identifies unknown error' do
|
198
|
+
# We don't know what to map this error case to
|
199
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(0, 'unknown')
|
200
|
+
expect(mapped_error).to eq Google::Gax::GaxError
|
201
|
+
|
202
|
+
mapped_error = Google::Gax.from_error GRPC::BadStatus.new(17, 'unknown')
|
203
|
+
expect(mapped_error).to eq Google::Gax::GaxError
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
111
207
|
def wrap_with_gax_error(err)
|
112
208
|
raise err
|
113
209
|
rescue => e
|
114
|
-
|
210
|
+
klass = Google::Gax.from_error(e)
|
211
|
+
raise klass.new(e.message)
|
115
212
|
end
|
116
213
|
|
117
214
|
def wrapped_error(msg)
|
@@ -29,7 +29,9 @@
|
|
29
29
|
|
30
30
|
require 'google/gax'
|
31
31
|
require 'google/protobuf/any_pb'
|
32
|
+
require 'google/protobuf/timestamp_pb'
|
32
33
|
require 'spec/fixtures/fixture_pb'
|
34
|
+
require 'stringio'
|
33
35
|
|
34
36
|
describe Google::Gax do
|
35
37
|
describe '#to_proto' do
|
@@ -110,6 +112,38 @@ describe Google::Gax do
|
|
110
112
|
end
|
111
113
|
end
|
112
114
|
|
115
|
+
it 'handles IO instances' do
|
116
|
+
file = File.new('spec/fixtures/fixture_file.txt')
|
117
|
+
request_hash = {
|
118
|
+
bytes_field: file
|
119
|
+
}
|
120
|
+
user = Google::Gax.to_proto(request_hash, Google::Protobuf::User)
|
121
|
+
expect(user.bytes_field).to eq("This is a text file.\n")
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'handles StringIO instances' do
|
125
|
+
expected = 'This is a StringIO.'
|
126
|
+
string_io = StringIO.new(expected)
|
127
|
+
request_hash = {
|
128
|
+
bytes_field: string_io
|
129
|
+
}
|
130
|
+
user = Google::Gax.to_proto(request_hash, Google::Protobuf::User)
|
131
|
+
expect(user.bytes_field).to eq(expected)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'auto-coerces Time' do
|
135
|
+
seconds = 271_828_182
|
136
|
+
nanos = 845_904_523
|
137
|
+
# Fixnum, not float, for precision
|
138
|
+
sometime = seconds + nanos * 10**-9
|
139
|
+
request_hash = {
|
140
|
+
timestamp: Time.at(sometime)
|
141
|
+
}
|
142
|
+
user = Google::Gax.to_proto(request_hash, Google::Protobuf::User)
|
143
|
+
expected = Google::Protobuf::Timestamp.new(seconds: seconds, nanos: nanos)
|
144
|
+
expect(user.timestamp).to eq(expected)
|
145
|
+
end
|
146
|
+
|
113
147
|
it 'fails if a key does not exist in the target message type' do
|
114
148
|
user_hash = {
|
115
149
|
name: USER_NAME,
|
@@ -135,4 +169,31 @@ describe Google::Gax do
|
|
135
169
|
end.to raise_error(ArgumentError)
|
136
170
|
end
|
137
171
|
end
|
172
|
+
|
173
|
+
describe 'time-timestamp conversion' do
|
174
|
+
SECONDS = 271_828_182
|
175
|
+
NANOS = 845_904_523
|
176
|
+
A_TIME = Time.at(SECONDS + NANOS * 10**-9)
|
177
|
+
A_TIMESTAMP =
|
178
|
+
Google::Protobuf::Timestamp.new(seconds: SECONDS, nanos: NANOS)
|
179
|
+
|
180
|
+
it 'converts time to timestamp' do
|
181
|
+
expect(Google::Gax.time_to_timestamp(A_TIME)).to eq A_TIMESTAMP
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'converts timestamp to time' do
|
185
|
+
expect(Google::Gax.timestamp_to_time(A_TIMESTAMP)).to eq A_TIME
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'is an identity when conversion is a round trip' do
|
189
|
+
expect(
|
190
|
+
Google::Gax.timestamp_to_time(Google::Gax.time_to_timestamp(A_TIME))
|
191
|
+
).to eq A_TIME
|
192
|
+
expect(
|
193
|
+
Google::Gax.time_to_timestamp(
|
194
|
+
Google::Gax.timestamp_to_time(A_TIMESTAMP)
|
195
|
+
)
|
196
|
+
).to eq A_TIMESTAMP
|
197
|
+
end
|
198
|
+
end
|
138
199
|
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.
|
4
|
+
version: 1.0.0
|
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-12-
|
11
|
+
date: 2017-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: googleauth
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/google/longrunning/operations_client.rb
|
185
185
|
- lib/google/longrunning/operations_client_config.json
|
186
186
|
- spec/fixtures/fixture.proto
|
187
|
+
- spec/fixtures/fixture_file.txt
|
187
188
|
- spec/fixtures/fixture_pb.rb
|
188
189
|
- spec/google/gax/api_callable_spec.rb
|
189
190
|
- spec/google/gax/bundling_spec.rb
|
@@ -214,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
215
|
version: '0'
|
215
216
|
requirements: []
|
216
217
|
rubyforge_project:
|
217
|
-
rubygems_version: 2.
|
218
|
+
rubygems_version: 2.6.12
|
218
219
|
signing_key:
|
219
220
|
specification_version: 4
|
220
221
|
summary: Aids the development of APIs for clients and servers based on GRPC and Google
|