Merge pull request #9963 from ncteisen/error-arena-optimization
Error arena optimization
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 914aa1f..ec41db7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -663,6 +663,7 @@
add_dependencies(buildtests_cxx secure_sync_unary_ping_pong_test)
endif()
add_dependencies(buildtests_cxx server_builder_plugin_test)
+add_dependencies(buildtests_cxx server_builder_test)
add_dependencies(buildtests_cxx server_context_test_spouse_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx server_crash_test)
@@ -2086,6 +2087,7 @@
src/cpp/common/rpc_method.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
+ src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc
@@ -2151,6 +2153,7 @@
include/grpc++/grpc++.h
include/grpc++/health_check_service_interface.h
include/grpc++/impl/call.h
+ include/grpc++/impl/channel_argument_option.h
include/grpc++/impl/client_unary_call.h
include/grpc++/impl/codegen/core_codegen.h
include/grpc++/impl/grpc_library.h
@@ -2272,6 +2275,7 @@
src/cpp/common/rpc_method.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
+ src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc
@@ -2521,6 +2525,7 @@
include/grpc++/grpc++.h
include/grpc++/health_check_service_interface.h
include/grpc++/impl/call.h
+ include/grpc++/impl/channel_argument_option.h
include/grpc++/impl/client_unary_call.h
include/grpc++/impl/codegen/core_codegen.h
include/grpc++/impl/grpc_library.h
@@ -2943,6 +2948,7 @@
src/cpp/common/rpc_method.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
+ src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc
@@ -3008,6 +3014,7 @@
include/grpc++/grpc++.h
include/grpc++/health_check_service_interface.h
include/grpc++/impl/call.h
+ include/grpc++/impl/channel_argument_option.h
include/grpc++/impl/client_unary_call.h
include/grpc++/impl/codegen/core_codegen.h
include/grpc++/impl/grpc_library.h
@@ -9869,6 +9876,55 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(server_builder_test
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
+ test/cpp/server/server_builder_test.cc
+ third_party/googletest/src/gtest-all.cc
+)
+
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/echo_messages.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/echo.proto
+)
+
+target_include_directories(server_builder_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${BORINGSSL_ROOT_DIR}/include
+ PRIVATE ${PROTOBUF_ROOT_DIR}/src
+ PRIVATE ${BENCHMARK_ROOT_DIR}/include
+ PRIVATE ${ZLIB_ROOT_DIR}
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+ PRIVATE third_party/googletest/include
+ PRIVATE third_party/googletest
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(server_builder_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc++_test_util
+ grpc_test_util
+ gpr_test_util
+ grpc++
+ grpc
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(server_context_test_spouse_test
test/cpp/test/server_context_test_spouse_test.cc
third_party/googletest/src/gtest-all.cc
diff --git a/Makefile b/Makefile
index 82bfe6b..534728d 100644
--- a/Makefile
+++ b/Makefile
@@ -1106,6 +1106,7 @@
secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test
server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test
+server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
@@ -1519,6 +1520,7 @@
$(BINDIR)/$(CONFIG)/secure_auth_context_test \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
+ $(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
@@ -1633,6 +1635,7 @@
$(BINDIR)/$(CONFIG)/secure_auth_context_test \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
+ $(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
@@ -1998,6 +2001,8 @@
$(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_plugin_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 )
+ $(E) "[RUN] Testing server_builder_test"
+ $(Q) $(BINDIR)/$(CONFIG)/server_builder_test || ( echo test server_builder_test failed ; exit 1 )
$(E) "[RUN] Testing server_context_test_spouse_test"
$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
$(E) "[RUN] Testing server_crash_test"
@@ -3942,6 +3947,7 @@
src/cpp/common/rpc_method.cc \
src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \
+ src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \
@@ -3974,6 +3980,7 @@
include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \
+ include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \
@@ -4141,6 +4148,7 @@
src/cpp/common/rpc_method.cc \
src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \
+ src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \
@@ -4356,6 +4364,7 @@
include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \
+ include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \
@@ -4824,6 +4833,7 @@
src/cpp/common/rpc_method.cc \
src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \
+ src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \
@@ -4856,6 +4866,7 @@
include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \
+ include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \
@@ -15124,6 +15135,56 @@
endif
+SERVER_BUILDER_TEST_SRC = \
+ $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
+ test/cpp/server/server_builder_test.cc \
+
+SERVER_BUILDER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/server_builder_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/server_builder_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_server_builder_test: $(SERVER_BUILDER_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SERVER_BUILDER_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc
+
+
SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \
test/cpp/test/server_context_test_spouse_test.cc \
diff --git a/build.yaml b/build.yaml
index a2ec276..9c1e3e7 100644
--- a/build.yaml
+++ b/build.yaml
@@ -774,6 +774,7 @@
- include/grpc++/grpc++.h
- include/grpc++/health_check_service_interface.h
- include/grpc++/impl/call.h
+ - include/grpc++/impl/channel_argument_option.h
- include/grpc++/impl/client_unary_call.h
- include/grpc++/impl/codegen/core_codegen.h
- include/grpc++/impl/grpc_library.h
@@ -830,6 +831,7 @@
- src/cpp/common/rpc_method.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
+ - src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/dynamic_thread_pool.cc
- src/cpp/server/health/default_health_check_service.cc
@@ -3934,6 +3936,21 @@
- grpc
- gpr_test_util
- gpr
+- name: server_builder_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - src/proto/grpc/testing/echo_messages.proto
+ - src/proto/grpc/testing/echo.proto
+ - test/cpp/server/server_builder_test.cc
+ deps:
+ - grpc++_test_util
+ - grpc_test_util
+ - gpr_test_util
+ - grpc++
+ - grpc
+ - gpr
- name: server_context_test_spouse_test
gtest: true
build: test
diff --git a/examples/csharp/helloworld-from-cli/global.json b/examples/csharp/helloworld-from-cli/global.json
new file mode 100644
index 0000000..32ff399
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/global.json
@@ -0,0 +1,5 @@
+{
+ "sdk": {
+ "version": "1.0.0-preview2-003121"
+ }
+}
\ No newline at end of file
diff --git a/include/grpc++/impl/channel_argument_option.h b/include/grpc++/impl/channel_argument_option.h
new file mode 100644
index 0000000..057acc2
--- /dev/null
+++ b/include/grpc++/impl/channel_argument_option.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
+#define GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
+
+#include <map>
+#include <memory>
+
+#include <grpc++/impl/server_builder_option.h>
+#include <grpc++/support/channel_arguments.h>
+
+namespace grpc {
+
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+ const grpc::string &name, const grpc::string &value);
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+ const grpc::string &name, int value);
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 2ac2f0a..d707100 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -39,6 +39,7 @@
#include <memory>
#include <vector>
+#include <grpc++/impl/channel_argument_option.h>
#include <grpc++/impl/server_builder_option.h>
#include <grpc++/impl/server_builder_plugin.h>
#include <grpc++/support/config.h>
@@ -130,6 +131,13 @@
/// Only useful if this is a Synchronous server.
ServerBuilder& SetSyncServerOption(SyncServerOption option, int value);
+ /// Add a channel argument (an escape hatch to tuning core library parameters
+ /// directly)
+ template <class T>
+ ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) {
+ return SetOption(MakeChannelArgumentOption(arg, value));
+ }
+
/// Tries to bind \a server to the given \a addr.
///
/// It can be invoked multiple times.
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index c6851b0..7cdbe30 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -370,7 +370,7 @@
internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
}
} else if (gpr_ref_is_unique(&in->refs)) {
- return in;
+ out = in;
} else {
uint8_t new_arena_capacity = in->arena_capacity;
// the returned err will be added to, so we ensure this is room to avoid
diff --git a/src/cpp/server/channel_argument_option.cc b/src/cpp/server/channel_argument_option.cc
new file mode 100644
index 0000000..723f968
--- /dev/null
+++ b/src/cpp/server/channel_argument_option.cc
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#include <grpc++/impl/channel_argument_option.h>
+
+namespace grpc {
+
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+ const grpc::string &name, const grpc::string &value) {
+ class StringOption final : public ServerBuilderOption {
+ public:
+ StringOption(const grpc::string &name, const grpc::string &value)
+ : name_(name), value_(value) {}
+
+ virtual void UpdateArguments(ChannelArguments *args) override {
+ args->SetString(name_, value_);
+ }
+ virtual void UpdatePlugins(
+ std::vector<std::unique_ptr<ServerBuilderPlugin>> *plugins) override {}
+
+ private:
+ const grpc::string name_;
+ const grpc::string value_;
+ };
+ return std::unique_ptr<ServerBuilderOption>(new StringOption(name, value));
+}
+
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+ const grpc::string &name, int value) {
+ class IntOption final : public ServerBuilderOption {
+ public:
+ IntOption(const grpc::string &name, int value)
+ : name_(name), value_(value) {}
+
+ virtual void UpdateArguments(ChannelArguments *args) override {
+ args->SetInt(name_, value_);
+ }
+ virtual void UpdatePlugins(
+ std::vector<std::unique_ptr<ServerBuilderPlugin>> *plugins) override {}
+
+ private:
+ const grpc::string name_;
+ const int value_;
+ };
+ return std::unique_ptr<ServerBuilderOption>(new IntOption(name, value));
+}
+
+} // namespace grpc
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 00a90bb..4eb4b5a 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -323,9 +323,14 @@
}
}
+ bool added_port = false;
for (auto port = ports_.begin(); port != ports_.end(); port++) {
int r = server->AddListeningPort(port->addr, port->creds.get());
- if (!r) return nullptr;
+ if (!r) {
+ if (added_port) server->Shutdown();
+ return nullptr;
+ }
+ added_port = true;
if (port->selected_port != nullptr) {
*port->selected_port = r;
}
@@ -333,6 +338,7 @@
auto cqs_data = cqs_.empty() ? nullptr : &cqs_[0];
if (!server->Start(cqs_data, cqs_.size())) {
+ if (added_port) server->Shutdown();
return nullptr;
}
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 9e11a8a..e874892 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -534,7 +534,7 @@
void Server::ShutdownInternal(gpr_timespec deadline) {
std::unique_lock<std::mutex> lock(mu_);
- if (started_ && !shutdown_) {
+ if (!shutdown_) {
shutdown_ = true;
/// The completion queue to use for server shutdown completion notification
diff --git a/src/csharp/global.json b/src/csharp/global.json
new file mode 100644
index 0000000..32ff399
--- /dev/null
+++ b/src/csharp/global.json
@@ -0,0 +1,5 @@
+{
+ "sdk": {
+ "version": "1.0.0-preview2-003121"
+ }
+}
\ No newline at end of file
diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
index 430f3fa..058ce15 100644
--- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include
+++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
@@ -1,7 +1,11 @@
# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
RUN apt-get update && apt-get install -y curl libunwind8 gettext
-RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
-RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.0-preview2-003121
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin
# Trigger the population of the local package cache
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index f25bcd2..014e2b9 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -37,6 +37,7 @@
#include <string.h>
#include <sstream>
+#include <grpc++/channel.h>
#include <grpc++/support/channel_arguments.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
@@ -55,11 +56,35 @@
#include "src/core/lib/transport/transport_impl.h"
}
+#include "src/cpp/client/create_channel_internal.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/helpers.h"
#include "third_party/benchmark/include/benchmark/benchmark.h"
auto &force_library_initialization = Library::get();
+void BM_Zalloc(benchmark::State &state) {
+ // speed of light for call creation is zalloc, so benchmark a few interesting
+ // sizes
+ size_t sz = state.range(0);
+ while (state.KeepRunning()) {
+ gpr_free(gpr_zalloc(sz));
+ }
+}
+BENCHMARK(BM_Zalloc)
+ ->Arg(64)
+ ->Arg(128)
+ ->Arg(256)
+ ->Arg(512)
+ ->Arg(1024)
+ ->Arg(1536)
+ ->Arg(2048)
+ ->Arg(3072)
+ ->Arg(4096)
+ ->Arg(5120)
+ ->Arg(6144)
+ ->Arg(7168);
+
class BaseChannelFixture {
public:
BaseChannelFixture(grpc_channel *channel) : channel_(channel) {}
@@ -105,6 +130,33 @@
BENCHMARK_TEMPLATE(BM_CallCreateDestroy, InsecureChannel);
BENCHMARK_TEMPLATE(BM_CallCreateDestroy, LameChannel);
+static void *tag(int i) {
+ return reinterpret_cast<void *>(static_cast<intptr_t>(i));
+}
+
+static void BM_LameChannelCallCreateCpp(benchmark::State &state) {
+ TrackCounters track_counters;
+ auto stub =
+ grpc::testing::EchoTestService::NewStub(grpc::CreateChannelInternal(
+ "", grpc_lame_client_channel_create(
+ "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah")));
+ grpc::CompletionQueue cq;
+ grpc::testing::EchoRequest send_request;
+ grpc::testing::EchoResponse recv_response;
+ grpc::Status recv_status;
+ while (state.KeepRunning()) {
+ grpc::ClientContext cli_ctx;
+ auto reader = stub->AsyncEcho(&cli_ctx, send_request, &cq);
+ reader->Finish(&recv_response, &recv_status, tag(0));
+ void *t;
+ bool ok;
+ GPR_ASSERT(cq.Next(&t, &ok));
+ GPR_ASSERT(ok);
+ }
+ track_counters.Finish(state);
+}
+BENCHMARK(BM_LameChannelCallCreateCpp);
+
static void FilterDestroy(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
gpr_free(arg);
diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc
index 947e81f..d277c59 100644
--- a/test/cpp/microbenchmarks/helpers.cc
+++ b/test/cpp/microbenchmarks/helpers.cc
@@ -45,6 +45,7 @@
void TrackCounters::AddToLabel(std::ostream &out, benchmark::State &state) {
#ifdef GPR_LOW_LEVEL_COUNTERS
+ grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot();
out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&gpr_mu_locks) -
mu_locks_at_start_) /
(double)state.iterations())
@@ -55,11 +56,10 @@
<< " atm_add/iter:"
<< ((double)(gpr_atm_no_barrier_load(&gpr_counter_atm_add) -
atm_add_at_start_) /
- (double)state.iterations());
-#endif
- grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot();
- out << " allocs/iter:"
+ (double)state.iterations())
+ << " allocs/iter:"
<< ((double)(counters_at_end.total_allocs_absolute -
counters_at_start_.total_allocs_absolute) /
(double)state.iterations());
+#endif
}
diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h
index 42a8fba..2829a46 100644
--- a/test/cpp/microbenchmarks/helpers.h
+++ b/test/cpp/microbenchmarks/helpers.h
@@ -84,8 +84,8 @@
gpr_atm_no_barrier_load(&gpr_counter_atm_cas);
const size_t atm_add_at_start_ =
gpr_atm_no_barrier_load(&gpr_counter_atm_add);
-#endif
grpc_memory_counters counters_at_start_ = grpc_memory_counters_snapshot();
+#endif
};
#endif
diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc
new file mode 100644
index 0000000..1d9eda1
--- /dev/null
+++ b/test/cpp/server/server_builder_test.cc
@@ -0,0 +1,96 @@
+/*
+ *
+ * Copyright 2017, 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.
+ *
+ */
+
+#include <grpc++/impl/codegen/config.h>
+#include <gtest/gtest.h>
+
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+
+namespace grpc {
+namespace {
+
+testing::EchoTestService::Service g_service;
+
+grpc::string MakePort() {
+ std::ostringstream s;
+ int p = grpc_pick_unused_port_or_die();
+ s << "localhost:" << p;
+ return s.str();
+}
+
+grpc::string g_port = MakePort();
+
+TEST(ServerBuilderTest, NoOp) { ServerBuilder b; }
+
+TEST(ServerBuilderTest, CreateServerNoPorts) {
+ ServerBuilder().RegisterService(&g_service).BuildAndStart()->Shutdown();
+}
+
+TEST(ServerBuilderTest, CreateServerOnePort) {
+ ServerBuilder()
+ .RegisterService(&g_service)
+ .AddListeningPort(g_port, InsecureServerCredentials())
+ .BuildAndStart()
+ ->Shutdown();
+}
+
+TEST(ServerBuilderTest, CreateServerRepeatedPort) {
+ ServerBuilder()
+ .RegisterService(&g_service)
+ .AddListeningPort(g_port, InsecureServerCredentials())
+ .AddListeningPort(g_port, InsecureServerCredentials())
+ .BuildAndStart()
+ ->Shutdown();
+}
+
+TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) {
+ EXPECT_EQ(ServerBuilder()
+ .RegisterService(&g_service)
+ .AddListeningPort(g_port, InsecureServerCredentials())
+ .AddListeningPort(g_port, InsecureServerCredentials())
+ .AddChannelArgument(GRPC_ARG_ALLOW_REUSEPORT, 0)
+ .BuildAndStart(),
+ nullptr);
+}
+
+} // namespace
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
index 9163982..c26c9a2 100644
--- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
@@ -99,8 +99,12 @@
# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
RUN apt-get update && apt-get install -y curl libunwind8 gettext
-RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
-RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.0-preview2-003121
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin
# Trigger the population of the local package cache
diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
index 9163982..c26c9a2 100644
--- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
+++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
@@ -99,8 +99,12 @@
# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
RUN apt-get update && apt-get install -y curl libunwind8 gettext
-RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
-RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.0-preview2-003121
+RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
+RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
+# dotnet-dev-1.0.1
+RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
+RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin
# Trigger the population of the local package cache
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 9652597..a181def 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -803,6 +803,7 @@
include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \
+include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/async_stream.h \
include/grpc++/impl/codegen/async_unary_call.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index d98475f..7595081 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -803,6 +803,7 @@
include/grpc++/grpc++.h \
include/grpc++/health_check_service_interface.h \
include/grpc++/impl/call.h \
+include/grpc++/impl/channel_argument_option.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/async_stream.h \
include/grpc++/impl/codegen/async_unary_call.h \
@@ -914,6 +915,7 @@
src/cpp/common/secure_create_auth_context.cc \
src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \
+src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.h \
diff --git a/tools/internal_ci/linux/grpc_master.cfg b/tools/internal_ci/linux/grpc_master.cfg
index 7536a91..6c94c3b 100644
--- a/tools/internal_ci/linux/grpc_master.cfg
+++ b/tools/internal_ci/linux/grpc_master.cfg
@@ -34,6 +34,6 @@
timeout_mins: 240
action {
define_artifacts {
- regex: "**/sponge_log.xml"
+ regex: "**/*sponge_log.xml"
}
}
diff --git a/tools/internal_ci/linux/grpc_master.sh b/tools/internal_ci/linux/grpc_master.sh
index d01d637..9ecf123 100755
--- a/tools/internal_ci/linux/grpc_master.sh
+++ b/tools/internal_ci/linux/grpc_master.sh
@@ -45,6 +45,8 @@
git submodule update --init
+# download docker images from dockerhub
+export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests.py -l c -t -x sponge_log.xml || FAILED="true"
# kill port_server.py to prevent the build from hanging
diff --git a/tools/internal_ci/linux/grpc_master_sanitizers.cfg b/tools/internal_ci/linux/grpc_master_sanitizers.cfg
new file mode 100644
index 0000000..a2a9407
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_master_sanitizers.cfg
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/linux/grpc_master_sanitizers.sh"
+timeout_mins: 1440
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
diff --git a/tools/internal_ci/linux/grpc_master_sanitizers.sh b/tools/internal_ci/linux/grpc_master_sanitizers.sh
new file mode 100644
index 0000000..2cd0efe
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_master_sanitizers.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -ex
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+git submodule update --init
+
+# download docker images from dockerhub
+export DOCKERHUB_ORGANIZATION=grpctesting
+tools/run_tests/run_tests_matrix.sh -f sanitizers linux
diff --git a/tools/internal_ci/linux/grpc_portability.cfg b/tools/internal_ci/linux/grpc_portability.cfg
new file mode 100644
index 0000000..0c25661
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_portability.cfg
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/linux/grpc_portability.sh"
+timeout_mins: 360
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
diff --git a/tools/internal_ci/linux/grpc_portability.sh b/tools/internal_ci/linux/grpc_portability.sh
new file mode 100644
index 0000000..c7ac3bb
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_portability.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -ex
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+git submodule update --init
+
+# download docker images from dockerhub
+export DOCKERHUB_ORGANIZATION=grpctesting
+tools/run_tests/run_tests_matrix.sh -f portability linux
diff --git a/tools/internal_ci/linux/grpc_portability_build_only.cfg b/tools/internal_ci/linux/grpc_portability_build_only.cfg
index ce5be5a..4d3dda4 100644
--- a/tools/internal_ci/linux/grpc_portability_build_only.cfg
+++ b/tools/internal_ci/linux/grpc_portability_build_only.cfg
@@ -34,6 +34,6 @@
timeout_mins: 180
action {
define_artifacts {
- regex: "**report**.xml"
+ regex: "**/*sponge_log.xml"
}
}
diff --git a/tools/internal_ci/linux/grpc_portability_build_only.sh b/tools/internal_ci/linux/grpc_portability_build_only.sh
index ebdc0e8..edd6f91 100644
--- a/tools/internal_ci/linux/grpc_portability_build_only.sh
+++ b/tools/internal_ci/linux/grpc_portability_build_only.sh
@@ -37,5 +37,4 @@
# download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting
-
-tools/jenkins/run_jenkins_matrix.sh -f portability linux --build_only
+tools/run_tests/run_tests_matrix.sh -f portability linux --build_only
diff --git a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg
index 511f2d6..1abf6ac 100644
--- a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg
+++ b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg
@@ -34,6 +34,6 @@
timeout_mins: 30
action {
define_artifacts {
- regex: "**/sponge_log.xml"
+ regex: "**/*sponge_log.xml"
}
}
diff --git a/tools/internal_ci/windows/grpc_master.cfg b/tools/internal_ci/windows/grpc_master.cfg
index f90af11..21a9d6a 100644
--- a/tools/internal_ci/windows/grpc_master.cfg
+++ b/tools/internal_ci/windows/grpc_master.cfg
@@ -34,6 +34,6 @@
timeout_mins: 360
action {
define_artifacts {
- regex: "**sponge_log.xml"
+ regex: "**/*sponge_log.xml"
}
}
diff --git a/tools/internal_ci/windows/grpc_portability_master.bat b/tools/internal_ci/windows/grpc_portability_master.bat
new file mode 100644
index 0000000..b98c701
--- /dev/null
+++ b/tools/internal_ci/windows/grpc_portability_master.bat
@@ -0,0 +1,43 @@
+@rem Copyright 2017, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+@rem make sure msys binaries are preferred over cygwin binaries
+@rem set path to python 2.7
+set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH%
+
+@rem enter repo root
+cd /d %~dp0\..\..\..
+
+git submodule update --init
+
+python tools/run_tests/run_tests_matrix.py -f portability windows -j 1 --inner_jobs 8 || goto :error
+goto :EOF
+
+:error
+exit /b %errorlevel%
diff --git a/tools/internal_ci/windows/grpc_portability_master.cfg b/tools/internal_ci/windows/grpc_portability_master.cfg
new file mode 100644
index 0000000..10d8e985
--- /dev/null
+++ b/tools/internal_ci/windows/grpc_portability_master.cfg
@@ -0,0 +1,39 @@
+# Copyright 2017, 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/windows/grpc_portability_master.bat"
+timeout_mins: 360
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
diff --git a/tools/profiling/microbenchmarks/bm2bq.py b/tools/profiling/microbenchmarks/bm2bq.py
index a83b3be..ae59332 100755
--- a/tools/profiling/microbenchmarks/bm2bq.py
+++ b/tools/profiling/microbenchmarks/bm2bq.py
@@ -36,7 +36,7 @@
import sys
import json
import csv
-import os
+import bm_json
columns = [
('jenkins_build', 'integer'),
@@ -88,147 +88,8 @@
writer = csv.DictWriter(sys.stdout, [c for c,t in columns])
-bm_specs = {
- 'BM_UnaryPingPong': {
- 'tpl': ['fixture', 'client_mutator', 'server_mutator'],
- 'dyn': ['request_size', 'response_size'],
- },
- 'BM_PumpStreamClientToServer': {
- 'tpl': ['fixture'],
- 'dyn': ['request_size'],
- },
- 'BM_PumpStreamServerToClient': {
- 'tpl': ['fixture'],
- 'dyn': ['request_size'],
- },
- 'BM_StreamingPingPong': {
- 'tpl': ['fixture', 'client_mutator', 'server_mutator'],
- 'dyn': ['request_size', 'request_count'],
- },
- 'BM_StreamingPingPongMsgs': {
- 'tpl': ['fixture', 'client_mutator', 'server_mutator'],
- 'dyn': ['request_size'],
- },
- 'BM_PumpStreamServerToClient_Trickle': {
- 'tpl': [],
- 'dyn': ['request_size', 'bandwidth_kilobits'],
- },
- 'BM_ErrorStringOnNewError': {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
- 'BM_ErrorStringRepeatedly': {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
- 'BM_ErrorGetStatus': {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
- 'BM_ErrorGetStatusCode': {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
- 'BM_ErrorHttpError': {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
- 'BM_HasClearGrpcStatus': {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
- 'BM_IsolatedFilter' : {
- 'tpl': ['fixture', 'client_mutator'],
- 'dyn': [],
- },
- 'BM_HpackEncoderEncodeHeader' : {
- 'tpl': ['fixture'],
- 'dyn': ['end_of_stream', 'request_size'],
- },
- 'BM_HpackParserParseHeader' : {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
- 'BM_CallCreateDestroy' : {
- 'tpl': ['fixture'],
- 'dyn': [],
- },
-}
-
-def numericalize(s):
- if not s: return ''
- if s[-1] == 'k':
- return int(s[:-1]) * 1024
- if s[-1] == 'M':
- return int(s[:-1]) * 1024 * 1024
- if 0 <= (ord(s[-1]) - ord('0')) <= 9:
- return int(s)
- assert 'not a number: %s' % s
-
-def parse_name(name):
- if '<' not in name and '/' not in name and name not in bm_specs:
- return {'name': name}
- rest = name
- out = {}
- tpl_args = []
- dyn_args = []
- if '<' in rest:
- tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')]
- arg = ''
- nesting = 0
- for c in tpl_bit:
- if c == '<':
- nesting += 1
- arg += c
- elif c == '>':
- nesting -= 1
- arg += c
- elif c == ',':
- if nesting == 0:
- tpl_args.append(arg.strip())
- arg = ''
- else:
- arg += c
- else:
- arg += c
- tpl_args.append(arg.strip())
- rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:]
- if '/' in rest:
- s = rest.split('/')
- rest = s[0]
- dyn_args = s[1:]
- name = rest
- assert name in bm_specs, 'bm_specs needs to be expanded for %s' % name
- assert len(dyn_args) == len(bm_specs[name]['dyn'])
- assert len(tpl_args) == len(bm_specs[name]['tpl'])
- out['name'] = name
- out.update(dict((k, numericalize(v)) for k, v in zip(bm_specs[name]['dyn'], dyn_args)))
- out.update(dict(zip(bm_specs[name]['tpl'], tpl_args)))
- return out
-
-for bm in js['benchmarks']:
- context = js['context']
- if 'label' in bm:
- labels_list = [s.split(':') for s in bm['label'].strip().split(' ') if len(s) and s[0] != '#']
- for el in labels_list:
- el[0] = el[0].replace('/iter', '_per_iteration')
- labels = dict(labels_list)
- else:
- labels = {}
- row = {
- 'jenkins_build': os.environ.get('BUILD_NUMBER', ''),
- 'jenkins_job': os.environ.get('JOB_NAME', ''),
- }
- row.update(context)
- row.update(bm)
- row.update(parse_name(row['name']))
- row.update(labels)
+for row in bm_json.expand_json(js, js2):
if 'label' in row:
del row['label']
- if js2:
- for bm2 in js2['benchmarks']:
- if bm['name'] == bm2['name']:
- row['cpu_time'] = bm2['cpu_time']
- row['real_time'] = bm2['real_time']
- row['iterations'] = bm2['iterations']
+ del row['cpp_name']
writer.writerow(row)
diff --git a/tools/profiling/microbenchmarks/bm_diff.py b/tools/profiling/microbenchmarks/bm_diff.py
new file mode 100755
index 0000000..59cc2d0
--- /dev/null
+++ b/tools/profiling/microbenchmarks/bm_diff.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python2.7
+# Copyright 2017, 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.
+
+import sys
+import json
+import bm_json
+import tabulate
+
+with open(sys.argv[1]) as f:
+ js_new_ctr = json.loads(f.read())
+with open(sys.argv[2]) as f:
+ js_new_opt = json.loads(f.read())
+with open(sys.argv[3]) as f:
+ js_old_ctr = json.loads(f.read())
+with open(sys.argv[4]) as f:
+ js_old_opt = json.loads(f.read())
+
+new = {}
+old = {}
+
+for row in bm_json.expand_json(js_new_ctr, js_new_opt):
+ new[row['cpp_name']] = row
+for row in bm_json.expand_json(js_old_ctr, js_old_opt):
+ old[row['cpp_name']] = row
+
+def changed_ratio(n, o):
+ return float(n-o)/float(o)
+
+def min_change(pct):
+ return lambda n, o: abs(changed_ratio(n,o)) > pct/100.0
+
+_INTERESTING = (
+ ('cpu_time', min_change(10)),
+ ('real_time', min_change(10)),
+ ('locks_per_iteration', min_change(5)),
+ ('allocs_per_iteration', min_change(5)),
+ ('writes_per_iteration', min_change(5)),
+ ('atm_cas_per_iteration', min_change(1)),
+ ('atm_add_per_iteration', min_change(5)),
+)
+
+changed = []
+for fld, chk in _INTERESTING:
+ for bm in new.keys():
+ if bm not in old: continue
+ n = new[bm]
+ o = old[bm]
+ if fld not in n or fld not in o: continue
+ if chk(n[fld], o[fld]):
+ changed.append((fld, chk))
+ break
+
+headers = ['Benchmark'] + [c[0] for c in changed] + ['Details']
+rows = []
+for bm in sorted(new.keys()):
+ if bm not in old: continue
+ row = [bm]
+ any_changed = False
+ n = new[bm]
+ o = old[bm]
+ details = ''
+ for fld, chk in _INTERESTING:
+ if fld not in n or fld not in o: continue
+ if chk(n[fld], o[fld]):
+ row.append(changed_ratio(n[fld], o[fld]))
+ if details: details += ', '
+ details += '%s:%r-->%r' % (fld, o[fld], n[fld])
+ any_changed = True
+ else:
+ row.append('')
+ if any_changed:
+ row.append(details)
+ rows.append(row)
+print tabulate.tabulate(rows, headers=headers, floatfmt='+.2f')
diff --git a/tools/profiling/microbenchmarks/bm_json.py b/tools/profiling/microbenchmarks/bm_json.py
new file mode 100644
index 0000000..6048237
--- /dev/null
+++ b/tools/profiling/microbenchmarks/bm_json.py
@@ -0,0 +1,180 @@
+# Copyright 2017, 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.
+
+import os
+
+_BM_SPECS = {
+ 'BM_UnaryPingPong': {
+ 'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+ 'dyn': ['request_size', 'response_size'],
+ },
+ 'BM_PumpStreamClientToServer': {
+ 'tpl': ['fixture'],
+ 'dyn': ['request_size'],
+ },
+ 'BM_PumpStreamServerToClient': {
+ 'tpl': ['fixture'],
+ 'dyn': ['request_size'],
+ },
+ 'BM_StreamingPingPong': {
+ 'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+ 'dyn': ['request_size', 'request_count'],
+ },
+ 'BM_StreamingPingPongMsgs': {
+ 'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+ 'dyn': ['request_size'],
+ },
+ 'BM_PumpStreamServerToClient_Trickle': {
+ 'tpl': [],
+ 'dyn': ['request_size', 'bandwidth_kilobits'],
+ },
+ 'BM_ErrorStringOnNewError': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_ErrorStringRepeatedly': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_ErrorGetStatus': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_ErrorGetStatusCode': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_ErrorHttpError': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_HasClearGrpcStatus': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_IsolatedFilter': {
+ 'tpl': ['fixture', 'client_mutator'],
+ 'dyn': [],
+ },
+ 'BM_HpackEncoderEncodeHeader': {
+ 'tpl': ['fixture'],
+ 'dyn': ['end_of_stream', 'request_size'],
+ },
+ 'BM_HpackParserParseHeader': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_CallCreateDestroy': {
+ 'tpl': ['fixture'],
+ 'dyn': [],
+ },
+ 'BM_Zalloc': {
+ 'tpl': [],
+ 'dyn': ['request_size'],
+ },
+}
+
+def numericalize(s):
+ if not s: return ''
+ if s[-1] == 'k':
+ return int(s[:-1]) * 1024
+ if s[-1] == 'M':
+ return int(s[:-1]) * 1024 * 1024
+ if 0 <= (ord(s[-1]) - ord('0')) <= 9:
+ return int(s)
+ assert 'not a number: %s' % s
+
+def parse_name(name):
+ cpp_name = name
+ if '<' not in name and '/' not in name and name not in _BM_SPECS:
+ return {'name': name, 'cpp_name': name}
+ rest = name
+ out = {}
+ tpl_args = []
+ dyn_args = []
+ if '<' in rest:
+ tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')]
+ arg = ''
+ nesting = 0
+ for c in tpl_bit:
+ if c == '<':
+ nesting += 1
+ arg += c
+ elif c == '>':
+ nesting -= 1
+ arg += c
+ elif c == ',':
+ if nesting == 0:
+ tpl_args.append(arg.strip())
+ arg = ''
+ else:
+ arg += c
+ else:
+ arg += c
+ tpl_args.append(arg.strip())
+ rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:]
+ if '/' in rest:
+ s = rest.split('/')
+ rest = s[0]
+ dyn_args = s[1:]
+ name = rest
+ assert name in _BM_SPECS, '_BM_SPECS needs to be expanded for %s' % name
+ assert len(dyn_args) == len(_BM_SPECS[name]['dyn'])
+ assert len(tpl_args) == len(_BM_SPECS[name]['tpl'])
+ out['name'] = name
+ out['cpp_name'] = cpp_name
+ out.update(dict((k, numericalize(v)) for k, v in zip(_BM_SPECS[name]['dyn'], dyn_args)))
+ out.update(dict(zip(_BM_SPECS[name]['tpl'], tpl_args)))
+ return out
+
+def expand_json(js, js2 = None):
+ for bm in js['benchmarks']:
+ context = js['context']
+ if 'label' in bm:
+ labels_list = [s.split(':') for s in bm['label'].strip().split(' ') if len(s) and s[0] != '#']
+ for el in labels_list:
+ el[0] = el[0].replace('/iter', '_per_iteration')
+ labels = dict(labels_list)
+ else:
+ labels = {}
+ row = {
+ 'jenkins_build': os.environ.get('BUILD_NUMBER', ''),
+ 'jenkins_job': os.environ.get('JOB_NAME', ''),
+ }
+ row.update(context)
+ row.update(bm)
+ row.update(parse_name(row['name']))
+ row.update(labels)
+ if js2:
+ for bm2 in js2['benchmarks']:
+ if bm['name'] == bm2['name']:
+ row['cpu_time'] = bm2['cpu_time']
+ row['real_time'] = bm2['real_time']
+ row['iterations'] = bm2['iterations']
+ yield row
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index fc6b8f3..767c2b2 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -3584,6 +3584,30 @@
"gpr_test_util",
"grpc",
"grpc++",
+ "grpc++_test_util",
+ "grpc_test_util"
+ ],
+ "headers": [
+ "src/proto/grpc/testing/echo.grpc.pb.h",
+ "src/proto/grpc/testing/echo.pb.h",
+ "src/proto/grpc/testing/echo_messages.grpc.pb.h",
+ "src/proto/grpc/testing/echo_messages.pb.h"
+ ],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "server_builder_test",
+ "src": [
+ "test/cpp/server/server_builder_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc++",
"grpc++_test",
"grpc_test_util"
],
@@ -8398,6 +8422,7 @@
"include/grpc++/grpc++.h",
"include/grpc++/health_check_service_interface.h",
"include/grpc++/impl/call.h",
+ "include/grpc++/impl/channel_argument_option.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/codegen/core_codegen.h",
"include/grpc++/impl/grpc_library.h",
@@ -8454,6 +8479,7 @@
"include/grpc++/grpc++.h",
"include/grpc++/health_check_service_interface.h",
"include/grpc++/impl/call.h",
+ "include/grpc++/impl/channel_argument_option.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/codegen/core_codegen.h",
"include/grpc++/impl/grpc_library.h",
@@ -8503,6 +8529,7 @@
"src/cpp/common/rpc_method.cc",
"src/cpp/common/version_cc.cc",
"src/cpp/server/async_generic_service.cc",
+ "src/cpp/server/channel_argument_option.cc",
"src/cpp/server/create_default_thread_pool.cc",
"src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/dynamic_thread_pool.h",
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 05f509e..f9e2a19 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -3513,6 +3513,28 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "server_builder_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ]
+ },
+ {
+ "args": [],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
"name": "server_context_test_spouse_test",
"platforms": [
"linux",
diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py
index f304743..5d812f2 100755
--- a/tools/run_tests/python_utils/jobset.py
+++ b/tools/run_tests/python_utils/jobset.py
@@ -476,13 +476,13 @@
skip_jobs=False,
quiet_success=False):
if skip_jobs:
- results = {}
+ resultset = {}
skipped_job_result = JobResult()
skipped_job_result.state = 'SKIPPED'
for job in cmdlines:
message('SKIPPED', job.shortname, do_newline=True)
- results[job.shortname] = [skipped_job_result]
- return results
+ resultset[job.shortname] = [skipped_job_result]
+ return 0, resultset
js = Jobset(check_cancelled,
maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS,
newline_on_success, travis, stop_on_failure, add_env,
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 0d5bec1..161fa81 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -501,6 +501,28 @@
return docker_cmdline
+def manual_cmdline(docker_cmdline):
+ """Returns docker cmdline adjusted for manual invocation."""
+ print_cmdline = []
+ for item in docker_cmdline:
+ if item.startswith('--name='):
+ continue
+ # add quotes when necessary
+ if any(character.isspace() for character in item):
+ item = "\"%s\"" % item
+ print_cmdline.append(item)
+ return ' '.join(print_cmdline)
+
+
+def write_cmdlog_maybe(cmdlog, filename):
+ """Returns docker cmdline adjusted for manual invocation."""
+ if cmdlog:
+ with open(filename, 'w') as logfile:
+ logfile.write('#!/bin/bash\n')
+ logfile.writelines("%s\n" % line for line in cmdlog)
+ print('Command log written to file %s' % filename)
+
+
def bash_cmdline(cmdline):
"""Creates bash -c cmdline from args list."""
# Use login shell:
@@ -551,7 +573,8 @@
def cloud_to_prod_jobspec(language, test_case, server_host_name,
- server_host_detail, docker_image=None, auth=False):
+ server_host_detail, docker_image=None, auth=False,
+ manual_cmd_log=None):
"""Creates jobspec for cloud-to-prod interop test"""
container_name = None
cmdargs = [
@@ -576,7 +599,9 @@
cwd=cwd,
environ=environ,
docker_args=['--net=host',
- '--name', container_name])
+ '--name=%s' % container_name])
+ if manual_cmd_log is not None:
+ manual_cmd_log.append(manual_cmdline(cmdline))
cwd = None
environ = None
@@ -597,7 +622,8 @@
def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
- server_port, docker_image=None, insecure=False):
+ server_port, docker_image=None, insecure=False,
+ manual_cmd_log=None):
"""Creates jobspec for cloud-to-cloud interop test"""
interop_only_options = [
'--server_host_override=foo.test.google.fr',
@@ -628,7 +654,9 @@
environ=environ,
cwd=cwd,
docker_args=['--net=host',
- '--name', container_name])
+ '--name=%s' % container_name])
+ if manual_cmd_log is not None:
+ manual_cmd_log.append(manual_cmdline(cmdline))
cwd = None
test_job = jobset.JobSpec(
@@ -646,7 +674,7 @@
return test_job
-def server_jobspec(language, docker_image, insecure=False):
+def server_jobspec(language, docker_image, insecure=False, manual_cmd_log=None):
"""Create jobspec for running a server"""
container_name = dockerjob.random_name('interop_server_%s' % language.safename)
cmdline = bash_cmdline(
@@ -676,7 +704,9 @@
cwd=language.server_cwd,
environ=environ,
docker_args=port_args +
- ['--name', container_name])
+ ['--name=%s' % container_name])
+ if manual_cmd_log is not None:
+ manual_cmd_log.append(manual_cmdline(docker_cmdline))
server_job = jobset.JobSpec(
cmdline=docker_cmdline,
environ=environ,
@@ -806,6 +836,14 @@
action='store_const',
const=True,
help='Allow flaky tests to show as passing (re-runs failed tests up to five times)')
+argp.add_argument('--manual_run',
+ default=False,
+ action='store_const',
+ const=True,
+ help='Prepare things for running interop tests manually. ' +
+ 'Preserve docker images after building them and skip '
+ 'actually running the tests. Only print commands to run by ' +
+ 'hand.')
argp.add_argument('--http2_interop',
default=False,
action='store_const',
@@ -837,6 +875,10 @@
print('copied to the docker environment.')
time.sleep(5)
+if args.manual_run and not args.use_docker:
+ print('--manual_run is only supported with --use_docker option enabled.')
+ sys.exit(1)
+
if not args.use_docker and servers:
print('Running interop servers is only supported with --use_docker option enabled.')
sys.exit(1)
@@ -887,24 +929,36 @@
dockerjob.remove_image(image, skip_nonexistent=True)
sys.exit(1)
+server_manual_cmd_log = [] if args.manual_run else None
+client_manual_cmd_log = [] if args.manual_run else None
+
# Start interop servers.
-server_jobs={}
-server_addresses={}
+server_jobs = {}
+server_addresses = {}
try:
for s in servers:
lang = str(s)
spec = server_jobspec(_LANGUAGES[lang], docker_images.get(lang),
- args.insecure)
- job = dockerjob.DockerJob(spec)
- server_jobs[lang] = job
- server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT))
+ args.insecure, manual_cmd_log=server_manual_cmd_log)
+ if not args.manual_run:
+ job = dockerjob.DockerJob(spec)
+ server_jobs[lang] = job
+ server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT))
+ else:
+ # don't run the server, set server port to a placeholder value
+ server_addresses[lang] = ('localhost', '${SERVER_PORT}')
if args.http2_badserver_interop:
# launch a HTTP2 server emulator that creates edge cases
lang = str(http2InteropServer)
- spec = server_jobspec(http2InteropServer, docker_images.get(lang))
- job = dockerjob.DockerJob(spec)
- server_jobs[lang] = job
+ spec = server_jobspec(http2InteropServer, docker_images.get(lang),
+ manual_cmd_log=server_manual_cmd_log)
+ if not args.manual_run:
+ job = dockerjob.DockerJob(spec)
+ server_jobs[lang] = job
+ else:
+ # don't run the server, set server port to a placeholder value
+ server_addresses[lang] = ('localhost', '${SERVER_PORT}')
jobs = []
if args.cloud_to_prod:
@@ -918,7 +972,8 @@
test_job = cloud_to_prod_jobspec(
language, test_case, server_host_name,
prod_servers[server_host_name],
- docker_image=docker_images.get(str(language)))
+ docker_image=docker_images.get(str(language)),
+ manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
if args.http2_interop:
@@ -926,7 +981,8 @@
test_job = cloud_to_prod_jobspec(
http2Interop, test_case, server_host_name,
prod_servers[server_host_name],
- docker_image=docker_images.get(str(http2Interop)))
+ docker_image=docker_images.get(str(http2Interop)),
+ manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
if args.cloud_to_prod_auth:
@@ -939,7 +995,8 @@
test_job = cloud_to_prod_jobspec(
language, test_case, server_host_name,
prod_servers[server_host_name],
- docker_image=docker_images.get(str(language)), auth=True)
+ docker_image=docker_images.get(str(language)), auth=True,
+ manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
for server in args.override_server:
@@ -963,7 +1020,8 @@
server_host,
server_port,
docker_image=docker_images.get(str(language)),
- insecure=args.insecure)
+ insecure=args.insecure,
+ manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
if args.http2_interop:
@@ -977,7 +1035,8 @@
server_host,
server_port,
docker_image=docker_images.get(str(http2Interop)),
- insecure=args.insecure)
+ insecure=args.insecure,
+ manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
if args.http2_badserver_interop:
@@ -988,7 +1047,8 @@
str(http2InteropServer),
'localhost',
_DEFAULT_SERVER_PORT,
- docker_image=docker_images.get(str(language)))
+ docker_image=docker_images.get(str(language)),
+ manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
if not jobs:
@@ -997,13 +1057,20 @@
dockerjob.remove_image(image, skip_nonexistent=True)
sys.exit(1)
+ if args.manual_run:
+ print('All tests will skipped --manual_run option is active.')
+
num_failures, resultset = jobset.run(jobs, newline_on_success=True,
- maxjobs=args.jobs)
+ maxjobs=args.jobs,
+ skip_jobs=args.manual_run)
if num_failures:
jobset.message('FAILED', 'Some tests failed', do_newline=True)
else:
jobset.message('SUCCESS', 'All tests passed', do_newline=True)
+ write_cmdlog_maybe(server_manual_cmd_log, 'interop_server_cmds.sh')
+ write_cmdlog_maybe(client_manual_cmd_log, 'interop_client_cmds.sh')
+
report_utils.render_junit_xml_report(resultset, 'report.xml')
for name, job in resultset.items():
@@ -1029,5 +1096,8 @@
dockerjob.finish_jobs([j for j in server_jobs.itervalues()])
for image in docker_images.itervalues():
- print('Removing docker image %s' % image)
- dockerjob.remove_image(image)
+ if not args.manual_run:
+ print('Removing docker image %s' % image)
+ dockerjob.remove_image(image)
+ else:
+ print('Preserving docker image: %s' % image)
diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py
index 4fb1d5f..f41bde1 100755
--- a/tools/run_tests/run_microbenchmark.py
+++ b/tools/run_tests/run_microbenchmark.py
@@ -178,13 +178,15 @@
def collect_summary(bm_name, args):
heading('Summary: %s [no counters]' % bm_name)
- text(run_summary(bm_name, 'opt', 'out'))
+ text(run_summary(bm_name, 'opt', bm_name))
heading('Summary: %s [with counters]' % bm_name)
- text(run_summary(bm_name, 'counters', 'out'))
+ text(run_summary(bm_name, 'counters', bm_name))
if args.bigquery_upload:
- with open('out.csv', 'w') as f:
- f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py', 'out.counters.json', 'out.opt.json']))
- subprocess.check_call(['bq', 'load', 'microbenchmarks.microbenchmarks', 'out.csv'])
+ with open('%s.csv' % bm_name, 'w') as f:
+ f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py',
+ '%s.counters.json' % bm_name,
+ '%s.opt.json' % bm_name]))
+ subprocess.check_call(['bq', 'load', 'microbenchmarks.microbenchmarks', '%s.csv' % bm_name])
collectors = {
'latency': collect_latency,
@@ -228,30 +230,39 @@
help='Minimum time to run benchmarks for the summary collection')
args = argp.parse_args()
-for bm_name in args.benchmarks:
- for collect in args.collect:
- collectors[collect](bm_name, args)
-if args.diff_perf:
+try:
for bm_name in args.benchmarks:
- run_summary(bm_name, 'opt', '%s.new' % bm_name)
- where_am_i = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
- subprocess.check_call(['git', 'checkout', args.diff_perf])
- comparables = []
- subprocess.check_call(['make', 'clean'])
- try:
- for bm_name in args.benchmarks:
- try:
- run_summary(bm_name, 'opt', '%s.old' % bm_name)
- comparables.append(bm_name)
- except subprocess.CalledProcessError, e:
- pass
- finally:
- subprocess.check_call(['git', 'checkout', where_am_i])
- for bm_name in comparables:
- subprocess.check_call(['third_party/benchmark/tools/compare_bench.py',
- '%s.new.opt.json' % bm_name,
- '%s.old.opt.json' % bm_name])
-
-index_html += "</body>\n</html>\n"
-with open('reports/index.html', 'w') as f:
- f.write(index_html)
+ for collect in args.collect:
+ collectors[collect](bm_name, args)
+ if args.diff_perf:
+ if 'summary' not in args.collect:
+ for bm_name in args.benchmarks:
+ run_summary(bm_name, 'opt', bm_name)
+ run_summary(bm_name, 'counters', bm_name)
+ where_am_i = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
+ subprocess.check_call(['git', 'checkout', args.diff_perf])
+ comparables = []
+ subprocess.check_call(['make', 'clean'])
+ try:
+ for bm_name in args.benchmarks:
+ try:
+ run_summary(bm_name, 'opt', '%s.old' % bm_name)
+ run_summary(bm_name, 'counters', '%s.old' % bm_name)
+ comparables.append(bm_name)
+ except subprocess.CalledProcessError, e:
+ pass
+ finally:
+ subprocess.check_call(['git', 'checkout', where_am_i])
+ for bm_name in comparables:
+ diff = subprocess.check_output(['tools/profiling/microbenchmarks/bm_diff.py',
+ '%s.counters.json' % bm_name,
+ '%s.opt.json' % bm_name,
+ '%s.old.counters.json' % bm_name,
+ '%s.old.opt.json' % bm_name]).strip()
+ if diff:
+ heading('Performance diff: %s' % bm_name)
+ text(diff)
+finally:
+ index_html += "</body>\n</html>\n"
+ with open('reports/index.html', 'w') as f:
+ f.write(index_html)
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index afac10b..6d9be2e 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -42,6 +42,12 @@
'grpc_slice_buffer_reset_and_unref(': ['src/core/lib/slice/slice_buffer.c'],
'grpc_slice_ref(': ['src/core/lib/slice/slice.c'],
'grpc_slice_unref(': ['src/core/lib/slice/slice.c'],
+ 'grpc_error_create(': ['src/core/lib/iomgr/error.c'],
+ 'grpc_error_ref(': ['src/core/lib/iomgr/error.c'],
+ 'grpc_error_unref(': ['src/core/lib/iomgr/error.c'],
+ 'grpc_os_error(': ['src/core/lib/iomgr/error.c'],
+ 'grpc_wsa_error(': ['src/core/lib/iomgr/error.c'],
+ 'grpc_log_if_error(': ['src/core/lib/iomgr/error.c'],
}
errors = 0
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 45f3037..c85454a 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -270,6 +270,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\health_check_service_interface.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
@@ -414,6 +415,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 95cdb74..d800b29 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -70,6 +70,9 @@
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
@@ -162,6 +165,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 22ea361..45c0ecd 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -270,6 +270,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\health_check_service_interface.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
@@ -398,6 +399,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index c3cef2d..987d56d 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -55,6 +55,9 @@
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\cpp\server\channel_argument_option.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\server\create_default_thread_pool.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
@@ -147,6 +150,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\channel_argument_option.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj
new file mode 100644
index 0000000..ebbfd59
--- /dev/null
+++ b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{60523734-00BD-765B-5A5B-19E19A2E31B8}</ProjectGuid>
+ <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+ <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+ <TargetName>server_builder_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'">
+ <TargetName>server_builder_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.cc">
+ </ClCompile>
+ <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.h">
+ </ClInclude>
+ <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.cc">
+ </ClCompile>
+ <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.h">
+ </ClInclude>
+ <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.cc">
+ </ClCompile>
+ <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.h">
+ </ClInclude>
+ <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.cc">
+ </ClCompile>
+ <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.h">
+ </ClInclude>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\server\server_builder_test.cc">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+ <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+ <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+ <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+ <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+ </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj.filters b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj.filters
new file mode 100644
index 0000000..c323b7a
--- /dev/null
+++ b/vsprojects/vcxproj/test/server_builder_test/server_builder_test.vcxproj.filters
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.proto">
+ <Filter>src\proto\grpc\testing</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.proto">
+ <Filter>src\proto\grpc\testing</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\server\server_builder_test.cc">
+ <Filter>test\cpp\server</Filter>
+ </ClCompile>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{828e0ffc-a89a-de93-ae06-706d522188a1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\proto">
+ <UniqueIdentifier>{538db689-e85f-c369-7020-8d78e0ee5049}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\proto\grpc">
+ <UniqueIdentifier>{351168ef-9b4f-6165-ff4f-0e13781910db}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\proto\grpc\testing">
+ <UniqueIdentifier>{530a1a67-0a37-50f8-42d0-7ccf0ec34cfc}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test">
+ <UniqueIdentifier>{67afe178-6a18-fd24-bbe6-656fee5a5f10}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\cpp">
+ <UniqueIdentifier>{aaa8777b-1bc3-abaa-5e6d-28040c5aa213}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\cpp\server">
+ <UniqueIdentifier>{af770080-f515-c773-3ae0-243d5929bbd0}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project>
+