From b6e444088009ade16d9af4ab497f484d63d65b86 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 28 Apr 2016 08:21:52 -0700 Subject: Disable fail fast for qps driver --- test/cpp/qps/driver.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 2583ceb819..04b2b453f9 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -83,6 +83,7 @@ static std::unordered_map> get_hosts_and_cores( auto stub = WorkerService::NewStub( CreateChannel(*it, InsecureChannelCredentials())); grpc::ClientContext ctx; + ctx.set_fail_fast(false); CoreRequest dummy; CoreResponse cores; grpc::Status s = stub->CoreCount(&ctx, dummy, &cores); @@ -166,6 +167,7 @@ namespace runsc { static ClientContext* AllocContext(list* contexts) { contexts->emplace_back(); auto context = &contexts->back(); + context->set_fail_fast(false); return context; } @@ -435,6 +437,7 @@ void RunQuit() { CreateChannel(workers[i], InsecureChannelCredentials())); Void dummy; grpc::ClientContext ctx; + ctx.set_fail_fast(false); GPR_ASSERT(stub->QuitWorker(&ctx, dummy, &dummy).ok()); } } -- cgit v1.2.3 From ad9d06effe37bf9c99a8b2aad8f52657b30e7abf Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 28 Apr 2016 22:15:04 -0700 Subject: Create Python stress test --- src/python/grpcio/tests/stress/__init__.py | 28 +++++ src/python/grpcio/tests/stress/client.py | 132 +++++++++++++++++++++++ src/python/grpcio/tests/stress/metrics_server.py | 60 +++++++++++ src/python/grpcio/tests/stress/test_runner.py | 73 +++++++++++++ 4 files changed, 293 insertions(+) create mode 100644 src/python/grpcio/tests/stress/__init__.py create mode 100644 src/python/grpcio/tests/stress/client.py create mode 100644 src/python/grpcio/tests/stress/metrics_server.py create mode 100644 src/python/grpcio/tests/stress/test_runner.py diff --git a/src/python/grpcio/tests/stress/__init__.py b/src/python/grpcio/tests/stress/__init__.py new file mode 100644 index 0000000000..100a624dc9 --- /dev/null +++ b/src/python/grpcio/tests/stress/__init__.py @@ -0,0 +1,28 @@ +# 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. diff --git a/src/python/grpcio/tests/stress/client.py b/src/python/grpcio/tests/stress/client.py new file mode 100644 index 0000000000..a733741b73 --- /dev/null +++ b/src/python/grpcio/tests/stress/client.py @@ -0,0 +1,132 @@ +# 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. + +"""Entry point for running stress tests.""" + +import argparse +import Queue +import threading + +from grpc.beta import implementations +from src.proto.grpc.testing import metrics_pb2 +from src.proto.grpc.testing import test_pb2 + +from tests.interop import methods +from tests.qps import histogram +from tests.stress import metrics_server +from tests.stress import test_runner + + +def _args(): + parser = argparse.ArgumentParser(description='gRPC Python stress test client') + parser.add_argument( + '--server_addresses', + help='comma seperated list of hostname:port to run servers on', + default='localhost:8080', type=str) + parser.add_argument( + '--test_cases', + help='comma seperated list of testcase:weighting of tests to run', + default='large_unary:100', + type=str) + parser.add_argument( + '--test_duration_secs', + help='number of seconds to run the stress test', + default=-1, type=int) + parser.add_argument( + '--num_channels_per_server', + help='number of channels per server', + default=1, type=int) + parser.add_argument( + '--num_stubs_per_channel', + help='number of stubs to create per channel', + default=1, type=int) + parser.add_argument( + '--metrics_port', + help='the port to listen for metrics requests on', + default=8081, type=int) + return parser.parse_args() + + +def _test_case_from_arg(test_case_arg): + for test_case in methods.TestCase: + if test_case_arg == test_case.value: + return test_case + else: + raise ValueError('No test case {}!'.format(test_case_arg)) + + +def _parse_weighted_test_cases(test_case_args): + weighted_test_cases = {} + for test_case_arg in test_case_args.split(','): + name, weight = test_case_arg.split(':', 1) + test_case = _test_case_from_arg(name) + weighted_test_cases[test_case] = int(weight) + return weighted_test_cases + + +def run_test(args): + test_cases = _parse_weighted_test_cases(args.test_cases) + test_servers = args.server_addresses.split(',') + # Propagate any client exceptions with a queue + exception_queue = Queue.Queue() + stop_event = threading.Event() + hist = histogram.Histogram(1, 1) + runners = [] + + server = metrics_pb2.beta_create_MetricsService_server( + metrics_server.MetricsServer(hist)) + server.add_insecure_port('[::]:{}'.format(args.metrics_port)) + server.start() + + for test_server in test_servers: + host, port = test_server.split(':', 1) + for _ in xrange(args.num_channels_per_server): + channel = implementations.insecure_channel(host, int(port)) + for _ in xrange(args.num_stubs_per_channel): + stub = test_pb2.beta_create_TestService_stub(channel) + runner = test_runner.TestRunner(stub, test_cases, hist, + exception_queue, stop_event) + runners.append(runner) + + for runner in runners: + runner.start() + try: + raise exception_queue.get(block=True, timeout=args.test_duration_secs) + except Queue.Empty: + # No exceptions thrown, success + pass + finally: + stop_event.set() + for runner in runners: + runner.join() + runner = None + server.stop(0) + +if __name__ == '__main__': + run_test(_args()) diff --git a/src/python/grpcio/tests/stress/metrics_server.py b/src/python/grpcio/tests/stress/metrics_server.py new file mode 100644 index 0000000000..b994e4643e --- /dev/null +++ b/src/python/grpcio/tests/stress/metrics_server.py @@ -0,0 +1,60 @@ +# 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. + +"""MetricsService for publishing stress test qps data.""" + +import time + +from src.proto.grpc.testing import metrics_pb2 + +GAUGE_NAME = 'python_overall_qps' + + +class MetricsServer(metrics_pb2.BetaMetricsServiceServicer): + + def __init__(self, histogram): + self._start_time = time.time() + self._histogram = histogram + + def _get_qps(self): + count = self._histogram.get_data().count + delta = time.time() - self._start_time + self._histogram.reset() + self._start_time = time.time() + return int(count/delta) + + def GetAllGauges(self, request, context): + qps = self._get_qps() + return [metrics_pb2.GaugeResponse(name=GAUGE_NAME, long_value=qps)] + + def GetGauge(self, request, context): + if request.name != GAUGE_NAME: + raise Exception('Gauge {} does not exist'.format(request.name)) + qps = self._get_qps() + return metrics_pb2.GaugeResponse(name=GAUGE_NAME, long_value=qps) diff --git a/src/python/grpcio/tests/stress/test_runner.py b/src/python/grpcio/tests/stress/test_runner.py new file mode 100644 index 0000000000..88f13727e3 --- /dev/null +++ b/src/python/grpcio/tests/stress/test_runner.py @@ -0,0 +1,73 @@ +# 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. + +"""Thread that sends random weighted requests on a TestService stub.""" + +import random +import threading +import time +import traceback + + +def _weighted_test_case_generator(weighted_cases): + weight_sum = sum(weighted_cases.itervalues()) + + while True: + val = random.uniform(0, weight_sum) + partial_sum = 0 + for case in weighted_cases: + partial_sum += weighted_cases[case] + if val <= partial_sum: + yield case + break + + +class TestRunner(threading.Thread): + + def __init__(self, stub, test_cases, hist, exception_queue, stop_event): + super(TestRunner, self).__init__() + self._exception_queue = exception_queue + self._stop_event = stop_event + self._stub = stub + self._test_cases = _weighted_test_case_generator(test_cases) + self._histogram = hist + + def run(self): + while not self._stop_event.is_set(): + try: + test_case = next(self._test_cases) + start_time = time.time() + test_case.test_interoperability(self._stub, None) + end_time = time.time() + self._histogram.add((end_time - start_time)*1e9) + except Exception as e: + traceback.print_exc() + self._exception_queue.put( + Exception("An exception occured during test {}" + .format(test_case), e)) -- cgit v1.2.3 From 3b293253d41627e3816167ef8ec3cf9bd0dcc48f Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Apr 2016 11:36:57 -0700 Subject: Created grpc-tools ruby gem for distributing protoc and the plugin --- src/ruby/tools/README.md | 12 +++++++ src/ruby/tools/bin/protoc.rb | 46 +++++++++++++++++++++++++++ src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb | 46 +++++++++++++++++++++++++++ src/ruby/tools/grpc-tools.gemspec | 20 ++++++++++++ src/ruby/tools/os_check.rb | 45 ++++++++++++++++++++++++++ src/ruby/tools/version.rb | 34 ++++++++++++++++++++ templates/src/ruby/tools/version.rb.template | 36 +++++++++++++++++++++ 7 files changed, 239 insertions(+) create mode 100644 src/ruby/tools/README.md create mode 100755 src/ruby/tools/bin/protoc.rb create mode 100644 src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb create mode 100644 src/ruby/tools/grpc-tools.gemspec create mode 100644 src/ruby/tools/os_check.rb create mode 100644 src/ruby/tools/version.rb create mode 100644 templates/src/ruby/tools/version.rb.template diff --git a/src/ruby/tools/README.md b/src/ruby/tools/README.md new file mode 100644 index 0000000000..e43f223c89 --- /dev/null +++ b/src/ruby/tools/README.md @@ -0,0 +1,12 @@ +# Ruby gRPC Tools + +This package distributes protoc and the Ruby gRPC protoc plugin for Windows, Linux, and Mac. + +Before this package is published, the following directories should be filled with the corresponding `protoc` and `grpc_ruby_plugin` executables. + + - `bin/x86-linux` + - `bin/x86_64-linux` + - `bin/x86-macos` + - `bin/x86_64-macos` + - `bin/x86-windows` + - `bin/x86_64-windows` diff --git a/src/ruby/tools/bin/protoc.rb b/src/ruby/tools/bin/protoc.rb new file mode 100755 index 0000000000..68cbc852fd --- /dev/null +++ b/src/ruby/tools/bin/protoc.rb @@ -0,0 +1,46 @@ +#!/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. + +require 'rbconfig' + +require_relative '../os_check' + +protoc_name = case OS.os_name + when 'windows' + 'protoc.exe' + else + 'protoc' + end + +protoc_path = File.join(File.dirname(__FILE__), + RbConfig::CONFIG['host_cpu'] + '-' + OS.os_name, + protoc_name) + +exec([ protoc_path, protoc_path ], *ARGV) diff --git a/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb b/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb new file mode 100644 index 0000000000..04cf435b58 --- /dev/null +++ b/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb @@ -0,0 +1,46 @@ +#!/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. + +require 'rbconfig' + +require_relative '../os_check' + +plugin_name = 'grpc_ruby_plugin' + case OS.os_name + when 'windows' + '.exe' + else + '' + end + +plugin_path = File.join(File.dirname(__FILE__), + RbConfig::CONFIG['host_cpu'] + '-' + OS.os_name, + plugin_name) + +exec([ plugin_path, plugin_path ], *ARGV) diff --git a/src/ruby/tools/grpc-tools.gemspec b/src/ruby/tools/grpc-tools.gemspec new file mode 100644 index 0000000000..f56f2f58ce --- /dev/null +++ b/src/ruby/tools/grpc-tools.gemspec @@ -0,0 +1,20 @@ +# -*- ruby -*- +# encoding: utf-8 +require_relative 'version.rb' +Gem::Specification.new do |s| + s.name = 'grpc-tools' + s.version = GRPC::Tools::VERSION + s.homepage = 'https://github.com/google/grpc/tree/master/src/ruby/tools' + s.summary = 'Development tools for Ruby gRPC' + s.description = 'protoc and the Ruby gRPC protoc plugin' + s.license = 'BSD-3-Clause' + + s.files = %w( version.rb os_check.rb README.md ) + s.files += Dir.glob('bin/**/*') + + s.bindir = 'bin' + + s.platform = Gem::Platform::RUBY + + s.executables = %w( protoc.rb protoc_grpc_ruby_plugin.rb ) +end diff --git a/src/ruby/tools/os_check.rb b/src/ruby/tools/os_check.rb new file mode 100644 index 0000000000..2677306457 --- /dev/null +++ b/src/ruby/tools/os_check.rb @@ -0,0 +1,45 @@ +# 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. + +# This is based on http://stackoverflow.com/a/171011/159388 by Aaron Hinni + +require 'rbconfig' + +module OS + def OS.os_name + case RbConfig::CONFIG['host_os'] + when /cygwin|mswin|mingw|bccwin|wince|emx/ + 'windows' + when /darwin/ + 'macos' + else + 'linux' + end + end +end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb new file mode 100644 index 0000000000..12ad21b80e --- /dev/null +++ b/src/ruby/tools/version.rb @@ -0,0 +1,34 @@ +# 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. + +module GRPC + module Tools + VERSION = '0.14.0.dev' + end +end diff --git a/templates/src/ruby/tools/version.rb.template b/templates/src/ruby/tools/version.rb.template new file mode 100644 index 0000000000..dbc5f48cf5 --- /dev/null +++ b/templates/src/ruby/tools/version.rb.template @@ -0,0 +1,36 @@ +%YAML 1.2 +--- | + # 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. + + module GRPC + module Tools + VERSION = '${settings.ruby_version.ruby()}' + end + end -- cgit v1.2.3 From f238194b25549cd97d19f8c785347e2d2f3d3c89 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Apr 2016 11:37:21 -0700 Subject: Updated build_package_ruby to build the grpc-tools gem --- tools/run_tests/build_package_ruby.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/run_tests/build_package_ruby.sh b/tools/run_tests/build_package_ruby.sh index 1a5b94348d..cde05181c7 100755 --- a/tools/run_tests/build_package_ruby.sh +++ b/tools/run_tests/build_package_ruby.sh @@ -32,6 +32,8 @@ set -ex cd $(dirname $0)/../.. +base=$(pwd) + mkdir -p artifacts/ # All the ruby packages have been built in the artifact phase already @@ -41,3 +43,25 @@ cp -r $EXTERNAL_GIT_ROOT/architecture={x86,x64},language=ruby,platform={windows, # TODO: all the artifact builder configurations generate a grpc-VERSION.gem # source distribution package, and only one of them will end up # in the artifacts/ directory. They should be all equivalent though. + +for arch in {x86,x64}; do + case arch in + x64) + ruby_arch=x86_64 + ;; + *) + ruby_arch=$arch + ;; + esac + for plat in {windows,linux,macos}; do + input_dir="$EXTERNAL_GIT_ROOT/architecture=$arch,language=protoc,platform=$plat/artifacts" + output_dir="$base/src/ruby/tools/bin/${ruby_arch}-${plat}" + mkdir -p output_dir + cp $input_dir/protoc* output_dir/ + cp $input_dir/grpc_ruby_plugin* output_dir/ + done +done + +cd $base/src/ruby/tools +gem build grpc-tools.gemspec +cp ./grpc-tools*.gem $base/artifacts/ -- cgit v1.2.3 From faf3bfca82c88b1bf08995fdfb26a152c90bf0a5 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Apr 2016 12:39:05 -0700 Subject: Fixed grpc-tools.gemspec --- src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb | 0 src/ruby/tools/grpc-tools.gemspec | 2 ++ 2 files changed, 2 insertions(+) mode change 100644 => 100755 src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb diff --git a/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb b/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb old mode 100644 new mode 100755 diff --git a/src/ruby/tools/grpc-tools.gemspec b/src/ruby/tools/grpc-tools.gemspec index f56f2f58ce..af904de4a9 100644 --- a/src/ruby/tools/grpc-tools.gemspec +++ b/src/ruby/tools/grpc-tools.gemspec @@ -4,6 +4,8 @@ require_relative 'version.rb' Gem::Specification.new do |s| s.name = 'grpc-tools' s.version = GRPC::Tools::VERSION + s.authors = ['grpc Authors'] + s.email = 'grpc-io@googlegroups.com' s.homepage = 'https://github.com/google/grpc/tree/master/src/ruby/tools' s.summary = 'Development tools for Ruby gRPC' s.description = 'protoc and the Ruby gRPC protoc plugin' -- cgit v1.2.3 From f897fec0dbd8814b3717b88058cdcaf6965a2d50 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Apr 2016 12:43:19 -0700 Subject: Fixed build_package_ruby's use of variables --- tools/run_tests/build_package_ruby.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/build_package_ruby.sh b/tools/run_tests/build_package_ruby.sh index cde05181c7..5725a19e62 100755 --- a/tools/run_tests/build_package_ruby.sh +++ b/tools/run_tests/build_package_ruby.sh @@ -56,9 +56,9 @@ for arch in {x86,x64}; do for plat in {windows,linux,macos}; do input_dir="$EXTERNAL_GIT_ROOT/architecture=$arch,language=protoc,platform=$plat/artifacts" output_dir="$base/src/ruby/tools/bin/${ruby_arch}-${plat}" - mkdir -p output_dir - cp $input_dir/protoc* output_dir/ - cp $input_dir/grpc_ruby_plugin* output_dir/ + mkdir -p $output_dir + cp $input_dir/protoc* $output_dir/ + cp $input_dir/grpc_ruby_plugin* $output_dir/ done done -- cgit v1.2.3 From 8cb5f2f413853829f75bc256ee93fec812d357a1 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Apr 2016 12:55:28 -0700 Subject: Fixed build_package_ruby's use of variables --- tools/run_tests/build_package_ruby.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/build_package_ruby.sh b/tools/run_tests/build_package_ruby.sh index 5725a19e62..e44428bf7e 100755 --- a/tools/run_tests/build_package_ruby.sh +++ b/tools/run_tests/build_package_ruby.sh @@ -45,7 +45,7 @@ cp -r $EXTERNAL_GIT_ROOT/architecture={x86,x64},language=ruby,platform={windows, # in the artifacts/ directory. They should be all equivalent though. for arch in {x86,x64}; do - case arch in + case $arch in x64) ruby_arch=x86_64 ;; -- cgit v1.2.3 From c7edb0ee1022bd31104e2fff4d5d4fb1ef776a20 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Apr 2016 15:33:31 -0700 Subject: Reverted 'Rewrite Node greeter example to use generated code' --- examples/node/greeter_client.js | 22 +-- examples/node/greeter_server.js | 12 +- examples/node/helloworld_grpc_pb.js | 39 ----- examples/node/helloworld_pb.js | 332 ------------------------------------ examples/node/package.json | 1 - 5 files changed, 12 insertions(+), 394 deletions(-) delete mode 100644 examples/node/helloworld_grpc_pb.js delete mode 100644 examples/node/helloworld_pb.js diff --git a/examples/node/greeter_client.js b/examples/node/greeter_client.js index 7125c2fec5..2820acbbb7 100644 --- a/examples/node/greeter_client.js +++ b/examples/node/greeter_client.js @@ -31,30 +31,22 @@ * */ -var grpc = require('grpc'); +var PROTO_PATH = __dirname + '/../protos/helloworld.proto'; -var hello_messages = require('./helloworld_pb'); -var hello_service = require('./helloworld_grpc_pb'); +var grpc = require('grpc'); +var hello_proto = grpc.load(PROTO_PATH).helloworld; function main() { - var client = new hello_service.GreeterClient('localhost:50051', - grpc.credentials.createInsecure()); + var client = new hello_proto.Greeter('localhost:50051', + grpc.credentials.createInsecure()); var user; if (process.argv.length >= 3) { user = process.argv[2]; } else { user = 'world'; } - - var request = new hello_messages.HelloRequest(); - request.setName(user); - - client.sayHello(request, function(err, response) { - if (err) { - debugger; - throw err; - } - console.log('Greeting:', response.getMessage()); + client.sayHello({name: user}, function(err, response) { + console.log('Greeting:', response.message); }); } diff --git a/examples/node/greeter_server.js b/examples/node/greeter_server.js index a4aebf6d09..e7ad51f600 100644 --- a/examples/node/greeter_server.js +++ b/examples/node/greeter_server.js @@ -31,18 +31,16 @@ * */ -var grpc = require('grpc'); +var PROTO_PATH = __dirname + '/../protos/helloworld.proto'; -var hello_messages = require('./helloworld_pb'); -var hello_service = require('./helloworld_grpc_pb'); +var grpc = require('grpc'); +var hello_proto = grpc.load(PROTO_PATH).helloworld; /** * Implements the SayHello RPC method. */ function sayHello(call, callback) { - var reply = new hello_messages.HelloReply(); - reply.setMessage("Hello " + call.request.getName()); - callback(null, reply); + callback(null, {message: 'Hello ' + call.request.name}); } /** @@ -51,7 +49,7 @@ function sayHello(call, callback) { */ function main() { var server = new grpc.Server(); - server.addService(hello_service.GreeterService, {sayHello: sayHello}); + server.addProtoService(hello_proto.Greeter.service, {sayHello: sayHello}); server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure()); server.start(); } diff --git a/examples/node/helloworld_grpc_pb.js b/examples/node/helloworld_grpc_pb.js deleted file mode 100644 index 3d070d7de0..0000000000 --- a/examples/node/helloworld_grpc_pb.js +++ /dev/null @@ -1,39 +0,0 @@ -// GENERATED CODE -- DO NOT EDIT! - -var grpc = require('grpc'); -var helloworld_pb = require('./helloworld_pb.js'); - -function serialize_HelloReply(arg) { - if (!(arg instanceof helloworld_pb.HelloReply)) { - throw new Error('Expected argument of type HelloReply'); - } - return new Buffer(arg.serializeBinary()); -} -function deserialize_HelloReply(buffer_arg) { - return helloworld_pb.HelloReply.deserializeBinary(new Uint8Array(buffer_arg)); -} -function serialize_HelloRequest(arg) { - if (!(arg instanceof helloworld_pb.HelloRequest)) { - throw new Error('Expected argument of type HelloRequest'); - } - return new Buffer(arg.serializeBinary()); -} -function deserialize_HelloRequest(buffer_arg) { - return helloworld_pb.HelloRequest.deserializeBinary(new Uint8Array(buffer_arg)); -} - -var GreeterService = exports.GreeterService = { - sayHello: { - path: '/helloworld.Greeter/SayHello', - requestStream: false, - responseStream: false, - requestType: helloworld_pb.HelloRequest, - responseType: helloworld_pb.HelloReply, - requestSerialize: serialize_HelloRequest, - requestDeserialize: deserialize_HelloRequest, - responseSerialize: serialize_HelloReply, - responseDeserialize: deserialize_HelloReply, - }, -}; - -exports.GreeterClient = grpc.makeGenericClientConstructor(GreeterService); diff --git a/examples/node/helloworld_pb.js b/examples/node/helloworld_pb.js deleted file mode 100644 index 6405bd90f1..0000000000 --- a/examples/node/helloworld_pb.js +++ /dev/null @@ -1,332 +0,0 @@ -/** - * @fileoverview - * @enhanceable - * @public - */ -// GENERATED CODE -- DO NOT EDIT! - -var jspb = require('google-protobuf'); -var goog = jspb; -var global = Function('return this')(); - -goog.exportSymbol('proto.helloworld.HelloReply', null, global); -goog.exportSymbol('proto.helloworld.HelloRequest', null, global); - -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -proto.helloworld.HelloRequest = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, null, null); -}; -goog.inherits(proto.helloworld.HelloRequest, jspb.Message); -if (goog.DEBUG && !COMPILED) { - proto.helloworld.HelloRequest.displayName = 'proto.helloworld.HelloRequest'; -} - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto suitable for use in Soy templates. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} - */ -proto.helloworld.HelloRequest.prototype.toObject = function(opt_includeInstance) { - return proto.helloworld.HelloRequest.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Whether to include the JSPB - * instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!proto.helloworld.HelloRequest} msg The msg instance to transform. - * @return {!Object} - */ -proto.helloworld.HelloRequest.toObject = function(includeInstance, msg) { - var f, obj = { - name: msg.getName() - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.helloworld.HelloRequest} - */ -proto.helloworld.HelloRequest.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new proto.helloworld.HelloRequest; - return proto.helloworld.HelloRequest.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!proto.helloworld.HelloRequest} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.helloworld.HelloRequest} - */ -proto.helloworld.HelloRequest.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {string} */ (reader.readString()); - msg.setName(value); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Class method variant: serializes the given message to binary data - * (in protobuf wire format), writing to the given BinaryWriter. - * @param {!proto.helloworld.HelloRequest} message - * @param {!jspb.BinaryWriter} writer - */ -proto.helloworld.HelloRequest.serializeBinaryToWriter = function(message, writer) { - message.serializeBinaryToWriter(writer); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -proto.helloworld.HelloRequest.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - this.serializeBinaryToWriter(writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format), - * writing to the given BinaryWriter. - * @param {!jspb.BinaryWriter} writer - */ -proto.helloworld.HelloRequest.prototype.serializeBinaryToWriter = function (writer) { - var f = undefined; - f = this.getName(); - if (f.length > 0) { - writer.writeString( - 1, - f - ); - } -}; - - -/** - * Creates a deep clone of this proto. No data is shared with the original. - * @return {!proto.helloworld.HelloRequest} The clone. - */ -proto.helloworld.HelloRequest.prototype.cloneMessage = function() { - return /** @type {!proto.helloworld.HelloRequest} */ (jspb.Message.cloneMessage(this)); -}; - - -/** - * optional string name = 1; - * @return {string} - */ -proto.helloworld.HelloRequest.prototype.getName = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, "")); -}; - - -/** @param {string} value */ -proto.helloworld.HelloRequest.prototype.setName = function(value) { - jspb.Message.setField(this, 1, value); -}; - - - -/** - * Generated by JsPbCodeGenerator. - * @param {Array=} opt_data Optional initial data array, typically from a - * server response, or constructed directly in Javascript. The array is used - * in place and becomes part of the constructed object. It is not cloned. - * If no data is provided, the constructed object will be empty, but still - * valid. - * @extends {jspb.Message} - * @constructor - */ -proto.helloworld.HelloReply = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, null, null); -}; -goog.inherits(proto.helloworld.HelloReply, jspb.Message); -if (goog.DEBUG && !COMPILED) { - proto.helloworld.HelloReply.displayName = 'proto.helloworld.HelloReply'; -} - - -if (jspb.Message.GENERATE_TO_OBJECT) { -/** - * Creates an object representation of this proto suitable for use in Soy templates. - * Field names that are reserved in JavaScript and will be renamed to pb_name. - * To access a reserved field use, foo.pb_, eg, foo.pb_default. - * For the list of reserved names please see: - * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} - */ -proto.helloworld.HelloReply.prototype.toObject = function(opt_includeInstance) { - return proto.helloworld.HelloReply.toObject(opt_includeInstance, this); -}; - - -/** - * Static version of the {@see toObject} method. - * @param {boolean|undefined} includeInstance Whether to include the JSPB - * instance for transitional soy proto support: - * http://goto/soy-param-migration - * @param {!proto.helloworld.HelloReply} msg The msg instance to transform. - * @return {!Object} - */ -proto.helloworld.HelloReply.toObject = function(includeInstance, msg) { - var f, obj = { - message: msg.getMessage() - }; - - if (includeInstance) { - obj.$jspbMessageInstance = msg - } - return obj; -}; -} - - -/** - * Deserializes binary data (in protobuf wire format). - * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.helloworld.HelloReply} - */ -proto.helloworld.HelloReply.deserializeBinary = function(bytes) { - var reader = new jspb.BinaryReader(bytes); - var msg = new proto.helloworld.HelloReply; - return proto.helloworld.HelloReply.deserializeBinaryFromReader(msg, reader); -}; - - -/** - * Deserializes binary data (in protobuf wire format) from the - * given reader into the given message object. - * @param {!proto.helloworld.HelloReply} msg The message object to deserialize into. - * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.helloworld.HelloReply} - */ -proto.helloworld.HelloReply.deserializeBinaryFromReader = function(msg, reader) { - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - switch (field) { - case 1: - var value = /** @type {string} */ (reader.readString()); - msg.setMessage(value); - break; - default: - reader.skipField(); - break; - } - } - return msg; -}; - - -/** - * Class method variant: serializes the given message to binary data - * (in protobuf wire format), writing to the given BinaryWriter. - * @param {!proto.helloworld.HelloReply} message - * @param {!jspb.BinaryWriter} writer - */ -proto.helloworld.HelloReply.serializeBinaryToWriter = function(message, writer) { - message.serializeBinaryToWriter(writer); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format). - * @return {!Uint8Array} - */ -proto.helloworld.HelloReply.prototype.serializeBinary = function() { - var writer = new jspb.BinaryWriter(); - this.serializeBinaryToWriter(writer); - return writer.getResultBuffer(); -}; - - -/** - * Serializes the message to binary data (in protobuf wire format), - * writing to the given BinaryWriter. - * @param {!jspb.BinaryWriter} writer - */ -proto.helloworld.HelloReply.prototype.serializeBinaryToWriter = function (writer) { - var f = undefined; - f = this.getMessage(); - if (f.length > 0) { - writer.writeString( - 1, - f - ); - } -}; - - -/** - * Creates a deep clone of this proto. No data is shared with the original. - * @return {!proto.helloworld.HelloReply} The clone. - */ -proto.helloworld.HelloReply.prototype.cloneMessage = function() { - return /** @type {!proto.helloworld.HelloReply} */ (jspb.Message.cloneMessage(this)); -}; - - -/** - * optional string message = 1; - * @return {string} - */ -proto.helloworld.HelloReply.prototype.getMessage = function() { - return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, "")); -}; - - -/** @param {string} value */ -proto.helloworld.HelloReply.prototype.setMessage = function(value) { - jspb.Message.setField(this, 1, value); -}; - - -goog.object.extend(exports, proto.helloworld); diff --git a/examples/node/package.json b/examples/node/package.json index 49ab74d318..d135df2464 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -4,7 +4,6 @@ "dependencies": { "async": "^1.5.2", "grpc": "0.13.0", - "google-protobuf": "*", "lodash": "^4.6.1", "minimist": "^1.2.0" } -- cgit v1.2.3 From 4ee1a627230c8564dfdab5247e8703e0eb10d5c8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 29 Apr 2016 16:47:27 -0700 Subject: Stress test fixes - properly fail a Read() on a stream if we fail to parse a protobuf - fix an ordering problem with the chttp2 transport global lock, whereby a sequence of two operations could be swapped - this resulted in slices being returned to the upper layers in the wrong order, corrupting data --- include/grpc++/impl/codegen/call.h | 7 +++---- .../ext/transport/chttp2/transport/chttp2_transport.c | 17 ++++++++++++----- src/core/ext/transport/chttp2/transport/internal.h | 3 ++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index aea1a6acec..d081b7d9c5 100644 --- a/include/grpc++/impl/codegen/call.h +++ b/include/grpc++/impl/codegen/call.h @@ -281,10 +281,9 @@ class CallOpRecvMessage { if (message_ == nullptr) return; if (recv_buf_) { if (*status) { - got_message = true; - *status = SerializationTraits::Deserialize(recv_buf_, message_, - max_message_size) - .ok(); + got_message = *status = SerializationTraits::Deserialize( + recv_buf_, message_, max_message_size) + .ok(); } else { got_message = false; g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index fcf2abfe66..8c8593748d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -629,9 +629,10 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx, check_read_ops(exec_ctx, &t->global); gpr_mu_lock(&t->executor.mu); - if (t->executor.pending_actions != NULL) { - hdr = t->executor.pending_actions; - t->executor.pending_actions = NULL; + if (t->executor.pending_actions_head != NULL) { + hdr = t->executor.pending_actions_head; + t->executor.pending_actions_head = t->executor.pending_actions_tail = + NULL; gpr_mu_unlock(&t->executor.mu); while (hdr != NULL) { hdr->action(exec_ctx, t, hdr->stream, hdr->arg); @@ -686,8 +687,14 @@ void grpc_chttp2_run_with_global_lock(grpc_exec_ctx *exec_ctx, gpr_free(hdr); continue; } - hdr->next = t->executor.pending_actions; - t->executor.pending_actions = hdr; + hdr->next = NULL; + if (t->executor.pending_actions_head != NULL) { + t->executor.pending_actions_tail = + t->executor.pending_actions_tail->next = hdr; + } else { + t->executor.pending_actions_tail = t->executor.pending_actions_head = + hdr; + } REF_TRANSPORT(t, "pending_action"); gpr_mu_unlock(&t->executor.mu); } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 7a8084641d..a269338b49 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -321,7 +321,8 @@ struct grpc_chttp2_transport { /** is a thread currently parsing */ bool parsing_active; - grpc_chttp2_executor_action_header *pending_actions; + grpc_chttp2_executor_action_header *pending_actions_head; + grpc_chttp2_executor_action_header *pending_actions_tail; } executor; /** is the transport destroying itself? */ -- cgit v1.2.3 From 615da649926677bf00b165cb183d97233fcd46c8 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Fri, 29 Apr 2016 18:14:05 -0700 Subject: explicitly cast constant value to gpr_atm --- src/core/ext/client_config/subchannel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index 3a5af9f53d..bd45d3825c 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -268,7 +268,7 @@ static void disconnect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { con = GET_CONNECTED_SUBCHANNEL(c, no_barrier); if (con != NULL) { GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, con, "connection"); - gpr_atm_no_barrier_store(&c->connected_subchannel, 0xdeadbeef); + gpr_atm_no_barrier_store(&c->connected_subchannel, (gpr_atm)0xdeadbeef); } gpr_mu_unlock(&c->mu); } -- cgit v1.2.3 From 67df784bbc603a9d43f75780c73714e53249c0ea Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 29 Apr 2016 16:38:03 -0700 Subject: C# Dockerfile and Config scripts --- .../grpc_interop_stress_csharp/Dockerfile.template | 41 +++++++++ .../grpc_interop_stress_csharp/Dockerfile | 101 +++++++++++++++++++++ .../build_interop_stress.sh | 47 ++++++++++ tools/run_tests/stress_test/configs/csharp.json | 90 ++++++++++++++++++ 4 files changed, 279 insertions(+) create mode 100644 templates/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile.template create mode 100644 tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile create mode 100755 tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh create mode 100644 tools/run_tests/stress_test/configs/csharp.json diff --git a/templates/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile.template b/templates/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile.template new file mode 100644 index 0000000000..074178252d --- /dev/null +++ b/templates/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile.template @@ -0,0 +1,41 @@ +%YAML 1.2 +--- | + # 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. + + FROM debian:jessie + + <%include file="../../apt_get_basic.include"/> + <%include file="../../ccache_setup.include"/> + <%include file="../../cxx_deps.include"/> + <%include file="../../gcp_api_libraries.include"/> + <%include file="../../csharp_deps.include"/> + # Define the default command. + CMD ["bash"] + diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile new file mode 100644 index 0000000000..823fe948fb --- /dev/null +++ b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile @@ -0,0 +1,101 @@ +# 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. + +FROM debian:jessie + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Prepare ccache +RUN ln -s /usr/bin/ccache /usr/local/bin/gcc +RUN ln -s /usr/bin/ccache /usr/local/bin/g++ +RUN ln -s /usr/bin/ccache /usr/local/bin/cc +RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN ln -s /usr/bin/ccache /usr/local/bin/clang +RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ + +#================= +# C++ dependencies +RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client + + +#================ +# C# dependencies + +# Update to a newer version of mono +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list +RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list + +# Install dependencies +RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ + mono-devel \ + ca-certificates-mono \ + nuget \ + && apt-get clean + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh new file mode 100755 index 0000000000..1f4bf893cc --- /dev/null +++ b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh @@ -0,0 +1,47 @@ +#!/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. +# +# Builds C# interop server and client in a base image. +set -e + +mkdir -p /var/local/git +git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc + +# Copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +cd /var/local/git/grpc + +# Build C++ metrics client (to query the metrics from csharp stress client) +make metrics_client -j + +# Build C# interop client & server +tools/run_tests/run_tests.py -l csharp -c dbg --build_only + diff --git a/tools/run_tests/stress_test/configs/csharp.json b/tools/run_tests/stress_test/configs/csharp.json new file mode 100644 index 0000000000..b7090696b4 --- /dev/null +++ b/tools/run_tests/stress_test/configs/csharp.json @@ -0,0 +1,90 @@ +{ + "dockerImages": { + "grpc_stress_csharp" : { + "buildScript": "tools/jenkins/build_interop_stress_image.sh", + "dockerFileDir": "grpc_interop_stress_csharp" + } + }, + + "clientTemplates": { + "baseTemplates": { + "default": { + "wrapperScriptPath": "/var/local/git/grpc/tools/gcp/stress_test/run_client.py", + "pollIntervalSecs": 60, + "clientArgs": { + "num_channels_per_server":5, + "num_stubs_per_channel":10, + "test_cases": "empty_unary:1,large_unary:1,client_streaming:1,server_streaming:1,empty_stream:1", + "metrics_port": 8081 + }, + "metricsPort": 8081, + "metricsArgs": { + "metrics_server_address": "localhost:8081", + "total_only": "true" + } + } + }, + "templates": { + "csharp_client": { + "baseTemplate": "default", + "stressClientCmd": [ + "mono", + "/var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.StressClient/bin/Debug/Grpc.IntegrationTesting.StressClient.exe" + ], + "metricsClientCmd": ["/var/local/git/grpc/bins/opt/metrics_client"] + } + } + }, + + "serverTemplates": { + "baseTemplates":{ + "default": { + "wrapperScriptPath": "/var/local/git/grpc/tools/gcp/stress_test/run_server.py", + "serverPort": 8080, + "serverArgs": { + "port": 8080 + } + } + }, + "templates": { + "csharp_server": { + "baseTemplate": "default", + "stressServerCmd": [ + "mono", + "/var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/Grpc.IntegrationTesting.Server.exe" + ] + } + } + }, + + "testMatrix": { + "serverPodSpecs": { + "stress-server-csharp": { + "serverTemplate": "csharp_server", + "dockerImage": "grpc_stress_csharp", + "numInstances": 1 + } + }, + + "clientPodSpecs": { + "stress-client-csharp": { + "clientTemplate": "csharp_client", + "dockerImage": "grpc_stress_csharp", + "numInstances": 10, + "serverPodSpec": "stress-server-csharp" + } + } + }, + + "globalSettings": { + "buildDockerImages": true, + "pollIntervalSecs": 60, + "testDurationSecs": 7200, + "kubernetesProxyPort": 8001, + "datasetIdNamePrefix": "stress_test_csharp", + "summaryTableId": "summary", + "qpsTableId": "qps", + "podWarmupSecs": 60 + } +} + -- cgit v1.2.3 From e98b494db77f9b10522cf6a8238deb8d7bd55345 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 30 Apr 2016 14:11:33 -0700 Subject: Fix bug where max_frame_size was ignored Also add corpus entries that helped diagnose this bug --- src/core/ext/transport/chttp2/transport/internal.h | 8 +- src/core/ext/transport/chttp2/transport/parsing.c | 21 +- .../03a72675e1969f836094f1ecfec2a7b34418e306 | Bin 0 -> 286 bytes .../0416afd6875d9ba55f1e5f86a6456a5445d5e576 | Bin 0 -> 651 bytes .../08c42ef29eff83052c5887855f2fa3e07ebe470c | Bin 0 -> 650 bytes .../1ba889ea1543297824e99e641e6ca8b91f45732e | Bin 0 -> 650 bytes .../3b09bf453c6f93983c24c4d5481e55d66213f93a | Bin 0 -> 650 bytes .../49cb33cbb60f041e8e99dd718993acd2c3354416 | Bin 0 -> 357 bytes .../59743fe120be6ae1aed1c02230ee1bb460f621ee | Bin 0 -> 628 bytes .../a5ccb8f124d8ddb5350b90bc0d6b96db280cb7c9 | Bin 0 -> 651 bytes .../a7fac1265a384fe9e45a9ee3d708b79c4e80505e | Bin 0 -> 286 bytes .../aaf049720c707d4e14e47e7eb31d6a2dda60e66a | Bin 0 -> 651 bytes .../c4e4c7572e005e18d56eac407033da058737a5ab | Bin 0 -> 651 bytes .../crash-dae0f07934a527989f23f06e630710ff6ca8c809 | Bin 0 -> 104 bytes .../e96ad9c17795e52edc810a08d4fc61fe8790002a | Bin 0 -> 651 bytes .../fa202a5f51cd49f8ea5af60c5f403f797c01c504 | Bin 0 -> 651 bytes tools/run_tests/tests.json | 224 +++++++++++++++++++++ 17 files changed, 246 insertions(+), 7 deletions(-) create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/03a72675e1969f836094f1ecfec2a7b34418e306 create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/0416afd6875d9ba55f1e5f86a6456a5445d5e576 create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/08c42ef29eff83052c5887855f2fa3e07ebe470c create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/1ba889ea1543297824e99e641e6ca8b91f45732e create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/3b09bf453c6f93983c24c4d5481e55d66213f93a create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/49cb33cbb60f041e8e99dd718993acd2c3354416 create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/59743fe120be6ae1aed1c02230ee1bb460f621ee create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/a5ccb8f124d8ddb5350b90bc0d6b96db280cb7c9 create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/a7fac1265a384fe9e45a9ee3d708b79c4e80505e create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/aaf049720c707d4e14e47e7eb31d6a2dda60e66a create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/c4e4c7572e005e18d56eac407033da058737a5ab create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809 create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/e96ad9c17795e52edc810a08d4fc61fe8790002a create mode 100644 test/core/end2end/fuzzers/server_fuzzer_corpus/fa202a5f51cd49f8ea5af60c5f403f797c01c504 diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 7a8084641d..04c75619df 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -236,9 +236,6 @@ struct grpc_chttp2_transport_parsing { /** was a goaway frame received? */ uint8_t goaway_received; - /** the last sent max_table_size setting */ - uint32_t last_sent_max_table_size; - /** initial window change */ int64_t initial_window_update; @@ -272,6 +269,9 @@ struct grpc_chttp2_transport_parsing { uint32_t incoming_frame_size; uint32_t incoming_stream_id; + /* current max frame size */ + uint32_t max_frame_size; + /* active parser */ void *parser_data; grpc_chttp2_stream_parsing *incoming_stream; @@ -282,6 +282,8 @@ struct grpc_chttp2_transport_parsing { /* received settings */ uint32_t settings[GRPC_CHTTP2_NUM_SETTINGS]; + /* last settings that were sent */ + uint32_t last_sent_settings[GRPC_CHTTP2_NUM_SETTINGS]; /* goaway data */ grpc_status_code goaway_error; diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index e827a43f7a..2995066e51 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -79,9 +79,12 @@ void grpc_chttp2_prepare_to_read( GPR_TIMER_BEGIN("grpc_chttp2_prepare_to_read", 0); transport_parsing->next_stream_id = transport_global->next_stream_id; - transport_parsing->last_sent_max_table_size = - transport_global->settings[GRPC_SENT_SETTINGS] - [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]; + memcpy(transport_parsing->last_sent_settings, + transport_global->settings[GRPC_SENT_SETTINGS], + sizeof(transport_parsing->last_sent_settings)); + transport_parsing->max_frame_size = + transport_global->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]; /* update the parsing view of incoming window */ while (grpc_chttp2_list_pop_unannounced_incoming_window_available( @@ -388,6 +391,12 @@ int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, return 1; } goto dts_fh_0; /* loop */ + } else if (transport_parsing->incoming_frame_size > + transport_parsing->max_frame_size) { + gpr_log(GPR_DEBUG, "Frame size %d is larger than max frame size %d", + transport_parsing->incoming_frame_size, + transport_parsing->max_frame_size); + return 0; } if (++cur == end) { return 1; @@ -840,7 +849,11 @@ static int init_settings_frame_parser( transport_parsing->settings_ack_received = 1; grpc_chttp2_hptbl_set_max_bytes( &transport_parsing->hpack_parser.table, - transport_parsing->last_sent_max_table_size); + transport_parsing + ->last_sent_settings[GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); + transport_parsing->max_frame_size = + transport_parsing + ->last_sent_settings[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]; } transport_parsing->parser = grpc_chttp2_settings_parser_parse; transport_parsing->parser_data = &transport_parsing->simple.settings; diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/03a72675e1969f836094f1ecfec2a7b34418e306 b/test/core/end2end/fuzzers/server_fuzzer_corpus/03a72675e1969f836094f1ecfec2a7b34418e306 new file mode 100644 index 0000000000..503af15fe8 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/03a72675e1969f836094f1ecfec2a7b34418e306 differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/0416afd6875d9ba55f1e5f86a6456a5445d5e576 b/test/core/end2end/fuzzers/server_fuzzer_corpus/0416afd6875d9ba55f1e5f86a6456a5445d5e576 new file mode 100644 index 0000000000..30229f98fd Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/0416afd6875d9ba55f1e5f86a6456a5445d5e576 differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/08c42ef29eff83052c5887855f2fa3e07ebe470c b/test/core/end2end/fuzzers/server_fuzzer_corpus/08c42ef29eff83052c5887855f2fa3e07ebe470c new file mode 100644 index 0000000000..828275ee3c Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/08c42ef29eff83052c5887855f2fa3e07ebe470c differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/1ba889ea1543297824e99e641e6ca8b91f45732e b/test/core/end2end/fuzzers/server_fuzzer_corpus/1ba889ea1543297824e99e641e6ca8b91f45732e new file mode 100644 index 0000000000..6ed060d1e3 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/1ba889ea1543297824e99e641e6ca8b91f45732e differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/3b09bf453c6f93983c24c4d5481e55d66213f93a b/test/core/end2end/fuzzers/server_fuzzer_corpus/3b09bf453c6f93983c24c4d5481e55d66213f93a new file mode 100644 index 0000000000..1a7a213cd7 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/3b09bf453c6f93983c24c4d5481e55d66213f93a differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/49cb33cbb60f041e8e99dd718993acd2c3354416 b/test/core/end2end/fuzzers/server_fuzzer_corpus/49cb33cbb60f041e8e99dd718993acd2c3354416 new file mode 100644 index 0000000000..7f975251dd Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/49cb33cbb60f041e8e99dd718993acd2c3354416 differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/59743fe120be6ae1aed1c02230ee1bb460f621ee b/test/core/end2end/fuzzers/server_fuzzer_corpus/59743fe120be6ae1aed1c02230ee1bb460f621ee new file mode 100644 index 0000000000..3038fde547 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/59743fe120be6ae1aed1c02230ee1bb460f621ee differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/a5ccb8f124d8ddb5350b90bc0d6b96db280cb7c9 b/test/core/end2end/fuzzers/server_fuzzer_corpus/a5ccb8f124d8ddb5350b90bc0d6b96db280cb7c9 new file mode 100644 index 0000000000..9d39854fc9 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/a5ccb8f124d8ddb5350b90bc0d6b96db280cb7c9 differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/a7fac1265a384fe9e45a9ee3d708b79c4e80505e b/test/core/end2end/fuzzers/server_fuzzer_corpus/a7fac1265a384fe9e45a9ee3d708b79c4e80505e new file mode 100644 index 0000000000..338f61bdce Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/a7fac1265a384fe9e45a9ee3d708b79c4e80505e differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/aaf049720c707d4e14e47e7eb31d6a2dda60e66a b/test/core/end2end/fuzzers/server_fuzzer_corpus/aaf049720c707d4e14e47e7eb31d6a2dda60e66a new file mode 100644 index 0000000000..dab9c75822 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/aaf049720c707d4e14e47e7eb31d6a2dda60e66a differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/c4e4c7572e005e18d56eac407033da058737a5ab b/test/core/end2end/fuzzers/server_fuzzer_corpus/c4e4c7572e005e18d56eac407033da058737a5ab new file mode 100644 index 0000000000..070a581b37 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/c4e4c7572e005e18d56eac407033da058737a5ab differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809 b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809 new file mode 100644 index 0000000000..b6dfd77e67 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809 differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/e96ad9c17795e52edc810a08d4fc61fe8790002a b/test/core/end2end/fuzzers/server_fuzzer_corpus/e96ad9c17795e52edc810a08d4fc61fe8790002a new file mode 100644 index 0000000000..df9241dd0c Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/e96ad9c17795e52edc810a08d4fc61fe8790002a differ diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/fa202a5f51cd49f8ea5af60c5f403f797c01c504 b/test/core/end2end/fuzzers/server_fuzzer_corpus/fa202a5f51cd49f8ea5af60c5f403f797c01c504 new file mode 100644 index 0000000000..0ba5935164 Binary files /dev/null and b/test/core/end2end/fuzzers/server_fuzzer_corpus/fa202a5f51cd49f8ea5af60c5f403f797c01c504 differ diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 0fd77854d2..cf1154426f 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -57757,6 +57757,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/03a72675e1969f836094f1ecfec2a7b34418e306" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/03b9be1fa172dff5d1543be079b9c64fa2c9a278" @@ -57773,6 +57789,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/0416afd6875d9ba55f1e5f86a6456a5445d5e576" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/052c8f28e5884bb48f0d504461272cd3a5893215" @@ -57917,6 +57949,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/08c42ef29eff83052c5887855f2fa3e07ebe470c" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/09938e3256d06a8e168eb038d8a58b8462f7f697" @@ -58365,6 +58413,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/1ba889ea1543297824e99e641e6ca8b91f45732e" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/1cf17783de9e662f3720847f2d83d86dcdcab500" @@ -59149,6 +59213,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/3b09bf453c6f93983c24c4d5481e55d66213f93a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/3ca5da2f.bin" @@ -59501,6 +59581,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/49cb33cbb60f041e8e99dd718993acd2c3354416" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/4aa883d0.bin" @@ -59949,6 +60045,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/59743fe120be6ae1aed1c02230ee1bb460f621ee" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/597fdab5.bin" @@ -61341,6 +61453,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/a5ccb8f124d8ddb5350b90bc0d6b96db280cb7c9" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/a7e64803.bin" @@ -61357,6 +61485,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/a7fac1265a384fe9e45a9ee3d708b79c4e80505e" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/a8d229374635fa6f2a75ca1669892e1bc244e719" @@ -61501,6 +61645,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/aaf049720c707d4e14e47e7eb31d6a2dda60e66a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/ad810f7f.bin" @@ -61965,6 +62125,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/c4e4c7572e005e18d56eac407033da058737a5ab" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/c559f565.bin" @@ -62269,6 +62445,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-e34b0a9a428001cb4094a9ebca76329f578811a4" @@ -62589,6 +62781,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/e96ad9c17795e52edc810a08d4fc61fe8790002a" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/e9bbe2fe47b7b9c2683e7f17f4a33625c6ffbd8c" @@ -62909,6 +63117,22 @@ "linux" ] }, + { + "args": [ + "test/core/end2end/fuzzers/server_fuzzer_corpus/fa202a5f51cd49f8ea5af60c5f403f797c01c504" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "server_fuzzer_one_entry", + "platforms": [ + "linux" + ] + }, { "args": [ "test/core/end2end/fuzzers/server_fuzzer_corpus/fa36b4280d9e28edd81c5e4d192d1a5c2765e5e4" -- cgit v1.2.3 From 13d1abf4447e30b2cef2924656b73044cf40cf8c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 2 May 2016 09:54:58 -0700 Subject: improve unary call response handler --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 016e1b8587..fc3c4a2b2b 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -407,12 +407,15 @@ namespace Grpc.Core.Internal /// /// Handler for unary response completion. /// - private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) + private void HandleUnaryResponse(bool sucess, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) { + // NOTE: because this event is a result of batch containing GRPC_OP_RECV_STATUS_ON_CLIENT, + // success will be always set to true. + using (Profilers.ForCurrentThread().NewScope("AsyncCall.HandleUnaryResponse")) { TResponse msg = default(TResponse); - var deserializeException = success ? TryDeserialize(receivedMessage, out msg) : null; + var deserializeException = TryDeserialize(receivedMessage, out msg); lock (myLock) { @@ -425,14 +428,13 @@ namespace Grpc.Core.Internal finishedStatus = receivedStatus; ReleaseResourcesIfPossible(); - } responseHeadersTcs.SetResult(responseHeaders); var status = receivedStatus.Status; - if (!success || status.StatusCode != StatusCode.OK) + if (status.StatusCode != StatusCode.OK) { unaryResponseTcs.SetException(new RpcException(status)); return; @@ -447,6 +449,9 @@ namespace Grpc.Core.Internal /// private void HandleFinished(bool success, ClientSideStatus receivedStatus) { + // NOTE: because this event is a result of batch containing GRPC_OP_RECV_STATUS_ON_CLIENT, + // success will be always set to true. + lock (myLock) { finished = true; @@ -457,7 +462,7 @@ namespace Grpc.Core.Internal var status = receivedStatus.Status; - if (!success || status.StatusCode != StatusCode.OK) + if (status.StatusCode != StatusCode.OK) { streamingCallFinishedTcs.SetException(new RpcException(status)); return; -- cgit v1.2.3 From a4a627030eb34e8e2f068f1ab327810cd4c3354c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 2 May 2016 09:55:18 -0700 Subject: add more tests --- .../Grpc.Core.Tests/Internal/AsyncCallTest.cs | 109 ++++++++++++++++++--- 1 file changed, 98 insertions(+), 11 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs index 60530d3250..a678e4dafe 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs @@ -64,28 +64,115 @@ namespace Grpc.Core.Internal.Tests } [Test] - public void AsyncUnary_CompletionSuccess() + public void AsyncUnary_CanBeStartedOnlyOnce() + { + asyncCall.UnaryCallAsync("request1"); + Assert.Throws(typeof(InvalidOperationException), + () => asyncCall.UnaryCallAsync("abc")); + } + + [Test] + public void AsyncUnary_StreamingOperationsNotAllowed() + { + asyncCall.UnaryCallAsync("request1"); + Assert.Throws(typeof(InvalidOperationException), + () => asyncCall.StartReadMessage((x,y) => {})); + Assert.Throws(typeof(InvalidOperationException), + () => asyncCall.StartSendMessage("abc", new WriteFlags(), (x,y) => {})); + } + + [Test] + public void AsyncUnary_Success() + { + var resultTask = asyncCall.UnaryCallAsync("request1"); + fakeCall.UnaryResponseClientHandler(true, + new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + CreateResponsePayload(), + new Metadata()); + + AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask); + } + + [Test] + public void AsyncUnary_NonSuccessStatusCode() + { + var resultTask = asyncCall.UnaryCallAsync("request1"); + fakeCall.UnaryResponseClientHandler(true, + CreateClientSideStatus(StatusCode.InvalidArgument), + CreateResponsePayload(), + new Metadata()); + + AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); + } + + [Test] + public void AsyncUnary_NullResponsePayload() + { + var resultTask = asyncCall.UnaryCallAsync("request1"); + fakeCall.UnaryResponseClientHandler(true, + new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + null, + new Metadata()); + + // failure to deserialize will result in InvalidArgument status. + AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal); + } + + [Test] + public void ClientStreaming_NoRequest_Success() + { + var resultTask = asyncCall.ClientStreamingCallAsync(); + fakeCall.UnaryResponseClientHandler(true, + new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + CreateResponsePayload(), + new Metadata()); + + AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask); + } + + [Test] + public void ClientStreaming_NoRequest_NonSuccessStatusCode() + { + var resultTask = asyncCall.ClientStreamingCallAsync(); + fakeCall.UnaryResponseClientHandler(true, + CreateClientSideStatus(StatusCode.InvalidArgument), + CreateResponsePayload(), + new Metadata()); + + AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); + } + + ClientSideStatus CreateClientSideStatus(StatusCode statusCode) + { + return new ClientSideStatus(new Status(statusCode, ""), new Metadata()); + } + + byte[] CreateResponsePayload() + { + return Marshallers.StringMarshaller.Serializer("response1"); + } + + static void AssertUnaryResponseSuccess(AsyncCall asyncCall, FakeNativeCall fakeCall, Task resultTask) { - var resultTask = asyncCall.UnaryCallAsync("abc"); - fakeCall.UnaryResponseClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), new byte[] { 1, 2, 3 }, new Metadata()); Assert.IsTrue(resultTask.IsCompleted); Assert.IsTrue(fakeCall.IsDisposed); + Assert.AreEqual(Status.DefaultSuccess, asyncCall.GetStatus()); + Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count); + Assert.AreEqual(0, asyncCall.GetTrailers().Count); + Assert.AreEqual("response1", resultTask.Result); } - [Test] - public void AsyncUnary_CompletionFailure() + static void AssertUnaryResponseError(AsyncCall asyncCall, FakeNativeCall fakeCall, Task resultTask, StatusCode expectedStatusCode) { - var resultTask = asyncCall.UnaryCallAsync("abc"); - fakeCall.UnaryResponseClientHandler(false, new ClientSideStatus(new Status(StatusCode.Internal, ""), null), new byte[] { 1, 2, 3 }, new Metadata()); - Assert.IsTrue(resultTask.IsCompleted); Assert.IsTrue(fakeCall.IsDisposed); - Assert.AreEqual(StatusCode.Internal, asyncCall.GetStatus().StatusCode); - Assert.IsNull(asyncCall.GetTrailers()); + Assert.AreEqual(expectedStatusCode, asyncCall.GetStatus().StatusCode); var ex = Assert.ThrowsAsync(async () => await resultTask); - Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); + Assert.AreEqual(expectedStatusCode, ex.Status.StatusCode); + Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count); + Assert.AreEqual(0, asyncCall.GetTrailers().Count); } internal class FakeNativeCall : INativeCall -- cgit v1.2.3 From edb8b76ac2dc5f1b9bdaf97e69a21e3c59bfb775 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 2 May 2016 10:43:04 -0700 Subject: Simplified Ruby tools extension checking --- src/ruby/tools/bin/protoc.rb | 9 +----- src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb | 9 +----- src/ruby/tools/os_check.rb | 45 --------------------------- 3 files changed, 2 insertions(+), 61 deletions(-) delete mode 100644 src/ruby/tools/os_check.rb diff --git a/src/ruby/tools/bin/protoc.rb b/src/ruby/tools/bin/protoc.rb index 68cbc852fd..728a88b007 100755 --- a/src/ruby/tools/bin/protoc.rb +++ b/src/ruby/tools/bin/protoc.rb @@ -30,14 +30,7 @@ require 'rbconfig' -require_relative '../os_check' - -protoc_name = case OS.os_name - when 'windows' - 'protoc.exe' - else - 'protoc' - end +protoc_name = 'protoc' + RbConfig::CONFIG['EXEEXT'] protoc_path = File.join(File.dirname(__FILE__), RbConfig::CONFIG['host_cpu'] + '-' + OS.os_name, diff --git a/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb b/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb index 04cf435b58..814aef2446 100755 --- a/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb +++ b/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb @@ -30,14 +30,7 @@ require 'rbconfig' -require_relative '../os_check' - -plugin_name = 'grpc_ruby_plugin' + case OS.os_name - when 'windows' - '.exe' - else - '' - end +plugin_name = 'grpc_ruby_plugin' + RbConfig::CONFIG['EXEEXT'] plugin_path = File.join(File.dirname(__FILE__), RbConfig::CONFIG['host_cpu'] + '-' + OS.os_name, diff --git a/src/ruby/tools/os_check.rb b/src/ruby/tools/os_check.rb deleted file mode 100644 index 2677306457..0000000000 --- a/src/ruby/tools/os_check.rb +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -# This is based on http://stackoverflow.com/a/171011/159388 by Aaron Hinni - -require 'rbconfig' - -module OS - def OS.os_name - case RbConfig::CONFIG['host_os'] - when /cygwin|mswin|mingw|bccwin|wince|emx/ - 'windows' - when /darwin/ - 'macos' - else - 'linux' - end - end -end -- cgit v1.2.3 From 8e4512ba482f03887f15ac7b978bffd8eb3b9840 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 2 May 2016 11:26:46 -0700 Subject: Reversed premature removal of a file --- src/ruby/tools/bin/protoc.rb | 2 ++ src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb | 2 ++ src/ruby/tools/os_check.rb | 45 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 src/ruby/tools/os_check.rb diff --git a/src/ruby/tools/bin/protoc.rb b/src/ruby/tools/bin/protoc.rb index 728a88b007..3a2a5b8dc9 100755 --- a/src/ruby/tools/bin/protoc.rb +++ b/src/ruby/tools/bin/protoc.rb @@ -30,6 +30,8 @@ require 'rbconfig' +require_relative '../os_check' + protoc_name = 'protoc' + RbConfig::CONFIG['EXEEXT'] protoc_path = File.join(File.dirname(__FILE__), diff --git a/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb b/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb index 814aef2446..4b296dedc7 100755 --- a/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb +++ b/src/ruby/tools/bin/protoc_grpc_ruby_plugin.rb @@ -30,6 +30,8 @@ require 'rbconfig' +require_relative '../os_check' + plugin_name = 'grpc_ruby_plugin' + RbConfig::CONFIG['EXEEXT'] plugin_path = File.join(File.dirname(__FILE__), diff --git a/src/ruby/tools/os_check.rb b/src/ruby/tools/os_check.rb new file mode 100644 index 0000000000..2677306457 --- /dev/null +++ b/src/ruby/tools/os_check.rb @@ -0,0 +1,45 @@ +# 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. + +# This is based on http://stackoverflow.com/a/171011/159388 by Aaron Hinni + +require 'rbconfig' + +module OS + def OS.os_name + case RbConfig::CONFIG['host_os'] + when /cygwin|mswin|mingw|bccwin|wince|emx/ + 'windows' + when /darwin/ + 'macos' + else + 'linux' + end + end +end -- cgit v1.2.3 From 08e1f755a3b456ce2e86db539068278407317a3c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 2 May 2016 12:07:21 -0700 Subject: fix typo --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index fc3c4a2b2b..50ba617cdb 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -407,7 +407,7 @@ namespace Grpc.Core.Internal /// /// Handler for unary response completion. /// - private void HandleUnaryResponse(bool sucess, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) + private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) { // NOTE: because this event is a result of batch containing GRPC_OP_RECV_STATUS_ON_CLIENT, // success will be always set to true. -- cgit v1.2.3 From 791e93ee2f66d6a29eb3e16f9d44ef29f1c0a83d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 1 Mar 2016 02:48:00 +0100 Subject: Always build the grpc library when building the ruby extension. --- src/ruby/ext/grpc/extconf.rb | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 82b6d313c8..07f7bb93b8 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -60,35 +60,27 @@ grpc_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) grpc_config = ENV['GRPC_CONFIG'] || 'opt' -if ENV.key?('GRPC_LIB_DIR') - grpc_lib_dir = File.join(grpc_root, ENV['GRPC_LIB_DIR']) -else - grpc_lib_dir = File.join(grpc_root, 'libs', grpc_config) -end - ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.7' -unless File.exist?(File.join(grpc_lib_dir, 'libgrpc.a')) or windows - ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs' - ENV['CC'] = RbConfig::CONFIG['CC'] - ENV['LD'] = ENV['CC'] +ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs' +ENV['CC'] = RbConfig::CONFIG['CC'] +ENV['LD'] = ENV['CC'] - ENV['AR'] = 'libtool -o' if RUBY_PLATFORM =~ /darwin/ +ENV['AR'] = 'libtool -o' if RUBY_PLATFORM =~ /darwin/ - ENV['EMBED_OPENSSL'] = 'true' - ENV['EMBED_ZLIB'] = 'true' - ENV['ARCH_FLAGS'] = RbConfig::CONFIG['ARCH_FLAG'] - ENV['ARCH_FLAGS'] = '-arch i386 -arch x86_64' if RUBY_PLATFORM =~ /darwin/ - ENV['CFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE' +ENV['EMBED_OPENSSL'] = 'true' +ENV['EMBED_ZLIB'] = 'true' +ENV['ARCH_FLAGS'] = RbConfig::CONFIG['ARCH_FLAG'] +ENV['ARCH_FLAGS'] = '-arch i386 -arch x86_64' if RUBY_PLATFORM =~ /darwin/ +ENV['CFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE' - output_dir = File.expand_path(RbConfig::CONFIG['topdir']) - grpc_lib_dir = File.join(output_dir, 'libs', grpc_config) - ENV['BUILDDIR'] = output_dir +output_dir = File.expand_path(RbConfig::CONFIG['topdir']) +grpc_lib_dir = File.join(output_dir, 'libs', grpc_config) +ENV['BUILDDIR'] = output_dir - puts 'Building internal gRPC into ' + grpc_lib_dir - system("make -j -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config}") - exit 1 unless $? == 0 -end +puts 'Building internal gRPC into ' + grpc_lib_dir +system("make -j -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config}") +exit 1 unless $? == 0 $CFLAGS << ' -I' + File.join(grpc_root, 'include') $LDFLAGS << ' ' + File.join(grpc_lib_dir, 'libgrpc.a') unless windows -- cgit v1.2.3 From 8a6efb7a42bc305d96163ef7c16167bf004cf1ab Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 2 May 2016 13:57:57 -0700 Subject: Node tools: use the right extension for running protoc on Windows --- src/node/tools/bin/protoc.js | 4 +++- src/node/tools/bin/protoc_plugin.js | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/node/tools/bin/protoc.js b/src/node/tools/bin/protoc.js index 0c6d7ce017..4d50c94b0f 100755 --- a/src/node/tools/bin/protoc.js +++ b/src/node/tools/bin/protoc.js @@ -43,7 +43,9 @@ var path = require('path'); var execFile = require('child_process').execFile; -var protoc = path.resolve(__dirname, 'protoc'); +var exe_ext = process.platform === 'win32' ? '.exe' : ''; + +var protoc = path.resolve(__dirname, 'protoc' + exe_ext); execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) { if (error) { diff --git a/src/node/tools/bin/protoc_plugin.js b/src/node/tools/bin/protoc_plugin.js index 0e0bb9406e..281ec0d85e 100755 --- a/src/node/tools/bin/protoc_plugin.js +++ b/src/node/tools/bin/protoc_plugin.js @@ -43,9 +43,11 @@ var path = require('path'); var execFile = require('child_process').execFile; -var protoc = path.resolve(__dirname, 'grpc_node_plugin'); +var exe_ext = process.platform === 'win32' ? '.exe' : ''; -execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) { +var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext); + +execFile(plugin, process.argv.slice(2), function(error, stdout, stderr) { if (error) { throw error; } -- cgit v1.2.3 From 777c26329cf1c1bfe06cd4d719a8fb9dbe24603f Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 2 May 2016 23:11:57 +0200 Subject: Properly using our build.yaml source of truth to generate our list of public APIs. --- tools/buildgen/plugins/list_api.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/buildgen/plugins/list_api.py b/tools/buildgen/plugins/list_api.py index ff937a0ab8..1fc4f4123c 100755 --- a/tools/buildgen/plugins/list_api.py +++ b/tools/buildgen/plugins/list_api.py @@ -64,12 +64,13 @@ def headers_under(directory): def mako_plugin(dictionary): apis = [] + headers = [] -# for lib in dictionary['libs']: -# if lib['name'] == 'grpc': -# apis.extend(list_c_apis(lib['public_headers'])) - apis.extend(list_c_apis(sorted(headers_under('include/grpc')))) + for lib in dictionary['libs']: + if lib['name'] in ['grpc', 'gpr']: + headers.extend(lib['public_headers']) + apis.extend(list_c_apis(sorted(set(headers)))) dictionary['c_apis'] = apis -- cgit v1.2.3