Merge pull request #9145 from nathanielmanistaatgoogle/v1.0.x-upmerge

v1.0.x manual upmerge
pull/9165/head
Nicolas Noble 8 years ago committed by GitHub
commit f29de26194
  1. 6
      gRPC-Core.podspec
  2. 4
      gRPC-ProtoRPC.podspec
  3. 4
      gRPC-RxLibrary.podspec
  4. 4
      gRPC.podspec
  5. 2
      grpc.gemspec
  6. 12
      include/grpc/grpc.h
  7. 13
      src/node/src/client.js
  8. 18
      src/node/src/server.js
  9. 7
      src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
  10. 2
      src/objective-c/GRPCClient/private/GRPCHost.m
  11. 8
      src/python/grpcio/grpc/__init__.py
  12. 128
      src/python/grpcio/grpc/_channel.py
  13. 22
      src/python/grpcio_tests/tests/interop/methods.py
  14. 1
      src/python/grpcio_tests/tests/tests.json
  15. 4
      src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
  16. 175
      src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
  17. 4
      src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
  18. 1
      src/ruby/ext/grpc/rb_byte_buffer.c
  19. 28
      src/ruby/ext/grpc/rb_server.c
  20. 156
      src/ruby/lib/grpc/errors.rb
  21. 4
      src/ruby/lib/grpc/generic/active_call.rb
  22. 4
      src/ruby/lib/grpc/generic/bidi_call.rb
  23. 3
      src/ruby/lib/grpc/generic/service.rb
  24. 4
      src/ruby/pb/grpc/health/checker.rb
  25. 7
      src/ruby/pb/test/client.rb
  26. 6
      src/ruby/qps/client.rb
  27. 64
      src/ruby/spec/error_sanity_spec.rb
  28. 9
      src/ruby/spec/generic/client_stub_spec.rb
  29. 8
      src/ruby/spec/generic/rpc_server_spec.rb
  30. 8
      src/ruby/spec/pb/health/checker_spec.rb
  31. 2
      src/ruby/spec/spec_helper.rb
  32. 6
      templates/gRPC-Core.podspec.template
  33. 2
      templates/grpc.gemspec.template
  34. 2
      tools/buildgen/generate_build_additions.sh
  35. 2
      tools/run_tests/build_artifact_node.bat
  36. 2
      tools/run_tests/build_artifact_node.sh

@ -35,7 +35,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.0.1'
version = '1.0.2'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'http://www.grpc.io'
@ -44,7 +44,9 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "v#{version}",
# TODO(mxyan): Change back to "v#{version}" for next release
#:tag => "v#{version}",
:tag => "objective-c-v#{version}",
# TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
:submodules => true,
}

@ -30,7 +30,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.0.1'
version = '1.0.2'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'http://www.grpc.io'
@ -39,7 +39,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "v#{version}",
:tag => "objective-c-v#{version}",
}
s.ios.deployment_target = '7.1'

@ -30,7 +30,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.0.1'
version = '1.0.2'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'http://www.grpc.io'
@ -39,7 +39,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "v#{version}",
:tag => "objective-c-v#{version}",
}
s.ios.deployment_target = '7.1'

@ -30,7 +30,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.0.1'
version = '1.0.2'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'http://www.grpc.io'
@ -39,7 +39,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "v#{version}",
:tag => "objective-c-v#{version}",
}
s.ios.deployment_target = '7.1'

@ -27,7 +27,7 @@ Gem::Specification.new do |s|
s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.0.2'
s.add_dependency 'google-protobuf', '~> 3.1.0'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_development_dependency 'bundler', '~> 1.9'

@ -202,9 +202,15 @@ GRPCAPI grpc_call *grpc_channel_create_registered_call(
completion of type 'tag' to the completion queue bound to the call.
The order of ops specified in the batch has no significance.
Only one operation of each type can be active at once in any given
batch. You must call grpc_completion_queue_next or
grpc_completion_queue_pluck on the completion queue associated with 'call'
for work to be performed.
batch.
If a call to grpc_call_start_batch returns GRPC_CALL_OK you must call
grpc_completion_queue_next or grpc_completion_queue_pluck on the completion
queue associated with 'call' for work to be performed. If a call to
grpc_call_start_batch returns any value other than GRPC_CALL_OK it is
guaranteed that no state associated with 'call' is changed and it is not
appropriate to call grpc_completion_queue_next or
grpc_completion_queue_pluck consequent to the failed grpc_call_start_batch
call.
THREAD SAFETY: access to grpc_call_start_batch in multi-threaded environment
needs to be synchronized. As an optimization, you may synchronize batches
containing just send operations independently from batches containing just

@ -99,7 +99,18 @@ function ClientWritableStream(call, serialize) {
function _write(chunk, encoding, callback) {
/* jshint validthis: true */
var batch = {};
var message = this.serialize(chunk);
var message;
try {
message = this.serialize(chunk);
} catch (e) {
/* Sending this error to the server and emitting it immediately on the
client may put the call in a slightly weird state on the client side,
but passing an object that causes a serialization failure is a misuse
of the API anyway, so that's OK. The primary purpose here is to give the
programmer a useful error and to stop the stream properly */
this.call.cancelWithStatus(grpc.status.INTERNAL, "Serialization failure");
callback(e);
}
if (_.isFinite(encoding)) {
/* Attach the encoding if it is a finite number. This is the closest we
* can get to checking that it is valid flags */

@ -127,7 +127,14 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
(new Metadata())._getCoreRepresentation();
call.metadataSent = true;
}
var message = serialize(value);
var message;
try {
message = serialize(value);
} catch (e) {
e.code = grpc.status.INTERNAL;
handleError(e);
return;
}
message.grpcWriteFlags = flags;
end_batch[grpc.opType.SEND_MESSAGE] = message;
end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status;
@ -278,7 +285,14 @@ function _write(chunk, encoding, callback) {
(new Metadata())._getCoreRepresentation();
this.call.metadataSent = true;
}
var message = this.serialize(chunk);
var message;
try {
message = this.serialize(chunk);
} catch (e) {
e.code = grpc.status.INTERNAL;
callback(e);
return;
}
if (_.isFinite(encoding)) {
/* Attach the encoding if it is a finite number. This is the closest we
* can get to checking that it is valid flags */

@ -36,7 +36,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
v = '1.0.1'
v = '1.0.2'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
@ -84,7 +84,10 @@ Pod::Spec.new do |s|
repo = 'grpc/grpc'
file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip"
s.source = {
:http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
# TODO(mxyan): Change back to "https://github.com/#{repo}/releases/download/v#{v}/#{file}" for
# next release
# :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
:http => "https://github.com/#{repo}/releases/download/objective-c-v#{v}/#{file}",
# TODO(jcanizales): Add sha1 or sha256
# :sha1 => '??',
}

@ -50,7 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
// TODO(jcanizales): Generate the version in a standalone header, from templates. Like
// templates/src/core/surface/version.c.template .
#define GRPC_OBJC_VERSION_STRING @"1.0.1"
#define GRPC_OBJC_VERSION_STRING @"1.0.2"
static NSMutableDictionary *kHostCache;

@ -768,8 +768,8 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
gRPC runtime to determine the status code of the RPC.
Args:
code: The integer status code of the RPC to be transmitted to the
invocation side of the RPC.
code: A StatusCode value to be transmitted to the invocation side of the
RPC as the status code of the RPC.
"""
raise NotImplementedError()
@ -781,8 +781,8 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
details to transmit.
Args:
details: The details string of the RPC to be transmitted to
the invocation side of the RPC.
details: A string to be transmitted to the invocation side of the RPC as
the status details of the RPC.
"""
raise NotImplementedError()

@ -36,8 +36,8 @@ import time
import grpc
from grpc import _common
from grpc import _grpcio_metadata
from grpc.framework.foundation import callable_util
from grpc._cython import cygrpc
from grpc.framework.foundation import callable_util
_USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
@ -99,6 +99,22 @@ def _wait_once_until(condition, until):
else:
condition.wait(timeout=remaining)
_INTERNAL_CALL_ERROR_MESSAGE_FORMAT = (
'Internal gRPC call error %d. ' +
'Please report to https://github.com/grpc/grpc/issues')
def _check_call_error(call_error, metadata):
if call_error == cygrpc.CallError.invalid_metadata:
raise ValueError('metadata was invalid: %s' % metadata)
elif call_error != cygrpc.CallError.ok:
raise ValueError(_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
def _call_error_set_RPCstate(state, call_error, metadata):
if call_error == cygrpc.CallError.invalid_metadata:
_abort(state, grpc.StatusCode.INTERNAL, 'metadata was invalid: %s' % metadata)
else:
_abort(state, grpc.StatusCode.INTERNAL,
_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
class _RPCState(object):
@ -358,7 +374,7 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call):
if self._state.callbacks is None:
return False
else:
self._state.callbacks.append(lambda: callback())
self._state.callbacks.append(callback)
return True
def initial_metadata(self):
@ -435,10 +451,10 @@ def _end_unary_response_blocking(state, with_call, deadline):
class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
def __init__(
self, channel, create_managed_call, method, request_serializer,
self, channel, managed_call, method, request_serializer,
response_deserializer):
self._channel = channel
self._create_managed_call = create_managed_call
self._managed_call = managed_call
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
@ -472,7 +488,8 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
None, 0, completion_queue, self._method, None, deadline_timespec)
if credentials is not None:
call.set_credentials(credentials._credentials)
call.start_client_batch(cygrpc.Operations(operations), None)
call_error = call.start_client_batch(cygrpc.Operations(operations), None)
_check_call_error(call_error, metadata)
_handle_event(completion_queue.poll(), state, self._response_deserializer)
return state, deadline
@ -490,23 +507,28 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
if rendezvous:
return rendezvous
else:
call = self._create_managed_call(
call, drive_call = self._managed_call(
None, 0, self._method, None, deadline_timespec)
if credentials is not None:
call.set_credentials(credentials._credentials)
event_handler = _event_handler(state, call, self._response_deserializer)
with state.condition:
call.start_client_batch(cygrpc.Operations(operations), event_handler)
call_error = call.start_client_batch(cygrpc.Operations(operations),
event_handler)
if call_error != cygrpc.CallError.ok:
_call_error_set_RPCstate(state, call_error, metadata)
return _Rendezvous(state, None, None, deadline)
drive_call()
return _Rendezvous(state, call, self._response_deserializer, deadline)
class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
def __init__(
self, channel, create_managed_call, method, request_serializer,
self, channel, managed_call, method, request_serializer,
response_deserializer):
self._channel = channel
self._create_managed_call = create_managed_call
self._managed_call = managed_call
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
@ -518,7 +540,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
raise rendezvous
else:
state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
call = self._create_managed_call(
call, drive_call = self._managed_call(
None, 0, self._method, None, deadline_timespec)
if credentials is not None:
call.set_credentials(credentials._credentials)
@ -535,17 +557,22 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
)
call.start_client_batch(cygrpc.Operations(operations), event_handler)
call_error = call.start_client_batch(cygrpc.Operations(operations),
event_handler)
if call_error != cygrpc.CallError.ok:
_call_error_set_RPCstate(state, call_error, metadata)
return _Rendezvous(state, None, None, deadline)
drive_call()
return _Rendezvous(state, call, self._response_deserializer, deadline)
class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
def __init__(
self, channel, create_managed_call, method, request_serializer,
self, channel, managed_call, method, request_serializer,
response_deserializer):
self._channel = channel
self._create_managed_call = create_managed_call
self._managed_call = managed_call
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
@ -569,7 +596,8 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
cygrpc.operation_receive_message(_EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
)
call.start_client_batch(cygrpc.Operations(operations), None)
call_error = call.start_client_batch(cygrpc.Operations(operations), None)
_check_call_error(call_error, metadata)
_consume_request_iterator(
request_iterator, state, call, self._request_serializer)
while True:
@ -597,7 +625,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
self, request_iterator, timeout=None, metadata=None, credentials=None):
deadline, deadline_timespec = _deadline(timeout)
state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
call = self._create_managed_call(
call, drive_call = self._managed_call(
None, 0, self._method, None, deadline_timespec)
if credentials is not None:
call.set_credentials(credentials._credentials)
@ -613,7 +641,12 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
cygrpc.operation_receive_message(_EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
)
call.start_client_batch(cygrpc.Operations(operations), event_handler)
call_error = call.start_client_batch(cygrpc.Operations(operations),
event_handler)
if call_error != cygrpc.CallError.ok:
_call_error_set_RPCstate(state, call_error, metadata)
return _Rendezvous(state, None, None, deadline)
drive_call()
_consume_request_iterator(
request_iterator, state, call, self._request_serializer)
return _Rendezvous(state, call, self._response_deserializer, deadline)
@ -622,10 +655,10 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
def __init__(
self, channel, create_managed_call, method, request_serializer,
self, channel, managed_call, method, request_serializer,
response_deserializer):
self._channel = channel
self._create_managed_call = create_managed_call
self._managed_call = managed_call
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
@ -634,7 +667,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
self, request_iterator, timeout=None, metadata=None, credentials=None):
deadline, deadline_timespec = _deadline(timeout)
state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
call = self._create_managed_call(
call, drive_call = self._managed_call(
None, 0, self._method, None, deadline_timespec)
if credentials is not None:
call.set_credentials(credentials._credentials)
@ -649,7 +682,12 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
_common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
)
call.start_client_batch(cygrpc.Operations(operations), event_handler)
call_error = call.start_client_batch(cygrpc.Operations(operations),
event_handler)
if call_error != cygrpc.CallError.ok:
_call_error_set_RPCstate(state, call_error, metadata)
return _Rendezvous(state, None, None, deadline)
drive_call()
_consume_request_iterator(
request_iterator, state, call, self._request_serializer)
return _Rendezvous(state, call, self._response_deserializer, deadline)
@ -687,16 +725,13 @@ def _run_channel_spin_thread(state):
channel_spin_thread.start()
def _create_channel_managed_call(state):
def create_channel_managed_call(parent, flags, method, host, deadline):
"""Creates a managed cygrpc.Call.
def _channel_managed_call_management(state):
def create(parent, flags, method, host, deadline):
"""Creates a managed cygrpc.Call and a function to call to drive it.
Callers of this function must conduct at least one operation on the returned
call. The tags associated with operations conducted on the returned call
must be no-argument callables that return None to indicate that this channel
should continue polling for events associated with the call and return the
call itself to indicate that no more events associated with the call will be
generated.
If operations are successfully added to the returned cygrpc.Call, the
returned function must be called. If operations are not successfully added
to the returned cygrpc.Call, the returned function must not be called.
Args:
parent: A cygrpc.Call to be used as the parent of the created call.
@ -706,18 +741,22 @@ def _create_channel_managed_call(state):
deadline: A cygrpc.Timespec to be the deadline of the created call.
Returns:
A cygrpc.Call with which to conduct an RPC.
A cygrpc.Call with which to conduct an RPC and a function to call if
operations are successfully started on the call.
"""
with state.lock:
call = state.channel.create_call(
parent, flags, state.completion_queue, method, host, deadline)
if state.managed_calls is None:
state.managed_calls = set((call,))
_run_channel_spin_thread(state)
else:
state.managed_calls.add(call)
return call
return create_channel_managed_call
call = state.channel.create_call(
parent, flags, state.completion_queue, method, host, deadline)
def drive():
with state.lock:
if state.managed_calls is None:
state.managed_calls = set((call,))
_run_channel_spin_thread(state)
else:
state.managed_calls.add(call)
return call, drive
return create
class _ChannelConnectivityState(object):
@ -847,6 +886,7 @@ def _options(options):
class Channel(grpc.Channel):
"""A cygrpc.Channel-backed implementation of grpc.Channel."""
def __init__(self, target, options, credentials):
"""Constructor.
@ -871,25 +911,25 @@ class Channel(grpc.Channel):
def unary_unary(
self, method, request_serializer=None, response_deserializer=None):
return _UnaryUnaryMultiCallable(
self._channel, _create_channel_managed_call(self._call_state),
self._channel, _channel_managed_call_management(self._call_state),
_common.encode(method), request_serializer, response_deserializer)
def unary_stream(
self, method, request_serializer=None, response_deserializer=None):
return _UnaryStreamMultiCallable(
self._channel, _create_channel_managed_call(self._call_state),
self._channel, _channel_managed_call_management(self._call_state),
_common.encode(method), request_serializer, response_deserializer)
def stream_unary(
self, method, request_serializer=None, response_deserializer=None):
return _StreamUnaryMultiCallable(
self._channel, _create_channel_managed_call(self._call_state),
self._channel, _channel_managed_call_management(self._call_state),
_common.encode(method), request_serializer, response_deserializer)
def stream_stream(
self, method, request_serializer=None, response_deserializer=None):
return _StreamStreamMultiCallable(
self._channel, _create_channel_managed_call(self._call_state),
self._channel, _channel_managed_call_management(self._call_state),
_common.encode(method), request_serializer, response_deserializer)
def __del__(self):

@ -33,7 +33,6 @@ import enum
import json
import os
import threading
import time
from oauth2client import client as oauth2client_client
@ -196,16 +195,6 @@ def _server_streaming(stub):
response, messages_pb2.COMPRESSABLE, sizes[index])
def _cancel_after_begin(stub):
sizes = (27182, 8, 1828, 45904,)
payloads = (messages_pb2.Payload(body=b'\x00' * size) for size in sizes)
requests = (messages_pb2.StreamingInputCallRequest(payload=payload)
for payload in payloads)
response_future = stub.StreamingInputCall.future(requests)
response_future.cancel()
if not response_future.cancelled():
raise ValueError('expected call to be cancelled')
class _Pipe(object):
@ -265,6 +254,16 @@ def _ping_pong(stub):
response, messages_pb2.COMPRESSABLE, response_size)
def _cancel_after_begin(stub):
with _Pipe() as pipe:
response_future = stub.StreamingInputCall.future(pipe)
response_future.cancel()
if not response_future.cancelled():
raise ValueError('expected cancelled method to return True')
if response_future.code() is not grpc.StatusCode.CANCELLED:
raise ValueError('expected status code CANCELLED')
def _cancel_after_first_response(stub):
request_response_sizes = (31415, 9, 2653, 58979,)
request_payload_sizes = (27182, 8, 1828, 45904,)
@ -302,7 +301,6 @@ def _timeout_on_sleeping_server(stub):
response_type=messages_pb2.COMPRESSABLE,
payload=messages_pb2.Payload(body=b'\x00' * request_payload_size))
pipe.add(request)
time.sleep(0.1)
try:
next(response_iterator)
except grpc.RpcError as rpc_error:

@ -27,6 +27,7 @@
"unit._cython.cygrpc_test.TypeSmokeTest",
"unit._empty_message_test.EmptyMessageTest",
"unit._exit_test.ExitTest",
"unit._invalid_metadata_test.InvalidMetadataTest",
"unit._metadata_code_details_test.MetadataCodeDetailsTest",
"unit._metadata_test.MetadataTest",
"unit._rpc_test.RPCTest",

@ -64,7 +64,7 @@ class ChannelReadyFutureTest(unittest.TestCase):
ready_future = grpc.channel_ready_future(channel)
ready_future.add_done_callback(callback.accept_value)
with self.assertRaises(grpc.FutureTimeoutError):
ready_future.result(test_constants.SHORT_TIMEOUT)
ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
self.assertFalse(ready_future.cancelled())
self.assertFalse(ready_future.done())
self.assertTrue(ready_future.running())
@ -85,7 +85,7 @@ class ChannelReadyFutureTest(unittest.TestCase):
ready_future = grpc.channel_ready_future(channel)
ready_future.add_done_callback(callback.accept_value)
self.assertIsNone(ready_future.result(test_constants.SHORT_TIMEOUT))
self.assertIsNone(ready_future.result(timeout=test_constants.LONG_TIMEOUT))
value_passed_to_callback = callback.block_until_called()
self.assertIs(ready_future, value_passed_to_callback)
self.assertFalse(ready_future.cancelled())

@ -0,0 +1,175 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Test of RPCs made against gRPC Python's application-layer API."""
import unittest
import grpc
from tests.unit.framework.common import test_constants
_SERIALIZE_REQUEST = lambda bytestring: bytestring * 2
_DESERIALIZE_REQUEST = lambda bytestring: bytestring[len(bytestring) // 2:]
_SERIALIZE_RESPONSE = lambda bytestring: bytestring * 3
_DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3]
_UNARY_UNARY = '/test/UnaryUnary'
_UNARY_STREAM = '/test/UnaryStream'
_STREAM_UNARY = '/test/StreamUnary'
_STREAM_STREAM = '/test/StreamStream'
def _unary_unary_multi_callable(channel):
return channel.unary_unary(_UNARY_UNARY)
def _unary_stream_multi_callable(channel):
return channel.unary_stream(
_UNARY_STREAM,
request_serializer=_SERIALIZE_REQUEST,
response_deserializer=_DESERIALIZE_RESPONSE)
def _stream_unary_multi_callable(channel):
return channel.stream_unary(
_STREAM_UNARY,
request_serializer=_SERIALIZE_REQUEST,
response_deserializer=_DESERIALIZE_RESPONSE)
def _stream_stream_multi_callable(channel):
return channel.stream_stream(_STREAM_STREAM)
class InvalidMetadataTest(unittest.TestCase):
def setUp(self):
self._channel = grpc.insecure_channel('localhost:8080')
self._unary_unary = _unary_unary_multi_callable(self._channel)
self._unary_stream = _unary_stream_multi_callable(self._channel)
self._stream_unary = _stream_unary_multi_callable(self._channel)
self._stream_stream = _stream_stream_multi_callable(self._channel)
def testUnaryRequestBlockingUnaryResponse(self):
request = b'\x07\x08'
metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
with self.assertRaises(ValueError) as exception_context:
self._unary_unary(request, metadata=metadata)
self.assertIn(expected_error_details, str(exception_context.exception))
def testUnaryRequestBlockingUnaryResponseWithCall(self):
request = b'\x07\x08'
metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponseWithCall'),)
expected_error_details = "metadata was invalid: %s" % metadata
with self.assertRaises(ValueError) as exception_context:
self._unary_unary.with_call(request, metadata=metadata)
self.assertIn(expected_error_details, str(exception_context.exception))
def testUnaryRequestFutureUnaryResponse(self):
request = b'\x07\x08'
metadata = (('InVaLiD', 'UnaryRequestFutureUnaryResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
response_future = self._unary_unary.future(request, metadata=metadata)
with self.assertRaises(grpc.RpcError) as exception_context:
response_future.result()
self.assertEqual(
exception_context.exception.details(), expected_error_details)
self.assertEqual(
exception_context.exception.code(), grpc.StatusCode.INTERNAL)
self.assertEqual(response_future.details(), expected_error_details)
self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
def testUnaryRequestStreamResponse(self):
request = b'\x37\x58'
metadata = (('InVaLiD', 'UnaryRequestStreamResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
response_iterator = self._unary_stream(request, metadata=metadata)
with self.assertRaises(grpc.RpcError) as exception_context:
next(response_iterator)
self.assertEqual(
exception_context.exception.details(), expected_error_details)
self.assertEqual(
exception_context.exception.code(), grpc.StatusCode.INTERNAL)
self.assertEqual(response_iterator.details(), expected_error_details)
self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
def testStreamRequestBlockingUnaryResponse(self):
request_iterator = (b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
with self.assertRaises(ValueError) as exception_context:
self._stream_unary(request_iterator, metadata=metadata)
self.assertIn(expected_error_details, str(exception_context.exception))
def testStreamRequestBlockingUnaryResponseWithCall(self):
request_iterator = (
b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponseWithCall'),)
expected_error_details = "metadata was invalid: %s" % metadata
multi_callable = _stream_unary_multi_callable(self._channel)
with self.assertRaises(ValueError) as exception_context:
multi_callable.with_call(request_iterator, metadata=metadata)
self.assertIn(expected_error_details, str(exception_context.exception))
def testStreamRequestFutureUnaryResponse(self):
request_iterator = (
b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
metadata = (('InVaLiD', 'StreamRequestFutureUnaryResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
response_future = self._stream_unary.future(
request_iterator, metadata=metadata)
with self.assertRaises(grpc.RpcError) as exception_context:
response_future.result()
self.assertEqual(
exception_context.exception.details(), expected_error_details)
self.assertEqual(
exception_context.exception.code(), grpc.StatusCode.INTERNAL)
self.assertEqual(response_future.details(), expected_error_details)
self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
def testStreamRequestStreamResponse(self):
request_iterator = (
b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
metadata = (('InVaLiD', 'StreamRequestStreamResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
response_iterator = self._stream_stream(request_iterator, metadata=metadata)
with self.assertRaises(grpc.RpcError) as exception_context:
next(response_iterator)
self.assertEqual(
exception_context.exception.details(), expected_error_details)
self.assertEqual(
exception_context.exception.code(), grpc.StatusCode.INTERNAL)
self.assertEqual(response_iterator.details(), expected_error_details)
self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
if __name__ == '__main__':
unittest.main(verbosity=2)

@ -66,7 +66,7 @@ class ChannelConnectivityTest(unittest.TestCase):
ready_future = utilities.channel_ready_future(channel)
ready_future.add_done_callback(callback.accept_value)
with self.assertRaises(future.TimeoutError):
ready_future.result(test_constants.SHORT_TIMEOUT)
ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
self.assertFalse(ready_future.cancelled())
self.assertFalse(ready_future.done())
self.assertTrue(ready_future.running())
@ -88,7 +88,7 @@ class ChannelConnectivityTest(unittest.TestCase):
ready_future = utilities.channel_ready_future(channel)
ready_future.add_done_callback(callback.accept_value)
self.assertIsNone(
ready_future.result(test_constants.SHORT_TIMEOUT))
ready_future.result(timeout=test_constants.LONG_TIMEOUT))
value_passed_to_callback = callback.block_until_called()
self.assertIs(ready_future, value_passed_to_callback)
self.assertFalse(ready_future.cancelled())

@ -65,5 +65,6 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
GRPC_SLICE_LENGTH(next));
grpc_slice_unref(next);
}
grpc_byte_buffer_reader_destroy(&reader);
return rb_string;
}

@ -37,6 +37,7 @@
#include "rb_server.h"
#include <grpc/grpc.h>
#include <grpc/support/atm.h>
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include "rb_call.h"
@ -59,22 +60,26 @@ typedef struct grpc_rb_server {
/* The actual server */
grpc_server *wrapped;
grpc_completion_queue *queue;
gpr_atm shutdown_started;
} grpc_rb_server;
static void destroy_server(grpc_rb_server *server, gpr_timespec deadline) {
grpc_event ev;
if (server->wrapped != NULL) {
grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
if (ev.type == GRPC_QUEUE_TIMEOUT) {
grpc_server_cancel_all_calls(server->wrapped);
rb_completion_queue_pluck(server->queue, NULL,
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
// This can be started by app or implicitly by GC. Avoid a race between these.
if (gpr_atm_full_fetch_add(&server->shutdown_started, (gpr_atm)1) == 0) {
if (server->wrapped != NULL) {
grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
if (ev.type == GRPC_QUEUE_TIMEOUT) {
grpc_server_cancel_all_calls(server->wrapped);
rb_completion_queue_pluck(server->queue, NULL,
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
}
grpc_server_destroy(server->wrapped);
grpc_rb_completion_queue_destroy(server->queue);
server->wrapped = NULL;
server->queue = NULL;
}
grpc_server_destroy(server->wrapped);
grpc_rb_completion_queue_destroy(server->queue);
server->wrapped = NULL;
server->queue = NULL;
}
}
@ -115,6 +120,7 @@ static const rb_data_type_t grpc_rb_server_data_type = {
static VALUE grpc_rb_server_alloc(VALUE cls) {
grpc_rb_server *wrapper = ALLOC(grpc_rb_server);
wrapper->wrapped = NULL;
wrapper->shutdown_started = (gpr_atm)0;
return TypedData_Wrap_Struct(cls, &grpc_rb_server_data_type, wrapper);
}

@ -35,9 +35,18 @@ module GRPC
# either end of a GRPC connection. When raised, it indicates that a status
# error should be returned to the other end of a GRPC connection; when
# caught it means that this end received a status error.
#
# There is also subclass of BadStatus in this module for each GRPC status.
# E.g., the GRPC::Cancelled class corresponds to status CANCELLED.
#
# See
# https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/status.h
# for detailed descriptions of each status code.
class BadStatus < StandardError
attr_reader :code, :details, :metadata
include GRPC::Core::StatusCodes
# @param code [Numeric] the status code
# @param details [String] the details of the exception
# @param metadata [Hash] the error's metadata
@ -55,9 +64,152 @@ module GRPC
def to_status
Struct::Status.new(code, details, @metadata)
end
def self.new_status_exception(code, details = 'unkown cause', metadata = {})
codes = {}
codes[OK] = Ok
codes[CANCELLED] = Cancelled
codes[UNKNOWN] = Unknown
codes[INVALID_ARGUMENT] = InvalidArgument
codes[DEADLINE_EXCEEDED] = DeadlineExceeded
codes[NOT_FOUND] = NotFound
codes[ALREADY_EXISTS] = AlreadyExists
codes[PERMISSION_DENIED] = PermissionDenied
codes[UNAUTHENTICATED] = Unauthenticated
codes[RESOURCE_EXHAUSTED] = ResourceExhausted
codes[FAILED_PRECONDITION] = FailedPrecondition
codes[ABORTED] = Aborted
codes[OUT_OF_RANGE] = OutOfRange
codes[UNIMPLEMENTED] = Unimplemented
codes[INTERNAL] = Internal
codes[UNIMPLEMENTED] = Unimplemented
codes[UNAVAILABLE] = Unavailable
codes[DATA_LOSS] = DataLoss
if codes[code].nil?
BadStatus.new(code, details, metadata)
else
codes[code].new(details, metadata)
end
end
end
# GRPC status code corresponding to status OK
class Ok < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::OK, details, metadata)
end
end
# Cancelled is an exception class that indicates that an rpc was cancelled.
class Cancelled < StandardError
# GRPC status code corresponding to status CANCELLED
class Cancelled < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::CANCELLED, details, metadata)
end
end
# GRPC status code corresponding to status UNKNOWN
class Unknown < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::UNKNOWN, details, metadata)
end
end
# GRPC status code corresponding to status INVALID_ARGUMENT
class InvalidArgument < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::INVALID_ARGUMENT, details, metadata)
end
end
# GRPC status code corresponding to status DEADLINE_EXCEEDED
class DeadlineExceeded < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::DEADLINE_EXCEEDED, details, metadata)
end
end
# GRPC status code corresponding to status NOT_FOUND
class NotFound < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::NOT_FOUND, details, metadata)
end
end
# GRPC status code corresponding to status ALREADY_EXISTS
class AlreadyExists < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::ALREADY_EXISTS, details, metadata)
end
end
# GRPC status code corresponding to status PERMISSION_DENIED
class PermissionDenied < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::PERMISSION_DENIED, details, metadata)
end
end
# GRPC status code corresponding to status UNAUTHENTICATED
class Unauthenticated < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::UNAUTHENTICATED, details, metadata)
end
end
# GRPC status code corresponding to status RESOURCE_EXHAUSTED
class ResourceExhausted < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::RESOURCE_EXHAUSTED, details, metadata)
end
end
# GRPC status code corresponding to status FAILED_PRECONDITION
class FailedPrecondition < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::FAILED_PRECONDITION, details, metadata)
end
end
# GRPC status code corresponding to status ABORTED
class Aborted < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::ABORTED, details, metadata)
end
end
# GRPC status code corresponding to status OUT_OF_RANGE
class OutOfRange < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::OUT_OF_RANGE, details, metadata)
end
end
# GRPC status code corresponding to status UNIMPLEMENTED
class Unimplemented < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::UNIMPLEMENTED, details, metadata)
end
end
# GRPC status code corresponding to status INTERNAL
class Internal < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::INTERNAL, details, metadata)
end
end
# GRPC status code corresponding to status UNAVAILABLE
class Unavailable < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::UNAVAILABLE, details, metadata)
end
end
# GRPC status code corresponding to status DATA_LOSS
class DataLoss < BadStatus
def initialize(details = 'unknown cause', metadata = {})
super(Core::StatusCodes::DATA_LOSS, details, metadata)
end
end
end

@ -43,8 +43,8 @@ class Struct
GRPC.logger.debug("Failing with status #{status}")
# raise BadStatus, propagating the metadata if present.
md = status.metadata
fail GRPC::BadStatus.new(status.code, status.details, md),
"status code: #{status.code}, details: #{status.details}"
fail GRPC::BadStatus.new_status_exception(
status.code, status.details, md)
end
status
end

@ -219,6 +219,10 @@ module GRPC
GRPC.logger.debug('bidi-read-loop: finished')
@reads_complete = true
finished
# Make sure that the write loop is done done before finishing the call.
# Note that blocking is ok at this point because we've already received
# a status
@enq_th.join if is_client
end
end
end

@ -111,7 +111,8 @@ module GRPC
marshal_class_method,
unmarshal_class_method)
define_method(GenericService.underscore(name.to_s).to_sym) do
fail GRPC::BadStatus, GRPC::Core::StatusCodes::UNIMPLEMENTED
fail GRPC::BadStatus.new_status_exception(
GRPC::Core::StatusCodes::UNIMPLEMENTED)
end
end

@ -52,7 +52,9 @@ module Grpc
@status_mutex.synchronize do
status = @statuses["#{req.service}"]
end
fail GRPC::BadStatus, StatusCodes::NOT_FOUND if status.nil?
if status.nil?
fail GRPC::BadStatus.new_status_exception(StatusCodes::NOT_FOUND)
end
HealthCheckResponse.new(status: status)
end

