mirror of https://github.com/grpc/grpc.git
Merge pull request #9986 from apolcyn/fix_connectivity
ruby add background channel state poller to handle disconnected transportspull/10269/head
commit
b0f3f55f8f
24 changed files with 1429 additions and 74 deletions
@ -0,0 +1,18 @@ |
||||
This directory contains some grpc-ruby end to end tests. |
||||
|
||||
Each test here involves two files: a "driver" and a "client". For example, |
||||
the "channel_closing" test involves channel_closing_driver.rb |
||||
and channel_closing_client.rb. |
||||
|
||||
Typically, the "driver" will start up a simple "echo" server, and then |
||||
spawn a client. It gives the client the address of the "echo" server as |
||||
well as an address to listen on for control rpcs. Depending on the test, the |
||||
client usually starts up a "ClientControl" grpc server for the driver to |
||||
interact with (the driver can tell the client process to do strange things at |
||||
different times, depending on the test). |
||||
|
||||
So far these tests are mostly useful for testing process-shutdown related |
||||
situations, since the client's run in separate processes. |
||||
|
||||
These tests are invoked through the "tools/run_tests/run_tests.py" script (the |
||||
Rakefile doesn't start these). |
@ -0,0 +1,84 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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_relative './end2end_common' |
||||
|
||||
# Calls '#close' on a Channel when "shutdown" called. This tries to |
||||
# trigger a hang or crash bug by closing a channel actively being watched |
||||
class ChannelClosingClientController < ClientControl::ClientController::Service |
||||
def initialize(ch) |
||||
@ch = ch |
||||
end |
||||
|
||||
def shutdown(_, _) |
||||
@ch.close |
||||
ClientControl::Void.new |
||||
end |
||||
end |
||||
|
||||
def main |
||||
client_control_port = '' |
||||
server_port = '' |
||||
OptionParser.new do |opts| |
||||
opts.on('--client_control_port=P', String) do |p| |
||||
client_control_port = p |
||||
end |
||||
opts.on('--server_port=P', String) do |p| |
||||
server_port = p |
||||
end |
||||
end.parse! |
||||
|
||||
ch = GRPC::Core::Channel.new("localhost:#{server_port}", {}, |
||||
:this_channel_is_insecure) |
||||
|
||||
srv = GRPC::RpcServer.new |
||||
thd = Thread.new do |
||||
srv.add_http2_port("0.0.0.0:#{client_control_port}", :this_port_is_insecure) |
||||
srv.handle(ChannelClosingClientController.new(ch)) |
||||
srv.run |
||||
end |
||||
|
||||
# this should break out with an exception once the channel is closed |
||||
loop do |
||||
begin |
||||
state = ch.connectivity_state(true) |
||||
ch.watch_connectivity_state(state, Time.now + 360) |
||||
rescue RuntimeError => e |
||||
STDERR.puts "(expected) error occurred: #{e.inspect}" |
||||
break |
||||
end |
||||
end |
||||
|
||||
srv.stop |
||||
thd.join |
||||
end |
||||
|
||||
main |
@ -0,0 +1,67 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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. |
||||
|
||||
# make sure that the client doesn't hang when channel is closed |
||||
# explictly while it's used |
||||
|
||||
require_relative './end2end_common' |
||||
|
||||
def main |
||||
STDERR.puts 'start server' |
||||
server_runner = ServerRunner.new |
||||
server_port = server_runner.run |
||||
|
||||
sleep 1 |
||||
|
||||
STDERR.puts 'start client' |
||||
control_stub, client_pid = start_client('channel_closing_client.rb', |
||||
server_port) |
||||
|
||||
sleep 3 |
||||
|
||||
begin |
||||
Timeout.timeout(10) do |
||||
control_stub.shutdown(ClientControl::Void.new) |
||||
Process.wait(client_pid) |
||||
end |
||||
rescue Timeout::Error |
||||
STDERR.puts "timeout wait for client pid #{client_pid}" |
||||
Process.kill('SIGKILL', client_pid) |
||||
Process.wait(client_pid) |
||||
STDERR.puts 'killed client child' |
||||
raise 'Timed out waiting for client process. It likely hangs when a ' \ |
||||
'channel is closed while connectivity is watched' |
||||
end |
||||
|
||||
server_runner.stop |
||||
end |
||||
|
||||
main |
@ -0,0 +1,54 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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_relative './end2end_common' |
||||
|
||||
def main |
||||
server_port = '' |
||||
OptionParser.new do |opts| |
||||
opts.on('--client_control_port=P', String) do |
||||
STDERR.puts 'client_control_port ignored' |
||||
end |
||||
opts.on('--server_port=P', String) do |p| |
||||
server_port = p |
||||
end |
||||
end.parse! |
||||
|
||||
ch = GRPC::Core::Channel.new("localhost:#{server_port}", {}, |
||||
:this_channel_is_insecure) |
||||
|
||||
loop do |
||||
state = ch.connectivity_state |
||||
ch.watch_connectivity_state(state, Time.now + 360) |
||||
end |
||||
end |
||||
|
||||
main |
@ -0,0 +1,64 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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. |
||||
|
||||
# make sure that the client doesn't hang when process ended abruptly |
||||
|
||||
require_relative './end2end_common' |
||||
|
||||
def main |
||||
STDERR.puts 'start server' |
||||
server_runner = ServerRunner.new |
||||
server_port = server_runner.run |
||||
|
||||
sleep 1 |
||||
|
||||
STDERR.puts 'start client' |
||||
_, client_pid = start_client('channel_state_client.rb', server_port) |
||||
|
||||
sleep 3 |
||||
|
||||
Process.kill('SIGTERM', client_pid) |
||||
|
||||
begin |
||||
Timeout.timeout(10) { Process.wait(client_pid) } |
||||
rescue Timeout::Error |
||||
STDERR.puts "timeout wait for client pid #{client_pid}" |
||||
Process.kill('SIGKILL', client_pid) |
||||
Process.wait(client_pid) |
||||
STDERR.puts 'killed client child' |
||||
raise 'Timed out waiting for client process. ' \ |
||||
'It likely hangs when ended abruptly' |
||||
end |
||||
|
||||
server_runner.stop |
||||
end |
||||
|
||||
main |
@ -0,0 +1,109 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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. |
||||
|
||||
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||
protos_lib_dir = File.join(this_dir, 'lib') |
||||
grpc_lib_dir = File.join(File.dirname(this_dir), 'lib') |
||||
$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir) |
||||
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir) |
||||
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||
|
||||
require 'grpc' |
||||
require 'echo_services_pb' |
||||
require 'client_control_services_pb' |
||||
require 'socket' |
||||
require 'optparse' |
||||
require 'thread' |
||||
require 'timeout' |
||||
require 'English' # see https://github.com/bbatsov/rubocop/issues/1747 |
||||
|
||||
# GreeterServer is simple server that implements the Helloworld Greeter server. |
||||
class EchoServerImpl < Echo::EchoServer::Service |
||||
# say_hello implements the SayHello rpc method. |
||||
def echo(echo_req, _) |
||||
Echo::EchoReply.new(response: echo_req.request) |
||||
end |
||||
end |
||||
|
||||
# ServerRunner starts an "echo server" that test clients can make calls to |
||||
class ServerRunner |
||||
def initialize |
||||
end |
||||
|
||||
def run |
||||
@srv = GRPC::RpcServer.new |
||||
port = @srv.add_http2_port('0.0.0.0:0', :this_port_is_insecure) |
||||
@srv.handle(EchoServerImpl) |
||||
|
||||
@thd = Thread.new do |
||||
@srv.run |
||||
end |
||||
@srv.wait_till_running |
||||
port |
||||
end |
||||
|
||||
def stop |
||||
@srv.stop |
||||
@thd.join |
||||
fail 'server not stopped' unless @srv.stopped? |
||||
end |
||||
end |
||||
|
||||
def start_client(client_main, server_port) |
||||
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||
|
||||
tmp_server = TCPServer.new(0) |
||||
client_control_port = tmp_server.local_address.ip_port |
||||
tmp_server.close |
||||
|
||||
client_path = File.join(this_dir, client_main) |
||||
client_pid = Process.spawn(RbConfig.ruby, |
||||
client_path, |
||||
"--client_control_port=#{client_control_port}", |
||||
"--server_port=#{server_port}") |
||||
sleep 1 |
||||
control_stub = ClientControl::ClientController::Stub.new( |
||||
"localhost:#{client_control_port}", :this_channel_is_insecure) |
||||
[control_stub, client_pid] |
||||
end |
||||
|
||||
def cleanup(control_stub, client_pid, server_runner) |
||||
control_stub.shutdown(ClientControl::Void.new) |
||||
Process.wait(client_pid) |
||||
|
||||
client_exit_code = $CHILD_STATUS |
||||
|
||||
if client_exit_code != 0 |
||||
fail "term sig test failure: client exit code: #{client_exit_code}" |
||||
end |
||||
|
||||
server_runner.stop |
||||
end |
@ -0,0 +1,32 @@ |
||||
#!/bin/bash |
||||
|
||||
# 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. |
||||
|
||||
grpc_tools_ruby_protoc -I protos --ruby_out=lib --grpc_out=lib protos/echo.proto protos/client_control.proto |
@ -0,0 +1,17 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# source: client_control.proto |
||||
|
||||
require 'google/protobuf' |
||||
|
||||
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||
add_message "client_control.DoEchoRpcRequest" do |
||||
optional :request, :string, 1 |
||||
end |
||||
add_message "client_control.Void" do |
||||
end |
||||
end |
||||
|
||||
module ClientControl |
||||
DoEchoRpcRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("client_control.DoEchoRpcRequest").msgclass |
||||
Void = Google::Protobuf::DescriptorPool.generated_pool.lookup("client_control.Void").msgclass |
||||
end |
@ -0,0 +1,53 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# Source: client_control.proto for package 'client_control' |
||||
# Original file comments: |
||||
# 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' |
||||
require 'client_control_pb' |
||||
|
||||
module ClientControl |
||||
module ClientController |
||||
class Service |
||||
|
||||
include GRPC::GenericService |
||||
|
||||
self.marshal_class_method = :encode |
||||
self.unmarshal_class_method = :decode |
||||
self.service_name = 'client_control.ClientController' |
||||
|
||||
rpc :DoEchoRpc, DoEchoRpcRequest, Void |
||||
rpc :Shutdown, Void, Void |
||||
end |
||||
|
||||
Stub = Service.rpc_stub_class |
||||
end |
||||
end |
@ -0,0 +1,18 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# source: echo.proto |
||||
|
||||
require 'google/protobuf' |
||||
|
||||
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||
add_message "echo.EchoRequest" do |
||||
optional :request, :string, 1 |
||||
end |
||||
add_message "echo.EchoReply" do |
||||
optional :response, :string, 1 |
||||
end |
||||
end |
||||
|
||||
module Echo |
||||
EchoRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("echo.EchoRequest").msgclass |
||||
EchoReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("echo.EchoReply").msgclass |
||||
end |
@ -0,0 +1,52 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# Source: echo.proto for package 'echo' |
||||
# Original file comments: |
||||
# 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' |
||||
require 'echo_pb' |
||||
|
||||
module Echo |
||||
module EchoServer |
||||
class Service |
||||
|
||||
include GRPC::GenericService |
||||
|
||||
self.marshal_class_method = :encode |
||||
self.unmarshal_class_method = :decode |
||||
self.service_name = 'echo.EchoServer' |
||||
|
||||
rpc :Echo, EchoRequest, EchoReply |
||||
end |
||||
|
||||
Stub = Service.rpc_stub_class |
||||
end |
||||
end |
@ -0,0 +1,43 @@ |
||||
// 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. |
||||
|
||||
syntax = "proto3"; |
||||
|
||||
package client_control; |
||||
|
||||
service ClientController { |
||||
rpc DoEchoRpc (DoEchoRpcRequest) returns (Void) {} |
||||
rpc Shutdown(Void) returns (Void) {} |
||||
} |
||||
|
||||
message DoEchoRpcRequest { |
||||
string request = 1; |
||||
} |
||||
|
||||
message Void{} |
@ -0,0 +1,46 @@ |
||||
// 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. |
||||
|
||||
syntax = "proto3"; |
||||
|
||||
package echo; |
||||
|
||||
service EchoServer { |
||||
rpc Echo (EchoRequest) returns (EchoReply) {} |
||||
} |
||||
|
||||
// The request message containing the user's name. |
||||
message EchoRequest { |
||||
string request = 1; |
||||
} |
||||
|
||||
// The response message containing the greetings |
||||
message EchoReply { |
||||
string response = 1; |
||||
} |
@ -0,0 +1,89 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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_relative './end2end_common' |
||||
|
||||
# Test client. Sends RPC's as normal but process also has signal handlers |
||||
class SigHandlingClientController < ClientControl::ClientController::Service |
||||
def initialize(srv, stub) |
||||
@srv = srv |
||||
@stub = stub |
||||
end |
||||
|
||||
def do_echo_rpc(req, _) |
||||
response = @stub.echo(Echo::EchoRequest.new(request: req.request)) |
||||
fail 'bad response' unless response.response == req.request |
||||
ClientControl::Void.new |
||||
end |
||||
|
||||
def shutdown(_, _) |
||||
Thread.new do |
||||
# TODO(apolcyn) There is a race between stopping the |
||||
# server and the "shutdown" rpc completing, |
||||
# See if stop method on server can end active RPC cleanly, to |
||||
# avoid this sleep. |
||||
sleep 3 |
||||
@srv.stop |
||||
end |
||||
ClientControl::Void.new |
||||
end |
||||
end |
||||
|
||||
def main |
||||
client_control_port = '' |
||||
server_port = '' |
||||
OptionParser.new do |opts| |
||||
opts.on('--client_control_port=P', String) do |p| |
||||
client_control_port = p |
||||
end |
||||
opts.on('--server_port=P', String) do |p| |
||||
server_port = p |
||||
end |
||||
end.parse! |
||||
|
||||
Signal.trap('TERM') do |
||||
STDERR.puts 'SIGTERM received' |
||||
end |
||||
|
||||
Signal.trap('INT') do |
||||
STDERR.puts 'SIGINT received' |
||||
end |
||||
|
||||
srv = GRPC::RpcServer.new |
||||
srv.add_http2_port("0.0.0.0:#{client_control_port}", |
||||
:this_port_is_insecure) |
||||
stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", |
||||
:this_channel_is_insecure) |
||||
srv.handle(SigHandlingClientController.new(srv, stub)) |
||||
srv.run |
||||
end |
||||
|
||||
main |
@ -0,0 +1,61 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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. |
||||
|
||||
# smoke test for a grpc-using app that receives and |
||||
# handles process-ending signals |
||||
|
||||
require_relative './end2end_common' |
||||
|
||||
def main |
||||
STDERR.puts 'start server' |
||||
server_runner = ServerRunner.new |
||||
server_port = server_runner.run |
||||
|
||||
sleep 1 |
||||
|
||||
STDERR.puts 'start client' |
||||
control_stub, client_pid = start_client('sig_handling_client.rb', server_port) |
||||
|
||||
sleep 1 |
||||
|
||||
count = 0 |
||||
while count < 5 |
||||
control_stub.do_echo_rpc( |
||||
ClientControl::DoEchoRpcRequest.new(request: 'hello')) |
||||
Process.kill('SIGTERM', client_pid) |
||||
Process.kill('SIGINT', client_pid) |
||||
count += 1 |
||||
end |
||||
|
||||
cleanup(control_stub, client_pid, server_runner) |
||||
end |
||||
|
||||
main |
@ -0,0 +1,70 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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_relative './end2end_common' |
||||
|
||||
# Start polling the channel state in both the main thread |
||||
# and a child thread. Try to get the driver to send process-ending |
||||
# interrupt while both a child thread and the main thread are in the |
||||
# middle of a blocking connectivity_state call. |
||||
def main |
||||
server_port = '' |
||||
OptionParser.new do |opts| |
||||
opts.on('--client_control_port=P', String) do |
||||
STDERR.puts 'client_control_port not used' |
||||
end |
||||
opts.on('--server_port=P', String) do |p| |
||||
server_port = p |
||||
end |
||||
end.parse! |
||||
|
||||
thd = Thread.new do |
||||
child_thread_channel = GRPC::Core::Channel.new("localhost:#{server_port}", |
||||
{}, |
||||
:this_channel_is_insecure) |
||||
loop do |
||||
state = child_thread_channel.connectivity_state(false) |
||||
child_thread_channel.watch_connectivity_state(state, Time.now + 360) |
||||
end |
||||
end |
||||
|
||||
main_channel = GRPC::Core::Channel.new("localhost:#{server_port}", |
||||
{}, |
||||
:this_channel_is_insecure) |
||||
loop do |
||||
state = main_channel.connectivity_state(false) |
||||
main_channel.watch_connectivity_state(state, Time.now + 360) |
||||
end |
||||
|
||||
thd.join |
||||
end |
||||
|
||||
main |
@ -0,0 +1,69 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# 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. |
||||
|
||||
# abruptly end a process that has active calls to |
||||
# Channel.watch_connectivity_state |
||||
|
||||
require_relative './end2end_common' |
||||
|
||||
def main |
||||
STDERR.puts 'start server' |
||||
server_runner = ServerRunner.new |
||||
server_port = server_runner.run |
||||
|
||||
sleep 1 |
||||
|
||||
STDERR.puts 'start client' |
||||
_, client_pid = start_client('sig_int_during_channel_watch_client.rb', |
||||
server_port) |
||||
|
||||
# give time for the client to get into the middle |
||||
# of a channel state watch call |
||||
sleep 1 |
||||
Process.kill('SIGINT', client_pid) |
||||
|
||||
begin |
||||
Timeout.timeout(10) do |
||||
Process.wait(client_pid) |
||||
end |
||||
rescue Timeout::Error |
||||
STDERR.puts "timeout wait for client pid #{client_pid}" |
||||
Process.kill('SIGKILL', client_pid) |
||||
Process.wait(client_pid) |
||||
STDERR.puts 'killed client child' |
||||
raise 'Timed out waiting for client process. It likely hangs when a ' \ |
||||
'SIGINT is sent while there is an active connectivity_state call' |
||||
end |
||||
|
||||
server_runner.stop |
||||
end |
||||
|
||||
main |
@ -0,0 +1,141 @@ |
||||
# 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' |
||||
|
||||
# A test message |
||||
class EchoMsg |
||||
def self.marshal(_o) |
||||
'' |
||||
end |
||||
|
||||
def self.unmarshal(_o) |
||||
EchoMsg.new |
||||
end |
||||
end |
||||
|
||||
# A test service with an echo implementation. |
||||
class EchoService |
||||
include GRPC::GenericService |
||||
rpc :an_rpc, EchoMsg, EchoMsg |
||||
attr_reader :received_md |
||||
|
||||
def initialize(**kw) |
||||
@trailing_metadata = kw |
||||
@received_md = [] |
||||
end |
||||
|
||||
def an_rpc(req, call) |
||||
GRPC.logger.info('echo service received a request') |
||||
call.output_metadata.update(@trailing_metadata) |
||||
@received_md << call.metadata unless call.metadata.nil? |
||||
req |
||||
end |
||||
end |
||||
|
||||
EchoStub = EchoService.rpc_stub_class |
||||
|
||||
def start_server(port = 0) |
||||
@srv = GRPC::RpcServer.new |
||||
server_port = @srv.add_http2_port("localhost:#{port}", :this_port_is_insecure) |
||||
@srv.handle(EchoService) |
||||
@server_thd = Thread.new { @srv.run } |
||||
@srv.wait_till_running |
||||
server_port |
||||
end |
||||
|
||||
def stop_server |
||||
expect(@srv.stopped?).to be(false) |
||||
@srv.stop |
||||
@server_thd.join |
||||
expect(@srv.stopped?).to be(true) |
||||
end |
||||
|
||||
describe 'channel connection behavior' do |
||||
it 'the client channel handles temporary loss of a transport' do |
||||
port = start_server |
||||
stub = EchoStub.new("localhost:#{port}", :this_channel_is_insecure) |
||||
req = EchoMsg.new |
||||
expect(stub.an_rpc(req)).to be_a(EchoMsg) |
||||
stop_server |
||||
sleep 1 |
||||
# TODO(apolcyn) grabbing the same port might fail, is this stable enough? |
||||
start_server(port) |
||||
expect(stub.an_rpc(req)).to be_a(EchoMsg) |
||||
stop_server |
||||
end |
||||
|
||||
it 'observably connects and reconnects to transient server' \ |
||||
' when using the channel state API' do |
||||
port = start_server |
||||
ch = GRPC::Core::Channel.new("localhost:#{port}", {}, |
||||
:this_channel_is_insecure) |
||||
|
||||
expect(ch.connectivity_state).to be(GRPC::Core::ConnectivityStates::IDLE) |
||||
|
||||
state = ch.connectivity_state(true) |
||||
|
||||
count = 0 |
||||
while count < 20 && state != GRPC::Core::ConnectivityStates::READY |
||||
ch.watch_connectivity_state(state, Time.now + 60) |
||||
state = ch.connectivity_state(true) |
||||
count += 1 |
||||
end |
||||
|
||||
expect(state).to be(GRPC::Core::ConnectivityStates::READY) |
||||
|
||||
stop_server |
||||
|
||||
state = ch.connectivity_state |
||||
|
||||
count = 0 |
||||
while count < 20 && state == GRPC::Core::ConnectivityStates::READY |
||||
ch.watch_connectivity_state(state, Time.now + 60) |
||||
state = ch.connectivity_state |
||||
count += 1 |
||||
end |
||||
|
||||
expect(state).to_not be(GRPC::Core::ConnectivityStates::READY) |
||||
|
||||
start_server(port) |
||||
|
||||
state = ch.connectivity_state(true) |
||||
|
||||
count = 0 |
||||
while count < 20 && state != GRPC::Core::ConnectivityStates::READY |
||||
ch.watch_connectivity_state(state, Time.now + 60) |
||||
state = ch.connectivity_state(true) |
||||
count += 1 |
||||
end |
||||
|
||||
expect(state).to be(GRPC::Core::ConnectivityStates::READY) |
||||
|
||||
stop_server |
||||
end |
||||
end |
@ -0,0 +1,41 @@ |
||||
#!/bin/bash |
||||
# 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. |
||||
|
||||
set -ex |
||||
|
||||
# change to grpc repo root |
||||
cd $(dirname $0)/../../.. |
||||
|
||||
EXIT_CODE=0 |
||||
ruby src/ruby/end2end/sig_handling_driver.rb || EXIT_CODE=1 |
||||
ruby src/ruby/end2end/channel_state_driver.rb || EXIT_CODE=1 |
||||
ruby src/ruby/end2end/channel_closing_driver.rb || EXIT_CODE=1 |
||||
ruby src/ruby/end2end/sig_int_during_channel_watch_driver.rb || EXIT_CODE=1 |
||||
exit $EXIT_CODE |
Loading…
Reference in new issue