diff options
51 files changed, 1854 insertions, 142 deletions
@@ -455,7 +455,7 @@ endif .SECONDARY = %.pb.h %.pb.cc -PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin +PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin ifeq ($(DEP_MISSING),) all: static shared plugins dep_error: @@ -631,6 +631,7 @@ end2end_test: $(BINDIR)/$(CONFIG)/end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin +grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin interop_client: $(BINDIR)/$(CONFIG)/interop_client @@ -2000,92 +2001,152 @@ endif ifeq ($(NO_PROTOC),true) $(GENDIR)/examples/pubsub/empty.pb.cc: protoc_dep_error +$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: protoc_dep_error else $(GENDIR)/examples/pubsub/empty.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/examples/pubsub/label.pb.cc: protoc_dep_error +$(GENDIR)/examples/pubsub/label.grpc.pb.cc: protoc_dep_error else $(GENDIR)/examples/pubsub/label.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/examples/pubsub/label.grpc.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/examples/pubsub/pubsub.pb.cc: protoc_dep_error +$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: protoc_dep_error else $(GENDIR)/examples/pubsub/pubsub.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/interop/empty.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/interop/empty.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/interop/messages.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/interop/messages.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/interop/test.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/interop/test.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/qps/qpstest.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/qps/qpstest.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/util/echo.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/util/echo.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/util/messages.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/util/messages.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif @@ -2162,10 +2223,10 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(prefix)/lib/gpr.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgpr.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) $(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so endif endif @@ -2175,10 +2236,10 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(prefix)/lib/grpc.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) $(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so endif endif @@ -2188,10 +2249,10 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc_unsecure.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc_unsecure.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) $(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so endif endif @@ -2209,10 +2270,10 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(prefix)/lib/grpc++.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc++.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so endif endif @@ -2222,10 +2283,10 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so endif endif @@ -2243,10 +2304,10 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so endif endif @@ -2265,6 +2326,8 @@ else $(Q) $(INSTALL) -d $(prefix)/bin $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(prefix)/bin/grpc_cpp_plugin $(Q) $(INSTALL) -d $(prefix)/bin + $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(prefix)/bin/grpc_objective_c_plugin + $(Q) $(INSTALL) -d $(prefix)/bin $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_python_plugin $(prefix)/bin/grpc_python_plugin $(Q) $(INSTALL) -d $(prefix)/bin $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(prefix)/bin/grpc_ruby_plugin @@ -2387,7 +2450,7 @@ $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT): $(LIBGPR_OBJS) $(ZLIB_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS) + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgpr.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS) else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.0 -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS) $(Q) ln -sf libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgpr.so.0 @@ -2777,7 +2840,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(LIBDIR $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr $(Q) ln -sf libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.so.0 @@ -3117,7 +3180,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT): $(LIBGRPC_UNSECURE_OBJS) $( $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr $(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.so.0 @@ -3367,7 +3430,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(LI $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc else $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so.0 @@ -3414,9 +3477,9 @@ $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: LIBGRPC++_TEST_UTIL_SRC = \ - $(GENDIR)/test/cpp/util/messages.pb.cc \ - $(GENDIR)/test/cpp/util/echo.pb.cc \ - $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc \ + $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc \ + $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc \ + $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc \ test/cpp/util/cli_call.cc \ test/cpp/util/create_test_channel.cc \ @@ -3477,8 +3540,8 @@ endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc LIBGRPC++_UNSECURE_SRC = \ @@ -3572,7 +3635,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure else $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so.0 @@ -3614,6 +3677,7 @@ $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: LIBGRPC_PLUGIN_SUPPORT_SRC = \ src/compiler/cpp_generator.cc \ + src/compiler/objective_c_generator.cc \ src/compiler/python_generator.cc \ src/compiler/ruby_generator.cc \ @@ -3648,14 +3712,15 @@ ifneq ($(NO_DEPS),true) endif $(OBJDIR)/$(CONFIG)/src/compiler/cpp_generator.o: +$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_generator.o: $(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o: $(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o: LIBPUBSUB_CLIENT_LIB_SRC = \ - $(GENDIR)/examples/pubsub/label.pb.cc \ - $(GENDIR)/examples/pubsub/empty.pb.cc \ - $(GENDIR)/examples/pubsub/pubsub.pb.cc \ + $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc \ + $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc \ + $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc \ examples/pubsub/publisher.cc \ examples/pubsub/subscriber.cc \ @@ -3716,12 +3781,12 @@ endif -$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc -$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc +$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc LIBQPS_SRC = \ - $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ + $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \ test/cpp/qps/driver.cc \ test/cpp/qps/timer.cc \ @@ -3778,8 +3843,8 @@ endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc LIBGRPC_CSHARP_EXT_SRC = \ @@ -3831,7 +3896,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_csharp_ext.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so.0 @@ -8330,6 +8395,36 @@ ifneq ($(NO_DEPS),true) endif +GRPC_OBJECTIVE_C_PLUGIN_SRC = \ + src/compiler/objective_c_plugin.cc \ + +GRPC_OBJECTIVE_C_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_OBJECTIVE_C_PLUGIN_SRC)))) + + +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)/grpc_objective_c_plugin: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: $(PROTOBUF_DEP) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a + $(E) "[HOSTLD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin + +endif + +$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a + +deps_grpc_objective_c_plugin: $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep) +endif + + GRPC_PYTHON_PLUGIN_SRC = \ src/compiler/python_plugin.cc \ @@ -8391,9 +8486,9 @@ endif INTEROP_CLIENT_SRC = \ - $(GENDIR)/test/cpp/interop/empty.pb.cc \ - $(GENDIR)/test/cpp/interop/messages.pb.cc \ - $(GENDIR)/test/cpp/interop/test.pb.cc \ + $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \ test/cpp/interop/client.cc \ INTEROP_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_CLIENT_SRC)))) @@ -8439,9 +8534,9 @@ endif INTEROP_SERVER_SRC = \ - $(GENDIR)/test/cpp/interop/empty.pb.cc \ - $(GENDIR)/test/cpp/interop/messages.pb.cc \ - $(GENDIR)/test/cpp/interop/test.pb.cc \ + $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \ test/cpp/interop/server.cc \ INTEROP_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_SERVER_SRC)))) diff --git a/build.json b/build.json index d814e4c6bd..f8f23e0d33 100644 --- a/build.json +++ b/build.json @@ -514,6 +514,8 @@ "src/compiler/cpp_generator.h", "src/compiler/cpp_generator_helpers.h", "src/compiler/generator_helpers.h", + "src/compiler/objective_c_generator.h", + "src/compiler/objective_c_generator_helpers.h", "src/compiler/python_generator.h", "src/compiler/ruby_generator.h", "src/compiler/ruby_generator_helpers-inl.h", @@ -522,6 +524,7 @@ ], "src": [ "src/compiler/cpp_generator.cc", + "src/compiler/objective_c_generator.cc", "src/compiler/python_generator.cc", "src/compiler/ruby_generator.cc" ], @@ -1818,6 +1821,18 @@ "secure": "no" }, { + "name": "grpc_objective_c_plugin", + "build": "protoc", + "language": "c++", + "src": [ + "src/compiler/objective_c_plugin.cc" + ], + "deps": [ + "grpc_plugin_support" + ], + "secure": "no" + }, + { "name": "grpc_python_plugin", "build": "protoc", "language": "c++", diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md new file mode 100644 index 0000000000..3f5ce37e1e --- /dev/null +++ b/doc/interop-test-descriptions.md @@ -0,0 +1,685 @@ +Interoperability Test Case Descriptions +======================================= + +Client and server use +[test.proto](https://github.com/grpc/grpc/blob/master/test/cpp/interop/test.proto) +and the [gRPC over HTTP/2 v2 +protocol](https://github.com/grpc/grpc-common/blob/master/PROTOCOL-HTTP2.md). + +Client +------ + +Clients implement test cases that test certain functionally. Each client is +provided the test case it is expected to run as a command-line parameter. Names +should be lowercase and without spaces. + +Clients should accept these arguments: +* --server_host=HOSTNAME + * The server host to connect to. For example, "localhost" or "127.0.0.1" +* --server_host_override=HOSTNAME + * The server host to claim to be connecting to, for use in TLS and HTTP/2 + :authority header. If unspecified, the value of --server_host will be + used +* --server_port=PORT + * The server port to connect to. For example, "8080" +* --test_case=TESTCASE + * The name of the test case to execute. For example, "empty_unary" +* --use_tls=BOOLEAN + * Whether to use a plaintext or encrypted connection +* --use_test_ca=BOOLEAN + * Whether to replace platform root CAs with + [ca.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/ca.pem) + as the CA root + +Clients must support TLS with ALPN. Clients must not disable certificate +checking. + +### empty_unary + +This test verifies that implementations support zero-size messages. Ideally, +client implementations would verify that the request and response were zero +bytes serialized, but this is generally prohibitive to perform, so is not +required. + +Server features: +* [EmptyCall][] + +Procedure: + 1. Client calls EmptyCall with the default Empty message + +Asserts: +* call was successful +* response is non-null + +*It may be possible to use UnaryCall instead of EmptyCall, but it is harder to +ensure that the proto serialized to zero bytes.* + +### large_unary + +This test verifies unary calls succeed in sending messages, and touches on flow +control (even if compression is enabled on the channel). + +Server features: +* [UnaryCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + +Asserts: +* call was successful +* response payload type is COMPRESSABLE +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### client_streaming + +This test verifies that client-only streaming succeeds. + +Server features: +* [StreamingInputCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls StreamingInputCall + 2. Client sends: + + ``` + { + payload:{ + body: 27182 bytes of zeros + } + } + ``` + 3. Client then sends: + + ``` + { + payload:{ + body: 8 bytes of zeros + } + } + ``` + 4. Client then sends: + + ``` + { + payload:{ + body: 1828 bytes of zeros + } + } + ``` + 5. Client then sends: + + ``` + { + payload:{ + body: 45904 bytes of zeros + } + } + ``` + 6. Client halfCloses + +Asserts: +* call was successful +* response aggregated_payload_size is 74922 + +### server_streaming + +This test verifies that server-only streaming succeeds. + +Server features: +* [StreamingOutputCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls StreamingOutputCall with: + + ``` + { + response_type:COMPRESSABLE + response_parameters:{ + size: 31415 + } + response_parameters:{ + size: 9 + } + response_parameters:{ + size: 2653 + } + response_parameters:{ + size: 58979 + } + } + ``` + +Asserts: +* call was successful +* exactly four responses +* response payloads are COMPRESSABLE +* response payload bodies are sized (in order): 31415, 9, 2653, 58979 +* clients are free to assert that the response payload body contents are zero + and comparing the entire response messages against golden responses + +### ping_pong + +This test verifies that full duplex bidi is supported. + +Server features: +* [FullDuplexCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls FullDuplexCall with: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 31415 + } + payload:{ + body: 27182 bytes of zeros + } + } + ``` + 2. After getting a reply, it sends: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 9 + } + payload:{ + body: 8 bytes of zeros + } + } + ``` + 3. After getting a reply, it sends: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 2653 + } + payload:{ + body: 1828 bytes of zeros + } + } + ``` + 4. After getting a reply, it sends: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 58979 + } + payload:{ + body: 45904 bytes of zeros + } + } + ``` + +Asserts: +* call was successful +* exactly four responses +* response payloads are COMPRESSABLE +* response payload bodies are sized (in order): 31415, 9, 2653, 58979 +* clients are free to assert that the response payload body contents are zero + and comparing the entire response messages against golden responses + +### empty_stream + +This test verifies that streams support having zero-messages in both +directions. + +Server features: +* [FullDuplexCall][] + +Procedure: + 1. Client calls FullDuplexCall and then half-closes + +Asserts: +* call was successful +* exactly zero responses + +### compute_engine_creds + +Status: Not yet implementable + +This test is only for cloud-to-prod path. + +This test verifies unary calls succeed in sending messages while using Service +Credentials from GCE metadata server. The client instance needs to be created +with desired oauth scope. + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* SimpeResponse.username +* SimpleResponse.oauth_scope + +Procedure: + 1. Client sets flags default_service_account with GCE service account name and + oauth_scope with the oauth scope to use. + 2. Client configures channel to use GCECredentials + 3. Client calls UnaryCall on the channel with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + fill_username: true + fill_oauth_scope: true + } + ``` + +Asserts: +* call was successful +* received SimpleResponse.username equals FLAGS_default_service_account +* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### service_account_creds + +Status: Not yet implementable + +This test is only for cloud-to-prod path. + +This test verifies unary calls succeed in sending messages while using JWT +signing keys (redeemed for OAuth2 access tokens by the auth implementation) + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* SimpleResponse.username +* SimpleResponse.oauth_scope + +Procedure: + 1. Client sets flags service_account_key_file with the path to json key file, + oauth_scope to the oauth scope. + 2. Client configures the channel to use ServiceAccountCredentials. + 3. Client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + fill_username: true + fill_oauth_scope: true + } + ``` + +Asserts: +* call was successful +* received SimpleResponse.username is in the json key file read from + FLAGS_service_account_key_file +* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### jwt_token_creds + +Status: Not yet implementable + +This test is only for cloud-to-prod path. + +This test verifies unary calls succeed in sending messages while using JWT +token (created by the project's key file) + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* SimpleResponse.username +* SimpleResponse.oauth_scope + +Procedure: + 1. Client sets flags service_account_key_file with the path to json key file + 2. Client configures the channel to use JWTTokenCredentials. + 3. Client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + fill_username: true + } + ``` + +Asserts: +* call was successful +* received SimpleResponse.username is in the json key file read from + FLAGS_service_account_key_file +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### Metadata (TODO: fix name) + +Status: Not yet implementable + +This test verifies that custom metadata in either binary or ascii format can be +sent in header and trailer. + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* Ability to receive custom metadata from client in header and send custom data + back to client in both header and trailer. (TODO: this is not defined) + +Procedure: + 1. While sending custom metadata (ascii + binary) in the header, client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + +Asserts: +* call was successful +* custom metadata is echoed back in the response header. +* custom metadata is echoed back in the response trailer. + +### status_code_and_message + +Status: Not yet implementable + +This test verifies unary calls succeed in sending messages, and propagates back +status code and message sent along with the messages. + +Server features: +* [UnaryCall][] + +Procedure: + 1. Client calls UnaryCall with: + + ``` + { + response_status:{ + code: 2 + message: "test status message" + } + } + ``` + +Asserts: +* received status code is the same with sent code +* received status message is the same with sent message + +### unimplemented_method + +Status: Not yet implementable + +This test verifies calling unimplemented RPC method returns unimplemented +status. + +Procedure: +* Client calls UnimplementedCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + +Asserts: +* received status code is 12 (UNIMPLEMENTED) +* received status message is empty or null/unset + +### cancel_after_begin + +This test verifies that a request can be cancelled after metadata has been sent +but before payloads are sent. + +Server features: +* [StreamingInputCall][] + +Procedure: + 1. Client starts StreamingInputCall + 2. Client immediately cancels request + +Asserts: +* Call completed with status CANCELLED + +### cancel_after_first_response + +This test verifies that a request can be cancelled after receiving a message +from the server. + +Server features: +* [FullDuplexCall][] +* [Compressable Payload][] + +Procedure: + 1. Client starts FullDuplexCall with + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 31415 + } + payload:{ + body: 27182 bytes of zeros + } + } + ``` + 2. After receiving a response, client cancels request + +Asserts: +* Call completed with status CANCELLED + +### concurrent_large_unary + +Status: TODO + +Client performs 1000 large_unary tests in parallel on the same channel. + +### Flow control. Pushback at client for large messages (TODO: fix name) + +Status: TODO + +This test verifies that a client sending faster than a server can drain sees +pushback (i.e., attempts to send succeed only after appropriate delays). + +### TODO Tests + +High priority: + +Propagation of status code and message (yangg) + +Cancel after sent headers (ctiller - done) + +Cancel after received first message (ctiller - done) + +Timeout after expire (zhaoq) + +Zero-message streams (ejona) + +Multiple thousand simultaneous calls on same Channel (ctiller - done) + +OAuth2 tokens + Service Credentials from GCE metadata server (GCE->prod only) +(abhishek) + +OAuth2 tokens + JWT signing key (GCE->prod only) (abhishek) + +Metadata: client headers, server headers + trailers, binary+ascii (chenw) + +Normal priority: + +Cancel before start (ctiller) + +Cancel after sent first message (ctiller) + +Cancel after received headers (ctiller) + +Timeout but completed before expire (zhaoq) + +Multiple thousand simultaneous calls timeout on same Channel (ctiller) + +Lower priority: + +Flow control. Pushback at client for large messages (abhishek) + +Flow control. Pushback at server for large messages (abhishek) + +Going over max concurrent streams doesn't fail (client controls itself) +(abhishek) + +RPC method not implemented (yangg) + +Multiple thousand simultaneous calls on different Channels (ctiller) + +Failed TLS hostname verification (ejona?) + +To priorize: + +Start streaming RPC but don't send any requests, server responds + +### Postponed Tests + +Resilience to buggy servers: These tests would verify that a client application +isn't affected negatively by the responses put on the wire by a buggy server +(e.g. the client library won't make the application crash). + +Reconnect after transport failure + +Reconnect backoff + +Fuzz testing + + +Server +------ + +Servers implement various named features for clients to test with. Server +features are orthogonal. If a server implements a feature, it is always +available for clients. Names are simple descriptions for developer +communication and tracking. + +Servers should accept these arguments: + +* --port=PORT + + * The port to listen on. For example, "8080" + +* --use_tls=BOOLEAN + + * Whether to use a plaintext or encrypted connection + +Servers must support TLS with ALPN. They should use +[server1.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/server1.pem) +for their certificate. + +### EmptyCall +[EmptyCall]: #emptycall + +Server implements EmptyCall which immediately returns the empty message. + +### UnaryCall +[UnaryCall]: #unarycall + +Server implements UnaryCall which immediately returns a SimpleResponse with a +payload body of size SimpleRequest.response_size bytes and type as appropriate +for the SimpleRequest.response_type. If the server does not support the +response_type, then it should fail the RPC with INVALID_ARGUMENT. + +If the request sets fill_username, the server should return the client username +it sees in field SimpleResponse.username. If the request sets fill_oauth_scope, +the server should return the oauth scope of the rpc in the form of "xapi_zoo" +in field SimpleResponse.oauth_scope. + +### StreamingInputCall +[StreamingInputCall]: #streaminginputcall + +Server implements StreamingInputCall which upon half close immediately returns +a StreamingInputCallResponse where aggregated_payload_size is the sum of all +request payload bodies received. + +### StreamingOutputCall +[StreamingOutputCall]: #streamingoutputcall + +Server implements StreamingOutputCall by replying, in order, with one +StreamingOutputCallResponses for each ResponseParameters in +StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a +payload body of size ResponseParameters.size bytes, as specified by its +respective ResponseParameters. After sending all responses, it closes with OK. + +### FullDuplexCall +[FullDuplexCall]: #fullduplexcall + +Server implements FullDuplexCall by replying, in order, with one +StreamingOutputCallResponses for each ResponseParameters in each +StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a +payload body of size ResponseParameters.size bytes, as specified by its +respective ResponseParameters. After receiving half close and sending all +responses, it closes with OK. + +### Compressable Payload +[Compressable Payload]: #compressable-payload + +When the client requests COMPRESSABLE payload, the response includes a payload +of the size requested containing all zeros and the payload type is +COMPRESSABLE. + +### Observe ResponseParameters.interval_us +[Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us + +In StreamingOutputCall and FullDuplexCall, server delays sending a +StreamingOutputCallResponse by the ResponseParameters's interval_us for that +particular response, relative to the last response sent. That is, interval_us +acts like a sleep *before* sending the response and accumulates from one +response to the next. + +Interaction with flow control is unspecified. + +### Echo Auth Information + +Status: Pending + +If a SimpleRequest has fill_username=true and that request was successfully +authenticated, then the SimpleResponse should have username filled with the +canonical form of the authenticated source. The canonical form is dependent on +the authentication method, but is likely to be a base 10 integer identifier or +an email address. + +Discussion: + +Ideally, this would be communicated via metadata and not in the +request/response, but we want to use this test in code paths that don't yet +fully communicate metadata. diff --git a/examples/pubsub/publisher.h b/examples/pubsub/publisher.h index c90406ffef..33bcf98df4 100644 --- a/examples/pubsub/publisher.h +++ b/examples/pubsub/publisher.h @@ -37,7 +37,7 @@ #include <grpc++/channel_interface.h> #include <grpc++/status.h> -#include "examples/pubsub/pubsub.pb.h" +#include "examples/pubsub/pubsub.grpc.pb.h" namespace grpc { namespace examples { diff --git a/examples/pubsub/subscriber.h b/examples/pubsub/subscriber.h index c587c01b82..40ab45471d 100644 --- a/examples/pubsub/subscriber.h +++ b/examples/pubsub/subscriber.h @@ -37,7 +37,7 @@ #include <grpc++/channel_interface.h> #include <grpc++/status.h> -#include "examples/pubsub/pubsub.pb.h" +#include "examples/pubsub/pubsub.grpc.pb.h" namespace grpc { namespace examples { diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 0a84c73520..c78f0333d8 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -109,8 +109,47 @@ bool HasBidiStreaming(const grpc::protobuf::FileDescriptor *file) { } return false; } + +grpc::string FilenameIdentifier(const grpc::string& filename) { + grpc::string result; + for (unsigned i = 0; i < filename.size(); i++) { + char c = filename[i]; + if (isalnum(c)) { + result.push_back(c); + } else { + static char hex[] = "0123456789abcdef"; + result.push_back('_'); + result.push_back(hex[(c >> 4) & 0xf]); + result.push_back(hex[c & 0xf]); + } + } + return result; +} } // namespace +grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + vars["filename"] = file->name(); + vars["filename_identifier"] = FilenameIdentifier(file->name()); + vars["filename_base"] = grpc_generator::StripProto(file->name()); + + printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n"); + printer.Print(vars, "// If you make any local change, they will be lost.\n"); + printer.Print(vars, "// source: $filename$\n"); + printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n"); + printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n"); + printer.Print(vars, "\n"); + printer.Print(vars, "#include \"$filename_base$.pb.h\"\n"); + printer.Print(vars, "\n"); + + return output; +} + grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, const Parameters ¶ms) { grpc::string temp = @@ -156,17 +195,21 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, "class ServerAsyncReaderWriter;\n"); } temp.append("} // namespace grpc\n"); - return temp; -} -grpc::string GetSourceIncludes(const Parameters ¶m) { - return "#include <grpc++/async_unary_call.h>\n" - "#include <grpc++/channel_interface.h>\n" - "#include <grpc++/impl/client_unary_call.h>\n" - "#include <grpc++/impl/rpc_method.h>\n" - "#include <grpc++/impl/rpc_service_method.h>\n" - "#include <grpc++/impl/service_type.h>\n" - "#include <grpc++/stream.h>\n"; + temp.append("\n"); + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.begin(); part != parts.end(); part++) { + temp.append("namespace "); + temp.append(*part); + temp.append(" {\n"); + } + + temp.append("\n"); + + return temp; } void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer, @@ -378,6 +421,78 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file, return output; } +grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + vars["filename"] = file->name(); + vars["filename_identifier"] = FilenameIdentifier(file->name()); + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.rbegin(); part != parts.rend(); part++) { + vars["part"] = *part; + printer.Print(vars, "} // namespace $part$\n"); + } + + printer.Print(vars, "\n\n"); + printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n"); + + return output; +} + +grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + vars["filename"] = file->name(); + vars["filename_base"] = grpc_generator::StripProto(file->name()); + + printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n"); + printer.Print(vars, "// If you make any local change, they will be lost.\n"); + printer.Print(vars, "// source: $filename$\n\n"); + printer.Print(vars, "#include \"$filename_base$.pb.h\"\n"); + printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n"); + printer.Print(vars, "\n"); + + return output; +} + +grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶m) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + printer.Print(vars, "#include <grpc++/async_unary_call.h>\n"); + printer.Print(vars, "#include <grpc++/channel_interface.h>\n"); + printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n"); + printer.Print(vars, "#include <grpc++/impl/rpc_method.h>\n"); + printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n"); + printer.Print(vars, "#include <grpc++/impl/service_type.h>\n"); + printer.Print(vars, "#include <grpc++/stream.h>\n"); + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.begin(); part != parts.end(); part++) { + vars["part"] = *part; + printer.Print(vars, "namespace $part$ {\n"); + } + + printer.Print(vars, "\n"); + + return output; +} + void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer, const grpc::protobuf::MethodDescriptor *method, std::map<grpc::string, grpc::string> *vars) { @@ -741,4 +856,22 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file, return output; } +grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string temp; + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.begin(); part != parts.end(); part++) { + temp.append("} // namespace "); + temp.append(*part); + temp.append("\n"); + } + + temp.append("\n"); + + return temp; +} + } // namespace grpc_cpp_generator diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h index 04ad71c067..70c2e985f6 100644 --- a/src/compiler/cpp_generator.h +++ b/src/compiler/cpp_generator.h @@ -44,12 +44,25 @@ struct Parameters { grpc::string services_namespace; }; +// Return the prologue of the generated header file. +grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + // Return the includes needed for generated header file. grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, const Parameters ¶ms); // Return the includes needed for generated source file. -grpc::string GetSourceIncludes(const Parameters ¶ms); +grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + +// Return the epilogue of the generated header file. +grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + +// Return the prologue of the generated source file. +grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); // Return the services for generated header file. grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file, @@ -59,6 +72,10 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file, grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file, const Parameters ¶ms); +// Return the epilogue of the generated source file. +grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + } // namespace grpc_cpp_generator #endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc index acbe128213..88c704948e 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -58,11 +58,6 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { return false; } - if (file->service_count() == 0) { - // No services. Do nothing. - return true; - } - grpc_cpp_generator::Parameters generator_parameters; if (!parameter.empty()) { @@ -84,16 +79,27 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { grpc::string file_name = grpc_generator::StripProto(file->name()); - // Generate .pb.h - Insert(context, file_name + ".pb.h", "includes", - grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters)); - Insert(context, file_name + ".pb.h", "namespace_scope", - grpc_cpp_generator::GetHeaderServices(file, generator_parameters)); - // Generate .pb.cc - Insert(context, file_name + ".pb.cc", "includes", - grpc_cpp_generator::GetSourceIncludes(generator_parameters)); - Insert(context, file_name + ".pb.cc", "namespace_scope", - grpc_cpp_generator::GetSourceServices(file, generator_parameters)); + grpc::string header_code = + grpc_cpp_generator::GetHeaderPrologue(file, generator_parameters) + + grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters) + + grpc_cpp_generator::GetHeaderServices(file, generator_parameters) + + grpc_cpp_generator::GetHeaderEpilogue(file, generator_parameters); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output( + context->Open(file_name + ".grpc.pb.h")); + grpc::protobuf::io::CodedOutputStream header_coded_out( + header_output.get()); + header_coded_out.WriteRaw(header_code.data(), header_code.size()); + + grpc::string source_code = + grpc_cpp_generator::GetSourcePrologue(file, generator_parameters) + + grpc_cpp_generator::GetSourceIncludes(file, generator_parameters) + + grpc_cpp_generator::GetSourceServices(file, generator_parameters) + + grpc_cpp_generator::GetSourceEpilogue(file, generator_parameters); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output( + context->Open(file_name + ".grpc.pb.cc")); + grpc::protobuf::io::CodedOutputStream source_coded_out( + source_output.get()); + source_coded_out.WriteRaw(source_code.data(), source_code.size()); return true; } diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h index 30857891c7..374e1374cf 100644 --- a/src/compiler/generator_helpers.h +++ b/src/compiler/generator_helpers.h @@ -95,6 +95,27 @@ inline std::vector<grpc::string> tokenize(const grpc::string &input, } } +inline grpc::string CapitalizeFirstLetter(grpc::string s) { + if (s.empty()) { + return s; + } + s[0] = ::toupper(s[0]); + return s; +} + +inline grpc::string LowerUnderscoreToUpperCamel(grpc::string str) { + std::vector<grpc::string> tokens = tokenize(str, "_"); + grpc::string result = ""; + for (unsigned int i = 0; i < tokens.size(); i++) { + result += CapitalizeFirstLetter(tokens[i]); + } + return result; +} + +inline grpc::string FileNameInUpperCamel(const grpc::protobuf::FileDescriptor *file) { + return LowerUnderscoreToUpperCamel(StripProto(file->name())); +} + } // namespace grpc_generator #endif // GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc new file mode 100644 index 0000000000..c68c9c37c2 --- /dev/null +++ b/src/compiler/objective_c_generator.cc @@ -0,0 +1,236 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <map> + +#include "src/compiler/objective_c_generator.h" +#include "src/compiler/objective_c_generator_helpers.h" + +#include "src/compiler/config.h" + +#include <sstream> + +namespace grpc_objective_c_generator { +namespace { + +void PrintSimpleBlockSignature(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + (*vars)["request_type"] = PrefixedName(method->input_type()->name()); + (*vars)["response_type"] = PrefixedName(method->output_type()->name()); + + if (method->server_streaming()) { + printer->Print("// When the response stream finishes, the handler is " + "called with nil for both arguments.\n\n"); + } else { + printer->Print("// The handler is only called once.\n\n"); + } + printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:" + "($request_type$)request completionHandler:(void(^)" + "($response_type$ *, NSError *))handler"); +} + +void PrintSimpleDelegateSignature(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + (*vars)["request_type"] = PrefixedName(method->input_type()->name()); + + printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:" + "($request_type$)request delegate:(id<GRXSink>)delegate"); +} + +void PrintAdvancedSignature(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:" + "(id<GRXSource>)request"); +} + +void PrintSourceMethodSimpleBlock(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + PrintSimpleBlockSignature(printer, method, vars); + + (*vars)["method_name"] = method->name(); + printer->Print(" {\n"); + printer->Indent(); + printer->Print(*vars, "return [[self $method_name$WithRequest:request] " + "connectHandler:^(id value, NSError *error) {\n"); + printer->Indent(); + printer->Print("handler(value, error);\n"); + printer->Outdent(); + printer->Print("}];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void PrintSourceMethodSimpleDelegate(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + PrintSimpleDelegateSignature(printer, method, vars); + + (*vars)["method_name"] = method->name(); + printer->Print(" {\n"); + printer->Indent(); + printer->Print(*vars, "return [[self $method_name$WithRequest:request]" + "connectToSink:delegate];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void PrintSourceMethodAdvanced(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + PrintAdvancedSignature(printer, method, vars); + + (*vars)["method_name"] = method->name(); + printer->Print(" {\n"); + printer->Indent(); + printer->Print(*vars, "return [self $method_name$WithRequest:request " + "client:[self newClient]];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void PrintSourceMethodHandler(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + (*vars)["response_type"] = PrefixedName(method->output_type()->name()); + (*vars)["caps_name"] = grpc_generator::CapitalizeFirstLetter(method->name()); + + printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:" + "(id<GRXSource>)request client:(PBgRPCClient *)client {\n"); + printer->Indent(); + printer->Print(*vars, + "return [self responseWithMethod:$@\"$caps_name\"\n"); + printer->Print(*vars, + " class:[$response_type$ class]\n"); + printer->Print(" request:request\n"); + printer->Print(" client:client];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +} + +grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, + const grpc::string message_header) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + printer.Print("#import \"PBgRPCClient.h\"\n"); + printer.Print("#import \"PBStub.h\"\n"); + vars["message_header"] = message_header; + printer.Print(vars, "#import \"$message_header$\"\n\n"); + printer.Print("@protocol GRXSource\n"); + printer.Print("@class GRXSource\n\n"); + vars["service_name"] = service->name(); + printer.Print("@protocol $service_name$Stub <NSObject>\n\n"); + printer.Print("#pragma mark Simple block handlers\n\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSimpleBlockSignature(&printer, service->method(i), &vars); + printer.Print(";\n"); + } + printer.Print("\n"); + printer.Print("#pragma mark Simple delegate handlers.\n\n"); + printer.Print("# TODO(jcanizales): Use high-level snippets to remove this duplication."); + for (int i = 0; i < service->method_count(); i++) { + PrintSimpleDelegateSignature(&printer, service->method(i), &vars); + printer.Print(";\n"); + } + printer.Print("\n"); + printer.Print("#pragma mark Advanced handlers.\n\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintAdvancedSignature(&printer, service->method(i), &vars); + printer.Print(";\n"); + } + printer.Print("\n"); + printer.Print("@end\n\n"); + printer.Print("// Basic stub that only does marshalling and parsing\n"); + printer.Print(vars, "@interface $service_name$Stub :" + " PBStub<$service_name$Stub>\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host;\n"); + printer.Print("@end\n"); + return output; +} + +grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + vars["service_name"] = service->name(); + printer.Print(vars, "#import \"$service_name$Stub.pb.h\"\n"); + printer.Print("#import \"PBGeneratedMessage+GRXSource.h\"\n\n"); + vars["full_name"] = service->full_name(); + printer.Print(vars, + "static NSString *const kInterface = @\"$full_name$\";\n"); + printer.Print("@implementation $service_name$Stub\n\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host {\n"); + printer.Indent(); + printer.Print("if ((self = [super initWithHost:host " + "interface:kInterface])) {\n"); + printer.Print("}\n"); + printer.Print("return self;\n"); + printer.Outdent(); + printer.Print("}\n\n"); + printer.Print("#pragma mark Simple block handlers.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodSimpleBlock(&printer, service->method(i), &vars); + } + printer.Print("\n"); + printer.Print("#pragma mark Simple delegate handlers.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodSimpleDelegate(&printer, service->method(i), &vars); + } + printer.Print("\n"); + printer.Print("#pragma mark Advanced handlers.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodAdvanced(&printer, service->method(i), &vars); + } + printer.Print("\n"); + printer.Print("#pragma mark Handlers for subclasses " + "(stub wrappers) to override.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodHandler(&printer, service->method(i), &vars); + } + printer.Print("@end\n"); + return output; +} + +} // namespace grpc_objective_c_generator diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h new file mode 100644 index 0000000000..93c730b34e --- /dev/null +++ b/src/compiler/objective_c_generator.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H +#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H + +#include "src/compiler/config.h" + +namespace grpc_objective_c_generator { + +grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, + const grpc::string message_header); + +grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service); + +} // namespace grpc_objective_c_generator + +#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h new file mode 100644 index 0000000000..6a7c13991f --- /dev/null +++ b/src/compiler/objective_c_generator_helpers.h @@ -0,0 +1,58 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H +#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H + +#include <map> +#include "src/compiler/config.h" +#include "src/compiler/generator_helpers.h" + +namespace grpc_objective_c_generator { + +const grpc::string prefix = "PBG"; + +inline grpc::string MessageHeaderName(const grpc::protobuf::FileDescriptor *file) { + return grpc_generator::FileNameInUpperCamel(file) + ".pb.h"; +} + +inline grpc::string StubFileName(grpc::string service_name) { + return prefix + service_name + "Stub"; +} + +inline grpc::string PrefixedName(grpc::string name) { + return prefix + name; +} + +} +#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc new file mode 100644 index 0000000000..eebce0cd20 --- /dev/null +++ b/src/compiler/objective_c_plugin.cc @@ -0,0 +1,98 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Generates Objective C gRPC service interface out of Protobuf IDL. + +#include <memory> + +#include "src/compiler/config.h" +#include "src/compiler/objective_c_generator.h" +#include "src/compiler/objective_c_generator_helpers.h" + +class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { + public: + ObjectiveCGrpcGenerator() {} + virtual ~ObjectiveCGrpcGenerator() {} + + virtual bool Generate(const grpc::protobuf::FileDescriptor *file, + const grpc::string ¶meter, + grpc::protobuf::compiler::GeneratorContext *context, + grpc::string *error) const { + + if (file->service_count() == 0) { + // No services. Do nothing. + return true; + } + + for (int i = 0; i < file->service_count(); i++) { + const grpc::protobuf::ServiceDescriptor *service = file->service(i); + grpc::string file_name = grpc_objective_c_generator::StubFileName( + service->name()); + + // Generate .pb.h + grpc::string header_code = grpc_objective_c_generator::GetHeader( + service, grpc_objective_c_generator::MessageHeaderName(file)); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output( + context->Open(file_name + ".pb.h")); + grpc::protobuf::io::CodedOutputStream header_coded_out( + header_output.get()); + header_coded_out.WriteRaw(header_code.data(), header_code.size()); + + // Generate .pb.m + grpc::string source_code = grpc_objective_c_generator::GetSource(service); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output( + context->Open(file_name + ".pb.m")); + grpc::protobuf::io::CodedOutputStream source_coded_out( + source_output.get()); + source_coded_out.WriteRaw(source_code.data(), source_code.size()); + } + + return true; + } + + private: + // Insert the given code into the given file at the given insertion point. + void Insert(grpc::protobuf::compiler::GeneratorContext *context, + const grpc::string &filename, const grpc::string &insertion_point, + const grpc::string &code) const { + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output( + context->OpenForInsert(filename, insertion_point)); + grpc::protobuf::io::CodedOutputStream coded_out(output.get()); + coded_out.WriteRaw(code.data(), code.size()); + } +}; + +int main(int argc, char *argv[]) { + ObjectiveCGrpcGenerator generator; + return grpc::protobuf::compiler::PluginMain(argc, argv, &generator); +} diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c index f92fb64a5c..3cc798293a 100644 --- a/src/core/support/thd_win32.c +++ b/src/core/support/thd_win32.c @@ -61,7 +61,7 @@ struct thd_info { static thread_local struct thd_info *g_thd_info; /* Destroys a thread info */ -static destroy_thread(struct thd_info *t) { +static void destroy_thread(struct thd_info *t) { if (t->joinable) CloseHandle(t->join_event); gpr_free(t); } diff --git a/src/csharp/Grpc.Examples.MathServer/.gitignore b/src/csharp/Grpc.Examples.MathServer/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj new file mode 100644 index 0000000000..3f7e6c0768 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">x86</Platform> + <ProductVersion>10.0.0</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{BF62FE08-373A-43D6-9D73-41CAA38B7011}</ProjectGuid> + <OutputType>Exe</OutputType> + <RootNamespace>Grpc.Examples.MathServer</RootNamespace> + <AssemblyName>Grpc.Examples.MathServer</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug</OutputPath> + <DefineConstants>DEBUG;</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Externalconsole>true</Externalconsole> + <PlatformTarget>x86</PlatformTarget> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> + <DebugType>full</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release</OutputPath> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Externalconsole>true</Externalconsole> + <PlatformTarget>x86</PlatformTarget> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="MathServer.cs" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <ItemGroup> + <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj"> + <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project> + <Name>Grpc.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj"> + <Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project> + <Name>Grpc.Examples</Name> + </ProjectReference> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs new file mode 100644 index 0000000000..884a84d0a6 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs @@ -0,0 +1,61 @@ +#region Copyright notice and license +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Runtime.InteropServices; +using System.Threading; +using Grpc.Core; + +namespace math +{ + class MainClass + { + public static void Main(string[] args) + { + String host = "0.0.0.0"; + + GrpcEnvironment.Initialize(); + + Server server = new Server(); + server.AddServiceDefinition(MathGrpc.BindService(new MathServiceImpl())); + int port = server.AddListeningPort(host + ":0"); + server.Start(); + + Console.WriteLine("MathServer listening on port " + port); + + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..6b3d0516b9 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("Grpc.Examples.MathServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Google Inc. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyVersion("0.1.*")] diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln index 2e6d288699..2f8c2e1719 100644 --- a/src/csharp/Grpc.sln +++ b/src/csharp/Grpc.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Cli EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.csproj", "{A654F3B8-E859-4E6A-B30D-227527DBEF0D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.csproj", "{BF62FE08-373A-43D6-9D73-41CAA38B7011}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
@@ -47,6 +49,10 @@ Global {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|x86.Build.0 = Debug|x86
{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.ActiveCfg = Release|x86
{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.Build.0 = Release|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.ActiveCfg = Debug|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.Build.0 = Debug|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.ActiveCfg = Release|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.Build.0 = Release|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.ActiveCfg = Debug|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.Build.0 = Debug|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|x86.ActiveCfg = Release|x86
diff --git a/src/php/bin/generate_proto_php.sh b/src/php/bin/generate_proto_php.sh new file mode 100755 index 0000000000..16f93747ab --- /dev/null +++ b/src/php/bin/generate_proto_php.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +set +e +cd $(dirname $0) + +gen_code='../tests/generated_code' +interop='../tests/interop' + +protoc-gen-php -i $gen_code -o $gen_code $gen_code/math.proto + +protoc-gen-php -i $interop -o $interop $interop/test.proto diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 6bc65b5367..b1525e9246 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -443,8 +443,9 @@ PHP_METHOD(Call, startBatch) { add_property_bool(result, "send_status", true); break; case GRPC_OP_RECV_INITIAL_METADATA: - add_property_zval(result, "metadata", - grpc_parse_metadata_array(&recv_metadata)); + array = grpc_parse_metadata_array(&recv_metadata); + add_property_zval(result, "metadata", array); + Z_DELREF_P(array); break; case GRPC_OP_RECV_MESSAGE: byte_buffer_to_string(message, &message_str, &message_len); @@ -458,11 +459,13 @@ PHP_METHOD(Call, startBatch) { case GRPC_OP_RECV_STATUS_ON_CLIENT: MAKE_STD_ZVAL(recv_status); object_init(recv_status); - add_property_zval(recv_status, "metadata", - grpc_parse_metadata_array(&recv_trailing_metadata)); + array = grpc_parse_metadata_array(&recv_trailing_metadata); + add_property_zval(recv_status, "metadata", array); + Z_DELREF_P(array); add_property_long(recv_status, "code", status); add_property_string(recv_status, "details", status_details, true); add_property_zval(result, "status", recv_status); + Z_DELREF_P(recv_status); break; case GRPC_OP_RECV_CLOSE_ON_SERVER: add_property_bool(result, "cancelled", cancelled); diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index 51a3eae0f4..b8262db162 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -62,6 +62,7 @@ void free_wrapped_grpc_channel(void *object TSRMLS_DC) { if (channel->wrapped != NULL) { grpc_channel_destroy(channel->wrapped); } + efree(channel->target); efree(channel); } diff --git a/src/python/interop/interop/_interop_test_case.py b/src/python/interop/interop/_interop_test_case.py index fec8f1915d..cd6a574e90 100644 --- a/src/python/interop/interop/_interop_test_case.py +++ b/src/python/interop/interop/_interop_test_case.py @@ -40,16 +40,16 @@ class InteropTestCase(object): """ def testEmptyUnary(self): - methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub) + methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub, None) def testLargeUnary(self): - methods.TestCase.LARGE_UNARY.test_interoperability(self.stub) + methods.TestCase.LARGE_UNARY.test_interoperability(self.stub, None) def testServerStreaming(self): - methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub) + methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub, None) def testClientStreaming(self): - methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub) + methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub, None) def testPingPong(self): - methods.TestCase.PING_PONG.test_interoperability(self.stub) + methods.TestCase.PING_PONG.test_interoperability(self.stub, None) diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py index 85a0dcd998..bae5e17460 100644 --- a/src/python/interop/interop/client.py +++ b/src/python/interop/interop/client.py @@ -30,6 +30,7 @@ """The Python implementation of the GRPC interoperability test client.""" import argparse +from oauth2client import client as oauth2client_client from grpc.early_adopter import implementations @@ -44,9 +45,6 @@ def _args(): parser.add_argument( '--server_host', help='the host to which to connect', type=str) parser.add_argument( - '--server_host_override', - help='the server host to which to claim to connect', type=str) - parser.add_argument( '--server_port', help='the port to which to connect', type=int) parser.add_argument( '--test_case', help='the test case to execute', type=str) @@ -56,10 +54,25 @@ def _args(): parser.add_argument( '--use_test_ca', help='replace platform root CAs with ca.pem', action='store_true') + parser.add_argument( + '--server_host_override', + help='the server host to which to claim to connect', type=str) + parser.add_argument('--oauth_scope', help='scope for OAuth tokens', type=str) + parser.add_argument( + '--default_service_account', + help='email address of the default service account', type=str) return parser.parse_args() +def _oauth_access_token(args): + credentials = client.GoogleCredentials.get_application_default() + scoped_credentials = credentials.create_scoped([args.oauth_scope]) + return scoped_credentials.get_access_token().access_token def _stub(args): + if args.oauth_scope: + metadata_transformer = lambda x: [('Authorization', 'Bearer %s' % _oauth_access_token(args))] + else: + metadata_transformer = lambda x: [] if args.use_tls: if args.use_test_ca: root_certificates = resources.test_root_certificates() @@ -68,7 +81,8 @@ def _stub(args): stub = implementations.stub( methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host, - args.server_port, secure=True, root_certificates=root_certificates, + args.server_port, metadata_transformer=metadata_transformer, + secure=True, root_certificates=root_certificates, server_host_override=args.server_host_override) else: stub = implementations.stub( @@ -89,7 +103,7 @@ def _test_interoperability(): args = _args() stub = _stub(args) test_case = _test_case_from_arg(args.test_case) - test_case.test_interoperability(stub) + test_case.test_interoperability(stub, args) if __name__ == '__main__': diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py index 79550a3789..c69771dff1 100644 --- a/src/python/interop/interop/methods.py +++ b/src/python/interop/interop/methods.py @@ -30,8 +30,12 @@ """Implementations of interoperability test methods.""" import enum +import json +import os import threading +from oauth2client import client as oauth2client_client + from grpc.framework.alpha import utilities from interop import empty_pb2 @@ -150,19 +154,12 @@ SERVER_METHODS = { } -def _empty_unary(stub): - with stub: - response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) - if not isinstance(response, empty_pb2.Empty): - raise TypeError( - 'response is of type "%s", not empty_pb2.Empty!', type(response)) - - -def _large_unary(stub): +def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope): with stub: request = messages_pb2.SimpleRequest( response_type=messages_pb2.COMPRESSABLE, response_size=314159, - payload=messages_pb2.Payload(body=b'\x00' * 271828)) + payload=messages_pb2.Payload(body=b'\x00' * 271828), + fill_username=fill_username, fill_oauth_scope=fill_oauth_scope) response_future = stub.UnaryCall.async(request, _TIMEOUT) response = response_future.result() if response.payload.type is not messages_pb2.COMPRESSABLE: @@ -171,6 +168,19 @@ def _large_unary(stub): if len(response.payload.body) != 314159: raise ValueError( 'response body of incorrect size %d!' % len(response.payload.body)) + return response + + +def _empty_unary(stub): + with stub: + response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) + if not isinstance(response, empty_pb2.Empty): + raise TypeError( + 'response is of type "%s", not empty_pb2.Empty!', type(response)) + + +def _large_unary(stub): + _large_unary_common_behavior(stub, False, False) def _client_streaming(stub): @@ -266,6 +276,28 @@ def _ping_pong(stub): pipe.close() +def _compute_engine_creds(stub, args): + response = _large_unary_common_behavior(stub, True, True) + if args.default_service_account != response.username: + raise ValueError( + 'expected username %s, got %s' % (args.default_service_account, + response.username)) + + +def _service_account_creds(stub, args): + json_key_filename = os.environ[ + oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] + wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + response = _large_unary_common_behavior(stub, True, True) + if wanted_email != response.username: + raise ValueError( + 'expected username %s, got %s' % (wanted_email, response.username)) + if response.oauth_scope in args.oauth_scope: + raise ValueError( + 'expected to find oauth scope "%s" in received "%s"' % + (response.oauth_scope, args.oauth_scope)) + + @enum.unique class TestCase(enum.Enum): EMPTY_UNARY = 'empty_unary' @@ -273,8 +305,10 @@ class TestCase(enum.Enum): SERVER_STREAMING = 'server_streaming' CLIENT_STREAMING = 'client_streaming' PING_PONG = 'ping_pong' + COMPUTE_ENGINE_CREDS = 'compute_engine_creds' + SERVICE_ACCOUNT_CREDS = 'service_account_creds' - def test_interoperability(self, stub): + def test_interoperability(self, stub, args): if self is TestCase.EMPTY_UNARY: _empty_unary(stub) elif self is TestCase.LARGE_UNARY: @@ -285,5 +319,9 @@ class TestCase(enum.Enum): _client_streaming(stub) elif self is TestCase.PING_PONG: _ping_pong(stub) + elif self is TestCase.COMPUTE_ENGINE_CREDS: + _compute_engine_creds(stub, args) + elif self is TestCase.SERVICE_ACCOUNT_CREDS: + _service_account_creds(stub, args) else: raise NotImplementedError('Test case "%s" not implemented!' % self.name) diff --git a/src/python/interop/setup.py b/src/python/interop/setup.py index 7a329924a5..502fcbedd8 100644 --- a/src/python/interop/setup.py +++ b/src/python/interop/setup.py @@ -45,7 +45,7 @@ _PACKAGE_DATA = { 'credentials/server1.pem',] } -_INSTALL_REQUIRES = ['grpcio>=0.4.0a4'] +_INSTALL_REQUIRES = ['oauth2client>=1.4.7', 'grpcio>=0.4.0a4'] setuptools.setup( name='interop', diff --git a/templates/Makefile.template b/templates/Makefile.template index d6c80a5c14..776ee7a49b 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -35,17 +35,11 @@ proto_re = re.compile('(.*)\\.proto') - def excluded(filename, exclude_res): - for r in exclude_res: - if r.match(filename): - return True - return False - def proto_to_cc(filename): m = proto_re.match(filename) if not m: return filename - return '$(GENDIR)/' + m.group(1) + '.pb.cc' + return '$(GENDIR)/' + m.group(1) + '.pb.cc $(GENDIR)/' + m.group(1) + '.grpc.pb.cc' %> @@ -840,11 +834,17 @@ endif % for p in protos: ifeq ($(NO_PROTOC),true) $(GENDIR)/${p}.pb.cc: protoc_dep_error +$(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error else $(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif % endfor @@ -926,10 +926,10 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/${lib.name}.$(SHARED_EXT) $(prefix)/lib/${lib.name}.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing lib${lib.name}.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) $(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so endif endif @@ -1166,7 +1166,7 @@ ${out_libbase}.$(SHARED_EXT): $(LIB${lib.name.upper()}_OBJS) ${lib_deps} $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs} + $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name lib${lib.name}.$(SHARED_EXT) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs} else $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} -o ${out_libbase}.$(SHARED_EXT) ${common}${libs} $(Q) ln -sf lib${lib.name}.$(SHARED_EXT) ${out_libbase}.so.${settings.version.major} diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 9938fcf12e..dd294d9516 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -35,8 +35,8 @@ #include <memory> #include "test/core/util/test_config.h" -#include "test/cpp/util/echo_duplicate.pb.h" -#include "test/cpp/util/echo.pb.h" +#include "test/cpp/util/echo_duplicate.grpc.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" #include "src/cpp/util/time.h" #include <grpc++/async_unary_call.h> #include <grpc++/channel_arguments.h> diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 0d5db046df..f96051cafa 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -35,8 +35,8 @@ #include <thread> #include "test/core/util/test_config.h" -#include "test/cpp/util/echo_duplicate.pb.h" -#include "test/cpp/util/echo.pb.h" +#include "test/cpp/util/echo_duplicate.grpc.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" #include "src/cpp/util/time.h" #include "src/cpp/server/thread_pool.h" #include <grpc++/channel_arguments.h> diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 9cdd8c94d1..eb6f5369a9 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -38,7 +38,7 @@ #include "src/cpp/util/time.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -#include "test/cpp/util/echo.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" #include <grpc++/async_generic_service.h> #include <grpc++/async_unary_call.h> #include <grpc++/byte_buffer.h> diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index de6c6b7b77..7c5e1aa715 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -51,9 +51,9 @@ #include <grpc++/status.h> #include <grpc++/stream.h> #include "test/cpp/util/create_test_channel.h" -#include "test/cpp/interop/test.pb.h" -#include "test/cpp/interop/empty.pb.h" -#include "test/cpp/interop/messages.pb.h" +#include "test/cpp/interop/test.grpc.pb.h" +#include "test/cpp/interop/empty.grpc.pb.h" +#include "test/cpp/interop/messages.grpc.pb.h" DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google"); diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc index 780a7370ac..87bf48938b 100644 --- a/test/cpp/interop/server.cc +++ b/test/cpp/interop/server.cc @@ -49,9 +49,9 @@ #include <grpc++/server_credentials.h> #include <grpc++/status.h> #include <grpc++/stream.h> -#include "test/cpp/interop/test.pb.h" -#include "test/cpp/interop/empty.pb.h" -#include "test/cpp/interop/messages.pb.h" +#include "test/cpp/interop/test.grpc.pb.h" +#include "test/cpp/interop/empty.grpc.pb.h" +#include "test/cpp/interop/messages.grpc.pb.h" DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); DEFINE_int32(port, 0, "Server port."); diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index cae7f44537..08b338c747 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -36,7 +36,7 @@ #include "test/cpp/qps/histogram.h" #include "test/cpp/qps/timer.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include <condition_variable> #include <mutex> diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index 1ed3c7157f..c01d840178 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -48,7 +48,7 @@ #include <grpc++/status.h> #include <grpc++/stream.h> #include "test/cpp/util/create_test_channel.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/timer.h" #include "test/cpp/qps/client.h" diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 77da1725ff..947618121b 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -55,7 +55,7 @@ #include <gtest/gtest.h> #include "test/cpp/util/create_test_channel.h" #include "test/cpp/qps/client.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/histogram.h" #include "test/cpp/qps/timer.h" diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 64a53496ae..f44883783d 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -74,7 +74,9 @@ static vector<string> get_hosts(const string& name) { ScenarioResult RunScenario(const ClientConfig& initial_client_config, size_t num_clients, const ServerConfig& server_config, - size_t num_servers) { + size_t num_servers, + int warmup_seconds, + int benchmark_seconds) { // ClientContext allocator (all are destroyed at scope exit) list<ClientContext> contexts; auto alloc_context = [&contexts]() { @@ -146,7 +148,7 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, // Let everything warmup gpr_log(GPR_INFO, "Warming up"); gpr_timespec start = gpr_now(); - gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(5))); + gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(warmup_seconds))); // Start a run gpr_log(GPR_INFO, "Starting"); @@ -171,7 +173,7 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, // Wait some time gpr_log(GPR_INFO, "Running"); - gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(15))); + gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(benchmark_seconds))); // Finish a run ScenarioResult result; diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index d87e80dc55..b3a8bf8cc4 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -35,7 +35,7 @@ #define TEST_QPS_DRIVER_H #include "test/cpp/qps/histogram.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" namespace grpc { namespace testing { @@ -54,7 +54,10 @@ struct ScenarioResult { ScenarioResult RunScenario(const grpc::testing::ClientConfig& client_config, size_t num_clients, const grpc::testing::ServerConfig& server_config, - size_t num_servers); + size_t num_servers, + int warmup_seconds, + int benchmark_seconds); + } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h index 7ba00e94c3..eb17821cdc 100644 --- a/test/cpp/qps/histogram.h +++ b/test/cpp/qps/histogram.h @@ -35,7 +35,7 @@ #define TEST_QPS_HISTOGRAM_H #include <grpc/support/histogram.h> -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" namespace grpc { namespace testing { diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc index f7aa8e2aba..f42d538b16 100644 --- a/test/cpp/qps/qps_driver.cc +++ b/test/cpp/qps/qps_driver.cc @@ -40,6 +40,9 @@ DEFINE_int32(num_clients, 1, "Number of client binaries"); DEFINE_int32(num_servers, 1, "Number of server binaries"); +DEFINE_int32(warmup_seconds, 5, "Warmup time (in seconds)"); +DEFINE_int32(benchmark_seconds, 30, "Benchmark time (in seconds)"); + // Common config DEFINE_bool(enable_ssl, false, "Use SSL"); DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING"); @@ -98,8 +101,9 @@ int main(int argc, char** argv) { server_config.set_threads(FLAGS_server_threads); server_config.set_enable_ssl(FLAGS_enable_ssl); - auto result = RunScenario(client_config, FLAGS_num_clients, server_config, - FLAGS_num_servers); + auto result = RunScenario(client_config, FLAGS_num_clients, + server_config, FLAGS_num_servers, + FLAGS_warmup_seconds, FLAGS_benchmark_seconds); gpr_log(GPR_INFO, "QPS: %.1f", result.latencies.Count() / diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index ef71cb94d0..68e0115410 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -35,7 +35,7 @@ #define TEST_QPS_SERVER_H #include "test/cpp/qps/timer.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" namespace grpc { namespace testing { diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 65c170af81..2e366a8d72 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -52,7 +52,7 @@ #include <grpc++/stream.h> #include <gtest/gtest.h> #include "src/cpp/server/thread_pool.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/server.h" #include <grpc/grpc.h> diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 9964429901..2770233a7c 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -47,7 +47,7 @@ #include <grpc++/status.h> #include <grpc++/stream.h> #include "src/cpp/server/thread_pool.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/server.h" #include "test/cpp/qps/timer.h" diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc index b6830cc055..101eb9f969 100644 --- a/test/cpp/qps/worker.cc +++ b/test/cpp/qps/worker.cc @@ -55,7 +55,7 @@ #include <grpc++/stream.h> #include "test/core/util/grpc_profiler.h" #include "test/cpp/util/create_test_channel.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/client.h" #include "test/cpp/qps/server.h" diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 91fc40c31f..32ef392cc4 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -33,7 +33,7 @@ #include "test/core/util/test_config.h" #include "test/cpp/util/cli_call.h" -#include "test/cpp/util/echo.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" #include "src/cpp/server/thread_pool.h" #include <grpc++/channel_arguments.h> #include <grpc++/channel_interface.h> diff --git a/tools/distpackages/build_deb_packages.sh b/tools/distpackages/build_deb_packages.sh index 7dff8e3743..0beb41ed0a 100755 --- a/tools/distpackages/build_deb_packages.sh +++ b/tools/distpackages/build_deb_packages.sh @@ -30,9 +30,13 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Where to put resulting .deb packages. +set -x deb_dest="/tmp/deb_out" mkdir -p $deb_dest +# Where the grpc disto is +grpc_root="/var/local/git/grpc" + # Update version from default values if the file /version.txt exists # # - when present, /version.txt will added by the docker build. @@ -41,7 +45,13 @@ if [ -f /version.txt ]; then pkg_version=$(cat /version.txt) fi version="${pkg_version}.0" -echo "Target release => $pkg_version" +release_tag="release-${pkg_version//./_}" +echo "Target release => $pkg_version, will checkout tag $release_tag" + +# Switch grpc_root to the release tag +pushd $grpc_root +git checkout $release_tag || { echo "bad release tag ${release_tag}"; exit 1; } +popd if [ -f /.dockerinit ]; then # We're in Docker where uname -p returns "unknown". @@ -71,7 +81,9 @@ do if [ $pkg_name == "libgrpc" ] then # Copy shared libraries - (cd ../..; make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib) + pushd $grpc_root + make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib + popd mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir # non-dev package should contain so.0 symlinks @@ -84,7 +96,10 @@ do if [ $pkg_name == "libgrpc-dev" ] then # Copy headers and static libraries - (cd ../..; make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib) + pushd $grpc_root + make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib + popd + mv $tmp_dir/$pkg_name/usr/lib/include $tmp_dir/$pkg_name/usr/include mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir diff --git a/tools/distpackages/templates/libgrpc/DEBIAN/control b/tools/distpackages/templates/libgrpc/DEBIAN/control index 417a825827..5854b1f4a1 100644 --- a/tools/distpackages/templates/libgrpc/DEBIAN/control +++ b/tools/distpackages/templates/libgrpc/DEBIAN/control @@ -2,7 +2,8 @@ Package: libgrpc Version: 0.5.0 Architecture: amd64 Maintainer: Jan Tattermusch <jtattermusch@google.com> -Depends: libc6 +Depends: libc6, openssl (1.0.2-1) +Build-Depends-Indep: openssl (1.0.2-1) Section: libs Priority: optional Homepage: https://github.com/grpc/grpc diff --git a/tools/dockerfile/grpc_build_deb/Dockerfile b/tools/dockerfile/grpc_build_deb/Dockerfile index cf8da594e9..7f025b6712 100644 --- a/tools/dockerfile/grpc_build_deb/Dockerfile +++ b/tools/dockerfile/grpc_build_deb/Dockerfile @@ -33,8 +33,14 @@ FROM grpc/base # Add the file containing the gRPC version ADD version.txt version.txt +# Add the update-to-date distpackages folder +ADD distpackages distpackages + # Install dependencies -RUN apt-get update && apt-get install -y lintian +RUN echo 'deb http://http.debian.net/debian experimental main contrib non-free' >> /etc/apt/sources.list +RUN apt-get update \ + && apt-get -t experimental install -y openssl=1.0.2-1 \ + && apt-get install -y lintian # Get the source from GitHub RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc @@ -42,4 +48,4 @@ RUN cd /var/local/git/grpc && \ git pull --recurse-submodules && \ git submodule update --init --recursive -RUN /bin/bash -l -c 'cd /var/local/git/grpc/tools/distpackages && ./build_deb_packages.sh' +RUN /bin/bash -l -c 'cd /distpackages && ./build_deb_packages.sh' diff --git a/tools/dockerfile/grpc_build_deb/version.txt b/tools/dockerfile/grpc_build_deb/version.txt index 4b9fcbec10..a918a2aa18 100644 --- a/tools/dockerfile/grpc_build_deb/version.txt +++ b/tools/dockerfile/grpc_build_deb/version.txt @@ -1 +1 @@ -0.5.1 +0.6.0 diff --git a/tools/dockerfile/grpc_dist_proto/version.txt b/tools/dockerfile/grpc_dist_proto/version.txt index 8f0916f768..a918a2aa18 100644 --- a/tools/dockerfile/grpc_dist_proto/version.txt +++ b/tools/dockerfile/grpc_dist_proto/version.txt @@ -1 +1 @@ -0.5.0 +0.6.0 diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 0e82ac1d12..40634291cf 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -747,6 +747,11 @@ grpc_build_debs() { local project_opt="--project $grpc_project" local zone_opt="--zone $grpc_zone" + # Update the remote distpackages_dir + local src_dist_dir='tools/distpackages' + local rmt_dist_dir="$host:~" + gcloud compute copy-files $src_dist_dir $rmt_dist_dir $project_opt $zone_opt || return 1 + # rebuild the build_deb image local label='build_deb' grpc_update_image -- -h $host $label || return 1 @@ -1036,6 +1041,35 @@ grpc_interop_gen_python_cmd() { echo $the_cmd } +# constructs the full dockerized python service_account auth interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_service_account_creds_gen_python_cmd() { + local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c"; + local gfe_flags=$(_grpc_prod_gfe_flags) + local added_gfe_flags=$(_grpc_default_creds_test_flags) + local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" + env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json" + local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'" + echo $the_cmd +} + +# constructs the full dockerized python gce auth interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_compute_engine_creds_gen_python_cmd() { + local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c"; + local gfe_flags=$(_grpc_prod_gfe_flags) + local added_gfe_flags=$(_grpc_gce_test_flags) + local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" + local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'" + echo $the_cmd +} + # constructs the full dockerized java interop test cmd. # # call-seq: diff --git a/tools/gce_setup/shared_startup_funcs.sh b/tools/gce_setup/shared_startup_funcs.sh index e6eecc56db..c4a076757a 100755 --- a/tools/gce_setup/shared_startup_funcs.sh +++ b/tools/gce_setup/shared_startup_funcs.sh @@ -434,6 +434,12 @@ grpc_dockerfile_install() { grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1; } + # For deb builds, copy the distpackages folder into the docker directory so + # that it can be installed using ADD distpackages distpackages. + [[ $image_label == "grpc/build_deb" ]] && { + cp -vR ~/distpackages $dockerfile_dir + } + # TODO(temiola): maybe make cache/no-cache a func option? sudo docker build $cache_opt -t $image_label $dockerfile_dir || { echo "$FUNCNAME:: build of $image_label <- $dockerfile_dir" |