@ -459,11 +459,8 @@ class NamedTests
deadline = GRPC::Core::TimeConsts::from_relative_time(1)
resps = @stub.full_duplex_call(enum.each_item, deadline: deadline)
resps.each { } # wait to receive each request (or timeout)
fail 'Should have raised GRPC::BadStatus(DEADLINE_EXCEEDED)'
rescue GRPC::BadStatus => e
assert("#{__callee__}: status was wrong") do
e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
end
fail 'Should have raised GRPC::DeadlineExceeded'
rescue GRPC::DeadlineExceeded
end
def empty_stream

@ -134,6 +134,7 @@ class BenchmarkClient
resp = stub.streaming_call(q.each_item)
start = Time.now
q.push(req)
pushed_sentinal = false
resp.each do |r|
@histogram.add((Time.now-start)*1e9)
if !@done
@ -141,8 +142,9 @@ class BenchmarkClient
start = Time.now
q.push(req)
else
q.push(self)
break
q.push(self) unless pushed_sentinal
# Continue polling on the responses to consume and release resources
pushed_sentinal = true
end
end
end

@ -0,0 +1,64 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'grpc'
StatusCodes = GRPC::Core::StatusCodes
describe StatusCodes do
# convert upper snake-case to camel case.
# e.g., DEADLINE_EXCEEDED -> DeadlineExceeded
def upper_snake_to_camel(name)
name.to_s.split('_').map(&:downcase).map(&:capitalize).join('')
end
StatusCodes.constants.each do |status_name|
it 'there is a subclass of BadStatus corresponding to StatusCode: ' \
"#{status_name} that has code: #{StatusCodes.const_get(status_name)}" do
camel_case = upper_snake_to_camel(status_name)
error_class = GRPC.const_get(camel_case)
# expect the error class to be a subclass of BadStatus
expect(error_class < GRPC::BadStatus)
error_object = error_class.new
# check that the code matches the int value of the error's constant
status_code = StatusCodes.const_get(status_name)
expect(error_object.code).to eq(status_code)
# check default parameters
expect(error_object.details).to eq('unknown cause')
expect(error_object.metadata).to eq({})
# check that the BadStatus factory for creates the correct
# exception too
from_factory = GRPC::BadStatus.new_status_exception(status_code)
expect(from_factory.is_a?(error_class)).to be(true)
end
end
end

