Add a default handler to Ruby services that returns UNIMPLEMENTED
This commit is contained in:
parent
8c33c7442c
commit
cf239e7309
|
|
@ -503,10 +503,8 @@ module GRPC
|
|||
unless cls.include?(GenericService)
|
||||
fail "#{cls} must 'include GenericService'"
|
||||
end
|
||||
if cls.rpc_descs.size.zero?
|
||||
fail "#{cls} should specify some rpc descriptions"
|
||||
end
|
||||
cls.assert_rpc_descs_have_methods
|
||||
fail "#{cls} should specify some rpc descriptions" if
|
||||
cls.rpc_descs.size.zero?
|
||||
end
|
||||
|
||||
# This should be called while holding @run_mutex
|
||||
|
|
|
|||
|
|
@ -110,6 +110,9 @@ module GRPC
|
|||
rpc_descs[name] = RpcDesc.new(name, input, output,
|
||||
marshal_class_method,
|
||||
unmarshal_class_method)
|
||||
define_method(name) do
|
||||
fail GRPC::BadStatus, GRPC::Core::StatusCodes::UNIMPLEMENTED
|
||||
end
|
||||
end
|
||||
|
||||
def inherited(subclass)
|
||||
|
|
@ -199,19 +202,6 @@ module GRPC
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Asserts that the appropriate methods are defined for each added rpc
|
||||
# spec. Is intended to aid verifying that server classes are correctly
|
||||
# implemented.
|
||||
def assert_rpc_descs_have_methods
|
||||
rpc_descs.each_pair do |m, spec|
|
||||
mth_name = GenericService.underscore(m.to_s).to_sym
|
||||
unless instance_methods.include?(mth_name)
|
||||
fail "#{self} does not provide instance method '#{mth_name}'"
|
||||
end
|
||||
spec.assert_arity_matches(instance_method(mth_name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.included(o)
|
||||
|
|
|
|||
|
|
@ -308,10 +308,6 @@ describe GRPC::RpcServer do
|
|||
expect { @srv.handle(EmptyService) }.to raise_error
|
||||
end
|
||||
|
||||
it 'raises if the service does not define its rpc methods' do
|
||||
expect { @srv.handle(NoRpcImplementation) }.to raise_error
|
||||
end
|
||||
|
||||
it 'raises if a handler method is already registered' do
|
||||
@srv.handle(EchoService)
|
||||
expect { r.handle(EchoService) }.to raise_error
|
||||
|
|
@ -349,6 +345,25 @@ describe GRPC::RpcServer do
|
|||
t.join
|
||||
end
|
||||
|
||||
it 'should return UNIMPLEMENTED on unimplemented methods', server: true do
|
||||
@srv.handle(NoRpcImplementation)
|
||||
t = Thread.new { @srv.run }
|
||||
@srv.wait_till_running
|
||||
req = EchoMsg.new
|
||||
blk = proc do
|
||||
cq = GRPC::Core::CompletionQueue.new
|
||||
stub = GRPC::ClientStub.new(@host, cq, :this_channel_is_insecure,
|
||||
**client_opts)
|
||||
stub.request_response('/an_rpc', req, marshal, unmarshal)
|
||||
end
|
||||
expect(&blk).to raise_error do |error|
|
||||
expect(error).to be_a(GRPC::BadStatus)
|
||||
expect(error.code).to be(GRPC::Core::StatusCodes::UNIMPLEMENTED)
|
||||
end
|
||||
@srv.stop
|
||||
t.join
|
||||
end
|
||||
|
||||
it 'should handle multiple sequential requests', server: true do
|
||||
@srv.handle(EchoService)
|
||||
t = Thread.new { @srv.run }
|
||||
|
|
|
|||
|
|
@ -273,73 +273,4 @@ describe GenericService do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#assert_rpc_descs_have_methods' do
|
||||
it 'fails if there is no instance method for an rpc descriptor' do
|
||||
c1 = Class.new do
|
||||
include GenericService
|
||||
rpc :AnRpc, GoodMsg, GoodMsg
|
||||
end
|
||||
expect { c1.assert_rpc_descs_have_methods }.to raise_error
|
||||
|
||||
c2 = Class.new do
|
||||
include GenericService
|
||||
rpc :AnRpc, GoodMsg, GoodMsg
|
||||
rpc :AnotherRpc, GoodMsg, GoodMsg
|
||||
|
||||
def an_rpc
|
||||
end
|
||||
end
|
||||
expect { c2.assert_rpc_descs_have_methods }.to raise_error
|
||||
end
|
||||
|
||||
it 'passes if there are corresponding methods for each descriptor' do
|
||||
c = Class.new do
|
||||
include GenericService
|
||||
rpc :AnRpc, GoodMsg, GoodMsg
|
||||
rpc :AServerStreamer, GoodMsg, stream(GoodMsg)
|
||||
rpc :AClientStreamer, stream(GoodMsg), GoodMsg
|
||||
rpc :ABidiStreamer, stream(GoodMsg), stream(GoodMsg)
|
||||
|
||||
def an_rpc(_req, _call)
|
||||
end
|
||||
|
||||
def a_server_streamer(_req, _call)
|
||||
end
|
||||
|
||||
def a_client_streamer(_call)
|
||||
end
|
||||
|
||||
def a_bidi_streamer(_call)
|
||||
end
|
||||
end
|
||||
expect { c.assert_rpc_descs_have_methods }.to_not raise_error
|
||||
end
|
||||
|
||||
it 'passes for subclasses of that include GenericService' do
|
||||
base = Class.new do
|
||||
include GenericService
|
||||
rpc :AnRpc, GoodMsg, GoodMsg
|
||||
|
||||
def an_rpc(_req, _call)
|
||||
end
|
||||
end
|
||||
c = Class.new(base)
|
||||
expect { c.assert_rpc_descs_have_methods }.to_not raise_error
|
||||
expect(c.include?(GenericService)).to be(true)
|
||||
end
|
||||
|
||||
it 'passes if subclasses define the rpc methods' do
|
||||
base = Class.new do
|
||||
include GenericService
|
||||
rpc :AnRpc, GoodMsg, GoodMsg
|
||||
end
|
||||
c = Class.new(base) do
|
||||
def an_rpc(_req, _call)
|
||||
end
|
||||
end
|
||||
expect { c.assert_rpc_descs_have_methods }.to_not raise_error
|
||||
expect(c.include?(GenericService)).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue