google-gax 0.10.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 042b5b8369bf9dd8599b15f142f6608fbd7d2eb2
4
- data.tar.gz: 1982637288109d3c84bd27d531f0736a8060ce27
3
+ metadata.gz: 87b2e27818073928a99f7edc7a49ab31a1ff05a6
4
+ data.tar.gz: bbe86ff3f6584127ace5d22509c59bb1be0b7e60
5
5
  SHA512:
6
- metadata.gz: f0cd057e35054c328494dab34bad86eeb47b90cbe762489be0e3f37598a52bed9097572d9b77a46ccc587fbdf35148a9e4e66e7a671571754a360063e55c5b6f
7
- data.tar.gz: 619f3cea1620d36159a1cc51f15899f4b7c608a6cb4a20044c8472ef9ccb84d0cc4c352d4b6b5e69e187907d9dcdc52720f6c4c8ddd6523b8bd48fc5909456b8
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, 'not started!' unless started?
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
- raise GaxError, 'RPC failed'
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, 'Exception occurred in retry method that ' \
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, 'Retry total timeout exceeded with exception'
360
+ raise RetryError.new('Retry total timeout exceeded with exception')
360
361
  end
361
362
  retry
362
363
  end
@@ -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
@@ -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, 'Only one of channel, chan_creds, and ' \
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
 
@@ -254,7 +254,7 @@ module Google
254
254
  until done?
255
255
  sleep(delay)
256
256
  if Time.now >= deadline
257
- raise RetryError, 'Retry total timeout exceeded with exception'
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(ArgumentError, msg)
178
+ raise ArgumentError.new(msg)
179
179
  end
180
180
  out.concat(PathTemplate.new(bindings[literal_sym]).segments)
181
181
  binding = true
@@ -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
- "Value #{hash} must be a Hash or a #{message_class.name}"
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, 'Value ' + array.to_s + ' must be an array'
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
@@ -29,6 +29,6 @@
29
29
 
30
30
  module Google
31
31
  module Gax
32
- VERSION = '0.10.2'.freeze
32
+ VERSION = '1.0.0'.freeze
33
33
  end
34
34
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2017, Google Inc. All rights reserved.
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 Inc. nor the names of its
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/0.6.8 gax/#{Google::Gax::VERSION}"
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,
@@ -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.
@@ -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 = :FAKE_STATUS_CODE_1
43
- FAKE_STATUS_CODE_2 = :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
@@ -158,7 +158,7 @@ describe Google::Gax do
158
158
  # A dummy api call that raises an exception
159
159
  def raise_exc
160
160
  proc do |_|
161
- raise Google::Gax::GaxError, 'Raised in a test'
161
+ raise Google::Gax::GaxError.new('Raised in a test')
162
162
  end
163
163
  end
164
164
 
@@ -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 be_an_instance_of(Google::Gax::GaxError)
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 be_an_instance_of(Google::Gax::GaxError)
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
- raise Google::Gax::GaxError, e.message
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.10.2
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-01 00:00:00.000000000 Z
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.4.8
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