@ -190,15 +190,14 @@ describe 'ClientStub' do
end
creds = GRPC::Core::CallCredentials.new(failing_auth)
error_occured = false
unauth_error_occured = false
begin
get_response(stub, credentials: creds)
rescue GRPC::BadStatus => e
error_occured = true
expect(e.code).to eq(GRPC::Core::StatusCodes::UNAUTHENTICATED)
rescue GRPC::Unauthenticated => e
unauth_error_occured = true
expect(e.details.include?(error_message)).to be true
end
expect(error_occured).to eq(true)
expect(unauth_error_occured).to eq(true)
# Kill the server thread so tests can complete
th.kill

@ -408,21 +408,21 @@ describe GRPC::RpcServer do
req = EchoMsg.new
n = 20 # arbitrary, use as many to ensure the server pool is exceeded
threads = []
bad_status_code = nil
one_failed_as_unavailable = false
n.times do
threads << Thread.new do
stub = SlowStub.new(alt_host, :this_channel_is_insecure)
begin
stub.an_rpc(req)
rescue GRPC::BadStatus => e
bad_status_code = e.code
rescue GRPC::ResourceExhausted
one_failed_as_unavailable = true
end
end
end
threads.each(&:join)
alt_srv.stop
t.join
expect(bad_status_code).to be(StatusCodes::RESOURCE_EXHAUSTED)
expect(one_failed_as_unavailable).to be(true)
end
end

@ -122,7 +122,7 @@ describe Grpc::Health::Checker do
checker.check(HCReq.new(service: t[:service]), nil)
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
expect(&blk).to raise_error GRPC::NotFound, expected_msg
end
end
end
@ -141,7 +141,7 @@ describe Grpc::Health::Checker do
checker.check(HCReq.new(service: t[:service]), nil)
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
expect(&blk).to raise_error GRPC::NotFound, expected_msg
end
end
end
@ -163,7 +163,7 @@ describe Grpc::Health::Checker do
checker.check(HCReq.new(service: t[:service]), nil)
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
expect(&blk).to raise_error GRPC::NotFound, expected_msg
end
end
end
@ -214,7 +214,7 @@ describe Grpc::Health::Checker do
stub.check(HCReq.new(service: 'unknown'))
end
expected_msg = /#{StatusCodes::NOT_FOUND}/
expect(&blk).to raise_error GRPC::BadStatus, expected_msg
expect(&blk).to raise_error GRPC::NotFound, expected_msg
@srv.stop
t.join
end

@ -67,3 +67,5 @@ RSpec.configure do |config|
end
RSpec::Expectations.configuration.warn_about_potential_false_positives = false
Thread.abort_on_exception = true

@ -62,7 +62,7 @@
%>
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.0.1'
version = '1.0.2'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'http://www.grpc.io'
@ -71,7 +71,9 @@
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "v#{version}",
# TODO(mxyan): Change back to "v#{version}" for next release
#:tag => "v#{version}",
:tag => "objective-c-v#{version}",
# TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
:submodules => true,
}

@ -29,7 +29,7 @@
s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.0.2'
s.add_dependency 'google-protobuf', '~> 3.1.0'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_development_dependency 'bundler', '~> 1.9'

@ -28,6 +28,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e
gen_build_yaml_dirs=" \
src/boringssl \
src/benchmark \

@ -27,7 +27,7 @@
@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0
set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 7.0.0
set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm

@ -42,7 +42,7 @@ mkdir -p artifacts
npm update
node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 )
node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 7.0.0 )
for version in ${node_versions[@]}
do

Loading…
Cancel
Save