- Adds the service and message classes generated from beefcake and a patched proto compiler - Adds an interop client that uses these service and message classes - Adds an interop server that implement the service description TESTED interop client works with the interop server Change on 2014/12/08 by temiola <temiola@google.com> ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=81615139pull/1/merge
parent
5ef51949bc
commit
ba22e87c68
9 changed files with 578 additions and 2 deletions
@ -0,0 +1,11 @@ |
|||||||
|
Interop test protos |
||||||
|
=================== |
||||||
|
|
||||||
|
These were generated by a patched version of beefcake and a patched version of |
||||||
|
protoc. |
||||||
|
|
||||||
|
- set up and access of the patched versions is described in ../../README.md |
||||||
|
|
||||||
|
The actual test proto is found in Google3 at |
||||||
|
|
||||||
|
- third_party/stubby/testing/proto/test.proto |
@ -0,0 +1,229 @@ |
|||||||
|
# Copyright 2014, 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. |
||||||
|
|
||||||
|
#!/usr/bin/env ruby |
||||||
|
# interop_client is a testing tool that accesses a gRPC interop testing |
||||||
|
# server and runs a test on it. |
||||||
|
# |
||||||
|
# Helps validate interoperation b/w different gRPC implementations. |
||||||
|
# |
||||||
|
# Usage: $ path/to/interop_client.rb --server_host=<hostname> \ |
||||||
|
# --server_port=<port> \ |
||||||
|
# --test_case=<testcase_name> |
||||||
|
|
||||||
|
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||||
|
lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib') |
||||||
|
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) |
||||||
|
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||||
|
|
||||||
|
require 'optparse' |
||||||
|
require 'minitest' |
||||||
|
require 'minitest/assertions' |
||||||
|
|
||||||
|
require 'grpc' |
||||||
|
require 'grpc/generic/client_stub' |
||||||
|
require 'grpc/generic/service' |
||||||
|
|
||||||
|
require 'third_party/stubby/testing/proto/test.pb' |
||||||
|
require 'third_party/stubby/testing/proto/messages.pb' |
||||||
|
|
||||||
|
# loads the certificates used to access the test server securely. |
||||||
|
def load_test_certs |
||||||
|
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||||
|
data_dir = File.join(File.dirname(File.dirname(this_dir)), 'spec/testdata') |
||||||
|
files = ['ca.pem', 'server1.key', 'server1.pem'] |
||||||
|
files.map { |f| File.open(File.join(data_dir, f)).read } |
||||||
|
end |
||||||
|
|
||||||
|
# creates a Credentials from the test certificates. |
||||||
|
def test_creds |
||||||
|
certs = load_test_certs |
||||||
|
creds = GRPC::Core::Credentials.new(certs[0]) |
||||||
|
end |
||||||
|
|
||||||
|
# creates a test stub that accesses host:port securely. |
||||||
|
def create_stub(host, port) |
||||||
|
address = "#{host}:#{port}" |
||||||
|
stub_opts = { |
||||||
|
:creds => test_creds, |
||||||
|
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com', |
||||||
|
} |
||||||
|
logger.info("... connecting securely to #{address}") |
||||||
|
stub = Grpc::Testing::TestService::Stub.new(address, **stub_opts) |
||||||
|
end |
||||||
|
|
||||||
|
# produces a string of null chars (\0) of length l. |
||||||
|
def nulls(l) |
||||||
|
raise 'requires #{l} to be +ve' if l < 0 |
||||||
|
[].pack('x' * l) |
||||||
|
end |
||||||
|
|
||||||
|
# defines methods corresponding to each interop test case. |
||||||
|
class NamedTests |
||||||
|
include Minitest::Assertions |
||||||
|
include Grpc::Testing |
||||||
|
include Grpc::Testing::PayloadType |
||||||
|
attr_accessor :assertions # required by Minitest::Assertions |
||||||
|
|
||||||
|
def initialize(stub) |
||||||
|
@assertions = 0 # required by Minitest::Assertions |
||||||
|
@stub = stub |
||||||
|
end |
||||||
|
|
||||||
|
# TESTING |
||||||
|
# PASSED |
||||||
|
# FAIL |
||||||
|
# ruby server: fails beefcake throws on deserializing the 0-length message |
||||||
|
def empty_unary |
||||||
|
resp = @stub.empty_call(Proto2::Empty.new) |
||||||
|
assert resp.is_a?(Proto::Empty), 'empty_unary: invalid response' |
||||||
|
p 'OK: empty_unary' |
||||||
|
end |
||||||
|
|
||||||
|
# TESTING |
||||||
|
# PASSED |
||||||
|
# ruby server |
||||||
|
# FAILED |
||||||
|
def large_unary |
||||||
|
req_size, wanted_response_size = 271828, 314159 |
||||||
|
payload = Payload.new(:type => COMPRESSABLE, :body => nulls(req_size)) |
||||||
|
req = SimpleRequest.new(:response_type => COMPRESSABLE, |
||||||
|
:response_size => wanted_response_size, |
||||||
|
:payload => payload) |
||||||
|
resp = @stub.unary_call(req) |
||||||
|
assert_equal(wanted_response_size, resp.payload.body.length, |
||||||
|
'large_unary: payload had the wrong length') |
||||||
|
assert_equal(nulls(wanted_response_size), resp.payload.body, |
||||||
|
'large_unary: payload content is invalid') |
||||||
|
p 'OK: large_unary' |
||||||
|
end |
||||||
|
|
||||||
|
# TESTING: |
||||||
|
# PASSED |
||||||
|
# ruby server |
||||||
|
# FAILED |
||||||
|
def client_streaming |
||||||
|
msg_sizes = [27182, 8, 1828, 45904] |
||||||
|
wanted_aggregate_size = 74922 |
||||||
|
reqs = msg_sizes.map do |x| |
||||||
|
req = Payload.new(:body => nulls(x)) |
||||||
|
StreamingInputCallRequest.new(:payload => req) |
||||||
|
end |
||||||
|
resp = @stub.streaming_input_call(reqs) |
||||||
|
assert_equal(wanted_aggregate_size, resp.aggregated_payload_size, |
||||||
|
'client_streaming: aggregate payload size is incorrect') |
||||||
|
p 'OK: client_streaming' |
||||||
|
end |
||||||
|
|
||||||
|
# TESTING: |
||||||
|
# PASSED |
||||||
|
# ruby server |
||||||
|
# FAILED |
||||||
|
def server_streaming |
||||||
|
msg_sizes = [31415, 9, 2653, 58979] |
||||||
|
response_spec = msg_sizes.map { |s| ResponseParameters.new(:size => s) } |
||||||
|
req = StreamingOutputCallRequest.new(:response_type => COMPRESSABLE, |
||||||
|
:response_parameters => response_spec) |
||||||
|
resps = @stub.streaming_output_call(req) |
||||||
|
resps.each_with_index do |r, i| |
||||||
|
assert i < msg_sizes.length, 'too many responses' |
||||||
|
assert_equal(COMPRESSABLE, r.payload.type, 'payload type is wrong') |
||||||
|
assert_equal(msg_sizes[i], r.payload.body.length, |
||||||
|
'payload body #{i} has the wrong length') |
||||||
|
end |
||||||
|
p 'OK: server_streaming' |
||||||
|
end |
||||||
|
|
||||||
|
# TESTING: |
||||||
|
# PASSED |
||||||
|
# ruby server |
||||||
|
# FAILED |
||||||
|
# |
||||||
|
# TODO(temiola): update this test to stay consistent with the java test's |
||||||
|
# interpretation of the test spec. |
||||||
|
def ping_pong |
||||||
|
req_cls, param_cls= StreamingOutputCallRequest, ResponseParameters # short |
||||||
|
msg_sizes = [[27182, 31415], [8, 9], [1828, 2653], [45904, 58979]] |
||||||
|
reqs = msg_sizes.map do |x| |
||||||
|
req_size, resp_size = x |
||||||
|
req_cls.new(:payload => Payload.new(:body => nulls(req_size)), |
||||||
|
:response_type => COMPRESSABLE, |
||||||
|
:response_parameters => param_cls.new(:size => resp_size)) |
||||||
|
end |
||||||
|
resps = @stub.full_duplex_call(reqs) |
||||||
|
resps.each_with_index do |r, i| |
||||||
|
assert i < msg_sizes.length, 'too many responses' |
||||||
|
assert_equal(COMPRESSABLE, r.payload.type, 'payload type is wrong') |
||||||
|
assert_equal(msg_sizes[i][1], r.payload.body.length, |
||||||
|
'payload body #{i} has the wrong length') |
||||||
|
end |
||||||
|
p 'OK ping_pong' |
||||||
|
end |
||||||
|
|
||||||
|
end |
||||||
|
|
||||||
|
# validates the the command line options, returning them as a Hash. |
||||||
|
def parse_options |
||||||
|
options = { |
||||||
|
'server_host' => nil, |
||||||
|
'server_port' => nil, |
||||||
|
'test_case' => nil, |
||||||
|
} |
||||||
|
OptionParser.new do |opts| |
||||||
|
opts.banner = 'Usage: --server_host <server_host> --server_port server_port' |
||||||
|
opts.on('--server_host SERVER_HOST', 'server hostname') do |v| |
||||||
|
options['server_host'] = v |
||||||
|
end |
||||||
|
opts.on('--server_port SERVER_PORT', 'server port') do |v| |
||||||
|
options['server_port'] = v |
||||||
|
end |
||||||
|
# instance_methods(false) gives only the methods defined in that class |
||||||
|
test_cases = NamedTests.instance_methods(false).map { |t| t.to_s } |
||||||
|
test_case_list = test_cases.join(',') |
||||||
|
opts.on("--test_case CODE", test_cases, {}, "select a test_case", |
||||||
|
" (#{test_case_list})") do |v| |
||||||
|
options['test_case'] = v |
||||||
|
end |
||||||
|
end.parse! |
||||||
|
|
||||||
|
['server_host', 'server_port', 'test_case'].each do |arg| |
||||||
|
if options[arg].nil? |
||||||
|
raise OptionParser::MissingArgument.new("please specify --#{arg}") |
||||||
|
end |
||||||
|
end |
||||||
|
options |
||||||
|
end |
||||||
|
|
||||||
|
def main |
||||||
|
opts = parse_options |
||||||
|
stub = create_stub(opts['server_host'], opts['server_port']) |
||||||
|
NamedTests.new(stub).method(opts['test_case']).call |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,185 @@ |
|||||||
|
# Copyright 2014, 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. |
||||||
|
|
||||||
|
#!/usr/bin/env ruby |
||||||
|
# |
||||||
|
# interop_server is a Testing app that runs a gRPC interop testing server. |
||||||
|
# |
||||||
|
# It helps validate interoperation b/w gRPC in different environments |
||||||
|
# |
||||||
|
# Helps validate interoperation b/w different gRPC implementations. |
||||||
|
# |
||||||
|
# Usage: $ path/to/interop_server.rb --port |
||||||
|
|
||||||
|
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||||
|
lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib') |
||||||
|
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) |
||||||
|
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||||
|
|
||||||
|
require 'forwardable' |
||||||
|
require 'optparse' |
||||||
|
|
||||||
|
require 'grpc' |
||||||
|
require 'grpc/generic/service' |
||||||
|
require 'grpc/generic/rpc_server' |
||||||
|
|
||||||
|
require 'third_party/stubby/testing/proto/test.pb' |
||||||
|
require 'third_party/stubby/testing/proto/messages.pb' |
||||||
|
|
||||||
|
# loads the certificates by the test server. |
||||||
|
def load_test_certs |
||||||
|
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||||
|
data_dir = File.join(File.dirname(File.dirname(this_dir)), 'spec/testdata') |
||||||
|
files = ['ca.pem', 'server1.key', 'server1.pem'] |
||||||
|
files.map { |f| File.open(File.join(data_dir, f)).read } |
||||||
|
end |
||||||
|
|
||||||
|
# creates a ServerCredentials from the test certificates. |
||||||
|
def test_server_creds |
||||||
|
certs = load_test_certs |
||||||
|
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) |
||||||
|
end |
||||||
|
|
||||||
|
# produces a string of null chars (\0) of length l. |
||||||
|
def nulls(l) |
||||||
|
raise 'requires #{l} to be +ve' if l < 0 |
||||||
|
[].pack('x' * l) |
||||||
|
end |
||||||
|
|
||||||
|
# A EnumeratorQueue wraps a Queue yielding the items added to it via each_item. |
||||||
|
class EnumeratorQueue |
||||||
|
extend Forwardable |
||||||
|
def_delegators :@q, :push |
||||||
|
|
||||||
|
def initialize(sentinel) |
||||||
|
@q = Queue.new |
||||||
|
@sentinel = sentinel |
||||||
|
end |
||||||
|
|
||||||
|
def each_item |
||||||
|
return enum_for(:each_item) unless block_given? |
||||||
|
loop do |
||||||
|
r = @q.pop |
||||||
|
break if r.equal?(@sentinel) |
||||||
|
raise r if r.is_a?Exception |
||||||
|
yield r |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# A runnable implementation of the schema-specified testing service, with each |
||||||
|
# service method implemented as required by the interop testing spec. |
||||||
|
class TestTarget < Grpc::Testing::TestService::Service |
||||||
|
include Grpc::Testing |
||||||
|
include Grpc::Testing::PayloadType |
||||||
|
|
||||||
|
def empty_call(empty, call) |
||||||
|
Proto::Empty.new |
||||||
|
end |
||||||
|
|
||||||
|
def unary_call(simple_req, call) |
||||||
|
req_size = simple_req.response_size |
||||||
|
SimpleResponse.new(:payload => Payload.new(:type => COMPRESSABLE, |
||||||
|
:body => nulls(req_size))) |
||||||
|
end |
||||||
|
|
||||||
|
def streaming_input_call(call) |
||||||
|
sizes = call.each_remote_read.map { |x| x.payload.body.length } |
||||||
|
sum = sizes.inject { |sum,x| sum + x } |
||||||
|
StreamingInputCallResponse.new(:aggregated_payload_size => sum) |
||||||
|
end |
||||||
|
|
||||||
|
def streaming_output_call(req, call) |
||||||
|
cls = StreamingOutputCallResponse |
||||||
|
req.response_parameters.map do |p| |
||||||
|
cls.new(:payload => Payload.new(:type => req.response_type, |
||||||
|
:body => nulls(p.size))) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def full_duplex_call(reqs) |
||||||
|
# reqs is a lazy Enumerator of the requests sent by the client. |
||||||
|
q = EnumeratorQueue.new(self) |
||||||
|
cls = StreamingOutputCallResponse |
||||||
|
t = Thread.new do |
||||||
|
begin |
||||||
|
reqs.each do |req| |
||||||
|
logger.info("read #{req.inspect}") |
||||||
|
resp_size = req.response_parameters[0].size |
||||||
|
resp = cls.new(:payload => Payload.new(:type => req.response_type, |
||||||
|
:body => nulls(resp_size))) |
||||||
|
q.push(resp) |
||||||
|
end |
||||||
|
logger.info('finished reads') |
||||||
|
q.push(self) |
||||||
|
rescue StandardError => e |
||||||
|
q.push(e) # share the exception with the enumerator |
||||||
|
end |
||||||
|
end |
||||||
|
q.each_item |
||||||
|
end |
||||||
|
|
||||||
|
def half_duplex_call(reqs) |
||||||
|
# TODO(temiola): clarify the behaviour of the half_duplex_call, it's not |
||||||
|
# currently used in any tests |
||||||
|
full_duplex_call(reqs) |
||||||
|
end |
||||||
|
|
||||||
|
end |
||||||
|
|
||||||
|
# validates the the command line options, returning them as a Hash. |
||||||
|
def parse_options |
||||||
|
options = { |
||||||
|
'port' => nil, |
||||||
|
} |
||||||
|
OptionParser.new do |opts| |
||||||
|
opts.banner = 'Usage: --port port' |
||||||
|
opts.on('--port PORT', 'server port') do |v| |
||||||
|
options['port'] = v |
||||||
|
end |
||||||
|
end.parse! |
||||||
|
|
||||||
|
if options['port'].nil? |
||||||
|
raise OptionParser::MissingArgument.new("please specify --port") |
||||||
|
end |
||||||
|
options |
||||||
|
end |
||||||
|
|
||||||
|
def main |
||||||
|
opts = parse_options |
||||||
|
host = "0.0.0.0:#{opts['port']}" |
||||||
|
s = GRPC::RpcServer.new(creds: test_server_creds) |
||||||
|
s.add_http2_port(host, true) |
||||||
|
logger.info("... running securely on #{host}") |
||||||
|
|
||||||
|
s.handle(TestTarget) |
||||||
|
s.run |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,14 @@ |
|||||||
|
## Generated from net/proto2/bridge/proto/message_set.proto for proto2.bridge |
||||||
|
require 'beefcake' |
||||||
|
|
||||||
|
module Proto2 |
||||||
|
module Bridge |
||||||
|
|
||||||
|
class MessageSet |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class MessageSet |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,12 @@ |
|||||||
|
## Generated from net/proto2/proto/empty.proto for proto2 |
||||||
|
require 'beefcake' |
||||||
|
|
||||||
|
module Proto2 |
||||||
|
|
||||||
|
class Empty |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class Empty |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,94 @@ |
|||||||
|
## Generated from third_party/stubby/testing/proto/messages.proto for grpc.testing |
||||||
|
require 'beefcake' |
||||||
|
|
||||||
|
require 'net/proto2/bridge/proto/message_set.pb' |
||||||
|
|
||||||
|
module Grpc |
||||||
|
module Testing |
||||||
|
|
||||||
|
module PayloadType |
||||||
|
COMPRESSABLE = 0 |
||||||
|
UNCOMPRESSABLE = 1 |
||||||
|
RANDOM = 2 |
||||||
|
end |
||||||
|
|
||||||
|
class Payload |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class SimpleRequest |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class SimpleResponse |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class SimpleContext |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingInputCallRequest |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingInputCallResponse |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class ResponseParameters |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingOutputCallRequest |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingOutputCallResponse |
||||||
|
include Beefcake::Message |
||||||
|
end |
||||||
|
|
||||||
|
class Payload |
||||||
|
optional :type, PayloadType, 1 |
||||||
|
optional :body, :bytes, 2 |
||||||
|
end |
||||||
|
|
||||||
|
class SimpleRequest |
||||||
|
optional :response_type, PayloadType, 1 |
||||||
|
optional :response_size, :int32, 2 |
||||||
|
optional :payload, Payload, 3 |
||||||
|
end |
||||||
|
|
||||||
|
class SimpleResponse |
||||||
|
optional :payload, Payload, 1 |
||||||
|
optional :effective_gaia_user_id, :int64, 2 |
||||||
|
end |
||||||
|
|
||||||
|
class SimpleContext |
||||||
|
optional :value, :string, 1 |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingInputCallRequest |
||||||
|
optional :payload, Payload, 1 |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingInputCallResponse |
||||||
|
optional :aggregated_payload_size, :int32, 1 |
||||||
|
end |
||||||
|
|
||||||
|
class ResponseParameters |
||||||
|
optional :size, :int32, 1 |
||||||
|
optional :interval_us, :int32, 2 |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingOutputCallRequest |
||||||
|
optional :response_type, PayloadType, 1 |
||||||
|
repeated :response_parameters, ResponseParameters, 2 |
||||||
|
optional :payload, Payload, 3 |
||||||
|
end |
||||||
|
|
||||||
|
class StreamingOutputCallResponse |
||||||
|
optional :payload, Payload, 1 |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,30 @@ |
|||||||
|
## Generated from third_party/stubby/testing/proto/test.proto for grpc.testing |
||||||
|
require 'beefcake' |
||||||
|
require 'grpc' |
||||||
|
|
||||||
|
require 'third_party/stubby/testing/proto/messages.pb' |
||||||
|
require 'net/proto2/proto/empty.pb' |
||||||
|
|
||||||
|
module Grpc |
||||||
|
module Testing |
||||||
|
|
||||||
|
module TestService |
||||||
|
|
||||||
|
class Service |
||||||
|
include GRPC::GenericService |
||||||
|
|
||||||
|
self.marshal_class_method = :encode |
||||||
|
self.unmarshal_class_method = :decode |
||||||
|
|
||||||
|
rpc :EmptyCall, Proto2::Empty, Proto2::Empty |
||||||
|
rpc :UnaryCall, SimpleRequest, SimpleResponse |
||||||
|
rpc :StreamingOutputCall, StreamingOutputCallRequest, stream(StreamingOutputCallResponse) |
||||||
|
rpc :StreamingInputCall, stream(StreamingInputCallRequest), StreamingInputCallResponse |
||||||
|
rpc :FullDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse) |
||||||
|
rpc :HalfDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse) |
||||||
|
end |
||||||
|
Stub = Service.rpc_stub_class |
||||||
|
|
||||||
|
end |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue