From 16d97edf56b036c28dbe60d1184ef89b71bf8a90 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 15 Mar 2017 10:01:13 -0700
Subject: [PATCH] add failing test revealing bug in channel state api

---
 src/ruby/end2end/channel_state_client.rb      | 53 ++++++++++++++++
 src/ruby/end2end/channel_state_driver.rb      | 63 +++++++++++++++++++
 src/ruby/end2end/end2end_common.rb            |  3 +-
 src/ruby/end2end/sig_handling_driver.rb       |  2 +-
 .../helper_scripts/run_ruby_end2end_tests.sh  |  5 +-
 5 files changed, 123 insertions(+), 3 deletions(-)
 create mode 100755 src/ruby/end2end/channel_state_client.rb
 create mode 100755 src/ruby/end2end/channel_state_driver.rb

diff --git a/src/ruby/end2end/channel_state_client.rb b/src/ruby/end2end/channel_state_client.rb
new file mode 100755
index 0000000000..476329ff73
--- /dev/null
+++ b/src/ruby/end2end/channel_state_client.rb
@@ -0,0 +1,53 @@
+#!/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 |p|
+      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
diff --git a/src/ruby/end2end/channel_state_driver.rb b/src/ruby/end2end/channel_state_driver.rb
new file mode 100755
index 0000000000..cab0147e1f
--- /dev/null
+++ b/src/ruby/end2end/channel_state_driver.rb
@@ -0,0 +1,63 @@
+#!/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"
+  _, 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)
+    raise 'Timed out waiting for client process. It likely hangs'
+  end
+
+  server_runner.stop
+end
+
+main
diff --git a/src/ruby/end2end/end2end_common.rb b/src/ruby/end2end/end2end_common.rb
index 67961cdf97..d98e41f642 100755
--- a/src/ruby/end2end/end2end_common.rb
+++ b/src/ruby/end2end/end2end_common.rb
@@ -42,6 +42,7 @@ require 'client_control_services_pb'
 require 'socket'
 require 'optparse'
 require 'thread'
+require 'timeout'
 
 # GreeterServer is simple server that implements the Helloworld Greeter server.
 class EchoServerImpl < Echo::EchoServer::Service
@@ -88,7 +89,7 @@ def start_client(client_main, server_port)
   return control_stub, client_pid
 end
 
-def cleanup(control_stub, server_runner)
+def cleanup(control_stub, client_pid, server_runner)
   control_stub.shutdown(ClientControl::Void.new)
   Process.wait(client_pid)
 
diff --git a/src/ruby/end2end/sig_handling_driver.rb b/src/ruby/end2end/sig_handling_driver.rb
index bda5c03c16..4d205da9ae 100755
--- a/src/ruby/end2end/sig_handling_driver.rb
+++ b/src/ruby/end2end/sig_handling_driver.rb
@@ -54,7 +54,7 @@ def main
     count += 1
   end
 
-  cleanup(control_stub, server_runner)
+  cleanup(control_stub, client_pid, server_runner)
 end
 
 main
diff --git a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
index 7ccbcfca70..518848b950 100755
--- a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
+++ b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
@@ -33,4 +33,7 @@ set -ex
 # change to grpc repo root
 cd $(dirname $0)/../../..
 
-ruby src/ruby/end2end/sig_handling_driver.rb
+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
+exit $EXIT_CODE
-- 
GitLab