Add a default handler to Ruby services that returns UNIMPLEMENTED

pull/6476/head
murgatroid99 9 years ago
parent 8c33c7442c
commit cf239e7309
  1. 6
      src/ruby/lib/grpc/generic/rpc_server.rb
  2. 16
      src/ruby/lib/grpc/generic/service.rb
  3. 23
      src/ruby/spec/generic/rpc_server_spec.rb
  4. 69
      src/ruby/spec/generic/service_spec.rb

@ -503,10 +503,8 @@ module GRPC
unless cls.include?(GenericService) unless cls.include?(GenericService)
fail "#{cls} must 'include GenericService'" fail "#{cls} must 'include GenericService'"
end end
if cls.rpc_descs.size.zero? fail "#{cls} should specify some rpc descriptions" if
fail "#{cls} should specify some rpc descriptions" cls.rpc_descs.size.zero?
end
cls.assert_rpc_descs_have_methods
end end
# This should be called while holding @run_mutex # This should be called while holding @run_mutex

@ -110,6 +110,9 @@ module GRPC
rpc_descs[name] = RpcDesc.new(name, input, output, rpc_descs[name] = RpcDesc.new(name, input, output,
marshal_class_method, marshal_class_method,
unmarshal_class_method) unmarshal_class_method)
define_method(name) do
fail GRPC::BadStatus, GRPC::Core::StatusCodes::UNIMPLEMENTED
end
end end
def inherited(subclass) def inherited(subclass)
@ -199,19 +202,6 @@ module GRPC
end end
end 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 end
def self.included(o) def self.included(o)

@ -308,10 +308,6 @@ describe GRPC::RpcServer do
expect { @srv.handle(EmptyService) }.to raise_error expect { @srv.handle(EmptyService) }.to raise_error
end 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 it 'raises if a handler method is already registered' do
@srv.handle(EchoService) @srv.handle(EchoService)
expect { r.handle(EchoService) }.to raise_error expect { r.handle(EchoService) }.to raise_error
@ -349,6 +345,25 @@ describe GRPC::RpcServer do
t.join t.join
end 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 it 'should handle multiple sequential requests', server: true do
@srv.handle(EchoService) @srv.handle(EchoService)
t = Thread.new { @srv.run } t = Thread.new { @srv.run }

@ -273,73 +273,4 @@ describe GenericService do
end end
end 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 end

Loading…
Cancel
Save