From 820c1f3fda95853e791ffe396b15b32d1bda356b Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Thu, 23 Jun 2016 14:31:28 -0400 Subject: [PATCH 001/151] ASSERT vector size before directly accessing first element --- test/cpp/end2end/end2end_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 8de9d339f635d..ea04ab97db239 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1407,7 +1407,7 @@ TEST_P(SecureEnd2endTest, ClientAuthContext) { std::shared_ptr auth_ctx = context.auth_context(); std::vector tst = auth_ctx->FindPropertyValues("transport_security_type"); - EXPECT_EQ(1u, tst.size()); + ASSERT_EQ(1u, tst.size()); EXPECT_EQ(GetParam().credentials_type, ToString(tst[0])); if (GetParam().credentials_type == kTlsCredentialsType) { EXPECT_EQ("x509_subject_alternative_name", From 256cc7aa034f038f8e82f3e278ca61b64252693b Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 7 Jul 2016 11:09:49 -0700 Subject: [PATCH 002/151] Support server reflection in CLI --- Makefile | 8 ++-- build.yaml | 4 ++ test/cpp/util/grpc_cli.cc | 44 ++++++++++--------- test/cpp/util/proto_file_parser.cc | 42 ++++++++++++++++-- test/cpp/util/proto_file_parser.h | 11 +++++ .../proto_reflection_descriptor_database.cc | 12 ++++- tools/run_tests/sources_and_headers.json | 8 +++- .../grpc_cli_libs/grpc_cli_libs.vcxproj | 3 ++ .../grpc_cli_libs.vcxproj.filters | 6 +++ .../vcxproj/test/grpc_cli/grpc_cli.vcxproj | 3 ++ 10 files changed, 111 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 701199637112f..6ba584cbdc56f 100644 --- a/Makefile +++ b/Makefile @@ -4140,6 +4140,7 @@ endif LIBGRPC_CLI_LIBS_SRC = \ test/cpp/util/cli_call.cc \ test/cpp/util/proto_file_parser.cc \ + test/cpp/util/proto_reflection_descriptor_database.cc \ PUBLIC_HEADERS_CXX += \ @@ -11079,16 +11080,16 @@ $(BINDIR)/$(CONFIG)/grpc_cli: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep) @@ -15002,6 +15003,7 @@ test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP) test/cpp/util/cli_call.cc: $(OPENSSL_DEP) test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP) test/cpp/util/proto_file_parser.cc: $(OPENSSL_DEP) +test/cpp/util/proto_reflection_descriptor_database.cc: $(OPENSSL_DEP) test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP) test/cpp/util/subprocess.cc: $(OPENSSL_DEP) test/cpp/util/test_config.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 1c485fd5c9e82..8fabaad7747bb 100644 --- a/build.yaml +++ b/build.yaml @@ -1028,10 +1028,13 @@ libs: headers: - test/cpp/util/cli_call.h - test/cpp/util/proto_file_parser.h + - test/cpp/util/proto_reflection_descriptor_database.h src: - test/cpp/util/cli_call.cc - test/cpp/util/proto_file_parser.cc + - test/cpp/util/proto_reflection_descriptor_database.cc deps: + - grpc++_reflection - grpc++ - grpc_plugin_support - name: grpc_plugin_support @@ -2669,6 +2672,7 @@ targets: - grpc_cli_libs - grpc++_test_util - grpc_test_util + - grpc++_reflection - grpc++ - grpc - gpr_test_util diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index c52e48bae650c..71470e5214ff2 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -86,6 +86,7 @@ DEFINE_string(output_binary_file, "", DEFINE_string(metadata, "", "Metadata to send to server, in the form of key1:val1:key2:val2"); DEFINE_string(proto_path, ".", "Path to look for the proto file."); +DEFINE_string(proto_file, "", "Name of the proto file."); void ParseMetadataFlag( std::multimap* client_metadata) { @@ -129,31 +130,47 @@ void PrintMetadata(const T& m, const grpc::string& message) { int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); - if (argc < 4 || argc == 5 || grpc::string(argv[1]) != "call") { + if (argc < 4 || grpc::string(argv[1]) != "call") { std::cout << "Usage: grpc_cli call server_host:port method_name " << "[proto file] [text format request] []" << std::endl; + return 1; } - grpc::string file_name; grpc::string request_text; grpc::string server_address(argv[2]); grpc::string method_name(argv[3]); std::unique_ptr parser; grpc::string serialized_request_proto; - if (argc == 6) { - file_name = argv[4]; + if (argc == 5) { // TODO(yangg) read from stdin as well? - request_text = argv[5]; + request_text = argv[4]; } + std::shared_ptr creds; + if (!FLAGS_enable_ssl) { + creds = grpc::InsecureChannelCredentials(); + } else { + if (FLAGS_use_auth) { + creds = grpc::GoogleDefaultCredentials(); + } else { + creds = grpc::SslCredentials(grpc::SslCredentialsOptions()); + } + } + std::shared_ptr channel = + grpc::CreateChannel(server_address, creds); + if (request_text.empty() && FLAGS_input_binary_file.empty()) { std::cout << "Missing input. Use text format input or " << "--input_binary_file for serialized request" << std::endl; return 1; } else if (!request_text.empty()) { - parser.reset(new grpc::testing::ProtoFileParser(FLAGS_proto_path, file_name, - method_name)); + if (!FLAGS_proto_file.empty()) { + parser.reset(new grpc::testing::ProtoFileParser( + FLAGS_proto_path, FLAGS_proto_file, method_name)); + } else { + parser.reset(new grpc::testing::ProtoFileParser(channel, method_name)); + } method_name = parser->GetFullMethodName(); if (parser->HasError()) { return 1; @@ -175,19 +192,6 @@ int main(int argc, char** argv) { } std::cout << "connecting to " << server_address << std::endl; - std::shared_ptr creds; - if (!FLAGS_enable_ssl) { - creds = grpc::InsecureChannelCredentials(); - } else { - if (FLAGS_use_auth) { - creds = grpc::GoogleDefaultCredentials(); - } else { - creds = grpc::SslCredentials(grpc::SslCredentialsOptions()); - } - } - std::shared_ptr channel = - grpc::CreateChannel(server_address, creds); - grpc::string serialized_response_proto; std::multimap client_metadata; std::multimap server_initial_metadata, diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc index 25aec329eb30e..2ac19858bf73e 100644 --- a/test/cpp/util/proto_file_parser.cc +++ b/test/cpp/util/proto_file_parser.cc @@ -95,9 +95,45 @@ ProtoFileParser::ProtoFileParser(const grpc::string& proto_path, dynamic_factory_.reset( new google::protobuf::DynamicMessageFactory(importer_->pool())); + std::vector service_desc_list; + for (int i = 0; i < file_desc->service_count(); i++) { + service_desc_list.push_back(file_desc->service(i)); + } + InitProtoFileParser(method, service_desc_list); +} + +ProtoFileParser::ProtoFileParser(std::shared_ptr channel, + const grpc::string& method) + : has_error_(false), + desc_db_(new grpc::ProtoReflectionDescriptorDatabase(channel)), + desc_pool_(new google::protobuf::DescriptorPool(desc_db_.get())) { + std::vector service_list; + if (!desc_db_->GetServices(&service_list)) { + LogError("Failed to get services"); + } + if (has_error_) { + return; + } + dynamic_factory_.reset( + new google::protobuf::DynamicMessageFactory(desc_pool_.get())); + + std::vector service_desc_list; + for (auto it = service_list.begin(); it != service_list.end(); it++) { + service_desc_list.push_back(desc_pool_->FindServiceByName(*it)); + } + InitProtoFileParser(method, service_desc_list); +} + +ProtoFileParser::~ProtoFileParser() {} + +void ProtoFileParser::InitProtoFileParser( + const grpc::string& method, + const std::vector + service_desc_list) { const google::protobuf::MethodDescriptor* method_descriptor = nullptr; - for (int i = 0; !method_descriptor && i < file_desc->service_count(); i++) { - const auto* service_desc = file_desc->service(i); + for (auto it = service_desc_list.begin(); it != service_desc_list.end(); + it++) { + const auto* service_desc = *it; for (int j = 0; j < service_desc->method_count(); j++) { const auto* method_desc = service_desc->method(j); if (MethodNameMatch(method_desc->full_name(), method)) { @@ -130,8 +166,6 @@ ProtoFileParser::ProtoFileParser(const grpc::string& proto_path, dynamic_factory_->GetPrototype(method_descriptor->output_type())->New()); } -ProtoFileParser::~ProtoFileParser() {} - grpc::string ProtoFileParser::GetSerializedProto( const grpc::string& text_format_proto, bool is_request) { grpc::string serialized; diff --git a/test/cpp/util/proto_file_parser.h b/test/cpp/util/proto_file_parser.h index 46cdd6650386d..b442d77db9846 100644 --- a/test/cpp/util/proto_file_parser.h +++ b/test/cpp/util/proto_file_parser.h @@ -38,8 +38,10 @@ #include #include +#include #include "src/compiler/config.h" +#include "test/cpp/util/proto_reflection_descriptor_database.h" namespace grpc { namespace testing { @@ -53,6 +55,9 @@ class ProtoFileParser { // even just Method. It will log an error if there is ambiguity. ProtoFileParser(const grpc::string& proto_path, const grpc::string& file_name, const grpc::string& method); + + ProtoFileParser(std::shared_ptr channel, + const grpc::string& method); ~ProtoFileParser(); grpc::string GetFullMethodName() const { return full_method_name_; } @@ -68,12 +73,18 @@ class ProtoFileParser { void LogError(const grpc::string& error_msg); private: + void InitProtoFileParser( + const grpc::string& method, + const std::vector services); + bool has_error_; grpc::string request_text_; grpc::string full_method_name_; google::protobuf::compiler::DiskSourceTree source_tree_; std::unique_ptr error_printer_; std::unique_ptr importer_; + std::unique_ptr desc_db_; + std::unique_ptr desc_pool_; std::unique_ptr dynamic_factory_; std::unique_ptr request_prototype_; std::unique_ptr response_prototype_; diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index 25b720aee0a36..48998551a59d3 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -53,7 +53,17 @@ ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( std::shared_ptr channel) : stub_(ServerReflection::NewStub(channel)) {} -ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() {} +ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { + if (!stream_) { + GetStream()->WritesDone(); + Status status = stream_->Finish(); + if (!status.ok()) { + gpr_log(GPR_ERROR, + "ServerReflectionInfo rpc failed. Error code: %d, details: %s", + (int)status.error_code(), status.error_message().c_str()); + } + } +} bool ProtoReflectionDescriptorDatabase::FindFileByName( const string& filename, google::protobuf::FileDescriptorProto* output) { diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 6d7cfdaf233f1..86383fa0cccd3 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2149,6 +2149,7 @@ "gpr_test_util", "grpc", "grpc++", + "grpc++_reflection", "grpc++_test_config", "grpc++_test_util", "grpc_cli_libs", @@ -4479,7 +4480,8 @@ ], "headers": [ "test/cpp/util/cli_call.h", - "test/cpp/util/proto_file_parser.h" + "test/cpp/util/proto_file_parser.h", + "test/cpp/util/proto_reflection_descriptor_database.h" ], "language": "c++", "name": "grpc_cli_libs", @@ -4487,7 +4489,9 @@ "test/cpp/util/cli_call.cc", "test/cpp/util/cli_call.h", "test/cpp/util/proto_file_parser.cc", - "test/cpp/util/proto_file_parser.h" + "test/cpp/util/proto_file_parser.h", + "test/cpp/util/proto_reflection_descriptor_database.cc", + "test/cpp/util/proto_reflection_descriptor_database.h" ], "third_party": false, "type": "lib" diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj index 39cb1e0cb5855..03c82f686ccfb 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj @@ -149,12 +149,15 @@ + + + diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters index 55ef18bf3061a..4add8ed5e13ee 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters @@ -7,6 +7,9 @@ test\cpp\util + + test\cpp\util + @@ -15,6 +18,9 @@ test\cpp\util + + test\cpp\util + diff --git a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj index cd844d1579430..9c8cdc54c2506 100644 --- a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj +++ b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj @@ -173,6 +173,9 @@ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + {5F575402-3F89-5D1A-6910-9DB8BF5D2BAB} + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} From c24e0ee4f00a348a2f9948c820cf08be813c5f8a Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 7 Jul 2016 11:32:25 -0700 Subject: [PATCH 003/151] Update docs --- test/cpp/util/grpc_cli.cc | 21 ++++++++++++--------- test/cpp/util/proto_file_parser.cc | 7 +++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index 71470e5214ff2..1a9662694ac2c 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -34,18 +34,21 @@ /* A command line tool to talk to a grpc server. Example of talking to grpc interop server: - grpc_cli call localhost:50051 UnaryCall src/proto/grpc/testing/test.proto \ - "response_size:10" --enable_ssl=false + grpc_cli call localhost:50051 UnaryCall "response_size:10" \ + --proto_file=src/proto/grpc/testing/test.prot --enable_ssl=false Options: - 1. --proto_path, if your proto file is not under current working directory, + 1. --proto_file, use this flag to provide a proto file if the server does + does not have the reflection service. + 2. --proto_path, if your proto file is not under current working directory, use this flag to provide a search root. It should work similar to the - counterpart in protoc. - 2. --metadata specifies metadata to be sent to the server, such as: + counterpart in protoc. This option is valid only when proto_file is + provided. + 3. --metadata specifies metadata to be sent to the server, such as: --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" - 3. --enable_ssl, whether to use tls. - 4. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call - 3. --input_binary_file, a file containing the serialized request. The file + 4. --enable_ssl, whether to use tls. + 5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call + 6. --input_binary_file, a file containing the serialized request. The file can be generated by calling something like: protoc --proto_path=src/proto/grpc/testing/ \ --encode=grpc.testing.SimpleRequest \ @@ -53,7 +56,7 @@ < input.txt > input.bin If this is used and no proto file is provided in the argument list, the method string has to be exact in the form of /package.service/method. - 4. --output_binary_file, a file to write binary format response into, it can + 7. --output_binary_file, a file to write binary format response into, it can be later decoded using protoc: protoc --proto_path=src/proto/grpc/testing/ \ --decode=grpc.testing.SimpleResponse \ diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc index 2ac19858bf73e..b1bf0471e159e 100644 --- a/test/cpp/util/proto_file_parser.cc +++ b/test/cpp/util/proto_file_parser.cc @@ -109,7 +109,10 @@ ProtoFileParser::ProtoFileParser(std::shared_ptr channel, desc_pool_(new google::protobuf::DescriptorPool(desc_db_.get())) { std::vector service_list; if (!desc_db_->GetServices(&service_list)) { - LogError("Failed to get services"); + LogError( + "Failed to get services from the server, " + "it may not have the reflection service.\n" + "Please try to use the --proto_file option to provide a proto file."); } if (has_error_) { return; @@ -177,7 +180,7 @@ grpc::string ProtoFileParser::GetSerializedProto( LogError("Failed to parse text format to proto."); return ""; } - ok = request_prototype_->SerializeToString(&serialized); + ok = msg->SerializeToString(&serialized); if (!ok) { LogError("Failed to serialize proto."); return ""; From a17c8d993d3bc4867fcc9d6fcf42e6bfff9c9cd8 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 7 Jul 2016 11:40:05 -0700 Subject: [PATCH 004/151] Fix typos --- test/cpp/util/grpc_cli.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index 1a9662694ac2c..7c8e2cdc639f3 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -35,7 +35,7 @@ A command line tool to talk to a grpc server. Example of talking to grpc interop server: grpc_cli call localhost:50051 UnaryCall "response_size:10" \ - --proto_file=src/proto/grpc/testing/test.prot --enable_ssl=false + --proto_file=src/proto/grpc/testing/test.proto --enable_ssl=false Options: 1. --proto_file, use this flag to provide a proto file if the server does From 39070fe3a536819708aaa4422ea912b303cbe30f Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 7 Jul 2016 13:57:12 -0700 Subject: [PATCH 005/151] Rerun generate_projects.sh --- tools/run_tests/sources_and_headers.json | 1 + vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj | 3 +++ 2 files changed, 4 insertions(+) diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 86383fa0cccd3..141c8982667a7 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4476,6 +4476,7 @@ { "deps": [ "grpc++", + "grpc++_reflection", "grpc_plugin_support" ], "headers": [ diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj index 03c82f686ccfb..d25c692e3e812 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj @@ -160,6 +160,9 @@ + + {5F575402-3F89-5D1A-6910-9DB8BF5D2BAB} + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} From 1c58bd221da3f67cc612149b99a7efe49bb884cb Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 7 Jul 2016 14:17:32 -0700 Subject: [PATCH 006/151] Enable server reflection in c++ examples --- examples/cpp/helloworld/Makefile | 4 +++- examples/cpp/route_guide/Makefile | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile index 780e5e427a767..a632f1b1262f2 100644 --- a/examples/cpp/helloworld/Makefile +++ b/examples/cpp/helloworld/Makefile @@ -32,7 +32,9 @@ CXX = g++ CPPFLAGS += -I/usr/local/include -pthread CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` -lprotobuf -lpthread -ldl +LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` \ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \ + -lprotobuf -lpthread -ldl PROTOC = protoc GRPC_CPP_PLUGIN = grpc_cpp_plugin GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile index 11f2a00cc8909..237152ecd32c0 100644 --- a/examples/cpp/route_guide/Makefile +++ b/examples/cpp/route_guide/Makefile @@ -32,7 +32,9 @@ CXX = g++ CPPFLAGS += -I/usr/local/include -pthread CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` -lprotobuf -lpthread -ldl +LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \ + -lprotobuf -lpthread -ldl PROTOC = protoc GRPC_CPP_PLUGIN = grpc_cpp_plugin GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` From c68640f05cea2cf79bf2703d83da6b76fa6dc5e6 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 7 Jul 2016 14:13:35 -0700 Subject: [PATCH 007/151] Read from stdin Read from stdin if the request text and binary file are not provided --- test/cpp/util/grpc_cli.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index 7c8e2cdc639f3..fdb1a7c2a0035 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -64,6 +64,7 @@ < output.bin > output.txt */ +#include #include #include #include @@ -146,7 +147,6 @@ int main(int argc, char** argv) { grpc::string serialized_request_proto; if (argc == 5) { - // TODO(yangg) read from stdin as well? request_text = argv[4]; } @@ -164,10 +164,15 @@ int main(int argc, char** argv) { grpc::CreateChannel(server_address, creds); if (request_text.empty() && FLAGS_input_binary_file.empty()) { - std::cout << "Missing input. Use text format input or " - << "--input_binary_file for serialized request" << std::endl; - return 1; - } else if (!request_text.empty()) { + if (isatty(STDIN_FILENO)) { + std::cout << "reading request message from stdin..." << std::endl; + } + std::stringstream input_stream; + input_stream << std::cin.rdbuf(); + request_text = input_stream.str(); + } + + if (!request_text.empty()) { if (!FLAGS_proto_file.empty()) { parser.reset(new grpc::testing::ProtoFileParser( FLAGS_proto_path, FLAGS_proto_file, method_name)); @@ -178,6 +183,12 @@ int main(int argc, char** argv) { if (parser->HasError()) { return 1; } + + if (!FLAGS_input_binary_file.empty()) { + std::cout + << "warning: request given in argv, ignoring --input_binary_file" + << std::endl; + } } if (parser) { @@ -226,7 +237,7 @@ int main(int argc, char** argv) { } } else { std::cout << "Rpc failed with status code " << s.error_code() - << " error message " << s.error_message() << std::endl; + << ", error message: " << s.error_message() << std::endl; } return 0; From 4bb1a9d8d8fd12556a10e063151f75a746e5b86b Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Fri, 8 Jul 2016 17:13:57 -0700 Subject: [PATCH 008/151] added lb diagram and some more detail --- doc/images/load_balancing_design.png | Bin 0 -> 38180 bytes doc/load-balancing.md | 73 ++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 doc/images/load_balancing_design.png diff --git a/doc/images/load_balancing_design.png b/doc/images/load_balancing_design.png new file mode 100644 index 0000000000000000000000000000000000000000..716378c0db20da9875b0cc1892e0e1aa217c1540 GIT binary patch literal 38180 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

oXQe~N~ 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 Vn`JgvQafaeb~dMumLGP%{U5zNV6gxI literal 0 HcmV?d00001 diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 681be02a72f04..05d555a3f1334 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -4,7 +4,7 @@ Load Balancing in gRPC # Objective To design a load balancing API between a gRPC client and a Load Balancer to -instruct the client how to send load to multiple backend servers. +instruct the client how to send load to multiple backend servers. # Background @@ -19,7 +19,7 @@ have temporary copies of the RPC request and response. This model also increases latency to the RPCs. The proxy model was deemed inefficient when considering request heavy services -like storage. +like storage. ### Balancing-aware Client @@ -28,7 +28,7 @@ example, the client could contain many load balancing policies (Round Robin, Random, etc) used to select servers from a list. In this model, a list of servers would be either statically configured in the client, provided by the name resolution system, an external load balancer, etc. In any case, the client -is responsible for choosing the preferred server from the list. +is responsible for choosing the preferred server from the list. One of the drawbacks of this approach is writing and maintaining the load balancing policies in multiple languages and/or versions of the clients. These @@ -53,14 +53,67 @@ unavailability or health issues. The load balancer will make any necessary complex decisions and inform the client. The load balancer may communicate with the backend servers to collect load and health information. + +## Requirements + +#### Simple API and client + +The gRPC client load balancing code must be simple and portable. The client +should only contain simple algorithms (ie Round Robin) for server selection. For +complex algorithms, the client should rely on a load balancer to provide load +balancing configuration and the list of servers to which the client should send +requests. The balancer will update the server list as needed to balance the load +as well as handle server unavailability or health issues. The load balancer will +make any necessary complex decisions and inform the client. The load balancer +may communicate with the backend servers to collect load and health information. + +#### Security + +The load balancer may be separate from the actual server backends and a +compromise of the load balancer should only lead to a compromise of the +loadbalancing functionality. In other words, a compromised load balancer should +not be able to cause a client to trust a (potentially malicious) backend server +any more than in a comparable situation without loadbalancing. + # Proposed Architecture -The gRPC load balancing approach follows the third approach, by having an -external load balancer which provides simple clients with a list of servers. +The gRPC load balancing implements the external load balancing server approach: +an external load balancer provides simple clients with an up-to-date list of +servers. + +![image](images/load_balancing_design.png) + +1. On startup, the gRPC client issues a name resolution request for the service. + The name will resolve to one or more IP addresses to gRPC servers, a hint on + whether the IP address(es) point to a load balancer or not, and also return a + client config. +2. The gRPC client connects to a gRPC Server. + 1. If the name resolution has hinted that the endpoint is a load balancer, + the client will attempt to open a stream to the load balancer service. The + server may respond in only one of the following ways. + 1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client + proceeds by sending all RPCs to this gRPC server. + 1. "I am a Load Balancer and here is the server list." (Goto Step 4.) + 1. "Please contact Load Balancer X" (See Step 3.) The client will close + this connection and cancel the stream. + 1. If the server fails to respond, the client will wait for some timeout + and then re-resolve the name (process to Step 1 above). + 1. If the name resolution has not hinted that the endpoint is a load + balancer, the client connects directly to the service it wants to talk to. +3. The gRPC client opens a separate connection to the Load Balancer. If this + fails, it will go back to step 1 and try another address. + 1. During channel initialization to the Load Balancer, the client will + attempt to open a stream to the Load Balancer service. + 1. The load balancer will return a server list to the gRPC client. + Optional: The load balancer will also open channels to the gRPC servers if + load reporting is needed. +4. The gRPC client will send RPCs to the gRPC servers contained in the server + list from the load balancer. +5. Optional: The gRPC servers may periodically report load to the Load Balancer. ## Client -When establishing a gRPC stream to the balancer, the client will send an initial +When establishing a gRPC _stream_ to the balancer, the client will send an initial request to the load balancer (via a regular gRPC message). The load balancer will respond with client config (including, for example, settings for flow control, RPC deadlines, etc.) or a redirect to another load balancer. If the @@ -87,11 +140,3 @@ balancer in order to compute the next list of servers. The gRPC Server is responsible for answering RPC requests and providing responses to the client. The server will also report load to the load balancer if a reporting stream was opened for this purpose. - -### Security - -The load balancer may be separate from the actual server backends and a -compromise of the load balancer should only lead to a compromise of the -loadbalancing functionality. In other words, a compromised load balancer should -not be able to cause a client to trust a (potentially malicious) backend server -any more than in a comparable situation without loadbalancing. From 52664ccee592f884435a668b9d4da25f62b4eca3 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Sat, 9 Jul 2016 11:24:30 +0800 Subject: [PATCH 009/151] Fix orig files for conflicting generated --- .gitignore | 3 ++ tools/run_tests/sanity/check_orig_mk.sh | 39 ++++++++++++++++++++++++ tools/run_tests/sanity/sanity_tests.yaml | 1 + 3 files changed, 43 insertions(+) create mode 100755 tools/run_tests/sanity/check_orig_mk.sh diff --git a/.gitignore b/.gitignore index f37989176ea38..09223fa1ead49 100644 --- a/.gitignore +++ b/.gitignore @@ -96,3 +96,6 @@ Pods/ # Artifacts directory artifacts/ + +# Git generated files for conflicting +*.orig diff --git a/tools/run_tests/sanity/check_orig_mk.sh b/tools/run_tests/sanity/check_orig_mk.sh new file mode 100755 index 0000000000000..142ef009ace39 --- /dev/null +++ b/tools/run_tests/sanity/check_orig_mk.sh @@ -0,0 +1,39 @@ +#!/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 + +if [ -f *.orig ] ; then + echo "Please don't commit *.orig file" + exit 1 +fi + diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index e699c5194df8f..dde05131cd243 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -1,5 +1,6 @@ # a set of tests that are run in parallel for sanity tests - script: tools/run_tests/sanity/check_cache_mk.sh +- script: tools/run_tests/sanity/check_orig_mk.sh - script: tools/run_tests/sanity/check_sources_and_headers.py - script: tools/run_tests/sanity/check_submodules.sh - script: tools/buildgen/generate_projects.sh -j 3 From 9f340958f6d131ae7d510270f1f60df7b277e994 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 11 Jul 2016 15:15:40 -0700 Subject: [PATCH 010/151] Remove unnecessary parsing detail --- .../transport/chttp2/transport/chttp2_transport.c | 13 ++++++------- test/core/end2end/bad_server_response_test.c | 4 +++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 38e782b9b4fc7..01a19eca05dd4 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1764,6 +1764,7 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx, static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_chttp2_transport *t = arg; + grpc_error *err = GRPC_ERROR_NONE; GPR_TIMER_BEGIN("reading_action.parse", 0); size_t i = 0; grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, @@ -1772,15 +1773,13 @@ static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, errors[1] = grpc_chttp2_perform_read(exec_ctx, &t->parsing, t->read_buffer.slices[i]); }; - if (i != t->read_buffer.count) { + if (errors[1] == GRPC_ERROR_NONE) { + err = GRPC_ERROR_REF(error); + } else { errors[2] = try_http_parsing(exec_ctx, t); + err = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors, + GPR_ARRAY_SIZE(errors)); } - grpc_error *err = - errors[0] == GRPC_ERROR_NONE && errors[1] == GRPC_ERROR_NONE && - errors[2] == GRPC_ERROR_NONE - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors, - GPR_ARRAY_SIZE(errors)); for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) { GRPC_ERROR_UNREF(errors[i]); } diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c index cca75f54a5f4f..ab80adf0e0643 100644 --- a/test/core/end2end/bad_server_response_test.c +++ b/test/core/end2end/bad_server_response_test.c @@ -71,6 +71,8 @@ #define UNPARSEABLE_DETAIL_MSG "Failed parsing HTTP/2" +#define HTTP1_DETAIL_MSG "Trying to connect an http1.x server" + /* TODO(zyc) Check the content of incomming data instead of using this length */ #define EXPECTED_INCOMING_DATA_LENGTH (size_t)310 @@ -334,7 +336,7 @@ int main(int argc, char **argv) { /* http1 response */ run_test(HTTP1_RESP, sizeof(HTTP1_RESP) - 1, GRPC_STATUS_UNAVAILABLE, - UNPARSEABLE_DETAIL_MSG); + HTTP1_DETAIL_MSG); return 0; } From 9275d4067cfd9233edf2ae9a0fe1255c8c730f19 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 11 Jul 2016 16:51:39 -0700 Subject: [PATCH 011/151] Shutdown the listeners early when destroying the tcp_server --- .../chttp2/server/insecure/server_chttp2.c | 1 + .../chttp2/server/secure/server_secure_chttp2.c | 1 + src/core/lib/iomgr/tcp_server.h | 4 ++++ src/core/lib/iomgr/tcp_server_posix.c | 13 +++++++++++++ src/core/lib/iomgr/tcp_server_windows.c | 3 +++ 5 files changed, 22 insertions(+) diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index e5c987925c3bd..054f15c8ff434 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -74,6 +74,7 @@ static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, grpc_closure *destroy_done) { grpc_tcp_server *tcp = tcpp; + grpc_tcp_server_shutdown_listeners(exec_ctx, tcp); grpc_tcp_server_unref(exec_ctx, tcp); grpc_exec_ctx_sched(exec_ctx, destroy_done, GRPC_ERROR_NONE, NULL); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index c42810e9130a5..7131cf5972ce4 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -166,6 +166,7 @@ static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, state->destroy_callback = callback; tcp = state->tcp; gpr_mu_unlock(&state->mu); + grpc_tcp_server_shutdown_listeners(exec_ctx, tcp); grpc_tcp_server_unref(exec_ctx, tcp); } diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h index 875a6ca14a7a8..5a25d39a0c4c3 100644 --- a/src/core/lib/iomgr/tcp_server.h +++ b/src/core/lib/iomgr/tcp_server.h @@ -105,4 +105,8 @@ void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, a call (exec_ctx!=NULL) to shutdown_complete. */ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s); +/* Shutdown the fds of listeners. */ +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s); + #endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_H */ diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index d3803c3bd0e4d..7b713723cec71 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -740,4 +740,17 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { } } +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s) { + gpr_mu_lock(&s->mu); + /* shutdown all fd's */ + if (s->active_ports) { + grpc_tcp_listener *sp; + for (sp = s->head; sp; sp = sp->next) { + grpc_fd_shutdown(exec_ctx, sp->emfd); + } + } + gpr_mu_unlock(&s->mu); +} + #endif diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c index 7b0966704c2bf..1b125e7005be3 100644 --- a/src/core/lib/iomgr/tcp_server_windows.c +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -540,4 +540,7 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, gpr_mu_unlock(&s->mu); } +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s) {} + #endif /* GPR_WINSOCK_SOCKET */ From 580a64af2499a98fae7cf3644ca89f32963e757a Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 12 Jul 2016 13:54:09 -0700 Subject: [PATCH 012/151] Improved some Ruby inline documentation --- src/ruby/lib/grpc/generic/bidi_call.rb | 2 +- src/ruby/lib/grpc/generic/client_stub.rb | 24 +++++++++++++++++------- src/ruby/lib/grpc/generic/rpc_server.rb | 12 ++++-------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb index 425dc3e519875..c2ac3c4dafea6 100644 --- a/src/ruby/lib/grpc/generic/bidi_call.rb +++ b/src/ruby/lib/grpc/generic/bidi_call.rb @@ -76,7 +76,7 @@ def initialize(call, marshal, unmarshal, metadata_received: false) # block that can be invoked with each response. # # @param requests the Enumerable of requests to send - # @op_notifier a Notifier used to signal completion + # @param op_notifier a Notifier used to signal completion # @return an Enumerator of requests to yield def run_on_client(requests, op_notifier, &blk) @op_notifier = op_notifier diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb index 9d6bd3bf59001..0d7c1f7805e67 100644 --- a/src/ruby/lib/grpc/generic/client_stub.rb +++ b/src/ruby/lib/grpc/generic/client_stub.rb @@ -34,7 +34,8 @@ module GRPC # rubocop:disable Metrics/ParameterLists - # ClientStub represents an endpoint used to send requests to GRPC servers. + # ClientStub represents a client connection to a gRPC server, and can be used + # to send requests. class ClientStub include Core::StatusCodes include Core::TimeConsts @@ -75,8 +76,9 @@ def self.setup_channel(alt_chan, host, creds, channel_args = {}) # my_stub = ClientStub.new(example.host.com:50505, # :this_channel_is_insecure) # - # Any arbitrary keyword arguments are treated as channel arguments used to - # configure the RPC connection to the host. + # If a channel_override argument is passed, it will be used as the + # underlying channel. Otherwise, the channel_args argument will be used + # to construct a new underlying channel. # # There are some specific keyword args that are not used to configure the # channel: @@ -91,10 +93,17 @@ def self.setup_channel(alt_chan, host, creds, channel_args = {}) # # @param host [String] the host the stub connects to # @param creds [Core::ChannelCredentials|Symbol] the channel credentials, or - # :this_channel_is_insecure + # :this_channel_is_insecure, which explicitly indicates that the client + # should be created with an insecure connection. Note: this argument is + # ignored if the channel_override argument is provided. # @param channel_override [Core::Channel] a pre-created channel # @param timeout [Number] the default timeout to use in requests - # @param channel_args [Hash] the channel arguments + # @param propagate_mask [Number] A bitwise combination of flags in + # GRPC::Core::PropagateMasks. Indicates how data should be propagated + # from parent server calls to child client calls if this client is being + # used within a gRPC server. + # @param channel_args [Hash] the channel arguments. Note: this argument is + # ignored if the channel_override argument is provided. def initialize(host, creds, channel_override: nil, timeout: nil, @@ -389,11 +398,11 @@ def server_streamer(method, req, marshal, unmarshal, # @param marshal [Function] f(obj)->string that marshals requests # @param unmarshal [Function] f(string)->obj that unmarshals responses # @param deadline [Time] (optional) the time the request should complete + # @param return_op [true|false] return an Operation if true # @param parent [Core::Call] a prior call whose reserved metadata # will be propagated by this one. # @param credentials [Core::CallCredentials] credentials to use when making # the call - # @param return_op [true|false] return an Operation if true # @param metadata [Hash] metadata to be sent to the server # @param blk [Block] when provided, is executed for each response # @return [Enumerator|nil|Operation] as discussed above @@ -430,7 +439,8 @@ def bidi_streamer(method, requests, marshal, unmarshal, # @param unmarshal [Function] f(string)->obj that unmarshals responses # @param parent [Grpc::Call] a parent call, available when calls are # made from server - # @param timeout [TimeConst] + # @param credentials [Core::CallCredentials] credentials to use when making + # the call def new_active_call(method, marshal, unmarshal, deadline: nil, parent: nil, diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index c92a532a50085..7ea2371365fda 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -172,22 +172,18 @@ def self.setup_connect_md_proc(a_proc) # The RPC server is configured using keyword arguments. # # There are some specific keyword args used to configure the RpcServer - # instance, however other arbitrary are allowed and when present are used - # to configure the listeninng connection set up by the RpcServer. - # - # * poll_period: when present, the server polls for new events with this - # period + # instance. # # * pool_size: the size of the thread pool the server uses to run its # threads # - # * creds: [GRPC::Core::ServerCredentials] - # the credentials used to secure the server - # # * max_waiting_requests: the maximum number of requests that are not # being handled to allow. When this limit is exceeded, the server responds # with not available to new requests # + # * poll_period: when present, the server polls for new events with this + # period + # # * connect_md_proc: # when non-nil is a proc for determining metadata to to send back the client # on receiving an invocation req. The proc signature is: From 165f9a713b658a73ff0cc8480714a24406f519af Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Tue, 12 Jul 2016 16:17:46 -0700 Subject: [PATCH 013/151] Restructure reStructured text to be valid --- tools/distrib/python/grpcio_tools/README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst index 8946a1d5b31be..4e5263ded5ad7 100644 --- a/tools/distrib/python/grpcio_tools/README.rst +++ b/tools/distrib/python/grpcio_tools/README.rst @@ -122,6 +122,7 @@ Help, I ... third_party/protobuf/src/google/protobuf/stubs/mathlimits.h:173:31: note: in expansion of macro 'SIGNED_INT_MAX' static const Type kPosMax = SIGNED_INT_MAX(Type); \\ ^ + And your toolchain is GCC (at the time of this writing, up through at least GCC 6.0), this is probably a bug where GCC chokes on constant expressions when the :code:`-fwrapv` flag is specified. You should consider setting your From 67bccfed99106e474bce80268de79d61e2859758 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 13 Jul 2016 08:37:29 -0700 Subject: [PATCH 014/151] php: prepare for GA release --- examples/php/README.md | 2 +- package.xml | 18 ++++++++++-------- src/php/README.md | 6 +++--- templates/package.xml.template | 18 ++++++++++-------- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/examples/php/README.md b/examples/php/README.md index 6889a6cb7e012..54cc97d8c2f8c 100644 --- a/examples/php/README.md +++ b/examples/php/README.md @@ -11,7 +11,7 @@ INSTALL - Install the gRPC PHP extension ```sh - $ [sudo] pecl install grpc-beta + $ [sudo] pecl install grpc ``` - Clone this repository diff --git a/package.xml b/package.xml index 3d7cb8702e97a..c5006dade576c 100644 --- a/package.xml +++ b/package.xml @@ -10,18 +10,19 @@ grpc-packages@google.com yes - 2016-06-30 + 2016-07-13 1.0.0 1.0.0 - beta - beta + stable + stable BSD +- GA release - Fix shutdown hang problem #4017 @@ -1086,16 +1087,17 @@ Update to wrap gRPC C Core version 0.10.0 - 0.15.1 - 0.15.1 + 1.0.0 + 1.0.0 - beta - beta + stable + stable - 2016-06-30 + 2016-07-13 BSD +- GA release - Fix shutdown hang problem #4017 diff --git a/src/php/README.md b/src/php/README.md index 6cc1ba4d46264..fba2c0f13b94d 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -5,7 +5,7 @@ This directory contains source code for PHP implementation of gRPC layered on sh #Status -Beta +GA ## Environment @@ -43,7 +43,7 @@ $ sudo mv phpunit-old.phar /usr/bin/phpunit Install the gRPC PHP extension ```sh -sudo pecl install grpc-beta +sudo pecl install grpc ``` This will compile and install the gRPC PHP extension into the standard PHP extension directory. You should be able to run the [unit tests](#unit-tests), with the PHP extension installed. @@ -75,7 +75,7 @@ $ sudo make install Install the gRPC PHP extension from PECL ```sh -$ sudo pecl install grpc-beta +$ sudo pecl install grpc ``` Or, compile from source diff --git a/templates/package.xml.template b/templates/package.xml.template index d8155cdd8235f..153823ece5b68 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,18 +12,19 @@ grpc-packages@google.com yes - 2016-06-30 + 2016-07-13 ${settings.php_version.php()} ${settings.php_version.php()} - beta - beta + stable + stable BSD + - GA release - Fix shutdown hang problem #4017 @@ -205,16 +206,17 @@ - 0.15.1 - 0.15.1 + 1.0.0 + 1.0.0 - beta - beta + stable + stable - 2016-06-30 + 2016-07-13 BSD + - GA release - Fix shutdown hang problem #4017 From 74e03a24ae2d1e750b13b3f6b93c37020573eda8 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 13 Jul 2016 10:12:17 -0700 Subject: [PATCH 015/151] Add handshaker API. --- src/core/lib/channel/handshaker.c | 53 +++++++++++++++++++++++ src/core/lib/channel/handshaker.h | 71 +++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 src/core/lib/channel/handshaker.c create mode 100644 src/core/lib/channel/handshaker.h diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c new file mode 100644 index 0000000000000..00d810e63df1e --- /dev/null +++ b/src/core/lib/channel/handshaker.c @@ -0,0 +1,53 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/lib/channel/handshaker.h" + +void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, + grpc_handshaker** handshaker) { + handshaker->vtable = vtable; +} + +void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker) { + handshaker->vtable->destroy(exec_ctx, handshaker); +} + +void grpc_handshaker_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* endpoint_in, gpr_timespec deadline, grpc_closure *on_done) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint_in, + deadline, on_done); +} + +#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h new file mode 100644 index 0000000000000..1ca85fd0088e4 --- /dev/null +++ b/src/core/lib/channel/handshaker.h @@ -0,0 +1,71 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H +#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H + +#include + +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/exec_ctx.h" + +// FIXME: document + +typedef struct grpc_handshaker grpc_handshaker; + +struct grpc_handshaker_vtable { + void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + + void (*do_handshake)( + grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* endpoint_in, gpr_timespec deadline, + grpc_closure *on_done); +}; + +struct grpc_handshaker { + const struct grpc_handshaker_vtable *vtable; +}; + +// Called by concrete implementations to initialize the base struct. +void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, + grpc_handshaker** handshaker); + +// Convenient wrappers for invoking methods via the vtable. +void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker); +void grpc_handshaker_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* in, gpr_timespec deadline, grpc_closure *on_done); + +#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 7deb5fd79562388a928aaa3da37bbc8921ebc162 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 13 Jul 2016 11:40:56 -0700 Subject: [PATCH 016/151] Establish Objective C end-to-end core test with Cronet --- gRPC-Cronet.podspec | 88 ++++ .../End2EndTest.xcodeproj/project.pbxproj | 405 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../End2EndTest/End2EndTest/AppDelegate.h | 17 + .../End2EndTest/End2EndTest/AppDelegate.m | 45 ++ .../AppIcon.appiconset/Contents.json | 38 ++ .../Base.lproj/LaunchScreen.storyboard | 27 ++ .../End2EndTest/Base.lproj/Main.storyboard | 25 ++ .../tests/End2EndTest/End2EndTest/Info.plist | 40 ++ .../End2EndTest/End2EndTest/ViewController.h | 15 + .../End2EndTest/End2EndTest/ViewController.m | 27 ++ .../tests/End2EndTest/End2EndTest/h2_ssl.m | 199 +++++++++ .../tests/End2EndTest/End2EndTest/main.m | 16 + src/objective-c/tests/End2EndTest/Podfile | 83 ++++ 14 files changed, 1032 insertions(+) create mode 100644 gRPC-Cronet.podspec create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/Info.plist create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m create mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/main.m create mode 100644 src/objective-c/tests/End2EndTest/Podfile diff --git a/gRPC-Cronet.podspec b/gRPC-Cronet.podspec new file mode 100644 index 0000000000000..8db5490e0e4aa --- /dev/null +++ b/gRPC-Cronet.podspec @@ -0,0 +1,88 @@ +# GRPC CocoaPods podspec +# This file has been automatically generated from a template file. +# Please look at the templates directory instead. +# This file can be regenerated from the template by running +# tools/buildgen/generate_projects.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. + + +Pod::Spec.new do |s| + s.name = 'gRPC-Cronet' + version = '0.14.0' + s.version = version + s.summary = 'Integration of CroNet framework into gRPC' + s.homepage = 'http://www.grpc.io' + s.license = 'New BSD' + s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } + + s.source = { + :git => 'https://github.com/grpc/grpc.git', + :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + } + + s.ios.deployment_target = '7.1' + s.osx.deployment_target = '10.9' + s.requires_arc = false + + name = 'grpc' + + s.module_name = name + + s.header_mappings_dir = '.' + + src_root = '$(PODS_ROOT)/gRPC-Cronet' + s.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/support/string.h` shadow the system `` and ``, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } + + s.subspec 'Interface' do |ss| + ss.header_mappings_dir = 'include/grpc' + ss.source_files = 'include/grpc/grpc_cronet.h' + end + + s.subspec 'Implementation' do |ss| + ss.header_mappings_dir = '.' + + ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', + 'src/core/ext/transport/cronet/transport/cronet_transport.c', + 'test/core/end2end/**/*.{c,h}', + 'test/core/util' + + ss.dependency 'gRPC-Core', version + end +end diff --git a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000..bc5006e9366ec --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj @@ -0,0 +1,405 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 5E201A771D3452D500A81F3A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E201A761D3452D500A81F3A /* AppDelegate.m */; }; + 5E201A7A1D3452D500A81F3A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E201A791D3452D500A81F3A /* ViewController.m */; }; + 5E201A7D1D3452D500A81F3A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A7B1D3452D500A81F3A /* Main.storyboard */; }; + 5E201A7F1D3452D600A81F3A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A7E1D3452D600A81F3A /* Assets.xcassets */; }; + 5E201A821D3452D600A81F3A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */; }; + 5EC76B971D36B2EE00A74FED /* h2_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EC76B961D36B2EE00A74FED /* h2_ssl.m */; }; + C124E05DC4ED9F5CA3EFD20D /* libPods-End2EndTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 931C29940B821E295AA90634 /* libPods-End2EndTest.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-End2EndTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest.debug.xcconfig"; sourceTree = ""; }; + 5E201A6F1D3452D500A81F3A /* End2EndTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = End2EndTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E201A751D3452D500A81F3A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5E201A761D3452D500A81F3A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5E201A781D3452D500A81F3A /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5E201A791D3452D500A81F3A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5E201A7C1D3452D500A81F3A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5E201A7E1D3452D600A81F3A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5E201A811D3452D600A81F3A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5E201A831D3452D600A81F3A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EC76B961D36B2EE00A74FED /* h2_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl.m; sourceTree = ""; }; + 931C29940B821E295AA90634 /* libPods-End2EndTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-End2EndTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + E7725B916D22B5AC6ECF8964 /* Pods-End2EndTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-End2EndTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5E201A6C1D3452D500A81F3A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C124E05DC4ED9F5CA3EFD20D /* libPods-End2EndTest.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 52027776D515577217FE123B /* Pods */ = { + isa = PBXGroup; + children = ( + 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */, + E7725B916D22B5AC6ECF8964 /* Pods-End2EndTest.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 5E201A661D3452D500A81F3A = { + isa = PBXGroup; + children = ( + 5E201A711D3452D500A81F3A /* End2EndTest */, + 5E201A701D3452D500A81F3A /* Products */, + 52027776D515577217FE123B /* Pods */, + D564C37197511893E4E62D12 /* Frameworks */, + ); + sourceTree = ""; + }; + 5E201A701D3452D500A81F3A /* Products */ = { + isa = PBXGroup; + children = ( + 5E201A6F1D3452D500A81F3A /* End2EndTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 5E201A711D3452D500A81F3A /* End2EndTest */ = { + isa = PBXGroup; + children = ( + 5E201A751D3452D500A81F3A /* AppDelegate.h */, + 5E201A761D3452D500A81F3A /* AppDelegate.m */, + 5E201A781D3452D500A81F3A /* ViewController.h */, + 5E201A791D3452D500A81F3A /* ViewController.m */, + 5E201A7B1D3452D500A81F3A /* Main.storyboard */, + 5E201A7E1D3452D600A81F3A /* Assets.xcassets */, + 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */, + 5E201A831D3452D600A81F3A /* Info.plist */, + 5E201A721D3452D500A81F3A /* Supporting Files */, + ); + path = End2EndTest; + sourceTree = ""; + }; + 5E201A721D3452D500A81F3A /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5EC76B961D36B2EE00A74FED /* h2_ssl.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + D564C37197511893E4E62D12 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 931C29940B821E295AA90634 /* libPods-End2EndTest.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5E201A6E1D3452D500A81F3A /* End2EndTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E201A861D3452D600A81F3A /* Build configuration list for PBXNativeTarget "End2EndTest" */; + buildPhases = ( + B6E7E45E860B5453E3A5F4A0 /* [CP] Check Pods Manifest.lock */, + 5E201A6B1D3452D500A81F3A /* Sources */, + 5E201A6C1D3452D500A81F3A /* Frameworks */, + 5E201A6D1D3452D500A81F3A /* Resources */, + AE303423292913AB8D447419 /* [CP] Embed Pods Frameworks */, + A4C61E4A2A73F6E1E1143310 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = End2EndTest; + productName = End2EndTest; + productReference = 5E201A6F1D3452D500A81F3A /* End2EndTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5E201A671D3452D500A81F3A /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0730; + ORGANIZATIONNAME = Google; + TargetAttributes = { + 5E201A6E1D3452D500A81F3A = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 5E201A6A1D3452D500A81F3A /* Build configuration list for PBXProject "End2EndTest" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5E201A661D3452D500A81F3A; + productRefGroup = 5E201A701D3452D500A81F3A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5E201A6E1D3452D500A81F3A /* End2EndTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5E201A6D1D3452D500A81F3A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E201A821D3452D600A81F3A /* LaunchScreen.storyboard in Resources */, + 5E201A7F1D3452D600A81F3A /* Assets.xcassets in Resources */, + 5E201A7D1D3452D500A81F3A /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + A4C61E4A2A73F6E1E1143310 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + AE303423292913AB8D447419 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + B6E7E45E860B5453E3A5F4A0 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5E201A6B1D3452D500A81F3A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E201A7A1D3452D500A81F3A /* ViewController.m in Sources */, + 5E201A771D3452D500A81F3A /* AppDelegate.m in Sources */, + 5EC76B971D36B2EE00A74FED /* h2_ssl.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5E201A7B1D3452D500A81F3A /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5E201A7C1D3452D500A81F3A /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5E201A811D3452D600A81F3A /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5E201A841D3452D600A81F3A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 5E201A851D3452D600A81F3A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5E201A871D3452D600A81F3A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/BoringSSL\"", + "\"${PODS_ROOT}/Headers/Public/CronetFramework\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-Cronet\"", + "\"${PODS_ROOT}/../../../../../include\"", + ); + INFOPLIST_FILE = End2EndTest/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.End2EndTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../../.."; + }; + name = Debug; + }; + 5E201A881D3452D600A81F3A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E7725B916D22B5AC6ECF8964 /* Pods-End2EndTest.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/BoringSSL\"", + "\"${PODS_ROOT}/Headers/Public/CronetFramework\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-Cronet\"", + "\"${PODS_ROOT}/../../../../../include\"", + ); + INFOPLIST_FILE = End2EndTest/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.End2EndTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../../.."; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5E201A6A1D3452D500A81F3A /* Build configuration list for PBXProject "End2EndTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E201A841D3452D600A81F3A /* Debug */, + 5E201A851D3452D600A81F3A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5E201A861D3452D600A81F3A /* Build configuration list for PBXNativeTarget "End2EndTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E201A871D3452D600A81F3A /* Debug */, + 5E201A881D3452D600A81F3A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5E201A671D3452D500A81F3A /* Project object */; +} diff --git a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000..220e863b896e3 --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h new file mode 100644 index 0000000000000..dbc592fcc8744 --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// End2EndTest +// +// Created by mxyan on 7/11/16. +// Copyright © 2016 Google. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m new file mode 100644 index 0000000000000..a4beef9954de9 --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m @@ -0,0 +1,45 @@ +// +// AppDelegate.m +// End2EndTest +// +// Created by mxyan on 7/11/16. +// Copyright © 2016 Google. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json b/src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000000..118c98f7461bf --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard b/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000000..2e721e1833f03 --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard b/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard new file mode 100644 index 0000000000000..f56d2f3bb56e8 --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Info.plist b/src/objective-c/tests/End2EndTest/End2EndTest/Info.plist new file mode 100644 index 0000000000000..6905cc67bbf73 --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/Info.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h new file mode 100644 index 0000000000000..941477a48ca70 --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h @@ -0,0 +1,15 @@ +// +// ViewController.h +// End2EndTest +// +// Created by mxyan on 7/11/16. +// Copyright © 2016 Google. All rights reserved. +// + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m new file mode 100644 index 0000000000000..535e40bcb392f --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m @@ -0,0 +1,27 @@ +// +// ViewController.m +// End2EndTest +// +// Created by mxyan on 7/11/16. +// Copyright © 2016 Google. All rights reserved. +// + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +@end diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m b/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m new file mode 100644 index 0000000000000..2649546fcadde --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m @@ -0,0 +1,199 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include +#include + +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +#include +#import + +#import +#import "AppDelegate.h" + +typedef struct fullstack_secure_fixture_data { + char *localaddr; +} fullstack_secure_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( + grpc_channel_args *client_args, grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + int port = grpc_pick_unused_port_or_die(); + fullstack_secure_fixture_data *ffd = + gpr_malloc(sizeof(fullstack_secure_fixture_data)); + memset(&f, 0, sizeof(f)); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); + + f.fixture_data = ffd; + f.cq = grpc_completion_queue_create(NULL); + + return f; +} + +static void process_auth_failure(void *state, grpc_auth_context *ctx, + const grpc_metadata *md, size_t md_count, + grpc_process_auth_metadata_done_cb cb, + void *user_data) { + GPR_ASSERT(state == NULL); + cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); +} + +static void chttp2_init_client_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *client_args, + cronet_engine *cronetEngine) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + f->client = + grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); + GPR_ASSERT(f->client != NULL); +} + +static void chttp2_init_server_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args, + grpc_server_credentials *server_creds) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args, NULL); + grpc_server_register_completion_queue(f->server, f->cq, NULL); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + server_creds)); + grpc_server_credentials_release(server_creds); + grpc_server_start(f->server); +} + +void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + gpr_free(ffd->localaddr); + gpr_free(ffd); +} + +static void chttp2_init_client_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { + grpc_arg ssl_name_override = {GRPC_ARG_STRING, + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + {"foo.test.google.fr"}}; + + grpc_channel_args *new_client_args = + grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + cronet_engine *cronetEngine = [Cronet getGlobalEngine]; + + chttp2_init_client_secure_fullstack(f, new_client_args, cronetEngine); + grpc_channel_args_destroy(new_client_args); +} + +static int fail_server_auth_check(grpc_channel_args *server_args) { + size_t i; + if (server_args == NULL) return 0; + for (i = 0; i < server_args->num_args; i++) { + if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == + 0) { + return 1; + } + } + return 0; +} + +static void chttp2_init_server_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { + grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, + test_server1_cert}; + grpc_server_credentials *ssl_creds = + grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); + if (fail_server_auth_check(server_args)) { + grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; + grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); + } + chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); +} + +/* All test configurations */ + +static grpc_end2end_test_config configs[] = { + {"chttp2/simple_ssl_fullstack", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + chttp2_create_fixture_secure_fullstack, + chttp2_init_client_simple_ssl_secure_fullstack, + chttp2_init_server_simple_ssl_secure_fullstack, + chttp2_tear_down_secure_fullstack}, +}; + +int main(int argc, char **argv) { + size_t i; + FILE *roots_file; + size_t roots_size = strlen(test_root_cert); + char *roots_filename; + + grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); + + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); + GPR_ASSERT(roots_filename != NULL); + GPR_ASSERT(roots_file != NULL); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + + grpc_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + + grpc_shutdown(); + + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); +} diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/main.m b/src/objective-c/tests/End2EndTest/End2EndTest/main.m new file mode 100644 index 0000000000000..a1894cdb4133a --- /dev/null +++ b/src/objective-c/tests/End2EndTest/End2EndTest/main.m @@ -0,0 +1,16 @@ +// +// main.m +// End2EndTest +// +// Created by mxyan on 7/11/16. +// Copyright © 2016 Google. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/src/objective-c/tests/End2EndTest/Podfile b/src/objective-c/tests/End2EndTest/Podfile new file mode 100644 index 0000000000000..59b64badfb9de --- /dev/null +++ b/src/objective-c/tests/End2EndTest/Podfile @@ -0,0 +1,83 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +install! 'cocoapods', :deterministic_uuids => false + +# Location of gRPC's repo root relative to this file. +GRPC_LOCAL_SRC = '../../../..' + +# Install the dependencies in the main target plus all test targets. +%w( + End2EndTest +).each do |target_name| + target target_name do + pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-Cronet', :path => GRPC_LOCAL_SRC + end +end + +# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's +# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded +# and before they are installed in the user project. +# +# This podspec searches for the gRPC core library headers under "$(PODS_ROOT)/gRPC-Core", where +# Cocoapods normally places the downloaded sources. When doing local development of the libraries, +# though, Cocoapods just takes the sources from whatever directory was specified using `:path`, and +# doesn't copy them under $(PODS_ROOT). When using static libraries, one can sometimes rely on the +# symbolic links to the pods headers that Cocoapods creates under "$(PODS_ROOT)/Headers". But those +# aren't created when using dynamic frameworks. So our solution is to modify the podspec on the fly +# to point at the local directory where the sources are. +# +# TODO(jcanizales): Send a PR to Cocoapods to get rid of this need. +pre_install do |installer| + # This is the gRPC-Core podspec object, as initialized by its podspec file. + grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Core'}.root_spec + + # Copied from gRPC-Core.podspec, except for the adjusted src_root: + src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/support/string.h` shadow the system `` and ``, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } + +# This is the gRPC-Core podspec object, as initialized by its podspec file. + grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Cronet'}.root_spec + + # Copied from gRPC-Core.podspec, except for the adjusted src_root: + src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/support/string.h` shadow the system `` and ``, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } + +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' + end + if target.name == 'gRPC-Core' + target.build_configurations.each do |config| + # TODO(zyc) Remove this setting after the issue is resolved + # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void + # function" warning + config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' + end + end + end +end From 60851911456ac71b34c0ba97595e19210d3f2722 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 13 Jul 2016 12:36:27 -0700 Subject: [PATCH 017/151] add back version to composer.json file --- src/php/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/composer.json b/src/php/composer.json index 2ad73223c65bd..b95cde1234ba9 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -5,6 +5,7 @@ "keywords": ["rpc"], "homepage": "http://grpc.io", "license": "BSD-3-Clause", + "version": "1.0.0", "repositories": [ { "type": "vcs", From ae8c64dc0083e546ae3cc4de3b3b48b2e8c31edb Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Thu, 30 Jun 2016 11:15:36 -0400 Subject: [PATCH 018/151] Correct error handling for failed set_sockopt calls in udp_server.c --- src/core/lib/iomgr/udp_server.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 1ebccf2ee2e05..5854ca52b267c 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -217,14 +217,23 @@ static int prepare_socket(int fd, const struct sockaddr *addr, goto error; } - if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1)) { - gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, - strerror(errno)); + if (grpc_set_socket_nonblocking(fd, 1) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set nonblocking %d: %s", fd, strerror(errno)); + goto error; + } + if (grpc_set_socket_cloexec(fd, 1) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set cloexec %d: %s", fd, strerror(errno)); + goto error; } - if (grpc_set_socket_ip_pktinfo_if_possible(fd) && - addr->sa_family == AF_INET6) { - grpc_set_socket_ipv6_recvpktinfo_if_possible(fd); + if (grpc_set_socket_ip_pktinfo_if_possible(fd) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set ip_pktinfo."); + goto error; + } else if (addr->sa_family == AF_INET6) { + if (grpc_set_socket_ipv6_recvpktinfo_if_possible(fd) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set ipv6_recvpktinfo."); + goto error; + } } GPR_ASSERT(addr_len < ~(socklen_t)0); @@ -241,13 +250,13 @@ static int prepare_socket(int fd, const struct sockaddr *addr, goto error; } - if (!grpc_set_socket_sndbuf(fd, buffer_size_bytes)) { + if (grpc_set_socket_sndbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes", buffer_size_bytes); goto error; } - if (!grpc_set_socket_rcvbuf(fd, buffer_size_bytes)) { + if (grpc_set_socket_rcvbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Failed to set receive buffer size to %d bytes", buffer_size_bytes); goto error; From 7f6864ac1218d65fdca27fbd6dedc1dda3826699 Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Thu, 30 Jun 2016 15:11:28 -0400 Subject: [PATCH 019/151] Use grpc_error instead of bool in udp_server's on_read --- src/core/lib/iomgr/udp_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 5854ca52b267c..39e9c75efd264 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -272,10 +272,10 @@ static int prepare_socket(int fd, const struct sockaddr *addr, } /* event manager callback when reads are ready */ -static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) { +static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error* error) { server_port *sp = arg; - if (!success) { + if (error != GRPC_ERROR_NONE) { gpr_mu_lock(&sp->server->mu); if (0 == --sp->server->active_ports) { gpr_mu_unlock(&sp->server->mu); From 7e8b4173a98fb70c2eb2a107d6b25919369a6cc7 Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Thu, 30 Jun 2016 15:06:12 -0400 Subject: [PATCH 020/151] Use the new socket creation api in udp_server.c --- src/core/lib/iomgr/udp_server.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 39e9c75efd264..f7381cebb57fc 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -378,7 +378,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, /* Try listening on IPv6 first. */ addr = (struct sockaddr *)&wild6; addr_len = sizeof(wild6); - fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); + // TODO(rjshade): Test and propagate the returned grpc_error*: + grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd); allocated_port1 = add_socket_to_server(s, fd, addr, addr_len, read_cb, orphan_cb); if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { @@ -393,7 +394,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, addr_len = sizeof(wild4); } - fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); + // TODO(rjshade): Test and propagate the returned grpc_error*: + grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd); if (fd < 0) { gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); } From c153337d04a7fdf40ad0fdd3da0ac395421f3625 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Wed, 13 Jul 2016 14:24:39 -0700 Subject: [PATCH 021/151] Fix missing source file --- PYTHON-MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in index 175a47f157648..96bcdb515c953 100644 --- a/PYTHON-MANIFEST.in +++ b/PYTHON-MANIFEST.in @@ -7,7 +7,7 @@ graft include/grpc graft third_party/boringssl graft third_party/nanopb graft third_party/zlib -include src/python/grpcio/build.py +include src/python/grpcio/_unixccompiler_patch.py include src/python/grpcio/commands.py include src/python/grpcio/grpc_version.py include src/python/grpcio/grpc_core_dependencies.py From 800a71cfb3b5fdc39a51e3ef52b1f80bf7790993 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 13 Jul 2016 14:44:33 -0700 Subject: [PATCH 022/151] Don't always import Protobuf like a framework If the macro isn't set, e.g. for Bazel compilations, import the way it was done before https://github.com/grpc/grpc/commit/fb4a54541a6e00c43e1671cda0a25e2eda4792df. --- src/objective-c/ProtoRPC/ProtoRPC.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index e7232f268322c..83d1b655e8d08 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -33,7 +33,11 @@ #import "ProtoRPC.h" -#import +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import +#endif #import #import From c41f81aeeb054ec436934c7cc1afeb1dee0a8581 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Wed, 13 Jul 2016 14:52:40 -0700 Subject: [PATCH 023/151] Document rpc details as string type --- src/python/grpcio/grpc/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index fd015129f02f1..513839df7d901 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -345,7 +345,7 @@ def details(self): This method blocks until the value is available. Returns: - The bytes of the details of the RPC. + The details string of the RPC. """ raise NotImplementedError() @@ -764,7 +764,7 @@ def set_details(self, details): details to transmit. Args: - details: The details bytes of the RPC to be transmitted to + details: The details string of the RPC to be transmitted to the invocation side of the RPC. """ raise NotImplementedError() From 4a7aca0e4bf357aa9755ac2a61ef23bf9035b3c1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 13 Jul 2016 15:32:13 -0700 Subject: [PATCH 024/151] Establish Objective C end-to-end core test with Cronet --- gRPC-Cronet.podspec | 37 ++++++++++++-- .../End2EndTest.xcodeproj/project.pbxproj | 8 +-- .../End2EndTest/End2EndTest/AppDelegate.h | 39 ++++++++++++--- .../End2EndTest/End2EndTest/AppDelegate.m | 39 ++++++++++++--- .../tests/End2EndTest/End2EndTest/h2_ssl.m | 15 ++++-- .../tests/End2EndTest/End2EndTest/main.m | 16 ------ src/objective-c/tests/End2EndTest/Podfile | 49 +++++++------------ 7 files changed, 130 insertions(+), 73 deletions(-) delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/main.m diff --git a/gRPC-Cronet.podspec b/gRPC-Cronet.podspec index 8db5490e0e4aa..b353bf9a43760 100644 --- a/gRPC-Cronet.podspec +++ b/gRPC-Cronet.podspec @@ -52,12 +52,34 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' s.requires_arc = false - name = 'grpc' + name = 'GRPCCronet' s.module_name = name - s.header_mappings_dir = '.' + # When creating a dynamic framework, copy the headers under `include/grpc/` into the root of + # the `Headers/` directory of the framework (i.e., not under `Headers/include/grpc`). + s.header_mappings_dir = 'include/grpc' + # The above has an undesired effect when creating a static library: It forces users to write + # includes like `#include `. `s.header_dir` adds a path prefix to that, and + # because Cocoapods lets omit the pod name when including headers of static libraries, the + # following lets users write `#include `. + s.header_dir = 'grpc' + + # To compile the library, we need the user headers search path (quoted includes) to point to the + # root of the repo, and the system headers search path (angled includes) to point to `include/`. + # Cocoapods effectively clones the repo under `/Pods/gRPC-Cronet/`, and sets a build + # variable called `$(PODS_ROOT)` to `/Pods/`, so we use that. + # + # Relying on the file structure under $(PODS_ROOT) isn't officially supported in Cocoapods, as it + # is taken as an implementation detail. We've asked for an alternative, and have been told that + # what we're doing should keep working: https://github.com/CocoaPods/CocoaPods/issues/4386 + # + # The `src_root` value of `$(PODS_ROOT)/gRPC-Cronet` assumes Cocoapods is installing this pod from + # its remote repo. For local development of this library, enabled by using `:path` in the Podfile, + # that assumption is wrong. In such case, the following settings need to be reset with the + # appropriate value of `src_root`. This can be accomplished in the `pre_install` hook of the + # Podfile; see `src/objective-c/tests/Podfile` for an example. src_root = '$(PODS_ROOT)/gRPC-Cronet' s.pod_target_xcconfig = { 'GRPC_SRC_ROOT' => src_root, @@ -80,9 +102,16 @@ Pod::Spec.new do |s| ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', 'src/core/ext/transport/cronet/transport/cronet_transport.c', - 'test/core/end2end/**/*.{c,h}', - 'test/core/util' + 'test/core/end2end/cq_verifier.{c,h}', + 'test/core/end2end/end2end_tests.{c,h}', + 'test/core/end2end/tests/*.{c,h}', + 'test/core/end2end/data/*.{c,h}', + 'test/core/util/test_config.{c,h}', + 'test/core/util/port.h', + 'test/core/util/port_posix.c', + 'test/core/util/port_server_client.{c,h}' ss.dependency 'gRPC-Core', version + ss.dependency 'CronetFramework' end end diff --git a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj index bc5006e9366ec..a878db9c2e33e 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj @@ -13,11 +13,12 @@ 5E201A7F1D3452D600A81F3A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A7E1D3452D600A81F3A /* Assets.xcassets */; }; 5E201A821D3452D600A81F3A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */; }; 5EC76B971D36B2EE00A74FED /* h2_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EC76B961D36B2EE00A74FED /* h2_ssl.m */; }; - C124E05DC4ED9F5CA3EFD20D /* libPods-End2EndTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 931C29940B821E295AA90634 /* libPods-End2EndTest.a */; }; + 809A4524D003F25B67A9E20C /* libPods-End2EndTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45442114339F6871ABA5F464 /* libPods-End2EndTest.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-End2EndTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest.debug.xcconfig"; sourceTree = ""; }; + 45442114339F6871ABA5F464 /* libPods-End2EndTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-End2EndTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 5E201A6F1D3452D500A81F3A /* End2EndTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = End2EndTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5E201A751D3452D500A81F3A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 5E201A761D3452D500A81F3A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -28,7 +29,6 @@ 5E201A811D3452D600A81F3A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 5E201A831D3452D600A81F3A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5EC76B961D36B2EE00A74FED /* h2_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl.m; sourceTree = ""; }; - 931C29940B821E295AA90634 /* libPods-End2EndTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-End2EndTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E7725B916D22B5AC6ECF8964 /* Pods-End2EndTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-End2EndTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -37,7 +37,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C124E05DC4ED9F5CA3EFD20D /* libPods-End2EndTest.a in Frameworks */, + 809A4524D003F25B67A9E20C /* libPods-End2EndTest.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -98,7 +98,7 @@ D564C37197511893E4E62D12 /* Frameworks */ = { isa = PBXGroup; children = ( - 931C29940B821E295AA90634 /* libPods-End2EndTest.a */, + 45442114339F6871ABA5F464 /* libPods-End2EndTest.a */, ); name = Frameworks; sourceTree = ""; diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h index dbc592fcc8744..867e62842aeca 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h +++ b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h @@ -1,10 +1,35 @@ -// -// AppDelegate.h -// End2EndTest -// -// Created by mxyan on 7/11/16. -// Copyright © 2016 Google. All rights reserved. -// +/* + * + * 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. + * + */ #import diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m index a4beef9954de9..66fceffd85cb4 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m +++ b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m @@ -1,10 +1,35 @@ -// -// AppDelegate.m -// End2EndTest -// -// Created by mxyan on 7/11/16. -// Copyright © 2016 Google. All rights reserved. -// +/* + * + * 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. + * + */ #import "AppDelegate.h" diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m b/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m index 2649546fcadde..800dd56649a1e 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m +++ b/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m @@ -31,6 +31,13 @@ * */ +/* + * This fixture creates a server full stack using chttp2 and a client + * full stack using Cronet. End-to-end tests are run against this fixture + * setting. + * + */ + #include "test/core/end2end/end2end_tests.h" #include @@ -83,7 +90,7 @@ static void process_auth_failure(void *state, grpc_auth_context *ctx, cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); } -static void chttp2_init_client_secure_fullstack( +static void cronet_init_client_secure_fullstack( grpc_end2end_test_fixture *f, grpc_channel_args *client_args, cronet_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = f->fixture_data; @@ -113,7 +120,7 @@ void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { gpr_free(ffd); } -static void chttp2_init_client_simple_ssl_secure_fullstack( +static void cronet_init_client_simple_ssl_secure_fullstack( grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { grpc_arg ssl_name_override = {GRPC_ARG_STRING, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, @@ -125,7 +132,7 @@ static void chttp2_init_client_simple_ssl_secure_fullstack( [Cronet start]; cronet_engine *cronetEngine = [Cronet getGlobalEngine]; - chttp2_init_client_secure_fullstack(f, new_client_args, cronetEngine); + cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); grpc_channel_args_destroy(new_client_args); } @@ -161,7 +168,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, chttp2_create_fixture_secure_fullstack, - chttp2_init_client_simple_ssl_secure_fullstack, + cronet_init_client_simple_ssl_secure_fullstack, chttp2_init_server_simple_ssl_secure_fullstack, chttp2_tear_down_secure_fullstack}, }; diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/main.m b/src/objective-c/tests/End2EndTest/End2EndTest/main.m deleted file mode 100644 index a1894cdb4133a..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/main.m +++ /dev/null @@ -1,16 +0,0 @@ -// -// main.m -// End2EndTest -// -// Created by mxyan on 7/11/16. -// Copyright © 2016 Google. All rights reserved. -// - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/src/objective-c/tests/End2EndTest/Podfile b/src/objective-c/tests/End2EndTest/Podfile index 59b64badfb9de..a3fd4d5e9559e 100644 --- a/src/objective-c/tests/End2EndTest/Podfile +++ b/src/objective-c/tests/End2EndTest/Podfile @@ -32,38 +32,25 @@ end # # TODO(jcanizales): Send a PR to Cocoapods to get rid of this need. pre_install do |installer| - # This is the gRPC-Core podspec object, as initialized by its podspec file. - grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Core'}.root_spec - - # Copied from gRPC-Core.podspec, except for the adjusted src_root: - src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" - grpc_core_spec.pod_target_xcconfig = { - 'GRPC_SRC_ROOT' => src_root, - 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', - 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', - # If we don't set these two settings, `include/grpc/support/time.h` and - # `src/core/lib/support/string.h` shadow the system `` and ``, breaking the - # build. - 'USE_HEADERMAP' => 'NO', - 'ALWAYS_SEARCH_USER_PATHS' => 'NO', - } - -# This is the gRPC-Core podspec object, as initialized by its podspec file. - grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Cronet'}.root_spec - - # Copied from gRPC-Core.podspec, except for the adjusted src_root: - src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" - grpc_core_spec.pod_target_xcconfig = { - 'GRPC_SRC_ROOT' => src_root, - 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', - 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', - # If we don't set these two settings, `include/grpc/support/time.h` and - # `src/core/lib/support/string.h` shadow the system `` and ``, breaking the - # build. - 'USE_HEADERMAP' => 'NO', - 'ALWAYS_SEARCH_USER_PATHS' => 'NO', - } + %w( + gRPC-Core + gRPC-Cronet + ).each do |target_name| + grpc_core_spec = installer.pod_targets.find{|t| t.name == target_name}.root_spec + # Copied from gRPC-Core.podspec, except for the adjusted src_root: + src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/support/string.h` shadow the system `` and ``, breaking + # the build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } + end end post_install do |installer| From b87d1068752cb0ff2453a7abf8b6662403d38c63 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Wed, 13 Jul 2016 16:25:44 -0700 Subject: [PATCH 025/151] Checking in new roots. --- etc/roots.pem | 1293 ++++++++++++++++++++++++++++++------------------- 1 file changed, 784 insertions(+), 509 deletions(-) diff --git a/etc/roots.pem b/etc/roots.pem index 7b4d5f10fbabb..e6df88ea923ab 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -2,33 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -# Issuer: O=Equifax OU=Equifax Secure Certificate Authority -# Subject: O=Equifax OU=Equifax Secure Certificate Authority -# Label: "Equifax Secure CA" -# Serial: 903804111 -# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4 -# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a -# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78 ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV -UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy -dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 -MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx -dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f -BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A -cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC -AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ -MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw -ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj -IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF -MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA -A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y -7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh -1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 ------END CERTIFICATE----- - # Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Label: "GlobalSign Root CA" @@ -120,38 +93,6 @@ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- -# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Label: "Verisign Class 4 Public Primary Certification Authority - G3" -# Serial: 314531972711909413743075096039378935511 -# MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df -# SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d -# SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06 ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 -GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ -+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd -U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm -NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY -ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ -ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 -CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq -g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm -fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c -2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ -bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== ------END CERTIFICATE----- - # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Label: "Entrust.net Premium 2048 Secure Server CA" @@ -214,30 +155,6 @@ ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. -# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. -# Label: "Equifax Secure Global eBusiness CA" -# Serial: 1 -# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc -# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45 -# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07 ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT -ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw -MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj -dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l -c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC -UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc -58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ -o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr -aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA -A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA -Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv -8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - # Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network # Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network # Label: "AddTrust Low-Value Services Root" @@ -907,70 +824,6 @@ Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M -----END CERTIFICATE----- -# Issuer: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden -# Label: "Staat der Nederlanden Root CA" -# Serial: 10000010 -# MD5 Fingerprint: 60:84:7c:5a:ce:db:0c:d4:cb:a7:e9:fe:02:c6:a9:c0 -# SHA1 Fingerprint: 10:1d:fa:3f:d5:0b:cb:bb:9b:b5:60:0c:19:55:a4:1a:f4:73:3a:04 -# SHA256 Fingerprint: d4:1d:82:9e:8c:16:59:82:2a:f9:3f:ce:62:bf:fc:de:26:4f:c8:4e:8b:95:0c:5f:f2:75:d0:52:35:46:95:a3 ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO -TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy -MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk -ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn -ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71 -9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO -hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U -tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o -BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh -SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww -OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv -cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA -7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k -/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm -eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6 -u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy -7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR -iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== ------END CERTIFICATE----- - -# Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com -# Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com -# Label: "UTN DATACorp SGC Root CA" -# Serial: 91374294542884689855167577680241077609 -# MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06 -# SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4 -# SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48 ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG -EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD -VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu -dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 -E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ -D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK -4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq -lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW -bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB -o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT -MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js -LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr -BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB -AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj -j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH -KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv -2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 -mfnGV/TJVTl4uix5yaaIK/QI ------END CERTIFICATE----- - # Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com # Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com # Label: "UTN USERFirst Hardware Root CA" @@ -1077,51 +930,6 @@ ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== -----END CERTIFICATE----- -# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok -# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok -# Label: "NetLock Notary (Class A) Root" -# Serial: 259 -# MD5 Fingerprint: 86:38:6d:5e:49:63:6c:85:5c:db:6d:dc:94:b7:d0:f7 -# SHA1 Fingerprint: ac:ed:5f:65:53:fd:25:ce:01:5f:1f:7a:48:3b:6a:74:9f:61:78:c6 -# SHA256 Fingerprint: 7f:12:cd:5f:7e:5e:29:0e:c7:d8:51:79:d5:b7:2c:20:a5:be:75:08:ff:db:5b:f8:1a:b9:68:4a:7f:c9:f6:67 ------BEGIN CERTIFICATE----- -MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV -MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe -TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0 -dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB -KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0 -N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC -dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu -MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL -b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD -zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi -3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8 -WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY -Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi -NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC -ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4 -QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0 -YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz -aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu -IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm -ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg -ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs -amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv -IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3 -Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6 -ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1 -YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg -dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs -b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G -CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO -xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP -0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ -QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk -f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK -8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI ------END CERTIFICATE----- - # Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Label: "XRamp Global CA Root" @@ -1534,71 +1342,6 @@ rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= -----END CERTIFICATE----- -# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. -# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. -# Label: "TURKTRUST Certificate Services Provider Root 1" -# Serial: 1 -# MD5 Fingerprint: f1:6a:22:18:c9:cd:df:ce:82:1d:1d:b7:78:5c:a9:a5 -# SHA1 Fingerprint: 79:98:a3:08:e1:4d:65:85:e6:c2:1e:15:3a:71:9f:ba:5a:d3:4a:d9 -# SHA256 Fingerprint: 44:04:e3:3b:5e:14:0d:cf:99:80:51:fd:fc:80:28:c7:c8:16:15:c5:ee:73:7b:11:1b:58:82:33:a9:b5:35:a0 ------BEGIN CERTIFICATE----- -MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc -UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx -c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg -MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 -dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz -MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy -dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD -VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg -xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu -xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7 -XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k -heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J -YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C -urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1 -JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51 -b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV -9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7 -kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh -fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy -B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA -aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS -RGQDJereW26fyfJOrN3H ------END CERTIFICATE----- - -# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005 -# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005 -# Label: "TURKTRUST Certificate Services Provider Root 2" -# Serial: 1 -# MD5 Fingerprint: 37:a5:6e:d4:b1:25:84:97:b7:fd:56:15:7a:f9:a2:00 -# SHA1 Fingerprint: b4:35:d4:e1:11:9d:1c:66:90:a7:49:eb:b3:94:bd:63:7b:a7:82:b7 -# SHA256 Fingerprint: c4:70:cf:54:7e:23:02:b9:77:fb:29:dd:71:a8:9a:7b:6c:1f:60:77:7b:03:29:f5:60:17:f3:28:bf:4f:6b:e6 ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc -UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx -c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS -S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg -SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3 -WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv -bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU -UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw -bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe -LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef -J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh -R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ -Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX -JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p -zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S -Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ -KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq -ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 -Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz -gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH -uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS -y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI= ------END CERTIFICATE----- - # Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG # Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG # Label: "SwissSign Gold CA - G2" @@ -2137,107 +1880,6 @@ t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- -# Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA -# Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA -# Label: "TC TrustCenter Class 2 CA II" -# Serial: 941389028203453866782103406992443 -# MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23 -# SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e -# SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4 ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf -tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg -uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J -XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK -8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 -5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 -kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS -GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt -ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 -au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV -hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI -dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA -# Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA -# Label: "TC TrustCenter Class 3 CA II" -# Serial: 1506523511417715638772220530020799 -# MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e -# SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5 -# SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW -Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q -Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 -1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq -ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 -Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX -XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN -irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 -TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 -g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB -95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj -S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Label: "TC TrustCenter Universal CA I" -# Serial: 601024842042189035295619584734726 -# MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c -# SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3 -# SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7 ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV -BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1 -c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx -MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg -R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD -VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR -JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T -fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu -jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z -wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ -fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD -VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G -CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1 -7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn -8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs -ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/ -2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------END CERTIFICATE----- - # Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center # Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center # Label: "Deutsche Telekom Root CA 2" @@ -2268,36 +1910,6 @@ xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU Cm26OWMohpLzGITY+9HPBVZkVw== -----END CERTIFICATE----- -# Issuer: CN=ComSign Secured CA O=ComSign -# Subject: CN=ComSign Secured CA O=ComSign -# Label: "ComSign Secured CA" -# Serial: 264725503855295744117309814499492384489 -# MD5 Fingerprint: 40:01:25:06:8d:21:43:6a:0e:43:00:9c:e7:43:f3:d5 -# SHA1 Fingerprint: f9:cd:0e:2c:da:76:24:c1:8f:bd:f0:f0:ab:b6:45:b8:f7:fe:d5:7a -# SHA256 Fingerprint: 50:79:41:c7:44:60:a0:b4:70:86:22:0d:4e:99:32:57:2a:b5:d1:b5:bb:cb:89:80:ab:1c:b1:76:51:a8:44:d2 ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw -PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu -MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx -GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL -MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf -HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh -gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW -v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue -Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr -9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt -6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 -MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl -Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 -ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq -hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p -iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC -dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL -kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL -hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------END CERTIFICATE----- - # Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc # Subject: CN=Cybertrust Global Root O=Cybertrust, Inc # Label: "Cybertrust Global Root" @@ -2435,34 +2047,6 @@ h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho -----END CERTIFICATE----- -# Issuer: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327 -# Subject: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327 -# Label: "Buypass Class 3 CA 1" -# Serial: 2 -# MD5 Fingerprint: df:3c:73:59:81:e7:39:50:81:04:4c:34:a2:cb:b3:7b -# SHA1 Fingerprint: 61:57:3a:11:df:0e:d8:7e:d5:92:65:22:ea:d0:56:d7:44:b3:23:71 -# SHA256 Fingerprint: b7:b1:2b:17:1f:82:1d:aa:99:0c:d0:fe:50:87:b1:28:44:8b:a8:e5:18:4f:84:c5:1e:02:b5:c8:fb:96:2b:24 ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg -Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL -MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD -VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg -isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z -NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI -+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R -hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+ -mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD -AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP -Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s -EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2 -mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC -e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow -dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 ------END CERTIFICATE----- - # Issuer: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. # Subject: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. # Label: "EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1" @@ -2843,38 +2427,6 @@ Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== -----END CERTIFICATE----- -# Issuer: CN=CA Disig O=Disig a.s. -# Subject: CN=CA Disig O=Disig a.s. -# Label: "CA Disig" -# Serial: 1 -# MD5 Fingerprint: 3f:45:96:39:e2:50:87:f7:bb:fe:98:0c:3c:20:98:e6 -# SHA1 Fingerprint: 2a:c8:d5:8b:57:ce:bf:2f:49:af:f2:fc:76:8f:51:14:62:90:7a:41 -# SHA256 Fingerprint: 92:bf:51:19:ab:ec:ca:d0:b1:33:2d:c4:e1:d0:5f:ba:75:b5:67:90:44:ee:0c:a2:6e:93:1f:74:4f:2f:33:cf ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET -MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE -AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw -CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg -YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE -Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX -mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD -XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW -S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp -FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD -AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu -ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z -ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv -Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw -DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6 -yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq -EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ -CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB -EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN -PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag= ------END CERTIFICATE----- - # Issuer: CN=Juur-SK O=AS Sertifitseerimiskeskus # Subject: CN=Juur-SK O=AS Sertifitseerimiskeskus # Label: "Juur-SK" @@ -3042,36 +2594,6 @@ tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW -----END CERTIFICATE----- -# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S. -# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S. -# Label: "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi" -# Serial: 91184789765598910059173000485363494069 -# MD5 Fingerprint: 3d:41:29:cb:1e:aa:11:74:cd:5d:b0:62:af:b0:43:5b -# SHA1 Fingerprint: dd:e1:d2:a9:01:80:2e:1d:87:5e:84:b3:80:7e:4b:b1:fd:99:41:34 -# SHA256 Fingerprint: e6:09:07:84:65:a4:19:78:0c:b6:ac:4c:1c:0b:fb:46:53:d9:d9:cc:6e:b3:94:6e:b7:f3:d6:99:97:ba:d5:98 ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1 -MQswCQYDVQQGEwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxp -Z2kgQS5TLjE8MDoGA1UEAxMzZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZp -a2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3MDEwNDExMzI0OFoXDTE3MDEwNDEx -MzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0cm9uaWsgQmlsZ2kg -R3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9uaWsg -U2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdU -MZTe1RK6UxYC6lhj71vY8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlT -L/jDj/6z/P2douNffb7tC+Bg62nsM+3YjfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H -5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAIJjjcJRFHLfO6IxClv7wC -90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk9Ok0oSy1 -c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoE -VtstxNulMA0GCSqGSIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLP -qk/CaOv/gKlR6D1id4k9CnU58W5dF4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S -/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwqD2fK/A+JYZ1lpTzlvBNbCNvj -/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4Vwpm+Vganf2X -KWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------END CERTIFICATE----- - # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Label: "GlobalSign Root CA - R3" @@ -3610,37 +3132,6 @@ ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= -----END CERTIFICATE----- -# Issuer: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03 -# Subject: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03 -# Label: "A-Trust-nQual-03" -# Serial: 93214 -# MD5 Fingerprint: 49:63:ae:27:f4:d5:95:3d:d8:db:24:86:b8:9c:07:53 -# SHA1 Fingerprint: d3:c0:63:f2:19:ed:07:3e:34:ad:5d:75:0b:32:76:29:ff:d5:9a:f2 -# SHA256 Fingerprint: 79:3c:bf:45:59:b9:fd:e3:8a:b2:2d:f1:68:69:f6:98:81:ae:14:c4:b0:13:9a:c7:88:a7:8a:1a:fc:ca:02:fb ------BEGIN CERTIFICATE----- -MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB -VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp -bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R -dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw -MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy -dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52 -ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM -EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj -lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ -znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH -2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1 -k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs -2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD -VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC -AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG -KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+ -8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R -FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS -mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE -DNuxUCAKGkq6ahq97BvIxYSazQ== ------END CERTIFICATE----- - # Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Label: "TWCA Root Certification Authority" @@ -3699,6 +3190,45 @@ t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- +# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Label: "EC-ACC" +# Serial: -23701579247955709139626555126524820479 +# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09 +# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8 +# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99 +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- + # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Label: "Hellenic Academic and Research Institutions RootCA 2011" @@ -5112,3 +4642,748 @@ KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg 515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO xwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. +# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. +# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5" +# Serial: 156233699172481 +# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e +# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb +# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78 +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE +BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn +aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg +QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg +SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0 +MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD +VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom +/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR +Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3 +4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z +5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0 +hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID +AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX +SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l +VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf +peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF +Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW ++qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. +# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. +# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6" +# Serial: 138134509972618 +# MD5 Fingerprint: f8:c5:ee:2a:6b:be:95:8d:08:f7:25:4a:ea:71:3e:46 +# SHA1 Fingerprint: 8a:5c:8c:ee:a5:03:e6:05:56:ba:d8:1b:d4:f6:c9:b0:ed:e5:2f:e0 +# SHA256 Fingerprint: 8d:e7:86:55:e1:be:7f:78:47:80:0b:93:f6:94:d2:1d:36:8c:c0:6e:03:3e:7f:ab:04:bb:5e:b9:9d:a6:b7:00 +-----BEGIN CERTIFICATE----- +MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQG +EwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdp +IMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBB +LsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBI +aXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5MDQxMFoXDTIzMTIx +NjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBLBgNV +BAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2 +ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVs +ZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdsGjW6L0UlqMACprx9MfMkU1x +eHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a2uqsxgbPJQ1BgfbBOCK9 ++bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EEDwnS3/faA +z1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0p +u5FbHH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6p +lVxiSvgNZ1GpryHV+DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMB +AAGjQjBAMB0GA1UdDgQWBBTdVRcT9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAb1gNl0Oq +FlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3RfdCaqaXKGDsC +QC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy +o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKID +gI6tflEATseWhvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm +9ocJV612ph1jmv3XZch4gyt1O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsG +tAuYSyher4hYyw== +-----END CERTIFICATE----- + +# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Root CA" +# Serial: 1 +# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f +# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 +# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=Certification Authority of WoSign G2 O=WoSign CA Limited +# Subject: CN=Certification Authority of WoSign G2 O=WoSign CA Limited +# Label: "Certification Authority of WoSign G2" +# Serial: 142423943073812161787490648904721057092 +# MD5 Fingerprint: c8:1c:7d:19:aa:cb:71:93:f2:50:f8:52:a8:1e:ba:60 +# SHA1 Fingerprint: fb:ed:dc:90:65:b7:27:20:37:bc:55:0c:9c:56:de:bb:f2:78:94:e1 +# SHA256 Fingerprint: d4:87:a5:6f:83:b0:74:82:e8:5e:96:33:94:c1:ec:c2:c9:e5:1d:09:03:ee:94:6b:02:c3:01:58:1e:d9:9e:16 +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBY +MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNV +BAMTJENlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDEx +MDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgxCzAJBgNVBAYTAkNOMRowGAYDVQQK +ExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPX +JYY1kBaiXW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgO +gHzKtB0TiGsOqCR3A9DuW/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg +5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg95k4ot+vElbGs/V6r+kHLXZ1L3PR8du9n +fwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BKv0mUYQs4kI9dJGwlezt5 +2eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJ +KoZIhvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8 +fHulwqZm46qwtyeYP0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G +3CE4Q3RM+zD4F3LBMvzIkRfEzFg3TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yy +SrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu+sif/a+RZQp4OBXllxcU3fng +LDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+7Q9LGOHSJDy7 +XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= +-----END CERTIFICATE----- + +# Issuer: CN=CA WoSign ECC Root O=WoSign CA Limited +# Subject: CN=CA WoSign ECC Root O=WoSign CA Limited +# Label: "CA WoSign ECC Root" +# Serial: 138625735294506723296996289575837012112 +# MD5 Fingerprint: 80:c6:53:ee:61:82:28:72:f0:ff:21:b9:17:ca:b2:20 +# SHA1 Fingerprint: d2:7a:d2:be:ed:94:c0:a1:3c:c7:25:21:ea:5d:71:be:81:19:f3:2b +# SHA256 Fingerprint: 8b:45:da:1c:06:f7:91:eb:0c:ab:f2:6b:e5:88:f5:fb:23:16:5c:2e:61:4b:f8:85:56:2d:0d:ce:50:b2:9b:02 +-----BEGIN CERTIFICATE----- +MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQsw +CQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMT +EkNBIFdvU2lnbiBFQ0MgUm9vdDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4 +NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEb +MBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACID +YgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiUt5v8 +KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES +1ns2o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUqv3VWqP2h4syhf3RMluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB +1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0Daupn75OcsqF1NnstTJFGG+rrQIwfcf3 +aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYua/GRspBl9JrmkO5K +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G1 O=Certplus +# Subject: CN=Certplus Root CA G1 O=Certplus +# Label: "Certplus Root CA G1" +# Serial: 1491911565779898356709731176965615564637713 +# MD5 Fingerprint: 7f:09:9c:f7:d9:b9:5c:69:69:56:d5:37:3e:14:0d:42 +# SHA1 Fingerprint: 22:fd:d0:b7:fd:a2:4e:0d:ac:49:2c:a0:ac:a6:7b:6a:1f:e3:f7:66 +# SHA256 Fingerprint: 15:2a:40:2b:fc:df:2c:d5:48:05:4d:22:75:b3:9c:7f:ca:3e:c0:97:80:78:b0:f0:ea:76:e5:61:a6:c7:43:3e +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a +iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt +6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP +0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f +6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE +EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN +1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc +h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT +mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV +4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO +WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud +DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd +Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq +hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7 +/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS +S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j +2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R +Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr +RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy +6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV +V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5 +g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl +++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G2 O=Certplus +# Subject: CN=Certplus Root CA G2 O=Certplus +# Label: "Certplus Root CA G2" +# Serial: 1492087096131536844209563509228951875861589 +# MD5 Fingerprint: a7:ee:c4:78:2d:1b:ee:2d:b9:29:ce:d6:a7:96:32:31 +# SHA1 Fingerprint: 4f:65:8e:1f:e9:06:d8:28:02:e9:54:47:41:c9:54:25:5d:69:cc:1a +# SHA256 Fingerprint: 6c:c0:50:41:e6:44:5e:74:69:6c:4c:fb:c9:f8:0f:54:3b:7e:ab:bb:44:b4:ce:6f:78:7c:6a:99:71:c4:2f:17 +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat +93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x +Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj +FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG +SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch +p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal +U5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G1 O=OpenTrust +# Subject: CN=OpenTrust Root CA G1 O=OpenTrust +# Label: "OpenTrust Root CA G1" +# Serial: 1492036577811947013770400127034825178844775 +# MD5 Fingerprint: 76:00:cc:81:29:cd:55:5e:88:6a:7a:2e:f7:4d:39:da +# SHA1 Fingerprint: 79:91:e8:34:f7:e2:ee:dd:08:95:01:52:e9:55:2d:14:e9:58:d5:7e +# SHA256 Fingerprint: 56:c7:71:28:d9:8c:18:d9:1b:4c:fd:ff:bc:25:ee:91:03:d4:75:8e:a2:ab:ad:82:6a:90:f3:45:7d:46:0e:b4 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b +wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX +/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0 +77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP +uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx +p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx +Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2 +TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W +G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw +vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY +EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1 +2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw +DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf +gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS +FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0 +V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P +XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I +i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t +TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91 +09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky +Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ +AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj +1oxx +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G2 O=OpenTrust +# Subject: CN=OpenTrust Root CA G2 O=OpenTrust +# Label: "OpenTrust Root CA G2" +# Serial: 1492012448042702096986875987676935573415441 +# MD5 Fingerprint: 57:24:b6:59:24:6b:ae:c8:fe:1c:0c:20:f2:c0:4e:eb +# SHA1 Fingerprint: 79:5f:88:60:c5:ab:7c:3d:92:e6:cb:f4:8d:e1:45:cd:11:ef:60:0b +# SHA256 Fingerprint: 27:99:58:29:fe:6a:75:15:c1:bf:e8:48:f9:c4:76:1d:b1:6c:22:59:29:25:7b:f4:0d:08:94:f2:9e:a8:ba:f2 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh +/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e +CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6 +1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE +FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS +gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X +G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy +YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH +vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4 +t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/ +gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3 +5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w +DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0 +nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT +RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT +wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2 +t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa +TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2 +o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU +3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA +iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f +WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM +S1IK +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G3 O=OpenTrust +# Subject: CN=OpenTrust Root CA G3 O=OpenTrust +# Label: "OpenTrust Root CA G3" +# Serial: 1492104908271485653071219941864171170455615 +# MD5 Fingerprint: 21:37:b4:17:16:92:7b:67:46:70:a9:96:d7:a8:13:24 +# SHA1 Fingerprint: 6e:26:64:f3:56:bf:34:55:bf:d1:93:3f:7c:01:de:d8:13:da:8a:a6 +# SHA256 Fingerprint: b7:c3:62:31:70:6e:81:07:8c:36:7c:b8:96:19:8f:1e:32:08:dd:92:69:49:dd:8f:57:09:a4:10:f7:5b:62:92 +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx +CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U +cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow +QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl +blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm +3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d +oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5 +DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK +BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q +j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx +4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- From e9b90e5e1f8183fd0259ae8ccc9735fb8027fe20 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Wed, 13 Jul 2016 16:57:31 -0700 Subject: [PATCH 026/151] Move Python.h include out of loader code To make a certain private code base work in a certain way nicer than the current way. --- src/python/grpcio/grpc/_cython/cygrpc.pyx | 9 +++++++++ src/python/grpcio/grpc/_cython/loader.c | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index e055d321bc76f..2fc8e1646153a 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -49,6 +49,11 @@ include "grpc/_cython/_cygrpc/server.pyx.pxi" # +cdef extern from "Python.h": + + int Py_AtExit(void(*func)()) + + def _initialize(): if not pygrpc_initialize_core(): raise ImportError('failed to initialize core gRPC library') @@ -56,4 +61,8 @@ def _initialize(): grpc_set_ssl_roots_override_callback( ssl_roots_override_callback) + if Py_AtExit(grpc_shutdown) != 0: + raise ImportError('failed to register gRPC library shutdown callbacks') + + _initialize() diff --git a/src/python/grpcio/grpc/_cython/loader.c b/src/python/grpcio/grpc/_cython/loader.c index 34bd897549522..4698f0aff8d51 100644 --- a/src/python/grpcio/grpc/_cython/loader.c +++ b/src/python/grpcio/grpc/_cython/loader.c @@ -31,7 +31,6 @@ * */ -#include #include "loader.h" #ifdef __cplusplus @@ -43,7 +42,7 @@ int pygrpc_load_core(char *path) { return 1; } // Cython doesn't have Py_AtExit bindings, so we call the C_API directly int pygrpc_initialize_core(void) { grpc_init(); - return Py_AtExit(grpc_shutdown) < 0 ? 0 : 1; + return 1; } #ifdef __cplusplus From f55adec54e4268f33ecd693fc88f0edc03d99137 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 14 Jul 2016 02:20:16 +0200 Subject: [PATCH 027/151] And remaining random leftover items. --- src/core/lib/iomgr/udp_server.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index f7381cebb57fc..48032412a2ee2 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -60,6 +60,7 @@ #include #include #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -128,7 +129,7 @@ grpc_udp_server *grpc_udp_server_create(void) { } static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { - grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1, NULL); + grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL); gpr_mu_destroy(&s->mu); gpr_cv_destroy(&s->cv); @@ -138,7 +139,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { } static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, - bool success) { + grpc_error *error) { grpc_udp_server *s = server; gpr_mu_lock(&s->mu); s->destroyed_ports++; @@ -272,7 +273,7 @@ static int prepare_socket(int fd, const struct sockaddr *addr, } /* event manager callback when reads are ready */ -static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error* error) { +static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { server_port *sp = arg; if (error != GRPC_ERROR_NONE) { From 3acddb20dbac343dcf12a4ba46bfdf7ebacf37f9 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Wed, 13 Jul 2016 18:38:33 -0700 Subject: [PATCH 028/151] Remove Python 'loader' hack --- setup.py | 5 +- .../grpcio/grpc/_cython/_cygrpc/grpc.pxi | 89 +++++++++++-------- src/python/grpcio/grpc/_cython/cygrpc.pyx | 4 +- .../grpcio/grpc/_cython/imports.generated.c | 37 -------- .../grpcio/grpc/_cython/imports.generated.h | 50 ----------- src/python/grpcio/grpc/_cython/loader.c | 51 ----------- src/python/grpcio/grpc/_cython/loader.h | 61 ------------- .../grpc/_cython/imports.generated.c.template | 41 --------- .../grpc/_cython/imports.generated.h.template | 52 ----------- 9 files changed, 53 insertions(+), 337 deletions(-) delete mode 100644 src/python/grpcio/grpc/_cython/imports.generated.c delete mode 100644 src/python/grpcio/grpc/_cython/imports.generated.h delete mode 100644 src/python/grpcio/grpc/_cython/loader.c delete mode 100644 src/python/grpcio/grpc/_cython/loader.h delete mode 100644 templates/src/python/grpcio/grpc/_cython/imports.generated.c.template delete mode 100644 templates/src/python/grpcio/grpc/_cython/imports.generated.h.template diff --git a/setup.py b/setup.py index 700515b894dfc..056e1fd03353c 100644 --- a/setup.py +++ b/setup.py @@ -90,10 +90,7 @@ CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',) -CYTHON_HELPER_C_FILES = ( - os.path.join(PYTHON_STEM, 'grpc/_cython/loader.c'), - os.path.join(PYTHON_STEM, 'grpc/_cython/imports.generated.c'), -) +CYTHON_HELPER_C_FILES = () CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 7714504d1bb80..42fced654570e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -30,19 +30,29 @@ cimport libc.time -cdef extern from "grpc/_cython/loader.h": +# Typedef types with approximately the same semantics to provide their names to +# Cython +ctypedef int int32_t +ctypedef unsigned uint32_t +ctypedef long int64_t - ctypedef int int32_t - ctypedef unsigned uint32_t - ctypedef long int64_t - int pygrpc_load_core(char*) - int pygrpc_initialize_core() +cdef extern from "grpc/support/alloc.h": void *gpr_malloc(size_t size) nogil void gpr_free(void *ptr) nogil void *gpr_realloc(void *p, size_t size) nogil + +cdef extern from "grpc/byte_buffer_reader.h": + + struct grpc_byte_buffer_reader: + # We don't care about the internals + pass + + +cdef extern from "grpc/grpc.h": + ctypedef struct gpr_slice: # don't worry about writing out the members of gpr_slice; we never access # them directly. @@ -86,7 +96,22 @@ cdef extern from "grpc/_cython/loader.h": gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) nogil int gpr_time_cmp(gpr_timespec a, gpr_timespec b) nogil - + + ctypedef struct grpc_byte_buffer: + # We don't care about the internals. + pass + + grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, + size_t nslices) nogil + size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) nogil + void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer) nogil + + int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, + grpc_byte_buffer *buffer) nogil + int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, + gpr_slice *slice) nogil + void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) nogil + ctypedef enum grpc_status_code: GRPC_STATUS_OK GRPC_STATUS_CANCELLED @@ -107,37 +132,6 @@ cdef extern from "grpc/_cython/loader.h": GRPC_STATUS_DATA_LOSS GRPC_STATUS__DO_NOT_USE - ctypedef enum grpc_ssl_roots_override_result: - GRPC_SSL_ROOTS_OVERRIDE_OK - GRPC_SSL_ROOTS_OVERRIDE_FAILED_PERMANENTLY - GRPC_SSL_ROOTS_OVERRIDE_FAILED - - ctypedef enum grpc_ssl_client_certificate_request_type: - GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, - GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY - GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY - GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY - GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY - - struct grpc_byte_buffer_reader: - # We don't care about the internals - pass - - ctypedef struct grpc_byte_buffer: - # We don't care about the internals. - pass - - grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, - size_t nslices) nogil - size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) nogil - void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer) nogil - - int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, - grpc_byte_buffer *buffer) nogil - int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, - gpr_slice *slice) nogil - void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) nogil - const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING const char *GRPC_ARG_ENABLE_CENSUS const char *GRPC_ARG_MAX_CONCURRENT_STREAMS @@ -353,6 +347,21 @@ cdef extern from "grpc/_cython/loader.h": void grpc_server_cancel_all_calls(grpc_server *server) nogil void grpc_server_destroy(grpc_server *server) nogil + +cdef extern from "grpc/grpc_security.h": + + ctypedef enum grpc_ssl_roots_override_result: + GRPC_SSL_ROOTS_OVERRIDE_OK + GRPC_SSL_ROOTS_OVERRIDE_FAILED_PERMANENTLY + GRPC_SSL_ROOTS_OVERRIDE_FAILED + + ctypedef enum grpc_ssl_client_certificate_request_type: + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + ctypedef struct grpc_ssl_pem_key_cert_pair: const char *private_key const char *certificate_chain "cert_chain" @@ -438,6 +447,9 @@ cdef extern from "grpc/_cython/loader.h": grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( grpc_metadata_credentials_plugin plugin, void *reserved) nogil + +cdef extern from "grpc/compression.h": + ctypedef enum grpc_compression_algorithm: GRPC_COMPRESS_NONE GRPC_COMPRESS_DEFLATE @@ -472,3 +484,4 @@ cdef extern from "grpc/_cython/loader.h": int grpc_compression_options_is_algorithm_enabled( const grpc_compression_options *opts, grpc_compression_algorithm algorithm) nogil + diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index 2fc8e1646153a..a9520b9c0fa27 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -55,9 +55,7 @@ cdef extern from "Python.h": def _initialize(): - if not pygrpc_initialize_core(): - raise ImportError('failed to initialize core gRPC library') - + grpc_init() grpc_set_ssl_roots_override_callback( ssl_roots_override_callback) diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c deleted file mode 100644 index c0080b5a47aa6..0000000000000 --- a/src/python/grpcio/grpc/_cython/imports.generated.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* TODO(atash) remove cruft */ -#include - -#include "imports.generated.h" diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h deleted file mode 100644 index 8e5c9a8ce2ba4..0000000000000 --- a/src/python/grpcio/grpc/_cython/imports.generated.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* TODO(atash) remove cruft */ -#ifndef PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ -#define PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/src/python/grpcio/grpc/_cython/loader.c b/src/python/grpcio/grpc/_cython/loader.c deleted file mode 100644 index 4698f0aff8d51..0000000000000 --- a/src/python/grpcio/grpc/_cython/loader.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "loader.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cpluslus */ - -int pygrpc_load_core(char *path) { return 1; } - -// Cython doesn't have Py_AtExit bindings, so we call the C_API directly -int pygrpc_initialize_core(void) { - grpc_init(); - return 1; -} - -#ifdef __cplusplus -} -#endif /* __cpluslus */ - diff --git a/src/python/grpcio/grpc/_cython/loader.h b/src/python/grpcio/grpc/_cython/loader.h deleted file mode 100644 index 62fd225204727..0000000000000 --- a/src/python/grpcio/grpc/_cython/loader.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef PYGRPC_LOADER_H_ -#define PYGRPC_LOADER_H_ - -#include "imports.generated.h" - -/* Additional inclusions not covered by "imports.generated.h" */ -#include - -/* TODO(atash) remove cruft */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cpluslus */ - -/* Attempts to load the core if necessary, and return non-zero upon succes. */ -int pygrpc_load_core(char *path); - -/* Initializes grpc and registers grpc_shutdown() to be called right before - * interpreter exit. Returns non-zero upon success. - */ -int pygrpc_initialize_core(void); - -#ifdef __cplusplus -} -#endif /* __cpluslus */ - -#endif /* GRPC_RB_BYTE_BUFFER_H_ */ - diff --git a/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template b/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template deleted file mode 100644 index d83bccad1db90..0000000000000 --- a/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template +++ /dev/null @@ -1,41 +0,0 @@ -%YAML 1.2 ---- | - /* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - /* TODO(atash) remove cruft */ - #include - - #include "imports.generated.h" - - diff --git a/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template b/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template deleted file mode 100644 index b85bc3dbd8b56..0000000000000 --- a/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template +++ /dev/null @@ -1,52 +0,0 @@ -%YAML 1.2 ---- | - /* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - /* TODO(atash) remove cruft */ - #ifndef PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ - #define PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ - - #include - - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #endif From febe79116c77a26ad863ff28d8fb8bb123ec3421 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 13 Jul 2016 17:12:12 -0700 Subject: [PATCH 029/151] php: fix interop tests breakage --- composer.json | 8 +------- examples/php/composer.json | 6 ------ src/php/README.md | 2 +- src/php/composer.json | 8 +------- templates/composer.json.template | 8 +------- 5 files changed, 4 insertions(+), 28 deletions(-) diff --git a/composer.json b/composer.json index 6e7f24b451eb5..0ebe0a1108447 100644 --- a/composer.json +++ b/composer.json @@ -5,15 +5,9 @@ "keywords": ["rpc"], "homepage": "http://grpc.io", "license": "BSD-3-Clause", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/stanley-cheung/Protobuf-PHP" - } - ], "require": { "php": ">=5.5.0", - "datto/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "dev-master" }, "require-dev": { "google/auth": "v0.9" diff --git a/examples/php/composer.json b/examples/php/composer.json index 950e11367d0f7..a8b790b1de16c 100644 --- a/examples/php/composer.json +++ b/examples/php/composer.json @@ -2,12 +2,6 @@ "name": "grpc/grpc-demo", "description": "gRPC example for PHP", "minimum-stability": "dev", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/stanley-cheung/Protobuf-PHP" - } - ], "require": { "grpc/grpc": "v0.15.0" } diff --git a/src/php/README.md b/src/php/README.md index fba2c0f13b94d..8abedc40a3b38 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -148,7 +148,7 @@ Alternatively, you can download `protoc` binaries from [the protocol buffers Git You need to install `protoc-gen-php` to generate stub class `.php` files from service definition `.proto` files. ```sh -$ cd grpc/src/php/vendor/datto/protobuf-php # if you had run `composer install` in the previous step +$ cd grpc/src/php/vendor/stanley-cheung/protobuf-php # if you had run `composer install` in the previous step OR diff --git a/src/php/composer.json b/src/php/composer.json index b95cde1234ba9..ca8e085fca13d 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -6,15 +6,9 @@ "homepage": "http://grpc.io", "license": "BSD-3-Clause", "version": "1.0.0", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/stanley-cheung/Protobuf-PHP" - } - ], "require": { "php": ">=5.5.0", - "datto/protobuf-php": "dev-master", + "stanley-cheung/protobuf-php": "dev-master", "google/auth": "v0.7" }, "autoload": { diff --git a/templates/composer.json.template b/templates/composer.json.template index c9ffbbcbd019a..07ab1f20ebab2 100644 --- a/templates/composer.json.template +++ b/templates/composer.json.template @@ -7,15 +7,9 @@ "keywords": ["rpc"], "homepage": "http://grpc.io", "license": "BSD-3-Clause", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/stanley-cheung/Protobuf-PHP" - } - ], "require": { "php": ">=5.5.0", - "datto/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "dev-master" }, "require-dev": { "google/auth": "v0.9" From 05573f1692647ca30a10839b61731486700587ac Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 11 Jul 2016 15:48:01 -0700 Subject: [PATCH 030/151] Make Server::Wait work for async only server. --- include/grpc++/server.h | 2 ++ src/cpp/server/server.cc | 5 ++--- test/cpp/end2end/async_end2end_test.cc | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 7a8858ef1941f..9a2f8f11c4223 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -183,6 +183,8 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen { int num_running_cb_; grpc::condition_variable callback_cv_; + grpc::condition_variable shutdown_cv_; + std::shared_ptr global_callbacks_; std::list* sync_methods_; diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index fb4c68ebe4905..374c9cbc04859 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -462,14 +462,13 @@ void Server::ShutdownInternal(gpr_timespec deadline) { while (num_running_cb_ != 0) { callback_cv_.wait(lock); } + shutdown_cv_.notify_all(); } } void Server::Wait() { grpc::unique_lock lock(mu_); - while (num_running_cb_ != 0) { - callback_cv_.wait(lock); - } + shutdown_cv_.wait(lock); } void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) { diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 6c7eae53a40bd..01ba8962d798a 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -345,6 +345,24 @@ TEST_P(AsyncEnd2endTest, SequentialRpcs) { SendRpc(10); } +// We do not need to protect notify because the use is synchronized. +void ServerWait(Server* server, int* notify) { + server->Wait(); + *notify = 1; +} +TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) { + int notify = 0; + std::thread* wait_thread = + new std::thread(&ServerWait, server_.get(), ¬ify); + ResetStub(); + SendRpc(1); + EXPECT_EQ(0, notify); + server_->Shutdown(); + wait_thread->join(); + EXPECT_EQ(1, notify); + delete wait_thread; +} + // Test a simple RPC using the async version of Next TEST_P(AsyncEnd2endTest, AsyncNextRpc) { ResetStub(); From c05539f8a464ebc81e7295879d4a85ff69843cd7 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 09:12:51 -0700 Subject: [PATCH 031/151] Tweaked grpc_handshaker API and added grpc_handshake_manager API. --- src/core/lib/channel/handshaker.c | 115 +++++++++++++++++++++++++++++- src/core/lib/channel/handshaker.h | 41 ++++++++++- 2 files changed, 150 insertions(+), 6 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 00d810e63df1e..3018b95464ccd 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -33,6 +33,10 @@ #include "src/core/lib/channel/handshaker.h" +// +// grpc_handshaker +// + void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, grpc_handshaker** handshaker) { handshaker->vtable = vtable; @@ -43,11 +47,116 @@ void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, handshaker->vtable->destroy(exec_ctx, handshaker); } +void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker) { + handshaker->vtable->shutdown(exec_ctx, handshaker); +} + void grpc_handshaker_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint_in, gpr_timespec deadline, grpc_closure *on_done) { - handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint_in, - deadline, on_done); + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, + deadline, cb, arg); +} + +// +// grpc_handshake_manager +// + +// State used while chaining handshakers. +struct grpc_handshaker_state { + // The index of the handshaker to invoke next. + size_t index; + // The deadline for all handshakers. + gpr_timespec deadline; + // The final callback and arg to invoke after the last handshaker. + grpc_handshaker_done_cb final_cb; + void* final_arg; +}; + +struct grpc_handshake_manager { + // An array of handshakers added via grpc_handshake_manager_add(). + size_t count; + grpc_handshaker* handshakers; + // State used while chaining handshakers. + grpc_handshaker_state* state; +}; + +grpc_handshake_manager* grpc_handshake_manager_create() { + grpc_handshake_manager* mgr = gpr_malloc(sizeof(grpc_handshake_manager)); + memset(mgr, 0, sizeof(*mgr)); + return mgr; +} + +void grpc_handshake_manager_add(grpc_handshaker* handshaker, + grpc_handshake_manager* mgr) { + mgr->handshakers = gpr_realloc(mgr->handshakers, + (mgr->count + 1) * sizeof(grpc_handshaker*)); + mgr->handshakers[mgr->count++] = handshaker; +} + +void grpc_handshake_manager_destroy( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { + for (int i = 0; i < mgr->count; ++i) { + grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); + } + gpr_free(mgr); +} + +void grpc_handshake_manager_shutdown( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { + // FIXME: maybe check which handshaker is currently in progress, and + // only shut down that one? + for (int i = 0; i < mgr->count; ++i) { + grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[i]); + } + if (mgr->state != NULL) { + gpr_free(mgr->state); + mgr->state = NULL; + } +} + +// A function used as the handshaker-done callback when chaining +// handshakers together. +static void call_next_handshaker(grpc_exec_ctx* exec_ctx, + grpc_endpoint* endpoint, void* arg) { + grpc_handshake_manager* mgr = arg; + GPR_ASSERT(mgr->state != NULL); + GPR_ASSERT(mgr->state->index < mgr->count); + grpc_handshaker_done_cb cb = call_next_handshaker; + // If this is the last handshaker, use the caller-supplied callback + // and arg instead of chaining back to this function again. + if (mgr->state->index == mgr->count - 1) { + cb = mgr->state->final_cb; + arg = mgr->state->final_arg; + } + // Invoke handshaker. + grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], + endpoint, mgr->state->deadline, cb, arg); + ++mgr->state->index; + // If this is the last handshaker, clean up state. + if (mgr->state->index == mgr->count) { + gpr_free(mgr->state); + mgr->state = NULL; + } +} + +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg) { + if (mgr->count == 0) { + // No handshakers registered, so we just immediately call the done + // callback with the passed-in endpoint. + cb(exec_ctx, endpoint, arg); + } else { + GPR_ASSERT(mgr->state == NULL); + mgr->state = gpr_malloc(sizeof(grpc_handshaker_state)); + memset(mgr->state, 0, sizeof(grpc_handshaker_state)); + *mgr->state = {0, deadline, cb, arg}; + call_next_handshaker(exec_ctx, endpoint, mgr); + } } #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 1ca85fd0088e4..c4e3bef5a50eb 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -40,17 +40,26 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" +// +// grpc_handshaker -- API for initial handshaking for a new connection +// + // FIXME: document typedef struct grpc_handshaker grpc_handshaker; +typedef void (*grpc_handshaker_done_cb)( + grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, void* arg); + struct grpc_handshaker_vtable { void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + void (*do_handshake)( grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint_in, gpr_timespec deadline, - grpc_closure *on_done); + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); }; struct grpc_handshaker { @@ -64,8 +73,34 @@ void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, // Convenient wrappers for invoking methods via the vtable. void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); +void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker); void grpc_handshaker_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* in, gpr_timespec deadline, grpc_closure *on_done); + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); + +// +// grpc_handshake_manager -- manages a set of handshakers +// + +typedef struct grpc_handshake_manager grpc_handshake_manager; + +grpc_handshake_manager* grpc_handshake_manager_create(); + +// Handshakers will be invoked in the order added. +void grpc_handshake_manager_add(grpc_handshaker* handshaker, + grpc_handshake_manager* mgr); + +void grpc_handshake_manager_destroy( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); + +void grpc_handshake_manager_shutdown( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); + +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 1d3b2cc84948b874985951039fab1965d0a30ef5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 09:18:12 -0700 Subject: [PATCH 032/151] clang-format --- src/core/lib/channel/handshaker.c | 33 +++++++++++++------------- src/core/lib/channel/handshaker.h | 39 ++++++++++++++++--------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 3018b95464ccd..65c2a96df70f4 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -52,12 +52,13 @@ void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, handshaker->vtable->shutdown(exec_ctx, handshaker); } -void grpc_handshaker_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg) { - handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, - deadline, cb, arg); +void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, deadline, cb, + arg); } // @@ -96,16 +97,16 @@ void grpc_handshake_manager_add(grpc_handshaker* handshaker, mgr->handshakers[mgr->count++] = handshaker; } -void grpc_handshake_manager_destroy( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { +void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr) { for (int i = 0; i < mgr->count; ++i) { grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); } gpr_free(mgr); } -void grpc_handshake_manager_shutdown( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { +void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr) { // FIXME: maybe check which handshaker is currently in progress, and // only shut down that one? for (int i = 0; i < mgr->count; ++i) { @@ -142,10 +143,12 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, } } -void grpc_handshake_manager_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg) { +void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, + void* arg) { if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done // callback with the passed-in endpoint. @@ -158,5 +161,3 @@ void grpc_handshake_manager_do_handshake( call_next_handshaker(exec_ctx, endpoint, mgr); } } - -#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index c4e3bef5a50eb..583df4b241909 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -48,22 +48,21 @@ typedef struct grpc_handshaker grpc_handshaker; -typedef void (*grpc_handshaker_done_cb)( - grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, void* arg); +typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx, + grpc_endpoint* endpoint, void* arg); struct grpc_handshaker_vtable { void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); - void (*do_handshake)( - grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); }; struct grpc_handshaker { - const struct grpc_handshaker_vtable *vtable; + const struct grpc_handshaker_vtable* vtable; }; // Called by concrete implementations to initialize the base struct. @@ -75,10 +74,11 @@ void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); -void grpc_handshaker_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); +void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); // // grpc_handshake_manager -- manages a set of handshakers @@ -92,15 +92,16 @@ grpc_handshake_manager* grpc_handshake_manager_create(); void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr); -void grpc_handshake_manager_destroy( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr); -void grpc_handshake_manager_shutdown( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr); -void grpc_handshake_manager_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); +void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From dfbdefedd381b57dd33631aea3a79659ac019bc9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 09:18:22 -0700 Subject: [PATCH 033/151] Added handshaker.[ch] to build.yaml. --- BUILD | 8 ++++++++ CMakeLists.txt | 3 +++ Makefile | 3 +++ binding.gyp | 1 + build.yaml | 2 ++ config.m4 | 1 + gRPC-Core.podspec | 3 +++ gRPC.podspec | 3 +++ grpc.gemspec | 2 ++ package.xml | 2 ++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 ++ tools/run_tests/sources_and_headers.json | 3 +++ vsprojects/vcxproj/grpc/grpc.vcxproj | 3 +++ vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 ++++++ vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 +++ .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 ++++++ 17 files changed, 52 insertions(+) diff --git a/BUILD b/BUILD index 33323be229d12..8a6d7fdc0a611 100644 --- a/BUILD +++ b/BUILD @@ -165,6 +165,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -316,6 +317,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -552,6 +554,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -693,6 +696,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -904,6 +908,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -1032,6 +1037,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -1791,6 +1797,7 @@ objc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -2006,6 +2013,7 @@ objc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c0059cd2dbd1..1f647e0a988d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,7 @@ add_library(grpc src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c @@ -344,6 +345,7 @@ add_library(grpc_cronet src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c @@ -526,6 +528,7 @@ add_library(grpc_unsecure src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c diff --git a/Makefile b/Makefile index e958b145e7773..efc1cec90c83d 100644 --- a/Makefile +++ b/Makefile @@ -2479,6 +2479,7 @@ LIBGRPC_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -2751,6 +2752,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -3092,6 +3094,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ diff --git a/binding.gyp b/binding.gyp index e1130ad01abca..1dd7ee95555d5 100644 --- a/binding.gyp +++ b/binding.gyp @@ -568,6 +568,7 @@ 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', diff --git a/build.yaml b/build.yaml index 071d4a8e1eab7..21490d00d9c68 100644 --- a/build.yaml +++ b/build.yaml @@ -156,6 +156,7 @@ filegroups: - src/core/lib/channel/compress_filter.h - src/core/lib/channel/connected_channel.h - src/core/lib/channel/context.h + - src/core/lib/channel/handshaker.h - src/core/lib/channel/http_client_filter.h - src/core/lib/channel/http_server_filter.h - src/core/lib/compression/algorithm_metadata.h @@ -234,6 +235,7 @@ filegroups: - src/core/lib/channel/channel_stack_builder.c - src/core/lib/channel/compress_filter.c - src/core/lib/channel/connected_channel.c + - src/core/lib/channel/handshaker.c - src/core/lib/channel/http_client_filter.c - src/core/lib/channel/http_server_filter.c - src/core/lib/compression/compression.c diff --git a/config.m4 b/config.m4 index 0c3322d8efe99..e4e410884d02b 100644 --- a/config.m4 +++ b/config.m4 @@ -87,6 +87,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e10e05387b15a..afe9cffc4c693 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -256,6 +256,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', @@ -411,6 +412,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', @@ -609,6 +611,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', diff --git a/gRPC.podspec b/gRPC.podspec index fd58bd6281f0e..78cb164fac946 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -168,6 +168,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', @@ -353,6 +354,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', @@ -551,6 +553,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', diff --git a/grpc.gemspec b/grpc.gemspec index 369851b0f242d..6b8beba907808 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -177,6 +177,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/compress_filter.h ) s.files += %w( src/core/lib/channel/connected_channel.h ) s.files += %w( src/core/lib/channel/context.h ) + s.files += %w( src/core/lib/channel/handshaker.h ) s.files += %w( src/core/lib/channel/http_client_filter.h ) s.files += %w( src/core/lib/channel/http_server_filter.h ) s.files += %w( src/core/lib/compression/algorithm_metadata.h ) @@ -332,6 +333,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/channel_stack_builder.c ) s.files += %w( src/core/lib/channel/compress_filter.c ) s.files += %w( src/core/lib/channel/connected_channel.c ) + s.files += %w( src/core/lib/channel/handshaker.c ) s.files += %w( src/core/lib/channel/http_client_filter.c ) s.files += %w( src/core/lib/channel/http_server_filter.c ) s.files += %w( src/core/lib/compression/compression.c ) diff --git a/package.xml b/package.xml index d7d10b3f7cc92..b4ec9f994f74e 100644 --- a/package.xml +++ b/package.xml @@ -184,6 +184,7 @@ + @@ -339,6 +340,7 @@ + diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index b37e27c27ea67..fc0908b2f1b4e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -81,6 +81,7 @@ 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 8233da957d1ca..62cf5cc8c7ae1 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -796,6 +796,7 @@ src/core/lib/channel/channel_stack_builder.h \ src/core/lib/channel/compress_filter.h \ src/core/lib/channel/connected_channel.h \ src/core/lib/channel/context.h \ +src/core/lib/channel/handshaker.h \ src/core/lib/channel/http_client_filter.h \ src/core/lib/channel/http_server_filter.h \ src/core/lib/compression/algorithm_metadata.h \ @@ -951,6 +952,7 @@ src/core/lib/channel/channel_stack.c \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ +src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index cdbc254f4306a..ee24a63077aea 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -5712,6 +5712,7 @@ "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -5805,6 +5806,8 @@ "src/core/lib/channel/connected_channel.c", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.c", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index a9e96dab462e6..33485d3dc919f 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -305,6 +305,7 @@ + @@ -468,6 +469,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index be77e53f457e7..a21d873b88f96 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -19,6 +19,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel @@ -671,6 +674,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 1cfe06aec6d38..3a3610d524ddd 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -294,6 +294,7 @@ + @@ -435,6 +436,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index c33c6650e7086..bec089e860ecd 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -22,6 +22,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel @@ -578,6 +581,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel From 54698a9184467c8db0d5844da086c1d5dcc606e4 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Thu, 14 Jul 2016 11:32:15 -0700 Subject: [PATCH 034/151] Updated with PR comments. --- doc/load-balancing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 05d555a3f1334..6da2479d24abf 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -92,7 +92,7 @@ servers. the client will attempt to open a stream to the load balancer service. The server may respond in only one of the following ways. 1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client - proceeds by sending all RPCs to this gRPC server. + call will fail. 1. "I am a Load Balancer and here is the server list." (Goto Step 4.) 1. "Please contact Load Balancer X" (See Step 3.) The client will close this connection and cancel the stream. From 7c2a58c107d9c64ed27642a916d60e1776788f0e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 11:53:47 -0700 Subject: [PATCH 035/151] Fix build problems. --- src/core/lib/channel/handshaker.c | 23 +++++++++++++++-------- src/core/lib/channel/handshaker.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 65c2a96df70f4..5b8c08bc15123 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -31,6 +31,11 @@ * */ +#include + +#include +#include + #include "src/core/lib/channel/handshaker.h" // @@ -38,7 +43,7 @@ // void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, - grpc_handshaker** handshaker) { + grpc_handshaker* handshaker) { handshaker->vtable = vtable; } @@ -79,9 +84,9 @@ struct grpc_handshaker_state { struct grpc_handshake_manager { // An array of handshakers added via grpc_handshake_manager_add(). size_t count; - grpc_handshaker* handshakers; + grpc_handshaker** handshakers; // State used while chaining handshakers. - grpc_handshaker_state* state; + struct grpc_handshaker_state* state; }; grpc_handshake_manager* grpc_handshake_manager_create() { @@ -99,7 +104,7 @@ void grpc_handshake_manager_add(grpc_handshaker* handshaker, void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { - for (int i = 0; i < mgr->count; ++i) { + for (size_t i = 0; i < mgr->count; ++i) { grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); } gpr_free(mgr); @@ -109,7 +114,7 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { // FIXME: maybe check which handshaker is currently in progress, and // only shut down that one? - for (int i = 0; i < mgr->count; ++i) { + for (size_t i = 0; i < mgr->count; ++i) { grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[i]); } if (mgr->state != NULL) { @@ -155,9 +160,11 @@ void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, cb(exec_ctx, endpoint, arg); } else { GPR_ASSERT(mgr->state == NULL); - mgr->state = gpr_malloc(sizeof(grpc_handshaker_state)); - memset(mgr->state, 0, sizeof(grpc_handshaker_state)); - *mgr->state = {0, deadline, cb, arg}; + mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); + memset(mgr->state, 0, sizeof(*mgr->state)); + mgr->state->deadline = deadline; + mgr->state->final_cb = cb; + mgr->state->final_arg = arg; call_next_handshaker(exec_ctx, endpoint, mgr); } } diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 583df4b241909..8cb6fdbc805d3 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -67,7 +67,7 @@ struct grpc_handshaker { // Called by concrete implementations to initialize the base struct. void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, - grpc_handshaker** handshaker); + grpc_handshaker* handshaker); // Convenient wrappers for invoking methods via the vtable. void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, From 142efc905f835f39010cf3efe6ec5cfe04a251ff Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 14 Jul 2016 13:33:35 -0700 Subject: [PATCH 036/151] Establish Objective C end-to-end core test with Cronet --- .../End2EndTest.xcodeproj/project.pbxproj | 8 ++-- .../End2EndTest/End2EndTest/ViewController.h | 39 +++++++++++++++---- .../End2EndTest/End2EndTest/ViewController.m | 39 +++++++++++++++---- 3 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj index a878db9c2e33e..bf412187f43d8 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj @@ -7,18 +7,18 @@ objects = { /* Begin PBXBuildFile section */ + 1518576073757E501D232EDA /* Pods_End2EndTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4035DBC43CDC1A29CB0EB05D /* Pods_End2EndTest.framework */; }; 5E201A771D3452D500A81F3A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E201A761D3452D500A81F3A /* AppDelegate.m */; }; 5E201A7A1D3452D500A81F3A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E201A791D3452D500A81F3A /* ViewController.m */; }; 5E201A7D1D3452D500A81F3A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A7B1D3452D500A81F3A /* Main.storyboard */; }; 5E201A7F1D3452D600A81F3A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A7E1D3452D600A81F3A /* Assets.xcassets */; }; 5E201A821D3452D600A81F3A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */; }; 5EC76B971D36B2EE00A74FED /* h2_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EC76B961D36B2EE00A74FED /* h2_ssl.m */; }; - 809A4524D003F25B67A9E20C /* libPods-End2EndTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45442114339F6871ABA5F464 /* libPods-End2EndTest.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-End2EndTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest.debug.xcconfig"; sourceTree = ""; }; - 45442114339F6871ABA5F464 /* libPods-End2EndTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-End2EndTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4035DBC43CDC1A29CB0EB05D /* Pods_End2EndTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_End2EndTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5E201A6F1D3452D500A81F3A /* End2EndTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = End2EndTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5E201A751D3452D500A81F3A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 5E201A761D3452D500A81F3A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -37,7 +37,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 809A4524D003F25B67A9E20C /* libPods-End2EndTest.a in Frameworks */, + 1518576073757E501D232EDA /* Pods_End2EndTest.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -98,7 +98,7 @@ D564C37197511893E4E62D12 /* Frameworks */ = { isa = PBXGroup; children = ( - 45442114339F6871ABA5F464 /* libPods-End2EndTest.a */, + 4035DBC43CDC1A29CB0EB05D /* Pods_End2EndTest.framework */, ); name = Frameworks; sourceTree = ""; diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h index 941477a48ca70..38cd7f92b660a 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h +++ b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h @@ -1,10 +1,35 @@ -// -// ViewController.h -// End2EndTest -// -// Created by mxyan on 7/11/16. -// Copyright © 2016 Google. All rights reserved. -// +/* + * + * 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. + * + */ #import diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m index 535e40bcb392f..70b5d45811051 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m +++ b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m @@ -1,10 +1,35 @@ -// -// ViewController.m -// End2EndTest -// -// Created by mxyan on 7/11/16. -// Copyright © 2016 Google. All rights reserved. -// +/* + * + * 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. + * + */ #import "ViewController.h" From dba5d2708c6d59a73b65d378440dc64b3af2b873 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 13:45:05 -0700 Subject: [PATCH 037/151] Use handshake_manager API in client and server. --- .../chttp2/client/insecure/channel_create.c | 34 +++++++++++---- .../client/secure/secure_channel_create.c | 28 ++++++++++--- .../chttp2/server/insecure/server_chttp2.c | 42 +++++++++++++++---- .../server/secure/server_secure_chttp2.c | 32 +++++++++++--- src/core/lib/channel/handshaker.h | 2 + 5 files changed, 111 insertions(+), 27 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 85f9efb3b634a..648a9d90a5fd8 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -45,6 +45,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_client_filter.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/surface/api_trace.h" @@ -63,6 +64,8 @@ typedef struct { grpc_endpoint *tcp; grpc_closure connected; + + grpc_handshake_manager *handshake_mgr; } connector; static void connector_ref(grpc_connector *con) { @@ -74,6 +77,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } } @@ -83,6 +87,19 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, connector_unref(exec_ctx, arg); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + connector *c = arg; + c->result->transport = + grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, endpoint, 1); + GPR_ASSERT(c->result->transport); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); + c->result->channel_args = grpc_channel_args_copy(c->args.channel_args); + grpc_closure *notify = c->notify; + c->notify = NULL; + grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); +} + static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; grpc_closure *notify; @@ -97,19 +114,17 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector_ref(arg); grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); + } else { + grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.deadline, on_handshake_done, + c); } - c->result->transport = - grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); - GPR_ASSERT(c->result->transport); - c->result->channel_args = grpc_channel_args_copy(c->args.channel_args); } else { memset(c->result, 0, sizeof(*c->result)); + notify = c->notify; + c->notify = NULL; + grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } - notify = c->notify; - c->notify = NULL; - grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {} @@ -171,6 +186,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel( memset(c, 0, sizeof(*c)); c->base.vtable = &connector_vtable; gpr_ref_init(&c->refs, 1); + c->handshake_mgr = grpc_handshake_manager_create(); args->args = final_args; s = grpc_subchannel_create(exec_ctx, &c->base, args); grpc_connector_unref(exec_ctx, &c->base); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 721ba82d8f7c9..30477ded1a310 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -44,6 +44,7 @@ #include "src/core/ext/client_config/resolver_registry.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -69,6 +70,8 @@ typedef struct { grpc_endpoint *newly_connecting_endpoint; grpc_closure connected_closure; + + grpc_handshake_manager *handshake_mgr; } connector; static void connector_ref(grpc_connector *con) { @@ -80,6 +83,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } } @@ -116,12 +120,23 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + connector *c = arg; + // TODO(roth, jboeuf): Convert security connector handshaking to use new + // handshake API, and then move the code from on_secure_handshake_done() + // into this function. + grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector, + endpoint, c->args.deadline, + on_secure_handshake_done, c); +} + static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, c->connecting_endpoint, c->args.deadline, - on_secure_handshake_done, c); + grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, + c->connecting_endpoint, c->args.deadline, + on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -142,9 +157,9 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); } else { - grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, tcp, c->args.deadline, - on_secure_handshake_done, c); + grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.deadline, on_handshake_done, + c); } } else { memset(c->result, 0, sizeof(*c->result)); @@ -227,6 +242,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel( memset(c, 0, sizeof(*c)); c->base.vtable = &connector_vtable; c->security_connector = f->security_connector; + c->handshake_mgr = grpc_handshake_manager_create(); gpr_mu_init(&c->mu); gpr_ref_init(&c->refs, 1); args->args = final_args; diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index e5c987925c3bd..d3748f576d585 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -38,15 +38,23 @@ #include #include #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/server.h" -static void new_transport(grpc_exec_ctx *exec_ctx, void *server, - grpc_endpoint *tcp, grpc_pollset *accepting_pollset, - grpc_tcp_server_acceptor *acceptor) { +typedef struct server_connect_state { + grpc_server *server; + grpc_pollset *accepting_pollset; + grpc_tcp_server_acceptor *acceptor; + grpc_handshake_manager *handshake_mgr; +} server_connect_state; + +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + server_connect_state *state = arg; /* * Beware that the call to grpc_create_chttp2_transport() has to happen before * grpc_tcp_server_destroy(). This is fine here, but similar code @@ -55,17 +63,37 @@ static void new_transport(grpc_exec_ctx *exec_ctx, void *server, * case. */ grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(server), tcp, 0); - grpc_server_setup_transport(exec_ctx, server, transport, accepting_pollset, - grpc_server_get_channel_args(server)); + exec_ctx, grpc_server_get_channel_args(state->server), endpoint, 0); + grpc_server_setup_transport(exec_ctx, state->server, transport, + state->accepting_pollset, + grpc_server_get_channel_args(state->server)); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + // Clean up. + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + gpr_free(state); +} + +static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, + grpc_pollset *accepting_pollset, + grpc_tcp_server_acceptor *acceptor) { + server_connect_state *state = gpr_malloc(sizeof(server_connect_state)); + state->server = server; + state->accepting_pollset = accepting_pollset; + state->acceptor = acceptor; + state->handshake_mgr = grpc_handshake_manager_create(); + // TODO(roth): We should really get this timeout value from channel + // args instead of hard-coding it. + const gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); + grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, + deadline, on_handshake_done, state); } /* Server callback: start listening on our ports */ static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) { grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport, + grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, on_accept, server); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index c42810e9130a5..57931bdb43bc8 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -42,6 +42,7 @@ #include #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -68,6 +69,10 @@ typedef struct server_secure_state { typedef struct server_secure_connect { server_secure_state *state; grpc_pollset *accepting_pollset; + grpc_tcp_server_acceptor *acceptor; + gpr_timespec deadline; // FIXME: remove when we eliminate + // grpc_server_security_connector_do_handshake() + grpc_handshake_manager *handshake_mgr; } server_secure_connect; static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); } @@ -122,6 +127,19 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, gpr_free(state); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + server_secure_connect *state = arg; + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + state->handshake_mgr = NULL; + // TODO(roth, jboeuf): Convert security connector handshaking to use new + // handshake API, and then move the code from on_secure_handshake_done() + // into this function. + grpc_server_security_connector_do_handshake( + exec_ctx, state->state->sc, state->acceptor, endpoint, state->deadline, + on_secure_handshake_done, state); +} + static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, grpc_pollset *accepting_pollset, grpc_tcp_server_acceptor *acceptor) { @@ -129,11 +147,15 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, state->state = statep; state_ref(state->state); state->accepting_pollset = accepting_pollset; - grpc_server_security_connector_do_handshake( - exec_ctx, state->state->sc, acceptor, tcp, - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(120, GPR_TIMESPAN)), - on_secure_handshake_done, state); + state->acceptor = acceptor; + // TODO(roth): We should really get this timeout value from channel + // args instead of hard-coding it. + state->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(120, GPR_TIMESPAN)); + state->handshake_mgr = grpc_handshake_manager_create(); + grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, + state->deadline, on_handshake_done, + state); } /* Server callback: start listening on our ports */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 8cb6fdbc805d3..9d084f071771c 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -40,6 +40,8 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" +// FIXME: high-level documentation + // // grpc_handshaker -- API for initial handshaking for a new connection // From 37480eb60a3beebddb6a582c5f95de660abe4d8b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 14 Jul 2016 16:22:03 -0700 Subject: [PATCH 038/151] Establish Objective C end-to-end core test with Cronet --- gRPC-Core.podspec | 23 +- gRPC-Cronet.podspec | 117 ---------- .../CoreCronetEnd2EndTests.m | 39 ++++ .../tests/CoreCronetEnd2EndTests/h2_ssl.m | 206 ++++++++++++++++++ src/objective-c/tests/Podfile | 9 +- .../tests/Tests.xcodeproj/project.pbxproj | 170 +++++++++++++++ templates/gRPC-Core.podspec.template | 24 ++ 7 files changed, 469 insertions(+), 119 deletions(-) delete mode 100644 gRPC-Cronet.podspec create mode 100644 src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m create mode 100644 src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e10e05387b15a..4811abf698bae 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -193,7 +193,6 @@ Pod::Spec.new do |s| ss.dependency "#{s.name}/Interface", version ss.dependency 'BoringSSL', '~> 4.0' - # To save you from scrolling, this is the last part of the podspec. ss.source_files = 'src/core/lib/profiling/timers.h', 'src/core/lib/support/backoff.h', 'src/core/lib/support/block_annotate.h', @@ -759,4 +758,26 @@ Pod::Spec.new do |s| 'src/core/ext/census/mlog.h', 'src/core/ext/census/rpc_metric_id.h' end + + s.subspec 'Cronet-Interface' do |ss| + ss.header_mappings_dir = 'include/grpc' + ss.source_files = 'include/grpc/grpc_cronet.h' + end + + s.subspec 'Cronet-Tests' do |ss| + ss.header_mappings_dir = '.' + + ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', + 'src/core/ext/transport/cronet/transport/cronet_transport.c', + 'test/core/end2end/cq_verifier.{c,h}', + 'test/core/end2end/end2end_tests.{c,h}', + 'test/core/end2end/tests/*.{c,h}', + 'test/core/end2end/data/*.{c,h}', + 'test/core/util/test_config.{c,h}', + 'test/core/util/port.h', + 'test/core/util/port_posix.c', + 'test/core/util/port_server_client.{c,h}' + + ss.dependency 'CronetFramework' + end end diff --git a/gRPC-Cronet.podspec b/gRPC-Cronet.podspec deleted file mode 100644 index b353bf9a43760..0000000000000 --- a/gRPC-Cronet.podspec +++ /dev/null @@ -1,117 +0,0 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.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. - - -Pod::Spec.new do |s| - s.name = 'gRPC-Cronet' - version = '0.14.0' - s.version = version - s.summary = 'Integration of CroNet framework into gRPC' - s.homepage = 'http://www.grpc.io' - s.license = 'New BSD' - s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - - s.source = { - :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", - } - - s.ios.deployment_target = '7.1' - s.osx.deployment_target = '10.9' - s.requires_arc = false - - name = 'GRPCCronet' - - s.module_name = name - - # When creating a dynamic framework, copy the headers under `include/grpc/` into the root of - # the `Headers/` directory of the framework (i.e., not under `Headers/include/grpc`). - s.header_mappings_dir = 'include/grpc' - - # The above has an undesired effect when creating a static library: It forces users to write - # includes like `#include `. `s.header_dir` adds a path prefix to that, and - # because Cocoapods lets omit the pod name when including headers of static libraries, the - # following lets users write `#include `. - s.header_dir = 'grpc' - - # To compile the library, we need the user headers search path (quoted includes) to point to the - # root of the repo, and the system headers search path (angled includes) to point to `include/`. - # Cocoapods effectively clones the repo under `/Pods/gRPC-Cronet/`, and sets a build - # variable called `$(PODS_ROOT)` to `/Pods/`, so we use that. - # - # Relying on the file structure under $(PODS_ROOT) isn't officially supported in Cocoapods, as it - # is taken as an implementation detail. We've asked for an alternative, and have been told that - # what we're doing should keep working: https://github.com/CocoaPods/CocoaPods/issues/4386 - # - # The `src_root` value of `$(PODS_ROOT)/gRPC-Cronet` assumes Cocoapods is installing this pod from - # its remote repo. For local development of this library, enabled by using `:path` in the Podfile, - # that assumption is wrong. In such case, the following settings need to be reset with the - # appropriate value of `src_root`. This can be accomplished in the `pre_install` hook of the - # Podfile; see `src/objective-c/tests/Podfile` for an example. - src_root = '$(PODS_ROOT)/gRPC-Cronet' - s.pod_target_xcconfig = { - 'GRPC_SRC_ROOT' => src_root, - 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', - 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', - # If we don't set these two settings, `include/grpc/support/time.h` and - # `src/core/lib/support/string.h` shadow the system `` and ``, breaking the - # build. - 'USE_HEADERMAP' => 'NO', - 'ALWAYS_SEARCH_USER_PATHS' => 'NO', - } - - s.subspec 'Interface' do |ss| - ss.header_mappings_dir = 'include/grpc' - ss.source_files = 'include/grpc/grpc_cronet.h' - end - - s.subspec 'Implementation' do |ss| - ss.header_mappings_dir = '.' - - ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', - 'src/core/ext/transport/cronet/transport/cronet_transport.c', - 'test/core/end2end/cq_verifier.{c,h}', - 'test/core/end2end/end2end_tests.{c,h}', - 'test/core/end2end/tests/*.{c,h}', - 'test/core/end2end/data/*.{c,h}', - 'test/core/util/test_config.{c,h}', - 'test/core/util/port.h', - 'test/core/util/port_posix.c', - 'test/core/util/port_server_client.{c,h}' - - ss.dependency 'gRPC-Core', version - ss.dependency 'CronetFramework' - end -end diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m new file mode 100644 index 0000000000000..0f07b6682e67d --- /dev/null +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -0,0 +1,39 @@ +// +// CoreCronetEnd2EndTests.m +// CoreCronetEnd2EndTests +// +// Created by Muxi Yan on 7/14/16. +// Copyright © 2016 gRPC. All rights reserved. +// + +#import + +@interface CoreCronetEnd2EndTests : XCTestCase + +@end + +@implementation CoreCronetEnd2EndTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m new file mode 100644 index 0000000000000..800dd56649a1e --- /dev/null +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m @@ -0,0 +1,206 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * This fixture creates a server full stack using chttp2 and a client + * full stack using Cronet. End-to-end tests are run against this fixture + * setting. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include + +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +#include +#import + +#import +#import "AppDelegate.h" + +typedef struct fullstack_secure_fixture_data { + char *localaddr; +} fullstack_secure_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( + grpc_channel_args *client_args, grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + int port = grpc_pick_unused_port_or_die(); + fullstack_secure_fixture_data *ffd = + gpr_malloc(sizeof(fullstack_secure_fixture_data)); + memset(&f, 0, sizeof(f)); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); + + f.fixture_data = ffd; + f.cq = grpc_completion_queue_create(NULL); + + return f; +} + +static void process_auth_failure(void *state, grpc_auth_context *ctx, + const grpc_metadata *md, size_t md_count, + grpc_process_auth_metadata_done_cb cb, + void *user_data) { + GPR_ASSERT(state == NULL); + cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); +} + +static void cronet_init_client_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *client_args, + cronet_engine *cronetEngine) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + f->client = + grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); + GPR_ASSERT(f->client != NULL); +} + +static void chttp2_init_server_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args, + grpc_server_credentials *server_creds) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args, NULL); + grpc_server_register_completion_queue(f->server, f->cq, NULL); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + server_creds)); + grpc_server_credentials_release(server_creds); + grpc_server_start(f->server); +} + +void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + gpr_free(ffd->localaddr); + gpr_free(ffd); +} + +static void cronet_init_client_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { + grpc_arg ssl_name_override = {GRPC_ARG_STRING, + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + {"foo.test.google.fr"}}; + + grpc_channel_args *new_client_args = + grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + cronet_engine *cronetEngine = [Cronet getGlobalEngine]; + + cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); + grpc_channel_args_destroy(new_client_args); +} + +static int fail_server_auth_check(grpc_channel_args *server_args) { + size_t i; + if (server_args == NULL) return 0; + for (i = 0; i < server_args->num_args; i++) { + if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == + 0) { + return 1; + } + } + return 0; +} + +static void chttp2_init_server_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { + grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, + test_server1_cert}; + grpc_server_credentials *ssl_creds = + grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); + if (fail_server_auth_check(server_args)) { + grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; + grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); + } + chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); +} + +/* All test configurations */ + +static grpc_end2end_test_config configs[] = { + {"chttp2/simple_ssl_fullstack", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + chttp2_create_fixture_secure_fullstack, + cronet_init_client_simple_ssl_secure_fullstack, + chttp2_init_server_simple_ssl_secure_fullstack, + chttp2_tear_down_secure_fullstack}, +}; + +int main(int argc, char **argv) { + size_t i; + FILE *roots_file; + size_t roots_size = strlen(test_root_cert); + char *roots_filename; + + grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); + + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); + GPR_ASSERT(roots_filename != NULL); + GPR_ASSERT(roots_file != NULL); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + + grpc_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + + grpc_shutdown(); + + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); +} diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 30a34260d407c..62ffd59f07947 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -18,7 +18,6 @@ GRPC_LOCAL_SRC = '../../..' target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC', :path => GRPC_LOCAL_SRC pod 'gRPC-Core', :path => GRPC_LOCAL_SRC pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC @@ -27,6 +26,14 @@ GRPC_LOCAL_SRC = '../../..' end end +target 'CoreCronetEnd2EndTests' do + pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Cronet-Tests', :path => GRPC_LOCAL_SRC +end + # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's # pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded # and before they are installed in the user project. diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index f9389a4977fe6..6c41563a350e5 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -12,6 +12,10 @@ 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; }; + 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */; }; + 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5E8A5DB01D3849F1000F8BC4 /* h2_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */; }; + 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */; }; 6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; 63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; }; @@ -38,6 +42,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -91,12 +102,17 @@ 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; 07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.debug.xcconfig"; sourceTree = ""; }; 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = ""; }; + 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; + 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; + 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl.m; sourceTree = ""; }; 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; 63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = ""; }; @@ -123,11 +139,21 @@ E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = ""; }; E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = ""; }; E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; + FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */, + 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63423F411B150A5F006CF63C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -194,6 +220,7 @@ DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */, A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */, 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */, + FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */, ); name = Frameworks; sourceTree = ""; @@ -215,15 +242,27 @@ 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */, 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */, E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */, + 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */, + 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */, ); name = Pods; sourceTree = ""; }; + 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { + isa = PBXGroup; + children = ( + 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */, + 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */, + ); + path = CoreCronetEnd2EndTests; + sourceTree = ""; + }; 635697BE1B14FC11007A7283 = { isa = PBXGroup; children = ( 635697C91B14FC11007A7283 /* Tests */, 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */, + 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -239,6 +278,7 @@ 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */, 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */, 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */, + 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */, ); name = Products; sourceTree = ""; @@ -270,6 +310,27 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; + buildPhases = ( + F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */, + 5E8A5DA01D3840B4000F8BC4 /* Sources */, + 5E8A5DA11D3840B4000F8BC4 /* Frameworks */, + 5E8A5DA21D3840B4000F8BC4 /* Resources */, + E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */, + 6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */, + ); + name = CoreCronetEnd2EndTests; + productName = CoreCronetEnd2EndTests; + productReference = 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 63423F431B150A5F006CF63C /* AllTests */ = { isa = PBXNativeTarget; buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */; @@ -403,6 +464,9 @@ LastUpgradeCheck = 0630; ORGANIZATIONNAME = gRPC; TargetAttributes = { + 5E8A5DA31D3840B4000F8BC4 = { + CreatedOnToolsVersion = 7.3.1; + }; 63423F431B150A5F006CF63C = { CreatedOnToolsVersion = 6.3.1; }; @@ -441,11 +505,19 @@ 63DC84221BE15267000708E8 /* InteropTestsRemote */, 63DC84331BE15294000708E8 /* InteropTestsLocalSSL */, 63DC84421BE152B5000708E8 /* InteropTestsLocalCleartext */, + 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 5E8A5DA21D3840B4000F8BC4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63423F421B150A5F006CF63C /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -561,6 +633,21 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -741,9 +828,48 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; + E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 5E8A5DA01D3840B4000F8BC4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E8A5DB01D3849F1000F8BC4 /* h2_ssl.m in Sources */, + 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63423F401B150A5F006CF63C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -804,6 +930,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */; + }; 63423F4C1B150A5F006CF63C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -832,6 +963,36 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 5E8A5DAC1D3840B4000F8BC4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 5E8A5DAD1D3840B4000F8BC4 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 63423F4E1B150A5F006CF63C /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */; @@ -1071,6 +1232,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E8A5DAC1D3840B4000F8BC4 /* Debug */, + 5E8A5DAD1D3840B4000F8BC4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index aefe6e965cc24..9eeee222713ee 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -128,6 +128,8 @@ 'ALWAYS_SEARCH_USER_PATHS' => 'NO', } + s.default_subspecs = 'Interface', 'Implementation' + # Like many other C libraries, gRPC-Core has its public headers under `include//` and its # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in @@ -154,4 +156,26 @@ ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)} end + + s.subspec 'Cronet-Interface' do |ss| + ss.header_mappings_dir = 'include/grpc' + ss.source_files = 'include/grpc/grpc_cronet.h' + end + + s.subspec 'Cronet-Tests' do |ss| + ss.header_mappings_dir = '.' + + ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', + 'src/core/ext/transport/cronet/transport/cronet_transport.c', + 'test/core/end2end/cq_verifier.{c,h}', + 'test/core/end2end/end2end_tests.{c,h}', + 'test/core/end2end/tests/*.{c,h}', + 'test/core/end2end/data/*.{c,h}', + 'test/core/util/test_config.{c,h}', + 'test/core/util/port.h', + 'test/core/util/port_posix.c', + 'test/core/util/port_server_client.{c,h}' + + ss.dependency 'CronetFramework' + end end From 69b74784fe84ca8d290eb4303ec797e9ddd190e7 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 14 Jul 2016 21:23:22 -0700 Subject: [PATCH 039/151] Reduce the number of unnecessary allocations --- .../grpc++/impl/codegen/async_unary_call.h | 2 +- src/core/lib/iomgr/ev_poll_posix.c | 30 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h index 47ac5bee92555..05681e22425ad 100644 --- a/include/grpc++/impl/codegen/async_unary_call.h +++ b/include/grpc++/impl/codegen/async_unary_call.h @@ -65,7 +65,7 @@ class ClientAsyncResponseReader GRPC_FINAL const W& request) : context_(context), call_(channel->CreateCall(method, context, cq)), - collection_(new CallOpSetCollection) { + collection_(std::make_shared()) { collection_->init_buf_.SetCollection(collection_); collection_->init_buf_.SendInitialMetadata( context->send_initial_metadata_, context->initial_metadata_flags()); diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 4b593f4b2c208..16a5e3083e61d 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -844,6 +844,11 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, *worker_hdl = &worker; grpc_error *error = GRPC_ERROR_NONE; + /* Avoid malloc for small number of elements. */ + enum { inline_elements = 96 }; + struct pollfd pollfd_space[inline_elements]; + struct grpc_fd_watcher watcher_space[inline_elements]; + /* pollset->mu already held */ int added_worker = 0; int locked = 1; @@ -899,15 +904,23 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, int r; size_t i, fd_count; nfds_t pfd_count; - /* TODO(ctiller): inline some elements to avoid an allocation */ grpc_fd_watcher *watchers; struct pollfd *pfds; timeout = poll_deadline_to_millis_timeout(deadline, now); - /* TODO(ctiller): perform just one malloc here if we exceed the inline - * case */ - pfds = gpr_malloc(sizeof(*pfds) * (pollset->fd_count + 2)); - watchers = gpr_malloc(sizeof(*watchers) * (pollset->fd_count + 2)); + + if (pollset->fd_count + 2 <= inline_elements) { + pfds = pollfd_space; + watchers = watcher_space; + } else { + /* Allocate one buffer to hold both pfds and watchers arrays */ + const size_t pfd_size = sizeof(*pfds) * (pollset->fd_count + 2); + const size_t watch_size = sizeof(*watchers) * (pollset->fd_count + 2); + void *buf = gpr_malloc(pfd_size + watch_size); + pfds = buf; + watchers = (void *)((char *)buf + pfd_size); + } + fd_count = 0; pfd_count = 2; pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); @@ -974,8 +987,11 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, } } - gpr_free(pfds); - gpr_free(watchers); + if (pfds != pollfd_space) { + /* pfds and watchers are in the same memory block pointed to by pfds */ + gpr_free(pfds); + } + GPR_TIMER_END("maybe_work_and_unlock", 0); locked = 0; } else { From 807387641f8a8acceb3a8e58adabf3080afb871d Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 14 Jul 2016 14:53:35 -0700 Subject: [PATCH 040/151] prevent spurious wake up and unstarted/already shutdown server --- include/grpc++/server.h | 1 + src/cpp/server/server.cc | 7 ++++++- test/cpp/end2end/async_end2end_test.cc | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 9a2f8f11c4223..6876961e210fe 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -179,6 +179,7 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen { grpc::mutex mu_; bool started_; bool shutdown_; + bool shutdown_notified_; // The number of threads which are running callbacks. int num_running_cb_; grpc::condition_variable callback_cv_; diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 374c9cbc04859..af04fd4ca6477 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -281,6 +281,7 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, : max_message_size_(max_message_size), started_(false), shutdown_(false), + shutdown_notified_(false), num_running_cb_(0), sync_methods_(new std::list), has_generic_service_(false), @@ -462,13 +463,17 @@ void Server::ShutdownInternal(gpr_timespec deadline) { while (num_running_cb_ != 0) { callback_cv_.wait(lock); } + + shutdown_notified_ = true; shutdown_cv_.notify_all(); } } void Server::Wait() { grpc::unique_lock lock(mu_); - shutdown_cv_.wait(lock); + while (started_ && !shutdown_notified_) { + shutdown_cv_.wait(lock); + } } void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) { diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 01ba8962d798a..4a8936d281020 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -363,6 +363,13 @@ TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) { delete wait_thread; } +TEST_P(AsyncEnd2endTest, ShutdownThenWait) { + ResetStub(); + SendRpc(1); + server_->Shutdown(); + server_->Wait(); +} + // Test a simple RPC using the async version of Next TEST_P(AsyncEnd2endTest, AsyncNextRpc) { ResetStub(); From 3fcd20fb5aaa920afd8ab8fccaccb5ea7371b02b Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Fri, 8 Jul 2016 14:38:39 +0100 Subject: [PATCH 041/151] Overhaul how the native extension is found, loaded and used The goal of this is to fix #7230. The changes here are: - The layout in the nuget package; the files are now in `/runtimes/{os}/native/{library}` - The filename of each library, which now includes the architecture, e.g `grpc_csharp_ext.x64.dll` - The targets file used to copy those files in msbuild-based projects; note that we now don't build up a folder structure. - The way the functions are found Before this change, on Linux and OSX we used to find library symbols manually, and use DllImport on Windows. With this change, the name of the library file changes based on architecture, so `DllImport` doesn't work. Instead, we have to use `GetProcAddress` to fetch the function. This is further convoluted by the convention on Windows-x86 to prefix the function name with `_` and suffix it based on the stack size of the arguments. We can't easily tell the argument size here, so we just try 0, 4, 8...128. (128 bytes should be enough for anyone.) This is inefficient, but it's a one-time hit with a known number of functions, and doesn't seem to have any significant impact. The benefit of this in code is we don't need the DllImports any more, and we don't need to conditionally use `FindSymbol` - we just use it for everything, so things are rather more uniform and tidy. The further benefit of this is that the library name is no longer tied to a particular filename format - so if someone wanted to have a directory with the libraries for every version in, with the version in the filename, we'd handle that just fine. (At least once Testing: - Windows: - Console app under msbuild, dotnet cli and DNX - ASP.NET Classic under msbuild - ASP.NET Core (still running under net451) - Ubuntu 16.04 - Console app under dotnet cli, run with dotnet run and mono - OSX: - Console app under dotnet cli, run with dotnet run and mono Under dotnet cli, a dependency on `Microsoft.NETCore.Platforms` is required in order to force the libraries to be copied. This change does *not* further enable .NET Core. It attempts to keep the existing experimental .NET Core project files in line with the msbuild files, but I expect further work to be required for .NET Core, which has a different build/publication model. --- src/csharp/Grpc.Core.Tests/project.json | 16 +- src/csharp/Grpc.Core/Grpc.Core.nuspec | 12 +- src/csharp/Grpc.Core/Grpc.Core.targets | 24 +- .../Grpc.Core/Internal/NativeExtension.cs | 31 +- .../Grpc.Core/Internal/NativeMethods.cs | 622 +++--------------- .../Grpc.Core/Internal/UnmanagedLibrary.cs | 33 +- src/csharp/Grpc.Core/NativeDeps.Linux.targets | 2 +- src/csharp/Grpc.Core/NativeDeps.Mac.targets | 2 +- .../Grpc.Core/NativeDeps.Windows.targets | 2 +- src/csharp/Grpc.Core/project.json | 12 +- .../Grpc.Examples.MathClient/project.json | 16 +- .../Grpc.Examples.MathServer/project.json | 16 +- src/csharp/Grpc.Examples.Tests/project.json | 16 +- .../Grpc.HealthCheck.Tests/project.json | 16 +- .../project.json | 16 +- .../project.json | 16 +- .../project.json | 16 +- .../project.json | 16 +- .../Grpc.IntegrationTesting/project.json | 16 +- .../csharp/Grpc.Core/project.json.template | 12 +- templates/src/csharp/build_options.include | 16 +- 21 files changed, 271 insertions(+), 657 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json index f58bcbb5159e7..d4c9a2ef31687 100644 --- a/src/csharp/Grpc.Core.Tests/project.json +++ b/src/csharp/Grpc.Core.Tests/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec index 47593f787b1a2..543549eb2d2c6 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.nuspec +++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec @@ -25,11 +25,11 @@ - - - - - - + + + + + + diff --git a/src/csharp/Grpc.Core/Grpc.Core.targets b/src/csharp/Grpc.Core/Grpc.Core.targets index 501fc5054827a..3367d51a80e7d 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.targets +++ b/src/csharp/Grpc.Core/Grpc.Core.targets @@ -1,29 +1,29 @@  - + PreserveNewest - nativelibs\windows_x86\grpc_csharp_ext.dll + grpc_csharp_ext.x86.dll - + PreserveNewest - nativelibs\windows_x64\grpc_csharp_ext.dll + grpc_csharp_ext.x64.dll - + PreserveNewest - nativelibs\linux_x86\libgrpc_csharp_ext.so + libgrpc_csharp_ext.x86.so - + PreserveNewest - nativelibs\linux_x64\libgrpc_csharp_ext.so + libgrpc_csharp_ext.x64.so - + PreserveNewest - nativelibs\macosx_x86\libgrpc_csharp_ext.dylib + libgrpc_csharp_ext.x86.dylib - + PreserveNewest - nativelibs\macosx_x64\libgrpc_csharp_ext.dylib + libgrpc_csharp_ext.x64.dylib \ No newline at end of file diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index a6d792581627f..509baf7cb1f3d 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -44,9 +44,6 @@ namespace Grpc.Core.Internal /// internal sealed class NativeExtension { - const string NativeLibrariesDir = "nativelibs"; - const string DnxStyleNativeLibrariesDir = "../../build/native/bin/"; - static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); static readonly object staticLock = new object(); static volatile NativeExtension instance; @@ -98,20 +95,25 @@ public NativeMethods NativeMethods private static UnmanagedLibrary Load() { // TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property). - - var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString()); - + // See https://github.com/grpc/grpc/pull/7303 for one option. var assemblyDirectory = Path.GetDirectoryName(GetAssemblyPath()); // With old-style VS projects, the native libraries get copied using a .targets rule to the build output folder // alongside the compiled assembly. - var classicPath = Path.Combine(assemblyDirectory, NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename()); + // With dotnet cli projects, the native libraries (just the required ones) are similarly copied to the built output folder, + // through the magic of Microsoft.NETCore.Platforms. + var classicPath = Path.Combine(assemblyDirectory, GetNativeLibraryFilename()); // DNX-style project.json projects will use Grpc.Core assembly directly in the location where it got restored // by nuget. We locate the native libraries based on known structure of Grpc.Core nuget package. - var dnxStylePath = Path.Combine(assemblyDirectory, DnxStyleNativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename()); - return new UnmanagedLibrary(new string[] {classicPath, dnxStylePath}); + // TODO: Support .NET Core applications, which act slightly differently. We may be okay if "dotnet publish" + // is used, but "dotnet run" leaves the native libraries in-package, while copying assemblies. + string platform = GetPlatformString(); + string relativeDirectory = string.Format("../../runtimes/{0}/native", platform); + var dnxStylePath = Path.Combine(assemblyDirectory, relativeDirectory, GetNativeLibraryFilename()); + string[] paths = new[] { classicPath, dnxStylePath }; + return new UnmanagedLibrary(paths); } private static string GetAssemblyPath() @@ -147,7 +149,7 @@ private static string GetPlatformString() { if (PlatformApis.IsWindows) { - return "windows"; + return "win"; } if (PlatformApis.IsLinux) { @@ -155,7 +157,7 @@ private static string GetPlatformString() } if (PlatformApis.IsMacOSX) { - return "macosx"; + return "osx"; } throw new InvalidOperationException("Unsupported platform."); } @@ -176,17 +178,18 @@ private static string GetArchitectureString() // platform specific file name of the extension library private static string GetNativeLibraryFilename() { + string architecture = GetArchitectureString(); if (PlatformApis.IsWindows) { - return "grpc_csharp_ext.dll"; + return string.Format("grpc_csharp_ext.{0}.dll", architecture); } if (PlatformApis.IsLinux) { - return "libgrpc_csharp_ext.so"; + return string.Format("libgrpc_csharp_ext.{0}.so", architecture); } if (PlatformApis.IsMacOSX) { - return "libgrpc_csharp_ext.dylib"; + return string.Format("libgrpc_csharp_ext.{0}.dylib", architecture); } throw new InvalidOperationException("Unsupported platform."); } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs index 65607ed12042e..f457c9dbf1e8b 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs @@ -159,215 +159,107 @@ internal class NativeMethods public NativeMethods(UnmanagedLibrary library) { - if (PlatformApis.IsLinux || PlatformApis.IsMacOSX) - { - this.grpcsharp_init = GetMethodDelegate(library); - this.grpcsharp_shutdown = GetMethodDelegate(library); - this.grpcsharp_version_string = GetMethodDelegate(library); - - this.grpcsharp_batch_context_create = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_call = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_method = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_host = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_deadline = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_request_metadata = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_close_on_server_cancelled = GetMethodDelegate(library); - this.grpcsharp_batch_context_destroy = GetMethodDelegate(library); - - this.grpcsharp_composite_call_credentials_create = GetMethodDelegate(library); - this.grpcsharp_call_credentials_release = GetMethodDelegate(library); - - this.grpcsharp_call_cancel = GetMethodDelegate(library); - this.grpcsharp_call_cancel_with_status = GetMethodDelegate(library); - this.grpcsharp_call_start_unary = GetMethodDelegate(library); - this.grpcsharp_call_start_client_streaming = GetMethodDelegate(library); - this.grpcsharp_call_start_server_streaming = GetMethodDelegate(library); - this.grpcsharp_call_start_duplex_streaming = GetMethodDelegate(library); - this.grpcsharp_call_send_message = GetMethodDelegate(library); - this.grpcsharp_call_send_close_from_client = GetMethodDelegate(library); - this.grpcsharp_call_send_status_from_server = GetMethodDelegate(library); - this.grpcsharp_call_recv_message = GetMethodDelegate(library); - this.grpcsharp_call_recv_initial_metadata = GetMethodDelegate(library); - this.grpcsharp_call_start_serverside = GetMethodDelegate(library); - this.grpcsharp_call_send_initial_metadata = GetMethodDelegate(library); - this.grpcsharp_call_set_credentials = GetMethodDelegate(library); - this.grpcsharp_call_get_peer = GetMethodDelegate(library); - this.grpcsharp_call_destroy = GetMethodDelegate(library); - - this.grpcsharp_channel_args_create = GetMethodDelegate(library); - this.grpcsharp_channel_args_set_string = GetMethodDelegate(library); - this.grpcsharp_channel_args_set_integer = GetMethodDelegate(library); - this.grpcsharp_channel_args_destroy = GetMethodDelegate(library); - - this.grpcsharp_override_default_ssl_roots = GetMethodDelegate(library); - this.grpcsharp_ssl_credentials_create = GetMethodDelegate(library); - this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate(library); - this.grpcsharp_channel_credentials_release = GetMethodDelegate(library); - - this.grpcsharp_insecure_channel_create = GetMethodDelegate(library); - this.grpcsharp_secure_channel_create = GetMethodDelegate(library); - this.grpcsharp_channel_create_call = GetMethodDelegate(library); - this.grpcsharp_channel_check_connectivity_state = GetMethodDelegate(library); - this.grpcsharp_channel_watch_connectivity_state = GetMethodDelegate(library); - this.grpcsharp_channel_get_target = GetMethodDelegate(library); - this.grpcsharp_channel_destroy = GetMethodDelegate(library); - - this.grpcsharp_sizeof_grpc_event = GetMethodDelegate(library); - - this.grpcsharp_completion_queue_create = GetMethodDelegate(library); - this.grpcsharp_completion_queue_shutdown = GetMethodDelegate(library); - this.grpcsharp_completion_queue_next = GetMethodDelegate(library); - this.grpcsharp_completion_queue_pluck = GetMethodDelegate(library); - this.grpcsharp_completion_queue_destroy = GetMethodDelegate(library); - - this.gprsharp_free = GetMethodDelegate(library); - - this.grpcsharp_metadata_array_create = GetMethodDelegate(library); - this.grpcsharp_metadata_array_add = GetMethodDelegate(library); - this.grpcsharp_metadata_array_count = GetMethodDelegate(library); - this.grpcsharp_metadata_array_get_key = GetMethodDelegate(library); - this.grpcsharp_metadata_array_get_value = GetMethodDelegate(library); - this.grpcsharp_metadata_array_get_value_length = GetMethodDelegate(library); - this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate(library); - - this.grpcsharp_redirect_log = GetMethodDelegate(library); - - this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate(library); - this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate(library); - - this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate(library); - this.grpcsharp_server_credentials_release = GetMethodDelegate(library); - - this.grpcsharp_server_create = GetMethodDelegate(library); - this.grpcsharp_server_register_completion_queue = GetMethodDelegate(library); - this.grpcsharp_server_add_insecure_http2_port = GetMethodDelegate(library); - this.grpcsharp_server_add_secure_http2_port = GetMethodDelegate(library); - this.grpcsharp_server_start = GetMethodDelegate(library); - this.grpcsharp_server_request_call = GetMethodDelegate(library); - this.grpcsharp_server_cancel_all_calls = GetMethodDelegate(library); - this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate(library); - this.grpcsharp_server_destroy = GetMethodDelegate(library); - - this.gprsharp_now = GetMethodDelegate(library); - this.gprsharp_inf_future = GetMethodDelegate(library); - this.gprsharp_inf_past = GetMethodDelegate(library); - this.gprsharp_convert_clock_type = GetMethodDelegate(library); - this.gprsharp_sizeof_timespec = GetMethodDelegate(library); - - this.grpcsharp_test_callback = GetMethodDelegate(library); - this.grpcsharp_test_nop = GetMethodDelegate(library); - } - else - { - // Windows or fallback - this.grpcsharp_init = PInvokeMethods.grpcsharp_init; - this.grpcsharp_shutdown = PInvokeMethods.grpcsharp_shutdown; - this.grpcsharp_version_string = PInvokeMethods.grpcsharp_version_string; - - this.grpcsharp_batch_context_create = PInvokeMethods.grpcsharp_batch_context_create; - this.grpcsharp_batch_context_recv_initial_metadata = PInvokeMethods.grpcsharp_batch_context_recv_initial_metadata; - this.grpcsharp_batch_context_recv_message_length = PInvokeMethods.grpcsharp_batch_context_recv_message_length; - this.grpcsharp_batch_context_recv_message_to_buffer = PInvokeMethods.grpcsharp_batch_context_recv_message_to_buffer; - this.grpcsharp_batch_context_recv_status_on_client_status = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_status; - this.grpcsharp_batch_context_recv_status_on_client_details = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_details; - this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_trailing_metadata; - this.grpcsharp_batch_context_server_rpc_new_call = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_call; - this.grpcsharp_batch_context_server_rpc_new_method = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_method; - this.grpcsharp_batch_context_server_rpc_new_host = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_host; - this.grpcsharp_batch_context_server_rpc_new_deadline = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_deadline; - this.grpcsharp_batch_context_server_rpc_new_request_metadata = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_request_metadata; - this.grpcsharp_batch_context_recv_close_on_server_cancelled = PInvokeMethods.grpcsharp_batch_context_recv_close_on_server_cancelled; - this.grpcsharp_batch_context_destroy = PInvokeMethods.grpcsharp_batch_context_destroy; - - this.grpcsharp_composite_call_credentials_create = PInvokeMethods.grpcsharp_composite_call_credentials_create; - this.grpcsharp_call_credentials_release = PInvokeMethods.grpcsharp_call_credentials_release; - - this.grpcsharp_call_cancel = PInvokeMethods.grpcsharp_call_cancel; - this.grpcsharp_call_cancel_with_status = PInvokeMethods.grpcsharp_call_cancel_with_status; - this.grpcsharp_call_start_unary = PInvokeMethods.grpcsharp_call_start_unary; - this.grpcsharp_call_start_client_streaming = PInvokeMethods.grpcsharp_call_start_client_streaming; - this.grpcsharp_call_start_server_streaming = PInvokeMethods.grpcsharp_call_start_server_streaming; - this.grpcsharp_call_start_duplex_streaming = PInvokeMethods.grpcsharp_call_start_duplex_streaming; - this.grpcsharp_call_send_message = PInvokeMethods.grpcsharp_call_send_message; - this.grpcsharp_call_send_close_from_client = PInvokeMethods.grpcsharp_call_send_close_from_client; - this.grpcsharp_call_send_status_from_server = PInvokeMethods.grpcsharp_call_send_status_from_server; - this.grpcsharp_call_recv_message = PInvokeMethods.grpcsharp_call_recv_message; - this.grpcsharp_call_recv_initial_metadata = PInvokeMethods.grpcsharp_call_recv_initial_metadata; - this.grpcsharp_call_start_serverside = PInvokeMethods.grpcsharp_call_start_serverside; - this.grpcsharp_call_send_initial_metadata = PInvokeMethods.grpcsharp_call_send_initial_metadata; - this.grpcsharp_call_set_credentials = PInvokeMethods.grpcsharp_call_set_credentials; - this.grpcsharp_call_get_peer = PInvokeMethods.grpcsharp_call_get_peer; - this.grpcsharp_call_destroy = PInvokeMethods.grpcsharp_call_destroy; - - this.grpcsharp_channel_args_create = PInvokeMethods.grpcsharp_channel_args_create; - this.grpcsharp_channel_args_set_string = PInvokeMethods.grpcsharp_channel_args_set_string; - this.grpcsharp_channel_args_set_integer = PInvokeMethods.grpcsharp_channel_args_set_integer; - this.grpcsharp_channel_args_destroy = PInvokeMethods.grpcsharp_channel_args_destroy; - - this.grpcsharp_override_default_ssl_roots = PInvokeMethods.grpcsharp_override_default_ssl_roots; - this.grpcsharp_ssl_credentials_create = PInvokeMethods.grpcsharp_ssl_credentials_create; - this.grpcsharp_composite_channel_credentials_create = PInvokeMethods.grpcsharp_composite_channel_credentials_create; - this.grpcsharp_channel_credentials_release = PInvokeMethods.grpcsharp_channel_credentials_release; - - this.grpcsharp_insecure_channel_create = PInvokeMethods.grpcsharp_insecure_channel_create; - this.grpcsharp_secure_channel_create = PInvokeMethods.grpcsharp_secure_channel_create; - this.grpcsharp_channel_create_call = PInvokeMethods.grpcsharp_channel_create_call; - this.grpcsharp_channel_check_connectivity_state = PInvokeMethods.grpcsharp_channel_check_connectivity_state; - this.grpcsharp_channel_watch_connectivity_state = PInvokeMethods.grpcsharp_channel_watch_connectivity_state; - this.grpcsharp_channel_get_target = PInvokeMethods.grpcsharp_channel_get_target; - this.grpcsharp_channel_destroy = PInvokeMethods.grpcsharp_channel_destroy; - - this.grpcsharp_sizeof_grpc_event = PInvokeMethods.grpcsharp_sizeof_grpc_event; - - this.grpcsharp_completion_queue_create = PInvokeMethods.grpcsharp_completion_queue_create; - this.grpcsharp_completion_queue_shutdown = PInvokeMethods.grpcsharp_completion_queue_shutdown; - this.grpcsharp_completion_queue_next = PInvokeMethods.grpcsharp_completion_queue_next; - this.grpcsharp_completion_queue_pluck = PInvokeMethods.grpcsharp_completion_queue_pluck; - this.grpcsharp_completion_queue_destroy = PInvokeMethods.grpcsharp_completion_queue_destroy; - - this.gprsharp_free = PInvokeMethods.gprsharp_free; - - this.grpcsharp_metadata_array_create = PInvokeMethods.grpcsharp_metadata_array_create; - this.grpcsharp_metadata_array_add = PInvokeMethods.grpcsharp_metadata_array_add; - this.grpcsharp_metadata_array_count = PInvokeMethods.grpcsharp_metadata_array_count; - this.grpcsharp_metadata_array_get_key = PInvokeMethods.grpcsharp_metadata_array_get_key; - this.grpcsharp_metadata_array_get_value = PInvokeMethods.grpcsharp_metadata_array_get_value; - this.grpcsharp_metadata_array_get_value_length = PInvokeMethods.grpcsharp_metadata_array_get_value_length; - this.grpcsharp_metadata_array_destroy_full = PInvokeMethods.grpcsharp_metadata_array_destroy_full; - - this.grpcsharp_redirect_log = PInvokeMethods.grpcsharp_redirect_log; - - this.grpcsharp_metadata_credentials_create_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_create_from_plugin; - this.grpcsharp_metadata_credentials_notify_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_notify_from_plugin; - - this.grpcsharp_ssl_server_credentials_create = PInvokeMethods.grpcsharp_ssl_server_credentials_create; - this.grpcsharp_server_credentials_release = PInvokeMethods.grpcsharp_server_credentials_release; - - this.grpcsharp_server_create = PInvokeMethods.grpcsharp_server_create; - this.grpcsharp_server_register_completion_queue = PInvokeMethods.grpcsharp_server_register_completion_queue; - this.grpcsharp_server_add_insecure_http2_port = PInvokeMethods.grpcsharp_server_add_insecure_http2_port; - this.grpcsharp_server_add_secure_http2_port = PInvokeMethods.grpcsharp_server_add_secure_http2_port; - this.grpcsharp_server_start = PInvokeMethods.grpcsharp_server_start; - this.grpcsharp_server_request_call = PInvokeMethods.grpcsharp_server_request_call; - this.grpcsharp_server_cancel_all_calls = PInvokeMethods.grpcsharp_server_cancel_all_calls; - this.grpcsharp_server_shutdown_and_notify_callback = PInvokeMethods.grpcsharp_server_shutdown_and_notify_callback; - this.grpcsharp_server_destroy = PInvokeMethods.grpcsharp_server_destroy; - - this.gprsharp_now = PInvokeMethods.gprsharp_now; - this.gprsharp_inf_future = PInvokeMethods.gprsharp_inf_future; - this.gprsharp_inf_past = PInvokeMethods.gprsharp_inf_past; - this.gprsharp_convert_clock_type = PInvokeMethods.gprsharp_convert_clock_type; - this.gprsharp_sizeof_timespec = PInvokeMethods.gprsharp_sizeof_timespec; - - this.grpcsharp_test_callback = PInvokeMethods.grpcsharp_test_callback; - this.grpcsharp_test_nop = PInvokeMethods.grpcsharp_test_nop; - } + this.grpcsharp_init = GetMethodDelegate(library); + this.grpcsharp_shutdown = GetMethodDelegate(library); + this.grpcsharp_version_string = GetMethodDelegate(library); + + this.grpcsharp_batch_context_create = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_call = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_method = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_host = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_deadline = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_request_metadata = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_close_on_server_cancelled = GetMethodDelegate(library); + this.grpcsharp_batch_context_destroy = GetMethodDelegate(library); + + this.grpcsharp_composite_call_credentials_create = GetMethodDelegate(library); + this.grpcsharp_call_credentials_release = GetMethodDelegate(library); + + this.grpcsharp_call_cancel = GetMethodDelegate(library); + this.grpcsharp_call_cancel_with_status = GetMethodDelegate(library); + this.grpcsharp_call_start_unary = GetMethodDelegate(library); + this.grpcsharp_call_start_client_streaming = GetMethodDelegate(library); + this.grpcsharp_call_start_server_streaming = GetMethodDelegate(library); + this.grpcsharp_call_start_duplex_streaming = GetMethodDelegate(library); + this.grpcsharp_call_send_message = GetMethodDelegate(library); + this.grpcsharp_call_send_close_from_client = GetMethodDelegate(library); + this.grpcsharp_call_send_status_from_server = GetMethodDelegate(library); + this.grpcsharp_call_recv_message = GetMethodDelegate(library); + this.grpcsharp_call_recv_initial_metadata = GetMethodDelegate(library); + this.grpcsharp_call_start_serverside = GetMethodDelegate(library); + this.grpcsharp_call_send_initial_metadata = GetMethodDelegate(library); + this.grpcsharp_call_set_credentials = GetMethodDelegate(library); + this.grpcsharp_call_get_peer = GetMethodDelegate(library); + this.grpcsharp_call_destroy = GetMethodDelegate(library); + + this.grpcsharp_channel_args_create = GetMethodDelegate(library); + this.grpcsharp_channel_args_set_string = GetMethodDelegate(library); + this.grpcsharp_channel_args_set_integer = GetMethodDelegate(library); + this.grpcsharp_channel_args_destroy = GetMethodDelegate(library); + + this.grpcsharp_override_default_ssl_roots = GetMethodDelegate(library); + this.grpcsharp_ssl_credentials_create = GetMethodDelegate(library); + this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate(library); + this.grpcsharp_channel_credentials_release = GetMethodDelegate(library); + + this.grpcsharp_insecure_channel_create = GetMethodDelegate(library); + this.grpcsharp_secure_channel_create = GetMethodDelegate(library); + this.grpcsharp_channel_create_call = GetMethodDelegate(library); + this.grpcsharp_channel_check_connectivity_state = GetMethodDelegate(library); + this.grpcsharp_channel_watch_connectivity_state = GetMethodDelegate(library); + this.grpcsharp_channel_get_target = GetMethodDelegate(library); + this.grpcsharp_channel_destroy = GetMethodDelegate(library); + + this.grpcsharp_sizeof_grpc_event = GetMethodDelegate(library); + + this.grpcsharp_completion_queue_create = GetMethodDelegate(library); + this.grpcsharp_completion_queue_shutdown = GetMethodDelegate(library); + this.grpcsharp_completion_queue_next = GetMethodDelegate(library); + this.grpcsharp_completion_queue_pluck = GetMethodDelegate(library); + this.grpcsharp_completion_queue_destroy = GetMethodDelegate(library); + + this.gprsharp_free = GetMethodDelegate(library); + + this.grpcsharp_metadata_array_create = GetMethodDelegate(library); + this.grpcsharp_metadata_array_add = GetMethodDelegate(library); + this.grpcsharp_metadata_array_count = GetMethodDelegate(library); + this.grpcsharp_metadata_array_get_key = GetMethodDelegate(library); + this.grpcsharp_metadata_array_get_value = GetMethodDelegate(library); + this.grpcsharp_metadata_array_get_value_length = GetMethodDelegate(library); + this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate(library); + + this.grpcsharp_redirect_log = GetMethodDelegate(library); + + this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate(library); + this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate(library); + + this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate(library); + this.grpcsharp_server_credentials_release = GetMethodDelegate(library); + + this.grpcsharp_server_create = GetMethodDelegate(library); + this.grpcsharp_server_register_completion_queue = GetMethodDelegate(library); + this.grpcsharp_server_add_insecure_http2_port = GetMethodDelegate(library); + this.grpcsharp_server_add_secure_http2_port = GetMethodDelegate(library); + this.grpcsharp_server_start = GetMethodDelegate(library); + this.grpcsharp_server_request_call = GetMethodDelegate(library); + this.grpcsharp_server_cancel_all_calls = GetMethodDelegate(library); + this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate(library); + this.grpcsharp_server_destroy = GetMethodDelegate(library); + + this.gprsharp_now = GetMethodDelegate(library); + this.gprsharp_inf_future = GetMethodDelegate(library); + this.gprsharp_inf_past = GetMethodDelegate(library); + this.gprsharp_convert_clock_type = GetMethodDelegate(library); + this.gprsharp_sizeof_timespec = GetMethodDelegate(library); + + this.grpcsharp_test_callback = GetMethodDelegate(library); + this.grpcsharp_test_nop = GetMethodDelegate(library); } ///

@@ -516,317 +408,5 @@ public delegate void grpcsharp_channel_watch_connectivity_state_delegate(Channel public delegate CallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback); public delegate IntPtr grpcsharp_test_nop_delegate(IntPtr ptr); } - - /// - /// Default PInvoke bindings for native methods that are used on Windows. - /// Alternatively, they can also be used as a fallback on Mono - /// (if libgrpc_csharp_ext is installed on your system, or is made accessible through e.g. LD_LIBRARY_PATH environment variable - /// or using Mono's dllMap feature). - /// - private class PInvokeMethods - { - // Environment - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_init(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_shutdown(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_version_string(); // returns not-owned const char* - - // BatchContextSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern BatchContextSafeHandle grpcsharp_batch_context_create(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); - - [DllImport("grpc_csharp_ext.dll")] - public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx); // returns const char* - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char* - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx); // returns const char* - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_batch_context_destroy(IntPtr ctx); - - // CallCredentialsSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_call_credentials_release(IntPtr credentials); - - // CallSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_cancel(CallSafeHandle call); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_unary(CallSafeHandle call, - BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_client_streaming(CallSafeHandle call, - BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_server_streaming(CallSafeHandle call, - BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, - MetadataArraySafeHandle metadataArray, WriteFlags writeFlags); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call, - BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_message(CallSafeHandle call, - BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, bool sendEmptyInitialMetadata); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, - BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, - byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_recv_message(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_serverside(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_initial_metadata(CallSafeHandle call, - BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_call_destroy(IntPtr call); - - // ChannelArgsSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_args_destroy(IntPtr args); - - // ChannelCredentialsSafeHandle - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_credentials_release(IntPtr credentials); - - // ChannelSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs); - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline); - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, - Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_destroy(IntPtr channel); - - // CompletionQueueEvent - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_sizeof_grpc_event(); - - // CompletionQueueSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_completion_queue_destroy(IntPtr cq); - - // CStringSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern void gprsharp_free(IntPtr ptr); - - // MetadataArraySafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength); - - [DllImport("grpc_csharp_ext.dll")] - public static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index); - - [DllImport("grpc_csharp_ext.dll")] - public static extern UIntPtr grpcsharp_metadata_array_get_value_length(IntPtr metadataArray, UIntPtr index); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_metadata_array_destroy_full(IntPtr array); - - // NativeLogRedirector - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_redirect_log(GprLogDelegate callback); - - // NativeMetadataCredentialsPlugin - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); - - // ServerCredentialsSafeHandle - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_credentials_release(IntPtr credentials); - - // ServerSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_start(ServerSafeHandle server); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_cancel_all_calls(ServerSafeHandle server); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_destroy(IntPtr server); - - // Timespec - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_now(ClockType clockType); - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_inf_future(ClockType clockType); - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_inf_past(ClockType clockType); - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_convert_clock_type(Timespec t, ClockType targetClock); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int gprsharp_sizeof_timespec(); - - // Testing - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_test_nop(IntPtr ptr); - } } } diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index 5a807461015d1..dc629bd714fae 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -82,6 +82,32 @@ public UnmanagedLibrary(string[] libraryPathAlternatives) /// public IntPtr LoadSymbol(string symbolName) { + if (PlatformApis.IsWindows) + { + // See http://stackoverflow.com/questions/10473310 for background on this. + if (PlatformApis.Is64Bit) + { + return Windows.GetProcAddress(this.handle, symbolName); + } + else + { + // Yes, we could potentially predict the size... but it's a lot simpler to just try + // all the candidates. Most functions have a suffix of @0, @4 or @8 so we won't be trying + // many options - and if it takes a little bit longer to fail if we've really got the wrong + // library, that's not a big problem. This is only called once per function in the native library. + symbolName = "_" + symbolName + "@"; + for (int stackSize = 0; stackSize < 128; stackSize += 4) + { + IntPtr candidate = Windows.GetProcAddress(this.handle, symbolName + stackSize); + if (candidate != IntPtr.Zero) + { + return candidate; + } + } + // Fail. + return IntPtr.Zero; + } + } if (PlatformApis.IsLinux) { if (PlatformApis.IsMono) @@ -142,13 +168,18 @@ private static string FirstValidLibraryPath(string[] libraryPathAlternatives) return path; } } - throw new FileNotFoundException(String.Format("Error loading native library. Not found in any of the possible locations {0}", libraryPathAlternatives)); + throw new FileNotFoundException( + String.Format("Error loading native library. Not found in any of the possible locations: {0}", + string.Join(",", libraryPathAlternatives))); } private static class Windows { [DllImport("kernel32.dll")] internal static extern IntPtr LoadLibrary(string filename); + + [DllImport("kernel32.dll")] + internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName); } private static class Linux diff --git a/src/csharp/Grpc.Core/NativeDeps.Linux.targets b/src/csharp/Grpc.Core/NativeDeps.Linux.targets index a3848c6f2eddc..e0c9132b1d5fe 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Linux.targets +++ b/src/csharp/Grpc.Core/NativeDeps.Linux.targets @@ -3,7 +3,7 @@ PreserveNewest - nativelibs\linux_x64\libgrpc_csharp_ext.so + libgrpc_csharp_ext.x64.so \ No newline at end of file diff --git a/src/csharp/Grpc.Core/NativeDeps.Mac.targets b/src/csharp/Grpc.Core/NativeDeps.Mac.targets index c3c6264fd3ffe..e22c7384fc5b8 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Mac.targets +++ b/src/csharp/Grpc.Core/NativeDeps.Mac.targets @@ -3,7 +3,7 @@ PreserveNewest - nativelibs\macosx_x86\libgrpc_csharp_ext.dylib + libgrpc_csharp_ext.x86.dylib \ No newline at end of file diff --git a/src/csharp/Grpc.Core/NativeDeps.Windows.targets b/src/csharp/Grpc.Core/NativeDeps.Windows.targets index f6a3405e29f8b..93db0935bc10b 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Windows.targets +++ b/src/csharp/Grpc.Core/NativeDeps.Windows.targets @@ -3,7 +3,7 @@ PreserveNewest - nativelibs\windows_x86\grpc_csharp_ext.dll + grpc_csharp_ext.x86.dll \ No newline at end of file diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index a07da323d17b0..7a676f59a64df 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -14,12 +14,12 @@ "files": { "mappings": { "build/net45/": "Grpc.Core.targets", - "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll", - "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll", - "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", - "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", - "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", - "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" + "runtimes/win/native/grpc_csharp_ext.x86.dll": "../nativelibs/windows_x86/grpc_csharp_ext.dll", + "runtimes/win/native/grpc_csharp_ext.x64.dll": "../nativelibs/windows_x64/grpc_csharp_ext.dll", + "runtimes/linux/native/libgrpc_csharp_ext.x86.so": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", + "runtimes/linux/native/libgrpc_csharp_ext.x64.so": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", + "runtimes/osx/native/libgrpc_csharp_ext.x86.dylib": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", + "runtimes/osx/native/libgrpc_csharp_ext.x64.dylib": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" } } }, diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json index b865cd5011859..206d6c598244c 100644 --- a/src/csharp/Grpc.Examples.MathClient/project.json +++ b/src/csharp/Grpc.Examples.MathClient/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json index b865cd5011859..206d6c598244c 100644 --- a/src/csharp/Grpc.Examples.MathServer/project.json +++ b/src/csharp/Grpc.Examples.MathServer/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json index cc518eb6ff7ce..b4c4c5f691046 100644 --- a/src/csharp/Grpc.Examples.Tests/project.json +++ b/src/csharp/Grpc.Examples.Tests/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json index fbf8d92f04d20..f44a3225ae650 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/project.json +++ b/src/csharp/Grpc.HealthCheck.Tests/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json index 4a2846feea0d4..6b61a4b76e801 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/project.json +++ b/src/csharp/Grpc.IntegrationTesting.Client/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json index 4a2846feea0d4..6b61a4b76e801 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json index 4a2846feea0d4..6b61a4b76e801 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/project.json +++ b/src/csharp/Grpc.IntegrationTesting.Server/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json index 4a2846feea0d4..6b61a4b76e801 100644 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json index 6297600ddc31e..dcd9ccabd295c 100644 --- a/src/csharp/Grpc.IntegrationTesting/project.json +++ b/src/csharp/Grpc.IntegrationTesting/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template index cdcebc5303db5..6355db53892e2 100644 --- a/templates/src/csharp/Grpc.Core/project.json.template +++ b/templates/src/csharp/Grpc.Core/project.json.template @@ -16,12 +16,12 @@ "files": { "mappings": { "build/net45/": "Grpc.Core.targets", - "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll", - "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll", - "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", - "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", - "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", - "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" + "runtimes/win/native/grpc_csharp_ext.x86.dll": "../nativelibs/windows_x86/grpc_csharp_ext.dll", + "runtimes/win/native/grpc_csharp_ext.x64.dll": "../nativelibs/windows_x64/grpc_csharp_ext.dll", + "runtimes/linux/native/libgrpc_csharp_ext.x86.so": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", + "runtimes/linux/native/libgrpc_csharp_ext.x64.so": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", + "runtimes/osx/native/libgrpc_csharp_ext.x86.dylib": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", + "runtimes/osx/native/libgrpc_csharp_ext.x64.dylib": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" } } }, diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include index ae96b94f72827..169a45a808a37 100644 --- a/templates/src/csharp/build_options.include +++ b/templates/src/csharp/build_options.include @@ -20,10 +20,10 @@ "include": "data/*", % endif "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -42,10 +42,10 @@ "include": "data/*", % endif "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } From 2a083033e2559ddb4bbba8ed595067cbd7d392b2 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Fri, 15 Jul 2016 15:52:53 +0800 Subject: [PATCH 042/151] unify the version of google/auth --- src/php/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/composer.json b/src/php/composer.json index ca8e085fca13d..23bfcedbe6b82 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -9,7 +9,7 @@ "require": { "php": ">=5.5.0", "stanley-cheung/protobuf-php": "dev-master", - "google/auth": "v0.7" + "google/auth": "v0.9" }, "autoload": { "psr-4": { From 26b60607297ff5caf01c72ba31f70b2641fd9198 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Fri, 15 Jul 2016 07:35:13 -0700 Subject: [PATCH 043/151] Small tweaks in text and diagram --- doc/images/load_balancing_design.png | Bin 38180 -> 40354 bytes doc/load-balancing.md | 26 ++++++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/doc/images/load_balancing_design.png b/doc/images/load_balancing_design.png index 716378c0db20da9875b0cc1892e0e1aa217c1540..86183966fb88e24a5a86dbd4b62ae2a308d0a542 100644 GIT binary patch literal 40354 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

oXQe~N~ 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 Vn`JgvQafaeb~dMumLGP%{U5zNV6gxI diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 6da2479d24abf..dfaa7a7f33b36 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -89,26 +89,28 @@ servers. client config. 2. The gRPC client connects to a gRPC Server. 1. If the name resolution has hinted that the endpoint is a load balancer, - the client will attempt to open a stream to the load balancer service. The - server may respond in only one of the following ways. + the client's gRPC LB policy will attempt to open a stream to the load + balancer service. The server may respond in only one of the following + ways. 1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client call will fail. - 1. "I am a Load Balancer and here is the server list." (Goto Step 4.) - 1. "Please contact Load Balancer X" (See Step 3.) The client will close + 2. "I am a Load Balancer and here is the server list." (Goto Step 4.) + 3. "Please contact Load Balancer X" (See Step 3.) The client will close this connection and cancel the stream. - 1. If the server fails to respond, the client will wait for some timeout + 4. If the server fails to respond, the client will wait for some timeout and then re-resolve the name (process to Step 1 above). - 1. If the name resolution has not hinted that the endpoint is a load + 2. If the name resolution has not hinted that the endpoint is a load balancer, the client connects directly to the service it wants to talk to. -3. The gRPC client opens a separate connection to the Load Balancer. If this - fails, it will go back to step 1 and try another address. +3. The gRPC client's gRPC LB policy opens a separate connection to the Load + Balancer. If this fails, it will go back to step 1 and try another address. 1. During channel initialization to the Load Balancer, the client will attempt to open a stream to the Load Balancer service. - 1. The load balancer will return a server list to the gRPC client. - Optional: The load balancer will also open channels to the gRPC servers if - load reporting is needed. + 2. The Load Balancer will return a server list to the gRPC client. If the + server list is empty, the call will wait until a non-empty one is + received. Optional: The Load Balancer will also open channels to the gRPC + servers if load reporting is needed. 4. The gRPC client will send RPCs to the gRPC servers contained in the server - list from the load balancer. + list from the Load Balancer. 5. Optional: The gRPC servers may periodically report load to the Load Balancer. ## Client From 45015dc8dac51979fe7bffdc20a92e895e57180e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 15 Jul 2016 08:48:25 -0700 Subject: [PATCH 044/151] Plumb channel args through handshakers. --- .../chttp2/client/insecure/channel_create.c | 12 ++-- .../client/secure/secure_channel_create.c | 21 +++--- .../chttp2/server/insecure/server_chttp2.c | 10 ++- .../server/secure/server_secure_chttp2.c | 31 +++++---- src/core/lib/channel/channel_args.h | 2 + src/core/lib/channel/handshaker.c | 35 ++++++---- src/core/lib/channel/handshaker.h | 67 ++++++++++++++----- 7 files changed, 116 insertions(+), 62 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 648a9d90a5fd8..154c4493ffc10 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -88,13 +88,13 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - connector *c = arg; + grpc_channel_args* args, void *user_data) { + connector *c = user_data; c->result->transport = - grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, endpoint, 1); + grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); GPR_ASSERT(c->result->transport); grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); - c->result->channel_args = grpc_channel_args_copy(c->args.channel_args); + c->result->channel_args = args; grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); @@ -102,7 +102,6 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_closure *notify; grpc_endpoint *tcp = c->tcp; if (tcp != NULL) { if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) { @@ -116,12 +115,13 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { &c->initial_string_sent); } else { grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.channel_args, c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 30477ded1a310..f071e31cb324c 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -72,6 +72,9 @@ typedef struct { grpc_closure connected_closure; grpc_handshake_manager *handshake_mgr; + + // TODO(roth): Remove once we eliminate on_secure_handshake_done(). + grpc_channel_args* tmp_args; } connector; static void connector_ref(grpc_connector *con) { @@ -83,6 +86,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_channel_args_destroy(c->tmp_args); grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } @@ -93,7 +97,6 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context) { connector *c = arg; - grpc_closure *notify; gpr_mu_lock(&c->mu); if (c->connecting_endpoint == NULL) { memset(c->result, 0, sizeof(*c->result)); @@ -113,19 +116,20 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, 0); auth_context_arg = grpc_auth_context_to_arg(auth_context); c->result->channel_args = grpc_channel_args_copy_and_add( - c->args.channel_args, &auth_context_arg, 1); + c->tmp_args, &auth_context_arg, 1); } - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - connector *c = arg; + grpc_channel_args* args, void *user_data) { + connector *c = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() // into this function. + c->tmp_args = args; grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector, endpoint, c->args.deadline, on_secure_handshake_done, c); @@ -135,13 +139,13 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, - c->connecting_endpoint, c->args.deadline, + c->connecting_endpoint, + c->args.channel_args, c->args.deadline, on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_closure *notify; grpc_endpoint *tcp = c->newly_connecting_endpoint; if (tcp != NULL) { gpr_mu_lock(&c->mu); @@ -158,12 +162,13 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { &c->initial_string_sent); } else { grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.channel_args, c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index d3748f576d585..920875f694740 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -37,7 +37,9 @@ #include #include #include + #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -53,8 +55,8 @@ typedef struct server_connect_state { } server_connect_state; static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - server_connect_state *state = arg; + grpc_channel_args* args, void *user_data) { + server_connect_state *state = user_data; /* * Beware that the call to grpc_create_chttp2_transport() has to happen before * grpc_tcp_server_destroy(). This is fine here, but similar code @@ -63,12 +65,13 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, * case. */ grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(state->server), endpoint, 0); + exec_ctx, args, endpoint, 0); grpc_server_setup_transport(exec_ctx, state->server, transport, state->accepting_pollset, grpc_server_get_channel_args(state->server)); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); // Clean up. + grpc_channel_args_destroy(args); grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); gpr_free(state); } @@ -86,6 +89,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, const gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, + grpc_server_get_channel_args(server), deadline, on_handshake_done, state); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index 57931bdb43bc8..e3184bc1f937e 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -70,9 +70,11 @@ typedef struct server_secure_connect { server_secure_state *state; grpc_pollset *accepting_pollset; grpc_tcp_server_acceptor *acceptor; - gpr_timespec deadline; // FIXME: remove when we eliminate - // grpc_server_security_connector_do_handshake() grpc_handshake_manager *handshake_mgr; + // TODO(roth): Remove the following two fields when we eliminate + // grpc_server_security_connector_do_handshake(). + gpr_timespec deadline; + grpc_channel_args* args; } server_secure_connect; static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); } @@ -102,13 +104,11 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, transport = grpc_create_chttp2_transport( exec_ctx, grpc_server_get_channel_args(state->state->server), secure_endpoint, 0); - grpc_channel_args *args_copy; grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(state->state->creds); args_to_add[1] = grpc_auth_context_to_arg(auth_context); - args_copy = grpc_channel_args_copy_and_add( - grpc_server_get_channel_args(state->state->server), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + grpc_channel_args *args_copy = grpc_channel_args_copy_and_add( + state->args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); grpc_server_setup_transport(exec_ctx, state->state->server, transport, state->accepting_pollset, args_copy); grpc_channel_args_destroy(args_copy); @@ -123,18 +123,20 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, } else { gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); } + grpc_channel_args_destroy(state->args); state_unref(state->state); gpr_free(state); } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - server_secure_connect *state = arg; - grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); - state->handshake_mgr = NULL; + grpc_channel_args* args, void *user_data) { + server_secure_connect *state = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() // into this function. + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + state->handshake_mgr = NULL; + state->args = args; grpc_server_security_connector_do_handshake( exec_ctx, state->state->sc, state->acceptor, endpoint, state->deadline, on_secure_handshake_done, state); @@ -148,14 +150,15 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, state_ref(state->state); state->accepting_pollset = accepting_pollset; state->acceptor = acceptor; + state->handshake_mgr = grpc_handshake_manager_create(); // TODO(roth): We should really get this timeout value from channel // args instead of hard-coding it. state->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); - state->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, - state->deadline, on_handshake_done, - state); + grpc_handshake_manager_do_handshake( + exec_ctx, state->handshake_mgr, tcp, + grpc_server_get_channel_args(state->state->server), state->deadline, + on_handshake_done, state); } /* Server callback: start listening on our ports */ diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index 653d04f427957..aec61ee7c62f0 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -37,6 +37,8 @@ #include #include +// Channel args are intentionally immutable, to avoid the need for locking. + /** Copy the arguments in \a src into a new instance */ grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src); diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 5b8c08bc15123..7dcbe1df9cee9 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -36,6 +36,7 @@ #include #include +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" // @@ -60,10 +61,11 @@ void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, + grpc_channel_args* args, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg) { - handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, deadline, cb, - arg); + grpc_handshaker_done_cb cb, void* user_data) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, + deadline, cb, user_data); } // @@ -76,9 +78,9 @@ struct grpc_handshaker_state { size_t index; // The deadline for all handshakers. gpr_timespec deadline; - // The final callback and arg to invoke after the last handshaker. + // The final callback and user_data to invoke after the last handshaker. grpc_handshaker_done_cb final_cb; - void* final_arg; + void* final_user_data; }; struct grpc_handshake_manager { @@ -126,20 +128,23 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, // A function used as the handshaker-done callback when chaining // handshakers together. static void call_next_handshaker(grpc_exec_ctx* exec_ctx, - grpc_endpoint* endpoint, void* arg) { - grpc_handshake_manager* mgr = arg; + grpc_endpoint* endpoint, + grpc_channel_args* args, + void* user_data) { + grpc_handshake_manager* mgr = user_data; GPR_ASSERT(mgr->state != NULL); GPR_ASSERT(mgr->state->index < mgr->count); grpc_handshaker_done_cb cb = call_next_handshaker; // If this is the last handshaker, use the caller-supplied callback - // and arg instead of chaining back to this function again. + // and user_data instead of chaining back to this function again. if (mgr->state->index == mgr->count - 1) { cb = mgr->state->final_cb; - arg = mgr->state->final_arg; + user_data = mgr->state->final_user_data; } // Invoke handshaker. grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], - endpoint, mgr->state->deadline, cb, arg); + endpoint, args, mgr->state->deadline, cb, + user_data); ++mgr->state->index; // If this is the last handshaker, clean up state. if (mgr->state->index == mgr->count) { @@ -151,20 +156,22 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, + const grpc_channel_args* args, gpr_timespec deadline, grpc_handshaker_done_cb cb, - void* arg) { + void* user_data) { + grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done // callback with the passed-in endpoint. - cb(exec_ctx, endpoint, arg); + cb(exec_ctx, endpoint, args_copy, user_data); } else { GPR_ASSERT(mgr->state == NULL); mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); memset(mgr->state, 0, sizeof(*mgr->state)); mgr->state->deadline = deadline; mgr->state->final_cb = cb; - mgr->state->final_arg = arg; - call_next_handshaker(exec_ctx, endpoint, mgr); + mgr->state->final_user_data = user_data; + call_next_handshaker(exec_ctx, endpoint, args_copy, mgr); } } diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 9d084f071771c..6a39529150a87 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -34,44 +34,62 @@ #ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H #define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H +#include #include #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" -// FIXME: high-level documentation +/// Handshakers are used to perform initial handshakes on a connection +/// before the client sends the initial request. Some examples of what +/// a handshaker can be used for includes support for HTTP CONNECT on +/// the client side and various types of security initialization. +/// +/// In general, handshakers should be used via a handshake manager. -// -// grpc_handshaker -- API for initial handshaking for a new connection -// - -// FIXME: document +/// +/// grpc_handshaker +/// typedef struct grpc_handshaker grpc_handshaker; +/// Callback type invoked when a handshaker is done. +/// Takes ownership of \a args. typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx, - grpc_endpoint* endpoint, void* arg); + grpc_endpoint* endpoint, + grpc_channel_args* args, + void* user_data); struct grpc_handshaker_vtable { + /// Destroys the handshaker. void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + /// Shuts down the handshaker (e.g., to clean up when the operation is + /// aborted in the middle). void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + /// Performs handshaking. When finished, calls \a cb with \a user_data. + /// Takes ownership of \a args. void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + grpc_endpoint* endpoint, grpc_channel_args* args, + gpr_timespec deadline, grpc_handshaker_done_cb cb, + void* user_data); }; +/// Base struct. To subclass, make this the first member of the +/// implementation struct. struct grpc_handshaker { const struct grpc_handshaker_vtable* vtable; }; -// Called by concrete implementations to initialize the base struct. +/// Called by concrete implementations to initialize the base struct. void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, grpc_handshaker* handshaker); -// Convenient wrappers for invoking methods via the vtable. +/// Convenient wrappers for invoking methods via the vtable. +/// These probably do not need to be called from anywhere but +/// grpc_handshake_manager. void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, @@ -79,31 +97,46 @@ void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, + grpc_channel_args* args, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + grpc_handshaker_done_cb cb, void* user_data); -// -// grpc_handshake_manager -- manages a set of handshakers -// +/// +/// grpc_handshake_manager +/// typedef struct grpc_handshake_manager grpc_handshake_manager; +/// Creates a new handshake manager. Caller takes ownership. grpc_handshake_manager* grpc_handshake_manager_create(); -// Handshakers will be invoked in the order added. +/// Adds a handshaker to the handshake manager. +/// Takes ownership of \a mgr. void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr); +/// Destroys the handshake manager. void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +/// Shuts down the handshake manager (e.g., to clean up when the operation is +/// aborted in the middle). +/// The caller must still call grpc_handshake_manager_destroy() after +/// calling this function. void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +/// Invokes handshakers in the order they were added. +/// Does NOT take ownership of \a args. Instead, makes a copy before +/// invoking the first handshaker. +/// If successful, invokes \a cb with \a user_data after all handshakers +/// have completed. void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, + const grpc_channel_args* args, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + grpc_handshaker_done_cb cb, + void* user_data); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 4e9753d28c09d9a2828c0f38a161ec7b0d3ec85c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 15 Jul 2016 10:07:57 -0700 Subject: [PATCH 045/151] Establish Objective C end-to-end core test with Cronet --- .../CoreCronetEnd2EndTests.m | 52 ++- .../Info.plist | 20 +- .../tests/CoreCronetEnd2EndTests/h2_ssl.m | 5 +- .../End2EndTest.xcodeproj/project.pbxproj | 405 ------------------ .../contents.xcworkspacedata | 7 - .../End2EndTest/End2EndTest/AppDelegate.h | 42 -- .../End2EndTest/End2EndTest/AppDelegate.m | 70 --- .../AppIcon.appiconset/Contents.json | 38 -- .../Base.lproj/LaunchScreen.storyboard | 27 -- .../End2EndTest/Base.lproj/Main.storyboard | 25 -- .../End2EndTest/End2EndTest/ViewController.h | 40 -- .../End2EndTest/End2EndTest/ViewController.m | 52 --- .../tests/End2EndTest/End2EndTest/h2_ssl.m | 206 --------- src/objective-c/tests/End2EndTest/Podfile | 70 --- src/objective-c/tests/Podfile | 2 - .../tests/Tests.xcodeproj/project.pbxproj | 2 + 16 files changed, 42 insertions(+), 1021 deletions(-) rename src/objective-c/tests/{End2EndTest/End2EndTest => CoreCronetEnd2EndTests}/Info.plist (55%) delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m delete mode 100644 src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m delete mode 100644 src/objective-c/tests/End2EndTest/Podfile diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index 0f07b6682e67d..1703b5265e53e 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -1,10 +1,35 @@ -// -// CoreCronetEnd2EndTests.m -// CoreCronetEnd2EndTests -// -// Created by Muxi Yan on 7/14/16. -// Copyright © 2016 gRPC. All rights reserved. -// +/* + * + * 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. + * + */ #import @@ -12,6 +37,8 @@ @interface CoreCronetEnd2EndTests : XCTestCase @end +int main(int argc, char **argv); + @implementation CoreCronetEnd2EndTests - (void)setUp { @@ -24,16 +51,11 @@ - (void)tearDown { [super tearDown]; } -- (void)testExample { +- (void)testCoreCronetEnd2End { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. -} - -- (void)testPerformanceExample { - // This is an example of a performance test case. - [self measureBlock:^{ - // Put the code you want to measure the time of here. - }]; + char *argv[] = {"h2_ssl"}; + main(1, argv); } @end diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Info.plist b/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist similarity index 55% rename from src/objective-c/tests/End2EndTest/End2EndTest/Info.plist rename to src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist index 6905cc67bbf73..fbeeb96ba6cb2 100644 --- a/src/objective-c/tests/End2EndTest/End2EndTest/Info.plist +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist @@ -7,34 +7,18 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) + gRPC.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType - APPL + BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m index 800dd56649a1e..68010f341b32e 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m @@ -59,9 +59,6 @@ #include #import -#import -#import "AppDelegate.h" - typedef struct fullstack_secure_fixture_data { char *localaddr; } fullstack_secure_fixture_data; @@ -202,5 +199,5 @@ int main(int argc, char **argv) { remove(roots_filename); gpr_free(roots_filename); - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + return 0; } diff --git a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj deleted file mode 100644 index bf412187f43d8..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.pbxproj +++ /dev/null @@ -1,405 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1518576073757E501D232EDA /* Pods_End2EndTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4035DBC43CDC1A29CB0EB05D /* Pods_End2EndTest.framework */; }; - 5E201A771D3452D500A81F3A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E201A761D3452D500A81F3A /* AppDelegate.m */; }; - 5E201A7A1D3452D500A81F3A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E201A791D3452D500A81F3A /* ViewController.m */; }; - 5E201A7D1D3452D500A81F3A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A7B1D3452D500A81F3A /* Main.storyboard */; }; - 5E201A7F1D3452D600A81F3A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A7E1D3452D600A81F3A /* Assets.xcassets */; }; - 5E201A821D3452D600A81F3A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */; }; - 5EC76B971D36B2EE00A74FED /* h2_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EC76B961D36B2EE00A74FED /* h2_ssl.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-End2EndTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest.debug.xcconfig"; sourceTree = ""; }; - 4035DBC43CDC1A29CB0EB05D /* Pods_End2EndTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_End2EndTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E201A6F1D3452D500A81F3A /* End2EndTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = End2EndTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E201A751D3452D500A81F3A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 5E201A761D3452D500A81F3A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 5E201A781D3452D500A81F3A /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; - 5E201A791D3452D500A81F3A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - 5E201A7C1D3452D500A81F3A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 5E201A7E1D3452D600A81F3A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 5E201A811D3452D600A81F3A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 5E201A831D3452D600A81F3A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5EC76B961D36B2EE00A74FED /* h2_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl.m; sourceTree = ""; }; - E7725B916D22B5AC6ECF8964 /* Pods-End2EndTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-End2EndTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 5E201A6C1D3452D500A81F3A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 1518576073757E501D232EDA /* Pods_End2EndTest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 52027776D515577217FE123B /* Pods */ = { - isa = PBXGroup; - children = ( - 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */, - E7725B916D22B5AC6ECF8964 /* Pods-End2EndTest.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 5E201A661D3452D500A81F3A = { - isa = PBXGroup; - children = ( - 5E201A711D3452D500A81F3A /* End2EndTest */, - 5E201A701D3452D500A81F3A /* Products */, - 52027776D515577217FE123B /* Pods */, - D564C37197511893E4E62D12 /* Frameworks */, - ); - sourceTree = ""; - }; - 5E201A701D3452D500A81F3A /* Products */ = { - isa = PBXGroup; - children = ( - 5E201A6F1D3452D500A81F3A /* End2EndTest.app */, - ); - name = Products; - sourceTree = ""; - }; - 5E201A711D3452D500A81F3A /* End2EndTest */ = { - isa = PBXGroup; - children = ( - 5E201A751D3452D500A81F3A /* AppDelegate.h */, - 5E201A761D3452D500A81F3A /* AppDelegate.m */, - 5E201A781D3452D500A81F3A /* ViewController.h */, - 5E201A791D3452D500A81F3A /* ViewController.m */, - 5E201A7B1D3452D500A81F3A /* Main.storyboard */, - 5E201A7E1D3452D600A81F3A /* Assets.xcassets */, - 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */, - 5E201A831D3452D600A81F3A /* Info.plist */, - 5E201A721D3452D500A81F3A /* Supporting Files */, - ); - path = End2EndTest; - sourceTree = ""; - }; - 5E201A721D3452D500A81F3A /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 5EC76B961D36B2EE00A74FED /* h2_ssl.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - D564C37197511893E4E62D12 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 4035DBC43CDC1A29CB0EB05D /* Pods_End2EndTest.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 5E201A6E1D3452D500A81F3A /* End2EndTest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5E201A861D3452D600A81F3A /* Build configuration list for PBXNativeTarget "End2EndTest" */; - buildPhases = ( - B6E7E45E860B5453E3A5F4A0 /* [CP] Check Pods Manifest.lock */, - 5E201A6B1D3452D500A81F3A /* Sources */, - 5E201A6C1D3452D500A81F3A /* Frameworks */, - 5E201A6D1D3452D500A81F3A /* Resources */, - AE303423292913AB8D447419 /* [CP] Embed Pods Frameworks */, - A4C61E4A2A73F6E1E1143310 /* [CP] Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = End2EndTest; - productName = End2EndTest; - productReference = 5E201A6F1D3452D500A81F3A /* End2EndTest.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 5E201A671D3452D500A81F3A /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0730; - ORGANIZATIONNAME = Google; - TargetAttributes = { - 5E201A6E1D3452D500A81F3A = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 5E201A6A1D3452D500A81F3A /* Build configuration list for PBXProject "End2EndTest" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 5E201A661D3452D500A81F3A; - productRefGroup = 5E201A701D3452D500A81F3A /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 5E201A6E1D3452D500A81F3A /* End2EndTest */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 5E201A6D1D3452D500A81F3A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E201A821D3452D600A81F3A /* LaunchScreen.storyboard in Resources */, - 5E201A7F1D3452D600A81F3A /* Assets.xcassets in Resources */, - 5E201A7D1D3452D500A81F3A /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - A4C61E4A2A73F6E1E1143310 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - AE303423292913AB8D447419 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-End2EndTest/Pods-End2EndTest-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - B6E7E45E860B5453E3A5F4A0 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 5E201A6B1D3452D500A81F3A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E201A7A1D3452D500A81F3A /* ViewController.m in Sources */, - 5E201A771D3452D500A81F3A /* AppDelegate.m in Sources */, - 5EC76B971D36B2EE00A74FED /* h2_ssl.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 5E201A7B1D3452D500A81F3A /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 5E201A7C1D3452D500A81F3A /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 5E201A801D3452D600A81F3A /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 5E201A811D3452D600A81F3A /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 5E201A841D3452D600A81F3A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 5E201A851D3452D600A81F3A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 5E201A871D3452D600A81F3A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 18957F402A222D334CEBE57B /* Pods-End2EndTest.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "\"${PODS_ROOT}/Headers/Public\"", - "\"${PODS_ROOT}/Headers/Public/BoringSSL\"", - "\"${PODS_ROOT}/Headers/Public/CronetFramework\"", - "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"", - "\"${PODS_ROOT}/Headers/Public/gRPC-Cronet\"", - "\"${PODS_ROOT}/../../../../../include\"", - ); - INFOPLIST_FILE = End2EndTest/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.google.End2EndTest; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../../.."; - }; - name = Debug; - }; - 5E201A881D3452D600A81F3A /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E7725B916D22B5AC6ECF8964 /* Pods-End2EndTest.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "\"${PODS_ROOT}/Headers/Public\"", - "\"${PODS_ROOT}/Headers/Public/BoringSSL\"", - "\"${PODS_ROOT}/Headers/Public/CronetFramework\"", - "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"", - "\"${PODS_ROOT}/Headers/Public/gRPC-Cronet\"", - "\"${PODS_ROOT}/../../../../../include\"", - ); - INFOPLIST_FILE = End2EndTest/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.google.End2EndTest; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../../.."; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 5E201A6A1D3452D500A81F3A /* Build configuration list for PBXProject "End2EndTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E201A841D3452D600A81F3A /* Debug */, - 5E201A851D3452D600A81F3A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5E201A861D3452D600A81F3A /* Build configuration list for PBXNativeTarget "End2EndTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E201A871D3452D600A81F3A /* Debug */, - 5E201A881D3452D600A81F3A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 5E201A671D3452D500A81F3A /* Project object */; -} diff --git a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 220e863b896e3..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h deleted file mode 100644 index 867e62842aeca..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * 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. - * - */ - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m b/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m deleted file mode 100644 index 66fceffd85cb4..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/AppDelegate.m +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * 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. - * - */ - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json b/src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 118c98f7461bf..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard b/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 2e721e1833f03..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard b/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard deleted file mode 100644 index f56d2f3bb56e8..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/Base.lproj/Main.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h deleted file mode 100644 index 38cd7f92b660a..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * 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. - * - */ - -#import - -@interface ViewController : UIViewController - - -@end - diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m b/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m deleted file mode 100644 index 70b5d45811051..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/ViewController.m +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * 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. - * - */ - -#import "ViewController.h" - -@interface ViewController () - -@end - -@implementation ViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -@end diff --git a/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m b/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m deleted file mode 100644 index 800dd56649a1e..0000000000000 --- a/src/objective-c/tests/End2EndTest/End2EndTest/h2_ssl.m +++ /dev/null @@ -1,206 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * This fixture creates a server full stack using chttp2 and a client - * full stack using Cronet. End-to-end tests are run against this fixture - * setting. - * - */ - -#include "test/core/end2end/end2end_tests.h" - -#include -#include - -#include -#include -#include - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" -#include "test/core/end2end/data/ssl_test_data.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -#include -#import - -#import -#import "AppDelegate.h" - -typedef struct fullstack_secure_fixture_data { - char *localaddr; -} fullstack_secure_fixture_data; - -static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( - grpc_channel_args *client_args, grpc_channel_args *server_args) { - grpc_end2end_test_fixture f; - int port = grpc_pick_unused_port_or_die(); - fullstack_secure_fixture_data *ffd = - gpr_malloc(sizeof(fullstack_secure_fixture_data)); - memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - - f.fixture_data = ffd; - f.cq = grpc_completion_queue_create(NULL); - - return f; -} - -static void process_auth_failure(void *state, grpc_auth_context *ctx, - const grpc_metadata *md, size_t md_count, - grpc_process_auth_metadata_done_cb cb, - void *user_data) { - GPR_ASSERT(state == NULL); - cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); -} - -static void cronet_init_client_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *client_args, - cronet_engine *cronetEngine) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - f->client = - grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); - GPR_ASSERT(f->client != NULL); -} - -static void chttp2_init_server_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *server_args, - grpc_server_credentials *server_creds) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - if (f->server) { - grpc_server_destroy(f->server); - } - f->server = grpc_server_create(server_args, NULL); - grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, - server_creds)); - grpc_server_credentials_release(server_creds); - grpc_server_start(f->server); -} - -void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - gpr_free(ffd->localaddr); - gpr_free(ffd); -} - -static void cronet_init_client_simple_ssl_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { - grpc_arg ssl_name_override = {GRPC_ARG_STRING, - GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, - {"foo.test.google.fr"}}; - - grpc_channel_args *new_client_args = - grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); - [Cronet setHttp2Enabled:YES]; - [Cronet start]; - cronet_engine *cronetEngine = [Cronet getGlobalEngine]; - - cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); - grpc_channel_args_destroy(new_client_args); -} - -static int fail_server_auth_check(grpc_channel_args *server_args) { - size_t i; - if (server_args == NULL) return 0; - for (i = 0; i < server_args->num_args; i++) { - if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == - 0) { - return 1; - } - } - return 0; -} - -static void chttp2_init_server_simple_ssl_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { - grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, - test_server1_cert}; - grpc_server_credentials *ssl_creds = - grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); - if (fail_server_auth_check(server_args)) { - grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; - grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); - } - chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); -} - -/* All test configurations */ - -static grpc_end2end_test_config configs[] = { - {"chttp2/simple_ssl_fullstack", - FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, - chttp2_create_fixture_secure_fullstack, - cronet_init_client_simple_ssl_secure_fullstack, - chttp2_init_server_simple_ssl_secure_fullstack, - chttp2_tear_down_secure_fullstack}, -}; - -int main(int argc, char **argv) { - size_t i; - FILE *roots_file; - size_t roots_size = strlen(test_root_cert); - char *roots_filename; - - grpc_test_init(argc, argv); - grpc_end2end_tests_pre_init(); - - /* Set the SSL roots env var. */ - roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); - GPR_ASSERT(roots_filename != NULL); - GPR_ASSERT(roots_file != NULL); - GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); - fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); - - grpc_init(); - - for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(argc, argv, configs[i]); - } - - grpc_shutdown(); - - /* Cleanup. */ - remove(roots_filename); - gpr_free(roots_filename); - - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); -} diff --git a/src/objective-c/tests/End2EndTest/Podfile b/src/objective-c/tests/End2EndTest/Podfile deleted file mode 100644 index a3fd4d5e9559e..0000000000000 --- a/src/objective-c/tests/End2EndTest/Podfile +++ /dev/null @@ -1,70 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' - -install! 'cocoapods', :deterministic_uuids => false - -# Location of gRPC's repo root relative to this file. -GRPC_LOCAL_SRC = '../../../..' - -# Install the dependencies in the main target plus all test targets. -%w( - End2EndTest -).each do |target_name| - target target_name do - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod 'gRPC-Core', :path => GRPC_LOCAL_SRC - pod 'gRPC-Cronet', :path => GRPC_LOCAL_SRC - end -end - -# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's -# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded -# and before they are installed in the user project. -# -# This podspec searches for the gRPC core library headers under "$(PODS_ROOT)/gRPC-Core", where -# Cocoapods normally places the downloaded sources. When doing local development of the libraries, -# though, Cocoapods just takes the sources from whatever directory was specified using `:path`, and -# doesn't copy them under $(PODS_ROOT). When using static libraries, one can sometimes rely on the -# symbolic links to the pods headers that Cocoapods creates under "$(PODS_ROOT)/Headers". But those -# aren't created when using dynamic frameworks. So our solution is to modify the podspec on the fly -# to point at the local directory where the sources are. -# -# TODO(jcanizales): Send a PR to Cocoapods to get rid of this need. -pre_install do |installer| - %w( - gRPC-Core - gRPC-Cronet - ).each do |target_name| - grpc_core_spec = installer.pod_targets.find{|t| t.name == target_name}.root_spec - - # Copied from gRPC-Core.podspec, except for the adjusted src_root: - src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" - grpc_core_spec.pod_target_xcconfig = { - 'GRPC_SRC_ROOT' => src_root, - 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', - 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', - # If we don't set these two settings, `include/grpc/support/time.h` and - # `src/core/lib/support/string.h` shadow the system `` and ``, breaking - # the build. - 'USE_HEADERMAP' => 'NO', - 'ALWAYS_SEARCH_USER_PATHS' => 'NO', - } - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' - end - if target.name == 'gRPC-Core' - target.build_configurations.each do |config| - # TODO(zyc) Remove this setting after the issue is resolved - # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void - # function" warning - config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' - end - end - end -end diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index e5265630a2ca6..546017c9f78a7 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -27,8 +27,6 @@ GRPC_LOCAL_SRC = '../../..' pod 'gRPC-Core', :path => GRPC_LOCAL_SRC pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC - - pod 'RemoteTest', :path => "RemoteTestClient" end end diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 6c41563a350e5..4aa5b1bdbe4ec 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -976,6 +976,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; }; name = Debug; }; @@ -990,6 +991,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; }; name = Release; }; From 854b81a83b2ba74dd56d79e217ff802eab9781c6 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 11:23:48 -0700 Subject: [PATCH 046/151] Advance versions from 0.14 -> 1.0 Pending: - Tag BoringSSL repo. - Tag gRPC repo. - Build the plugin, zip it, and add it to the release. - Push Cocoapods to trunk. --- examples/objective-c/auth_sample/AuthTestService.podspec | 2 +- examples/objective-c/helloworld/HelloWorld.podspec | 2 +- examples/objective-c/route_guide/RouteGuide.podspec | 2 +- gRPC-Core.podspec | 4 ++-- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 4 ++-- src/objective-c/BoringSSL.podspec | 2 +- src/objective-c/README.md | 2 +- src/objective-c/examples/RemoteTestClient/RemoteTest.podspec | 2 +- src/objective-c/tests/RemoteTestClient/RemoteTest.podspec | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec index af5ef2894648f..1df6f98ad5bdb 100644 --- a/examples/objective-c/auth_sample/AuthTestService.podspec +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec index bce6cd5172484..11c7fb3bcf002 100644 --- a/examples/objective-c/helloworld/HelloWorld.podspec +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec index e2132507514a4..729b45f87a2d3 100644 --- a/examples/objective-c/route_guide/RouteGuide.podspec +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e10e05387b15a..a102f9a76a3d4 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -35,7 +35,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'http://www.grpc.io' @@ -191,7 +191,7 @@ Pod::Spec.new do |s| ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL', '~> 4.0' + ss.dependency 'BoringSSL', '~> 5.0' # To save you from scrolling, this is the last part of the podspec. ss.source_files = 'src/core/lib/profiling/timers.h', diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 9cc33c7dbd0e7..e27c294c630ca 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'http://www.grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 6263878213e01..deca772db4152 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'http://www.grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index e5556cc5448f9..4bfffe5dacf51 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'http://www.grpc.io' diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 72cadb9319943..078e11c32e759 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '0.14.0' + v = '1.0.0' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC @@ -82,7 +82,7 @@ Pod::Spec.new do |s| s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } repo = 'grpc/grpc' - release = 'release-0_14_1' + release = 'v1.0.x' file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip" s.source = { :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}", diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec index 42b4434d0d326..653cf1c5c649b 100644 --- a/src/objective-c/BoringSSL.podspec +++ b/src/objective-c/BoringSSL.podspec @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.name = 'BoringSSL' - version = '4.0' + version = '5.0' s.version = version s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.' # Adapted from the homepage: diff --git a/src/objective-c/README.md b/src/objective-c/README.md index a0ca5f448a0ea..22f0bdd09b8eb 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -48,7 +48,7 @@ Pod::Spec.new do |s| src = '.' # We'll use protoc with the gRPC plugin. - s.dependency '!ProtoCompiler-gRPCPlugin', '~> 0.14' + s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0' # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = '/Pods' diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index 6e783fb5adbf8..8839b81b616a1 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 7d84a5ae4dc73..30173a332f453 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" From e1466d66292e8317e64d770a5077dd1beeb07c77 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Fri, 15 Jul 2016 21:43:02 +0000 Subject: [PATCH 047/151] Client and server multiplex example --- examples/python/multiplex/.gitignore | 1 + examples/python/multiplex/README.md | 1 + examples/python/multiplex/helloworld_pb2.py | 204 ++++++ examples/python/multiplex/multiplex_client.py | 139 ++++ examples/python/multiplex/multiplex_server.py | 149 +++++ examples/python/multiplex/route_guide_db.json | 601 ++++++++++++++++++ examples/python/multiplex/route_guide_pb2.py | 516 +++++++++++++++ .../python/multiplex/route_guide_resources.py | 53 ++ examples/python/multiplex/run_codegen.py | 51 ++ 9 files changed, 1715 insertions(+) create mode 100644 examples/python/multiplex/.gitignore create mode 100644 examples/python/multiplex/README.md create mode 100644 examples/python/multiplex/helloworld_pb2.py create mode 100644 examples/python/multiplex/multiplex_client.py create mode 100644 examples/python/multiplex/multiplex_server.py create mode 100644 examples/python/multiplex/route_guide_db.json create mode 100644 examples/python/multiplex/route_guide_pb2.py create mode 100644 examples/python/multiplex/route_guide_resources.py create mode 100755 examples/python/multiplex/run_codegen.py diff --git a/examples/python/multiplex/.gitignore b/examples/python/multiplex/.gitignore new file mode 100644 index 0000000000000..0d20b6487c61e --- /dev/null +++ b/examples/python/multiplex/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/examples/python/multiplex/README.md b/examples/python/multiplex/README.md new file mode 100644 index 0000000000000..bad3a42b37041 --- /dev/null +++ b/examples/python/multiplex/README.md @@ -0,0 +1 @@ +An example showing two stubs sharing a channel and two servicers sharing a server. diff --git a/examples/python/multiplex/helloworld_pb2.py b/examples/python/multiplex/helloworld_pb2.py new file mode 100644 index 0000000000000..3ce33fbf2bf36 --- /dev/null +++ b/examples/python/multiplex/helloworld_pb2.py @@ -0,0 +1,204 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='helloworld', + syntax='proto3', + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='helloworld.HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='helloworld.HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=32, + serialized_end=60, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='helloworld.HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='helloworld.HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=62, + serialized_end=91, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) +import grpc +from grpc.beta import implementations as beta_implementations +from grpc.beta import interfaces as beta_interfaces +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=HelloRequest.SerializeToString, + response_deserializer=HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=HelloRequest.FromString, + response_serializer=HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + +class BetaGreeterServicer(object): + """The greeting service definition. + """ + def SayHello(self, request, context): + """Sends a greeting + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + + +class BetaGreeterStub(object): + """The greeting service definition. + """ + def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """Sends a greeting + """ + raise NotImplementedError() + SayHello.future = None + + +def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): + request_deserializers = { + ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString, + } + response_serializers = { + ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString, + } + method_implementations = { + ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello), + } + server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) + return beta_implementations.server(method_implementations, options=server_options) + + +def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): + request_serializers = { + ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString, + } + response_deserializers = { + ('helloworld.Greeter', 'SayHello'): HelloReply.FromString, + } + cardinalities = { + 'SayHello': cardinality.Cardinality.UNARY_UNARY, + } + stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) + return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options) +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/multiplex/multiplex_client.py b/examples/python/multiplex/multiplex_client.py new file mode 100644 index 0000000000000..2e8162926b777 --- /dev/null +++ b/examples/python/multiplex/multiplex_client.py @@ -0,0 +1,139 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""A client that makes both Greeter and RouteGuide RPCs.""" + +from __future__ import print_function + +import random +import time + +import grpc + +import helloworld_pb2 +import route_guide_pb2 +import route_guide_resources + + +def make_route_note(message, latitude, longitude): + return route_guide_pb2.RouteNote( + message=message, + location=route_guide_pb2.Point(latitude=latitude, longitude=longitude)) + + +def guide_get_one_feature(route_guide_stub, point): + feature = route_guide_stub.GetFeature(point) + if not feature.location: + print("Server returned incomplete feature") + return + + if feature.name: + print("Feature called %s at %s" % (feature.name, feature.location)) + else: + print("Found no feature at %s" % feature.location) + + +def guide_get_feature(route_guide_stub): + guide_get_one_feature( + route_guide_stub, + route_guide_pb2.Point(latitude=409146138, longitude=-746188906)) + guide_get_one_feature( + route_guide_stub, route_guide_pb2.Point(latitude=0, longitude=0)) + + +def guide_list_features(route_guide_stub): + rectangle = route_guide_pb2.Rectangle( + lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000), + hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000)) + print("Looking for features between 40, -75 and 42, -73") + + features = route_guide_stub.ListFeatures(rectangle) + + for feature in features: + print("Feature called %s at %s" % (feature.name, feature.location)) + + +def generate_route(feature_list): + for _ in range(0, 10): + random_feature = feature_list[random.randint(0, len(feature_list) - 1)] + print("Visiting point %s" % random_feature.location) + yield random_feature.location + time.sleep(random.uniform(0.5, 1.5)) + + +def guide_record_route(route_guide_stub): + feature_list = route_guide_resources.read_route_guide_database() + + route_iterator = generate_route(feature_list) + route_summary = route_guide_stub.RecordRoute(route_iterator) + print("Finished trip with %s points " % route_summary.point_count) + print("Passed %s features " % route_summary.feature_count) + print("Travelled %s meters " % route_summary.distance) + print("It took %s seconds " % route_summary.elapsed_time) + + +def generate_messages(): + messages = [ + make_route_note("First message", 0, 0), + make_route_note("Second message", 0, 1), + make_route_note("Third message", 1, 0), + make_route_note("Fourth message", 0, 0), + make_route_note("Fifth message", 1, 0), + ] + for msg in messages: + print("Sending %s at %s" % (msg.message, msg.location)) + yield msg + time.sleep(random.uniform(0.5, 1.0)) + + +def guide_route_chat(route_guide_stub): + responses = route_guide_stub.RouteChat(generate_messages()) + for response in responses: + print("Received message %s at %s" % (response.message, response.location)) + + +def run(): + channel = grpc.insecure_channel('localhost:50051') + greeter_stub = helloworld_pb2.GreeterStub(channel) + route_guide_stub = route_guide_pb2.RouteGuideStub(channel) + greeter_response = greeter_stub.SayHello( + helloworld_pb2.HelloRequest(name='you')) + print("Greeter client received: " + greeter_response.message) + print("-------------- GetFeature --------------") + guide_get_feature(route_guide_stub) + print("-------------- ListFeatures --------------") + guide_list_features(route_guide_stub) + print("-------------- RecordRoute --------------") + guide_record_route(route_guide_stub) + print("-------------- RouteChat --------------") + guide_route_chat(route_guide_stub) + + +if __name__ == '__main__': + run() diff --git a/examples/python/multiplex/multiplex_server.py b/examples/python/multiplex/multiplex_server.py new file mode 100644 index 0000000000000..32a4ee4a4977f --- /dev/null +++ b/examples/python/multiplex/multiplex_server.py @@ -0,0 +1,149 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""A gRPC server servicing both Greeter and RouteGuide RPCs.""" + +from concurrent import futures +import time +import math + +import grpc + +import helloworld_pb2 +import route_guide_pb2 +import route_guide_resources + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def _get_feature(feature_db, point): + """Returns Feature at given location or None.""" + for feature in feature_db: + if feature.location == point: + return feature + return None + + +def _get_distance(start, end): + """Distance between two points.""" + coord_factor = 10000000.0 + lat_1 = start.latitude / coord_factor + lat_2 = end.latitude / coord_factor + lon_1 = start.longitude / coord_factor + lon_2 = end.longitude / coord_factor + lat_rad_1 = math.radians(lat_1) + lat_rad_2 = math.radians(lat_2) + delta_lat_rad = math.radians(lat_2 - lat_1) + delta_lon_rad = math.radians(lon_2 - lon_1) + + a = (pow(math.sin(delta_lat_rad / 2), 2) + + (math.cos(lat_rad_1) * math.cos(lat_rad_2) * + pow(math.sin(delta_lon_rad / 2), 2))) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) + R = 6371000; # metres + return R * c; + + +class _GreeterServicer(helloworld_pb2.GreeterServicer): + + def SayHello(self, request, context): + return helloworld_pb2.HelloReply(message='Hello, {}!'.format(request.name)) + + +class _RouteGuideServicer(route_guide_pb2.RouteGuideServicer): + """Provides methods that implement functionality of route guide server.""" + + def __init__(self): + self.db = route_guide_resources.read_route_guide_database() + + def GetFeature(self, request, context): + feature = _get_feature(self.db, request) + if feature is None: + return route_guide_pb2.Feature(name="", location=request) + else: + return feature + + def ListFeatures(self, request, context): + left = min(request.lo.longitude, request.hi.longitude) + right = max(request.lo.longitude, request.hi.longitude) + top = max(request.lo.latitude, request.hi.latitude) + bottom = min(request.lo.latitude, request.hi.latitude) + for feature in self.db: + if (feature.location.longitude >= left and + feature.location.longitude <= right and + feature.location.latitude >= bottom and + feature.location.latitude <= top): + yield feature + + def RecordRoute(self, request_iterator, context): + point_count = 0 + feature_count = 0 + distance = 0.0 + prev_point = None + + start_time = time.time() + for point in request_iterator: + point_count += 1 + if _get_feature(self.db, point): + feature_count += 1 + if prev_point: + distance += _get_distance(prev_point, point) + prev_point = point + + elapsed_time = time.time() - start_time + return route_guide_pb2.RouteSummary(point_count=point_count, + feature_count=feature_count, + distance=int(distance), + elapsed_time=int(elapsed_time)) + + def RouteChat(self, request_iterator, context): + prev_notes = [] + for new_note in request_iterator: + for prev_note in prev_notes: + if prev_note.location == new_note.location: + yield prev_note + prev_notes.append(new_note) + + +def serve(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2.add_GreeterServicer_to_server(_GreeterServicer(), server) + route_guide_pb2.add_RouteGuideServicer_to_server( + _RouteGuideServicer(), server) + server.add_insecure_port('[::]:50051') + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(0) + + +if __name__ == '__main__': + serve() diff --git a/examples/python/multiplex/route_guide_db.json b/examples/python/multiplex/route_guide_db.json new file mode 100644 index 0000000000000..9d6a980ab7d76 --- /dev/null +++ b/examples/python/multiplex/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/examples/python/multiplex/route_guide_pb2.py b/examples/python/multiplex/route_guide_pb2.py new file mode 100644 index 0000000000000..924e186e06e4c --- /dev/null +++ b/examples/python/multiplex/route_guide_pb2.py @@ -0,0 +1,516 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='route_guide.proto', + package='routeguide', + syntax='proto3', + serialized_pb=_b('\n\x11route_guide.proto\x12\nrouteguide\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"I\n\tRectangle\x12\x1d\n\x02lo\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x1d\n\x02hi\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"<\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x08location\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"A\n\tRouteNote\x12#\n\x08location\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\x85\x02\n\nRouteGuide\x12\x36\n\nGetFeature\x12\x11.routeguide.Point\x1a\x13.routeguide.Feature\"\x00\x12>\n\x0cListFeatures\x12\x15.routeguide.Rectangle\x1a\x13.routeguide.Feature\"\x00\x30\x01\x12>\n\x0bRecordRoute\x12\x11.routeguide.Point\x1a\x18.routeguide.RouteSummary\"\x00(\x01\x12?\n\tRouteChat\x12\x15.routeguide.RouteNote\x1a\x15.routeguide.RouteNote\"\x00(\x01\x30\x01\x42\x36\n\x1bio.grpc.examples.routeguideB\x0fRouteGuideProtoP\x01\xa2\x02\x03RTGb\x06proto3') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_POINT = _descriptor.Descriptor( + name='Point', + full_name='routeguide.Point', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='latitude', full_name='routeguide.Point.latitude', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='longitude', full_name='routeguide.Point.longitude', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=33, + serialized_end=77, +) + + +_RECTANGLE = _descriptor.Descriptor( + name='Rectangle', + full_name='routeguide.Rectangle', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='lo', full_name='routeguide.Rectangle.lo', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='hi', full_name='routeguide.Rectangle.hi', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=79, + serialized_end=152, +) + + +_FEATURE = _descriptor.Descriptor( + name='Feature', + full_name='routeguide.Feature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='routeguide.Feature.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='location', full_name='routeguide.Feature.location', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=154, + serialized_end=214, +) + + +_ROUTENOTE = _descriptor.Descriptor( + name='RouteNote', + full_name='routeguide.RouteNote', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='location', full_name='routeguide.RouteNote.location', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='message', full_name='routeguide.RouteNote.message', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=216, + serialized_end=281, +) + + +_ROUTESUMMARY = _descriptor.Descriptor( + name='RouteSummary', + full_name='routeguide.RouteSummary', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='point_count', full_name='routeguide.RouteSummary.point_count', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='feature_count', full_name='routeguide.RouteSummary.feature_count', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='distance', full_name='routeguide.RouteSummary.distance', index=2, + number=3, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='elapsed_time', full_name='routeguide.RouteSummary.elapsed_time', index=3, + number=4, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=283, + serialized_end=381, +) + +_RECTANGLE.fields_by_name['lo'].message_type = _POINT +_RECTANGLE.fields_by_name['hi'].message_type = _POINT +_FEATURE.fields_by_name['location'].message_type = _POINT +_ROUTENOTE.fields_by_name['location'].message_type = _POINT +DESCRIPTOR.message_types_by_name['Point'] = _POINT +DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE +DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE +DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE +DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY + +Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict( + DESCRIPTOR = _POINT, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.Point) + )) +_sym_db.RegisterMessage(Point) + +Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict( + DESCRIPTOR = _RECTANGLE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.Rectangle) + )) +_sym_db.RegisterMessage(Rectangle) + +Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict( + DESCRIPTOR = _FEATURE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.Feature) + )) +_sym_db.RegisterMessage(Feature) + +RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict( + DESCRIPTOR = _ROUTENOTE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.RouteNote) + )) +_sym_db.RegisterMessage(RouteNote) + +RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict( + DESCRIPTOR = _ROUTESUMMARY, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.RouteSummary) + )) +_sym_db.RegisterMessage(RouteSummary) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG')) +import grpc +from grpc.beta import implementations as beta_implementations +from grpc.beta import interfaces as beta_interfaces +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + + +class RouteGuideStub(object): + """Interface exported by the server. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetFeature = channel.unary_unary( + '/routeguide.RouteGuide/GetFeature', + request_serializer=Point.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.ListFeatures = channel.unary_stream( + '/routeguide.RouteGuide/ListFeatures', + request_serializer=Rectangle.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.RecordRoute = channel.stream_unary( + '/routeguide.RouteGuide/RecordRoute', + request_serializer=Point.SerializeToString, + response_deserializer=RouteSummary.FromString, + ) + self.RouteChat = channel.stream_stream( + '/routeguide.RouteGuide/RouteChat', + request_serializer=RouteNote.SerializeToString, + response_deserializer=RouteNote.FromString, + ) + + +class RouteGuideServicer(object): + """Interface exported by the server. + """ + + def GetFeature(self, request, context): + """A simple RPC. + + Obtains the feature at a given position. + + A feature with an empty name is returned if there's no feature at the given + position. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListFeatures(self, request, context): + """A server-to-client streaming RPC. + + Obtains the Features available within the given Rectangle. Results are + streamed rather than returned at once (e.g. in a response message with a + repeated field), as the rectangle may cover a large area and contain a + huge number of features. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RecordRoute(self, request_iterator, context): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RouteChat(self, request_iterator, context): + """A Bidirectional streaming RPC. + + Accepts a stream of RouteNotes sent while a route is being traversed, + while receiving other RouteNotes (e.g. from other users). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_RouteGuideServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetFeature': grpc.unary_unary_rpc_method_handler( + servicer.GetFeature, + request_deserializer=Point.FromString, + response_serializer=Feature.SerializeToString, + ), + 'ListFeatures': grpc.unary_stream_rpc_method_handler( + servicer.ListFeatures, + request_deserializer=Rectangle.FromString, + response_serializer=Feature.SerializeToString, + ), + 'RecordRoute': grpc.stream_unary_rpc_method_handler( + servicer.RecordRoute, + request_deserializer=Point.FromString, + response_serializer=RouteSummary.SerializeToString, + ), + 'RouteChat': grpc.stream_stream_rpc_method_handler( + servicer.RouteChat, + request_deserializer=RouteNote.FromString, + response_serializer=RouteNote.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'routeguide.RouteGuide', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + +class BetaRouteGuideServicer(object): + """Interface exported by the server. + """ + def GetFeature(self, request, context): + """A simple RPC. + + Obtains the feature at a given position. + + A feature with an empty name is returned if there's no feature at the given + position. + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def ListFeatures(self, request, context): + """A server-to-client streaming RPC. + + Obtains the Features available within the given Rectangle. Results are + streamed rather than returned at once (e.g. in a response message with a + repeated field), as the rectangle may cover a large area and contain a + huge number of features. + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def RecordRoute(self, request_iterator, context): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def RouteChat(self, request_iterator, context): + """A Bidirectional streaming RPC. + + Accepts a stream of RouteNotes sent while a route is being traversed, + while receiving other RouteNotes (e.g. from other users). + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + + +class BetaRouteGuideStub(object): + """Interface exported by the server. + """ + def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """A simple RPC. + + Obtains the feature at a given position. + + A feature with an empty name is returned if there's no feature at the given + position. + """ + raise NotImplementedError() + GetFeature.future = None + def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """A server-to-client streaming RPC. + + Obtains the Features available within the given Rectangle. Results are + streamed rather than returned at once (e.g. in a response message with a + repeated field), as the rectangle may cover a large area and contain a + huge number of features. + """ + raise NotImplementedError() + def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + raise NotImplementedError() + RecordRoute.future = None + def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): + """A Bidirectional streaming RPC. + + Accepts a stream of RouteNotes sent while a route is being traversed, + while receiving other RouteNotes (e.g. from other users). + """ + raise NotImplementedError() + + +def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): + request_deserializers = { + ('routeguide.RouteGuide', 'GetFeature'): Point.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, + } + response_serializers = { + ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, + } + method_implementations = { + ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature), + ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures), + ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute), + ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat), + } + server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) + return beta_implementations.server(method_implementations, options=server_options) + + +def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): + request_serializers = { + ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, + } + response_deserializers = { + ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, + } + cardinalities = { + 'GetFeature': cardinality.Cardinality.UNARY_UNARY, + 'ListFeatures': cardinality.Cardinality.UNARY_STREAM, + 'RecordRoute': cardinality.Cardinality.STREAM_UNARY, + 'RouteChat': cardinality.Cardinality.STREAM_STREAM, + } + stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) + return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options) +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/multiplex/route_guide_resources.py b/examples/python/multiplex/route_guide_resources.py new file mode 100644 index 0000000000000..30c7711019fb6 --- /dev/null +++ b/examples/python/multiplex/route_guide_resources.py @@ -0,0 +1,53 @@ +# 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. + +"""Common resources used in the gRPC route guide example.""" + +import json + +import route_guide_pb2 + + +def read_route_guide_database(): + """Reads the route guide database. + + Returns: + The full contents of the route guide database as a sequence of + route_guide_pb2.Features. + """ + feature_list = [] + with open("route_guide_db.json") as route_guide_db_file: + for item in json.load(route_guide_db_file): + feature = route_guide_pb2.Feature( + name=item["name"], + location=route_guide_pb2.Point( + latitude=item["location"]["latitude"], + longitude=item["location"]["longitude"])) + feature_list.append(feature) + return feature_list diff --git a/examples/python/multiplex/run_codegen.py b/examples/python/multiplex/run_codegen.py new file mode 100755 index 0000000000000..7922a0f5c7f51 --- /dev/null +++ b/examples/python/multiplex/run_codegen.py @@ -0,0 +1,51 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Generates protocol messages and gRPC stubs.""" + +from grpc.tools import protoc + +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/helloworld.proto', + ) +) +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/route_guide.proto', + ) +) From 65515a76dd783296769dee23712804b2036c5d80 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 15 Jul 2016 15:12:33 -0700 Subject: [PATCH 048/151] Establish Objective C end-to-end core test with Cronet --- .../tests/CoreCronetEnd2EndTests/h2_ssl.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h new file mode 100644 index 0000000000000..a7f2bd724a37f --- /dev/null +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h @@ -0,0 +1,13 @@ +// +// h2_ssl.h +// Tests +// +// Created by Muxi Yan on 7/15/16. +// Copyright © 2016 gRPC. All rights reserved. +// + +#ifndef h2_ssl_h +#define h2_ssl_h + + +#endif /* h2_ssl_h */ From 46585e23f14b0463c4b7a0d04d72d71228c674ae Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Fri, 15 Jul 2016 22:33:50 +0000 Subject: [PATCH 049/151] Update examples to GA API --- examples/python/helloworld/greeter_client.py | 10 +- examples/python/helloworld/greeter_server.py | 8 +- examples/python/helloworld/helloworld_pb2.py | 63 +++++-- .../{run_codegen.sh => run_codegen.py} | 16 +- .../python/route_guide/route_guide_client.py | 26 ++- .../python/route_guide/route_guide_pb2.py | 172 ++++++++++++++---- .../route_guide/route_guide_resources.py | 0 .../python/route_guide/route_guide_server.py | 7 +- .../{run_codegen.sh => run_codegen.py} | 16 +- 9 files changed, 239 insertions(+), 79 deletions(-) rename examples/python/helloworld/{run_codegen.sh => run_codegen.py} (86%) mode change 100755 => 100644 mode change 100755 => 100644 examples/python/route_guide/route_guide_resources.py rename examples/python/route_guide/{run_codegen.sh => run_codegen.py} (86%) mode change 100755 => 100644 diff --git a/examples/python/helloworld/greeter_client.py b/examples/python/helloworld/greeter_client.py index 40d637fb7b479..44d42c102b5f8 100644 --- a/examples/python/helloworld/greeter_client.py +++ b/examples/python/helloworld/greeter_client.py @@ -31,17 +31,15 @@ from __future__ import print_function -from grpc.beta import implementations +import grpc import helloworld_pb2 -_TIMEOUT_SECONDS = 10 - def run(): - channel = implementations.insecure_channel('localhost', 50051) - stub = helloworld_pb2.beta_create_Greeter_stub(channel) - response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS) + channel = grpc.insecure_channel('localhost:50051') + stub = helloworld_pb2.GreeterStub(channel) + response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) print("Greeter client received: " + response.message) diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py index 2cde5add435d6..37d8bd49ccdce 100644 --- a/examples/python/helloworld/greeter_server.py +++ b/examples/python/helloworld/greeter_server.py @@ -29,21 +29,25 @@ """The Python implementation of the GRPC helloworld.Greeter server.""" +from concurrent import futures import time +import grpc + import helloworld_pb2 _ONE_DAY_IN_SECONDS = 60 * 60 * 24 -class Greeter(helloworld_pb2.BetaGreeterServicer): +class Greeter(helloworld_pb2.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def serve(): - server = helloworld_pb2.beta_create_Greeter_server(Greeter()) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() try: diff --git a/examples/python/helloworld/helloworld_pb2.py b/examples/python/helloworld/helloworld_pb2.py index 1ee80e4034c22..3ce33fbf2bf36 100644 --- a/examples/python/helloworld/helloworld_pb2.py +++ b/examples/python/helloworld/helloworld_pb2.py @@ -107,13 +107,55 @@ DESCRIPTOR.has_options = True DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) -import abc -import six +import grpc from grpc.beta import implementations as beta_implementations from grpc.beta import interfaces as beta_interfaces from grpc.framework.common import cardinality from grpc.framework.interfaces.face import utilities as face_utilities + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=HelloRequest.SerializeToString, + response_deserializer=HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=HelloRequest.FromString, + response_serializer=HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + class BetaGreeterServicer(object): """The greeting service definition. """ @@ -122,23 +164,23 @@ def SayHello(self, request, context): """ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + class BetaGreeterStub(object): """The greeting service definition. """ - def SayHello(self, request, timeout): + def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None): """Sends a greeting """ raise NotImplementedError() SayHello.future = None + def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): - import helloworld_pb2 - import helloworld_pb2 request_deserializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloRequest.FromString, + ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString, } response_serializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloReply.SerializeToString, + ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString, } method_implementations = { ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello), @@ -146,14 +188,13 @@ def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_time server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) return beta_implementations.server(method_implementations, options=server_options) + def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): - import helloworld_pb2 - import helloworld_pb2 request_serializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloRequest.SerializeToString, + ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString, } response_deserializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloReply.FromString, + ('helloworld.Greeter', 'SayHello'): HelloReply.FromString, } cardinalities = { 'SayHello': cardinality.Cardinality.UNARY_UNARY, diff --git a/examples/python/helloworld/run_codegen.sh b/examples/python/helloworld/run_codegen.py old mode 100755 new mode 100644 similarity index 86% rename from examples/python/helloworld/run_codegen.sh rename to examples/python/helloworld/run_codegen.py index 34224e5c418f5..4835ec2b4d28c --- a/examples/python/helloworld/run_codegen.sh +++ b/examples/python/helloworld/run_codegen.py @@ -1,4 +1,3 @@ -#!/bin/bash # Copyright 2015, Google Inc. # All rights reserved. # @@ -28,5 +27,16 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -python -m grpc.tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/helloworld.proto +"""Runs protoc with the gRPC plugin to generate messages and gRPC stubs.""" + +from grpc.tools import protoc + +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/helloworld.proto', + ) +) diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py index ffcbd061d6e14..8a80ed892dee7 100644 --- a/examples/python/route_guide/route_guide_client.py +++ b/examples/python/route_guide/route_guide_client.py @@ -34,13 +34,11 @@ import random import time -from grpc.beta import implementations +import grpc import route_guide_pb2 import route_guide_resources -_TIMEOUT_SECONDS = 30 - def make_route_note(message, latitude, longitude): return route_guide_pb2.RouteNote( @@ -49,7 +47,7 @@ def make_route_note(message, latitude, longitude): def guide_get_one_feature(stub, point): - feature = stub.GetFeature(point, _TIMEOUT_SECONDS) + feature = stub.GetFeature(point) if not feature.location: print("Server returned incomplete feature") return @@ -66,14 +64,12 @@ def guide_get_feature(stub): def guide_list_features(stub): - rect = route_guide_pb2.Rectangle( - lo=route_guide_pb2.Point( - latitude=400000000, longitude = -750000000), - hi=route_guide_pb2.Point( - latitude = 420000000, longitude = -730000000)) + rectangle = route_guide_pb2.Rectangle( + lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000), + hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000)) print("Looking for features between 40, -75 and 42, -73") - features = stub.ListFeatures(rect, _TIMEOUT_SECONDS) + features = stub.ListFeatures(rectangle) for feature in features: print("Feature called %s at %s" % (feature.name, feature.location)) @@ -90,8 +86,8 @@ def generate_route(feature_list): def guide_record_route(stub): feature_list = route_guide_resources.read_route_guide_database() - route_iter = generate_route(feature_list) - route_summary = stub.RecordRoute(route_iter, _TIMEOUT_SECONDS) + route_iterator = generate_route(feature_list) + route_summary = stub.RecordRoute(route_iterator) print("Finished trip with %s points " % route_summary.point_count) print("Passed %s features " % route_summary.feature_count) print("Travelled %s meters " % route_summary.distance) @@ -113,14 +109,14 @@ def generate_messages(): def guide_route_chat(stub): - responses = stub.RouteChat(generate_messages(), _TIMEOUT_SECONDS) + responses = stub.RouteChat(generate_messages()) for response in responses: print("Received message %s at %s" % (response.message, response.location)) def run(): - channel = implementations.insecure_channel('localhost', 50051) - stub = route_guide_pb2.beta_create_RouteGuide_stub(channel) + channel = grpc.insecure_channel('localhost:50051') + stub = route_guide_pb2.RouteGuideStub(channel) print("-------------- GetFeature --------------") guide_get_feature(stub) print("-------------- ListFeatures --------------") diff --git a/examples/python/route_guide/route_guide_pb2.py b/examples/python/route_guide/route_guide_pb2.py index 81d5d075274f8..924e186e06e4c 100644 --- a/examples/python/route_guide/route_guide_pb2.py +++ b/examples/python/route_guide/route_guide_pb2.py @@ -277,13 +277,122 @@ DESCRIPTOR.has_options = True DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG')) -import abc -import six +import grpc from grpc.beta import implementations as beta_implementations from grpc.beta import interfaces as beta_interfaces from grpc.framework.common import cardinality from grpc.framework.interfaces.face import utilities as face_utilities + +class RouteGuideStub(object): + """Interface exported by the server. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetFeature = channel.unary_unary( + '/routeguide.RouteGuide/GetFeature', + request_serializer=Point.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.ListFeatures = channel.unary_stream( + '/routeguide.RouteGuide/ListFeatures', + request_serializer=Rectangle.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.RecordRoute = channel.stream_unary( + '/routeguide.RouteGuide/RecordRoute', + request_serializer=Point.SerializeToString, + response_deserializer=RouteSummary.FromString, + ) + self.RouteChat = channel.stream_stream( + '/routeguide.RouteGuide/RouteChat', + request_serializer=RouteNote.SerializeToString, + response_deserializer=RouteNote.FromString, + ) + + +class RouteGuideServicer(object): + """Interface exported by the server. + """ + + def GetFeature(self, request, context): + """A simple RPC. + + Obtains the feature at a given position. + + A feature with an empty name is returned if there's no feature at the given + position. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListFeatures(self, request, context): + """A server-to-client streaming RPC. + + Obtains the Features available within the given Rectangle. Results are + streamed rather than returned at once (e.g. in a response message with a + repeated field), as the rectangle may cover a large area and contain a + huge number of features. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RecordRoute(self, request_iterator, context): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RouteChat(self, request_iterator, context): + """A Bidirectional streaming RPC. + + Accepts a stream of RouteNotes sent while a route is being traversed, + while receiving other RouteNotes (e.g. from other users). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_RouteGuideServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetFeature': grpc.unary_unary_rpc_method_handler( + servicer.GetFeature, + request_deserializer=Point.FromString, + response_serializer=Feature.SerializeToString, + ), + 'ListFeatures': grpc.unary_stream_rpc_method_handler( + servicer.ListFeatures, + request_deserializer=Rectangle.FromString, + response_serializer=Feature.SerializeToString, + ), + 'RecordRoute': grpc.stream_unary_rpc_method_handler( + servicer.RecordRoute, + request_deserializer=Point.FromString, + response_serializer=RouteSummary.SerializeToString, + ), + 'RouteChat': grpc.stream_stream_rpc_method_handler( + servicer.RouteChat, + request_deserializer=RouteNote.FromString, + response_serializer=RouteNote.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'routeguide.RouteGuide', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + class BetaRouteGuideServicer(object): """Interface exported by the server. """ @@ -320,10 +429,11 @@ def RouteChat(self, request_iterator, context): """ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + class BetaRouteGuideStub(object): """Interface exported by the server. """ - def GetFeature(self, request, timeout): + def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None): """A simple RPC. Obtains the feature at a given position. @@ -333,7 +443,7 @@ def GetFeature(self, request, timeout): """ raise NotImplementedError() GetFeature.future = None - def ListFeatures(self, request, timeout): + def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None): """A server-to-client streaming RPC. Obtains the Features available within the given Rectangle. Results are @@ -342,7 +452,7 @@ def ListFeatures(self, request, timeout): huge number of features. """ raise NotImplementedError() - def RecordRoute(self, request_iterator, timeout): + def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): """A client-to-server streaming RPC. Accepts a stream of Points on a route being traversed, returning a @@ -350,7 +460,7 @@ def RecordRoute(self, request_iterator, timeout): """ raise NotImplementedError() RecordRoute.future = None - def RouteChat(self, request_iterator, timeout): + def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): """A Bidirectional streaming RPC. Accepts a stream of RouteNotes sent while a route is being traversed, @@ -358,26 +468,19 @@ def RouteChat(self, request_iterator, timeout): """ raise NotImplementedError() + def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 request_deserializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Point.FromString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Rectangle.FromString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.Point.FromString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.FromString, + ('routeguide.RouteGuide', 'GetFeature'): Point.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, } response_serializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Feature.SerializeToString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Feature.SerializeToString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.RouteSummary.SerializeToString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.SerializeToString, + ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, } method_implementations = { ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature), @@ -388,26 +491,19 @@ def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_t server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) return beta_implementations.server(method_implementations, options=server_options) + def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 request_serializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Point.SerializeToString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Rectangle.SerializeToString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.Point.SerializeToString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.SerializeToString, + ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, } response_deserializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Feature.FromString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Feature.FromString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.RouteSummary.FromString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.FromString, + ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, } cardinalities = { 'GetFeature': cardinality.Cardinality.UNARY_UNARY, diff --git a/examples/python/route_guide/route_guide_resources.py b/examples/python/route_guide/route_guide_resources.py old mode 100755 new mode 100644 diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py index 2d8b33ac1783e..4e780a70a1910 100644 --- a/examples/python/route_guide/route_guide_server.py +++ b/examples/python/route_guide/route_guide_server.py @@ -29,9 +29,12 @@ """The Python implementation of the gRPC route guide server.""" +from concurrent import futures import time import math +import grpc + import route_guide_pb2 import route_guide_resources @@ -121,7 +124,9 @@ def RouteChat(self, request_iterator, context): def serve(): - server = route_guide_pb2.beta_create_RouteGuide_server(RouteGuideServicer()) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + route_guide_pb2.add_RouteGuideServicer_to_server( + RouteGuideServicer(), server) server.add_insecure_port('[::]:50051') server.start() try: diff --git a/examples/python/route_guide/run_codegen.sh b/examples/python/route_guide/run_codegen.py old mode 100755 new mode 100644 similarity index 86% rename from examples/python/route_guide/run_codegen.sh rename to examples/python/route_guide/run_codegen.py index a377a1ab40903..c7c60085809a9 --- a/examples/python/route_guide/run_codegen.sh +++ b/examples/python/route_guide/run_codegen.py @@ -1,4 +1,3 @@ -#!/bin/bash # Copyright 2015, Google Inc. # All rights reserved. # @@ -28,5 +27,16 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -python -m grpc.tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/route_guide.proto +"""Runs protoc with the gRPC plugin to generate messages and gRPC stubs.""" + +from grpc.tools import protoc + +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/route_guide.proto', + ) +) From e04089e7c043e34e79bd077ca9a8c0b98d6c9ec7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 15 Jul 2016 16:35:20 -0700 Subject: [PATCH 050/151] Establish Objective C end-to-end core test with Cronet --- gRPC-Core.podspec | 2 + .../CoreCronetEnd2EndTests.m | 15 +----- .../tests/CoreCronetEnd2EndTests/h2_ssl.h | 46 +++++++++++++++---- src/objective-c/tests/Podfile | 3 +- .../tests/Tests.xcodeproj/project.pbxproj | 2 + 5 files changed, 43 insertions(+), 25 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4811abf698bae..0678f3b3ae7df 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -101,6 +101,8 @@ Pod::Spec.new do |s| 'ALWAYS_SEARCH_USER_PATHS' => 'NO', } + s.default_subspecs = 'Interface', 'Implementation' + # Like many other C libraries, gRPC-Core has its public headers under `include//` and its # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index 1703b5265e53e..5d501602d908f 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -32,28 +32,15 @@ */ #import +#include "./h2_ssl.h" @interface CoreCronetEnd2EndTests : XCTestCase @end -int main(int argc, char **argv); - @implementation CoreCronetEnd2EndTests -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - - (void)testCoreCronetEnd2End { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. char *argv[] = {"h2_ssl"}; main(1, argv); } diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h index a7f2bd724a37f..3aa0a05ddadef 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h @@ -1,13 +1,39 @@ -// -// h2_ssl.h -// Tests -// -// Created by Muxi Yan on 7/15/16. -// Copyright © 2016 gRPC. All rights reserved. -// +/* + * + * 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 h2_ssl_h -#define h2_ssl_h +#ifndef GRPC_H2_SSL_H +#define GRPC_H2_SSL_H +int main(int argc, char **argv); -#endif /* h2_ssl_h */ +#endif /* GRPC_H2_SSL_H */ \ No newline at end of file diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 546017c9f78a7..db11208a1bb70 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -27,6 +27,7 @@ GRPC_LOCAL_SRC = '../../..' pod 'gRPC-Core', :path => GRPC_LOCAL_SRC pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC + pod 'RemoteTest', :path => "RemoteTestClient" end end @@ -74,7 +75,7 @@ post_install do |installer| target.build_configurations.each do |config| config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' end - if target.name == 'gRPC-Core' + if target.name == 'gRPC-Core' or target.name == 'gRPC-Core.default-Cronet-Interface-Cronet-Tests' target.build_configurations.each do |config| # TODO(zyc): Remove this setting after the issue is resolved # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 4aa5b1bdbe4ec..4161dcc43cf44 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -113,6 +113,7 @@ 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl.m; sourceTree = ""; }; + 5ED3173E1D397C7500C613BD /* h2_ssl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = h2_ssl.h; sourceTree = ""; }; 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; 63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = ""; }; @@ -252,6 +253,7 @@ isa = PBXGroup; children = ( 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */, + 5ED3173E1D397C7500C613BD /* h2_ssl.h */, 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */, ); path = CoreCronetEnd2EndTests; From 3a9ba6bd53cdf5b4ae471f17c366b1010a16e549 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Sat, 16 Jul 2016 10:14:56 +0800 Subject: [PATCH 051/151] delete some commits which not need --- tools/run_tests/sanity/check_orig_mk.sh | 39 ------------------------ tools/run_tests/sanity/sanity_tests.yaml | 1 - 2 files changed, 40 deletions(-) delete mode 100755 tools/run_tests/sanity/check_orig_mk.sh diff --git a/tools/run_tests/sanity/check_orig_mk.sh b/tools/run_tests/sanity/check_orig_mk.sh deleted file mode 100755 index 142ef009ace39..0000000000000 --- a/tools/run_tests/sanity/check_orig_mk.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/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 - -if [ -f *.orig ] ; then - echo "Please don't commit *.orig file" - exit 1 -fi - diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index dde05131cd243..e699c5194df8f 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -1,6 +1,5 @@ # a set of tests that are run in parallel for sanity tests - script: tools/run_tests/sanity/check_cache_mk.sh -- script: tools/run_tests/sanity/check_orig_mk.sh - script: tools/run_tests/sanity/check_sources_and_headers.py - script: tools/run_tests/sanity/check_submodules.sh - script: tools/buildgen/generate_projects.sh -j 3 From 93bd780a9c3d9c38dc8f79efe663d0ffd169187d Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:08:42 -0700 Subject: [PATCH 052/151] Solve warnings by adding headers not included by grpc.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two log.h can’t be listed, though, as they include the nefarious (See discussing at BoringSSL.podspec). Not listing them seems to be alright, though. --- include/grpc/module.modulemap | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap index ae11a78b74a2f..02fb2f39b20be 100644 --- a/include/grpc/module.modulemap +++ b/include/grpc/module.modulemap @@ -1,5 +1,15 @@ framework module grpc { umbrella header "grpc.h" + + header "byte_buffer_reader.h" + header "grpc_security.h" + header "grpc_security_constants.h" + header "impl/codegen/alloc.h" + header "impl/codegen/byte_buffer_reader.h" + header "support/alloc.h" + header "support/port_platform.h" + header "support/string_util.h" + export * module * { export * } } From 7ed4fb7e3c87516e57bef16df2aff391767c16ac Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:09:59 -0700 Subject: [PATCH 053/151] Use google/protobuf/empty.proto in the sample apps --- .../examples/RemoteTestClient/empty.proto | 44 ------------------- .../examples/RemoteTestClient/test.proto | 4 +- 2 files changed, 2 insertions(+), 46 deletions(-) delete mode 100644 src/objective-c/examples/RemoteTestClient/empty.proto diff --git a/src/objective-c/examples/RemoteTestClient/empty.proto b/src/objective-c/examples/RemoteTestClient/empty.proto deleted file mode 100644 index a678048289e2f..0000000000000 --- a/src/objective-c/examples/RemoteTestClient/empty.proto +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package grpc.testing; - -option objc_class_prefix = "RMT"; - -// An empty message that you can re-use to avoid defining duplicated empty -// messages in your project. A typical example is to use it as argument or the -// return value of a service API. For instance: -// -// service Foo { -// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; -// }; -// -message Empty {} diff --git a/src/objective-c/examples/RemoteTestClient/test.proto b/src/objective-c/examples/RemoteTestClient/test.proto index 514c3b80955fc..5c359c5c1296e 100644 --- a/src/objective-c/examples/RemoteTestClient/test.proto +++ b/src/objective-c/examples/RemoteTestClient/test.proto @@ -31,7 +31,7 @@ // of unary/streaming requests/responses. syntax = "proto3"; -import "empty.proto"; +import "google/protobuf/empty.proto"; import "messages.proto"; package grpc.testing; @@ -42,7 +42,7 @@ option objc_class_prefix = "RMT"; // performance with various types of payload. service TestService { // One empty request followed by one empty response. - rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty); + rpc EmptyCall(google.protobuf.Empty) returns (google.protobuf.Empty); // One request followed by one response. rpc UnaryCall(SimpleRequest) returns (SimpleResponse); From 4a72356bd339993952090fcf8849bb46f53306e8 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:11:48 -0700 Subject: [PATCH 054/151] SwiftSample: always use frameworks --- .../examples/SwiftSample/Bridging-Header.h | 45 ------------------- src/objective-c/examples/SwiftSample/Podfile | 2 + .../SwiftSample.xcodeproj/project.pbxproj | 16 +++---- .../examples/SwiftSample/ViewController.swift | 2 + 4 files changed, 11 insertions(+), 54 deletions(-) delete mode 100644 src/objective-c/examples/SwiftSample/Bridging-Header.h diff --git a/src/objective-c/examples/SwiftSample/Bridging-Header.h b/src/objective-c/examples/SwiftSample/Bridging-Header.h deleted file mode 100644 index 65f768a760b4f..0000000000000 --- a/src/objective-c/examples/SwiftSample/Bridging-Header.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * 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 SwiftSample_Bridging_Header_h -#define SwiftSample_Bridging_Header_h - -#import -#import -#import -#import -#import -#import -#import - -#endif diff --git a/src/objective-c/examples/SwiftSample/Podfile b/src/objective-c/examples/SwiftSample/Podfile index 2f783340f56c1..b08a346ae2a38 100644 --- a/src/objective-c/examples/SwiftSample/Podfile +++ b/src/objective-c/examples/SwiftSample/Podfile @@ -3,6 +3,8 @@ platform :ios, '8.0' install! 'cocoapods', :deterministic_uuids => false +use_frameworks! + # Location of gRPC's repo root relative to this file. GRPC_LOCAL_SRC = '../../../..' diff --git a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj index 2a1b30f2cf9fa..e3811bc82a837 100644 --- a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj +++ b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj @@ -7,11 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 2C0B024CB798839E17F76126 /* Pods_SwiftSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B394F343BDE186C5436DBDB9 /* Pods_SwiftSample.framework */; }; 633BFFC81B950B210007E424 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633BFFC71B950B210007E424 /* AppDelegate.swift */; }; 633BFFCA1B950B210007E424 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633BFFC91B950B210007E424 /* ViewController.swift */; }; 633BFFCD1B950B210007E424 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 633BFFCB1B950B210007E424 /* Main.storyboard */; }; 633BFFCF1B950B210007E424 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 633BFFCE1B950B210007E424 /* Images.xcassets */; }; - 92EDB1408A1E1E7DDAB25D9C /* libPods-SwiftSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69BB5C6CA3C1F97E007AC527 /* libPods-SwiftSample.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -21,9 +21,8 @@ 633BFFC91B950B210007E424 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 633BFFCC1B950B210007E424 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 633BFFCE1B950B210007E424 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6367AD231B951655007FD3A4 /* Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = ""; }; - 69BB5C6CA3C1F97E007AC527 /* libPods-SwiftSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SwiftSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A7E614A494D89D01BB395761 /* Pods-SwiftSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftSample/Pods-SwiftSample.debug.xcconfig"; sourceTree = ""; }; + B394F343BDE186C5436DBDB9 /* Pods_SwiftSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftSample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C314E3E246AF23AC29B38FCF /* Pods-SwiftSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftSample/Pods-SwiftSample.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -32,7 +31,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 92EDB1408A1E1E7DDAB25D9C /* libPods-SwiftSample.a in Frameworks */, + 2C0B024CB798839E17F76126 /* Pods_SwiftSample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -74,7 +73,6 @@ 633BFFCB1B950B210007E424 /* Main.storyboard */, 633BFFCE1B950B210007E424 /* Images.xcassets */, 633BFFC51B950B210007E424 /* Supporting Files */, - 6367AD231B951655007FD3A4 /* Bridging-Header.h */, ); name = SwiftSample; sourceTree = SOURCE_ROOT; @@ -90,7 +88,7 @@ 9D63A7F6423989BA306810CA /* Frameworks */ = { isa = PBXGroup; children = ( - 69BB5C6CA3C1F97E007AC527 /* libPods-SwiftSample.a */, + B394F343BDE186C5436DBDB9 /* Pods_SwiftSample.framework */, ); name = Frameworks; sourceTree = ""; @@ -125,7 +123,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0710; - LastUpgradeCheck = 0640; + LastUpgradeCheck = 0730; ORGANIZATIONNAME = gRPC; TargetAttributes = { 633BFFC11B950B210007E424 = { @@ -326,7 +324,7 @@ INFOPLIST_FILE = Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = ""; USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; @@ -339,7 +337,7 @@ INFOPLIST_FILE = Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = ""; USER_HEADER_SEARCH_PATHS = ""; }; name = Release; diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index 2a95d2de51690..000a6faf59363 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -33,6 +33,8 @@ import UIKit +import RemoteTest + class ViewController: UIViewController { override func viewDidLoad() { From f4df3d2d02701c614c7b7155d3553eb2b3675953 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:14:35 -0700 Subject: [PATCH 055/151] =?UTF-8?q?Don=E2=80=99t=20care=20about=20installe?= =?UTF-8?q?d=20protoc=20in=20the=20test=20scripts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/objective-c/tests/build_example_test.sh | 18 ------------------ src/objective-c/tests/build_tests.sh | 21 --------------------- src/objective-c/tests/run_tests.sh | 12 ++++++++++-- 3 files changed, 10 insertions(+), 41 deletions(-) diff --git a/src/objective-c/tests/build_example_test.sh b/src/objective-c/tests/build_example_test.sh index 5c3766b4c0bd9..ea262c61f40b5 100755 --- a/src/objective-c/tests/build_example_test.sh +++ b/src/objective-c/tests/build_example_test.sh @@ -35,40 +35,22 @@ set -eo pipefail cd `dirname $0` -BINDIR=`pwd`/../../../bins/$CONFIG -TMP_PATH=$PATH - -# If `protoc` is not found, add bins/$CONFIG/protobuf/protoc to the search path -hash protoc 2>/dev/null || TMP_PATH=$BINDIR/protobuf:$TMP_PATH - -# If `protoc-gen-objcgrpc` is not found, make a symlink from -# bins/$CONGIF/grpc_objective_c_plugin and add it to the search path -PATH=$TMP_PATH hash protoc-gen-objcgrpc 2>/dev/null || { - ln -sf $BINDIR/grpc_objective_c_plugin $BINDIR/protoc-gen-objcgrpc - TMP_PATH=$BINDIR:$TMP_PATH -} - SCHEME=HelloWorld \ EXAMPLE_PATH=examples/objective-c/helloworld \ - PATH=$TMP_PATH \ ./build_one_example.sh SCHEME=RouteGuideClient \ EXAMPLE_PATH=examples/objective-c/route_guide \ - PATH=$TMP_PATH \ ./build_one_example.sh SCHEME=AuthSample \ EXAMPLE_PATH=examples/objective-c/auth_sample \ - PATH=$TMP_PATH \ ./build_one_example.sh SCHEME=Sample \ EXAMPLE_PATH=src/objective-c/examples/Sample \ - PATH=$TMP_PATH \ ./build_one_example.sh SCHEME=SwiftSample \ EXAMPLE_PATH=src/objective-c/examples/SwiftSample \ - PATH=$TMP_PATH \ ./build_one_example.sh diff --git a/src/objective-c/tests/build_tests.sh b/src/objective-c/tests/build_tests.sh index 8547bfd3a83dc..0afa819db23ea 100755 --- a/src/objective-c/tests/build_tests.sh +++ b/src/objective-c/tests/build_tests.sh @@ -44,26 +44,5 @@ hash xcodebuild 2>/dev/null || { exit 1 } -BINDIR=../../../bins/$CONFIG - -if [ ! -f $BINDIR/protobuf/protoc ]; then - hash protoc 2>/dev/null || { - echo >&2 "Can't find protoc. Make sure run_tests.py is making" \ - "grpc_objective_c_plugin before calling this script." - exit 1 - } - # When protoc is already installed, make doesn't compile one. Put a link - # there so the podspecs can do codegen using that path. - mkdir -p $BINDIR/protobuf - ln -s `which protoc` $BINDIR/protobuf/protoc -fi - -[ -f $BINDIR/interop_server ] || { - echo >&2 "Can't find the test server. Make sure run_tests.py is making" \ - "interop_server before calling this script. It needs to be done" \ - "before because pod install of gRPC renames some C gRPC files" \ - "and not the server's code references to them." - exit 1 -} pod install diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index c4fc5644f284c..9ad2aa1ca7561 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -36,8 +36,16 @@ set -e cd $(dirname $0) # Run the tests server. -../../../bins/$CONFIG/interop_server --port=5050 & -../../../bins/$CONFIG/interop_server --port=5051 --use_tls & + +BINDIR=../../../bins/$CONFIG + +[ -f $BINDIR/interop_server ] || { + echo >&2 "Can't find the test server. Make sure run_tests.py is making" \ + "interop_server before calling this script." + exit 1 +} +$BINDIR/interop_server --port=5050 & +$BINDIR/interop_server --port=5051 --use_tls & # Kill them when this script exits. trap 'kill -9 `jobs -p`' EXIT From 545bad349cb7979a66e265b0ab8eda498c84f94e Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:16:32 -0700 Subject: [PATCH 056/151] Misc test scripts cleanup: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Echo commands - Remove generated code before pod install - Don’t “clean” before “build” --- src/objective-c/tests/build_example_test.sh | 4 +++- src/objective-c/tests/build_one_example.sh | 4 ++-- src/objective-c/tests/build_tests.sh | 5 +++++ src/objective-c/tests/run_tests.sh | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/build_example_test.sh b/src/objective-c/tests/build_example_test.sh index ea262c61f40b5..756475c9322da 100755 --- a/src/objective-c/tests/build_example_test.sh +++ b/src/objective-c/tests/build_example_test.sh @@ -31,7 +31,7 @@ # Don't run this script standalone. Instead, run from the repository root: # ./tools/run_tests/run_tests.py -l objc -set -eo pipefail +set -evo pipefail cd `dirname $0` @@ -47,6 +47,8 @@ SCHEME=AuthSample \ EXAMPLE_PATH=examples/objective-c/auth_sample \ ./build_one_example.sh +rm -f ../examples/RemoteTestClient/*.{h,m} + SCHEME=Sample \ EXAMPLE_PATH=src/objective-c/examples/Sample \ ./build_one_example.sh diff --git a/src/objective-c/tests/build_one_example.sh b/src/objective-c/tests/build_one_example.sh index 24fb8b7bab44d..9fef6582a38b5 100755 --- a/src/objective-c/tests/build_one_example.sh +++ b/src/objective-c/tests/build_one_example.sh @@ -31,7 +31,7 @@ # Don't run this script standalone. Instead, run from the repository root: # ./tools/run_tests/run_tests.py -l objc -set -e +set -ev # Params: # EXAMPLE_PATH - directory of the example @@ -54,7 +54,7 @@ pod install set -o pipefail XCODEBUILD_FILTER='(^===|^\*\*|\bfatal\b|\berror\b|\bwarning\b|\bfail)' xcodebuild \ - clean build \ + build \ -workspace *.xcworkspace \ -scheme $SCHEME \ -destination name="iPhone 6" \ diff --git a/src/objective-c/tests/build_tests.sh b/src/objective-c/tests/build_tests.sh index 0afa819db23ea..bc5bc0449436d 100755 --- a/src/objective-c/tests/build_tests.sh +++ b/src/objective-c/tests/build_tests.sh @@ -44,5 +44,10 @@ hash xcodebuild 2>/dev/null || { exit 1 } +# clean the directory +rm -rf Pods +rm -rf Tests.xcworkspace +rm -f Podfile.lock +rm -f RemoteTestClient/*.{h,m} pod install diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 9ad2aa1ca7561..a265149f488a3 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -31,7 +31,7 @@ # Don't run this script standalone. Instead, run from the repository root: # ./tools/run_tests/run_tests.py -l objc -set -e +set -ev cd $(dirname $0) From 7f097a14c2a3bf3c1681e0638ed2d5612abde926 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:17:57 -0700 Subject: [PATCH 057/151] Build sample app both with and without frameworks --- src/objective-c/examples/Sample/Podfile | 2 ++ .../examples/Sample/Sample.xcodeproj/project.pbxproj | 10 +++++----- src/objective-c/tests/build_example_test.sh | 5 +++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile index 8740b2f96382e..f6f0c00d5d057 100644 --- a/src/objective-c/examples/Sample/Podfile +++ b/src/objective-c/examples/Sample/Podfile @@ -3,6 +3,8 @@ platform :ios, '8.0' install! 'cocoapods', :deterministic_uuids => false +use_frameworks! if ENV['FRAMEWORKS'] == 'YES' + # Location of gRPC's repo root relative to this file. GRPC_LOCAL_SRC = '../../../..' diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj index 5c2a6d14f96ee..cb2f479e696f5 100644 --- a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj +++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 426A5020E0E158A101BCA1D9 /* libPods-Sample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C20055928615A6F8434E26B4 /* libPods-Sample.a */; }; + 3F035697392F601049D3DDE1 /* Pods_Sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC1B27EA0C428429B07BC34B /* Pods_Sample.framework */; }; 6369A2701A9322E20015FC5C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A26F1A9322E20015FC5C /* main.m */; }; 6369A2731A9322E20015FC5C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2721A9322E20015FC5C /* AppDelegate.m */; }; 6369A2761A9322E20015FC5C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2751A9322E20015FC5C /* ViewController.m */; }; @@ -26,7 +26,7 @@ 6369A2751A9322E20015FC5C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 6369A2781A9322E20015FC5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 6369A27A1A9322E20015FC5C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - C20055928615A6F8434E26B4 /* libPods-Sample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Sample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CC1B27EA0C428429B07BC34B /* Pods_Sample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Sample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E3C01DF315C4E7433BCEC6E6 /* Pods-Sample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -35,7 +35,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 426A5020E0E158A101BCA1D9 /* libPods-Sample.a in Frameworks */, + 3F035697392F601049D3DDE1 /* Pods_Sample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -95,7 +95,7 @@ C4C2C5219053E079C9EFB930 /* Frameworks */ = { isa = PBXGroup; children = ( - C20055928615A6F8434E26B4 /* libPods-Sample.a */, + CC1B27EA0C428429B07BC34B /* Pods_Sample.framework */, ); name = Frameworks; sourceTree = ""; @@ -129,7 +129,7 @@ 6369A2621A9322E20015FC5C /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0610; + LastUpgradeCheck = 0730; ORGANIZATIONNAME = gRPC; TargetAttributes = { 6369A2691A9322E20015FC5C = { diff --git a/src/objective-c/tests/build_example_test.sh b/src/objective-c/tests/build_example_test.sh index 756475c9322da..ae75941ec613f 100755 --- a/src/objective-c/tests/build_example_test.sh +++ b/src/objective-c/tests/build_example_test.sh @@ -53,6 +53,11 @@ SCHEME=Sample \ EXAMPLE_PATH=src/objective-c/examples/Sample \ ./build_one_example.sh +SCHEME=Sample \ + EXAMPLE_PATH=src/objective-c/examples/Sample \ + FRAMEWORKS=YES \ + ./build_one_example.sh + SCHEME=SwiftSample \ EXAMPLE_PATH=src/objective-c/examples/SwiftSample \ ./build_one_example.sh From 57dab9281123532c4e1b357b1ac75b20df644374 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:18:43 -0700 Subject: [PATCH 058/151] Sample app: solve XCode config warnings --- .../examples/Sample/Sample.xcodeproj/project.pbxproj | 3 +++ src/objective-c/examples/Sample/Sample/Info.plist | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj index cb2f479e696f5..ab7159cda2f80 100644 --- a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj +++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj @@ -260,6 +260,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -325,6 +326,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Sample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -336,6 +338,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Sample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/src/objective-c/examples/Sample/Sample/Info.plist b/src/objective-c/examples/Sample/Sample/Info.plist index 4436635ab4e1f..2cdf09dc2fc55 100644 --- a/src/objective-c/examples/Sample/Sample/Info.plist +++ b/src/objective-c/examples/Sample/Sample/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - org.grpc.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName From ac06cf09bec8a1e46214311924c5052c719682a1 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:18:52 -0700 Subject: [PATCH 059/151] SwiftSample app: solve XCode config warnings --- src/objective-c/examples/SwiftSample/Info.plist | 2 +- .../examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/objective-c/examples/SwiftSample/Info.plist b/src/objective-c/examples/SwiftSample/Info.plist index 10f0450b346e2..2cdf09dc2fc55 100644 --- a/src/objective-c/examples/SwiftSample/Info.plist +++ b/src/objective-c/examples/SwiftSample/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - io.grpc.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj index e3811bc82a837..afc3da71168c9 100644 --- a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj +++ b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj @@ -254,6 +254,7 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -323,6 +324,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = ""; USER_HEADER_SEARCH_PATHS = ""; @@ -336,6 +338,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = ""; USER_HEADER_SEARCH_PATHS = ""; From d7f0e877085ed96db10cba137bed2b4afae46f6a Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:19:14 -0700 Subject: [PATCH 060/151] Sample app: ProtoMethod -> GRPCProtoMethod --- src/objective-c/examples/Sample/Sample/ViewController.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/examples/Sample/Sample/ViewController.m b/src/objective-c/examples/Sample/Sample/ViewController.m index 433a8a2ba3bc1..70244ee62dd77 100644 --- a/src/objective-c/examples/Sample/Sample/ViewController.m +++ b/src/objective-c/examples/Sample/Sample/ViewController.m @@ -66,9 +66,9 @@ - (void)viewDidLoad { // Same example call using the generic gRPC client library: - ProtoMethod *method = [[ProtoMethod alloc] initWithPackage:@"grpc.testing" - service:@"TestService" - method:@"UnaryCall"]; + GRPCProtoMethod *method = [[GRPCProtoMethod alloc] initWithPackage:@"grpc.testing" + service:@"TestService" + method:@"UnaryCall"]; GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]]; From a5e86f3aef6c89b4f0588f20732d237adc633e96 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:19:30 -0700 Subject: [PATCH 061/151] SwiftSample app: ProtoMethod -> GRPCProtoMethod, etc. --- src/objective-c/examples/SwiftSample/ViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index 000a6faf59363..e7bab137620db 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -62,7 +62,7 @@ class ViewController: UIViewController { // Same but manipulating headers: - var RPC : ProtoRPC! // Needed to convince Swift to capture by reference (__block) + var RPC : GRPCProtoCall! // Needed to convince Swift to capture by reference (__block) RPC = service.RPCToUnaryCallWithRequest(request) { response, error in if let response = response { NSLog("2. Finished successfully with response:\n\(response)") @@ -81,7 +81,7 @@ class ViewController: UIViewController { // Same example call using the generic gRPC client library: - let method = ProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall") + let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall") let requestsWriter = GRXWriter(value: request.data()) From 8e428073a54e0647f7ad8f9095c19aac1f91180a Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:25:08 -0700 Subject: [PATCH 062/151] travis.yml: format spacing to highlight test scheme --- .travis.yml | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4cdad37c6c52d..c5ffd1e131d88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,33 +8,34 @@ env: - TEST=objc - JOBS=1 matrix: - - SCHEME="RxLibraryUnitTests" WORKSPACE="Tests.xcworkspace" - TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + - SCHEME="RxLibraryUnitTests" + WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" INTEROP_SERVER="false" - - SCHEME="InteropTestsLocalSSL" WORKSPACE="Tests.xcworkspace" - TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" INTEROP_SERVER="true" - - SCHEME="InteropTestsLocalCleartext" WORKSPACE="Tests.xcworkspace" - TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + - SCHEME="InteropTestsLocalSSL" + WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + INTEROP_SERVER="true" + - SCHEME="InteropTestsLocalCleartext" + WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" INTEROP_SERVER="true" # TODO(jcanizales): Make tests an app project (instead of library), so the following will work. - # - SCHEME="InteropTestsRemote" WORKSPACE="Tests.xcworkspace" - # TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + # - SCHEME="InteropTestsRemote" + # WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" # INTEROP_SERVER="true" - - SCHEME="HelloWorld" WORKSPACE="HelloWorld.xcworkspace" - TEST_PATH="examples/objective-c/helloworld" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="RouteGuideClient" WORKSPACE="RouteGuideClient.xcworkspace" - TEST_PATH="examples/objective-c/route_guide" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="AuthSample" WORKSPACE="AuthSample.xcworkspace" - TEST_PATH="examples/objective-c/auth_sample" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="Sample" WORKSPACE="Sample.xcworkspace" - TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="SwiftSample" WORKSPACE="SwiftSample.xcworkspace" - TEST_PATH="src/objective-c/examples/SwiftSample" BUILD_ONLY="true" + - SCHEME="HelloWorld" + WORKSPACE="HelloWorld.xcworkspace" TEST_PATH="examples/objective-c/helloworld" + BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="RouteGuideClient" + WORKSPACE="RouteGuideClient.xcworkspace" TEST_PATH="examples/objective-c/route_guide" + BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="AuthSample" + WORKSPACE="AuthSample.xcworkspace" TEST_PATH="examples/objective-c/auth_sample" + BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="Sample" + WORKSPACE="Sample.xcworkspace" TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="SwiftSample" + WORKSPACE="SwiftSample.xcworkspace" TEST_PATH="src/objective-c/examples/SwiftSample" + BUILD_ONLY="true" INTEROP_SERVER="false" before_install: # Until Travis upgrades from Cocoapods 0.39, we need to do it here. - pod --version From 10726f0421a0e0ce83b9832c8ba387df93aec5b9 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 15 Jul 2016 23:25:47 -0700 Subject: [PATCH 063/151] Have Travis build the Sample app with frameworks too --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index c5ffd1e131d88..94bf382b25ea7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,9 @@ env: - SCHEME="Sample" WORKSPACE="Sample.xcworkspace" TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="Sample" + WORKSPACE="Sample.xcworkspace" TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true" + INTEROP_SERVER="false" FRAMEWORKS="YES" - SCHEME="SwiftSample" WORKSPACE="SwiftSample.xcworkspace" TEST_PATH="src/objective-c/examples/SwiftSample" BUILD_ONLY="true" INTEROP_SERVER="false" From 302bfd1a108c048a1db81236acc0c41fb84ae3b5 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Wed, 13 Jul 2016 16:53:09 -0700 Subject: [PATCH 064/151] Test Python source distribution installation --- test/distrib/python/run_distrib_test.sh | 55 +++++++++++++++---------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/test/distrib/python/run_distrib_test.sh b/test/distrib/python/run_distrib_test.sh index 8a983bc248809..0c2154838ff20 100755 --- a/test/distrib/python/run_distrib_test.sh +++ b/test/distrib/python/run_distrib_test.sh @@ -33,34 +33,47 @@ set -ex cd $(dirname $0) # Pick up the source dist archive whatever its version is +SDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio-*.tar.gz BDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio-*.whl +TOOLS_SDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio_tools-*.tar.gz TOOLS_BDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio_tools-*.whl -if [ ! -f ${SDIST_ARCHIVE} ] -then - echo "Archive ${SDIST_ARCHIVE} does not exist." - exit 1 -fi +function make_virtualenv() { + virtualenv $1 + $1/bin/python -m pip install --upgrade six pip + $1/bin/python -m pip install cython +} -PYTHON=python2 -PIP=pip2 -which $PYTHON || PYTHON=python -which $PIP || PIP=pip +function at_least_one_installs() { + for file in "$@"; do + if python -m pip install $file; then + return 0 + fi + done + return -1 +} -# TODO(jtattermusch): this shouldn't be required -# TODO(jtattermusch): run the command twice to workaround docker-on-overlay -# issue https://github.com/docker/docker/issues/12327 -# (first attempt will fail when using docker with overlayFS) -${PIP} install --upgrade six pip || ${PIP} install --upgrade six pip +make_virtualenv bdist_test +make_virtualenv sdist_test -# At least one of the bdist packages has to succeed (whichever one matches the -# test machine, anyway). -for bdist in ${BDIST_ARCHIVES} ${TOOLS_BDIST_ARCHIVES}; do - ($PYTHON -m pip install $bdist) || true -done +# +# Install our distributions in order of dependencies +# + +(source bdist_test/bin/activate && at_least_one_installs ${BDIST_ARCHIVES}) +(source bdist_test/bin/activate && at_least_one_installs ${TOOLS_BDIST_ARCHIVES}) + +(source sdist_test/bin/activate && at_least_one_installs ${SDIST_ARCHIVES}) +(source sdist_test/bin/activate && at_least_one_installs ${TOOLS_SDIST_ARCHIVES}) + +# +# Test our distributions +# # TODO(jtattermusch): add a .proto file to the distribtest, generate python # code from it and then use the generated code from distribtest.py -$PYTHON -m grpc.tools.protoc +(source bdist_test/bin/activate && python -m grpc.tools.protoc --help) +(source sdist_test/bin/activate && python -m grpc.tools.protoc --help) -$PYTHON distribtest.py +(source bdist_test/bin/activate && python distribtest.py) +(source sdist_test/bin/activate && python distribtest.py) From e917486753fc5a995635ee54c8959dd31bbb9319 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Thu, 14 Jul 2016 14:34:39 -0700 Subject: [PATCH 065/151] Install virtualenv in Python distribtest Dockerfiles --- tools/dockerfile/distribtest/python_arch_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/python_centos6_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_centos7_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_fedora22_x64/Dockerfile | 1 + tools/dockerfile/distribtest/python_fedora23_x64/Dockerfile | 1 + tools/dockerfile/distribtest/python_jessie_x64/Dockerfile | 1 + tools/dockerfile/distribtest/python_jessie_x86/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_opensuse_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_ubuntu1204_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_ubuntu1404_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_ubuntu1504_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_ubuntu1510_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_ubuntu1604_x64/Dockerfile | 2 ++ tools/dockerfile/distribtest/python_wheezy_x64/Dockerfile | 2 ++ 16 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tools/dockerfile/distribtest/python_arch_x64/Dockerfile b/tools/dockerfile/distribtest/python_arch_x64/Dockerfile index 2f79cc3017aa9..dff72eee97a88 100644 --- a/tools/dockerfile/distribtest/python_arch_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_arch_x64/Dockerfile @@ -33,4 +33,4 @@ RUN pacman --noconfirm -Syy RUN pacman --noconfirm -S openssl RUN pacman --noconfirm -S python2 RUN pacman --noconfirm -S python2-pip - +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/python_centos6_x64/Dockerfile index d4f473792e1b6..967450156cdb9 100644 --- a/tools/dockerfile/distribtest/python_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_centos6_x64/Dockerfile @@ -44,3 +44,5 @@ RUN curl https://bootstrap.pypa.io/get-pip.py | python - # "which" command required by python's run_distrib_test.sh RUN yum install -y which + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/python_centos7_x64/Dockerfile index ca64fa7bea932..0127fe1e28b77 100644 --- a/tools/dockerfile/distribtest/python_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_centos7_x64/Dockerfile @@ -32,4 +32,4 @@ FROM centos:7 RUN yum install -y python RUN yum install -y epel-release RUN yum install -y python-pip - +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile index 8b0f769c2638a..3d3636e43da7d 100644 --- a/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile @@ -35,3 +35,5 @@ RUN yum clean all && yum update -y && yum install -y python python-pip # Trying twice makes it work fine. # https://github.com/docker/docker/issues/10180 RUN pip install --upgrade six || pip install --upgrade six + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile index fcbe053f1fc20..0b1b6aeb350ea 100644 --- a/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile @@ -40,3 +40,5 @@ RUN yum clean all && yum update -y && yum install -y python python-pip # Trying twice makes it work fine. # https://github.com/docker/docker/issues/10180 RUN pip2 install --upgrade six || pip2 install --upgrade six + +RUN pip2 install virtualenv diff --git a/tools/dockerfile/distribtest/python_fedora22_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora22_x64/Dockerfile index ddcacb4257d7a..4d75034c158d5 100644 --- a/tools/dockerfile/distribtest/python_fedora22_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_fedora22_x64/Dockerfile @@ -30,3 +30,4 @@ FROM fedora:22 RUN yum clean all && yum update -y && yum install -y python python-pip +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_fedora23_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora23_x64/Dockerfile index d45195e509c8f..a1bc9ba8d6e6c 100644 --- a/tools/dockerfile/distribtest/python_fedora23_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_fedora23_x64/Dockerfile @@ -30,3 +30,4 @@ FROM fedora:23 RUN yum clean all && yum update -y && yum install -y python python-pip +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_jessie_x64/Dockerfile b/tools/dockerfile/distribtest/python_jessie_x64/Dockerfile index 83df4ed4fae9b..7dc32a088edb4 100644 --- a/tools/dockerfile/distribtest/python_jessie_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_jessie_x64/Dockerfile @@ -30,3 +30,4 @@ FROM debian:jessie RUN apt-get update && apt-get install -y python python-pip +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_jessie_x86/Dockerfile b/tools/dockerfile/distribtest/python_jessie_x86/Dockerfile index 19addb29120ce..04c1402e722d9 100644 --- a/tools/dockerfile/distribtest/python_jessie_x86/Dockerfile +++ b/tools/dockerfile/distribtest/python_jessie_x86/Dockerfile @@ -31,6 +31,8 @@ FROM 32bit/debian:jessie RUN apt-get update && apt-get install -y python python-pip +RUN pip install virtualenv + # docker is running on a 64-bit machine, so we need to # override "uname -m" to report i686 instead of x86_64, otherwise # python will choose a wrong binary package to install. diff --git a/tools/dockerfile/distribtest/python_opensuse_x64/Dockerfile b/tools/dockerfile/distribtest/python_opensuse_x64/Dockerfile index fe1406be98c97..27159c72e339a 100644 --- a/tools/dockerfile/distribtest/python_opensuse_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_opensuse_x64/Dockerfile @@ -38,3 +38,5 @@ RUN zypper --non-interactive install which # Without this, pip won't be able to connect to # https://pypi.python.org/simple/ RUN zypper --non-interactive install ca-certificates-mozilla + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_ubuntu1204_x64/Dockerfile b/tools/dockerfile/distribtest/python_ubuntu1204_x64/Dockerfile index 4068fbe2bad0e..7a8c91b79bdfc 100644 --- a/tools/dockerfile/distribtest/python_ubuntu1204_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_ubuntu1204_x64/Dockerfile @@ -30,3 +30,5 @@ FROM ubuntu:12.04 RUN apt-get update -y && apt-get install -y python python-pip + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_ubuntu1404_x64/Dockerfile b/tools/dockerfile/distribtest/python_ubuntu1404_x64/Dockerfile index 0858fb0c06490..65189a44de91a 100644 --- a/tools/dockerfile/distribtest/python_ubuntu1404_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_ubuntu1404_x64/Dockerfile @@ -30,3 +30,5 @@ FROM ubuntu:14.04 RUN apt-get update -y && apt-get install -y python python-pip + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_ubuntu1504_x64/Dockerfile b/tools/dockerfile/distribtest/python_ubuntu1504_x64/Dockerfile index ed6ffddbec72f..abf36c4a2458e 100644 --- a/tools/dockerfile/distribtest/python_ubuntu1504_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_ubuntu1504_x64/Dockerfile @@ -30,3 +30,5 @@ FROM ubuntu:15.04 RUN apt-get update -y && apt-get install -y python python-pip + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_ubuntu1510_x64/Dockerfile b/tools/dockerfile/distribtest/python_ubuntu1510_x64/Dockerfile index 9e3e0c260f635..6e862d203b2ce 100644 --- a/tools/dockerfile/distribtest/python_ubuntu1510_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_ubuntu1510_x64/Dockerfile @@ -30,3 +30,5 @@ FROM ubuntu:15.10 RUN apt-get update -y && apt-get install -y python python-pip + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_ubuntu1604_x64/Dockerfile b/tools/dockerfile/distribtest/python_ubuntu1604_x64/Dockerfile index 5098da8a26f29..59f4feab55338 100644 --- a/tools/dockerfile/distribtest/python_ubuntu1604_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_ubuntu1604_x64/Dockerfile @@ -30,3 +30,5 @@ FROM ubuntu:16.04 RUN apt-get update -y && apt-get install -y python python-pip + +RUN pip install virtualenv diff --git a/tools/dockerfile/distribtest/python_wheezy_x64/Dockerfile b/tools/dockerfile/distribtest/python_wheezy_x64/Dockerfile index 66165ee9296a2..bc8816d30508f 100644 --- a/tools/dockerfile/distribtest/python_wheezy_x64/Dockerfile +++ b/tools/dockerfile/distribtest/python_wheezy_x64/Dockerfile @@ -30,3 +30,5 @@ FROM debian:wheezy RUN apt-get update -y && apt-get install -y python python-pip + +RUN pip install virtualenv From b236279832e0064ec36d80c71766681f3ea335a6 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Mon, 11 Jul 2016 15:10:02 -0700 Subject: [PATCH 066/151] Patch `spawn` for Python 'unix' compilers instead Before we patched the link command, now we just patch `spawn` as an updatable catch-all solution to ARG_MAX limitations on bash for MSYS and MinGW and friends. --- setup.py | 4 +- src/python/grpcio/_unixccompiler_patch.py | 98 ++++++----------------- 2 files changed, 27 insertions(+), 75 deletions(-) diff --git a/setup.py b/setup.py index 056e1fd03353c..28aa5a5c8e8a9 100644 --- a/setup.py +++ b/setup.py @@ -62,8 +62,8 @@ import grpc_core_dependencies import grpc_version -# TODO(atash) make this conditional on being on a mingw32 build -_unixccompiler_patch.monkeypatch_unix_compiler() +if 'win32' in sys.platform: + _unixccompiler_patch.monkeypatch_unix_compiler() LICENSE = '3-clause BSD' diff --git a/src/python/grpcio/_unixccompiler_patch.py b/src/python/grpcio/_unixccompiler_patch.py index 9a697989b30c5..0ce5d63e981a1 100644 --- a/src/python/grpcio/_unixccompiler_patch.py +++ b/src/python/grpcio/_unixccompiler_patch.py @@ -38,84 +38,36 @@ import sys import tempfile +def _unix_commandfile_spawn(self, command): + """Wrapper around distutils.util.spawn that attempts to use command files. -def _unix_piecemeal_link( - self, target_desc, objects, output_filename, output_dir=None, - libraries=None, library_dirs=None, runtime_library_dirs=None, - export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, - build_temp=None, target_lang=None): - """`link` externalized method taken almost verbatim from UnixCCompiler. + Meant to replace the CCompiler method `spawn` on UnixCCompiler and its + derivatives (e.g. the MinGW32 compiler). - Modifies the link command for unix-like compilers by using a command file so - that long command line argument strings don't break the command shell's - ARG_MAX character limit. + Some commands like `gcc` (and friends like `clang`) support command files to + work around shell command length limits. """ - objects, output_dir = self._fix_object_args(objects, output_dir) - libraries, library_dirs, runtime_library_dirs = self._fix_lib_args( - libraries, library_dirs, runtime_library_dirs) - # filter out standard library paths, which are not explicitely needed - # for linking - library_dirs = [dir for dir in library_dirs - if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] - runtime_library_dirs = [dir for dir in runtime_library_dirs - if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] - lib_opts = ccompiler.gen_lib_options(self, library_dirs, runtime_library_dirs, - libraries) - if (not (isinstance(output_dir, str) or isinstance(output_dir, bytes)) - and output_dir is not None): - raise TypeError("'output_dir' must be a string or None") - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - ld_args = (objects + self.objects + - lib_opts + ['-o', output_filename]) - if debug: - ld_args[:0] = ['-g'] - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - self.mkpath(os.path.dirname(output_filename)) - try: - if target_desc == ccompiler.CCompiler.EXECUTABLE: - linker = self.linker_exe[:] - else: - linker = self.linker_so[:] - if target_lang == "c++" and self.compiler_cxx: - # skip over environment variable settings if /usr/bin/env - # is used to set up the linker's environment. - # This is needed on OSX. Note: this assumes that the - # normal and C++ compiler have the same environment - # settings. - i = 0 - if os.path.basename(linker[0]) == "env": - i = 1 - while '=' in linker[i]: - i = i + 1 - - linker[i] = self.compiler_cxx[i] - - if sys.platform == 'darwin': - import _osx_support - linker = _osx_support.compiler_fixup(linker, ld_args) - - temporary_directory = tempfile.mkdtemp() - command_filename = os.path.abspath( - os.path.join(temporary_directory, 'command')) - with open(command_filename, 'w') as command_file: - escaped_ld_args = [arg.replace('\\', '\\\\') for arg in ld_args] - command_file.write(' '.join(escaped_ld_args)) - self.spawn(linker + ['@{}'.format(command_filename)]) - except errors.DistutilsExecError: - raise ccompiler.LinkError + command_base = os.path.basename(command[0].strip()) + if command_base == 'ccache': + command_base = command[:2] + command_args = command[2:] + elif command_base.startswith('ccache') or command_base in ['gcc', 'clang', 'clang++', 'g++']: + command_base = command[:1] + command_args = command[1:] else: - log.debug("skipping %s (up-to-date)", output_filename) + return ccompiler.CCompiler.spawn(self, command) + temporary_directory = tempfile.mkdtemp() + command_filename = os.path.abspath(os.path.join(temporary_directory, 'command')) + with open(command_filename, 'w') as command_file: + escaped_args = [arg.replace('\\', '\\\\') for arg in command_args] + command_file.write(' '.join(escaped_args)) + modified_command = command_base + ['@{}'.format(command_filename)] + result = ccompiler.CCompiler.spawn(self, modified_command) + shutil.rmtree(temporary_directory) + return result + -# TODO(atash) try replacing this monkeypatch of the compiler harness' link -# operation with a monkeypatch of the distutils `spawn` that applies -# command-argument-file hacks where it can. Might be cleaner. def monkeypatch_unix_compiler(): """Monkeypatching is dumb, but it's either that or we become maintainers of something much, much bigger.""" - unixccompiler.UnixCCompiler.link = _unix_piecemeal_link + unixccompiler.UnixCCompiler.spawn = _unix_commandfile_spawn From 9756fa3e1a76b30318861ed0f564103da72bcec9 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Fri, 15 Jul 2016 20:22:52 -0700 Subject: [PATCH 067/151] Allow make_grpcio_tools.py to be invoked in parallel --- tools/distrib/python/make_grpcio_tools.py | 83 ++++++++++++++++++++--- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/tools/distrib/python/make_grpcio_tools.py b/tools/distrib/python/make_grpcio_tools.py index fd9b38b084be1..b1184e01b2105 100755 --- a/tools/distrib/python/make_grpcio_tools.py +++ b/tools/distrib/python/make_grpcio_tools.py @@ -29,12 +29,18 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from __future__ import print_function + +import errno +import filecmp +import glob import os import os.path import shutil import subprocess import sys import traceback +import uuid DEPS_FILE_CONTENT=""" # Copyright 2016, Google Inc. @@ -125,19 +131,76 @@ def get_deps(): return deps_file_content +def atomic_file_copy(src, dst): + """Based on the lock-free-whack-a-mole algorithm, depending on filesystem + renaming being atomic. Described at http://stackoverflow.com/a/28090883. + """ + try: + if filecmp.cmp(src, dst): + return + except: + pass + dst_dir = os.path.abspath(os.path.dirname(dst)) + dst_base = os.path.basename(dst) + this_id = str(uuid.uuid4()).replace('.', '-') + temporary_file = os.path.join(dst_dir, '{}.{}.tmp'.format(dst_base, this_id)) + mole_file = os.path.join(dst_dir, '{}.{}.mole.tmp'.format(dst_base, this_id)) + shutil.copy2(src, temporary_file) + try: + os.rename(temporary_file, mole_file) + except: + print('Error moving temporary file {} to {}'.format(temporary_file, mole_file), file=sys.stderr) + print('while trying to copy file {} to {}'.format(src, dst), file=sys.stderr) + raise + for other_file in glob.glob('{}.*.mole.tmp'.format(dst)): + other_id = other_file.split('.')[-3] + if this_id == other_id: + pass + elif this_id < other_id: + try: + os.remove(other_file) + except: + pass + else: + try: + os.remove(mole_file) + except: + pass + this_id = other_id + mole_file = other_file + try: + if filecmp.cmp(src, dst): + try: + os.remove(mole_file) + except: + pass + return + except: + pass + try: + os.rename(mole_file, dst) + except: + pass + + def main(): os.chdir(GRPC_ROOT) - for tree in [GRPC_PYTHON_PROTOBUF, - GRPC_PYTHON_PROTOC_PLUGINS, - GRPC_PYTHON_INCLUDE]: - try: - shutil.rmtree(tree) - except Exception as _: - pass - shutil.copytree(GRPC_PROTOBUF, GRPC_PYTHON_PROTOBUF) - shutil.copytree(GRPC_PROTOC_PLUGINS, GRPC_PYTHON_PROTOC_PLUGINS) - shutil.copytree(GRPC_INCLUDE, GRPC_PYTHON_INCLUDE) + for source, target in [ + (GRPC_PROTOBUF, GRPC_PYTHON_PROTOBUF), + (GRPC_PROTOC_PLUGINS, GRPC_PYTHON_PROTOC_PLUGINS), + (GRPC_INCLUDE, GRPC_PYTHON_INCLUDE)]: + for source_dir, _, files in os.walk(source): + target_dir = os.path.abspath(os.path.join(target, os.path.relpath(source_dir, source))) + try: + os.makedirs(target_dir) + except OSError as error: + if error.errno != errno.EEXIST: + raise + for relative_file in files: + source_file = os.path.abspath(os.path.join(source_dir, relative_file)) + target_file = os.path.abspath(os.path.join(target_dir, relative_file)) + atomic_file_copy(source_file, target_file) try: protoc_lib_deps_content = get_deps() From 0e12875b7c07524075b30984d26febf91b4c5d60 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Fri, 15 Jul 2016 14:36:54 -0700 Subject: [PATCH 068/151] Build Python distributions for Python 3 --- tools/run_tests/artifact_targets.py | 47 ++++++++++++++++++----------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py index bd1269ceb7235..4a4297f1998e4 100644 --- a/tools/run_tests/artifact_targets.py +++ b/tools/run_tests/artifact_targets.py @@ -30,6 +30,9 @@ """Definition of targets to build artifacts.""" +import os.path +import sys + import jobset @@ -76,27 +79,30 @@ def create_jobspec(name, cmdline, environ=None, shell=False, 'x64': '-m64' } -python_version_arch_map = { - 'x86': 'Python27_32bits', - 'x64': 'Python27' +python_windows_version_arch_map = { + ('x86', '2.7'): 'Python27_32bits', + ('x64', '2.7'): 'Python27', + ('x86', '3.4'): 'Python34_32bits', + ('x64', '3.4'): 'Python34', } class PythonArtifact: """Builds Python artifacts.""" - def __init__(self, platform, arch, manylinux_build=None): + def __init__(self, platform, arch, python_version, manylinux_build=None): if manylinux_build: - self.name = 'python_%s_%s_%s' % (platform, arch, manylinux_build) + self.name = 'python%s_%s_%s_%s' % (python_version, platform, arch, manylinux_build) else: - self.name = 'python_%s_%s' % (platform, arch) + self.name = 'python%s_%s_%s' % (python_version, platform, arch) self.platform = platform self.arch = arch - self.labels = ['artifact', 'python', platform, arch] - self.python_version = python_version_arch_map[arch] + self.labels = ['artifact', 'python', python_version, platform, arch] + self.python_version = python_version + self.python_windows_prefix = python_windows_version_arch_map[arch, python_version] self.manylinux_build = manylinux_build def pre_build_jobspecs(self): - return [] + return [] def build_jobspec(self): environ = {} @@ -107,7 +113,6 @@ def build_jobspec(self): # special places... environ['PYTHON'] = '/opt/python/{}/bin/python'.format(self.manylinux_build) environ['PIP'] = '/opt/python/{}/bin/pip'.format(self.manylinux_build) - # Our docker image has all the prerequisites pip-installed already. environ['SKIP_PIP_INSTALL'] = '1' # Platform autodetection for the manylinux1 image breaks so we set the # defines ourselves. @@ -121,12 +126,13 @@ def build_jobspec(self): elif self.platform == 'windows': return create_jobspec(self.name, ['tools\\run_tests\\build_artifact_python.bat', - self.python_version, + self.python_windows_prefix, '32' if self.arch == 'x86' else '64' ], shell=True) else: environ['SKIP_PIP_INSTALL'] = 'TRUE' + environ['PYTHON'] = 'python{}'.format(self.python_version) return create_jobspec(self.name, ['tools/run_tests/build_artifact_python.sh'], environ=environ) @@ -323,13 +329,18 @@ def targets(): for Cls in (CSharpExtArtifact, NodeExtArtifact, ProtocArtifact) for platform in ('linux', 'macos', 'windows') for arch in ('x86', 'x64')] + - [PythonArtifact('linux', 'x86', 'cp27-cp27m'), - PythonArtifact('linux', 'x86', 'cp27-cp27mu'), - PythonArtifact('linux', 'x64', 'cp27-cp27m'), - PythonArtifact('linux', 'x64', 'cp27-cp27mu'), - PythonArtifact('macos', 'x64'), - PythonArtifact('windows', 'x86'), - PythonArtifact('windows', 'x64'), + [PythonArtifact('linux', 'x86', '2.7', 'cp27-cp27m'), + PythonArtifact('linux', 'x86', '2.7', 'cp27-cp27mu'), + PythonArtifact('linux', 'x64', '2.7', 'cp27-cp27m'), + PythonArtifact('linux', 'x64', '2.7', 'cp27-cp27mu'), + PythonArtifact('macos', 'x64', '2.7'), + PythonArtifact('windows', 'x86', '2.7'), + PythonArtifact('windows', 'x64', '2.7'), + PythonArtifact('linux', 'x86', '3.4', 'cp34-cp34m'), + PythonArtifact('linux', 'x64', '3.4', 'cp34-cp34m'), + PythonArtifact('macos', 'x64', '3.4'), + PythonArtifact('windows', 'x86', '3.4'), + PythonArtifact('windows', 'x64', '3.4'), RubyArtifact('linux', 'x86'), RubyArtifact('linux', 'x64'), RubyArtifact('macos', 'x64'), From 027835fbd684cabd1f8b4114f431e8ee3a6d6a72 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Fri, 15 Jul 2016 22:31:50 -0700 Subject: [PATCH 069/151] Increase build timeouts for Python artifacts --- tools/run_tests/artifact_targets.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py index 4a4297f1998e4..b145e0392cef3 100644 --- a/tools/run_tests/artifact_targets.py +++ b/tools/run_tests/artifact_targets.py @@ -37,7 +37,7 @@ def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={}, - flake_retries=0, timeout_retries=0): + flake_retries=0, timeout_retries=0, timeout_seconds=30*60): """Creates jobspec for a task running under docker.""" environ = environ.copy() environ['RUN_COMMAND'] = shell_command @@ -52,20 +52,20 @@ def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={}, cmdline=['tools/run_tests/dockerize/build_and_run_docker.sh'] + docker_args, environ=docker_env, shortname='build_artifact.%s' % (name), - timeout_seconds=30*60, + timeout_seconds=timeout_seconds, flake_retries=flake_retries, timeout_retries=timeout_retries) return jobspec def create_jobspec(name, cmdline, environ=None, shell=False, - flake_retries=0, timeout_retries=0): + flake_retries=0, timeout_retries=0, timeout_seconds=30*60): """Creates jobspec.""" jobspec = jobset.JobSpec( cmdline=cmdline, environ=environ, shortname='build_artifact.%s' % (name), - timeout_seconds=30*60, + timeout_seconds=timeout_seconds, flake_retries=flake_retries, timeout_retries=timeout_retries, shell=shell) @@ -122,7 +122,8 @@ def build_jobspec(self): return create_docker_jobspec(self.name, 'tools/dockerfile/grpc_artifact_python_manylinux_%s' % self.arch, 'tools/run_tests/build_artifact_python.sh', - environ=environ) + environ=environ, + timeout_seconds=60*60) elif self.platform == 'windows': return create_jobspec(self.name, ['tools\\run_tests\\build_artifact_python.bat', From c089a58a20b5f6ca996640016cdcba4d62712601 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Fri, 15 Jul 2016 23:40:32 -0700 Subject: [PATCH 070/151] Change directory when building grpcio-tools --- tools/run_tests/build_artifact_python.bat | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/build_artifact_python.bat b/tools/run_tests/build_artifact_python.bat index 7c8c2aa12d742..d0b147b42620f 100644 --- a/tools/run_tests/build_artifact_python.bat +++ b/tools/run_tests/build_artifact_python.bat @@ -65,11 +65,19 @@ python tools\distrib\python\make_grpcio_tools.py @rem Build gRPC Python extensions python setup.py build_ext -c mingw32 -python tools\distrib\python\grpcio_tools\setup.py build_ext -c mingw32 + +pushd tools\distrib\python\grpcio_tools +python setup.py build_ext -c mingw32 +popd + @rem Build gRPC Python distributions python setup.py bdist_wheel -python tools\distrib\python\grpcio_tools\setup.py bdist_wheel + +pushd tools\distrib\python\grpcio_tools +python setup.py bdist_wheel +popd + mkdir artifacts xcopy /Y /I /S dist\* artifacts\ || goto :error From a39c2cb4f2881351fb8844d5e5a49e5bc80e2f8a Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Sat, 16 Jul 2016 00:17:10 -0700 Subject: [PATCH 071/151] Handle distutils command idiosyncracies --- src/python/grpcio/_unixccompiler_patch.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python/grpcio/_unixccompiler_patch.py b/src/python/grpcio/_unixccompiler_patch.py index 0ce5d63e981a1..894c3ef395a64 100644 --- a/src/python/grpcio/_unixccompiler_patch.py +++ b/src/python/grpcio/_unixccompiler_patch.py @@ -34,6 +34,7 @@ from distutils import unixccompiler import os import os.path +import shlex import shutil import sys import tempfile @@ -47,6 +48,9 @@ def _unix_commandfile_spawn(self, command): Some commands like `gcc` (and friends like `clang`) support command files to work around shell command length limits. """ + # Sometimes distutils embeds the executables as full strings including some + # hard-coded flags rather than as lists. + command = list(shlex.split(command[0])) + list(command[1:]) command_base = os.path.basename(command[0].strip()) if command_base == 'ccache': command_base = command[:2] From 58a0494cebb3d0d262557ec9ac25f60f2053fc86 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Sat, 16 Jul 2016 01:42:52 -0700 Subject: [PATCH 072/151] Use normalized path separators in `setup.py`s --- setup.py | 17 ++++++++------ tools/distrib/python/grpcio_tools/setup.py | 27 ++++++++++++++-------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/setup.py b/setup.py index 28aa5a5c8e8a9..5d33756c19147 100644 --- a/setup.py +++ b/setup.py @@ -47,10 +47,10 @@ egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in' PY3 = sys.version_info.major == 3 -PYTHON_STEM = './src/python/grpcio' -CORE_INCLUDE = ('./include', '.',) -BORINGSSL_INCLUDE = ('./third_party/boringssl/include',) -ZLIB_INCLUDE = ('./third_party/zlib',) +PYTHON_STEM = os.path.join('src', 'python', 'grpcio') +CORE_INCLUDE = ('include', '.',) +BORINGSSL_INCLUDE = (os.path.join('third_party', 'boringssl', 'include'),) +ZLIB_INCLUDE = (os.path.join('third_party', 'zlib'),) # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -105,7 +105,9 @@ if "win32" in sys.platform: EXTENSION_LIBRARIES += ('ws2_32',) -DEFINE_MACROS = (('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600), ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),) +DEFINE_MACROS = ( + ('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600), + ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),) if "win32" in sys.platform: DEFINE_MACROS += (('OPENSSL_WINDOWS', 1), ('WIN32_LEAN_AND_MEAN', 1),) if '64bit' in platform.architecture()[0]: @@ -200,12 +202,13 @@ def cython_extensions(module_names, extra_sources, include_dirs, } # Ensure that package data is copied over before any commands have been run: -credentials_dir = os.path.join(PYTHON_STEM, 'grpc/_cython/_credentials') +credentials_dir = os.path.join(PYTHON_STEM, 'grpc', '_cython', '_credentials') try: os.mkdir(credentials_dir) except OSError: pass -shutil.copyfile('etc/roots.pem', os.path.join(credentials_dir, 'roots.pem')) +shutil.copyfile(os.path.join('etc', 'roots.pem'), + os.path.join(credentials_dir, 'roots.pem')) PACKAGE_DATA = { # Binaries that may or may not be present in the final installation, but are diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index d804f34fc60b2..a00ce0111072d 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -61,6 +61,13 @@ EXTRA_LINK_ARGS = shlex.split(os.environ.get('GRPC_PYTHON_LDFLAGS', '-lpthread')) +CC_FILES = [ + os.path.normpath(cc_file) for cc_file in protoc_lib_deps.CC_FILES] +PROTO_FILES = [ + os.path.normpath(proto_file) for proto_file in protoc_lib_deps.PROTO_FILES] +CC_INCLUDE = os.path.normpath(protoc_lib_deps.CC_INCLUDE) +PROTO_INCLUDE = os.path.normpath(protoc_lib_deps.PROTO_INCLUDE) + GRPC_PYTHON_TOOLS_PACKAGE = 'grpc.tools' GRPC_PYTHON_PROTO_RESOURCES_NAME = '_proto' @@ -82,8 +89,8 @@ def package_data(): proto_resources_path = os.path.join(tools_path, GRPC_PYTHON_PROTO_RESOURCES_NAME) proto_files = [] - for proto_file in protoc_lib_deps.PROTO_FILES: - source = os.path.join(protoc_lib_deps.PROTO_INCLUDE, proto_file) + for proto_file in PROTO_FILES: + source = os.path.join(PROTO_INCLUDE, proto_file) target = os.path.join(proto_resources_path, proto_file) relative_target = os.path.join(GRPC_PYTHON_PROTO_RESOURCES_NAME, proto_file) try: @@ -99,18 +106,20 @@ def package_data(): def protoc_ext_module(): plugin_sources = [ - 'grpc/tools/main.cc', - 'grpc_root/src/compiler/python_generator.cc'] + [ - os.path.join(protoc_lib_deps.CC_INCLUDE, cc_file) - for cc_file in protoc_lib_deps.CC_FILES] + os.path.join('grpc', 'tools', 'main.cc'), + os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [ + os.path.join(CC_INCLUDE, cc_file) + for cc_file in CC_FILES] plugin_ext = extension.Extension( name='grpc.tools._protoc_compiler', - sources=['grpc/tools/_protoc_compiler.pyx'] + plugin_sources, + sources=( + [os.path.join('grpc', 'tools', '_protoc_compiler.pyx')] + + plugin_sources), include_dirs=[ '.', 'grpc_root', - 'grpc_root/include', - protoc_lib_deps.CC_INCLUDE, + os.path.join('grpc_root', 'include'), + CC_INCLUDE, ], language='c++', define_macros=list(DEFINE_MACROS), From 792d899b7e6eca330d380260a7d218b55ee0b51c Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Sat, 16 Jul 2016 02:19:26 -0700 Subject: [PATCH 073/151] Support long paths in make_grpcio_tools.py --- tools/distrib/python/make_grpcio_tools.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/distrib/python/make_grpcio_tools.py b/tools/distrib/python/make_grpcio_tools.py index b1184e01b2105..adf58445afe8f 100755 --- a/tools/distrib/python/make_grpcio_tools.py +++ b/tools/distrib/python/make_grpcio_tools.py @@ -130,6 +130,11 @@ def get_deps(): proto_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT)) return deps_file_content +def long_path(path): + if os.name == 'nt': + return '\\\\?\\' + path + else: + return path def atomic_file_copy(src, dst): """Based on the lock-free-whack-a-mole algorithm, depending on filesystem @@ -145,6 +150,12 @@ def atomic_file_copy(src, dst): this_id = str(uuid.uuid4()).replace('.', '-') temporary_file = os.path.join(dst_dir, '{}.{}.tmp'.format(dst_base, this_id)) mole_file = os.path.join(dst_dir, '{}.{}.mole.tmp'.format(dst_base, this_id)) + mole_pattern = os.path.join(dst_dir, '{}.*.mole.tmp'.format(dst_base)) + src = long_path(src) + dst = long_path(dst) + temporary_file = long_path(temporary_file) + mole_file = long_path(mole_file) + mole_pattern = long_path(mole_pattern) shutil.copy2(src, temporary_file) try: os.rename(temporary_file, mole_file) @@ -152,7 +163,7 @@ def atomic_file_copy(src, dst): print('Error moving temporary file {} to {}'.format(temporary_file, mole_file), file=sys.stderr) print('while trying to copy file {} to {}'.format(src, dst), file=sys.stderr) raise - for other_file in glob.glob('{}.*.mole.tmp'.format(dst)): + for other_file in glob.glob(mole_pattern): other_id = other_file.split('.')[-3] if this_id == other_id: pass From 6660c110dfc842314ba1ef063d8fcbe3f79dd180 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Sun, 17 Jul 2016 18:27:23 +0800 Subject: [PATCH 074/151] fix spell error by pyflakes found --- tools/gcp/stress_test/stress_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gcp/stress_test/stress_test_utils.py b/tools/gcp/stress_test/stress_test_utils.py index b821fc8fcc1d3..be50af31845f7 100755 --- a/tools/gcp/stress_test/stress_test_utils.py +++ b/tools/gcp/stress_test/stress_test_utils.py @@ -121,7 +121,7 @@ def check_if_any_tests_failed(self, num_query_retries=3, timeout_msec=30000): if not page['jobComplete']: print('TIMEOUT ERROR: The query %s timed out. Current timeout value is' ' %d msec. Returning False (i.e assuming there are no failures)' - ) % (query, timeoout_msec) + ) % (query, timeout_msec) return False num_failures = int(page['totalRows']) From 8f18ee64b26d9a1462e8bccfb15aba00e8550492 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 18 Jul 2016 08:00:33 -0700 Subject: [PATCH 075/151] Make default log verbosity ERROR, run tests with DEBUG --- src/core/lib/support/log.c | 19 ++++++++++--------- tools/run_tests/run_tests.py | 7 +++++-- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c index bae0957df7209..899f1218b60b7 100644 --- a/src/core/lib/support/log.c +++ b/src/core/lib/support/log.c @@ -79,17 +79,18 @@ void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) { void gpr_log_verbosity_init() { char *verbosity = gpr_getenv("GRPC_VERBOSITY"); - if (verbosity == NULL) return; - gpr_atm min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; - if (strcmp(verbosity, "DEBUG") == 0) { - min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_DEBUG; - } else if (strcmp(verbosity, "INFO") == 0) { - min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_INFO; - } else if (strcmp(verbosity, "ERROR") == 0) { - min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_ERROR; + gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR; + if (verbosity != NULL) { + if (strcmp(verbosity, "DEBUG") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_DEBUG; + } else if (strcmp(verbosity, "INFO") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_INFO; + } else if (strcmp(verbosity, "ERROR") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_ERROR; + } + gpr_free(verbosity); } - gpr_free(verbosity); if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) == GPR_LOG_VERBOSITY_UNSET) { gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print); diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 95d53e5f9e59f..3266cfd19fcf1 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -60,7 +60,9 @@ os.chdir(_ROOT) -_FORCE_ENVIRON_FOR_WRAPPERS = {} +_FORCE_ENVIRON_FOR_WRAPPERS = { + 'GRPC_VERBOSITY': 'DEBUG', +} _POLLING_STRATEGIES = { @@ -158,7 +160,8 @@ def test_specs(self): for polling_strategy in polling_strategies: env={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH': _ROOT + '/src/core/lib/tsi/test_creds/ca.pem', - 'GRPC_POLL_STRATEGY': polling_strategy} + 'GRPC_POLL_STRATEGY': polling_strategy, + 'GRPC_VERBOSITY': 'DEBUG'} shortname_ext = '' if polling_strategy=='all' else ' polling=%s' % polling_strategy if self.config.build_config in target['exclude_configs']: continue From 24987dbf772978680dce4acaccc0481b9c0e9382 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 18 Jul 2016 10:35:44 -0700 Subject: [PATCH 076/151] fix typo --- include/grpc++/impl/codegen/config_protobuf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h index 4bee1bc422796..318ba5968315e 100644 --- a/include/grpc++/impl/codegen/config_protobuf.h +++ b/include/grpc++/impl/codegen/config_protobuf.h @@ -49,7 +49,7 @@ #include #define GRPC_CUSTOM_DESCRIPTOR ::google::protobuf::Descriptor #define GRPC_CUSTOM_DESCRIPTORPOOL ::google::protobuf::DescriptorPool -#define GPRC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor +#define GRPC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor #define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor #define GRPC_CUSTOM_FILEDESCRIPTORPROTO ::google::protobuf::FileDescriptorProto #define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor @@ -75,7 +75,7 @@ typedef GRPC_CUSTOM_PROTOBUF_INT64 int64; typedef GRPC_CUSTOM_DESCRIPTOR Descriptor; typedef GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool; -typedef GPRC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor; +typedef GRPC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto; typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor; From 9f6e6dcc30f61061b26304cd30dab2d287c80c61 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 18 Jul 2016 11:50:10 -0700 Subject: [PATCH 077/151] Rename h2_ssl.* to h2_ssl_cronet.* and add static specifier to chttp2_tear_down_secure_fullstack in h2_ssl_cronet.m --- .../CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m | 2 +- .../{h2_ssl.h => h2_ssl_cronet.h} | 0 .../{h2_ssl.m => h2_ssl_cronet.m} | 2 +- .../tests/Tests.xcodeproj/project.pbxproj | 12 ++++++------ 4 files changed, 8 insertions(+), 8 deletions(-) rename src/objective-c/tests/CoreCronetEnd2EndTests/{h2_ssl.h => h2_ssl_cronet.h} (100%) rename src/objective-c/tests/CoreCronetEnd2EndTests/{h2_ssl.m => h2_ssl_cronet.m} (98%) diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index 5d501602d908f..097e3686749d6 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -32,7 +32,7 @@ */ #import -#include "./h2_ssl.h" +#include "./h2_ssl_cronet.h" @interface CoreCronetEnd2EndTests : XCTestCase diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.h similarity index 100% rename from src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.h rename to src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.h diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m similarity index 98% rename from src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m rename to src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m index 68010f341b32e..dfa27abf8d096 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m @@ -111,7 +111,7 @@ static void chttp2_init_server_secure_fullstack( grpc_server_start(f->server); } -void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { +static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { fullstack_secure_fixture_data *ffd = f->fixture_data; gpr_free(ffd->localaddr); gpr_free(ffd); diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 4161dcc43cf44..9b7d23728cab4 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -12,9 +12,9 @@ 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; }; + 5E1BD3B21D3D583900A47325 /* h2_ssl_cronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */; }; 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */; }; 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5E8A5DB01D3849F1000F8BC4 /* h2_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */; }; 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */; }; 6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; 63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; @@ -110,10 +110,10 @@ 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; + 5E1BD3B01D3D583900A47325 /* h2_ssl_cronet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = h2_ssl_cronet.h; sourceTree = ""; }; + 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl_cronet.m; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; - 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl.m; sourceTree = ""; }; - 5ED3173E1D397C7500C613BD /* h2_ssl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = h2_ssl.h; sourceTree = ""; }; 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; 63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = ""; }; @@ -252,8 +252,8 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( - 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */, - 5ED3173E1D397C7500C613BD /* h2_ssl.h */, + 5E1BD3B01D3D583900A47325 /* h2_ssl_cronet.h */, + 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */, 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */, ); path = CoreCronetEnd2EndTests; @@ -867,8 +867,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5E8A5DB01D3849F1000F8BC4 /* h2_ssl.m in Sources */, 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */, + 5E1BD3B21D3D583900A47325 /* h2_ssl_cronet.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 3046557a028519ef8c324728cf4367bb55cfad7d Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 18 Jul 2016 10:35:44 -0700 Subject: [PATCH 078/151] fix typo --- include/grpc++/impl/codegen/config_protobuf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h index 4bee1bc422796..318ba5968315e 100644 --- a/include/grpc++/impl/codegen/config_protobuf.h +++ b/include/grpc++/impl/codegen/config_protobuf.h @@ -49,7 +49,7 @@ #include #define GRPC_CUSTOM_DESCRIPTOR ::google::protobuf::Descriptor #define GRPC_CUSTOM_DESCRIPTORPOOL ::google::protobuf::DescriptorPool -#define GPRC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor +#define GRPC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor #define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor #define GRPC_CUSTOM_FILEDESCRIPTORPROTO ::google::protobuf::FileDescriptorProto #define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor @@ -75,7 +75,7 @@ typedef GRPC_CUSTOM_PROTOBUF_INT64 int64; typedef GRPC_CUSTOM_DESCRIPTOR Descriptor; typedef GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool; -typedef GPRC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor; +typedef GRPC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto; typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor; From 0af0ae471504d4bc3ca3d9b74df12e8c1363d87b Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 12:08:19 -0700 Subject: [PATCH 079/151] Update err_data.c to BoringSSL commit 8d343b44bbab --- src/objective-c/BoringSSL.podspec | 462 +++++++++++++++--------------- 1 file changed, 234 insertions(+), 228 deletions(-) diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec index 653cf1c5c649b..01f01bff8fb5a 100644 --- a/src/objective-c/BoringSSL.podspec +++ b/src/objective-c/BoringSSL.podspec @@ -219,7 +219,7 @@ Pod::Spec.new do |s| * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - /* This file was generated by err_data_generate.go. */ + /* This file was generated by err_data_generate.go. */ #include #include @@ -385,42 +385,42 @@ Pod::Spec.new do |s| 0x28340c19, 0x283480ac, 0x283500ea, - 0x2c322775, - 0x2c32a783, - 0x2c332795, - 0x2c33a7a7, - 0x2c3427bb, - 0x2c34a7cd, - 0x2c3527e8, - 0x2c35a7fa, - 0x2c36280d, + 0x2c3227cb, + 0x2c32a7d9, + 0x2c3327eb, + 0x2c33a7fd, + 0x2c342811, + 0x2c34a823, + 0x2c35283e, + 0x2c35a850, + 0x2c362863, 0x2c36832d, - 0x2c37281a, - 0x2c37a82c, - 0x2c38283f, - 0x2c38a856, - 0x2c392864, - 0x2c39a874, - 0x2c3a2886, - 0x2c3aa89a, - 0x2c3b28ab, - 0x2c3ba8ca, - 0x2c3c28de, - 0x2c3ca8f4, - 0x2c3d290d, - 0x2c3da92a, - 0x2c3e293b, - 0x2c3ea949, - 0x2c3f2961, - 0x2c3fa979, - 0x2c402986, + 0x2c372870, + 0x2c37a882, + 0x2c382895, + 0x2c38a8ac, + 0x2c3928ba, + 0x2c39a8ca, + 0x2c3a28dc, + 0x2c3aa8f0, + 0x2c3b2901, + 0x2c3ba920, + 0x2c3c2934, + 0x2c3ca94a, + 0x2c3d2963, + 0x2c3da980, + 0x2c3e2991, + 0x2c3ea99f, + 0x2c3f29b7, + 0x2c3fa9cf, + 0x2c4029dc, 0x2c4090e7, - 0x2c412997, - 0x2c41a9aa, + 0x2c4129ed, + 0x2c41aa00, 0x2c4210c0, - 0x2c42a9bb, + 0x2c42aa11, 0x2c430720, - 0x2c43a8bc, + 0x2c43a912, 0x30320000, 0x30328015, 0x3033001f, @@ -594,145 +594,148 @@ Pod::Spec.new do |s| 0x404619e8, 0x40469a08, 0x40471a16, - 0x40479a2a, - 0x40481a3f, - 0x40489a58, - 0x40491a6f, - 0x40499a89, - 0x404a1aa0, - 0x404a9abe, - 0x404b1ad6, - 0x404b9aed, - 0x404c1b03, - 0x404c9b15, - 0x404d1b36, - 0x404d9b58, - 0x404e1b6c, - 0x404e9b79, - 0x404f1b90, - 0x404f9ba0, - 0x40501bca, - 0x40509bde, - 0x40511bf9, - 0x40519c09, - 0x40521c20, - 0x40529c32, - 0x40531c4a, - 0x40539c5d, - 0x40541c72, - 0x40549c95, - 0x40551ca3, - 0x40559cc0, - 0x40561ccd, - 0x40569ce6, - 0x40571cfe, - 0x40579d11, - 0x40581d26, - 0x40589d38, - 0x40591d48, - 0x40599d61, - 0x405a1d75, - 0x405a9d85, - 0x405b1d9d, - 0x405b9dae, - 0x405c1dc1, - 0x405c9dd2, - 0x405d1ddf, - 0x405d9df6, - 0x405e1e16, + 0x40479a3d, + 0x40481a52, + 0x40489a6b, + 0x40491a82, + 0x40499a9c, + 0x404a1ab3, + 0x404a9ad1, + 0x404b1ae9, + 0x404b9b00, + 0x404c1b16, + 0x404c9b28, + 0x404d1b49, + 0x404d9b6b, + 0x404e1b7f, + 0x404e9b8c, + 0x404f1ba3, + 0x404f9bb3, + 0x40501bdd, + 0x40509bf1, + 0x40511c0c, + 0x40519c1c, + 0x40521c33, + 0x40529c45, + 0x40531c5d, + 0x40539c70, + 0x40541c85, + 0x40549ca8, + 0x40551cb6, + 0x40559cd3, + 0x40561ce0, + 0x40569cf9, + 0x40571d11, + 0x40579d24, + 0x40581d39, + 0x40589d4b, + 0x40591d7a, + 0x40599d93, + 0x405a1da7, + 0x405a9db7, + 0x405b1dcf, + 0x405b9de0, + 0x405c1df3, + 0x405c9e04, + 0x405d1e11, + 0x405d9e28, + 0x405e1e48, 0x405e8a95, - 0x405f1e37, - 0x405f9e44, - 0x40601e52, - 0x40609e74, - 0x40611e9c, - 0x40619eb1, - 0x40621ec8, - 0x40629ed9, - 0x40631eea, - 0x40639eff, - 0x40641f16, - 0x40649f27, - 0x40651f42, - 0x40659f59, - 0x40661f71, - 0x40669f9b, - 0x40671fc6, - 0x40679fe7, - 0x40681ffa, - 0x4068a01b, - 0x4069204d, - 0x4069a07b, - 0x406a209c, - 0x406aa0bc, - 0x406b2244, - 0x406ba267, - 0x406c227d, - 0x406ca4a9, - 0x406d24d8, - 0x406da500, - 0x406e2519, - 0x406ea531, - 0x406f2550, - 0x406fa565, - 0x40702578, - 0x4070a595, + 0x405f1e69, + 0x405f9e76, + 0x40601e84, + 0x40609ea6, + 0x40611ece, + 0x40619ee3, + 0x40621efa, + 0x40629f0b, + 0x40631f1c, + 0x40639f31, + 0x40641f48, + 0x40649f59, + 0x40651f74, + 0x40659f8b, + 0x40661fa3, + 0x40669fcd, + 0x40671ff8, + 0x4067a019, + 0x4068202c, + 0x4068a04d, + 0x4069207f, + 0x4069a0ad, + 0x406a20ce, + 0x406aa0ee, + 0x406b2276, + 0x406ba299, + 0x406c22af, + 0x406ca4db, + 0x406d250a, + 0x406da532, + 0x406e254b, + 0x406ea563, + 0x406f2582, + 0x406fa597, + 0x407025aa, + 0x4070a5c7, 0x40710800, - 0x4071a5a7, - 0x407225ba, - 0x4072a5d3, - 0x407325eb, + 0x4071a5d9, + 0x407225ec, + 0x4072a605, + 0x4073261d, 0x4073936d, - 0x407425ff, - 0x4074a619, - 0x4075262a, - 0x4075a63e, - 0x4076264c, + 0x40742631, + 0x4074a64b, + 0x4075265c, + 0x4075a670, + 0x4076267e, 0x407691aa, - 0x40772671, - 0x4077a693, - 0x407826ae, - 0x4078a6c3, - 0x407926da, - 0x4079a6f0, - 0x407a26fc, - 0x407aa70f, - 0x407b2724, - 0x407ba736, - 0x407c274b, - 0x407ca754, - 0x407d2036, - 0x407d9bb0, - 0x41f4216f, - 0x41f92201, - 0x41fe20f4, - 0x41fea2d0, - 0x41ff23c1, - 0x42032188, - 0x420821aa, - 0x4208a1e6, - 0x420920d8, - 0x4209a220, - 0x420a212f, - 0x420aa10f, - 0x420b214f, - 0x420ba1c8, - 0x420c23dd, - 0x420ca29d, - 0x420d22b7, - 0x420da2ee, - 0x42122308, - 0x421723a4, - 0x4217a34a, - 0x421c236c, - 0x421f2327, - 0x422123f4, - 0x42262387, - 0x422b248d, - 0x422ba456, - 0x422c2475, - 0x422ca430, - 0x422d240f, + 0x407726a3, + 0x4077a6c5, + 0x407826e0, + 0x4078a719, + 0x40792730, + 0x4079a746, + 0x407a2752, + 0x407aa765, + 0x407b277a, + 0x407ba78c, + 0x407c27a1, + 0x407ca7aa, + 0x407d2068, + 0x407d9bc3, + 0x407e26f5, + 0x407e9d5b, + 0x407f1a2a, + 0x41f421a1, + 0x41f92233, + 0x41fe2126, + 0x41fea302, + 0x41ff23f3, + 0x420321ba, + 0x420821dc, + 0x4208a218, + 0x4209210a, + 0x4209a252, + 0x420a2161, + 0x420aa141, + 0x420b2181, + 0x420ba1fa, + 0x420c240f, + 0x420ca2cf, + 0x420d22e9, + 0x420da320, + 0x4212233a, + 0x421723d6, + 0x4217a37c, + 0x421c239e, + 0x421f2359, + 0x42212426, + 0x422623b9, + 0x422b24bf, + 0x422ba488, + 0x422c24a7, + 0x422ca462, + 0x422d2441, 0x4432072b, 0x4432873a, 0x44330746, @@ -775,69 +778,69 @@ Pod::Spec.new do |s| 0x4c3d136d, 0x4c3d937c, 0x4c3e1389, - 0x503229cd, - 0x5032a9dc, - 0x503329e7, - 0x5033a9f7, - 0x50342a10, - 0x5034aa2a, - 0x50352a38, - 0x5035aa4e, - 0x50362a60, - 0x5036aa76, - 0x50372a8f, - 0x5037aaa2, - 0x50382aba, - 0x5038aacb, - 0x50392ae0, - 0x5039aaf4, - 0x503a2b14, - 0x503aab2a, - 0x503b2b42, - 0x503bab54, - 0x503c2b70, - 0x503cab87, - 0x503d2ba0, - 0x503dabb6, - 0x503e2bc3, - 0x503eabd9, - 0x503f2beb, + 0x50322a23, + 0x5032aa32, + 0x50332a3d, + 0x5033aa4d, + 0x50342a66, + 0x5034aa80, + 0x50352a8e, + 0x5035aaa4, + 0x50362ab6, + 0x5036aacc, + 0x50372ae5, + 0x5037aaf8, + 0x50382b10, + 0x5038ab21, + 0x50392b36, + 0x5039ab4a, + 0x503a2b6a, + 0x503aab80, + 0x503b2b98, + 0x503babaa, + 0x503c2bc6, + 0x503cabdd, + 0x503d2bf6, + 0x503dac0c, + 0x503e2c19, + 0x503eac2f, + 0x503f2c41, 0x503f8382, - 0x50402bfe, - 0x5040ac0e, - 0x50412c28, - 0x5041ac37, - 0x50422c51, - 0x5042ac6e, - 0x50432c7e, - 0x5043ac8e, - 0x50442c9d, + 0x50402c54, + 0x5040ac64, + 0x50412c7e, + 0x5041ac8d, + 0x50422ca7, + 0x5042acc4, + 0x50432cd4, + 0x5043ace4, + 0x50442cf3, 0x5044843f, - 0x50452cb1, - 0x5045accf, - 0x50462ce2, - 0x5046acf8, - 0x50472d0a, - 0x5047ad1f, - 0x50482d45, - 0x5048ad53, - 0x50492d66, - 0x5049ad7b, - 0x504a2d91, - 0x504aada1, - 0x504b2dc1, - 0x504badd4, - 0x504c2df7, - 0x504cae25, - 0x504d2e37, - 0x504dae54, - 0x504e2e6f, - 0x504eae8b, - 0x504f2e9d, - 0x504faeb4, - 0x50502ec3, + 0x50452d07, + 0x5045ad25, + 0x50462d38, + 0x5046ad4e, + 0x50472d60, + 0x5047ad75, + 0x50482d9b, + 0x5048ada9, + 0x50492dbc, + 0x5049add1, + 0x504a2de7, + 0x504aadf7, + 0x504b2e17, + 0x504bae2a, + 0x504c2e4d, + 0x504cae7b, + 0x504d2e8d, + 0x504daeaa, + 0x504e2ec5, + 0x504eaee1, + 0x504f2ef3, + 0x504faf0a, + 0x50502f19, 0x505086ef, - 0x50512ed6, + 0x50512f2c, 0x58320ec9, 0x68320e8b, 0x68328c25, @@ -1218,6 +1221,7 @@ Pod::Spec.new do |s| "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" "DH_P_TOO_LONG\\0" "DIGEST_CHECK_FAILED\\0" + "DOWNGRADE_DETECTED\\0" "DTLS_MESSAGE_TOO_BIG\\0" "ECC_CERT_NOT_FOR_SIGNING\\0" "EMS_STATE_INCONSISTENT\\0" @@ -1254,6 +1258,7 @@ Pod::Spec.new do |s| "NO_CIPHERS_AVAILABLE\\0" "NO_CIPHERS_PASSED\\0" "NO_CIPHER_MATCH\\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\\0" "NO_COMPRESSION_SPECIFIED\\0" "NO_METHOD_SPECIFIED\\0" "NO_P256_SUPPORT\\0" @@ -1344,6 +1349,7 @@ Pod::Spec.new do |s| "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" "UNSUPPORTED_ELLIPTIC_CURVE\\0" "UNSUPPORTED_PROTOCOL\\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" "WRONG_CERTIFICATE_TYPE\\0" "WRONG_CIPHER_RETURNED\\0" "WRONG_CURVE\\0" From fffff2296c9b897a0828bd613ded6bd865ebb07e Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 12:09:07 -0700 Subject: [PATCH 080/151] Point BoringSSL.podspec to 5.0 commit (pending tag) --- src/objective-c/BoringSSL.podspec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec index 01f01bff8fb5a..9cbf6bfc9f7eb 100644 --- a/src/objective-c/BoringSSL.podspec +++ b/src/objective-c/BoringSSL.podspec @@ -67,8 +67,11 @@ Pod::Spec.new do |s| # "The name and email addresses of the library maintainers, not the Podspec maintainer." s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' - s.source = { :git => 'https://boringssl.googlesource.com/boringssl', - :tag => "version_for_cocoapods_#{version}" } + s.source = { + :git => 'https://boringssl.googlesource.com/boringssl', + # :tag => "version_for_cocoapods_#{version}", + :commit => '8d343b44bbab829d1a28fdef650ca95f7db4412e', + } name = 'openssl' From 0f594e91c668006646814d4216ca749fc3195b01 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 12:13:08 -0700 Subject: [PATCH 081/151] =?UTF-8?q?Write=20100=20times:=20=E2=80=9CgRPC-Co?= =?UTF-8?q?re.podspec=20is=20a=20template=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/gRPC-Core.podspec.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index aefe6e965cc24..f562ca596da4b 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -62,7 +62,7 @@ %> Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'http://www.grpc.io' @@ -147,7 +147,7 @@ ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL', '~> 4.0' + ss.dependency 'BoringSSL', '~> 5.0' # To save you from scrolling, this is the last part of the podspec. ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)} From 5c421ef8ab029d5d6a8fecea1708e3faf4373a0d Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 12:26:37 -0700 Subject: [PATCH 082/151] BoringSSL 5.0 is now tagged and pushed. --- src/objective-c/BoringSSL.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec index 9cbf6bfc9f7eb..b759997c11515 100644 --- a/src/objective-c/BoringSSL.podspec +++ b/src/objective-c/BoringSSL.podspec @@ -69,8 +69,8 @@ Pod::Spec.new do |s| s.source = { :git => 'https://boringssl.googlesource.com/boringssl', - # :tag => "version_for_cocoapods_#{version}", - :commit => '8d343b44bbab829d1a28fdef650ca95f7db4412e', + :tag => "version_for_cocoapods_#{version}", + # :commit => '8d343b44bbab829d1a28fdef650ca95f7db4412e', } name = 'openssl' From 854c16706965b225ce24475ebe405bf370ab61e1 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 12:30:01 -0700 Subject: [PATCH 083/151] =?UTF-8?q?We=E2=80=99re=20done=20with=20the=20und?= =?UTF-8?q?erscore=20tags=20for=20good!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Yay compatibility and predictability! --- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 3 +-- src/objective-c/!ProtoCompiler.podspec | 3 +-- templates/gRPC-Core.podspec.template | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index a102f9a76a3d4..cb243c80c7d47 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -44,7 +44,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules. :submodules => true, } diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index e27c294c630ca..1f1235c1ba24e 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -45,7 +45,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", } s.ios.deployment_target = '7.1' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index deca772db4152..05e64e5974250 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -45,7 +45,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", } s.ios.deployment_target = '7.1' diff --git a/gRPC.podspec b/gRPC.podspec index 4bfffe5dacf51..10a1f0f80ff30 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -45,7 +45,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", } s.ios.deployment_target = '7.1' diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 078e11c32e759..279549cfafc69 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -82,10 +82,9 @@ Pod::Spec.new do |s| s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } repo = 'grpc/grpc' - release = 'v1.0.x' file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip" s.source = { - :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}", + :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}", # TODO(jcanizales): Add sha1 or sha256 # :sha1 => '??', } diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 5e59b25aee284..56aacc3330512 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -97,10 +97,9 @@ Pod::Spec.new do |s| s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' } repo = 'google/protobuf' - release = "v#{v}" file = "protoc-#{v}-osx-x86_64.zip" s.source = { - :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}", + :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}", # TODO(jcanizales): Add sha1 or sha256 # :sha1 => '??', } diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index f562ca596da4b..b9f5d18d72313 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -71,7 +71,7 @@ s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules. :submodules => true, } From dd24c1ece4dd49b694588d6d4933879490875a04 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Wed, 13 Jul 2016 14:18:33 -0700 Subject: [PATCH 084/151] Polish grpcio_health_checking package -Rename namespace to grpc_health->grpc to match spec -Proper use of NOT_FOUND status code -Improve testing -Add source distribution to artifact build --- include/grpc/impl/codegen/port_platform.h | 2 +- setup.cfg | 2 +- src/python/grpcio_health_checking/MANIFEST.in | 3 +- .../health/v1 => grpc}/__init__.py | 2 +- .../{grpc_health => grpc/health}/__init__.py | 0 .../health => grpc/health/v1}/__init__.py | 0 .../{grpc_health => grpc}/health/v1/health.py | 19 +++--- .../grpcio_health_checking/grpc_version.py | 32 ++++++++++ .../grpcio_health_checking/health_commands.py | 29 ++++++---- src/python/grpcio_health_checking/setup.py | 23 +++----- src/python/grpcio_tests/commands.py | 2 +- src/python/grpcio_tests/setup.py | 2 +- .../health_check/_health_servicer_test.py | 58 +++++++++++++------ .../grpc_version.py.template | 34 +++++++++++ .../python/grpcio_tools/grpc/tools/command.py | 38 ++++++------ tools/run_tests/artifact_targets.py | 3 +- tools/run_tests/build_artifact_python.sh | 25 +++++--- tools/run_tests/build_python.sh | 3 +- 18 files changed, 187 insertions(+), 90 deletions(-) rename src/python/grpcio_health_checking/{grpc_health/health/v1 => grpc}/__init__.py (96%) rename src/python/grpcio_health_checking/{grpc_health => grpc/health}/__init__.py (100%) rename src/python/grpcio_health_checking/{grpc_health/health => grpc/health/v1}/__init__.py (100%) rename src/python/grpcio_health_checking/{grpc_health => grpc}/health/v1/health.py (81%) create mode 100644 src/python/grpcio_health_checking/grpc_version.py create mode 100644 templates/src/python/grpcio_health_checking/grpc_version.py.template diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 3ad665a7a297d..7c67bad5ae1af 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -119,7 +119,7 @@ // libraries; it should be integrated with the `__linux__` definitions below. #define GPR_PLATFORM_STRING "manylinux" #define GPR_POSIX_CRASH_HANDLER 1 -#define GPR_CPU_LINUX 1 +#define GPR_CPU_POSIX 1 #define GPR_GCC_ATOMIC 1 #define GPR_GCC_TLS 1 #define GPR_LINUX 1 diff --git a/setup.cfg b/setup.cfg index 7194716f61b29..dd9161ca8b90a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,5 +9,5 @@ build_base=python_build [build_ext] inplace=1 -[build_proto_modules] +[build_package_protos] exclude=.*protoc_plugin/protoc_plugin_test\.proto$ diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in index 7d26647697e1a..7407f646d1618 100644 --- a/src/python/grpcio_health_checking/MANIFEST.in +++ b/src/python/grpcio_health_checking/MANIFEST.in @@ -1,3 +1,4 @@ +include grpc_version.py include health_commands.py -graft grpc_health +graft grpc global-exclude *.pyc diff --git a/src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py b/src/python/grpcio_health_checking/grpc/__init__.py similarity index 96% rename from src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py rename to src/python/grpcio_health_checking/grpc/__init__.py index 708651910607f..fcc7048815f6b 100644 --- a/src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py +++ b/src/python/grpcio_health_checking/grpc/__init__.py @@ -27,4 +27,4 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - +__import__('pkg_resources').declare_namespace(__name__) diff --git a/src/python/grpcio_health_checking/grpc_health/__init__.py b/src/python/grpcio_health_checking/grpc/health/__init__.py similarity index 100% rename from src/python/grpcio_health_checking/grpc_health/__init__.py rename to src/python/grpcio_health_checking/grpc/health/__init__.py diff --git a/src/python/grpcio_health_checking/grpc_health/health/__init__.py b/src/python/grpcio_health_checking/grpc/health/v1/__init__.py similarity index 100% rename from src/python/grpcio_health_checking/grpc_health/health/__init__.py rename to src/python/grpcio_health_checking/grpc/health/v1/__init__.py diff --git a/src/python/grpcio_health_checking/grpc_health/health/v1/health.py b/src/python/grpcio_health_checking/grpc/health/v1/health.py similarity index 81% rename from src/python/grpcio_health_checking/grpc_health/health/v1/health.py rename to src/python/grpcio_health_checking/grpc/health/v1/health.py index 8da60c70cb1d6..8108ac1096200 100644 --- a/src/python/grpcio_health_checking/grpc_health/health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc/health/v1/health.py @@ -31,10 +31,12 @@ import threading -from grpc_health.health.v1 import health_pb2 +import grpc +from grpc.health.v1 import health_pb2 -class HealthServicer(health_pb2.BetaHealthServicer): + +class HealthServicer(health_pb2.HealthServicer): """Servicer handling RPCs for service statuses.""" def __init__(self): @@ -43,14 +45,12 @@ def __init__(self): def Check(self, request, context): with self._server_status_lock: - if request.service not in self._server_status: - # TODO(atash): once the Python API has a way of setting the server - # status, bring us into conformance with the health check spec by - # returning the NOT_FOUND status here. - raise NotImplementedError() + status = self._server_status.get(request.service) + if status is None: + context.set_code(grpc.StatusCode.NOT_FOUND) + return health_pb2.HealthCheckResponse() else: - return health_pb2.HealthCheckResponse( - status=self._server_status[request.service]) + return health_pb2.HealthCheckResponse(status=status) def set(self, service, status): """Sets the status of a service. @@ -63,4 +63,3 @@ def set(self, service, status): """ with self._server_status_lock: self._server_status[service] = status - diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py new file mode 100644 index 0000000000000..2e48fde8931ee --- /dev/null +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -0,0 +1,32 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! + +VERSION='1.0.0rc1' diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py index a7a59f6974b76..66df25da63f7c 100644 --- a/src/python/grpcio_health_checking/health_commands.py +++ b/src/python/grpcio_health_checking/health_commands.py @@ -29,16 +29,10 @@ """Provides distutils command classes for the GRPC Python setup process.""" -import distutils -import glob import os -import os.path import shutil -import subprocess -import sys import setuptools -from setuptools.command import build_py ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto') @@ -60,12 +54,25 @@ def run(self): if os.path.isfile(HEALTH_PROTO): shutil.copyfile( HEALTH_PROTO, - os.path.join(ROOT_DIR, 'grpc_health/health/v1/health.proto')) + os.path.join(ROOT_DIR, 'grpc/health/v1/health.proto')) -class BuildPy(build_py.build_py): - """Custom project build command.""" +class BuildPackageProtos(setuptools.Command): + """Command to generate project *_pb2.py modules from proto files.""" + + description = 'build grpc protobuf modules' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass def run(self): - self.run_command('build_proto_modules') - build_py.build_py.run(self) + # due to limitations of the proto generator, we require that only *one* + # directory is provided as an 'include' directory. We assume it's the '' key + # to `self.distribution.package_dir` (and get a key error if it's not + # there). + from grpc.tools import command + command.build_package_protos(self.distribution.package_dir['']) diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 70b4575bf5d1e..727d6288853d1 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -30,49 +30,42 @@ """Setup module for the GRPC Python package's optional health checking.""" import os -import os.path import sys -from distutils import core as _core import setuptools -import grpc.tools.command - # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) # Break import-style to ensure we can actually find our commands module. import health_commands - -PACKAGES = ( - setuptools.find_packages('.') -) +import grpc_version PACKAGE_DIRECTORIES = { '': '.', } SETUP_REQUIRES = ( - 'grpcio-tools>=0.14.0', + 'grpcio-tools>=0.15.0', ) INSTALL_REQUIRES = ( - 'grpcio>=0.13.1', + 'grpcio>=0.15.0', ) COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! 'preprocess': health_commands.CopyProtoModules, - - 'build_proto_modules': grpc.tools.command.BuildProtoModules, - 'build_py': health_commands.BuildPy, + 'build_package_protos': health_commands.BuildPackageProtos, } setuptools.setup( name='grpcio-health-checking', - version='0.14.0', - packages=list(PACKAGES), + version=grpc_version.VERSION, + license='3-clause BSD', package_dir=PACKAGE_DIRECTORIES, + packages=setuptools.find_packages('.'), + namespace_packages=['grpc'], install_requires=INSTALL_REQUIRES, setup_requires=SETUP_REQUIRES, cmdclass=COMMAND_CLASS diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 171829b62fccf..5ee551cfe1eab 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -138,7 +138,7 @@ class BuildPy(build_py.build_py): def run(self): try: - self.run_command('build_proto_modules') + self.run_command('build_package_protos') except CommandError as error: sys.stderr.write('warning: %s\n' % error.message) build_py.build_py.run(self) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index 7eef420bdb01e..0afaf7dfa2183 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -75,7 +75,7 @@ # Run `preprocess` *before* doing any packaging! 'preprocess': commands.GatherProto, - 'build_proto_modules': grpc.tools.command.BuildProtoModules, + 'build_package_protos': grpc.tools.command.BuildPackageProtos, 'build_py': commands.BuildPy, 'run_interop': commands.RunInterop, 'test_lite': commands.TestLite diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 1b6338866351d..80300d13df7cb 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -27,48 +27,68 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Tests of grpc_health.health.v1.health.""" +"""Tests of grpc.health.v1.health.""" import unittest -from grpc_health.health.v1 import health -from grpc_health.health.v1 import health_pb2 +import grpc +from grpc.framework.foundation import logging_pool +from grpc.health.v1 import health +from grpc.health.v1 import health_pb2 + +from tests.unit.framework.common import test_constants class HealthServicerTest(unittest.TestCase): def setUp(self): - self.servicer = health.HealthServicer() - self.servicer.set('', health_pb2.HealthCheckResponse.SERVING) - self.servicer.set('grpc.test.TestServiceServing', - health_pb2.HealthCheckResponse.SERVING) - self.servicer.set('grpc.test.TestServiceUnknown', - health_pb2.HealthCheckResponse.UNKNOWN) - self.servicer.set('grpc.test.TestServiceNotServing', - health_pb2.HealthCheckResponse.NOT_SERVING) + servicer = health.HealthServicer() + servicer.set('', health_pb2.HealthCheckResponse.SERVING) + servicer.set('grpc.test.TestServiceServing', + health_pb2.HealthCheckResponse.SERVING) + servicer.set('grpc.test.TestServiceUnknown', + health_pb2.HealthCheckResponse.UNKNOWN) + servicer.set('grpc.test.TestServiceNotServing', + health_pb2.HealthCheckResponse.NOT_SERVING) + server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY) + self._server = grpc.server(server_pool) + port = self._server.add_insecure_port('[::]:0') + health_pb2.add_HealthServicer_to_server(servicer, self._server) + self._server.start() + + channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = health_pb2.HealthStub(channel) def test_empty_service(self): request = health_pb2.HealthCheckRequest() - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) def test_serving_service(self): request = health_pb2.HealthCheckRequest( service='grpc.test.TestServiceServing') - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) def test_unknown_serivce(self): request = health_pb2.HealthCheckRequest( service='grpc.test.TestServiceUnknown') - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.UNKNOWN) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status) def test_not_serving_service(self): request = health_pb2.HealthCheckRequest( service='grpc.test.TestServiceNotServing') - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.NOT_SERVING) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status) + + def test_not_found_service(self): + request = health_pb2.HealthCheckRequest( + service='not-found') + with self.assertRaises(grpc.RpcError) as context: + resp = self._stub.Check(request) + + self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code()) if __name__ == '__main__': diff --git a/templates/src/python/grpcio_health_checking/grpc_version.py.template b/templates/src/python/grpcio_health_checking/grpc_version.py.template new file mode 100644 index 0000000000000..98946e95d3dbf --- /dev/null +++ b/templates/src/python/grpcio_health_checking/grpc_version.py.template @@ -0,0 +1,34 @@ +%YAML 1.2 +--- | + # Copyright 2016, Google Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! + + VERSION='${settings.python_version.pep440()}' diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/command.py b/tools/distrib/python/grpcio_tools/grpc/tools/command.py index ccf38b7d569e0..2520099835736 100644 --- a/tools/distrib/python/grpcio_tools/grpc/tools/command.py +++ b/tools/distrib/python/grpcio_tools/grpc/tools/command.py @@ -35,7 +35,26 @@ from grpc.tools import protoc -class BuildProtoModules(setuptools.Command): +def build_package_protos(package_root): + proto_files = [] + inclusion_root = os.path.abspath(package_root) + for root, _, files in os.walk(inclusion_root): + for filename in files: + if filename.endswith('.proto'): + proto_files.append(os.path.abspath(os.path.join(root, filename))) + + for proto_file in proto_files: + command = [ + 'grpc.tools.protoc', + '--proto_path={}'.format(inclusion_root), + '--python_out={}'.format(inclusion_root), + '--grpc_python_out={}'.format(inclusion_root), + ] + [proto_file] + if protoc.main(command) != 0: + sys.stderr.write('warning: {} failed'.format(command)) + + +class BuildPackageProtos(setuptools.Command): """Command to generate project *_pb2.py modules from proto files.""" description = 'build grpc protobuf modules' @@ -52,19 +71,4 @@ def run(self): # directory is provided as an 'include' directory. We assume it's the '' key # to `self.distribution.package_dir` (and get a key error if it's not # there). - proto_files = [] - inclusion_root = os.path.abspath(self.distribution.package_dir['']) - for root, _, files in os.walk(inclusion_root): - for filename in files: - if filename.endswith('.proto'): - proto_files.append(os.path.abspath(os.path.join(root, filename))) - - for proto_file in proto_files: - command = [ - 'grpc.tools.protoc', - '--proto_path={}'.format(inclusion_root), - '--python_out={}'.format(inclusion_root), - '--grpc_python_out={}'.format(inclusion_root), - ] + [proto_file] - if protoc.main(command) != 0: - sys.stderr.write('warning: {} failed'.format(command)) + build_package_protos(self.distribution.package_dir['']) diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py index b145e0392cef3..d9f8a2072c8ce 100644 --- a/tools/run_tests/artifact_targets.py +++ b/tools/run_tests/artifact_targets.py @@ -113,12 +113,12 @@ def build_jobspec(self): # special places... environ['PYTHON'] = '/opt/python/{}/bin/python'.format(self.manylinux_build) environ['PIP'] = '/opt/python/{}/bin/pip'.format(self.manylinux_build) - environ['SKIP_PIP_INSTALL'] = '1' # Platform autodetection for the manylinux1 image breaks so we set the # defines ourselves. # TODO(atash) get better platform-detection support in core so we don't # need to do this manually... environ['CFLAGS'] = '-DGPR_MANYLINUX1=1' + environ['BUILD_HEALTH_CHECKING'] = 'TRUE' return create_docker_jobspec(self.name, 'tools/dockerfile/grpc_artifact_python_manylinux_%s' % self.arch, 'tools/run_tests/build_artifact_python.sh', @@ -132,7 +132,6 @@ def build_jobspec(self): ], shell=True) else: - environ['SKIP_PIP_INSTALL'] = 'TRUE' environ['PYTHON'] = 'python{}'.format(self.python_version) return create_jobspec(self.name, ['tools/run_tests/build_artifact_python.sh'], diff --git a/tools/run_tests/build_artifact_python.sh b/tools/run_tests/build_artifact_python.sh index 55f8eb634ba7e..9c71235e11ca6 100755 --- a/tools/run_tests/build_artifact_python.sh +++ b/tools/run_tests/build_artifact_python.sh @@ -39,15 +39,6 @@ export PIP=${PIP:-pip} export AUDITWHEEL=${AUDITWHEEL:-auditwheel} -if [ "$SKIP_PIP_INSTALL" == "" ] -then - ${PIP} install --upgrade six - # There's a bug in newer versions of setuptools (see - # https://bitbucket.org/pypa/setuptools/issues/503/pkg_resources_vendorpackagingrequirementsi) - ${PIP} pip install --upgrade 'setuptools==18' - ${PIP} install -rrequirements.txt -fi - # Build the source distribution first because MANIFEST.in cannot override # exclusion of built shared objects among package resources (for some # inexplicable reason). @@ -81,5 +72,21 @@ then done fi +# We need to use the built grpcio-tools/grpcio to compile the health proto +# Wheels are not supported by setup_requires/dependency_links, so we +# manually install the dependency. Note we should only do this if we +# are in a docker image or in a virtualenv. +if [ "$BUILD_HEALTH_CHECKING" != "" ] +then + ${PIP} install -rrequirements.txt + ${PIP} install grpcio --no-index --find-links "file://${PWD}/artifacts/" + ${PIP} install grpcio-tools --no-index --find-links "file://${PWD}/artifacts/" + + # Build gRPC health check source distribution + ${SETARCH_CMD} ${PYTHON} src/python/grpcio_health_checking/setup.py \ + preprocess build_package_protos sdist + cp -r src/python/grpcio_health_checking/dist/* artifacts +fi + cp -r dist/* artifacts cp -r tools/distrib/python/grpcio_tools/dist/* artifacts diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh index a3fa8200d5db6..13d745d14fef1 100755 --- a/tools/run_tests/build_python.sh +++ b/tools/run_tests/build_python.sh @@ -177,7 +177,8 @@ pip_install_dir $ROOT/tools/distrib/python/grpcio_tools # etc... pip_install_dir $ROOT $VENV_PYTHON $ROOT/src/python/grpcio_health_checking/setup.py preprocess +$VENV_PYTHON $ROOT/src/python/grpcio_health_checking/setup.py build_package_protos pip_install_dir $ROOT/src/python/grpcio_health_checking $VENV_PYTHON $ROOT/src/python/grpcio_tests/setup.py preprocess -$VENV_PYTHON $ROOT/src/python/grpcio_tests/setup.py build_proto_modules +$VENV_PYTHON $ROOT/src/python/grpcio_tests/setup.py build_package_protos pip_install_dir $ROOT/src/python/grpcio_tests From 1318479011fa7d2e2859c20c89748b098618a5f8 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 18 Jul 2016 13:07:42 -0700 Subject: [PATCH 085/151] Separate generated file and protobuf dependency --- Makefile | 68 ++++++- build.yaml | 18 +- include/grpc++/impl/codegen/config_protobuf.h | 9 + src/cpp/ext/proto_server_reflection.h | 4 + test/cpp/end2end/async_end2end_test.cc | 40 +---- .../end2end/proto_server_reflection_test.cc | 24 ++- .../proto_reflection_descriptor_database.cc | 12 +- .../proto_reflection_descriptor_database.h | 22 ++- tools/run_tests/sources_and_headers.json | 40 ++++- .../grpc++_reflection_codegen.vcxproj | 168 ++++++++++++++++++ .../grpc++_reflection_codegen.vcxproj.filters | 27 +++ 11 files changed, 354 insertions(+), 78 deletions(-) create mode 100644 vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj create mode 100644 vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj.filters diff --git a/Makefile b/Makefile index 4ce22678d7e89..ab8da11a93df1 100644 --- a/Makefile +++ b/Makefile @@ -1184,9 +1184,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a endif @@ -1889,6 +1889,21 @@ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v1/lo $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif +ifeq ($(NO_PROTOC),true) +$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: protoc_dep_error +$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: protoc_dep_error +else +$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[PROTOC] Generating protobuf CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $< + +$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< +endif + ifeq ($(NO_PROTOC),true) $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: protoc_dep_error @@ -3709,6 +3724,55 @@ endif endif +LIBGRPC++_REFLECTION_CODEGEN_SRC = \ + $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBGRPC++_REFLECTION_CODEGEN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_CODEGEN_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_CODEGEN_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a + $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBGRPC++_REFLECTION_CODEGEN_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC++_REFLECTION_CODEGEN_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_TEST_CONFIG_SRC = \ test/cpp/util/test_config.cc \ diff --git a/build.yaml b/build.yaml index 57545839d43e8..4c9dbd046d3bd 100644 --- a/build.yaml +++ b/build.yaml @@ -768,6 +768,14 @@ filegroups: language: c++ public_headers: - include/grpc++/impl/codegen/config_protobuf.h +- name: grpc++_reflection_proto + language: c++ + public_headers: + - include/grpc++/ext/reflection.grpc.pb.h + - include/grpc++/ext/reflection.pb.h + src: + - src/cpp/ext/reflection.grpc.pb.cc + - src/cpp/ext/reflection.pb.cc libs: - name: gpr build: all @@ -960,19 +968,21 @@ libs: language: c++ public_headers: - include/grpc++/ext/proto_server_reflection_plugin.h - - include/grpc++/ext/reflection.grpc.pb.h - - include/grpc++/ext/reflection.pb.h headers: - src/cpp/ext/proto_server_reflection.h src: - src/cpp/ext/proto_server_reflection.cc - src/cpp/ext/proto_server_reflection_plugin.cc - - src/cpp/ext/reflection.grpc.pb.cc - - src/cpp/ext/reflection.pb.cc deps: - grpc++ filegroups: + - grpc++_reflection_proto - grpc++_codegen_proto +- name: grpc++_reflection_codegen + build: private + language: c++ + src: + - src/proto/grpc/reflection/v1alpha/reflection.proto - name: grpc++_test_config build: private language: c++ diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h index 318ba5968315e..ea7b9777912fc 100644 --- a/include/grpc++/impl/codegen/config_protobuf.h +++ b/include/grpc++/impl/codegen/config_protobuf.h @@ -57,6 +57,13 @@ #define GRPC_CUSTOM_SOURCELOCATION ::google::protobuf::SourceLocation #endif +#ifndef GRPC_CUSTOM_DESCRIPTORDATABASE +#include +#define GRPC_CUSTOM_DESCRIPTORDATABASE ::google::protobuf::DescriptorDatabase +#define GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE \ + ::google::protobuf::SimpleDescriptorDatabase +#endif + #ifndef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM #include #include @@ -75,11 +82,13 @@ typedef GRPC_CUSTOM_PROTOBUF_INT64 int64; typedef GRPC_CUSTOM_DESCRIPTOR Descriptor; typedef GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool; +typedef GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase; typedef GRPC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto; typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor; typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor; +typedef GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase; typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation; namespace io { diff --git a/src/cpp/ext/proto_server_reflection.h b/src/cpp/ext/proto_server_reflection.h index 23c130513d1a6..1a9a0c95a8633 100644 --- a/src/cpp/ext/proto_server_reflection.h +++ b/src/cpp/ext/proto_server_reflection.h @@ -36,7 +36,11 @@ #include #include +#ifdef GRPC_NO_GENERATED_CODE +#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" +#else #include +#endif // GRPC_NO_GENERATED_CODE #include namespace grpc { diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 4a8936d281020..084d6db5006a7 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -200,6 +200,10 @@ class Verifier { bool spin_; }; +bool plugin_has_sync_methods(std::unique_ptr& plugin) { + return plugin->has_sync_methods(); +} + // This class disables the server builder plugins that may add sync services to // the server. If there are sync services, UnimplementedRpc test will triger // the sync unkown rpc routine on the server side, rather than the async one @@ -210,14 +214,9 @@ class ServerBuilderSyncPluginDisabler : public ::grpc::ServerBuilderOption { void UpdatePlugins(std::vector>* plugins) GRPC_OVERRIDE { - auto plugin = plugins->begin(); - while (plugin != plugins->end()) { - if ((*plugin)->has_sync_methods()) { - plugins->erase(plugin++); - } else { - plugin++; - } - } + plugins->erase(std::remove_if(plugins->begin(), plugins->end(), + plugin_has_sync_methods), + plugins->end()); } }; @@ -345,31 +344,6 @@ TEST_P(AsyncEnd2endTest, SequentialRpcs) { SendRpc(10); } -// We do not need to protect notify because the use is synchronized. -void ServerWait(Server* server, int* notify) { - server->Wait(); - *notify = 1; -} -TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) { - int notify = 0; - std::thread* wait_thread = - new std::thread(&ServerWait, server_.get(), ¬ify); - ResetStub(); - SendRpc(1); - EXPECT_EQ(0, notify); - server_->Shutdown(); - wait_thread->join(); - EXPECT_EQ(1, notify); - delete wait_thread; -} - -TEST_P(AsyncEnd2endTest, ShutdownThenWait) { - ResetStub(); - SendRpc(1); - server_->Shutdown(); - server_->Wait(); -} - // Test a simple RPC using the async version of Next TEST_P(AsyncEnd2endTest, AsyncNextRpc) { ResetStub(); diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc index f8fc39b553518..efbb0e1f8e5f6 100644 --- a/test/cpp/end2end/proto_server_reflection_test.cc +++ b/test/cpp/end2end/proto_server_reflection_test.cc @@ -31,7 +31,6 @@ * */ -#include #include #include #include @@ -59,7 +58,7 @@ class ProtoServerReflectionTest : public ::testing::Test { void SetUp() GRPC_OVERRIDE { port_ = grpc_pick_unused_port_or_die(); - ref_desc_pool_ = google::protobuf::DescriptorPool::generated_pool(); + ref_desc_pool_ = protobuf::DescriptorPool::generated_pool(); ServerBuilder builder; grpc::string server_address = "localhost:" + to_string(port_); @@ -73,7 +72,7 @@ class ProtoServerReflectionTest : public ::testing::Test { CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); desc_db_.reset(new ProtoReflectionDescriptorDatabase(channel)); - desc_pool_.reset(new google::protobuf::DescriptorPool(desc_db_.get())); + desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); } string to_string(const int number) { @@ -83,15 +82,15 @@ class ProtoServerReflectionTest : public ::testing::Test { } void CompareService(const grpc::string& service) { - const google::protobuf::ServiceDescriptor* service_desc = + const protobuf::ServiceDescriptor* service_desc = desc_pool_->FindServiceByName(service); - const google::protobuf::ServiceDescriptor* ref_service_desc = + const protobuf::ServiceDescriptor* ref_service_desc = ref_desc_pool_->FindServiceByName(service); EXPECT_TRUE(service_desc != nullptr); EXPECT_TRUE(ref_service_desc != nullptr); EXPECT_EQ(service_desc->DebugString(), ref_service_desc->DebugString()); - const google::protobuf::FileDescriptor* file_desc = service_desc->file(); + const protobuf::FileDescriptor* file_desc = service_desc->file(); if (known_files_.find(file_desc->package() + "/" + file_desc->name()) != known_files_.end()) { EXPECT_EQ(file_desc->DebugString(), @@ -105,9 +104,9 @@ class ProtoServerReflectionTest : public ::testing::Test { } void CompareMethod(const grpc::string& method) { - const google::protobuf::MethodDescriptor* method_desc = + const protobuf::MethodDescriptor* method_desc = desc_pool_->FindMethodByName(method); - const google::protobuf::MethodDescriptor* ref_method_desc = + const protobuf::MethodDescriptor* ref_method_desc = ref_desc_pool_->FindMethodByName(method); EXPECT_TRUE(method_desc != nullptr); EXPECT_TRUE(ref_method_desc != nullptr); @@ -122,9 +121,8 @@ class ProtoServerReflectionTest : public ::testing::Test { return; } - const google::protobuf::Descriptor* desc = - desc_pool_->FindMessageTypeByName(type); - const google::protobuf::Descriptor* ref_desc = + const protobuf::Descriptor* desc = desc_pool_->FindMessageTypeByName(type); + const protobuf::Descriptor* ref_desc = ref_desc_pool_->FindMessageTypeByName(type); EXPECT_TRUE(desc != nullptr); EXPECT_TRUE(ref_desc != nullptr); @@ -135,10 +133,10 @@ class ProtoServerReflectionTest : public ::testing::Test { std::unique_ptr server_; std::unique_ptr stub_; std::unique_ptr desc_db_; - std::unique_ptr desc_pool_; + std::unique_ptr desc_pool_; std::unordered_set known_files_; std::unordered_set known_types_; - const google::protobuf::DescriptorPool* ref_desc_pool_; + const protobuf::DescriptorPool* ref_desc_pool_; int port_; reflection::ProtoServerReflectionPlugin plugin_; }; diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index 25b720aee0a36..ebfcc27e2f295 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -56,7 +56,7 @@ ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() {} bool ProtoReflectionDescriptorDatabase::FindFileByName( - const string& filename, google::protobuf::FileDescriptorProto* output) { + const string& filename, protobuf::FileDescriptorProto* output) { if (cached_db_.FindFileByName(filename, output)) { return true; } @@ -101,7 +101,7 @@ bool ProtoReflectionDescriptorDatabase::FindFileByName( } bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, google::protobuf::FileDescriptorProto* output) { + const string& symbol_name, protobuf::FileDescriptorProto* output) { if (cached_db_.FindFileContainingSymbol(symbol_name, output)) { return true; } @@ -148,7 +148,7 @@ bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol( bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension( const string& containing_type, int field_number, - google::protobuf::FileDescriptorProto* output) { + protobuf::FileDescriptorProto* output) { if (cached_db_.FindFileContainingExtension(containing_type, field_number, output)) { return true; @@ -276,10 +276,10 @@ bool ProtoReflectionDescriptorDatabase::GetServices( return false; } -const google::protobuf::FileDescriptorProto +const protobuf::FileDescriptorProto ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse( const std::string& byte_fd_proto) { - google::protobuf::FileDescriptorProto file_desc_proto; + protobuf::FileDescriptorProto file_desc_proto; file_desc_proto.ParseFromString(byte_fd_proto); return file_desc_proto; } @@ -287,7 +287,7 @@ ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse( void ProtoReflectionDescriptorDatabase::AddFileFromResponse( const grpc::reflection::v1alpha::FileDescriptorResponse& response) { for (int i = 0; i < response.file_descriptor_proto_size(); ++i) { - const google::protobuf::FileDescriptorProto file_proto = + const protobuf::FileDescriptorProto file_proto = ParseFileDescriptorProtoResponse(response.file_descriptor_proto(i)); if (known_files_.find(file_proto.name()) == known_files_.end()) { known_files_.insert(file_proto.name()); diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index 99c00675bb368..182323b2ec578 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -38,19 +38,18 @@ #include #include -#include -#include -#include +#ifdef GRPC_NO_GENERATED_CODE +#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" +#else #include +#endif // GRPC_NO_GENERATED_CODE #include - namespace grpc { // ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and // provides the methods defined by DescriptorDatabase interfaces. It can be used // to feed a DescriptorPool instance. -class ProtoReflectionDescriptorDatabase - : public google::protobuf::DescriptorDatabase { +class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { public: explicit ProtoReflectionDescriptorDatabase( std::unique_ptr stub); @@ -65,14 +64,13 @@ class ProtoReflectionDescriptorDatabase // Find a file by file name. Fills in in *output and returns true if found. // Otherwise, returns false, leaving the contents of *output undefined. bool FindFileByName(const string& filename, - google::protobuf::FileDescriptorProto* output) - GRPC_OVERRIDE; + protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; // Find the file that declares the given fully-qualified symbol name. // If found, fills in *output and returns true, otherwise returns false // and leaves *output undefined. bool FindFileContainingSymbol(const string& symbol_name, - google::protobuf::FileDescriptorProto* output) + protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; // Find the file which defines an extension extending the given message type @@ -81,7 +79,7 @@ class ProtoReflectionDescriptorDatabase // must be a fully-qualified type name. bool FindFileContainingExtension( const string& containing_type, int field_number, - google::protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; + protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; // Finds the tag numbers used by all known extensions of // extendee_type, and appends them to output in an undefined @@ -102,7 +100,7 @@ class ProtoReflectionDescriptorDatabase grpc::reflection::v1alpha::ServerReflectionResponse> ClientStream; - const google::protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse( + const protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse( const std::string& byte_fd_proto); void AddFileFromResponse( @@ -123,7 +121,7 @@ class ProtoReflectionDescriptorDatabase std::unordered_map> cached_extension_numbers_; std::mutex stream_mutex_; - google::protobuf::SimpleDescriptorDatabase cached_db_; + protobuf::SimpleDescriptorDatabase cached_db_; }; } // namespace grpc diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index e3cfd55cd62f1..451f535a2aab6 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4360,26 +4360,33 @@ { "deps": [ "grpc++", - "grpc++_codegen_proto" + "grpc++_codegen_proto", + "grpc++_reflection_proto" ], "headers": [ "include/grpc++/ext/proto_server_reflection_plugin.h", - "include/grpc++/ext/reflection.grpc.pb.h", - "include/grpc++/ext/reflection.pb.h", "src/cpp/ext/proto_server_reflection.h" ], "language": "c++", "name": "grpc++_reflection", "src": [ "include/grpc++/ext/proto_server_reflection_plugin.h", - "include/grpc++/ext/reflection.grpc.pb.h", - "include/grpc++/ext/reflection.pb.h", "src/cpp/ext/proto_server_reflection.cc", "src/cpp/ext/proto_server_reflection.h", - "src/cpp/ext/proto_server_reflection_plugin.cc", - "src/cpp/ext/reflection.grpc.pb.cc", - "src/cpp/ext/reflection.pb.cc" + "src/cpp/ext/proto_server_reflection_plugin.cc" + ], + "third_party": false, + "type": "lib" + }, + { + "deps": [], + "headers": [ + "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h", + "src/proto/grpc/reflection/v1alpha/reflection.pb.h" ], + "language": "c++", + "name": "grpc++_reflection_codegen", + "src": [], "third_party": false, "type": "lib" }, @@ -6751,5 +6758,22 @@ ], "third_party": false, "type": "filegroup" + }, + { + "deps": [], + "headers": [ + "include/grpc++/ext/reflection.grpc.pb.h", + "include/grpc++/ext/reflection.pb.h" + ], + "language": "c++", + "name": "grpc++_reflection_proto", + "src": [ + "include/grpc++/ext/reflection.grpc.pb.h", + "include/grpc++/ext/reflection.pb.h", + "src/cpp/ext/reflection.grpc.pb.cc", + "src/cpp/ext/reflection.pb.cc" + ], + "third_party": false, + "type": "filegroup" } ] diff --git a/vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj b/vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj new file mode 100644 index 0000000000000..d9e10c2d37e1e --- /dev/null +++ b/vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C8A925BF-4373-D85D-60AE-96CDCBBF33F2} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + grpc++_reflection_codegen + + + grpc++_reflection_codegen + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + diff --git a/vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj.filters b/vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj.filters new file mode 100644 index 0000000000000..577dcc77d8ff5 --- /dev/null +++ b/vsprojects/vcxproj/grpc++_reflection_codegen/grpc++_reflection_codegen.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + src\proto\grpc\reflection\v1alpha + + + + + + {d6f45d49-92db-00f7-3dd4-e53f5768d80c} + + + {32b951f4-cef1-24a3-ffb9-bb229f0cdd6a} + + + {8fdcb9f3-4d86-2f49-5c15-c92e0e0f4fba} + + + {098a074c-f3de-2840-8009-1a3840af1efc} + + + {219ff371-7d3a-130c-5792-be36514a4e98} + + + + From f8f70ebb2be4ea72ac77fc4b35c75e58adb77198 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 18 Jul 2016 13:32:48 -0700 Subject: [PATCH 086/151] Update cronet test comments and structure --- .../CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m | 11 ++++++++++- .../{h2_ssl_cronet.h => fixture.h} | 7 +------ .../tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m | 3 +++ src/objective-c/tests/Tests.xcodeproj/project.pbxproj | 4 ++-- 4 files changed, 16 insertions(+), 9 deletions(-) rename src/objective-c/tests/CoreCronetEnd2EndTests/{h2_ssl_cronet.h => fixture.h} (93%) diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index 097e3686749d6..b0e58fe2ed781 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -32,7 +32,7 @@ */ #import -#include "./h2_ssl_cronet.h" +#import "src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h" @interface CoreCronetEnd2EndTests : XCTestCase @@ -42,6 +42,15 @@ @implementation CoreCronetEnd2EndTests - (void)testCoreCronetEnd2End { char *argv[] = {"h2_ssl"}; + + // This main() function is not the entry point of this test case; it + // refers to that in h2_ssl_cronet.m. We can use it because XCode + // builder does not use main() as the entry point for a test. + // Since h2_ssl_cronet.m is derived from h2_ssl.c in the core end2end + // test fixture, we preserves the fixture structure (in particular + // the main() function here) so that another fixture can easily + // replace the fixture h2_ssl_cronet, in case we need more tests in + // the future main(1, argv); } diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.h b/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h similarity index 93% rename from src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.h rename to src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h index 3aa0a05ddadef..31e36a71f2a45 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.h +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h @@ -31,9 +31,4 @@ * */ -#ifndef GRPC_H2_SSL_H -#define GRPC_H2_SSL_H - -int main(int argc, char **argv); - -#endif /* GRPC_H2_SSL_H */ \ No newline at end of file +int main(int argc, char **argv); \ No newline at end of file diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m index dfa27abf8d096..37d98b793c83b 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m @@ -32,6 +32,9 @@ */ /* + * This fixture derives from h2_ssl.c fixture in core end2end test + * (test/core/end2end/fixture/h2_ssl.c) + * * This fixture creates a server full stack using chttp2 and a client * full stack using Cronet. End-to-end tests are run against this fixture * setting. diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 9b7d23728cab4..c1fd8afa23c66 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -110,8 +110,8 @@ 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; - 5E1BD3B01D3D583900A47325 /* h2_ssl_cronet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = h2_ssl_cronet.h; sourceTree = ""; }; 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl_cronet.m; sourceTree = ""; }; + 5E1BD3B31D3D736C00A47325 /* fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fixture.h; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; @@ -252,7 +252,7 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( - 5E1BD3B01D3D583900A47325 /* h2_ssl_cronet.h */, + 5E1BD3B31D3D736C00A47325 /* fixture.h */, 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */, 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */, ); From 9afdd01e6901fe1f6be68c4242e68332e58efed0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 18 Jul 2016 13:35:30 -0700 Subject: [PATCH 087/151] Rename h2_ssl_cronet.m to fixture_h2_ssl_cronet.m --- .../{h2_ssl_cronet.m => fixture_h2_ssl_cronet.m} | 0 src/objective-c/tests/Tests.xcodeproj/project.pbxproj | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/objective-c/tests/CoreCronetEnd2EndTests/{h2_ssl_cronet.m => fixture_h2_ssl_cronet.m} (100%) diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m b/src/objective-c/tests/CoreCronetEnd2EndTests/fixture_h2_ssl_cronet.m similarity index 100% rename from src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl_cronet.m rename to src/objective-c/tests/CoreCronetEnd2EndTests/fixture_h2_ssl_cronet.m diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index c1fd8afa23c66..8de0fdcb8e5d1 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -12,7 +12,7 @@ 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; }; - 5E1BD3B21D3D583900A47325 /* h2_ssl_cronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */; }; + 5E1BD3B51D3D74EC00A47325 /* fixture_h2_ssl_cronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E1BD3B41D3D74EC00A47325 /* fixture_h2_ssl_cronet.m */; }; 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */; }; 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */; }; @@ -110,8 +110,8 @@ 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; - 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl_cronet.m; sourceTree = ""; }; 5E1BD3B31D3D736C00A47325 /* fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fixture.h; sourceTree = ""; }; + 5E1BD3B41D3D74EC00A47325 /* fixture_h2_ssl_cronet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = fixture_h2_ssl_cronet.m; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; @@ -252,8 +252,8 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( + 5E1BD3B41D3D74EC00A47325 /* fixture_h2_ssl_cronet.m */, 5E1BD3B31D3D736C00A47325 /* fixture.h */, - 5E1BD3B11D3D583900A47325 /* h2_ssl_cronet.m */, 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */, ); path = CoreCronetEnd2EndTests; @@ -868,7 +868,7 @@ buildActionMask = 2147483647; files = ( 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */, - 5E1BD3B21D3D583900A47325 /* h2_ssl_cronet.m in Sources */, + 5E1BD3B51D3D74EC00A47325 /* fixture_h2_ssl_cronet.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From abdff3df896e4e0ed0bf76983831bff6484ee75f Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Mon, 18 Jul 2016 13:26:25 -0700 Subject: [PATCH 088/151] Clean imports in grpcio's `setup.py` --- setup.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 5d33756c19147..24414457cd5f3 100644 --- a/setup.py +++ b/setup.py @@ -29,17 +29,16 @@ """A setup module for the GRPC Python package.""" +from distutils import extension as _extension import os import os.path +import pkg_resources import platform import shlex import shutil import sys import sysconfig -from distutils import core as _core -from distutils import extension as _extension -import pkg_resources import setuptools from setuptools.command import egg_info From 7c32959390881e3236dd5c61d28660271bd4289a Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 18 Jul 2016 14:22:01 -0700 Subject: [PATCH 089/151] Updated outdated comment about uchannels --- src/core/ext/client_config/channel_connectivity.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/ext/client_config/channel_connectivity.c b/src/core/ext/client_config/channel_connectivity.c index c1220e3a8c354..03db06c2f741c 100644 --- a/src/core/ext/client_config/channel_connectivity.c +++ b/src/core/ext/client_config/channel_connectivity.c @@ -59,8 +59,7 @@ grpc_connectivity_state grpc_channel_check_connectivity_state( } gpr_log(GPR_ERROR, "grpc_channel_check_connectivity_state called on something that is " - "not a (u)client channel, but '%s'", - client_channel_elem->filter->name); + "not a client channel, but '%s'", client_channel_elem->filter->name); grpc_exec_ctx_finish(&exec_ctx); return GRPC_CHANNEL_SHUTDOWN; } From 791c4d7b7c89d68a3eda7e66a35ace852030caf8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 18 Jul 2016 15:12:19 -0700 Subject: [PATCH 090/151] Add new line to the end of fixture.h --- src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h b/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h index 31e36a71f2a45..45fbfc4bc823d 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h @@ -31,4 +31,5 @@ * */ -int main(int argc, char **argv); \ No newline at end of file +int main(int argc, char **argv); + From e39edac2c84f5a5195b09cca4bd9628a90318c12 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Tue, 12 Jul 2016 08:47:15 -0700 Subject: [PATCH 091/151] Fixed name syntax error --- src/python/grpcio/grpc/_channel.py | 4 ++-- src/python/grpcio/grpc/beta/_client_adaptations.py | 10 ++++++---- .../_future_invocation_asynchronous_event_service.py | 6 ++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 29dbc3a668ba5..3117dd1cb3140 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -353,12 +353,12 @@ def time_remaining(self): else: return max(self._deadline - time.time(), 0) - def add_cancellation_callback(self, callback): + def add_callback(self, callback): with self._state.condition: if self._state.callbacks is None: return False else: - self._state.callbacks.append(lambda unused_future: callback()) + self._state.callbacks.append(lambda: callback()) return True def initial_metadata(self): diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py index 73415e0be7f34..e4ee44d7a3e25 100644 --- a/src/python/grpcio/grpc/beta/_client_adaptations.py +++ b/src/python/grpcio/grpc/beta/_client_adaptations.py @@ -67,7 +67,7 @@ def _abortion(rpc_error_call): error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0] return face.Abortion( error_kind, rpc_error_call.initial_metadata(), - rpc_error_call.trailing_metadata(), code, rpc_error_code.details()) + rpc_error_call.trailing_metadata(), code, rpc_error_call.details()) def _abortion_error(rpc_error_call): @@ -159,9 +159,11 @@ def time_remaining(self): return self._call.time_remaining() def add_abortion_callback(self, abortion_callback): - registered = self._call.add_callback( - lambda: abortion_callback(_abortion(self._call))) - return None if registered else _abortion(self._call) + def done_callback(): + if self.code() is not grpc.StatusCode.OK: + abortion_callback(_abortion(self._call)) + registered = self._call.add_callback(done_callback) + return None if registered else done_callback() def protocol_context(self): return _InvocationProtocolContext() diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py index d32208f9eb059..df620b19ba5b7 100644 --- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py +++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py @@ -434,11 +434,13 @@ def testFailedUnaryRequestUnaryResponse(self): for test_messages in test_messages_sequence: request = test_messages.request() callback = _Callback() + abortion_callback = _Callback() with self._control.fail(): response_future = self._invoker.future(group, method)( request, _3069_test_constant.REALLY_SHORT_TIMEOUT) response_future.add_done_callback(callback) + response_future.add_abortion_callback(abortion_callback) self.assertIs(callback.future(), response_future) # Because the servicer fails outside of the thread from which the @@ -450,6 +452,7 @@ def testFailedUnaryRequestUnaryResponse(self): with self.assertRaises(face.ExpirationError): response_future.result() self.assertIsNotNone(response_future.traceback()) + self.assertIsNotNone(abortion_callback.future()) def testFailedUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( @@ -472,11 +475,13 @@ def testFailedStreamRequestUnaryResponse(self): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = _Callback() + abortion_callback = _Callback() with self._control.fail(): response_future = self._invoker.future(group, method)( iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT) response_future.add_done_callback(callback) + response_future.add_abortion_callback(abortion_callback) self.assertIs(callback.future(), response_future) # Because the servicer fails outside of the thread from which the @@ -488,6 +493,7 @@ def testFailedStreamRequestUnaryResponse(self): with self.assertRaises(face.ExpirationError): response_future.result() self.assertIsNotNone(response_future.traceback()) + self.assertIsNotNone(abortion_callback.future()) def testFailedStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( From f8c4580939cb6c89efad981800dbad8b06dcb173 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 17:51:31 -0700 Subject: [PATCH 092/151] Commit as 1.0.0-pre1 so we can release already. --- examples/objective-c/auth_sample/AuthTestService.podspec | 2 +- examples/objective-c/helloworld/HelloWorld.podspec | 2 +- examples/objective-c/route_guide/RouteGuide.podspec | 2 +- gRPC-Core.podspec | 4 ++-- gRPC-ProtoRPC.podspec | 4 ++-- gRPC-RxLibrary.podspec | 4 ++-- gRPC.podspec | 4 ++-- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 5 +++-- src/objective-c/examples/RemoteTestClient/RemoteTest.podspec | 2 +- src/objective-c/tests/RemoteTestClient/RemoteTest.podspec | 2 +- templates/gRPC-Core.podspec.template | 4 ++-- 11 files changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec index 1df6f98ad5bdb..d709c7e636f7a 100644 --- a/examples/objective-c/auth_sample/AuthTestService.podspec +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec index 11c7fb3bcf002..48364fc0af1c3 100644 --- a/examples/objective-c/helloworld/HelloWorld.podspec +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec index 729b45f87a2d3..04bc10bc0b5a7 100644 --- a/examples/objective-c/route_guide/RouteGuide.podspec +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index cb243c80c7d47..4c82f12432dfa 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -35,7 +35,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.0.0' + version = '1.0.0-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'http://www.grpc.io' @@ -44,7 +44,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "v#{version}", + :tag => "objective-c-v#{version}", # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules. :submodules => true, } diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 1f1235c1ba24e..741067b23f420 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.0.0' + version = '1.0.0-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'http://www.grpc.io' @@ -45,7 +45,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "v#{version}", + :tag => "objective-c-v#{version}", } s.ios.deployment_target = '7.1' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 05e64e5974250..862ed8974ba43 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.0.0' + version = '1.0.0-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'http://www.grpc.io' @@ -45,7 +45,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "v#{version}", + :tag => "objective-c-v#{version}", } s.ios.deployment_target = '7.1' diff --git a/gRPC.podspec b/gRPC.podspec index 10a1f0f80ff30..eda965a3280ac 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.0.0' + version = '1.0.0-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'http://www.grpc.io' @@ -45,7 +45,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "v#{version}", + :tag => "objective-c-v#{version}", } s.ios.deployment_target = '7.1' diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 279549cfafc69..97f4f586b729d 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.0.0' + v = '1.0.0-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC @@ -82,9 +82,10 @@ Pod::Spec.new do |s| s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } repo = 'grpc/grpc' + release = "objective-c-v#{v}" file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip" s.source = { - :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}", + :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}", # TODO(jcanizales): Add sha1 or sha256 # :sha1 => '??', } diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index 8839b81b616a1..7222a80b887e0 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 30173a332f453..53ba101913139 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index b9f5d18d72313..cf7ec31a8e1f0 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -62,7 +62,7 @@ %> Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.0.0' + version = '1.0.0-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'http://www.grpc.io' @@ -71,7 +71,7 @@ s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "v#{version}", + :tag => "objective-c-v#{version}", # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules. :submodules => true, } From 886eecf1e06ae762ba31cd0e5ef6d81955e448dd Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 17:54:03 -0700 Subject: [PATCH 093/151] Fixup: Readme to 1.0.0-pre1 too instead of 1.0.0 --- src/objective-c/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/README.md b/src/objective-c/README.md index 22f0bdd09b8eb..6e917ddd813bd 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -48,7 +48,7 @@ Pod::Spec.new do |s| src = '.' # We'll use protoc with the gRPC plugin. - s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0' + s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0.0-pre1' # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = '/Pods' From e8355a2cb360ad3ed95ce62039b73838a7e36216 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 18 Jul 2016 18:56:56 -0700 Subject: [PATCH 094/151] grpc_args doxygen --- include/grpc/impl/codegen/compression_types.h | 17 ++++++++- include/grpc/impl/codegen/grpc_types.h | 38 +++++++++++-------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h index 9065d1edd0279..3034182d4c574 100644 --- a/include/grpc/impl/codegen/compression_types.h +++ b/include/grpc/impl/codegen/compression_types.h @@ -46,12 +46,27 @@ extern "C" { #define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \ "grpc-internal-encoding-request" -/** To be used in channel arguments */ +/** To be used in channel arguments. + * + * \addtogroup grpc_arg_keys + * \{ */ +/** Default compression algorithm for the channel. + * Its value is an int from the \a grpc_compression_algorithm enum. */ #define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \ "grpc.default_compression_algorithm" +/** Default compression level for the channel. + * Its value is an int from the \a grpc_compression_level enum. */ #define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL "grpc.default_compression_level" +/** Compression algorithms supported by the channel. + * Its value is a bitset (an int). Bits correspond to algorithms in \a + * grpc_compression_algorithm. For example, its LSB corresponds to + * GRPC_COMPRESS_NONE, the next bit to GRPC_COMPRESS_DEFLATE, etc. + * Unset bits disable support for the algorithm. By default all algorithms are + * supported. It's not possible to disable GRPC_COMPRESS_NONE (the attempt will + * be ignored). */ #define GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \ "grpc.compression_enabled_algorithms_bitset" +/** \} */ /* The various compression algorithms supported by gRPC */ typedef enum { diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index c0ed13950662a..e5a82883be548 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -106,58 +106,66 @@ typedef struct { by grpc_arg; keys are strings to allow easy backwards-compatible extension by arbitrary parties. All evaluation is performed at channel creation time (i.e. the values in - this structure need only live through the creation invocation). */ + this structure need only live through the creation invocation). + + See the description of the \ref grpc_arg_keys "available args" for more + details. */ typedef struct { size_t num_args; grpc_arg *args; } grpc_channel_args; -/* Channel argument keys: */ -/** Enable census for tracing and stats collection */ +/** \defgroup grpc_arg_keys + * Channel argument keys. + * \{ + */ +/** If non-zero, enable census for tracing and stats collection. */ #define GRPC_ARG_ENABLE_CENSUS "grpc.census" -/** Enable load reporting */ +/** If non-zero, enable load reporting. */ #define GRPC_ARG_ENABLE_LOAD_REPORTING "grpc.loadreporting" /** Maximum number of concurrent incoming streams to allow on a http2 - connection */ + connection. Int valued. */ #define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams" -/** Maximum message length that the channel can receive */ +/** Maximum message length that the channel can receive. Int valued, bytes. */ #define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length" -/** Initial sequence number for http2 transports */ +/** Initial sequence number for http2 transports. Int valued. */ #define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \ "grpc.http2.initial_sequence_number" /** Amount to read ahead on individual streams. Defaults to 64kb, larger values can help throughput on high-latency connections. NOTE: at some point we'd like to auto-tune this, and this parameter - will become a no-op. */ + will become a no-op. Int valued, bytes. */ #define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes" -/** How much memory to use for hpack decoding */ +/** How much memory to use for hpack decoding. Int valued, bytes. */ #define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \ "grpc.http2.hpack_table_size.decoder" -/** How much memory to use for hpack encoding */ +/** How much memory to use for hpack encoding. Int valued, bytes. */ #define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \ "grpc.http2.hpack_table_size.encoder" -/** Default authority to pass if none specified on call construction */ +/** Default authority to pass if none specified on call construction. A string. + * */ #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority" /** Primary user agent: goes at the start of the user-agent metadata - sent on each request */ + sent on each request. A string. */ #define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent" /** Secondary user agent: goes at the end of the user-agent metadata - sent on each request */ + sent on each request. A string. */ #define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent" /** The maximum time between subsequent connection attempts, in ms */ #define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms" /* The caller of the secure_channel_create functions may override the target name used for SSL host name checking using this channel argument which is of - type GRPC_ARG_STRING. This *should* be used for testing only. + type \a GRPC_ARG_STRING. This *should* be used for testing only. If this argument is not specified, the name used for SSL host name checking will be the target parameter (assuming that the secure channel is an SSL channel). If this parameter is specified and the underlying is not an SSL channel, it will just be ignored. */ #define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override" -/* Maximum metadata size */ +/* Maximum metadata size, in bytes. */ #define GRPC_ARG_MAX_METADATA_SIZE "grpc.max_metadata_size" /** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */ #define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport" +/** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a particular operation, the grpc_call_error returned will be GRPC_CALL_OK. From 398b06e8432e5e9007349b7c89ae6b67e02c1035 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Fri, 15 Jul 2016 23:17:41 -0700 Subject: [PATCH 095/151] Force the Python host version on Mac OS X --- setup.py | 6 ++++++ tools/distrib/python/grpcio_tools/setup.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/setup.py b/setup.py index 24414457cd5f3..b43ec9ae3d475 100644 --- a/setup.py +++ b/setup.py @@ -30,10 +30,12 @@ """A setup module for the GRPC Python package.""" from distutils import extension as _extension +from distutils import util import os import os.path import pkg_resources import platform +import re import shlex import shutil import sys @@ -133,6 +135,10 @@ if mac_target and (pkg_resources.parse_version(mac_target) < pkg_resources.parse_version('10.7.0')): os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7' + os.environ['_PYTHON_HOST_PLATFORM'] = re.sub( + r'macosx-[0-9]+\.[0-9]+-(.+)', + r'macosx-10.7-\1', + util.get_platform()) def cython_extensions(module_names, extra_sources, include_dirs, diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index a00ce0111072d..8082c7a665a37 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -28,11 +28,13 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from distutils import extension +from distutils import util import errno import os import os.path import pkg_resources import platform +import re import shlex import shutil import sys @@ -83,6 +85,10 @@ if mac_target and (pkg_resources.parse_version(mac_target) < pkg_resources.parse_version('10.9.0')): os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9' + os.environ['_PYTHON_HOST_PLATFORM'] = re.sub( + r'macosx-[0-9]+\.[0-9]+-(.+)', + r'macosx-10.9-\1', + util.get_platform()) def package_data(): tools_path = GRPC_PYTHON_TOOLS_PACKAGE.replace('.', os.path.sep) From 23f7859a46df3c83964b18b4d58a453e368c60e8 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 19 Jul 2016 10:04:37 +0200 Subject: [PATCH 096/151] Fixing Ruby's Rakefile - high version number was hardcoded. --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index f44946fe93739..5b6f101d8ff7f 100755 --- a/Rakefile +++ b/Rakefile @@ -83,7 +83,7 @@ task 'dlls' do env += 'EMBED_ZLIB=true ' env += 'BUILDDIR=/tmp ' env += "V=#{verbose} " - out = '/tmp/libs/opt/grpc-0.dll' + out = '/tmp/libs/opt/grpc-1.dll' w64 = { cross: 'x86_64-w64-mingw32', out: 'grpc_c.64.ruby' } w32 = { cross: 'i686-w64-mingw32', out: 'grpc_c.32.ruby' } From 5ca7e47493899b69126a2ef331936bcba37ee545 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 19 Jul 2016 09:25:49 -0700 Subject: [PATCH 097/151] Merge pull request #6737 from ctiller/delayed-write Delay beginning most writes until we enter poll() --- Makefile | 36 -- build.yaml | 14 - .../client/secure/secure_channel_create.c | 6 +- .../chttp2/transport/chttp2_plugin.c | 3 + .../chttp2/transport/chttp2_transport.c | 369 +++++++++++++++--- .../ext/transport/chttp2/transport/internal.h | 65 ++- .../ext/transport/chttp2/transport/parsing.c | 11 +- .../transport/chttp2/transport/stream_lists.c | 20 +- .../ext/transport/chttp2/transport/writing.c | 16 +- src/core/lib/iomgr/endpoint.c | 4 + src/core/lib/iomgr/endpoint.h | 4 + src/core/lib/iomgr/ev_epoll_linux.c | 277 +++++++------ src/core/lib/iomgr/ev_poll_and_epoll_posix.c | 3 + src/core/lib/iomgr/ev_poll_posix.c | 3 + src/core/lib/iomgr/ev_posix.c | 4 + src/core/lib/iomgr/ev_posix.h | 4 + src/core/lib/iomgr/exec_ctx.c | 10 +- src/core/lib/iomgr/exec_ctx.h | 6 +- src/core/lib/iomgr/iomgr.c | 3 + src/core/lib/iomgr/network_status_tracker.c | 15 +- src/core/lib/iomgr/network_status_tracker.h | 4 + src/core/lib/iomgr/tcp_posix.c | 18 +- src/core/lib/iomgr/tcp_server_posix.c | 3 +- src/core/lib/iomgr/tcp_windows.c | 13 +- src/core/lib/iomgr/workqueue.h | 39 +- src/core/lib/iomgr/workqueue_posix.c | 8 +- src/core/lib/iomgr/workqueue_posix.h | 5 + src/core/lib/iomgr/workqueue_windows.c | 22 ++ .../lib/security/transport/secure_endpoint.c | 18 +- src/core/lib/surface/server.c | 76 ++-- src/core/lib/transport/connectivity_state.c | 3 + test/core/end2end/tests/high_initial_seqno.c | 6 + .../end2end/tests/network_status_change.c | 5 +- test/core/internal_api_canaries/iomgr.c | 13 +- test/core/iomgr/workqueue_test.c | 150 ------- test/core/util/mock_endpoint.c | 12 +- test/core/util/passthru_endpoint.c | 12 +- test/cpp/end2end/end2end_test.cc | 3 + test/cpp/qps/client_async.cc | 35 +- test/cpp/qps/gen_build_yaml.py | 11 +- test/cpp/qps/json_run_localhost.cc | 2 +- test/cpp/qps/server_async.cc | 5 +- .../test/python_pyenv_x64/Dockerfile | 112 ++++++ tools/run_tests/run_tests.py | 28 +- tools/run_tests/sources_and_headers.json | 16 - tools/run_tests/tests.json | 131 +++---- 46 files changed, 1001 insertions(+), 622 deletions(-) delete mode 100644 test/core/iomgr/workqueue_test.c create mode 100644 tools/dockerfile/test/python_pyenv_x64/Dockerfile diff --git a/Makefile b/Makefile index 992eee102b890..ed362f9752b47 100644 --- a/Makefile +++ b/Makefile @@ -991,7 +991,6 @@ transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test -workqueue_test: $(BINDIR)/$(CONFIG)/workqueue_test alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test @@ -1295,7 +1294,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/transport_security_test \ $(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \ - $(BINDIR)/$(CONFIG)/workqueue_test \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ @@ -1674,8 +1672,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/udp_server_test || ( echo test udp_server_test failed ; exit 1 ) $(E) "[RUN] Testing uri_parser_test" $(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 ) - $(E) "[RUN] Testing workqueue_test" - $(Q) $(BINDIR)/$(CONFIG)/workqueue_test || ( echo test workqueue_test failed ; exit 1 ) $(E) "[RUN] Testing public_headers_must_be_c89" $(Q) $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 || ( echo test public_headers_must_be_c89 failed ; exit 1 ) $(E) "[RUN] Testing badreq_bad_client_test" @@ -10175,38 +10171,6 @@ endif endif -WORKQUEUE_TEST_SRC = \ - test/core/iomgr/workqueue_test.c \ - -WORKQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WORKQUEUE_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/workqueue_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/workqueue_test: $(WORKQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(WORKQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/workqueue_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/workqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_workqueue_test: $(WORKQUEUE_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(WORKQUEUE_TEST_OBJS:.o=.dep) -endif -endif - - ALARM_CPP_TEST_SRC = \ test/cpp/common/alarm_cpp_test.cc \ diff --git a/build.yaml b/build.yaml index c5d92c1e63a8c..006d35245a5e8 100644 --- a/build.yaml +++ b/build.yaml @@ -2430,20 +2430,6 @@ targets: - grpc - gpr_test_util - gpr -- name: workqueue_test - build: test - language: c - src: - - test/core/iomgr/workqueue_test.c - deps: - - grpc_test_util - - grpc - - gpr_test_util - - gpr - platforms: - - mac - - linux - - posix - name: alarm_cpp_test gtest: true build: test diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 721ba82d8f7c9..9acacbd92d44c 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -91,11 +91,13 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, connector *c = arg; grpc_closure *notify; gpr_mu_lock(&c->mu); + grpc_error *error = GRPC_ERROR_NONE; if (c->connecting_endpoint == NULL) { memset(c->result, 0, sizeof(*c->result)); gpr_mu_unlock(&c->mu); } else if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, "Secure handshake failed with error %d.", status); + error = grpc_error_set_int(GRPC_ERROR_CREATE("Secure handshake failed"), + GRPC_ERROR_INT_SECURITY_STATUS, status); memset(c->result, 0, sizeof(*c->result)); c->connecting_endpoint = NULL; gpr_mu_unlock(&c->mu); @@ -113,7 +115,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, } notify = c->notify; c->notify = NULL; - grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); + grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); } static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c index bd87253ed32aa..7d5279b9da444 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c @@ -36,11 +36,14 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/transport/metadata.h" +extern int grpc_http_write_state_trace; + void grpc_chttp2_plugin_init(void) { grpc_chttp2_base64_encode_and_huffman_compress = grpc_chttp2_base64_encode_and_huffman_compress_impl; grpc_register_tracer("http", &grpc_http_trace); grpc_register_tracer("flowctl", &grpc_flowctl_trace); + grpc_register_tracer("http_write_state", &grpc_http_write_state_trace); } void grpc_chttp2_plugin_shutdown(void) {} diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index e2dd463a77305..d050467a0206f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -48,6 +48,7 @@ #include "src/core/ext/transport/chttp2/transport/status_conversion.h" #include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/lib/http/parser.h" +#include "src/core/lib/iomgr/workqueue.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" @@ -60,9 +61,9 @@ #define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024) #define MAX_CLIENT_STREAM_ID 0x7fffffffu - int grpc_http_trace = 0; int grpc_flowctl_trace = 0; +int grpc_http_write_state_trace = 0; #define TRANSPORT_FROM_WRITING(tw) \ ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ @@ -88,10 +89,16 @@ static const grpc_transport_vtable vtable; static void writing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); static void reading_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); static void parsing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error); +static void initiate_writing(grpc_exec_ctx *exec_ctx, void *t, + grpc_error *error); + +static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); +static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, grpc_error *error); /** Set a transport level setting, and push it to our peer */ -static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id, - uint32_t value); +static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_setting_id id, uint32_t value); /** Start disconnection chain */ static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -137,7 +144,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); static void incoming_byte_stream_update_flow_control( - grpc_chttp2_transport_global *transport_global, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, size_t max_size_hint, size_t have_already); static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, @@ -201,6 +208,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, gpr_free(t); } +/*#define REFCOUNTING_DEBUG 1*/ #ifdef REFCOUNTING_DEBUG #define REF_TRANSPORT(t, r) ref_transport(t, r, __FILE__, __LINE__) #define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t, r, __FILE__, __LINE__) @@ -231,7 +239,7 @@ static void ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); } static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, const grpc_channel_args *channel_args, - grpc_endpoint *ep, uint8_t is_client) { + grpc_endpoint *ep, bool is_client) { size_t i; int j; @@ -273,6 +281,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_closure_init(&t->writing_action, writing_action, t); grpc_closure_init(&t->reading_action, reading_action, t); grpc_closure_init(&t->parsing_action, parsing_action, t); + grpc_closure_init(&t->initiate_writing, initiate_writing, t); gpr_slice_buffer_init(&t->parsing.qbuf); grpc_chttp2_goaway_parser_init(&t->parsing.goaway_parser); @@ -286,6 +295,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_slice_buffer_add( &t->global.qbuf, gpr_slice_from_copied_string(GRPC_CHTTP2_CLIENT_CONNECT_STRING)); + grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "initial_write"); } /* 8 is a random stab in the dark as to a good initial size: it's small enough that it shouldn't waste memory for infrequently used connections, yet @@ -311,11 +321,12 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, /* configure http2 the way we like it */ if (is_client) { - push_setting(t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0); - push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0); + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0); + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0); } - push_setting(t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, DEFAULT_WINDOW); - push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, + DEFAULT_WINDOW); + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, DEFAULT_MAX_HEADER_LIST_SIZE); if (channel_args) { @@ -329,7 +340,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_log(GPR_ERROR, "%s: must be an integer", GRPC_ARG_MAX_CONCURRENT_STREAMS); } else { - push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, (uint32_t)channel_args->args[i].value.integer); } } else if (0 == strcmp(channel_args->args[i].key, @@ -368,7 +379,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_log(GPR_ERROR, "%s: must be non-negative", GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER); } else { - push_setting(t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, (uint32_t)channel_args->args[i].value.integer); } } else if (0 == strcmp(channel_args->args[i].key, @@ -393,7 +404,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, gpr_log(GPR_ERROR, "%s: must be non-negative", GRPC_ARG_MAX_METADATA_SIZE); } else { - push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, (uint32_t)channel_args->args[i].value.integer); } } @@ -444,6 +455,9 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { if (!t->closed) { + if (grpc_http_write_state_trace) { + gpr_log(GPR_DEBUG, "W:%p close transport", t); + } t->closed = 1; connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "close_transport"); @@ -590,7 +604,8 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer_destroy( &s->global.received_trailing_metadata); gpr_slice_buffer_destroy(&s->writing.flow_controlled_buffer); - GRPC_ERROR_UNREF(s->global.removal_error); + GRPC_ERROR_UNREF(s->global.read_closed_error); + GRPC_ERROR_UNREF(s->global.write_closed_error); UNREF_TRANSPORT(exec_ctx, t, "stream"); @@ -634,6 +649,36 @@ grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream( * LOCK MANAGEMENT */ +static const char *write_state_name(grpc_chttp2_write_state state) { + switch (state) { + case GRPC_CHTTP2_WRITING_INACTIVE: + return "INACTIVE"; + case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER: + return "REQUESTED[p=0]"; + case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER: + return "REQUESTED[p=1]"; + case GRPC_CHTTP2_WRITE_SCHEDULED: + return "SCHEDULED"; + case GRPC_CHTTP2_WRITING: + return "WRITING"; + case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: + return "WRITING[p=1]"; + case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: + return "WRITING[p=0]"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void set_write_state(grpc_chttp2_transport *t, + grpc_chttp2_write_state state, const char *reason) { + if (grpc_http_write_state_trace) { + gpr_log(GPR_DEBUG, "W:%p %s -> %s because %s", t, + write_state_name(t->executor.write_state), write_state_name(state), + reason); + } + t->executor.write_state = state; +} + static void finish_global_actions(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { grpc_chttp2_executor_action_header *hdr; @@ -642,13 +687,6 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx, GPR_TIMER_BEGIN("finish_global_actions", 0); for (;;) { - if (!t->executor.writing_active && !t->closed && - grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) { - t->executor.writing_active = 1; - REF_TRANSPORT(t, "writing"); - prevent_endpoint_shutdown(t); - grpc_exec_ctx_sched(exec_ctx, &t->writing_action, GRPC_ERROR_NONE, NULL); - } check_read_ops(exec_ctx, &t->global); gpr_mu_lock(&t->executor.mu); @@ -669,8 +707,28 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx, continue; } else { t->executor.global_active = false; + switch (t->executor.write_state) { + case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER: + set_write_state(t, GRPC_CHTTP2_WRITE_SCHEDULED, "unlocking"); + REF_TRANSPORT(t, "initiate_writing"); + gpr_mu_unlock(&t->executor.mu); + grpc_exec_ctx_sched( + exec_ctx, &t->initiate_writing, GRPC_ERROR_NONE, + t->ep != NULL ? grpc_endpoint_get_workqueue(t->ep) : NULL); + break; + case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER: + start_writing(exec_ctx, t); + gpr_mu_unlock(&t->executor.mu); + break; + case GRPC_CHTTP2_WRITING_INACTIVE: + case GRPC_CHTTP2_WRITING: + case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: + case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: + case GRPC_CHTTP2_WRITE_SCHEDULED: + gpr_mu_unlock(&t->executor.mu); + break; + } } - gpr_mu_unlock(&t->executor.mu); break; } @@ -741,16 +799,118 @@ void grpc_chttp2_run_with_global_lock(grpc_exec_ctx *exec_ctx, * OUTPUT PROCESSING */ -void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { +void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + bool covered_by_poller, const char *reason) { + /* Perform state checks, and transition to a scheduled state if appropriate. + Each time we finish the global lock execution, we check if we need to + write. If we do: + - (if there is a poller surrounding the write) schedule + initiate_writing, which locks and calls initiate_writing_locked to... + - call start_writing, which verifies (under the global lock) that there + are things that need to be written by calling + grpc_chttp2_unlocking_check_writes, and if so schedules writing_action + against the current exec_ctx, to be executed OUTSIDE of the global lock + - eventually writing_action results in grpc_chttp2_terminate_writing being + called, which re-takes the global lock, updates state, checks if we need + to do *another* write immediately, and if so loops back to + start_writing. + + Current problems: + - too much lock entry/exiting + - the writing thread can become stuck indefinitely (punt through the + workqueue periodically to fix) */ + + grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); + switch (t->executor.write_state) { + case GRPC_CHTTP2_WRITING_INACTIVE: + set_write_state(t, covered_by_poller + ? GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER + : GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER, + reason); + break; + case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER: + /* nothing to do: write already requested */ + break; + case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER: + if (covered_by_poller) { + /* upgrade to note poller is available to cover the write */ + set_write_state(t, GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER, reason); + } + break; + case GRPC_CHTTP2_WRITE_SCHEDULED: + /* nothing to do: write already scheduled */ + break; + case GRPC_CHTTP2_WRITING: + set_write_state(t, + covered_by_poller ? GRPC_CHTTP2_WRITING_STALE_WITH_POLLER + : GRPC_CHTTP2_WRITING_STALE_NO_POLLER, + reason); + break; + case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: + /* nothing to do: write already requested */ + break; + case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: + if (covered_by_poller) { + /* upgrade to note poller is available to cover the write */ + set_write_state(t, GRPC_CHTTP2_WRITING_STALE_WITH_POLLER, reason); + } + break; + } +} + +static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { + GPR_ASSERT(t->executor.write_state == GRPC_CHTTP2_WRITE_SCHEDULED || + t->executor.write_state == GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER); + if (!t->closed && + grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) { + set_write_state(t, GRPC_CHTTP2_WRITING, "start_writing"); + REF_TRANSPORT(t, "writing"); + prevent_endpoint_shutdown(t); + grpc_exec_ctx_sched(exec_ctx, &t->writing_action, GRPC_ERROR_NONE, NULL); + } else { + if (t->closed) { + set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, + "start_writing:transport_closed"); + } else { + set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, + "start_writing:nothing_to_write"); + } + end_waiting_for_write(exec_ctx, t, GRPC_ERROR_CREATE("Nothing to write")); + if (t->ep && !t->endpoint_reading) { + destroy_endpoint(exec_ctx, t); + } + } +} + +static void initiate_writing_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_chttp2_stream *s_unused, + void *arg_ignored) { + start_writing(exec_ctx, t); + UNREF_TRANSPORT(exec_ctx, t, "initiate_writing"); +} + +static void initiate_writing(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + grpc_chttp2_run_with_global_lock(exec_ctx, arg, NULL, initiate_writing_locked, + NULL, 0); +} + +void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + bool covered_by_poller, const char *reason) { if (!TRANSPORT_FROM_GLOBAL(transport_global)->closed && grpc_chttp2_list_add_writable_stream(transport_global, stream_global)) { GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing"); + grpc_chttp2_initiate_write(exec_ctx, transport_global, covered_by_poller, + reason); } } -static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id, - uint32_t value) { +static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_chttp2_setting_id id, uint32_t value) { const grpc_chttp2_setting_parameters *sp = &grpc_chttp2_settings_parameters[id]; uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value); @@ -761,9 +921,22 @@ static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id, if (use_value != t->global.settings[GRPC_LOCAL_SETTINGS][id]) { t->global.settings[GRPC_LOCAL_SETTINGS][id] = use_value; t->global.dirtied_local_settings = 1; + grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "push_setting"); } } +static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, grpc_error *error) { + grpc_chttp2_stream_global *stream_global; + while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, + &stream_global)) { + fail_pending_writes(exec_ctx, &t->global, stream_global, + GRPC_ERROR_REF(error)); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes"); + } + GRPC_ERROR_UNREF(error); +} + static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s_ignored, @@ -778,24 +951,32 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing); - grpc_chttp2_stream_global *stream_global; - while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, - &stream_global)) { - fail_pending_writes(exec_ctx, &t->global, stream_global, - GRPC_ERROR_REF(error)); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes"); + end_waiting_for_write(exec_ctx, t, error); + + switch (t->executor.write_state) { + case GRPC_CHTTP2_WRITING_INACTIVE: + case GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER: + case GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER: + case GRPC_CHTTP2_WRITE_SCHEDULED: + GPR_UNREACHABLE_CODE(break); + case GRPC_CHTTP2_WRITING: + set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, "terminate_writing"); + break; + case GRPC_CHTTP2_WRITING_STALE_WITH_POLLER: + set_write_state(t, GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER, + "terminate_writing"); + break; + case GRPC_CHTTP2_WRITING_STALE_NO_POLLER: + set_write_state(t, GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER, + "terminate_writing"); + break; } - /* leave the writing flag up on shutdown to prevent further writes in - unlock() - from starting */ - t->executor.writing_active = 0; if (t->ep && !t->endpoint_reading) { destroy_endpoint(exec_ctx, t); } UNREF_TRANSPORT(exec_ctx, t, "writing"); - GRPC_ERROR_UNREF(error); } void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, @@ -878,7 +1059,8 @@ static void maybe_start_some_streams( stream_global->id, STREAM_FROM_GLOBAL(stream_global)); stream_global->in_stream_map = true; transport_global->concurrent_stream_count++; - grpc_chttp2_become_writable(transport_global, stream_global); + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, true, + "new_stream"); } /* cancel out streams that will never be started */ while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID && @@ -1018,9 +1200,11 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, maybe_start_some_streams(exec_ctx, transport_global); } else { GPR_ASSERT(stream_global->id != 0); - grpc_chttp2_become_writable(transport_global, stream_global); + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, + true, "op.send_initial_metadata"); } } else { + stream_global->send_trailing_metadata = NULL; grpc_chttp2_complete_closure_step( exec_ctx, transport_global, stream_global, &stream_global->send_initial_metadata_finished, @@ -1042,7 +1226,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, } else { stream_global->send_message = op->send_message; if (stream_global->id != 0) { - grpc_chttp2_become_writable(transport_global, stream_global); + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, + true, "op.send_message"); } } } @@ -1075,6 +1260,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); } if (stream_global->write_closed) { + stream_global->send_trailing_metadata = NULL; grpc_chttp2_complete_closure_step( exec_ctx, transport_global, stream_global, &stream_global->send_trailing_metadata_finished, @@ -1085,7 +1271,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, } else if (stream_global->id != 0) { /* TODO(ctiller): check if there's flow control for any outstanding bytes before going writable */ - grpc_chttp2_become_writable(transport_global, stream_global); + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, + true, "op.send_trailing_metadata"); } } } @@ -1106,8 +1293,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, (stream_global->incoming_frames.head == NULL || stream_global->incoming_frames.head->is_tail)) { incoming_byte_stream_update_flow_control( - transport_global, stream_global, transport_global->stream_lookahead, - 0); + exec_ctx, transport_global, stream_global, + transport_global->stream_lookahead, 0); } grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); } @@ -1135,7 +1322,8 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, sizeof(*op)); } -static void send_ping_locked(grpc_chttp2_transport *t, grpc_closure *on_recv) { +static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + grpc_closure *on_recv) { grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p)); p->next = &t->global.pings; p->prev = p->next->prev; @@ -1150,6 +1338,7 @@ static void send_ping_locked(grpc_chttp2_transport *t, grpc_closure *on_recv) { p->id[7] = (uint8_t)(t->global.ping_counter & 0xff); p->on_recv = on_recv; gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id)); + grpc_chttp2_initiate_write(exec_ctx, &t->global, true, "send_ping"); } static void ack_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -1209,6 +1398,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, close_transport = grpc_chttp2_has_streams(t) ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE("GOAWAY sent"); + grpc_chttp2_initiate_write(exec_ctx, &t->global, false, "goaway_sent"); } if (op->set_accept_stream) { @@ -1226,7 +1416,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, } if (op->send_ping) { - send_ping_locked(t, op->send_ping); + send_ping_locked(exec_ctx, t, op->send_ping); } if (close_transport != GRPC_ERROR_NONE) { @@ -1414,6 +1604,8 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx, &transport_global->qbuf, grpc_chttp2_rst_stream_create(stream_global->id, (uint32_t)http_error, &stream_global->stats.outgoing)); + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "rst_stream"); } const char *msg = @@ -1473,10 +1665,39 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, } } +static void add_error(grpc_error *error, grpc_error **refs, size_t *nrefs) { + if (error == GRPC_ERROR_NONE) return; + for (size_t i = 0; i < *nrefs; i++) { + if (error == refs[i]) { + return; + } + } + refs[*nrefs] = error; + ++*nrefs; +} + +static grpc_error *removal_error(grpc_error *extra_error, + grpc_chttp2_stream_global *stream_global) { + grpc_error *refs[3]; + size_t nrefs = 0; + add_error(stream_global->read_closed_error, refs, &nrefs); + add_error(stream_global->write_closed_error, refs, &nrefs); + add_error(extra_error, refs, &nrefs); + grpc_error *error = GRPC_ERROR_NONE; + if (nrefs > 0) { + error = GRPC_ERROR_CREATE_REFERENCING("Failed due to stream removal", refs, + nrefs); + } + GRPC_ERROR_UNREF(extra_error); + return error; +} + static void fail_pending_writes(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, grpc_error *error) { + error = removal_error(error, stream_global); + stream_global->send_message = NULL; grpc_chttp2_complete_closure_step( exec_ctx, transport_global, stream_global, &stream_global->send_initial_metadata_finished, GRPC_ERROR_REF(error)); @@ -1499,14 +1720,17 @@ void grpc_chttp2_mark_stream_closed( } grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); if (close_reads && !stream_global->read_closed) { + stream_global->read_closed_error = GRPC_ERROR_REF(error); stream_global->read_closed = true; stream_global->published_initial_metadata = true; stream_global->published_trailing_metadata = true; decrement_active_streams_locked(exec_ctx, transport_global, stream_global); } if (close_writes && !stream_global->write_closed) { + stream_global->write_closed_error = GRPC_ERROR_REF(error); stream_global->write_closed = true; - if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.writing_active) { + if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.write_state != + GRPC_CHTTP2_WRITING_INACTIVE) { GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes"); grpc_chttp2_list_add_closed_waiting_for_writing(transport_global, stream_global); @@ -1516,7 +1740,6 @@ void grpc_chttp2_mark_stream_closed( } } if (stream_global->read_closed && stream_global->write_closed) { - stream_global->removal_error = GRPC_ERROR_REF(error); if (stream_global->id != 0 && TRANSPORT_FROM_GLOBAL(transport_global)->executor.parsing_active) { grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global, @@ -1524,7 +1747,8 @@ void grpc_chttp2_mark_stream_closed( } else { if (stream_global->id != 0) { remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), - stream_global->id, GRPC_ERROR_REF(error)); + stream_global->id, + removal_error(GRPC_ERROR_REF(error), stream_global)); } GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); } @@ -1649,6 +1873,8 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, 1, error); + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "close_from_api"); } typedef struct { @@ -1678,8 +1904,14 @@ static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } /** update window from a settings change */ +typedef struct { + grpc_chttp2_transport *t; + grpc_exec_ctx *exec_ctx; +} update_global_window_args; + static void update_global_window(void *args, uint32_t id, void *stream) { - grpc_chttp2_transport *t = args; + update_global_window_args *a = args; + grpc_chttp2_transport *t = a->t; grpc_chttp2_stream *s = stream; grpc_chttp2_transport_global *transport_global = &t->global; grpc_chttp2_stream_global *stream_global = &s->global; @@ -1693,7 +1925,8 @@ static void update_global_window(void *args, uint32_t id, void *stream) { is_zero = stream_global->outgoing_window <= 0; if (was_zero && !is_zero) { - grpc_chttp2_become_writable(transport_global, stream_global); + grpc_chttp2_become_writable(a->exec_ctx, transport_global, stream_global, + true, "update_global_window"); } } @@ -1801,14 +2034,19 @@ static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_transport_global *transport_global = &t->global; grpc_chttp2_transport_parsing *transport_parsing = &t->parsing; /* copy parsing qbuf to global qbuf */ - gpr_slice_buffer_move_into(&t->parsing.qbuf, &t->global.qbuf); + if (t->parsing.qbuf.count > 0) { + gpr_slice_buffer_move_into(&t->parsing.qbuf, &t->global.qbuf); + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "parsing_qbuf"); + } /* merge stream lists */ grpc_chttp2_stream_map_move_into(&t->new_stream_map, &t->parsing_stream_map); transport_global->concurrent_stream_count = (uint32_t)grpc_chttp2_stream_map_size(&t->parsing_stream_map); if (transport_parsing->initial_window_update != 0) { + update_global_window_args args = {t, exec_ctx}; grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, - update_global_window, t); + update_global_window, &args); transport_parsing->initial_window_update = 0; } /* handle higher level things */ @@ -1831,7 +2069,7 @@ static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, GPR_ASSERT(stream_global->write_closed); GPR_ASSERT(stream_global->read_closed); remove_stream(exec_ctx, t, stream_global->id, - GRPC_ERROR_REF(stream_global->removal_error)); + removal_error(GRPC_ERROR_NONE, stream_global)); GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); } @@ -1854,11 +2092,12 @@ static void post_reading_action_locked(grpc_exec_ctx *exec_ctx, } drop_connection(exec_ctx, t, GRPC_ERROR_REF(error)); t->endpoint_reading = 0; - if (!t->executor.writing_active && t->ep) { - grpc_endpoint_destroy(exec_ctx, t->ep); - t->ep = NULL; - /* safe as we still have a ref for read */ - UNREF_TRANSPORT(exec_ctx, t, "disconnect"); + if (grpc_http_write_state_trace) { + gpr_log(GPR_DEBUG, "R:%p -> 0 ws=%s", t, + write_state_name(t->executor.write_state)); + } + if (t->executor.write_state == GRPC_CHTTP2_WRITING_INACTIVE && t->ep) { + destroy_endpoint(exec_ctx, t); } } else if (!t->closed) { keep_reading = true; @@ -1942,7 +2181,7 @@ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx, } static void incoming_byte_stream_update_flow_control( - grpc_chttp2_transport_global *transport_global, + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, size_t max_size_hint, size_t have_already) { uint32_t max_recv_bytes; @@ -1977,7 +2216,8 @@ static void incoming_byte_stream_update_flow_control( add_max_recv_bytes); grpc_chttp2_list_add_unannounced_incoming_window_available(transport_global, stream_global); - grpc_chttp2_become_writable(transport_global, stream_global); + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, + false, "read_incoming_stream"); } } @@ -1999,8 +2239,9 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream_global *stream_global = &bs->stream->global; if (bs->is_tail) { - incoming_byte_stream_update_flow_control( - transport_global, stream_global, arg->max_size_hint, bs->slices.length); + incoming_byte_stream_update_flow_control(exec_ctx, transport_global, + stream_global, arg->max_size_hint, + bs->slices.length); } if (bs->slices.count > 0) { *arg->slice = gpr_slice_buffer_take_first(&bs->slices); @@ -2184,7 +2425,7 @@ static char *format_flowctl_context_var(const char *context, const char *var, if (context == NULL) { *scope = NULL; gpr_asprintf(&buf, "%s(%" PRId64 ")", var, val); - result = gpr_leftpad(buf, ' ', 40); + result = gpr_leftpad(buf, ' ', 60); gpr_free(buf); return result; } @@ -2197,7 +2438,7 @@ static char *format_flowctl_context_var(const char *context, const char *var, gpr_free(tmp); } gpr_asprintf(&buf, "%s.%s(%" PRId64 ")", underscore_pos + 1, var, val); - result = gpr_leftpad(buf, ' ', 40); + result = gpr_leftpad(buf, ' ', 60); gpr_free(buf); return result; } @@ -2230,7 +2471,7 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, tmp_phase = gpr_leftpad(phase, ' ', 8); tmp_scope1 = gpr_leftpad(scope1, ' ', 11); - gpr_asprintf(&prefix, "FLOW %s: %s %s ", phase, clisvr, scope1); + gpr_asprintf(&prefix, "FLOW %s: %s %s ", tmp_phase, clisvr, scope1); gpr_free(tmp_phase); gpr_free(tmp_scope1); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 8d79e93ceb30f..e1dcf5262a130 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -305,6 +305,22 @@ typedef struct grpc_chttp2_executor_action_header { void *arg; } grpc_chttp2_executor_action_header; +typedef enum { + /** no writing activity */ + GRPC_CHTTP2_WRITING_INACTIVE, + /** write has been requested, but not scheduled yet */ + GRPC_CHTTP2_WRITE_REQUESTED_WITH_POLLER, + GRPC_CHTTP2_WRITE_REQUESTED_NO_POLLER, + /** write has been requested and scheduled against the workqueue */ + GRPC_CHTTP2_WRITE_SCHEDULED, + /** write has been initiated after being reaped from the workqueue */ + GRPC_CHTTP2_WRITING, + /** write has been initiated, AND another write needs to be started once it's + done */ + GRPC_CHTTP2_WRITING_STALE_WITH_POLLER, + GRPC_CHTTP2_WRITING_STALE_NO_POLLER, +} grpc_chttp2_write_state; + struct grpc_chttp2_transport { grpc_transport base; /* must be first */ gpr_refcount refs; @@ -319,10 +335,10 @@ struct grpc_chttp2_transport { /** is a thread currently in the global lock */ bool global_active; - /** is a thread currently writing */ - bool writing_active; /** is a thread currently parsing */ bool parsing_active; + /** write execution state of the transport */ + grpc_chttp2_write_state write_state; grpc_chttp2_executor_action_header *pending_actions_head; grpc_chttp2_executor_action_header *pending_actions_tail; @@ -342,7 +358,8 @@ struct grpc_chttp2_transport { /** global state for reading/writing */ grpc_chttp2_transport_global global; /** state only accessible by the chain of execution that - set writing_active=1 */ + set writing_state >= GRPC_WRITING, and only by the writing closure + chain. */ grpc_chttp2_transport_writing writing; /** state only accessible by the chain of execution that set parsing_active=1 */ @@ -363,6 +380,8 @@ struct grpc_chttp2_transport { grpc_closure reading_action; /** closure to actually do parsing */ grpc_closure parsing_action; + /** closure to initiate writing */ + grpc_closure initiate_writing; /** incoming read bytes */ gpr_slice_buffer read_buffer; @@ -436,8 +455,10 @@ typedef struct { bool seen_error; bool exceeded_metadata_size; - /** the error that resulted in this stream being removed */ - grpc_error *removal_error; + /** the error that resulted in this stream being read-closed */ + grpc_error *read_closed_error; + /** the error that resulted in this stream being write-closed */ + grpc_error *write_closed_error; bool published_initial_metadata; bool published_trailing_metadata; @@ -514,15 +535,20 @@ struct grpc_chttp2_stream { }; /** Transport writing call flow: - chttp2_transport.c calls grpc_chttp2_unlocking_check_writes to see if writes - are required; - if they are, chttp2_transport.c calls grpc_chttp2_perform_writes to do the - writes. - Once writes have been completed (meaning another write could potentially be - started), - grpc_chttp2_terminate_writing is called. This will call - grpc_chttp2_cleanup_writing, at which - point the write phase is complete. */ + grpc_chttp2_initiate_write() is called anywhere that we know bytes need to + go out on the wire. + If no other write has been started, a task is enqueued onto our workqueue. + When that task executes, it obtains the global lock, and gathers the data + to write. + The global lock is dropped and we do the syscall to write. + After writing, a follow-up check is made to see if another round of writing + should be performed. + + The actual call chain is documented in the implementation of this function. + */ +void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + bool covered_by_poller, const char *reason); /** Someone is unlocking the transport mutex: check to see if writes are required, and schedule them if so */ @@ -610,9 +636,8 @@ int grpc_chttp2_list_pop_check_read_ops( void grpc_chttp2_list_add_writing_stalled_by_transport( grpc_chttp2_transport_writing *transport_writing, grpc_chttp2_stream_writing *stream_writing); -void grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - bool is_window_available); +bool grpc_chttp2_list_flush_writing_stalled_by_transport( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing); void grpc_chttp2_list_add_stalled_by_transport( grpc_chttp2_transport_writing *transport_writing, @@ -822,7 +847,9 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, /** add a ref to the stream and add it to the writable list; ref will be dropped in writing.c */ -void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); +void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + bool covered_by_poller, const char *reason); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H */ diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 84eb5752f16a6..e1fc0ddee200e 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -154,10 +154,8 @@ void grpc_chttp2_publish_reads( transport_parsing, outgoing_window); is_zero = transport_global->outgoing_window <= 0; if (was_zero && !is_zero) { - while (grpc_chttp2_list_pop_stalled_by_transport(transport_global, - &stream_global)) { - grpc_chttp2_become_writable(transport_global, stream_global); - } + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "new_global_flow_control"); } if (transport_parsing->incoming_window < @@ -168,6 +166,8 @@ void grpc_chttp2_publish_reads( announce_incoming_window, announce_bytes); GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_parsing, incoming_window, announce_bytes); + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "global incoming window"); } /* for each stream that saw an update, fixup global state */ @@ -190,7 +190,8 @@ void grpc_chttp2_publish_reads( outgoing_window); is_zero = stream_global->outgoing_window <= 0; if (was_zero && !is_zero) { - grpc_chttp2_become_writable(transport_global, stream_global); + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, + false, "stream.read_flow_control"); } stream_global->max_recv_bytes -= (uint32_t)GPR_MIN( diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.c b/src/core/ext/transport/chttp2/transport/stream_lists.c index 8f3ab00e6df8b..2eb5f5f632e17 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.c +++ b/src/core/ext/transport/chttp2/transport/stream_lists.c @@ -329,6 +329,7 @@ void grpc_chttp2_list_add_writing_stalled_by_transport( grpc_chttp2_transport_writing *transport_writing, grpc_chttp2_stream_writing *stream_writing) { grpc_chttp2_stream *stream = STREAM_FROM_WRITING(stream_writing); + gpr_log(GPR_DEBUG, "writing stalled %d", stream->global.id); if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) { GRPC_CHTTP2_STREAM_REF(&stream->global, "chttp2_writing_stalled"); } @@ -336,27 +337,28 @@ void grpc_chttp2_list_add_writing_stalled_by_transport( GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT); } -void grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - bool is_window_available) { +bool grpc_chttp2_list_flush_writing_stalled_by_transport( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing) { grpc_chttp2_stream *stream; + bool out = false; grpc_chttp2_transport *transport = TRANSPORT_FROM_WRITING(transport_writing); while (stream_list_pop(transport, &stream, GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) { - if (is_window_available) { - grpc_chttp2_become_writable(&transport->global, &stream->global); - } else { - grpc_chttp2_list_add_stalled_by_transport(transport_writing, - &stream->writing); - } + gpr_log(GPR_DEBUG, "move %d from writing stalled to just stalled", + stream->global.id); + grpc_chttp2_list_add_stalled_by_transport(transport_writing, + &stream->writing); GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &stream->global, "chttp2_writing_stalled"); + out = true; } + return out; } void grpc_chttp2_list_add_stalled_by_transport( grpc_chttp2_transport_writing *transport_writing, grpc_chttp2_stream_writing *stream_writing) { + gpr_log(GPR_DEBUG, "stalled %d", stream_writing->id); stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), STREAM_FROM_WRITING(stream_writing), GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index b19f5f068df9e..e0d87725e9dd8 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -75,9 +75,13 @@ int grpc_chttp2_unlocking_check_writes( GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("write", transport_writing, outgoing_window, transport_global, outgoing_window); - bool is_window_available = transport_writing->outgoing_window > 0; - grpc_chttp2_list_flush_writing_stalled_by_transport( - exec_ctx, transport_writing, is_window_available); + if (transport_writing->outgoing_window > 0) { + while (grpc_chttp2_list_pop_stalled_by_transport(transport_global, + &stream_global)) { + grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, + false, "transport.read_flow_control"); + } + } /* for each grpc_chttp2_stream that's become writable, frame it's data (according to available window sizes) and add to the output buffer */ @@ -331,6 +335,12 @@ void grpc_chttp2_cleanup_writing( grpc_chttp2_stream_writing *stream_writing; grpc_chttp2_stream_global *stream_global; + if (grpc_chttp2_list_flush_writing_stalled_by_transport(exec_ctx, + transport_writing)) { + grpc_chttp2_initiate_write(exec_ctx, transport_global, false, + "resume_stalled_stream"); + } + while (grpc_chttp2_list_pop_written_stream( transport_global, transport_writing, &stream_global, &stream_writing)) { if (stream_writing->sent_initial_metadata) { diff --git a/src/core/lib/iomgr/endpoint.c b/src/core/lib/iomgr/endpoint.c index 1ab3733d381cc..f901fcf962217 100644 --- a/src/core/lib/iomgr/endpoint.c +++ b/src/core/lib/iomgr/endpoint.c @@ -65,3 +65,7 @@ void grpc_endpoint_destroy(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep) { char* grpc_endpoint_get_peer(grpc_endpoint* ep) { return ep->vtable->get_peer(ep); } + +grpc_workqueue* grpc_endpoint_get_workqueue(grpc_endpoint* ep) { + return ep->vtable->get_workqueue(ep); +} diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index f9808bbda1882..894efc0b23829 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -51,6 +51,7 @@ struct grpc_endpoint_vtable { gpr_slice_buffer *slices, grpc_closure *cb); void (*write)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, gpr_slice_buffer *slices, grpc_closure *cb); + grpc_workqueue *(*get_workqueue)(grpc_endpoint *ep); void (*add_to_pollset)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_pollset *pollset); void (*add_to_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, @@ -69,6 +70,9 @@ void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, char *grpc_endpoint_get_peer(grpc_endpoint *ep); +/* Retrieve a reference to the workqueue associated with this endpoint */ +grpc_workqueue *grpc_endpoint_get_workqueue(grpc_endpoint *ep); + /* Write slices out to the socket. If the connection is ready for more data after the end of the call, it diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index cf0fe736a0b49..6a63c4d1d1868 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -57,6 +57,7 @@ #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/workqueue.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/block_annotate.h" @@ -113,9 +114,7 @@ struct grpc_fd { grpc_closure *read_closure; grpc_closure *write_closure; - /* The polling island to which this fd belongs to and the mutex protecting the - the field */ - gpr_mu pi_mu; + /* The polling island to which this fd belongs to (protected by mu) */ struct polling_island *polling_island; struct grpc_fd *freelist_next; @@ -152,16 +151,17 @@ static void fd_global_shutdown(void); * Polling island Declarations */ -// #define GRPC_PI_REF_COUNT_DEBUG +//#define GRPC_PI_REF_COUNT_DEBUG #ifdef GRPC_PI_REF_COUNT_DEBUG #define PI_ADD_REF(p, r) pi_add_ref_dbg((p), (r), __FILE__, __LINE__) -#define PI_UNREF(p, r) pi_unref_dbg((p), (r), __FILE__, __LINE__) +#define PI_UNREF(exec_ctx, p, r) \ + pi_unref_dbg((exec_ctx), (p), (r), __FILE__, __LINE__) #else /* defined(GRPC_PI_REF_COUNT_DEBUG) */ #define PI_ADD_REF(p, r) pi_add_ref((p)) -#define PI_UNREF(p, r) pi_unref((p)) +#define PI_UNREF(exec_ctx, p, r) pi_unref((exec_ctx), (p)) #endif /* !defined(GPRC_PI_REF_COUNT_DEBUG) */ @@ -172,7 +172,7 @@ typedef struct polling_island { Once the ref count becomes zero, this structure is destroyed which means we should ensure that there is never a scenario where a PI_ADD_REF() is racing with a PI_UNREF() that just made the ref_count zero. */ - gpr_refcount ref_count; + gpr_atm ref_count; /* Pointer to the polling_island this merged into. * merged_to value is only set once in polling_island's lifetime (and that too @@ -184,6 +184,9 @@ typedef struct polling_island { * (except mu and ref_count) are invalid and must be ignored. */ gpr_atm merged_to; + /* The workqueue associated with this polling island */ + grpc_workqueue *workqueue; + /* The fd of the underlying epoll set */ int epoll_fd; @@ -191,11 +194,6 @@ typedef struct polling_island { size_t fd_cnt; size_t fd_capacity; grpc_fd **fds; - - /* Polling islands that are no longer needed are kept in a freelist so that - they can be reused. This field points to the next polling island in the - free list */ - struct polling_island *next_free; } polling_island; /******************************************************************************* @@ -253,13 +251,14 @@ struct grpc_pollset_set { * Common helpers */ -static void append_error(grpc_error **composite, grpc_error *error, +static bool append_error(grpc_error **composite, grpc_error *error, const char *desc) { - if (error == GRPC_ERROR_NONE) return; + if (error == GRPC_ERROR_NONE) return true; if (*composite == GRPC_ERROR_NONE) { *composite = GRPC_ERROR_CREATE(desc); } *composite = grpc_error_add_child(*composite, error); + return false; } /******************************************************************************* @@ -275,11 +274,8 @@ static void append_error(grpc_error **composite, grpc_error *error, threads that woke up MUST NOT call grpc_wakeup_fd_consume_wakeup() */ static grpc_wakeup_fd polling_island_wakeup_fd; -/* Polling island freelist */ -static gpr_mu g_pi_freelist_mu; -static polling_island *g_pi_freelist = NULL; - -static void polling_island_delete(); /* Forward declaration */ +/* Forward declaration */ +static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi); #ifdef GRPC_TSAN /* Currently TSAN may incorrectly flag data races between epoll_ctl and @@ -293,28 +289,35 @@ gpr_atm g_epoll_sync; #endif /* defined(GRPC_TSAN) */ #ifdef GRPC_PI_REF_COUNT_DEBUG -void pi_add_ref(polling_island *pi); -void pi_unref(polling_island *pi); +static void pi_add_ref(polling_island *pi); +static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi); -void pi_add_ref_dbg(polling_island *pi, char *reason, char *file, int line) { - long old_cnt = gpr_atm_acq_load(&(pi->ref_count.count)); +static void pi_add_ref_dbg(polling_island *pi, char *reason, char *file, + int line) { + long old_cnt = gpr_atm_acq_load(&pi->ref_count); pi_add_ref(pi); gpr_log(GPR_DEBUG, "Add ref pi: %p, old: %ld -> new:%ld (%s) - (%s, %d)", (void *)pi, old_cnt, old_cnt + 1, reason, file, line); } -void pi_unref_dbg(polling_island *pi, char *reason, char *file, int line) { - long old_cnt = gpr_atm_acq_load(&(pi->ref_count.count)); - pi_unref(pi); +static void pi_unref_dbg(grpc_exec_ctx *exec_ctx, polling_island *pi, + char *reason, char *file, int line) { + long old_cnt = gpr_atm_acq_load(&pi->ref_count); + pi_unref(exec_ctx, pi); gpr_log(GPR_DEBUG, "Unref pi: %p, old:%ld -> new:%ld (%s) - (%s, %d)", (void *)pi, old_cnt, (old_cnt - 1), reason, file, line); } #endif -void pi_add_ref(polling_island *pi) { gpr_ref(&pi->ref_count); } +static void pi_add_ref(polling_island *pi) { + gpr_atm_no_barrier_fetch_add(&pi->ref_count, 1); +} -void pi_unref(polling_island *pi) { - /* If ref count went to zero, delete the polling island. +static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi) { + /* If ref count went to one, we're back to just the workqueue owning a ref. + Unref the workqueue to break the loop. + + If ref count went to zero, delete the polling island. Note that this deletion not be done under a lock. Once the ref count goes to zero, we are guaranteed that no one else holds a reference to the polling island (and that there is no racing pi_add_ref() call either). @@ -322,12 +325,20 @@ void pi_unref(polling_island *pi) { Also, if we are deleting the polling island and the merged_to field is non-empty, we should remove a ref to the merged_to polling island */ - if (gpr_unref(&pi->ref_count)) { - polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to); - polling_island_delete(pi); - if (next != NULL) { - PI_UNREF(next, "pi_delete"); /* Recursive call */ + switch (gpr_atm_full_fetch_add(&pi->ref_count, -1)) { + case 2: /* last external ref: the only one now owned is by the workqueue */ + GRPC_WORKQUEUE_UNREF(exec_ctx, pi->workqueue, "polling_island"); + break; + case 1: { + polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to); + polling_island_delete(exec_ctx, pi); + if (next != NULL) { + PI_UNREF(exec_ctx, next, "pi_delete"); /* Recursive call */ + } + break; } + case 0: + GPR_UNREACHABLE_CODE(return ); } } @@ -462,69 +473,68 @@ static void polling_island_remove_fd_locked(polling_island *pi, grpc_fd *fd, } /* Might return NULL in case of an error */ -static polling_island *polling_island_create(grpc_fd *initial_fd, +static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx, + grpc_fd *initial_fd, grpc_error **error) { polling_island *pi = NULL; - char *err_msg; const char *err_desc = "polling_island_create"; - /* Try to get one from the polling island freelist */ - gpr_mu_lock(&g_pi_freelist_mu); - if (g_pi_freelist != NULL) { - pi = g_pi_freelist; - g_pi_freelist = g_pi_freelist->next_free; - pi->next_free = NULL; - } - gpr_mu_unlock(&g_pi_freelist_mu); + *error = GRPC_ERROR_NONE; - /* Create new polling island if we could not get one from the free list */ - if (pi == NULL) { - pi = gpr_malloc(sizeof(*pi)); - gpr_mu_init(&pi->mu); - pi->fd_cnt = 0; - pi->fd_capacity = 0; - pi->fds = NULL; - } + pi = gpr_malloc(sizeof(*pi)); + gpr_mu_init(&pi->mu); + pi->fd_cnt = 0; + pi->fd_capacity = 0; + pi->fds = NULL; + pi->epoll_fd = -1; + pi->workqueue = NULL; - gpr_ref_init(&pi->ref_count, 0); + gpr_atm_rel_store(&pi->ref_count, 0); gpr_atm_rel_store(&pi->merged_to, (gpr_atm)NULL); pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (pi->epoll_fd < 0) { - gpr_asprintf(&err_msg, "epoll_create1 failed with error %d (%s)", errno, - strerror(errno)); - append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc); - gpr_free(err_msg); - } else { - polling_island_add_wakeup_fd_locked(pi, &grpc_global_wakeup_fd, error); - pi->next_free = NULL; + append_error(error, GRPC_OS_ERROR(errno, "epoll_create1"), err_desc); + goto done; + } - if (initial_fd != NULL) { - /* Lock the polling island here just in case we got this structure from - the freelist and the polling island lock was not released yet (by the - code that adds the polling island to the freelist) */ - gpr_mu_lock(&pi->mu); - polling_island_add_fds_locked(pi, &initial_fd, 1, true, error); - gpr_mu_unlock(&pi->mu); - } + polling_island_add_wakeup_fd_locked(pi, &grpc_global_wakeup_fd, error); + + if (initial_fd != NULL) { + polling_island_add_fds_locked(pi, &initial_fd, 1, true, error); + } + + if (append_error(error, grpc_workqueue_create(exec_ctx, &pi->workqueue), + err_desc) && + *error == GRPC_ERROR_NONE) { + polling_island_add_fds_locked(pi, &pi->workqueue->wakeup_read_fd, 1, true, + error); + GPR_ASSERT(pi->workqueue->wakeup_read_fd->polling_island == NULL); + pi->workqueue->wakeup_read_fd->polling_island = pi; + PI_ADD_REF(pi, "fd"); } +done: + if (*error != GRPC_ERROR_NONE) { + if (pi->workqueue != NULL) { + GRPC_WORKQUEUE_UNREF(exec_ctx, pi->workqueue, "polling_island"); + } + polling_island_delete(exec_ctx, pi); + pi = NULL; + } return pi; } -static void polling_island_delete(polling_island *pi) { +static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi) { GPR_ASSERT(pi->fd_cnt == 0); - gpr_atm_rel_store(&pi->merged_to, (gpr_atm)NULL); - - close(pi->epoll_fd); - pi->epoll_fd = -1; - - gpr_mu_lock(&g_pi_freelist_mu); - pi->next_free = g_pi_freelist; - g_pi_freelist = pi; - gpr_mu_unlock(&g_pi_freelist_mu); + if (pi->epoll_fd >= 0) { + close(pi->epoll_fd); + } + gpr_mu_destroy(&pi->mu); + gpr_free(pi->fds); + gpr_free(pi); } /* Attempts to gets the last polling island in the linked list (liked by the @@ -704,9 +714,6 @@ static polling_island *polling_island_merge(polling_island *p, static grpc_error *polling_island_global_init() { grpc_error *error = GRPC_ERROR_NONE; - gpr_mu_init(&g_pi_freelist_mu); - g_pi_freelist = NULL; - error = grpc_wakeup_fd_init(&polling_island_wakeup_fd); if (error == GRPC_ERROR_NONE) { error = grpc_wakeup_fd_wakeup(&polling_island_wakeup_fd); @@ -716,18 +723,6 @@ static grpc_error *polling_island_global_init() { } static void polling_island_global_shutdown() { - polling_island *next; - gpr_mu_lock(&g_pi_freelist_mu); - gpr_mu_unlock(&g_pi_freelist_mu); - while (g_pi_freelist != NULL) { - next = g_pi_freelist->next_free; - gpr_mu_destroy(&g_pi_freelist->mu); - gpr_free(g_pi_freelist->fds); - gpr_free(g_pi_freelist); - g_pi_freelist = next; - } - gpr_mu_destroy(&g_pi_freelist_mu); - grpc_wakeup_fd_destroy(&polling_island_wakeup_fd); } @@ -845,7 +840,6 @@ static grpc_fd *fd_create(int fd, const char *name) { if (new_fd == NULL) { new_fd = gpr_malloc(sizeof(grpc_fd)); gpr_mu_init(&new_fd->mu); - gpr_mu_init(&new_fd->pi_mu); } /* Note: It is not really needed to get the new_fd->mu lock here. If this is a @@ -896,6 +890,7 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, const char *reason) { bool is_fd_closed = false; grpc_error *error = GRPC_ERROR_NONE; + polling_island *unref_pi = NULL; gpr_mu_lock(&fd->mu); fd->on_done_closure = on_done; @@ -923,21 +918,26 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, - Unlock the latest polling island - Set fd->polling_island to NULL (but remove the ref on the polling island before doing this.) */ - gpr_mu_lock(&fd->pi_mu); if (fd->polling_island != NULL) { polling_island *pi_latest = polling_island_lock(fd->polling_island); polling_island_remove_fd_locked(pi_latest, fd, is_fd_closed, &error); gpr_mu_unlock(&pi_latest->mu); - PI_UNREF(fd->polling_island, "fd_orphan"); + unref_pi = fd->polling_island; fd->polling_island = NULL; } - gpr_mu_unlock(&fd->pi_mu); grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, error, NULL); gpr_mu_unlock(&fd->mu); UNREF_BY(fd, 2, reason); /* Drop the reference */ + if (unref_pi != NULL) { + /* Unref stale polling island here, outside the fd lock above. + The polling island owns a workqueue which owns an fd, and unreffing + inside the lock can cause an eventual lock loop that makes TSAN very + unhappy. */ + PI_UNREF(exec_ctx, unref_pi, "fd_orphan"); + } GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error)); } @@ -1037,6 +1037,17 @@ static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_mu_unlock(&fd->mu); } +static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) { + gpr_mu_lock(&fd->mu); + grpc_workqueue *workqueue = NULL; + if (fd->polling_island != NULL) { + workqueue = + GRPC_WORKQUEUE_REF(fd->polling_island->workqueue, "get_workqueue"); + } + gpr_mu_unlock(&fd->mu); + return workqueue; +} + /******************************************************************************* * Pollset Definitions */ @@ -1227,9 +1238,10 @@ static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { gpr_mu_unlock(&fd->mu); } -static void pollset_release_polling_island(grpc_pollset *ps, char *reason) { +static void pollset_release_polling_island(grpc_exec_ctx *exec_ctx, + grpc_pollset *ps, char *reason) { if (ps->polling_island != NULL) { - PI_UNREF(ps->polling_island, reason); + PI_UNREF(exec_ctx, ps->polling_island, reason); } ps->polling_island = NULL; } @@ -1242,7 +1254,7 @@ static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx, pollset->finish_shutdown_called = true; /* Release the ref and set pollset->polling_island to NULL */ - pollset_release_polling_island(pollset, "ps_shutdown"); + pollset_release_polling_island(exec_ctx, pollset, "ps_shutdown"); grpc_exec_ctx_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE, NULL); } @@ -1281,7 +1293,7 @@ static void pollset_reset(grpc_pollset *pollset) { pollset->finish_shutdown_called = false; pollset->kicked_without_pollers = false; pollset->shutdown_done = NULL; - pollset_release_polling_island(pollset, "ps_reset"); + GPR_ASSERT(pollset->polling_island == NULL); } #define GRPC_EPOLL_MAX_EVENTS 1000 @@ -1309,7 +1321,7 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, this function (i.e pollset_work_and_unlock()) is called */ if (pollset->polling_island == NULL) { - pollset->polling_island = polling_island_create(NULL, error); + pollset->polling_island = polling_island_create(exec_ctx, NULL, error); if (pollset->polling_island == NULL) { GPR_TIMER_END("pollset_work_and_unlock", 0); return; /* Fatal error. We cannot continue */ @@ -1329,7 +1341,7 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, /* Always do PI_ADD_REF before PI_UNREF because PI_UNREF may cause the polling island to be deleted */ PI_ADD_REF(pi, "ps"); - PI_UNREF(pollset->polling_island, "ps"); + PI_UNREF(exec_ctx, pollset->polling_island, "ps"); pollset->polling_island = pi; } @@ -1400,7 +1412,7 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, that we got before releasing the polling island lock). This is because pollset->polling_island pointer might get udpated in other parts of the code when there is an island merge while we are doing epoll_wait() above */ - PI_UNREF(pi, "ps_work"); + PI_UNREF(exec_ctx, pi, "ps_work"); GPR_TIMER_END("pollset_work_and_unlock", 0); } @@ -1517,10 +1529,11 @@ static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_error *error = GRPC_ERROR_NONE; gpr_mu_lock(&pollset->mu); - gpr_mu_lock(&fd->pi_mu); + gpr_mu_lock(&fd->mu); polling_island *pi_new = NULL; +retry: /* 1) If fd->polling_island and pollset->polling_island are both non-NULL and * equal, do nothing. * 2) If fd->polling_island and pollset->polling_island are both NULL, create @@ -1535,15 +1548,44 @@ static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, * polling_island fields in both fd and pollset to point to the merged * polling island. */ + + if (fd->orphaned) { + gpr_mu_unlock(&fd->mu); + gpr_mu_unlock(&pollset->mu); + /* early out */ + return; + } + if (fd->polling_island == pollset->polling_island) { pi_new = fd->polling_island; if (pi_new == NULL) { - pi_new = polling_island_create(fd, &error); - - GRPC_POLLING_TRACE( - "pollset_add_fd: Created new polling island. pi_new: %p (fd: %d, " - "pollset: %p)", - (void *)pi_new, fd->fd, (void *)pollset); + /* Unlock before creating a new polling island: the polling island will + create a workqueue which creates a file descriptor, and holding an fd + lock here can eventually cause a loop to appear to TSAN (making it + unhappy). We don't think it's a real loop (there's an epoch point where + that loop possibility disappears), but the advantages of keeping TSAN + happy outweigh any performance advantage we might have by keeping the + lock held. */ + gpr_mu_unlock(&fd->mu); + pi_new = polling_island_create(exec_ctx, fd, &error); + gpr_mu_lock(&fd->mu); + /* Need to reverify any assumptions made between the initial lock and + getting to this branch: if they've changed, we need to throw away our + work and figure things out again. */ + if (fd->polling_island != NULL) { + GRPC_POLLING_TRACE( + "pollset_add_fd: Raced creating new polling island. pi_new: %p " + "(fd: %d, pollset: %p)", + (void *)pi_new, fd->fd, (void *)pollset); + PI_ADD_REF(pi_new, "dance_of_destruction"); + PI_UNREF(exec_ctx, pi_new, "dance_of_destruction"); + goto retry; + } else { + GRPC_POLLING_TRACE( + "pollset_add_fd: Created new polling island. pi_new: %p (fd: %d, " + "pollset: %p)", + (void *)pi_new, fd->fd, (void *)pollset); + } } } else if (fd->polling_island == NULL) { pi_new = polling_island_lock(pollset->polling_island); @@ -1579,7 +1621,7 @@ static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, if (fd->polling_island != pi_new) { PI_ADD_REF(pi_new, "fd"); if (fd->polling_island != NULL) { - PI_UNREF(fd->polling_island, "fd"); + PI_UNREF(exec_ctx, fd->polling_island, "fd"); } fd->polling_island = pi_new; } @@ -1587,13 +1629,15 @@ static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, if (pollset->polling_island != pi_new) { PI_ADD_REF(pi_new, "ps"); if (pollset->polling_island != NULL) { - PI_UNREF(pollset->polling_island, "ps"); + PI_UNREF(exec_ctx, pollset->polling_island, "ps"); } pollset->polling_island = pi_new; } - gpr_mu_unlock(&fd->pi_mu); + gpr_mu_unlock(&fd->mu); gpr_mu_unlock(&pollset->mu); + + GRPC_LOG_IF_ERROR("pollset_add_fd", error); } /******************************************************************************* @@ -1744,9 +1788,9 @@ static void pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx, void *grpc_fd_get_polling_island(grpc_fd *fd) { polling_island *pi; - gpr_mu_lock(&fd->pi_mu); + gpr_mu_lock(&fd->mu); pi = fd->polling_island; - gpr_mu_unlock(&fd->pi_mu); + gpr_mu_unlock(&fd->mu); return pi; } @@ -1794,6 +1838,7 @@ static const grpc_event_engine_vtable vtable = { .fd_notify_on_read = fd_notify_on_read, .fd_notify_on_write = fd_notify_on_write, .fd_get_read_notifier_pollset = fd_get_read_notifier_pollset, + .fd_get_workqueue = fd_get_workqueue, .pollset_init = pollset_init, .pollset_shutdown = pollset_shutdown, diff --git a/src/core/lib/iomgr/ev_poll_and_epoll_posix.c b/src/core/lib/iomgr/ev_poll_and_epoll_posix.c index 9e306af5fac58..c2107e5e39320 100644 --- a/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +++ b/src/core/lib/iomgr/ev_poll_and_epoll_posix.c @@ -725,6 +725,8 @@ static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher, GRPC_FD_UNREF(fd, "poll"); } +static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) { return NULL; } + /******************************************************************************* * pollset_posix.c */ @@ -2006,6 +2008,7 @@ static const grpc_event_engine_vtable vtable = { .fd_notify_on_read = fd_notify_on_read, .fd_notify_on_write = fd_notify_on_write, .fd_get_read_notifier_pollset = fd_get_read_notifier_pollset, + .fd_get_workqueue = fd_get_workqueue, .pollset_init = pollset_init, .pollset_shutdown = pollset_shutdown, diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 45c0a5e954668..4b593f4b2c208 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -617,6 +617,8 @@ static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher, GRPC_FD_UNREF(fd, "poll"); } +static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) { return NULL; } + /******************************************************************************* * pollset_posix.c */ @@ -1234,6 +1236,7 @@ static const grpc_event_engine_vtable vtable = { .fd_notify_on_read = fd_notify_on_read, .fd_notify_on_write = fd_notify_on_write, .fd_get_read_notifier_pollset = fd_get_read_notifier_pollset, + .fd_get_workqueue = fd_get_workqueue, .pollset_init = pollset_init, .pollset_shutdown = pollset_shutdown, diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index a3c1e9db9a08b..65366726859da 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -148,6 +148,10 @@ grpc_fd *grpc_fd_create(int fd, const char *name) { return g_event_engine->fd_create(fd, name); } +grpc_workqueue *grpc_fd_get_workqueue(grpc_fd *fd) { + return g_event_engine->fd_get_workqueue(fd); +} + int grpc_fd_wrapped_fd(grpc_fd *fd) { return g_event_engine->fd_wrapped_fd(fd); } diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 579c84ef70725..c2aa1756ea2bb 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -56,6 +56,7 @@ typedef struct grpc_event_engine_vtable { void (*fd_notify_on_write)(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *closure); bool (*fd_is_shutdown)(grpc_fd *fd); + grpc_workqueue *(*fd_get_workqueue)(grpc_fd *fd); grpc_pollset *(*fd_get_read_notifier_pollset)(grpc_exec_ctx *exec_ctx, grpc_fd *fd); @@ -107,6 +108,9 @@ const char *grpc_get_poll_strategy_name(); This takes ownership of closing fd. */ grpc_fd *grpc_fd_create(int fd, const char *name); +/* Get a workqueue that's associated with this fd */ +grpc_workqueue *grpc_fd_get_workqueue(grpc_fd *fd); + /* Return the wrapped fd, or -1 if it has been released or closed. */ int grpc_fd_wrapped_fd(grpc_fd *fd); diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index c44aafcddf054..ac7785ec1353e 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -37,6 +37,7 @@ #include #include +#include "src/core/lib/iomgr/workqueue.h" #include "src/core/lib/profiling/timers.h" bool grpc_exec_ctx_ready_to_finish(grpc_exec_ctx *exec_ctx) { @@ -85,14 +86,17 @@ void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) { void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_error *error, grpc_workqueue *offload_target_or_null) { - GPR_ASSERT(offload_target_or_null == NULL); - grpc_closure_list_append(&exec_ctx->closure_list, closure, error); + if (offload_target_or_null == NULL) { + grpc_closure_list_append(&exec_ctx->closure_list, closure, error); + } else { + grpc_workqueue_enqueue(exec_ctx, offload_target_or_null, closure, error); + GRPC_WORKQUEUE_UNREF(exec_ctx, offload_target_or_null, "exec_ctx_sched"); + } } void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, grpc_closure_list *list, grpc_workqueue *offload_target_or_null) { - GPR_ASSERT(offload_target_or_null == NULL); grpc_closure_list_move(list, &exec_ctx->closure_list); } diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 38f27d9b136da..917f332f03de9 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -93,7 +93,11 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx); /** Finish any pending work for a grpc_exec_ctx. Must be called before * the instance is destroyed, or work may be lost. */ void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx); -/** Add a closure to be executed at the next flush/finish point */ +/** Add a closure to be executed in the future. + If \a offload_target_or_null is NULL, the closure will be executed at the + next exec_ctx.{finish,flush} point. + If \a offload_target_or_null is non-NULL, the closure will be scheduled + against the workqueue, and a reference to the workqueue will be consumed. */ void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_error *error, grpc_workqueue *offload_target_or_null); diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c index 89292a153ed3c..d67d388b8c975 100644 --- a/src/core/lib/iomgr/iomgr.c +++ b/src/core/lib/iomgr/iomgr.c @@ -45,6 +45,7 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/support/env.h" #include "src/core/lib/support/string.h" @@ -62,6 +63,7 @@ void grpc_iomgr_init(void) { grpc_timer_list_init(gpr_now(GPR_CLOCK_MONOTONIC)); g_root_object.next = g_root_object.prev = &g_root_object; g_root_object.name = "root"; + grpc_network_status_init(); grpc_iomgr_platform_init(); } @@ -140,6 +142,7 @@ void grpc_iomgr_shutdown(void) { grpc_iomgr_platform_shutdown(); grpc_exec_ctx_global_shutdown(); + grpc_network_status_shutdown(); gpr_mu_destroy(&g_mu); gpr_cv_destroy(&g_rcv); } diff --git a/src/core/lib/iomgr/network_status_tracker.c b/src/core/lib/iomgr/network_status_tracker.c index 38a1c9b7d4171..b4bb7e3cf7b22 100644 --- a/src/core/lib/iomgr/network_status_tracker.c +++ b/src/core/lib/iomgr/network_status_tracker.c @@ -42,10 +42,16 @@ typedef struct endpoint_ll_node { static endpoint_ll_node *head = NULL; static gpr_mu g_endpoint_mutex; -static bool g_init_done = false; -void grpc_initialize_network_status_monitor() { - g_init_done = true; +void grpc_network_status_shutdown(void) { + if (head != NULL) { + gpr_log(GPR_ERROR, + "Memory leaked as all network endpoints were not shut down"); + } + gpr_mu_destroy(&g_endpoint_mutex); +} + +void grpc_network_status_init(void) { gpr_mu_init(&g_endpoint_mutex); // TODO(makarandd): Install callback with OS to monitor network status. } @@ -60,9 +66,6 @@ void grpc_destroy_network_status_monitor() { } void grpc_network_status_register_endpoint(grpc_endpoint *ep) { - if (!g_init_done) { - grpc_initialize_network_status_monitor(); - } gpr_mu_lock(&g_endpoint_mutex); if (head == NULL) { head = (endpoint_ll_node *)gpr_malloc(sizeof(endpoint_ll_node)); diff --git a/src/core/lib/iomgr/network_status_tracker.h b/src/core/lib/iomgr/network_status_tracker.h index 74a1aa8135fb2..67cb645f44552 100644 --- a/src/core/lib/iomgr/network_status_tracker.h +++ b/src/core/lib/iomgr/network_status_tracker.h @@ -35,7 +35,11 @@ #define GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H #include "src/core/lib/iomgr/endpoint.h" +void grpc_network_status_init(void); +void grpc_network_status_shutdown(void); + void grpc_network_status_register_endpoint(grpc_endpoint *ep); void grpc_network_status_unregister_endpoint(grpc_endpoint *ep); void grpc_network_status_shutdown_all_endpoints(); + #endif /* GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H */ diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c index 2ab45e33ce3fd..ec21e0394488f 100644 --- a/src/core/lib/iomgr/tcp_posix.c +++ b/src/core/lib/iomgr/tcp_posix.c @@ -284,7 +284,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, } /* returns true if done, false if pending; if returning true, *error is set */ -#define MAX_WRITE_IOVEC 16 +#define MAX_WRITE_IOVEC 1024 static bool tcp_flush(grpc_tcp *tcp, grpc_error **error) { struct msghdr msg; struct iovec iov[MAX_WRITE_IOVEC]; @@ -450,9 +450,19 @@ static char *tcp_get_peer(grpc_endpoint *ep) { return gpr_strdup(tcp->peer_string); } -static const grpc_endpoint_vtable vtable = { - tcp_read, tcp_write, tcp_add_to_pollset, tcp_add_to_pollset_set, - tcp_shutdown, tcp_destroy, tcp_get_peer}; +static grpc_workqueue *tcp_get_workqueue(grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + return grpc_fd_get_workqueue(tcp->em_fd); +} + +static const grpc_endpoint_vtable vtable = {tcp_read, + tcp_write, + tcp_get_workqueue, + tcp_add_to_pollset, + tcp_add_to_pollset_set, + tcp_shutdown, + tcp_destroy, + tcp_get_peer}; grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size, const char *peer_string) { diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index d3803c3bd0e4d..cb2ff782d6044 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -491,7 +491,8 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { } for (unsigned i = 0; i < count; i++) { - int fd, port; + int fd = -1; + int port = -1; grpc_dualstack_mode dsmode; err = grpc_create_dualstack_socket(&listener->addr.sockaddr, SOCK_STREAM, 0, &dsmode, &fd); diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c index 37ab59021e367..35054c42b551b 100644 --- a/src/core/lib/iomgr/tcp_windows.c +++ b/src/core/lib/iomgr/tcp_windows.c @@ -389,9 +389,16 @@ static char *win_get_peer(grpc_endpoint *ep) { return gpr_strdup(tcp->peer_string); } -static grpc_endpoint_vtable vtable = { - win_read, win_write, win_add_to_pollset, win_add_to_pollset_set, - win_shutdown, win_destroy, win_get_peer}; +static grpc_workqueue *win_get_workqueue(grpc_endpoint *ep) { return NULL; } + +static grpc_endpoint_vtable vtable = {win_read, + win_write, + win_get_workqueue, + win_add_to_pollset, + win_add_to_pollset_set, + win_shutdown, + win_destroy, + win_get_peer}; grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string) { grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp)); diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h index 5cc40eea505f1..7156e490d7350 100644 --- a/src/core/lib/iomgr/workqueue.h +++ b/src/core/lib/iomgr/workqueue.h @@ -38,6 +38,7 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset_set.h" #ifdef GPR_POSIX_SOCKET #include "src/core/lib/iomgr/workqueue_posix.h" @@ -49,35 +50,45 @@ /* grpc_workqueue is forward declared in exec_ctx.h */ -/** Create a work queue */ -grpc_error *grpc_workqueue_create(grpc_exec_ctx *exec_ctx, - grpc_workqueue **workqueue); - +/* Deprecated: do not use. + This has *already* been removed in a future commit. */ void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); -#define GRPC_WORKQUEUE_REFCOUNT_DEBUG +/* Reference counting functions. Use the macro's always + (GRPC_WORKQUEUE_{REF,UNREF}). + + Pass in a descriptive reason string for reffing/unreffing as the last + argument to each macro. When GRPC_WORKQUEUE_REFCOUNT_DEBUG is defined, that + string will be printed alongside the refcount. When it is not defined, the + string will be discarded at compilation time. */ + +//#define GRPC_WORKQUEUE_REFCOUNT_DEBUG #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG #define GRPC_WORKQUEUE_REF(p, r) \ - grpc_workqueue_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_WORKQUEUE_UNREF(cl, p, r) \ - grpc_workqueue_unref((cl), (p), __FILE__, __LINE__, (r)) + (grpc_workqueue_ref((p), __FILE__, __LINE__, (r)), (p)) +#define GRPC_WORKQUEUE_UNREF(exec_ctx, p, r) \ + grpc_workqueue_unref((exec_ctx), (p), __FILE__, __LINE__, (r)) void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, const char *reason); void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, const char *file, int line, const char *reason); #else -#define GRPC_WORKQUEUE_REF(p, r) grpc_workqueue_ref((p)) +#define GRPC_WORKQUEUE_REF(p, r) (grpc_workqueue_ref((p)), (p)) #define GRPC_WORKQUEUE_UNREF(cl, p, r) grpc_workqueue_unref((cl), (p)) void grpc_workqueue_ref(grpc_workqueue *workqueue); void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); #endif -/** Bind this workqueue to a pollset */ -void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx, - grpc_workqueue *workqueue, - grpc_pollset *pollset); +/** Add a work item to a workqueue. Items added to a work queue will be started + in approximately the order they were enqueued, on some thread that may or + may not be the current thread. Successive closures enqueued onto a workqueue + MAY be executed concurrently. + + It is generally more expensive to add a closure to a workqueue than to the + execution context, both in terms of CPU work and in execution latency. -/** Add a work item to a workqueue */ + Use work queues when it's important that other threads be given a chance to + tackle some workload. */ void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, grpc_closure *closure, grpc_error *error); diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c index 45e0f6063b4f3..e0d6dac230879 100644 --- a/src/core/lib/iomgr/workqueue_posix.c +++ b/src/core/lib/iomgr/workqueue_posix.c @@ -70,7 +70,7 @@ grpc_error *grpc_workqueue_create(grpc_exec_ctx *exec_ctx, static void workqueue_destroy(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { - GPR_ASSERT(grpc_closure_list_empty(workqueue->closure_list)); + grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL); grpc_fd_shutdown(exec_ctx, workqueue->wakeup_read_fd); } @@ -100,12 +100,6 @@ void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { } } -void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx, - grpc_workqueue *workqueue, - grpc_pollset *pollset) { - grpc_pollset_add_fd(exec_ctx, pollset, workqueue->wakeup_read_fd); -} - void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { gpr_mu_lock(&workqueue->mu); grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL); diff --git a/src/core/lib/iomgr/workqueue_posix.h b/src/core/lib/iomgr/workqueue_posix.h index dcb47e7b59d3c..0f26ba58e27ec 100644 --- a/src/core/lib/iomgr/workqueue_posix.h +++ b/src/core/lib/iomgr/workqueue_posix.h @@ -50,4 +50,9 @@ struct grpc_workqueue { grpc_closure read_closure; }; +/** Create a work queue. Returns an error if creation fails. If creation + succeeds, sets *workqueue to point to it. */ +grpc_error *grpc_workqueue_create(grpc_exec_ctx *exec_ctx, + grpc_workqueue **workqueue); + #endif /* GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H */ diff --git a/src/core/lib/iomgr/workqueue_windows.c b/src/core/lib/iomgr/workqueue_windows.c index 275f040b1cc0f..23e2dea1859c7 100644 --- a/src/core/lib/iomgr/workqueue_windows.c +++ b/src/core/lib/iomgr/workqueue_windows.c @@ -37,4 +37,26 @@ #include "src/core/lib/iomgr/workqueue.h" +// Minimal implementation of grpc_workqueue for Windows +// Works by directly enqueuing workqueue items onto the current execution +// context, which is at least correct, if not performant or in the spirit of +// workqueues. + +void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) {} + +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG +void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, + const char *reason) {} +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason) {} +#else +void grpc_workqueue_ref(grpc_workqueue *workqueue) {} +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) {} +#endif + +void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + grpc_closure *closure, grpc_error *error) { + grpc_exec_ctx_sched(exec_ctx, closure, error, NULL); +} + #endif /* GPR_WINDOWS */ diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c index 7650d68e892df..bc50f9d1b0052 100644 --- a/src/core/lib/security/transport/secure_endpoint.c +++ b/src/core/lib/security/transport/secure_endpoint.c @@ -360,11 +360,19 @@ static char *endpoint_get_peer(grpc_endpoint *secure_ep) { return grpc_endpoint_get_peer(ep->wrapped_ep); } -static const grpc_endpoint_vtable vtable = { - endpoint_read, endpoint_write, - endpoint_add_to_pollset, endpoint_add_to_pollset_set, - endpoint_shutdown, endpoint_destroy, - endpoint_get_peer}; +static grpc_workqueue *endpoint_get_workqueue(grpc_endpoint *secure_ep) { + secure_endpoint *ep = (secure_endpoint *)secure_ep; + return grpc_endpoint_get_workqueue(ep->wrapped_ep); +} + +static const grpc_endpoint_vtable vtable = {endpoint_read, + endpoint_write, + endpoint_get_workqueue, + endpoint_add_to_pollset, + endpoint_add_to_pollset_set, + endpoint_shutdown, + endpoint_destroy, + endpoint_get_peer}; grpc_endpoint *grpc_secure_endpoint_create( struct tsi_frame_protector *protector, grpc_endpoint *transport, diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index def6e5068b012..2f108af48a129 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -73,6 +73,7 @@ typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type; typedef struct requested_call { requested_call_type type; + size_t cq_idx; void *tag; grpc_server *server; grpc_completion_queue *cq_bound_to_call; @@ -206,11 +207,11 @@ struct grpc_server { registered_method *registered_methods; /** one request matcher for unregistered methods */ request_matcher unregistered_request_matcher; - /** free list of available requested_calls indices */ - gpr_stack_lockfree *request_freelist; + /** free list of available requested_calls_per_cq indices */ + gpr_stack_lockfree **request_freelist_per_cq; /** requested call backing data */ - requested_call *requested_calls; - size_t max_requested_calls; + requested_call **requested_calls_per_cq; + int max_requested_calls_per_cq; gpr_atm shutdown_flag; uint8_t shutdown_published; @@ -357,7 +358,8 @@ static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx, for (size_t i = 0; i < server->cq_count; i++) { while ((request_id = gpr_stack_lockfree_pop(rm->requests_per_cq[i])) != -1) { - fail_call(exec_ctx, server, i, &server->requested_calls[request_id], + fail_call(exec_ctx, server, i, + &server->requested_calls_per_cq[i][request_id], GRPC_ERROR_REF(error)); } } @@ -392,12 +394,16 @@ static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) { } for (i = 0; i < server->cq_count; i++) { GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server"); + if (server->started) { + gpr_stack_lockfree_destroy(server->request_freelist_per_cq[i]); + gpr_free(server->requested_calls_per_cq[i]); + } } - gpr_stack_lockfree_destroy(server->request_freelist); + gpr_free(server->request_freelist_per_cq); + gpr_free(server->requested_calls_per_cq); gpr_free(server->cqs); gpr_free(server->pollsets); gpr_free(server->shutdown_tags); - gpr_free(server->requested_calls); gpr_free(server); } @@ -460,11 +466,13 @@ static void done_request_event(grpc_exec_ctx *exec_ctx, void *req, requested_call *rc = req; grpc_server *server = rc->server; - if (rc >= server->requested_calls && - rc < server->requested_calls + server->max_requested_calls) { - GPR_ASSERT(rc - server->requested_calls <= INT_MAX); - gpr_stack_lockfree_push(server->request_freelist, - (int)(rc - server->requested_calls)); + if (rc >= server->requested_calls_per_cq[rc->cq_idx] && + rc < server->requested_calls_per_cq[rc->cq_idx] + + server->max_requested_calls_per_cq) { + GPR_ASSERT(rc - server->requested_calls_per_cq[rc->cq_idx] <= INT_MAX); + gpr_stack_lockfree_push( + server->request_freelist_per_cq[rc->cq_idx], + (int)(rc - server->requested_calls_per_cq[rc->cq_idx])); } else { gpr_free(req); } @@ -540,7 +548,7 @@ static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, calld->state = ACTIVATED; gpr_mu_unlock(&calld->mu_state); publish_call(exec_ctx, server, calld, cq_idx, - &server->requested_calls[request_id]); + &server->requested_calls_per_cq[cq_idx][request_id]); return; /* early out */ } } @@ -979,8 +987,6 @@ void grpc_server_register_non_listening_completion_queue( } grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) { - size_t i; - GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved)); grpc_server *server = gpr_malloc(sizeof(grpc_server)); @@ -998,15 +1004,7 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) { &server->root_channel_data; /* TODO(ctiller): expose a channel_arg for this */ - server->max_requested_calls = 32768; - server->request_freelist = - gpr_stack_lockfree_create(server->max_requested_calls); - for (i = 0; i < (size_t)server->max_requested_calls; i++) { - gpr_stack_lockfree_push(server->request_freelist, (int)i); - } - server->requested_calls = gpr_malloc(server->max_requested_calls * - sizeof(*server->requested_calls)); - + server->max_requested_calls_per_cq = 32768; server->channel_args = grpc_channel_args_copy(args); return server; @@ -1066,16 +1064,28 @@ void grpc_server_start(grpc_server *server) { server->started = true; size_t pollset_count = 0; server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count); + server->request_freelist_per_cq = + gpr_malloc(sizeof(*server->request_freelist_per_cq) * server->cq_count); + server->requested_calls_per_cq = + gpr_malloc(sizeof(*server->requested_calls_per_cq) * server->cq_count); for (i = 0; i < server->cq_count; i++) { if (!grpc_cq_is_non_listening_server_cq(server->cqs[i])) { server->pollsets[pollset_count++] = grpc_cq_pollset(server->cqs[i]); } + server->request_freelist_per_cq[i] = + gpr_stack_lockfree_create((size_t)server->max_requested_calls_per_cq); + for (int j = 0; j < server->max_requested_calls_per_cq; j++) { + gpr_stack_lockfree_push(server->request_freelist_per_cq[i], j); + } + server->requested_calls_per_cq[i] = + gpr_malloc((size_t)server->max_requested_calls_per_cq * + sizeof(*server->requested_calls_per_cq[i])); } request_matcher_init(&server->unregistered_request_matcher, - server->max_requested_calls, server); + (size_t)server->max_requested_calls_per_cq, server); for (registered_method *rm = server->registered_methods; rm; rm = rm->next) { - request_matcher_init(&rm->request_matcher, server->max_requested_calls, - server); + request_matcher_init(&rm->request_matcher, + (size_t)server->max_requested_calls_per_cq, server); } for (l = server->listeners; l; l = l->next) { @@ -1307,11 +1317,13 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, GRPC_ERROR_CREATE("Server Shutdown")); return GRPC_CALL_OK; } - request_id = gpr_stack_lockfree_pop(server->request_freelist); + request_id = gpr_stack_lockfree_pop(server->request_freelist_per_cq[cq_idx]); if (request_id == -1) { /* out of request ids: just fail this one */ fail_call(exec_ctx, server, cq_idx, rc, - GRPC_ERROR_CREATE("Server Shutdown")); + grpc_error_set_int(GRPC_ERROR_CREATE("Out of request ids"), + GRPC_ERROR_INT_LIMIT, + server->max_requested_calls_per_cq)); return GRPC_CALL_OK; } switch (rc->type) { @@ -1322,7 +1334,7 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, rm = &rc->data.registered.registered_method->request_matcher; break; } - server->requested_calls[request_id] = *rc; + server->requested_calls_per_cq[cq_idx][request_id] = *rc; gpr_free(rc); if (gpr_stack_lockfree_push(rm->requests_per_cq[cq_idx], request_id)) { /* this was the first queued request: we need to lock and start @@ -1346,7 +1358,7 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, calld->state = ACTIVATED; gpr_mu_unlock(&calld->mu_state); publish_call(exec_ctx, server, calld, cq_idx, - &server->requested_calls[request_id]); + &server->requested_calls_per_cq[cq_idx][request_id]); } gpr_mu_lock(&server->mu_call); } @@ -1382,6 +1394,7 @@ grpc_call_error grpc_server_request_call( } grpc_cq_begin_op(cq_for_notification, tag); details->reserved = NULL; + rc->cq_idx = cq_idx; rc->type = BATCH_CALL; rc->server = server; rc->tag = tag; @@ -1430,6 +1443,7 @@ grpc_call_error grpc_server_request_registered_call( goto done; } grpc_cq_begin_op(cq_for_notification, tag); + rc->cq_idx = cq_idx; rc->type = REGISTERED_CALL; rc->server = server; rc->tag = tag; diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c index 054f112127ba3..68d05e3a85844 100644 --- a/src/core/lib/transport/connectivity_state.c +++ b/src/core/lib/transport/connectivity_state.c @@ -179,6 +179,9 @@ void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, while ((w = tracker->watchers) != NULL) { *w->current = tracker->current_state; tracker->watchers = w->next; + if (grpc_connectivity_state_trace) { + gpr_log(GPR_DEBUG, "NOTIFY: %p", w->notify); + } grpc_exec_ctx_sched(exec_ctx, w->notify, GRPC_ERROR_REF(tracker->current_error), NULL); gpr_free(w); diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c index 50e3c9cb89887..db45f5eb5ad8e 100644 --- a/test/core/end2end/tests/high_initial_seqno.c +++ b/test/core/end2end/tests/high_initial_seqno.c @@ -203,6 +203,12 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_call_destroy(c); grpc_call_destroy(s); + /* TODO(ctiller): this rate limits the test, and it should be removed when + retry has been implemented; until then cross-thread chatter + may result in some requests needing to be cancelled due to + seqno exhaustion. */ + cq_verify_empty(cqv); + cq_verifier_destroy(cqv); } diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c index 10207844ab039..39ddc13754313 100644 --- a/test/core/end2end/tests/network_status_change.c +++ b/test/core/end2end/tests/network_status_change.c @@ -186,9 +186,10 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == error); cq_expect_completion(cqv, tag(102), 1); + cq_verify(cqv); + // Simulate the network loss event grpc_network_status_shutdown_all_endpoints(); - cq_verify(cqv); op = ops; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; @@ -205,7 +206,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - void shutdown_all_endpoints(); + cq_expect_completion(cqv, tag(103), 1); cq_expect_completion(cqv, tag(1), 1); cq_verify(cqv); diff --git a/test/core/internal_api_canaries/iomgr.c b/test/core/internal_api_canaries/iomgr.c index 5e86c42309567..27d630623edee 100644 --- a/test/core/internal_api_canaries/iomgr.c +++ b/test/core/internal_api_canaries/iomgr.c @@ -77,11 +77,14 @@ static void test_code(void) { /* endpoint.h */ grpc_endpoint endpoint; - grpc_endpoint_vtable vtable = { - grpc_endpoint_read, grpc_endpoint_write, - grpc_endpoint_add_to_pollset, grpc_endpoint_add_to_pollset_set, - grpc_endpoint_shutdown, grpc_endpoint_destroy, - grpc_endpoint_get_peer}; + grpc_endpoint_vtable vtable = {grpc_endpoint_read, + grpc_endpoint_write, + grpc_endpoint_get_workqueue, + grpc_endpoint_add_to_pollset, + grpc_endpoint_add_to_pollset_set, + grpc_endpoint_shutdown, + grpc_endpoint_destroy, + grpc_endpoint_get_peer}; endpoint.vtable = &vtable; grpc_endpoint_read(&exec_ctx, &endpoint, NULL, NULL); diff --git a/test/core/iomgr/workqueue_test.c b/test/core/iomgr/workqueue_test.c deleted file mode 100644 index 76ecfae74b87b..0000000000000 --- a/test/core/iomgr/workqueue_test.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * - * 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 "src/core/lib/iomgr/workqueue.h" - -#include -#include -#include - -#include "test/core/util/test_config.h" - -static gpr_mu *g_mu; -static grpc_pollset *g_pollset; - -static void must_succeed(grpc_exec_ctx *exec_ctx, void *p, grpc_error *error) { - GPR_ASSERT(error == GRPC_ERROR_NONE); - gpr_mu_lock(g_mu); - *(int *)p = 1; - GPR_ASSERT( - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, NULL))); - gpr_mu_unlock(g_mu); -} - -static void test_ref_unref(void) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_workqueue *wq; - GPR_ASSERT(GRPC_LOG_IF_ERROR("grpc_workqueue_create", - grpc_workqueue_create(&exec_ctx, &wq))); - GRPC_WORKQUEUE_REF(wq, "test"); - GRPC_WORKQUEUE_UNREF(&exec_ctx, wq, "test"); - GRPC_WORKQUEUE_UNREF(&exec_ctx, wq, "destroy"); - grpc_exec_ctx_finish(&exec_ctx); -} - -static void test_add_closure(void) { - grpc_closure c; - int done = 0; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_workqueue *wq; - GPR_ASSERT(GRPC_LOG_IF_ERROR("grpc_workqueue_create", - grpc_workqueue_create(&exec_ctx, &wq))); - gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5); - grpc_pollset_worker *worker = NULL; - grpc_closure_init(&c, must_succeed, &done); - - grpc_workqueue_enqueue(&exec_ctx, wq, &c, GRPC_ERROR_NONE); - grpc_workqueue_add_to_pollset(&exec_ctx, wq, g_pollset); - - gpr_mu_lock(g_mu); - GPR_ASSERT(!done); - while (!done) { - GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(deadline.clock_type), deadline))); - } - gpr_mu_unlock(g_mu); - grpc_exec_ctx_finish(&exec_ctx); - GPR_ASSERT(done); - - GRPC_WORKQUEUE_UNREF(&exec_ctx, wq, "destroy"); - grpc_exec_ctx_finish(&exec_ctx); -} - -static void test_flush(void) { - grpc_closure c; - int done = 0; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_workqueue *wq; - GPR_ASSERT(GRPC_LOG_IF_ERROR("grpc_workqueue_create", - grpc_workqueue_create(&exec_ctx, &wq))); - gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5); - grpc_pollset_worker *worker = NULL; - grpc_closure_init(&c, must_succeed, &done); - - grpc_exec_ctx_sched(&exec_ctx, &c, GRPC_ERROR_NONE, NULL); - grpc_workqueue_flush(&exec_ctx, wq); - grpc_workqueue_add_to_pollset(&exec_ctx, wq, g_pollset); - - gpr_mu_lock(g_mu); - GPR_ASSERT(!done); - while (!done) { - GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(deadline.clock_type), deadline))); - } - gpr_mu_unlock(g_mu); - grpc_exec_ctx_finish(&exec_ctx); - GPR_ASSERT(done); - - GRPC_WORKQUEUE_UNREF(&exec_ctx, wq, "destroy"); - grpc_exec_ctx_finish(&exec_ctx); -} - -static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, - grpc_error *error) { - grpc_pollset_destroy(p); -} - -int main(int argc, char **argv) { - grpc_closure destroyed; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_test_init(argc, argv); - grpc_init(); - g_pollset = gpr_malloc(grpc_pollset_size()); - grpc_pollset_init(g_pollset, &g_mu); - - test_ref_unref(); - test_add_closure(); - test_flush(); - - grpc_closure_init(&destroyed, destroy_pollset, g_pollset); - grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed); - grpc_exec_ctx_finish(&exec_ctx); - grpc_shutdown(); - - gpr_free(g_pollset); - return 0; -} diff --git a/test/core/util/mock_endpoint.c b/test/core/util/mock_endpoint.c index ed9545e9df269..13e0e918fbe0d 100644 --- a/test/core/util/mock_endpoint.c +++ b/test/core/util/mock_endpoint.c @@ -95,9 +95,17 @@ static char *me_get_peer(grpc_endpoint *ep) { return gpr_strdup("fake:mock_endpoint"); } +static grpc_workqueue *me_get_workqueue(grpc_endpoint *ep) { return NULL; } + static const grpc_endpoint_vtable vtable = { - me_read, me_write, me_add_to_pollset, me_add_to_pollset_set, - me_shutdown, me_destroy, me_get_peer, + me_read, + me_write, + me_get_workqueue, + me_add_to_pollset, + me_add_to_pollset_set, + me_shutdown, + me_destroy, + me_get_peer, }; grpc_endpoint *grpc_mock_endpoint_create(void (*on_write)(gpr_slice slice)) { diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c index a39f3dd66e2e9..7ed9e97bd6a78 100644 --- a/test/core/util/passthru_endpoint.c +++ b/test/core/util/passthru_endpoint.c @@ -140,9 +140,17 @@ static char *me_get_peer(grpc_endpoint *ep) { return gpr_strdup("fake:mock_endpoint"); } +static grpc_workqueue *me_get_workqueue(grpc_endpoint *ep) { return NULL; } + static const grpc_endpoint_vtable vtable = { - me_read, me_write, me_add_to_pollset, me_add_to_pollset_set, - me_shutdown, me_destroy, me_get_peer, + me_read, + me_write, + me_get_workqueue, + me_add_to_pollset, + me_add_to_pollset_set, + me_shutdown, + me_destroy, + me_get_peer, }; static void half_init(half *m, passthru_endpoint *parent) { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 354a59cedd59b..0f87ae3e440df 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1166,6 +1166,9 @@ TEST_P(ProxyEnd2endTest, HugeResponse) { request.mutable_param()->set_response_message_length(kResponseSize); ClientContext context; + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::seconds(20); + context.set_deadline(deadline); Status s = stub_->Echo(&context, request, &response); EXPECT_EQ(kResponseSize, response.message().size()); EXPECT_TRUE(s.ok()); diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index 1507d1e3d6678..5dd0bd8533915 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -206,21 +206,30 @@ class AsyncClient : public ClientImpl { void* got_tag; bool ok; - if (cli_cqs_[thread_idx]->Next(&got_tag, &ok)) { - // Got a regular event, so process it - ClientRpcContext* ctx = ClientRpcContext::detag(got_tag); - if (!ctx->RunNextState(ok, histogram)) { - // The RPC and callback are done, so clone the ctx - // and kickstart the new one - auto clone = ctx->StartNewClone(); - clone->Start(cli_cqs_[thread_idx].get()); - // delete the old version - delete ctx; + switch (cli_cqs_[thread_idx]->AsyncNext( + &got_tag, &ok, + std::chrono::system_clock::now() + std::chrono::milliseconds(10))) { + case CompletionQueue::SHUTDOWN: + return false; + case CompletionQueue::GOT_EVENT: { + // Got a regular event, so process it + ClientRpcContext* ctx = ClientRpcContext::detag(got_tag); + if (!ctx->RunNextState(ok, histogram)) { + // The RPC and callback are done, so clone the ctx + // and kickstart the new one + auto clone = ctx->StartNewClone(); + clone->Start(cli_cqs_[thread_idx].get()); + // delete the old version + delete ctx; + } + return true; } - return true; - } else { // queue is shutting down - return false; + case CompletionQueue::TIMEOUT: + // TODO(ctiller): do something here to track how frequently we pass + // through this codepath. + return true; } + GPR_UNREACHABLE_CODE(return false); } protected: diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index 34b815144112d..4ff4e44b8b272 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -45,9 +45,10 @@ def _scenario_json_string(scenario_json): # tweak parameters to get fast test times - scenario_json['warmup_seconds'] = 1 + scenario_json['warmup_seconds'] = 0 scenario_json['benchmark_seconds'] = 1 - return json.dumps(scenario_config.remove_nonproto_fields(scenario_json)) + scenarios_json = {'scenarios': [scenario_config.remove_nonproto_fields(scenario_json)]} + return json.dumps(scenarios_json) def threads_of_type(scenario_json, path): d = scenario_json @@ -72,8 +73,7 @@ def guess_cpu(scenario_json): { 'name': 'json_run_localhost', 'shortname': 'json_run_localhost:%s' % scenario_json['name'], - 'args': ['--scenario_json', - pipes.quote(_scenario_json_string(scenario_json))], + 'args': ['--scenarios_json', _scenario_json_string(scenario_json)], 'ci_platforms': ['linux', 'mac', 'posix', 'windows'], 'platforms': ['linux', 'mac', 'posix', 'windows'], 'flaky': False, @@ -81,7 +81,8 @@ def guess_cpu(scenario_json): 'boringssl': True, 'defaults': 'boringssl', 'cpu_cost': guess_cpu(scenario_json), - 'exclude_configs': [] + 'exclude_configs': [], + 'timeout_seconds': 3*60 } for scenario_json in scenario_config.CXXLanguage().scenarios() ] diff --git a/test/cpp/qps/json_run_localhost.cc b/test/cpp/qps/json_run_localhost.cc index 6545dc2917db4..74e40fbf1a9b3 100644 --- a/test/cpp/qps/json_run_localhost.cc +++ b/test/cpp/qps/json_run_localhost.cc @@ -75,7 +75,7 @@ int main(int argc, char** argv) { for (int i = 1; i < argc; i++) { args.push_back(argv[i]); } - SubProcess(args).Join(); + GPR_ASSERT(SubProcess(args).Join() == 0); for (auto it = jobs.begin(); it != jobs.end(); ++it) { (*it)->Interrupt(); diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index c9954d0d02d92..73ca19148b56c 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -102,7 +102,7 @@ class AsyncQpsServerTest : public Server { auto process_rpc_bound = std::bind(process_rpc, config.payload_config(), _1, _2); - for (int i = 0; i < 10000 / num_threads; i++) { + for (int i = 0; i < 15000; i++) { for (int j = 0; j < num_threads; j++) { if (request_unary_function) { auto request_unary = @@ -132,7 +132,8 @@ class AsyncQpsServerTest : public Server { for (auto ss = shutdown_state_.begin(); ss != shutdown_state_.end(); ++ss) { (*ss)->set_shutdown(); } - server_->Shutdown(); + server_->Shutdown(std::chrono::system_clock::now() + + std::chrono::seconds(3)); for (auto thr = threads_.begin(); thr != threads_.end(); thr++) { thr->join(); } diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_pyenv_x64/Dockerfile new file mode 100644 index 0000000000000..abb5f3c89b3ae --- /dev/null +++ b/tools/dockerfile/test/python_pyenv_x64/Dockerfile @@ -0,0 +1,112 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM debian:jessie + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +#==================== +# Python dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + python-all-dev \ + python3-all-dev \ + python-pip + +# Install Python packages from PyPI +RUN pip install pip --upgrade +RUN pip install virtualenv +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 + +# Install dependencies for pyenv +RUN apt-get update && apt-get install -y \ + libbz2-dev \ + libncurses5-dev \ + libncursesw5-dev \ + libreadline-dev \ + libsqlite3-dev \ + libssl-dev \ + llvm \ + mercurial \ + zlib1g-dev && apt-get clean + +# Install Pyenv and dev Python versions 3.5 and 3.6 +RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash +RUN pyenv update +RUN pyenv install 3.5-dev +RUN pyenv install 3.6-dev +RUN pyenv local 3.5-dev 3.6-dev + +# Prepare ccache +RUN ln -s /usr/bin/ccache /usr/local/bin/gcc +RUN ln -s /usr/bin/ccache /usr/local/bin/g++ +RUN ln -s /usr/bin/ccache /usr/local/bin/cc +RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN ln -s /usr/bin/ccache /usr/local/bin/clang +RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 95d53e5f9e59f..7dd9e12614655 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -39,6 +39,7 @@ import multiprocessing import os import os.path +import pipes import platform import random import re @@ -72,6 +73,9 @@ def platform_string(): return jobset.platform_string() +_DEFAULT_TIMEOUT_SECONDS = 5 * 60 + + # SimpleConfig: just compile with CONFIG=config, and run the binary to test class Config(object): @@ -84,7 +88,7 @@ def __init__(self, config, environ=None, timeout_multiplier=1, tool_prefix=[]): self.tool_prefix = tool_prefix self.timeout_multiplier = timeout_multiplier - def job_spec(self, cmdline, timeout_seconds=5*60, + def job_spec(self, cmdline, timeout_seconds=_DEFAULT_TIMEOUT_SECONDS, shortname=None, environ={}, cpu_cost=1.0, flaky=False): """Construct a jobset.JobSpec for a test under this config @@ -159,7 +163,7 @@ def test_specs(self): env={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH': _ROOT + '/src/core/lib/tsi/test_creds/ca.pem', 'GRPC_POLL_STRATEGY': polling_strategy} - shortname_ext = '' if polling_strategy=='all' else ' polling=%s' % polling_strategy + shortname_ext = '' if polling_strategy=='all' else ' GRPC_POLL_STRATEGY=%s' % polling_strategy if self.config.build_config in target['exclude_configs']: continue if self.platform == 'windows': @@ -190,28 +194,26 @@ def test_specs(self): assert line[1] == ' ' test = base + line.strip() cmdline = [binary] + ['--gtest_filter=%s' % test] - out.append(self.config.job_spec(cmdline, [binary], - shortname='%s:%s %s' % (binary, test, shortname_ext), + out.append(self.config.job_spec(cmdline, + shortname='%s --gtest_filter=%s %s' % (binary, test, shortname_ext), cpu_cost=target['cpu_cost'], environ=env)) else: cmdline = [binary] + target['args'] - out.append(self.config.job_spec(cmdline, [binary], - shortname=' '.join(cmdline) + shortname_ext, + out.append(self.config.job_spec(cmdline, + shortname=' '.join( + pipes.quote(arg) + for arg in cmdline) + + shortname_ext, cpu_cost=target['cpu_cost'], flaky=target.get('flaky', False), + timeout_seconds=target.get('timeout_seconds', _DEFAULT_TIMEOUT_SECONDS), environ=env)) elif self.args.regex == '.*' or self.platform == 'windows': print '\nWARNING: binary not found, skipping', binary return sorted(out) def make_targets(self): - test_regex = self.args.regex - if self.platform != 'windows' and self.args.regex != '.*': - # use the regex to minimize the number of things to build - return [os.path.basename(target['name']) - for target in get_c_tests(False, self.test_lang) - if re.search(test_regex, '/' + target['name'])] if self.platform == 'windows': # don't build tools on windows just yet return ['buildtests_%s' % self.make_target] @@ -1283,8 +1285,6 @@ def _build_and_run( jobset.message( 'FLAKE', '%s [%d/%d runs flaked]' % (k, num_failures, num_runs), do_newline=True) - else: - jobset.message('PASSED', k, do_newline=True) finally: for antagonist in antagonists: antagonist.kill() diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index cdbc254f4306a..e3cfd55cd62f1 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -1818,22 +1818,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "gpr_test_util", - "grpc", - "grpc_test_util" - ], - "headers": [], - "language": "c", - "name": "workqueue_test", - "src": [ - "test/core/iomgr/workqueue_test.c" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 93d42e34546ce..d94301b946bbb 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -1935,25 +1935,6 @@ "windows" ] }, - { - "args": [], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "gtest": false, - "language": "c", - "name": "workqueue_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [], "ci_platforms": [ @@ -27153,8 +27134,8 @@ }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27175,12 +27156,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_secure" + "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27201,12 +27183,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure" + "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27227,12 +27210,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure" + "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27253,12 +27237,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure" + "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27279,12 +27264,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure" + "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27305,12 +27291,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure" + "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27331,12 +27318,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure" + "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27357,12 +27345,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure" + "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27383,12 +27372,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure" + "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27409,12 +27399,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure" + "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27435,12 +27426,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure" + "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}" ], "boringssl": true, "ci_platforms": [ @@ -27461,12 +27453,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure" + "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27487,12 +27480,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure" + "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27513,12 +27507,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure" + "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27539,12 +27534,13 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure" + "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure", + "timeout_seconds": 180 }, { "args": [ - "--scenario_json", - "'{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 1, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'" + "--scenarios_json", + "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}" ], "boringssl": true, "ci_platforms": [ @@ -27565,7 +27561,8 @@ "posix", "windows" ], - "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure" + "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure", + "timeout_seconds": 180 }, { "args": [ From 77c7f9fd621148ed63f938c21ad3364bba65445e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 15 Jul 2016 07:21:14 -0700 Subject: [PATCH 098/151] Merge pull request #7407 from ctiller/delayed-write Benchmark fixes --- src/proto/grpc/testing/control.proto | 3 + test/cpp/qps/client.h | 68 ++++++++++---- test/cpp/qps/client_async.cc | 92 +++++++++++------- test/cpp/qps/client_sync.cc | 28 +++--- test/cpp/qps/driver.cc | 135 ++++++++++++++++++++------- test/cpp/qps/driver.h | 2 +- test/cpp/qps/qps_json_driver.cc | 18 +++- test/cpp/qps/qps_worker.cc | 40 ++++---- test/cpp/qps/server_async.cc | 56 +++++------ 9 files changed, 287 insertions(+), 155 deletions(-) diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto index 20496a8116b60..ece691081582b 100644 --- a/src/proto/grpc/testing/control.proto +++ b/src/proto/grpc/testing/control.proto @@ -229,4 +229,7 @@ message ScenarioResult { repeated int32 server_cores = 5; // An after-the-fact computed summary ScenarioResultSummary summary = 6; + // Information on success or failure of each worker + repeated bool client_success = 7; + repeated bool server_success = 8; } diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 047bd16408224..4045e13460f56 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -112,6 +112,21 @@ class ClientRequestCreator { } }; +class HistogramEntry GRPC_FINAL { + public: + HistogramEntry() : used_(false) {} + bool used() const { return used_; } + double value() const { return value_; } + void set_value(double v) { + used_ = true; + value_ = v; + } + + private: + bool used_; + double value_; +}; + class Client { public: Client() : timer_(new UsageTimer), interarrival_timer_() {} @@ -151,10 +166,21 @@ class Client { return stats; } + // Must call AwaitThreadsCompletion before destructor to avoid a race + // between destructor and invocation of virtual ThreadFunc + void AwaitThreadsCompletion() { + DestroyMultithreading(); + std::unique_lock g(thread_completion_mu_); + while (threads_remaining_ != 0) { + threads_complete_.wait(g); + } + } + protected: bool closed_loop_; void StartThreads(size_t num_threads) { + threads_remaining_ = num_threads; for (size_t i = 0; i < num_threads; i++) { threads_.emplace_back(new Thread(this, i)); } @@ -162,7 +188,8 @@ class Client { void EndThreads() { threads_.clear(); } - virtual bool ThreadFunc(Histogram* histogram, size_t thread_idx) = 0; + virtual void DestroyMultithreading() = 0; + virtual bool ThreadFunc(HistogramEntry* histogram, size_t thread_idx) = 0; void SetupLoadTest(const ClientConfig& config, size_t num_threads) { // Set up the load distribution based on the number of threads @@ -215,7 +242,6 @@ class Client { public: Thread(Client* client, size_t idx) : done_(false), - new_stats_(nullptr), client_(client), idx_(idx), impl_(&Thread::ThreadFunc, this) {} @@ -230,15 +256,10 @@ class Client { void BeginSwap(Histogram* n) { std::lock_guard g(mu_); - new_stats_ = n; + n->Swap(&histogram_); } - void EndSwap() { - std::unique_lock g(mu_); - while (new_stats_ != nullptr) { - cv_.wait(g); - }; - } + void EndSwap() {} void MergeStatsInto(Histogram* hist) { std::unique_lock g(mu_); @@ -252,29 +273,26 @@ class Client { void ThreadFunc() { for (;;) { // run the loop body - const bool thread_still_ok = client_->ThreadFunc(&histogram_, idx_); - // lock, see if we're done + HistogramEntry entry; + const bool thread_still_ok = client_->ThreadFunc(&entry, idx_); + // lock, update histogram if needed and see if we're done std::lock_guard g(mu_); + if (entry.used()) { + histogram_.Add(entry.value()); + } if (!thread_still_ok) { gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); done_ = true; } if (done_) { + client_->CompleteThread(); return; } - // check if we're resetting stats, swap out the histogram if so - if (new_stats_) { - new_stats_->Swap(&histogram_); - new_stats_ = nullptr; - cv_.notify_one(); - } } } std::mutex mu_; - std::condition_variable cv_; bool done_; - Histogram* new_stats_; Histogram histogram_; Client* client_; const size_t idx_; @@ -286,6 +304,18 @@ class Client { InterarrivalTimer interarrival_timer_; std::vector next_time_; + + std::mutex thread_completion_mu_; + size_t threads_remaining_; + std::condition_variable threads_complete_; + + void CompleteThread() { + std::lock_guard g(thread_completion_mu_); + threads_remaining_--; + if (threads_remaining_ == 0) { + threads_complete_.notify_all(); + } + } }; template diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index 5dd0bd8533915..5d9cb4bd0cfc3 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -31,7 +31,6 @@ * */ -#include #include #include #include @@ -48,7 +47,6 @@ #include #include #include -#include #include #include "src/proto/grpc/testing/services.grpc.pb.h" @@ -64,7 +62,7 @@ class ClientRpcContext { ClientRpcContext() {} virtual ~ClientRpcContext() {} // next state, return false if done. Collect stats when appropriate - virtual bool RunNextState(bool, Histogram* hist) = 0; + virtual bool RunNextState(bool, HistogramEntry* entry) = 0; virtual ClientRpcContext* StartNewClone() = 0; static void* tag(ClientRpcContext* c) { return reinterpret_cast(c); } static ClientRpcContext* detag(void* t) { @@ -104,7 +102,7 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { alarm_.reset(new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this))); } } - bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE { + bool RunNextState(bool ok, HistogramEntry* entry) GRPC_OVERRIDE { switch (next_state_) { case State::READY: start_ = UsageTimer::Now(); @@ -114,7 +112,7 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { next_state_ = State::RESP_DONE; return true; case State::RESP_DONE: - hist->Add((UsageTimer::Now() - start_) * 1e9); + entry->set_value((UsageTimer::Now() - start_) * 1e9); callback_(status_, &response_); next_state_ = State::INVALID; return false; @@ -176,6 +174,7 @@ class AsyncClient : public ClientImpl { for (int i = 0; i < num_async_threads_; i++) { cli_cqs_.emplace_back(new CompletionQueue); next_issuers_.emplace_back(NextIssuer(i)); + shutdown_state_.emplace_back(new PerThreadShutdownState()); } using namespace std::placeholders; @@ -192,7 +191,6 @@ class AsyncClient : public ClientImpl { } virtual ~AsyncClient() { for (auto cq = cli_cqs_.begin(); cq != cli_cqs_.end(); cq++) { - (*cq)->Shutdown(); void* got_tag; bool ok; while ((*cq)->Next(&got_tag, &ok)) { @@ -201,7 +199,36 @@ class AsyncClient : public ClientImpl { } } - bool ThreadFunc(Histogram* histogram, + protected: + const int num_async_threads_; + + private: + struct PerThreadShutdownState { + mutable std::mutex mutex; + bool shutdown; + PerThreadShutdownState() : shutdown(false) {} + }; + + int NumThreads(const ClientConfig& config) { + int num_threads = config.async_client_threads(); + if (num_threads <= 0) { // Use dynamic sizing + num_threads = cores_; + gpr_log(GPR_INFO, "Sizing async client to %d threads", num_threads); + } + return num_threads; + } + void DestroyMultithreading() GRPC_OVERRIDE GRPC_FINAL { + for (auto ss = shutdown_state_.begin(); ss != shutdown_state_.end(); ++ss) { + std::lock_guard lock((*ss)->mutex); + (*ss)->shutdown = true; + } + for (auto cq = cli_cqs_.begin(); cq != cli_cqs_.end(); cq++) { + (*cq)->Shutdown(); + } + this->EndThreads(); // this needed for resolution + } + + bool ThreadFunc(HistogramEntry* entry, size_t thread_idx) GRPC_OVERRIDE GRPC_FINAL { void* got_tag; bool ok; @@ -209,12 +236,15 @@ class AsyncClient : public ClientImpl { switch (cli_cqs_[thread_idx]->AsyncNext( &got_tag, &ok, std::chrono::system_clock::now() + std::chrono::milliseconds(10))) { - case CompletionQueue::SHUTDOWN: - return false; case CompletionQueue::GOT_EVENT: { // Got a regular event, so process it ClientRpcContext* ctx = ClientRpcContext::detag(got_tag); - if (!ctx->RunNextState(ok, histogram)) { + // Proceed while holding a lock to make sure that + // this thread isn't supposed to shut down + std::lock_guard l(shutdown_state_[thread_idx]->mutex); + if (shutdown_state_[thread_idx]->shutdown) { + return true; + } else if (!ctx->RunNextState(ok, entry)) { // The RPC and callback are done, so clone the ctx // and kickstart the new one auto clone = ctx->StartNewClone(); @@ -224,29 +254,23 @@ class AsyncClient : public ClientImpl { } return true; } - case CompletionQueue::TIMEOUT: - // TODO(ctiller): do something here to track how frequently we pass - // through this codepath. + case CompletionQueue::TIMEOUT: { + std::lock_guard l(shutdown_state_[thread_idx]->mutex); + if (shutdown_state_[thread_idx]->shutdown) { + return true; + } + return true; + } + case CompletionQueue::SHUTDOWN: // queue is shutting down, so we must be + // done return true; } - GPR_UNREACHABLE_CODE(return false); - } - - protected: - const int num_async_threads_; - - private: - int NumThreads(const ClientConfig& config) { - int num_threads = config.async_client_threads(); - if (num_threads <= 0) { // Use dynamic sizing - num_threads = cores_; - gpr_log(GPR_INFO, "Sizing async client to %d threads", num_threads); - } - return num_threads; + GPR_UNREACHABLE_CODE(return true); } std::vector> cli_cqs_; std::vector> next_issuers_; + std::vector> shutdown_state_; }; static std::unique_ptr BenchmarkStubCreator( @@ -262,7 +286,7 @@ class AsyncUnaryClient GRPC_FINAL config, SetupCtx, BenchmarkStubCreator) { StartThreads(num_async_threads_); } - ~AsyncUnaryClient() GRPC_OVERRIDE { EndThreads(); } + ~AsyncUnaryClient() GRPC_OVERRIDE {} private: static void CheckDone(grpc::Status s, SimpleResponse* response) {} @@ -307,7 +331,7 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext { stream_ = start_req_(stub_, &context_, cq, ClientRpcContext::tag(this)); next_state_ = State::STREAM_IDLE; } - bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE { + bool RunNextState(bool ok, HistogramEntry* entry) GRPC_OVERRIDE { while (true) { switch (next_state_) { case State::STREAM_IDLE: @@ -339,7 +363,7 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext { return true; break; case State::READ_DONE: - hist->Add((UsageTimer::Now() - start_) * 1e9); + entry->set_value((UsageTimer::Now() - start_) * 1e9); callback_(status_, &response_); next_state_ = State::STREAM_IDLE; break; // loop around @@ -391,7 +415,7 @@ class AsyncStreamingClient GRPC_FINAL StartThreads(num_async_threads_); } - ~AsyncStreamingClient() GRPC_OVERRIDE { EndThreads(); } + ~AsyncStreamingClient() GRPC_OVERRIDE {} private: static void CheckDone(grpc::Status s, SimpleResponse* response) {} @@ -439,7 +463,7 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext { ClientRpcContext::tag(this)); next_state_ = State::STREAM_IDLE; } - bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE { + bool RunNextState(bool ok, HistogramEntry* entry) GRPC_OVERRIDE { while (true) { switch (next_state_) { case State::STREAM_IDLE: @@ -471,7 +495,7 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext { return true; break; case State::READ_DONE: - hist->Add((UsageTimer::Now() - start_) * 1e9); + entry->set_value((UsageTimer::Now() - start_) * 1e9); callback_(status_, &response_); next_state_ = State::STREAM_IDLE; break; // loop around @@ -527,7 +551,7 @@ class GenericAsyncStreamingClient GRPC_FINAL StartThreads(num_async_threads_); } - ~GenericAsyncStreamingClient() GRPC_OVERRIDE { EndThreads(); } + ~GenericAsyncStreamingClient() GRPC_OVERRIDE {} private: static void CheckDone(grpc::Status s, ByteBuffer* response) {} diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index c88e95b80e5da..25c7823553262 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -31,7 +31,6 @@ * */ -#include #include #include #include @@ -46,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -55,7 +53,6 @@ #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/services.grpc.pb.h" #include "test/cpp/qps/client.h" -#include "test/cpp/qps/histogram.h" #include "test/cpp/qps/interarrival.h" #include "test/cpp/qps/usage_timer.h" @@ -90,6 +87,9 @@ class SynchronousClient size_t num_threads_; std::vector responses_; + + private: + void DestroyMultithreading() GRPC_OVERRIDE GRPC_FINAL { EndThreads(); } }; class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { @@ -98,9 +98,9 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { : SynchronousClient(config) { StartThreads(num_threads_); } - ~SynchronousUnaryClient() { EndThreads(); } + ~SynchronousUnaryClient() {} - bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE { + bool ThreadFunc(HistogramEntry* entry, size_t thread_idx) GRPC_OVERRIDE { WaitToIssue(thread_idx); auto* stub = channels_[thread_idx % channels_.size()].get_stub(); double start = UsageTimer::Now(); @@ -108,7 +108,7 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { grpc::ClientContext context; grpc::Status s = stub->UnaryCall(&context, request_, &responses_[thread_idx]); - histogram->Add((UsageTimer::Now() - start) * 1e9); + entry->set_value((UsageTimer::Now() - start) * 1e9); return s.ok(); } }; @@ -127,25 +127,29 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { StartThreads(num_threads_); } ~SynchronousStreamingClient() { - EndThreads(); - for (auto stream = &stream_[0]; stream != &stream_[num_threads_]; - stream++) { + for (size_t i = 0; i < num_threads_; i++) { + auto stream = &stream_[i]; if (*stream) { (*stream)->WritesDone(); - EXPECT_TRUE((*stream)->Finish().ok()); + Status s = (*stream)->Finish(); + EXPECT_TRUE(s.ok()); + if (!s.ok()) { + gpr_log(GPR_ERROR, "Stream %zu received an error %s", i, + s.error_message().c_str()); + } } } delete[] stream_; delete[] context_; } - bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE { + bool ThreadFunc(HistogramEntry* entry, size_t thread_idx) GRPC_OVERRIDE { WaitToIssue(thread_idx); GPR_TIMER_SCOPE("SynchronousStreamingClient::ThreadFunc", 0); double start = UsageTimer::Now(); if (stream_[thread_idx]->Write(request_) && stream_[thread_idx]->Read(&responses_[thread_idx])) { - histogram->Add((UsageTimer::Now() - start) * 1e9); + entry->set_value((UsageTimer::Now() - start) * 1e9); return true; } return false; diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 08bf0458832e3..2aeaea51f2540 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -87,7 +87,7 @@ static std::unordered_map> get_hosts_and_cores( CoreRequest dummy; CoreResponse cores; grpc::Status s = stub->CoreCount(&ctx, dummy, &cores); - assert(s.ok()); + GPR_ASSERT(s.ok()); std::deque dq; for (int i = 0; i < cores.cores(); i++) { dq.push_back(i); @@ -289,9 +289,13 @@ std::unique_ptr RunScenario( *args.mutable_setup() = server_config; servers[i].stream = servers[i].stub->RunServer(runsc::AllocContext(&contexts)); - GPR_ASSERT(servers[i].stream->Write(args)); + if (!servers[i].stream->Write(args)) { + gpr_log(GPR_ERROR, "Could not write args to server %zu", i); + } ServerStatus init_status; - GPR_ASSERT(servers[i].stream->Read(&init_status)); + if (!servers[i].stream->Read(&init_status)) { + gpr_log(GPR_ERROR, "Server %zu did not yield initial status", i); + } gpr_join_host_port(&cli_target, host, init_status.port()); client_config.add_server_targets(cli_target); gpr_free(host); @@ -345,9 +349,13 @@ std::unique_ptr RunScenario( *args.mutable_setup() = per_client_config; clients[i].stream = clients[i].stub->RunClient(runsc::AllocContext(&contexts)); - GPR_ASSERT(clients[i].stream->Write(args)); + if (!clients[i].stream->Write(args)) { + gpr_log(GPR_ERROR, "Could not write args to client %zu", i); + } ClientStatus init_status; - GPR_ASSERT(clients[i].stream->Read(&init_status)); + if (!clients[i].stream->Read(&init_status)) { + gpr_log(GPR_ERROR, "Client %zu did not yield initial status", i); + } } // Let everything warmup @@ -362,19 +370,31 @@ std::unique_ptr RunScenario( server_mark.mutable_mark()->set_reset(true); ClientArgs client_mark; client_mark.mutable_mark()->set_reset(true); - for (auto server = &servers[0]; server != &servers[num_servers]; server++) { - GPR_ASSERT(server->stream->Write(server_mark)); + for (size_t i = 0; i < num_servers; i++) { + auto server = &servers[i]; + if (!server->stream->Write(server_mark)) { + gpr_log(GPR_ERROR, "Couldn't write mark to server %zu", i); + } } - for (auto client = &clients[0]; client != &clients[num_clients]; client++) { - GPR_ASSERT(client->stream->Write(client_mark)); + for (size_t i = 0; i < num_clients; i++) { + auto client = &clients[i]; + if (!client->stream->Write(client_mark)) { + gpr_log(GPR_ERROR, "Couldn't write mark to client %zu", i); + } } ServerStatus server_status; ClientStatus client_status; - for (auto server = &servers[0]; server != &servers[num_servers]; server++) { - GPR_ASSERT(server->stream->Read(&server_status)); + for (size_t i = 0; i < num_servers; i++) { + auto server = &servers[i]; + if (!server->stream->Read(&server_status)) { + gpr_log(GPR_ERROR, "Couldn't get status from server %zu", i); + } } - for (auto client = &clients[0]; client != &clients[num_clients]; client++) { - GPR_ASSERT(client->stream->Read(&client_status)); + for (size_t i = 0; i < num_clients; i++) { + auto client = &clients[i]; + if (!client->stream->Read(&client_status)) { + gpr_log(GPR_ERROR, "Couldn't get status from client %zu", i); + } } // Wait some time @@ -390,37 +410,73 @@ std::unique_ptr RunScenario( Histogram merged_latencies; gpr_log(GPR_INFO, "Finishing clients"); - for (auto client = &clients[0]; client != &clients[num_clients]; client++) { - GPR_ASSERT(client->stream->Write(client_mark)); - GPR_ASSERT(client->stream->WritesDone()); + for (size_t i = 0; i < num_clients; i++) { + auto client = &clients[i]; + if (!client->stream->Write(client_mark)) { + gpr_log(GPR_ERROR, "Couldn't write mark to client %zu", i); + } + if (!client->stream->WritesDone()) { + gpr_log(GPR_ERROR, "Failed WritesDone for client %zu", i); + } } - for (auto client = &clients[0]; client != &clients[num_clients]; client++) { - GPR_ASSERT(client->stream->Read(&client_status)); - const auto& stats = client_status.stats(); - merged_latencies.MergeProto(stats.latencies()); - result->add_client_stats()->CopyFrom(stats); - GPR_ASSERT(!client->stream->Read(&client_status)); + for (size_t i = 0; i < num_clients; i++) { + auto client = &clients[i]; + // Read the client final status + if (client->stream->Read(&client_status)) { + gpr_log(GPR_INFO, "Received final status from client %zu", i); + const auto& stats = client_status.stats(); + merged_latencies.MergeProto(stats.latencies()); + result->add_client_stats()->CopyFrom(stats); + // That final status should be the last message on the client stream + GPR_ASSERT(!client->stream->Read(&client_status)); + } else { + gpr_log(GPR_ERROR, "Couldn't get final status from client %zu", i); + } } - for (auto client = &clients[0]; client != &clients[num_clients]; client++) { - GPR_ASSERT(client->stream->Finish().ok()); + for (size_t i = 0; i < num_clients; i++) { + auto client = &clients[i]; + Status s = client->stream->Finish(); + result->add_client_success(s.ok()); + if (!s.ok()) { + gpr_log(GPR_ERROR, "Client %zu had an error %s", i, + s.error_message().c_str()); + } } delete[] clients; merged_latencies.FillProto(result->mutable_latencies()); gpr_log(GPR_INFO, "Finishing servers"); - for (auto server = &servers[0]; server != &servers[num_servers]; server++) { - GPR_ASSERT(server->stream->Write(server_mark)); - GPR_ASSERT(server->stream->WritesDone()); + for (size_t i = 0; i < num_servers; i++) { + auto server = &servers[i]; + if (!server->stream->Write(server_mark)) { + gpr_log(GPR_ERROR, "Couldn't write mark to server %zu", i); + } + if (!server->stream->WritesDone()) { + gpr_log(GPR_ERROR, "Failed WritesDone for server %zu", i); + } } - for (auto server = &servers[0]; server != &servers[num_servers]; server++) { - GPR_ASSERT(server->stream->Read(&server_status)); - result->add_server_stats()->CopyFrom(server_status.stats()); - result->add_server_cores(server_status.cores()); - GPR_ASSERT(!server->stream->Read(&server_status)); + for (size_t i = 0; i < num_servers; i++) { + auto server = &servers[i]; + // Read the server final status + if (server->stream->Read(&server_status)) { + gpr_log(GPR_INFO, "Received final status from server %zu", i); + result->add_server_stats()->CopyFrom(server_status.stats()); + result->add_server_cores(server_status.cores()); + // That final status should be the last message on the server stream + GPR_ASSERT(!server->stream->Read(&server_status)); + } else { + gpr_log(GPR_ERROR, "Couldn't get final status from server %zu", i); + } } - for (auto server = &servers[0]; server != &servers[num_servers]; server++) { - GPR_ASSERT(server->stream->Finish().ok()); + for (size_t i = 0; i < num_servers; i++) { + auto server = &servers[i]; + Status s = server->stream->Finish(); + result->add_server_success(s.ok()); + if (!s.ok()) { + gpr_log(GPR_ERROR, "Server %zu had an error %s", i, + s.error_message().c_str()); + } } delete[] servers; @@ -429,8 +485,9 @@ std::unique_ptr RunScenario( return result; } -void RunQuit() { +bool RunQuit() { // Get client, server lists + bool result = true; auto workers = get_workers("QPS_WORKERS"); for (size_t i = 0; i < workers.size(); i++) { auto stub = WorkerService::NewStub( @@ -438,8 +495,14 @@ void RunQuit() { Void dummy; grpc::ClientContext ctx; ctx.set_fail_fast(false); - GPR_ASSERT(stub->QuitWorker(&ctx, dummy, &dummy).ok()); + Status s = stub->QuitWorker(&ctx, dummy, &dummy); + if (!s.ok()) { + gpr_log(GPR_ERROR, "Worker %zu could not be properly quit because %s", i, + s.error_message().c_str()); + result = false; + } } + return result; } } // namespace testing diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index 3a5cf138f11c3..93f4370cafa51 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -47,7 +47,7 @@ std::unique_ptr RunScenario( const grpc::testing::ServerConfig& server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count); -void RunQuit(); +bool RunQuit(); } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc index f5d739f893a45..1524ebbc38957 100644 --- a/test/cpp/qps/qps_json_driver.cc +++ b/test/cpp/qps/qps_json_driver.cc @@ -53,7 +53,7 @@ DEFINE_bool(quit, false, "Quit the workers"); namespace grpc { namespace testing { -static void QpsDriver() { +static bool QpsDriver() { grpc::string json; bool scfile = (FLAGS_scenarios_file != ""); @@ -81,13 +81,13 @@ static void QpsDriver() { } else if (scjson) { json = FLAGS_scenarios_json.c_str(); } else if (FLAGS_quit) { - RunQuit(); - return; + return RunQuit(); } // Parse into an array of scenarios Scenarios scenarios; ParseJson(json.c_str(), "grpc.testing.Scenarios", &scenarios); + bool success = true; // Make sure that there is at least some valid scenario here GPR_ASSERT(scenarios.scenarios_size() > 0); @@ -109,7 +109,15 @@ static void QpsDriver() { GetReporter()->ReportQPSPerCore(*result); GetReporter()->ReportLatency(*result); GetReporter()->ReportTimes(*result); + + for (int i = 0; success && i < result->client_success_size(); i++) { + success = result->client_success(i); + } + for (int i = 0; success && i < result->server_success_size(); i++) { + success = result->server_success(i); + } } + return success; } } // namespace testing @@ -118,7 +126,7 @@ static void QpsDriver() { int main(int argc, char **argv) { grpc::testing::InitBenchmark(&argc, &argv, true); - grpc::testing::QpsDriver(); + bool ok = grpc::testing::QpsDriver(); - return 0; + return ok ? 0 : 1; } diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index f514e23e85404..d3e53fe14a63a 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -33,7 +33,6 @@ #include "test/cpp/qps/qps_worker.h" -#include #include #include #include @@ -124,11 +123,12 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service { GRPC_OVERRIDE { InstanceGuard g(this); if (!g.Acquired()) { - return Status(StatusCode::RESOURCE_EXHAUSTED, ""); + return Status(StatusCode::RESOURCE_EXHAUSTED, "Client worker busy"); } ScopedProfile profile("qps_client.prof", false); Status ret = RunClientBody(ctx, stream); + gpr_log(GPR_INFO, "RunClient: Returning"); return ret; } @@ -137,11 +137,12 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service { GRPC_OVERRIDE { InstanceGuard g(this); if (!g.Acquired()) { - return Status(StatusCode::RESOURCE_EXHAUSTED, ""); + return Status(StatusCode::RESOURCE_EXHAUSTED, "Server worker busy"); } ScopedProfile profile("qps_server.prof", false); Status ret = RunServerBody(ctx, stream); + gpr_log(GPR_INFO, "RunServer: Returning"); return ret; } @@ -154,7 +155,7 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service { Status QuitWorker(ServerContext* ctx, const Void*, Void*) GRPC_OVERRIDE { InstanceGuard g(this); if (!g.Acquired()) { - return Status(StatusCode::RESOURCE_EXHAUSTED, ""); + return Status(StatusCode::RESOURCE_EXHAUSTED, "Quitting worker busy"); } worker_->MarkDone(); @@ -197,33 +198,38 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service { ServerReaderWriter* stream) { ClientArgs args; if (!stream->Read(&args)) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Couldn't read args"); } if (!args.has_setup()) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Invalid setup arg"); } gpr_log(GPR_INFO, "RunClientBody: about to create client"); auto client = CreateClient(args.setup()); if (!client) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Couldn't create client"); } gpr_log(GPR_INFO, "RunClientBody: client created"); ClientStatus status; if (!stream->Write(status)) { - return Status(StatusCode::UNKNOWN, ""); + return Status(StatusCode::UNKNOWN, "Client couldn't report init status"); } gpr_log(GPR_INFO, "RunClientBody: creation status reported"); while (stream->Read(&args)) { gpr_log(GPR_INFO, "RunClientBody: Message read"); if (!args.has_mark()) { gpr_log(GPR_INFO, "RunClientBody: Message is not a mark!"); - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Invalid mark"); } *status.mutable_stats() = client->Mark(args.mark().reset()); - stream->Write(status); + if (!stream->Write(status)) { + return Status(StatusCode::UNKNOWN, "Client couldn't respond to mark"); + } gpr_log(GPR_INFO, "RunClientBody: Mark response given"); } + gpr_log(GPR_INFO, "RunClientBody: Awaiting Threads Completion"); + client->AwaitThreadsCompletion(); + gpr_log(GPR_INFO, "RunClientBody: Returning"); return Status::OK; } @@ -232,10 +238,10 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service { ServerReaderWriter* stream) { ServerArgs args; if (!stream->Read(&args)) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Couldn't read server args"); } if (!args.has_setup()) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Bad server creation args"); } if (server_port_ != 0) { args.mutable_setup()->set_port(server_port_); @@ -243,24 +249,26 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service { gpr_log(GPR_INFO, "RunServerBody: about to create server"); auto server = CreateServer(args.setup()); if (!server) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Couldn't create server"); } gpr_log(GPR_INFO, "RunServerBody: server created"); ServerStatus status; status.set_port(server->port()); status.set_cores(server->cores()); if (!stream->Write(status)) { - return Status(StatusCode::UNKNOWN, ""); + return Status(StatusCode::UNKNOWN, "Server couldn't report init status"); } gpr_log(GPR_INFO, "RunServerBody: creation status reported"); while (stream->Read(&args)) { gpr_log(GPR_INFO, "RunServerBody: Message read"); if (!args.has_mark()) { gpr_log(GPR_INFO, "RunServerBody: Message not a mark!"); - return Status(StatusCode::INVALID_ARGUMENT, ""); + return Status(StatusCode::INVALID_ARGUMENT, "Invalid mark"); } *status.mutable_stats() = server->Mark(args.mark().reset()); - stream->Write(status); + if (!stream->Write(status)) { + return Status(StatusCode::UNKNOWN, "Server couldn't respond to mark"); + } gpr_log(GPR_INFO, "RunServerBody: Mark response given"); } diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 73ca19148b56c..dea87463312b5 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -123,22 +123,24 @@ class AsyncQpsServerTest : public Server { for (int i = 0; i < num_threads; i++) { shutdown_state_.emplace_back(new PerThreadShutdownState()); - } - for (int i = 0; i < num_threads; i++) { threads_.emplace_back(&AsyncQpsServerTest::ThreadFunc, this, i); } } ~AsyncQpsServerTest() { for (auto ss = shutdown_state_.begin(); ss != shutdown_state_.end(); ++ss) { - (*ss)->set_shutdown(); + std::lock_guard lock((*ss)->mutex); + (*ss)->shutdown = true; + } + // TODO (vpai): Remove this deadline and allow Shutdown to finish properly + auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(3); + server_->Shutdown(deadline); + for (auto cq = srv_cqs_.begin(); cq != srv_cqs_.end(); ++cq) { + (*cq)->Shutdown(); } - server_->Shutdown(std::chrono::system_clock::now() + - std::chrono::seconds(3)); for (auto thr = threads_.begin(); thr != threads_.end(); thr++) { thr->join(); } for (auto cq = srv_cqs_.begin(); cq != srv_cqs_.end(); ++cq) { - (*cq)->Shutdown(); bool ok; void *got_tag; while ((*cq)->Next(&got_tag, &ok)) @@ -151,22 +153,24 @@ class AsyncQpsServerTest : public Server { } private: - void ThreadFunc(int rank) { + void ThreadFunc(int thread_idx) { // Wait until work is available or we are shutting down bool ok; void *got_tag; - while (srv_cqs_[rank]->Next(&got_tag, &ok)) { + while (srv_cqs_[thread_idx]->Next(&got_tag, &ok)) { ServerRpcContext *ctx = detag(got_tag); // The tag is a pointer to an RPC context to invoke - const bool still_going = ctx->RunNextState(ok); - if (!shutdown_state_[rank]->shutdown()) { - // this RPC context is done, so refresh it - if (!still_going) { - ctx->Reset(); - } - } else { + // Proceed while holding a lock to make sure that + // this thread isn't supposed to shut down + std::lock_guard l(shutdown_state_[thread_idx]->mutex); + if (shutdown_state_[thread_idx]->shutdown) { return; } + const bool still_going = ctx->RunNextState(ok); + // if this RPC context is done, refresh it + if (!still_going) { + ctx->Reset(); + } } return; } @@ -334,24 +338,12 @@ class AsyncQpsServerTest : public Server { ServiceType async_service_; std::forward_list contexts_; - class PerThreadShutdownState { - public: - PerThreadShutdownState() : shutdown_(false) {} - - bool shutdown() const { - std::lock_guard lock(mutex_); - return shutdown_; - } - - void set_shutdown() { - std::lock_guard lock(mutex_); - shutdown_ = true; - } - - private: - mutable std::mutex mutex_; - bool shutdown_; + struct PerThreadShutdownState { + mutable std::mutex mutex; + bool shutdown; + PerThreadShutdownState() : shutdown(false) {} }; + std::vector> shutdown_state_; }; From 91633cb2f231570bbdc2f4e65d02e5b93f0133aa Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 19 Jul 2016 10:36:01 -0700 Subject: [PATCH 099/151] Fix undefined reference in Ruby code, add linker warning --- src/ruby/ext/grpc/extconf.rb | 1 + src/ruby/ext/grpc/rb_channel.c | 25 +++++++++++++++++++------ src/ruby/ext/grpc/rb_completion_queue.h | 3 --- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 6d65db8306707..d74d5e37e019d 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -92,6 +92,7 @@ end $LDFLAGS << ' -Wl,-wrap,memcpy' if RUBY_PLATFORM =~ /linux/ +$LDFLAGS << ' -Wl,--no-undefined' $LDFLAGS << ' -static' if windows $CFLAGS << ' -std=c99 ' diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 18a15d0125226..e6d30a174b888 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "rb_grpc.h" #include "rb_call.h" #include "rb_channel_args.h" @@ -71,6 +72,7 @@ typedef struct grpc_rb_channel { /* The actual channel */ grpc_channel *wrapped; + grpc_completion_queue *queue; } grpc_rb_channel; /* Destroys Channel instances. */ @@ -83,6 +85,7 @@ static void grpc_rb_channel_free(void *p) { if (ch->wrapped != NULL) { grpc_channel_destroy(ch->wrapped); + grpc_rb_completion_queue_destroy(ch->queue); } xfree(p); @@ -165,6 +168,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) { } rb_ivar_set(self, id_target, target); wrapper->wrapped = ch; + wrapper->queue = grpc_completion_queue_create(NULL); return self; } @@ -203,16 +207,18 @@ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE *argv, the completion queue with success=0 */ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self, VALUE last_state, - VALUE cqueue, - VALUE deadline, - VALUE tag) { + VALUE deadline) { grpc_rb_channel *wrapper = NULL; grpc_channel *ch = NULL; grpc_completion_queue *cq = NULL; - cq = grpc_rb_get_wrapped_completion_queue(cqueue); + void *tag = wrapper; + + grpc_event event; + TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper); ch = wrapper->wrapped; + cq = wrapper->queue; if (ch == NULL) { rb_raise(rb_eRuntimeError, "closed!"); return Qnil; @@ -222,9 +228,16 @@ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self, (grpc_connectivity_state)NUM2LONG(last_state), grpc_rb_time_timeval(deadline, /* absolute time */ 0), cq, - ROBJECT(tag)); + tag); - return Qnil; + event = rb_completion_queue_pluck(cq, tag, + gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + + if (event.success) { + return Qtrue; + } else { + return Qfalse; + } } /* Create a call given a grpc_channel, in order to call method. The request diff --git a/src/ruby/ext/grpc/rb_completion_queue.h b/src/ruby/ext/grpc/rb_completion_queue.h index 9f8f6aa5fff67..aa9dc6416af12 100644 --- a/src/ruby/ext/grpc/rb_completion_queue.h +++ b/src/ruby/ext/grpc/rb_completion_queue.h @@ -38,9 +38,6 @@ #include -/* Gets the wrapped completion queue from the ruby wrapper */ -grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v); - void grpc_rb_completion_queue_destroy(grpc_completion_queue *cq); /** From c23d33b29ba6971713da5128687cba4984e0468a Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 19 Jul 2016 11:19:12 -0700 Subject: [PATCH 100/151] Revert "Generate html report for perf tests" --- tools/run_tests/perf_html_report.template | 21 ------------- tools/run_tests/report_utils.py | 37 ----------------------- tools/run_tests/run_performance_tests.py | 11 +------ 3 files changed, 1 insertion(+), 68 deletions(-) delete mode 100644 tools/run_tests/perf_html_report.template diff --git a/tools/run_tests/perf_html_report.template b/tools/run_tests/perf_html_report.template deleted file mode 100644 index c219fa888a838..0000000000000 --- a/tools/run_tests/perf_html_report.template +++ /dev/null @@ -1,21 +0,0 @@ - - -Performance Test Result - -

Performance Test Result

- - <% sorted_test_cases = sorted(resultset.keys()) %> - % for test_case in sorted_test_cases: - - <% result = resultset[test_case] %> - - - % endfor -
${test_case} - % for k, v in result.iteritems(): - ${k}: ${v}
- % endfor -
- - - diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/report_utils.py index 7188d3dcd7058..5648a694cd0db 100644 --- a/tools/run_tests/report_utils.py +++ b/tools/run_tests/report_utils.py @@ -37,8 +37,6 @@ from mako import exceptions except (ImportError): pass # Mako not installed but it is ok. -import glob -import json import os import string import xml.etree.cElementTree as ET @@ -122,38 +120,3 @@ def render_interop_html_report( print(exceptions.text_error_template().render()) raise - -def render_perf_html_report(report_dir): - """Generate a simple HTML report for the perf tests.""" - template_file = 'tools/run_tests/perf_html_report.template' - try: - mytemplate = Template(filename=template_file, format_exceptions=True) - except NameError: - print('Mako template is not installed. Skipping HTML report generation.') - return - except IOError as e: - print('Failed to find the template %s: %s' % (template_file, e)) - return - - resultset = {} - for result_file in glob.glob(os.path.join(report_dir, '*.json')): - with open(result_file, 'r') as f: - scenario_result = json.loads(f.read()) - test_case = scenario_result['scenario']['name'] - if 'ping_pong' in test_case: - latency50 = round(scenario_result['summary']['latency50'], 2) - latency99 = round(scenario_result['summary']['latency99'], 2) - summary = {'latency50': latency50, 'latency99': latency99} - else: - summary = {'qps': round(scenario_result['summary']['qps'], 2)} - resultset[test_case] = summary - - args = {'resultset': resultset} - - html_file_path = os.path.join(report_dir, 'index.html') - try: - with open(html_file_path, 'w') as output_file: - mytemplate.render_context(Context(output_file, **args)) - except: - print(exceptions.text_error_template().render()) - raise diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index 5ff96968089f2..5fdf7a407d901 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -40,7 +40,6 @@ import os import pipes import re -import report_utils import subprocess import sys import tempfile @@ -55,7 +54,6 @@ _REMOTE_HOST_USERNAME = 'jenkins' -_REPORT_DIR = 'perf_reports' class QpsWorkerJob: @@ -105,11 +103,7 @@ def create_scenario_jobspec(scenario_json, workers, remote_host=None, cmd += 'BQ_RESULT_TABLE="%s" ' % bq_result_table cmd += 'tools/run_tests/performance/run_qps_driver.sh ' cmd += '--scenarios_json=%s ' % pipes.quote(json.dumps({'scenarios': [scenario_json]})) - if not os.path.isdir(_REPORT_DIR): - os.makedirs(_REPORT_DIR) - report_path = os.path.join(_REPORT_DIR, - '%s-scenario_result.json' % scenario_json['name']) - cmd += '--scenario_result_file=%s' % report_path + cmd += '--scenario_result_file=scenario_result.json' if remote_host: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host) cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd)) @@ -442,9 +436,6 @@ def finish_qps_workers(jobs): jobset.message('START', 'Running scenarios.', do_newline=True) num_failures, _ = jobset.run( scenarios, newline_on_success=True, maxjobs=1) - - report_utils.render_perf_html_report(_REPORT_DIR) - if num_failures == 0: jobset.message('SUCCESS', 'All scenarios finished successfully.', From bff5cbf6b588feb7fd218d4cee5657c8effe885d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 19 Jul 2016 11:22:20 -0700 Subject: [PATCH 101/151] Collapse fixture into CoreCronetEnd2EndTests.m so that individual test cases can be run, instead of only allow running the entire fixture --- .../CoreCronetEnd2EndTests.m | 349 +++++++++++++++++- .../tests/CoreCronetEnd2EndTests/fixture.h | 35 -- .../fixture_h2_ssl_cronet.m | 206 ----------- .../tests/Tests.xcodeproj/project.pbxproj | 6 - 4 files changed, 336 insertions(+), 260 deletions(-) delete mode 100644 src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h delete mode 100644 src/objective-c/tests/CoreCronetEnd2EndTests/fixture_h2_ssl_cronet.m diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index b0e58fe2ed781..ec1d222fbd0b8 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -32,7 +32,140 @@ */ #import -#import "src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h" +#include "test/core/end2end/end2end_tests.h" + +#include +#include + +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +#include +#import + +typedef struct fullstack_secure_fixture_data { + char *localaddr; +} fullstack_secure_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( + grpc_channel_args *client_args, grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + int port = grpc_pick_unused_port_or_die(); + fullstack_secure_fixture_data *ffd = + gpr_malloc(sizeof(fullstack_secure_fixture_data)); + memset(&f, 0, sizeof(f)); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); + + f.fixture_data = ffd; + f.cq = grpc_completion_queue_create(NULL); + + return f; +} + +static void process_auth_failure(void *state, grpc_auth_context *ctx, + const grpc_metadata *md, size_t md_count, + grpc_process_auth_metadata_done_cb cb, + void *user_data) { + GPR_ASSERT(state == NULL); + cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); +} + +static void cronet_init_client_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *client_args, + cronet_engine *cronetEngine) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + f->client = + grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); + GPR_ASSERT(f->client != NULL); +} + +static void chttp2_init_server_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args, + grpc_server_credentials *server_creds) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args, NULL); + grpc_server_register_completion_queue(f->server, f->cq, NULL); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + server_creds)); + grpc_server_credentials_release(server_creds); + grpc_server_start(f->server); +} + +static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + gpr_free(ffd->localaddr); + gpr_free(ffd); +} + +static void cronet_init_client_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { + grpc_arg ssl_name_override = {GRPC_ARG_STRING, + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + {"foo.test.google.fr"}}; + + grpc_channel_args *new_client_args = + grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + cronet_engine *cronetEngine = [Cronet getGlobalEngine]; + + cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); + grpc_channel_args_destroy(new_client_args); +} + +static int fail_server_auth_check(grpc_channel_args *server_args) { + size_t i; + if (server_args == NULL) return 0; + for (i = 0; i < server_args->num_args; i++) { + if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == + 0) { + return 1; + } + } + return 0; +} + +static void chttp2_init_server_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { + grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, + test_server1_cert}; + grpc_server_credentials *ssl_creds = + grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); + if (fail_server_auth_check(server_args)) { + grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; + grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); + } + chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); +} + +/* All test configurations */ + +static grpc_end2end_test_config configs[] = { + {"chttp2/simple_ssl_fullstack", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + chttp2_create_fixture_secure_fullstack, + cronet_init_client_simple_ssl_secure_fullstack, + chttp2_init_server_simple_ssl_secure_fullstack, + chttp2_tear_down_secure_fullstack}, +}; + + + @interface CoreCronetEnd2EndTests : XCTestCase @@ -40,18 +173,208 @@ @interface CoreCronetEnd2EndTests : XCTestCase @implementation CoreCronetEnd2EndTests -- (void)testCoreCronetEnd2End { - char *argv[] = {"h2_ssl"}; - - // This main() function is not the entry point of this test case; it - // refers to that in h2_ssl_cronet.m. We can use it because XCode - // builder does not use main() as the entry point for a test. - // Since h2_ssl_cronet.m is derived from h2_ssl.c in the core end2end - // test fixture, we preserves the fixture structure (in particular - // the main() function here) so that another fixture can easily - // replace the fixture h2_ssl_cronet, in case we need more tests in - // the future - main(1, argv); +char *roots_filename; + +// The setUp() function is run before the test cases run and only run once ++ (void)setUp { + [super setUp]; + + FILE *roots_file; + size_t roots_size = strlen(test_root_cert); + + char *argv[] = {"CoreCronetEnd2EndTests"}; + grpc_test_init(1, argv); + grpc_end2end_tests_pre_init(); + + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); + GPR_ASSERT(roots_filename != NULL); + GPR_ASSERT(roots_file != NULL); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + + grpc_init(); + +} + +// The tearDown() function is run after all test cases finish running ++ (void)tearDown { + grpc_shutdown(); + + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + + [super tearDown]; +} + +- (void)testIndividualCase:(char*)test_case { + char *argv[] = {"h2_ssl", test_case}; + + for (int i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(sizeof(argv) / sizeof(argv[0]), argv, configs[i]); + } +} + +- (void)testBadHostname { + [self testIndividualCase:"bad_hostname"]; +} + +- (void)testBinaryMetadata { + [self testIndividualCase:"binary_metadata"]; +} + +- (void)testCallCreds { + [self testIndividualCase:"call_creds"]; +} + +- (void)testCancelAfterAccept { + [self testIndividualCase:"cancel_after_accept"]; +} + +- (void)testCancelAfterClientDone { + [self testIndividualCase:"cancel_after_client_done"]; +} + +- (void)testCancelAfterInvoke { + [self testIndividualCase:"cancel_after_invoke"]; +} + +- (void)testCancelBeforeInvoke { + [self testIndividualCase:"cancel_before_invoke"]; +} + +- (void)testCancelInAVacuum { + [self testIndividualCase:"cancel_in_a_vacuum"]; +} + +- (void)testCancelWithStatus { + [self testIndividualCase:"cancel_with_status"]; +} + +- (void)testCompressedPayload { + [self testIndividualCase:"compressed_payload"]; +} + +- (void)testConnectivity { + [self testIndividualCase:"connectivity"]; +} + +- (void)testDefaultHost { + [self testIndividualCase:"default_host"]; +} + +- (void)testDisappearingServer { + [self testIndividualCase:"disappearing_server"]; +} + +- (void)testEmptyBatch { + [self testIndividualCase:"empty_batch"]; +} + +- (void)testFilterCausesClose { + [self testIndividualCase:"filter_causes_close"]; +} + +- (void)testGracefulServerShutdown { + [self testIndividualCase:"graceful_server_shutdown"]; +} + +- (void)testHighInitialSeqno { + [self testIndividualCase:"high_initial_seqno"]; +} + +- (void)testHpackSize { + [self testIndividualCase:"hpack_size"]; +} + +- (void)testIdempotentRequest { + [self testIndividualCase:"idempotent_request"]; +} + +- (void)testInvokeLargeRequest { + [self testIndividualCase:"invoke_large_request"]; +} + +- (void)testLargeMetadata { + [self testIndividualCase:"large_metadata"]; +} + +- (void)testMaxConcurrentStreams { + [self testIndividualCase:"max_concurrent_streams"]; +} + +- (void)testMaxMessageLength { + [self testIndividualCase:"max_message_length"]; +} + +- (void)testNegativeDeadline { + [self testIndividualCase:"negative_deadline"]; +} + +- (void)testNetworkStatusChange { + [self testIndividualCase:"network_status_change"]; +} + +- (void)testNoOp { + [self testIndividualCase:"no_op"]; +} + +- (void)testPayload { + [self testIndividualCase:"payload"]; +} + +- (void)testPing { + [self testIndividualCase:"ping"]; +} + +- (void)testPingPongStreaming { + [self testIndividualCase:"ping_pong_streaming"]; +} + +- (void)testRegisteredCall { + [self testIndividualCase:"registered_call"]; +} + +- (void)testRequestWithFlags { + [self testIndividualCase:"request_with_flags"]; +} + +- (void)testRequestWithPayload { + [self testIndividualCase:"request_with_payload"]; +} + +- (void)testServerFinishesRequest { + [self testIndividualCase:"server_finishes_request"]; +} + +- (void)testShutdownFinishesCalls { + [self testIndividualCase:"shutdown_finishes_calls"]; +} + +- (void)testShutdownFinishesTags { + [self testIndividualCase:"shutdown_finishes_tags"]; +} + +- (void)testSimpleDelayedRequest { + [self testIndividualCase:"simple_delayed_request"]; +} + +- (void)testSimpleMetadata { + [self testIndividualCase:"simple_metadata"]; +} + +- (void)testSimpleRequest { + [self testIndividualCase:"simple_request"]; +} + +- (void)testStreamingErrorResponse { + [self testIndividualCase:"streaming_error_response"]; +} + +- (void)testTrailingMetadata { + [self testIndividualCase:"trailing_metadata"]; } @end diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h b/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h deleted file mode 100644 index 45fbfc4bc823d..0000000000000 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/fixture.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * 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. - * - */ - -int main(int argc, char **argv); - diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/fixture_h2_ssl_cronet.m b/src/objective-c/tests/CoreCronetEnd2EndTests/fixture_h2_ssl_cronet.m deleted file mode 100644 index 37d98b793c83b..0000000000000 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/fixture_h2_ssl_cronet.m +++ /dev/null @@ -1,206 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * This fixture derives from h2_ssl.c fixture in core end2end test - * (test/core/end2end/fixture/h2_ssl.c) - * - * This fixture creates a server full stack using chttp2 and a client - * full stack using Cronet. End-to-end tests are run against this fixture - * setting. - * - */ - -#include "test/core/end2end/end2end_tests.h" - -#include -#include - -#include -#include -#include - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" -#include "test/core/end2end/data/ssl_test_data.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -#include -#import - -typedef struct fullstack_secure_fixture_data { - char *localaddr; -} fullstack_secure_fixture_data; - -static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( - grpc_channel_args *client_args, grpc_channel_args *server_args) { - grpc_end2end_test_fixture f; - int port = grpc_pick_unused_port_or_die(); - fullstack_secure_fixture_data *ffd = - gpr_malloc(sizeof(fullstack_secure_fixture_data)); - memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - - f.fixture_data = ffd; - f.cq = grpc_completion_queue_create(NULL); - - return f; -} - -static void process_auth_failure(void *state, grpc_auth_context *ctx, - const grpc_metadata *md, size_t md_count, - grpc_process_auth_metadata_done_cb cb, - void *user_data) { - GPR_ASSERT(state == NULL); - cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); -} - -static void cronet_init_client_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *client_args, - cronet_engine *cronetEngine) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - f->client = - grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); - GPR_ASSERT(f->client != NULL); -} - -static void chttp2_init_server_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *server_args, - grpc_server_credentials *server_creds) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - if (f->server) { - grpc_server_destroy(f->server); - } - f->server = grpc_server_create(server_args, NULL); - grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, - server_creds)); - grpc_server_credentials_release(server_creds); - grpc_server_start(f->server); -} - -static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - gpr_free(ffd->localaddr); - gpr_free(ffd); -} - -static void cronet_init_client_simple_ssl_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { - grpc_arg ssl_name_override = {GRPC_ARG_STRING, - GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, - {"foo.test.google.fr"}}; - - grpc_channel_args *new_client_args = - grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); - [Cronet setHttp2Enabled:YES]; - [Cronet start]; - cronet_engine *cronetEngine = [Cronet getGlobalEngine]; - - cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); - grpc_channel_args_destroy(new_client_args); -} - -static int fail_server_auth_check(grpc_channel_args *server_args) { - size_t i; - if (server_args == NULL) return 0; - for (i = 0; i < server_args->num_args; i++) { - if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == - 0) { - return 1; - } - } - return 0; -} - -static void chttp2_init_server_simple_ssl_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { - grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, - test_server1_cert}; - grpc_server_credentials *ssl_creds = - grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); - if (fail_server_auth_check(server_args)) { - grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; - grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); - } - chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); -} - -/* All test configurations */ - -static grpc_end2end_test_config configs[] = { - {"chttp2/simple_ssl_fullstack", - FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, - chttp2_create_fixture_secure_fullstack, - cronet_init_client_simple_ssl_secure_fullstack, - chttp2_init_server_simple_ssl_secure_fullstack, - chttp2_tear_down_secure_fullstack}, -}; - -int main(int argc, char **argv) { - size_t i; - FILE *roots_file; - size_t roots_size = strlen(test_root_cert); - char *roots_filename; - - grpc_test_init(argc, argv); - grpc_end2end_tests_pre_init(); - - /* Set the SSL roots env var. */ - roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); - GPR_ASSERT(roots_filename != NULL); - GPR_ASSERT(roots_file != NULL); - GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); - fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); - - grpc_init(); - - for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(argc, argv, configs[i]); - } - - grpc_shutdown(); - - /* Cleanup. */ - remove(roots_filename); - gpr_free(roots_filename); - - return 0; -} diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 8de0fdcb8e5d1..2c80b08d030a9 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; }; - 5E1BD3B51D3D74EC00A47325 /* fixture_h2_ssl_cronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E1BD3B41D3D74EC00A47325 /* fixture_h2_ssl_cronet.m */; }; 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */; }; 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */; }; @@ -110,8 +109,6 @@ 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; - 5E1BD3B31D3D736C00A47325 /* fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fixture.h; sourceTree = ""; }; - 5E1BD3B41D3D74EC00A47325 /* fixture_h2_ssl_cronet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = fixture_h2_ssl_cronet.m; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; @@ -252,8 +249,6 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( - 5E1BD3B41D3D74EC00A47325 /* fixture_h2_ssl_cronet.m */, - 5E1BD3B31D3D736C00A47325 /* fixture.h */, 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */, ); path = CoreCronetEnd2EndTests; @@ -868,7 +863,6 @@ buildActionMask = 2147483647; files = ( 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */, - 5E1BD3B51D3D74EC00A47325 /* fixture_h2_ssl_cronet.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From dd5b9a8086ef9a43c909d20bf61832f300bd7039 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Tue, 19 Jul 2016 11:49:10 -0700 Subject: [PATCH 102/151] Fix sanity check --- build.yaml | 3 ++- tools/run_tests/sanity/check_sources_and_headers.py | 3 ++- tools/run_tests/sources_and_headers.json | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/build.yaml b/build.yaml index 4c9dbd046d3bd..fa4dd5a691f81 100644 --- a/build.yaml +++ b/build.yaml @@ -776,6 +776,8 @@ filegroups: src: - src/cpp/ext/reflection.grpc.pb.cc - src/cpp/ext/reflection.pb.cc + uses: + - grpc++_codegen_proto libs: - name: gpr build: all @@ -977,7 +979,6 @@ libs: - grpc++ filegroups: - grpc++_reflection_proto - - grpc++_codegen_proto - name: grpc++_reflection_codegen build: private language: c++ diff --git a/tools/run_tests/sanity/check_sources_and_headers.py b/tools/run_tests/sanity/check_sources_and_headers.py index c028499ca635c..28c1dc46d7fb8 100755 --- a/tools/run_tests/sanity/check_sources_and_headers.py +++ b/tools/run_tests/sanity/check_sources_and_headers.py @@ -55,7 +55,8 @@ def target_has_header(target, name): for dep in target['deps']: if target_has_header(get_target(dep), name): return True - if name == 'src/core/lib/profiling/stap_probes.h': + if name in ['src/core/lib/profiling/stap_probes.h', + 'src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h']: return True return False diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 451f535a2aab6..87e5001c091a5 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4360,7 +4360,6 @@ { "deps": [ "grpc++", - "grpc++_codegen_proto", "grpc++_reflection_proto" ], "headers": [ @@ -6760,7 +6759,9 @@ "type": "filegroup" }, { - "deps": [], + "deps": [ + "grpc++_codegen_proto" + ], "headers": [ "include/grpc++/ext/reflection.grpc.pb.h", "include/grpc++/ext/reflection.pb.h" From 77b74258b56dcc19c3a6d6be32eca579eac95aae Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Tue, 19 Jul 2016 11:53:37 -0700 Subject: [PATCH 103/151] Revert unnecessary deletions --- test/cpp/end2end/async_end2end_test.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 084d6db5006a7..ac79fe827400d 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -344,6 +344,31 @@ TEST_P(AsyncEnd2endTest, SequentialRpcs) { SendRpc(10); } +// We do not need to protect notify because the use is synchronized. +void ServerWait(Server* server, int* notify) { + server->Wait(); + *notify = 1; +} +TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) { + int notify = 0; + std::thread* wait_thread = + new std::thread(&ServerWait, server_.get(), ¬ify); + ResetStub(); + SendRpc(1); + EXPECT_EQ(0, notify); + server_->Shutdown(); + wait_thread->join(); + EXPECT_EQ(1, notify); + delete wait_thread; +} + +TEST_P(AsyncEnd2endTest, ShutdownThenWait) { + ResetStub(); + SendRpc(1); + server_->Shutdown(); + server_->Wait(); +} + // Test a simple RPC using the async version of Next TEST_P(AsyncEnd2endTest, AsyncNextRpc) { ResetStub(); From 268a47a2b1402d92d924889b52d9b4266f53483c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 19 Jul 2016 12:57:18 -0700 Subject: [PATCH 104/151] Add latency profiling from 'important' marks Allows seeing directly how long was spent: - running up to putting bytes on the wire - between sending and receiving - between receiving and finishing --- .../latency_profile/profile_analyzer.py | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tools/profiling/latency_profile/profile_analyzer.py b/tools/profiling/latency_profile/profile_analyzer.py index dad0712d4028b..48b8e9b950f1e 100755 --- a/tools/profiling/latency_profile/profile_analyzer.py +++ b/tools/profiling/latency_profile/profile_analyzer.py @@ -43,6 +43,7 @@ TIME_TO_SCOPE_END = object() TIME_FROM_STACK_START = object() TIME_TO_STACK_END = object() +TIME_FROM_LAST_IMPORTANT = object() argp = argparse.ArgumentParser(description='Process output of basic_prof builds') @@ -78,10 +79,14 @@ def mark(self, line): self.call_stack_builder.lines.append(line_item) def finish(self, line): - assert line['tag'] == self.top_line.tag, 'expected %s, got %s; thread=%s; t0=%f t1=%f' % (self.top_line.tag, line['tag'], line['thd'], self.top_line.start_time, line['t']) + assert line['tag'] == self.top_line.tag, ( + 'expected %s, got %s; thread=%s; t0=%f t1=%f' % + (self.top_line.tag, line['tag'], line['thd'], self.top_line.start_time, + line['t'])) final_time_stamp = line['t'] assert self.top_line.end_time is None self.top_line.end_time = final_time_stamp + self.top_line.important = self.top_line.important or line['imp'] assert SELF_TIME not in self.top_line.times self.top_line.times[SELF_TIME] = final_time_stamp - self.top_line.start_time for line in self.call_stack_builder.lines[self.first_child_pos:]: @@ -101,9 +106,14 @@ def finish(self): start_time = self.lines[0].start_time end_time = self.lines[0].end_time self.signature = self.signature.hexdigest() + last_important = start_time for line in self.lines: line.times[TIME_FROM_STACK_START] = line.start_time - start_time line.times[TIME_TO_STACK_END] = end_time - line.end_time + line.times[TIME_FROM_LAST_IMPORTANT] = line.start_time - last_important + if line.important: + last_important = line.end_time + last_important = end_time def add(self, line): line_type = line['type'] @@ -113,7 +123,9 @@ def add(self, line): self.stk.append(ScopeBuilder(self, line)) return False elif line_type == '}': - assert self.stk, 'expected non-empty stack for closing %s; thread=%s; t=%f' % (line['tag'], line['thd'], line['t']) + assert self.stk, ( + 'expected non-empty stack for closing %s; thread=%s; t=%f' % + (line['tag'], line['thd'], line['t'])) self.stk.pop().finish(line) if not self.stk: self.finish() @@ -216,9 +228,16 @@ def ent(line, idx=idx): return '' return ent +BANNER = { + 'simple': 'Count: %(count)d', + 'html': '

Count: %(count)d

' +} + FORMAT = [ ('TAG', lambda line: '..'*line.indent + tidy_tag(line.tag)), ('LOC', lambda line: '%s:%d' % (line.filename[line.filename.rfind('/')+1:], line.fileline)), + ('IMP', lambda line: '*' if line.important else ''), + ('FROM_IMP', time_format(TIME_FROM_LAST_IMPORTANT)), ('FROM_STACK_START', time_format(TIME_FROM_STACK_START)), ('SELF', time_format(SELF_TIME)), ('TO_STACK_END', time_format(TIME_TO_STACK_END)), @@ -227,11 +246,6 @@ def ent(line, idx=idx): ('TO_SCOPE_END', time_format(TIME_TO_SCOPE_END)), ] -BANNER = { - 'simple': 'Count: %(count)d', - 'html': '

Count: %(count)d

' -} - if args.fmt == 'html': print '' print '' From 34c9a73ab907dd3e7dadaa82af465399290eebfc Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Thu, 14 Jul 2016 17:22:01 -0700 Subject: [PATCH 105/151] Document the custom grpcio-tools command class --- tools/distrib/python/grpcio_tools/README.rst | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst index 4e5263ded5ad7..55521d17bb172 100644 --- a/tools/distrib/python/grpcio_tools/README.rst +++ b/tools/distrib/python/grpcio_tools/README.rst @@ -137,3 +137,42 @@ Given protobuf include directories :code:`$INCLUDE`, an output directory :: $ python -m grpc.tools.protoc -I$INCLUDE --python_out=$OUTPUT --grpc_python_out=$OUTPUT $PROTO_FILES + +To use as a build step in distutils-based projects, you may use the provided +command class in your :code:`setup.py`: + +:: + + setuptools.setup( + # ... + cmdclass={ + 'build_proto_modules': grpc.tools.command.BuildPackageProtos, + } + # ... + ) + +Invocation of the command will walk the project tree and transpile every +:code:`.proto` file into a :code:`_pb2.py` file in the same directory. + +Note that this particular approach requires :code:`grpcio-tools` to be +installed on the machine before the setup script is invoked (i.e. no +combination of :code:`setup_requires` or :code:`install_requires` will provide +access to :code:`grpc.tools.command.BuildPackageProtos` if it isn't already +installed). One way to work around this can be found in our +:code:`grpcio-health-checking` +`package `_: + +:: + + class BuildPackageProtos(setuptools.Command): + """Command to generate project *_pb2.py modules from proto files.""" + # ... + def run(self): + from grpc.tools import command + command.build_package_protos(self.distribution.package_dir['']) + +Now including :code:`grpcio-tools` in :code:`setup_requires` will provide the +command on-setup as desired. + +For more information on command classes, consult :code:`distutils` and +:code:`setuptools` documentation. From b6b0932c28ff636d2e4405ef54d5a62349c2cd18 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 19 Jul 2016 14:33:23 -0700 Subject: [PATCH 106/151] Add fixture description and TODO for test name inferral from test case method name --- .../CoreCronetEnd2EndTests.m | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index ec1d222fbd0b8..122200a294bd7 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -31,6 +31,18 @@ * */ +/* + * This test file is derived from fixture h2_ssl.c in core end2end test + * (test/core/end2end/fixture/h2_ssl.c). The structure of the fixture is + * preserved as much as possible + * + * This fixture creates a server full stack using chttp2 and a client + * full stack using Cronet. End-to-end tests are run against this + * configuration + * + */ + + #import #include "test/core/end2end/end2end_tests.h" @@ -166,6 +178,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( +char *roots_filename; @interface CoreCronetEnd2EndTests : XCTestCase @@ -173,7 +186,6 @@ @interface CoreCronetEnd2EndTests : XCTestCase @implementation CoreCronetEnd2EndTests -char *roots_filename; // The setUp() function is run before the test cases run and only run once + (void)setUp { @@ -217,6 +229,8 @@ - (void)testIndividualCase:(char*)test_case { } } +// TODO(mxyan): Use NSStringFromSelector(_cmd) to acquire test name from the +// test case method name, so that bodies of test cases can stay identical - (void)testBadHostname { [self testIndividualCase:"bad_hostname"]; } From e6c04aa6126d3de7e27c86b2086b00d5353011ed Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 19 Jul 2016 14:46:50 -0700 Subject: [PATCH 107/151] Add a macro to support protobuf lite --- include/grpc++/impl/codegen/config_protobuf.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h index 4bee1bc422796..e1198f0ea030e 100644 --- a/include/grpc++/impl/codegen/config_protobuf.h +++ b/include/grpc++/impl/codegen/config_protobuf.h @@ -40,9 +40,14 @@ #endif #ifndef GRPC_CUSTOM_MESSAGE +#ifdef GRPC_USE_PROTO_LITE +#include +#define GRPC_CUSTOM_MESSAGE ::google::protobuf::MessageLite +#else #include #define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message #endif +#endif #ifndef GRPC_CUSTOM_DESCRIPTOR #include From fb709049b448ea49f3afb61daf744329f0a86150 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 18 Jul 2016 18:56:56 -0700 Subject: [PATCH 108/151] grpc_args doxygen --- include/grpc/impl/codegen/compression_types.h | 17 ++++++++- include/grpc/impl/codegen/grpc_types.h | 38 +++++++++++-------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h index 9065d1edd0279..3034182d4c574 100644 --- a/include/grpc/impl/codegen/compression_types.h +++ b/include/grpc/impl/codegen/compression_types.h @@ -46,12 +46,27 @@ extern "C" { #define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \ "grpc-internal-encoding-request" -/** To be used in channel arguments */ +/** To be used in channel arguments. + * + * \addtogroup grpc_arg_keys + * \{ */ +/** Default compression algorithm for the channel. + * Its value is an int from the \a grpc_compression_algorithm enum. */ #define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \ "grpc.default_compression_algorithm" +/** Default compression level for the channel. + * Its value is an int from the \a grpc_compression_level enum. */ #define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL "grpc.default_compression_level" +/** Compression algorithms supported by the channel. + * Its value is a bitset (an int). Bits correspond to algorithms in \a + * grpc_compression_algorithm. For example, its LSB corresponds to + * GRPC_COMPRESS_NONE, the next bit to GRPC_COMPRESS_DEFLATE, etc. + * Unset bits disable support for the algorithm. By default all algorithms are + * supported. It's not possible to disable GRPC_COMPRESS_NONE (the attempt will + * be ignored). */ #define GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \ "grpc.compression_enabled_algorithms_bitset" +/** \} */ /* The various compression algorithms supported by gRPC */ typedef enum { diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index c0ed13950662a..e5a82883be548 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -106,58 +106,66 @@ typedef struct { by grpc_arg; keys are strings to allow easy backwards-compatible extension by arbitrary parties. All evaluation is performed at channel creation time (i.e. the values in - this structure need only live through the creation invocation). */ + this structure need only live through the creation invocation). + + See the description of the \ref grpc_arg_keys "available args" for more + details. */ typedef struct { size_t num_args; grpc_arg *args; } grpc_channel_args; -/* Channel argument keys: */ -/** Enable census for tracing and stats collection */ +/** \defgroup grpc_arg_keys + * Channel argument keys. + * \{ + */ +/** If non-zero, enable census for tracing and stats collection. */ #define GRPC_ARG_ENABLE_CENSUS "grpc.census" -/** Enable load reporting */ +/** If non-zero, enable load reporting. */ #define GRPC_ARG_ENABLE_LOAD_REPORTING "grpc.loadreporting" /** Maximum number of concurrent incoming streams to allow on a http2 - connection */ + connection. Int valued. */ #define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams" -/** Maximum message length that the channel can receive */ +/** Maximum message length that the channel can receive. Int valued, bytes. */ #define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length" -/** Initial sequence number for http2 transports */ +/** Initial sequence number for http2 transports. Int valued. */ #define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \ "grpc.http2.initial_sequence_number" /** Amount to read ahead on individual streams. Defaults to 64kb, larger values can help throughput on high-latency connections. NOTE: at some point we'd like to auto-tune this, and this parameter - will become a no-op. */ + will become a no-op. Int valued, bytes. */ #define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes" -/** How much memory to use for hpack decoding */ +/** How much memory to use for hpack decoding. Int valued, bytes. */ #define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \ "grpc.http2.hpack_table_size.decoder" -/** How much memory to use for hpack encoding */ +/** How much memory to use for hpack encoding. Int valued, bytes. */ #define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \ "grpc.http2.hpack_table_size.encoder" -/** Default authority to pass if none specified on call construction */ +/** Default authority to pass if none specified on call construction. A string. + * */ #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority" /** Primary user agent: goes at the start of the user-agent metadata - sent on each request */ + sent on each request. A string. */ #define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent" /** Secondary user agent: goes at the end of the user-agent metadata - sent on each request */ + sent on each request. A string. */ #define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent" /** The maximum time between subsequent connection attempts, in ms */ #define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms" /* The caller of the secure_channel_create functions may override the target name used for SSL host name checking using this channel argument which is of - type GRPC_ARG_STRING. This *should* be used for testing only. + type \a GRPC_ARG_STRING. This *should* be used for testing only. If this argument is not specified, the name used for SSL host name checking will be the target parameter (assuming that the secure channel is an SSL channel). If this parameter is specified and the underlying is not an SSL channel, it will just be ignored. */ #define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override" -/* Maximum metadata size */ +/* Maximum metadata size, in bytes. */ #define GRPC_ARG_MAX_METADATA_SIZE "grpc.max_metadata_size" /** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */ #define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport" +/** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a particular operation, the grpc_call_error returned will be GRPC_CALL_OK. From 8a16ce265bcecb4935da4f5c6dc8bf1e463c743a Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 19 Jul 2016 14:49:28 -0700 Subject: [PATCH 109/151] Make new linker warning linux-only --- src/ruby/ext/grpc/extconf.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index d74d5e37e019d..46749644ee595 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -92,7 +92,7 @@ end $LDFLAGS << ' -Wl,-wrap,memcpy' if RUBY_PLATFORM =~ /linux/ -$LDFLAGS << ' -Wl,--no-undefined' +$LDFLAGS << ' -Wl,--no-undefined' if RUBY_PLATFORM =~ /linux/ $LDFLAGS << ' -static' if windows $CFLAGS << ' -std=c99 ' From 5a14bbec66c75e877f3744b859c723911ae8b129 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 19 Jul 2016 15:22:01 -0700 Subject: [PATCH 110/151] Let roots_filename be a static variable --- .../tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index 122200a294bd7..58abb492ceaef 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -178,7 +178,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( -char *roots_filename; +static char *roots_filename; @interface CoreCronetEnd2EndTests : XCTestCase From 90e5b2e58e940ae77e6f592384dbb13af225dfa9 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 19 Jul 2016 16:51:22 -0700 Subject: [PATCH 111/151] Remove undefined reference warning in Ruby build --- src/ruby/ext/grpc/extconf.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 46749644ee595..6d65db8306707 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -92,7 +92,6 @@ end $LDFLAGS << ' -Wl,-wrap,memcpy' if RUBY_PLATFORM =~ /linux/ -$LDFLAGS << ' -Wl,--no-undefined' if RUBY_PLATFORM =~ /linux/ $LDFLAGS << ' -static' if windows $CFLAGS << ' -std=c99 ' From 4c82af59d588930bb37b39e629bcc2450b138178 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 19 Jul 2016 17:40:39 -0700 Subject: [PATCH 112/151] Add test target file to repo --- .../xcschemes/CoreCronetEnd2EndTests.xcscheme | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme new file mode 100644 index 0000000000000..a1da2e0c97cb0 --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From cc7eb8ef88dcbd11acb3f24000e1628026b975c5 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 19 Jul 2016 19:03:55 -0700 Subject: [PATCH 113/151] Makefile modifications and instructions to enable cross-compilation --- Makefile | 196 +++++++++++++++++++++--------------- templates/Makefile.template | 52 ++++++++-- 2 files changed, 156 insertions(+), 92 deletions(-) diff --git a/Makefile b/Makefile index 4ce22678d7e89..e156bc25a20d1 100644 --- a/Makefile +++ b/Makefile @@ -405,6 +405,29 @@ LIBS = m pthread ws2_32 LDFLAGS += -pthread endif +# +# The steps for cross-compiling are as follows: +# First, clone and make install of grpc using the native compilers for the host. +# Also, install protoc (e.g., from a package like apt-get) +# Then clone a fresh grpc for the actual cross-compiled build +# Set the environment variable GRPC_CROSS_COMPILE to true +# Set CC, CXX, LD, LDXX, AR, and STRIP to the cross-compiling binaries +# Also set PROTOBUF_CONFIG_OPTS to indicate cross-compilation to protobuf (e.g., +# PROTOBUF_CONFIG_OPTS="--host=arm-linux --with-protoc=/usr/local/bin/protoc" ) +# Set HAS_PKG_CONFIG=false +# To build tests, go to third_party/gflags and follow its ccmake instructions +# Make sure that you enable building shared libraries and set your prefix to +# something useful like /usr/local/cross +# You will also need to set GRPC_CROSS_LDOPTS and GRPC_CROSS_AROPTS to hold +# additional required arguments for LD and AR (examples below) +# Then you can do a make from the cross-compiling fresh clone! +# +ifeq ($(GRPC_CROSS_COMPILE),true) +LDFLAGS += $(GRPC_CROSS_LDOPTS) # e.g. -L/usr/local/lib -L/usr/local/cross/lib +AROPTS = $(GRPC_CROSS_AROPTS) # e.g., rc --target=elf32-little +USE_BUILT_PROTOC = false +endif + GTEST_LIB = -Ithird_party/googletest/include -Ithird_party/googletest third_party/googletest/src/gtest-all.cc GTEST_LIB += -lgflags ifeq ($(V),1) @@ -709,6 +732,9 @@ PC_LIBS_GRPCXX = CPPFLAGS := -Ithird_party/googletest/include $(CPPFLAGS) +PROTOC_PLUGINS_ALL = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin +PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG) + ifeq ($(HAS_SYSTEM_PROTOBUF),true) ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true @@ -722,13 +748,20 @@ endif endif else PC_LIBS_GRPCXX = -lprotobuf +PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) endif else ifeq ($(HAS_EMBEDDED_PROTOBUF),true) PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a CPPFLAGS := -Ithird_party/protobuf/src $(CPPFLAGS) LDFLAGS := -L$(LIBDIR)/$(CONFIG)/protobuf $(LDFLAGS) +ifneq ($(USE_BUILT_PROTOC),false) PROTOC = $(BINDIR)/$(CONFIG)/protobuf/protoc +PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) +else +PROTOC_PLUGINS = +PROTOC_PLUGINS_DIR = $(prefix)/bin +endif else NO_PROTOBUF = true endif @@ -776,7 +809,6 @@ endif .SECONDARY = %.pb.h %.pb.cc -PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_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: @@ -1147,7 +1179,7 @@ third_party/protobuf/configure: $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure $(E) "[MAKE] Building protobuf" - $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static) + $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static $(PROTOBUF_CONFIG_OPTS)) $(Q)$(MAKE) -C third_party/protobuf clean $(Q)$(MAKE) -C third_party/protobuf $(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf @@ -1886,7 +1918,7 @@ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: src/proto/grpc/lb/v1/load_ba $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1901,7 +1933,7 @@ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/com $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1916,7 +1948,7 @@ $(GENDIR)/src/proto/grpc/testing/control.pb.cc: src/proto/grpc/testing/control.p $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: src/proto/grpc/testing/control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1931,7 +1963,7 @@ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: src/proto/grpc/ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1946,7 +1978,7 @@ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $ $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1961,7 +1993,7 @@ $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: src/proto/grpc/testing/ech $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: src/proto/grpc/testing/echo_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1976,7 +2008,7 @@ $(GENDIR)/src/proto/grpc/testing/empty.pb.cc: src/proto/grpc/testing/empty.proto $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: src/proto/grpc/testing/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1991,7 +2023,7 @@ $(GENDIR)/src/proto/grpc/testing/messages.pb.cc: src/proto/grpc/testing/messages $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: src/proto/grpc/testing/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2006,7 +2038,7 @@ $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: src/proto/grpc/testing/metrics.p $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc: src/proto/grpc/testing/metrics.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2021,7 +2053,7 @@ $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: src/proto/grpc/testing/payloads $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: src/proto/grpc/testing/payloads.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2036,7 +2068,7 @@ $(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2051,7 +2083,7 @@ $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: src/proto/grpc/testing/stats.proto $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: src/proto/grpc/testing/stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2066,7 +2098,7 @@ $(GENDIR)/src/proto/grpc/testing/test.pb.cc: src/proto/grpc/testing/test.proto $ $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: src/proto/grpc/testing/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif @@ -2413,7 +2445,7 @@ $(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(LIBGPR_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBGPR_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBGPR_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr.a endif @@ -2455,7 +2487,7 @@ $(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP) $(LIBGPR_TEST_UTIL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr_test_util.a endif @@ -2706,7 +2738,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_OBJS) $(LIB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc.a endif @@ -2955,7 +2987,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_CRONE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a endif @@ -3027,7 +3059,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_TE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBGRPC_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBGRPC_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a endif @@ -3067,7 +3099,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP) $(LIBGRPC_TEST_UT $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a endif @@ -3276,7 +3308,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(LIBGRPC_UNSECURE_OBJS) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a endif @@ -3328,7 +3360,7 @@ $(LIBDIR)/$(CONFIG)/libreconnect_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBRECON $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libreconnect_server.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBRECONNECT_SERVER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBRECONNECT_SERVER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libreconnect_server.a endif @@ -3367,7 +3399,7 @@ $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBTEST_T $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBTEST_TCP_SERVER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBTEST_TCP_SERVER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a endif @@ -3546,7 +3578,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LI $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++.a endif @@ -3673,7 +3705,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBU $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a endif @@ -3739,7 +3771,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBGRPC++_TEST_CONFIG_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBGRPC++_TEST_CONFIG_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a endif @@ -3850,7 +3882,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBGRPC++_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBGRPC++_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a endif @@ -4023,7 +4055,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a endif @@ -4086,7 +4118,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBGRPC_CLI_LIBS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBGRPC_CLI_LIBS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a endif @@ -4132,7 +4164,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a endif @@ -4178,7 +4210,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PRO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBINTEROP_CLIENT_HELPER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBINTEROP_CLIENT_HELPER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a endif @@ -4232,7 +4264,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_main.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBINTEROP_CLIENT_MAIN_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBINTEROP_CLIENT_MAIN_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_client_main.a endif @@ -4283,7 +4315,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PRO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBINTEROP_SERVER_HELPER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBINTEROP_SERVER_HELPER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a endif @@ -4335,7 +4367,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_main.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBINTEROP_SERVER_MAIN_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBINTEROP_SERVER_MAIN_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_main.a endif @@ -4400,7 +4432,7 @@ $(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBQP $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libqps.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBQPS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBQPS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libqps.a endif @@ -4453,7 +4485,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_C $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a endif @@ -4797,7 +4829,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP) $(LIBBORINGSSL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl.a $(LIBBORINGSSL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl.a $(LIBBORINGSSL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl.a endif @@ -4835,7 +4867,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBBORINGSSL_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBBORINGSSL_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a endif @@ -4873,7 +4905,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBBORINGSSL_AES_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBBORINGSSL_AES_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a endif @@ -4911,7 +4943,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a endif @@ -4949,7 +4981,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a endif @@ -4987,7 +5019,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a endif @@ -5025,7 +5057,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBBORINGSSL_BN_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBBORINGSSL_BN_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a endif @@ -5063,7 +5095,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a endif @@ -5101,7 +5133,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a endif @@ -5139,7 +5171,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a endif @@ -5177,7 +5209,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a endif @@ -5206,7 +5238,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP) $(LIBBOR $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a endif @@ -5242,7 +5274,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a endif @@ -5280,7 +5312,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a endif @@ -5318,7 +5350,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBBORINGSSL_DH_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBBORINGSSL_DH_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a endif @@ -5356,7 +5388,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a endif @@ -5385,7 +5417,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_DSA $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a endif @@ -5421,7 +5453,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBBORINGSSL_EC_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBBORINGSSL_EC_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a endif @@ -5450,7 +5482,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a endif @@ -5486,7 +5518,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a endif @@ -5524,7 +5556,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a endif @@ -5562,7 +5594,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_D $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a endif @@ -5600,7 +5632,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a endif @@ -5638,7 +5670,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a endif @@ -5667,7 +5699,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_HK $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a endif @@ -5703,7 +5735,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a endif @@ -5732,7 +5764,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a endif @@ -5759,7 +5791,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_GCM $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a endif @@ -5795,7 +5827,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a endif @@ -5833,7 +5865,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a endif @@ -5871,7 +5903,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a endif @@ -5900,7 +5932,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSS $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a endif @@ -5936,7 +5968,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a endif @@ -5965,7 +5997,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a endif @@ -5992,7 +6024,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_P $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a endif @@ -6028,7 +6060,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBBORINGSSL_X509_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBBORINGSSL_X509_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a endif @@ -6057,7 +6089,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_TAB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a endif @@ -6084,7 +6116,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a endif @@ -6111,7 +6143,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a $(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a $(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a endif @@ -6147,7 +6179,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a endif @@ -6189,7 +6221,7 @@ $(LIBDIR)/$(CONFIG)/libz.a: $(LIBZ_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libz.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libz.a $(LIBZ_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libz.a $(LIBZ_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libz.a endif @@ -6224,7 +6256,7 @@ $(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBBAD_CL $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBBAD_CLIENT_TEST_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBBAD_CLIENT_TEST_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbad_client_test.a endif @@ -6263,7 +6295,7 @@ $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBBA $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBBAD_SSL_TEST_SERVER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBBAD_SSL_TEST_SERVER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a endif @@ -6342,7 +6374,7 @@ $(LIBDIR)/$(CONFIG)/libend2end_tests.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBEND2END_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_tests.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBEND2END_TESTS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBEND2END_TESTS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_tests.a endif @@ -6410,7 +6442,7 @@ $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP) $(LIBEND2END_NOSEC_TE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBEND2END_NOSEC_TESTS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBEND2END_NOSEC_TESTS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a endif diff --git a/templates/Makefile.template b/templates/Makefile.template index 0cbd8bfdd552d..cb33643dd2a0c 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -282,6 +282,29 @@ LDFLAGS += -pthread endif + # + # The steps for cross-compiling are as follows: + # First, clone and make install of grpc using the native compilers for the host. + # Also, install protoc (e.g., from a package like apt-get) + # Then clone a fresh grpc for the actual cross-compiled build + # Set the environment variable GRPC_CROSS_COMPILE to true + # Set CC, CXX, LD, LDXX, AR, and STRIP to the cross-compiling binaries + # Also set PROTOBUF_CONFIG_OPTS to indicate cross-compilation to protobuf (e.g., + # PROTOBUF_CONFIG_OPTS="--host=arm-linux --with-protoc=/usr/local/bin/protoc" ) + # Set HAS_PKG_CONFIG=false + # To build tests, go to third_party/gflags and follow its ccmake instructions + # Make sure that you enable building shared libraries and set your prefix to + # something useful like /usr/local/cross + # You will also need to set GRPC_CROSS_LDOPTS and GRPC_CROSS_AROPTS to hold + # additional required arguments for LD and AR (examples below) + # Then you can do a make from the cross-compiling fresh clone! + # + ifeq ($(GRPC_CROSS_COMPILE),true) + LDFLAGS += $(GRPC_CROSS_LDOPTS) # e.g. -L/usr/local/lib -L/usr/local/cross/lib + AROPTS = $(GRPC_CROSS_AROPTS) # e.g., rc --target=elf32-little + USE_BUILT_PROTOC = false + endif + GTEST_LIB = -Ithird_party/googletest/include -Ithird_party/googletest third_party/googletest/src/gtest-all.cc GTEST_LIB += -lgflags ifeq ($(V),1) @@ -597,6 +620,15 @@ CPPFLAGS := -Ithird_party/googletest/include $(CPPFLAGS) + PROTOC_PLUGINS_ALL =\ + % for tgt in targets: + % if tgt.build == 'protoc': + $(BINDIR)/$(CONFIG)/${tgt.name}\ + % endif + % endfor + + PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG) + ifeq ($(HAS_SYSTEM_PROTOBUF),true) ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true @@ -610,13 +642,20 @@ endif else PC_LIBS_GRPCXX = -lprotobuf + PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) endif else ifeq ($(HAS_EMBEDDED_PROTOBUF),true) PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a CPPFLAGS := -Ithird_party/protobuf/src $(CPPFLAGS) LDFLAGS := -L$(LIBDIR)/$(CONFIG)/protobuf $(LDFLAGS) + ifneq ($(USE_BUILT_PROTOC),false) PROTOC = $(BINDIR)/$(CONFIG)/protobuf/protoc + PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) + else + PROTOC_PLUGINS = + PROTOC_PLUGINS_DIR = $(prefix)/bin + endif else NO_PROTOBUF = true endif @@ -664,13 +703,6 @@ .SECONDARY = %.pb.h %.pb.cc - PROTOC_PLUGINS =\ - % for tgt in targets: - % if tgt.build == 'protoc': - $(BINDIR)/$(CONFIG)/${tgt.name}\ - % endif - % endfor - ifeq ($(DEP_MISSING),) all: static shared plugins\ % for tgt in targets: @@ -792,7 +824,7 @@ $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure $(E) "[MAKE] Building protobuf" - $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static) + $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static $(PROTOBUF_CONFIG_OPTS)) $(Q)$(MAKE) -C third_party/protobuf clean $(Q)$(MAKE) -C third_party/protobuf $(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf @@ -1124,7 +1156,7 @@ $(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc $(GENDIR)/%s.grpc.pb.cc' % (q,q) for q in proto_deps.get(p, []))} $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif % endfor @@ -1416,7 +1448,7 @@ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) \ + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) \ % if lib.get('baselib', False): $(LIBGPR_OBJS) \ $(ZLIB_MERGE_OBJS) \ From 6b88b22d9e844254406e8b4d572d4b0476c04cd2 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Tue, 19 Jul 2016 19:12:46 -0700 Subject: [PATCH 114/151] Add comments for GRPC_NO_GENERATED_CODE --- src/cpp/ext/proto_server_reflection.h | 14 ++++++++++++++ .../util/proto_reflection_descriptor_database.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/cpp/ext/proto_server_reflection.h b/src/cpp/ext/proto_server_reflection.h index 1a9a0c95a8633..fa3b9406c6ad8 100644 --- a/src/cpp/ext/proto_server_reflection.h +++ b/src/cpp/ext/proto_server_reflection.h @@ -30,12 +30,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ + +/* + - If the generated header `grpc++/ext/reflection.grpc.pb.h` needs to be + installed, target `grpc++_reflection` in `build.yaml` should use the + filegroup `grpc++_reflection_proto`, and GRPC_NO_GENERATED_CODE should not + be defined. + - If the server reflection library needs to generate `reflection.grpc.pb.h` + from `reflection.proto` at the time of making, the generated header + `grpc++/ext/reflection.grpc.pb.h` should not be installed. In this case, + target `grpc++_reflection` should depend on `grpc++_reflection_codegen`, and + GRPC_NO_GENERATED_CODE should be defined. +*/ + #ifndef GRPC_INTERNAL_CPP_EXT_PROTO_SERVER_REFLECTION_H #define GRPC_INTERNAL_CPP_EXT_PROTO_SERVER_REFLECTION_H #include #include +// GRPC_NO_GENERATED_CODE indicates generated pb files should not be used #ifdef GRPC_NO_GENERATED_CODE #include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" #else diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index 182323b2ec578..eb7cf4907db77 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -38,6 +38,7 @@ #include #include +// GRPC_NO_GENERATED_CODE indicates generated pb files should not be used #ifdef GRPC_NO_GENERATED_CODE #include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" #else From a3730b75f8cf086f7eedc2f34ad6d928b69b28d0 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Wed, 20 Jul 2016 16:59:54 +0800 Subject: [PATCH 115/151] support php7 by marco --- src/php/ext/grpc/call.c | 692 +++++++++++++----- src/php/ext/grpc/call.h | 36 +- src/php/ext/grpc/call_credentials.c | 103 ++- src/php/ext/grpc/call_credentials.h | 23 + src/php/ext/grpc/channel.c | 191 ++++- src/php/ext/grpc/channel.h | 23 +- src/php/ext/grpc/channel_credentials.c | 89 ++- src/php/ext/grpc/channel_credentials.h | 23 + src/php/ext/grpc/php_grpc.c | 54 +- src/php/ext/grpc/php_grpc.h | 4 +- src/php/ext/grpc/server.c | 136 +++- src/php/ext/grpc/server.h | 20 + src/php/ext/grpc/server_credentials.c | 64 +- src/php/ext/grpc/server_credentials.h | 20 + src/php/ext/grpc/timeval.c | 138 +++- src/php/ext/grpc/timeval.h | 23 + src/php/lib/Grpc/BaseStub.php | 4 +- src/php/lib/Grpc/BidiStreamingCall.php | 1 + src/php/lib/Grpc/ClientStreamingCall.php | 1 + src/php/lib/Grpc/ServerStreamingCall.php | 1 + src/php/lib/Grpc/UnaryCall.php | 1 + src/php/tests/unit_tests/CallTest.php | 47 ++ .../unit_tests/ChannelCredentialsTest.php | 24 +- src/php/tests/unit_tests/ChannelTest.php | 107 +++ src/php/tests/unit_tests/EndToEndTest.php | 0 .../tests/unit_tests/SecureEndToEndTest.php | 0 src/php/tests/unit_tests/ServerTest.php | 142 +++- src/php/tests/unit_tests/TimevalTest.php | 53 ++ 28 files changed, 1726 insertions(+), 294 deletions(-) mode change 100755 => 100644 src/php/lib/Grpc/BaseStub.php mode change 100755 => 100644 src/php/tests/unit_tests/CallTest.php mode change 100755 => 100644 src/php/tests/unit_tests/EndToEndTest.php mode change 100755 => 100644 src/php/tests/unit_tests/SecureEndToEndTest.php mode change 100755 => 100644 src/php/tests/unit_tests/TimevalTest.php diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 2cd45f10dc45b..bd1eccb01b4eb 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -59,12 +59,15 @@ zend_class_entry *grpc_ce_call; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_call */ void free_wrapped_grpc_call(void *object TSRMLS_DC) { wrapped_grpc_call *call = (wrapped_grpc_call *)object; if (call->owned && call->wrapped != NULL) { grpc_call_destroy(call->wrapped); } + zend_object_std_dtor(&call->std TSRMLS_CC); efree(call); } @@ -203,6 +206,131 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { return true; } +#else + +static zend_object_handlers call_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_call */ +static void free_wrapped_grpc_call(zend_object *object) { + wrapped_grpc_call *call = wrapped_grpc_call_from_obj(object); + if (call->owned && call->wrapped != NULL) { + grpc_call_destroy(call->wrapped); + } + zend_object_std_dtor(&call->std); +} + +/* Initializes an instance of wrapped_grpc_call to be associated with an + * object of a class specified by class_type */ +zend_object *create_wrapped_grpc_call(zend_class_entry *class_type) { + wrapped_grpc_call *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_call) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &call_ce_handlers; + return &intern->std; +} + +/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the + struct should be destroyed at the end of the object's lifecycle */ +void grpc_php_wrap_call(grpc_call *wrapped, bool owned, zval *call_object) { + object_init_ex(call_object, grpc_ce_call); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(call_object); + call->wrapped = wrapped; + call->owned = owned; +} + +/* Creates and returns a PHP array object with the data in a + * grpc_metadata_array. Returns NULL on failure */ +void grpc_parse_metadata_array(grpc_metadata_array *metadata_array, + zval *array) { + int count = metadata_array->count; + grpc_metadata *elements = metadata_array->metadata; + int i; + zval *data; + HashTable *array_hash; + zval inner_array; + char *str_key; + char *str_val; + size_t key_len; + + array_init(array); + array_hash = HASH_OF(array); + grpc_metadata *elem; + for (i = 0; i < count; i++) { + elem = &elements[i]; + key_len = strlen(elem->key); + str_key = ecalloc(key_len + 1, sizeof(char)); + memcpy(str_key, elem->key, key_len); + str_val = ecalloc(elem->value_length + 1, sizeof(char)); + memcpy(str_val, elem->value, elem->value_length); + if ((data = zend_hash_str_find(array_hash, str_key, key_len)) != NULL) { + if (Z_TYPE_P(data) != IS_ARRAY) { + zend_throw_exception(zend_exception_get_default(), + "Metadata hash somehow contains wrong types.", + 1); + efree(str_key); + efree(str_val); + return; + } + add_next_index_stringl(data, str_val, elem->value_length); + } else { + array_init(&inner_array); + add_next_index_stringl(&inner_array, str_val, elem->value_length); + add_assoc_zval(array, str_key, &inner_array); + } + } +} + +/* Populates a grpc_metadata_array with the data in a PHP array object. + Returns true on success and false on failure */ +bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { + zval *inner_array; + zval *value; + HashTable *array_hash; + HashTable *inner_array_hash; + zend_string *key; + if (Z_TYPE_P(array) != IS_ARRAY) { + return false; + } + grpc_metadata_array_init(metadata); + array_hash = HASH_OF(array); + + ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, inner_array) { + if (key == NULL) { + return false; + } + if (Z_TYPE_P(inner_array) != IS_ARRAY) { + return false; + } + inner_array_hash = HASH_OF(inner_array); + metadata->capacity += zend_hash_num_elements(inner_array_hash); + } + ZEND_HASH_FOREACH_END(); + + metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata)); + + ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, inner_array) { + if (key == NULL) { + return false; + } + inner_array_hash = HASH_OF(inner_array); + + ZEND_HASH_FOREACH_VAL(inner_array_hash, value) { + if (Z_TYPE_P(value) != IS_STRING) { + return false; + } + metadata->metadata[metadata->count].key = ZSTR_VAL(key); + metadata->metadata[metadata->count].value = Z_STRVAL_P(value); + metadata->metadata[metadata->count].value_length = Z_STRLEN_P(value); + metadata->count += 1; + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + return true; +} + +#endif + /** * Constructs a new instance of the Call class. * @param Channel $channel The channel to associate the call with. Must not be @@ -211,30 +339,38 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { * @param Timeval $absolute_deadline The deadline for completing the call */ PHP_METHOD(Call, __construct) { - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); zval *channel_obj; char *method; - int method_len; zval *deadline_obj; char *host_override = NULL; +#if PHP_MAJOR_VERSION < 7 + int method_len; int host_override_len = 0; + wrapped_grpc_call *call = + (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + size_t method_len; + size_t host_override_len = 0; + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); +#endif + /* "OsO|s" == 1 Object, 1 string, 1 Object, 1 optional string */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", - &channel_obj, grpc_ce_channel, - &method, &method_len, - &deadline_obj, grpc_ce_timeval, - &host_override, &host_override_len) - == FAILURE) { - zend_throw_exception( - spl_ce_InvalidArgumentException, - "Call expects a Channel, a String, a Timeval and an optional String", - 1 TSRMLS_CC); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", &channel_obj, + grpc_ce_channel, &method, &method_len, + &deadline_obj, grpc_ce_timeval, &host_override, + &host_override_len) == FAILURE) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Call expects a Channel, a String, a Timeval and " + "an optional String", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object( channel_obj TSRMLS_CC); +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(channel_obj); +#endif if (channel->wrapped == NULL) { zend_throw_exception(spl_ce_InvalidArgumentException, "Call cannot be constructed from a closed Channel", @@ -242,12 +378,17 @@ PHP_METHOD(Call, __construct) { return; } add_property_zval(getThis(), "channel", channel_obj); +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *deadline = (wrapped_grpc_timeval *)zend_object_store_get_object( deadline_obj TSRMLS_CC); - call->wrapped = grpc_channel_create_call( - channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, completion_queue, method, - host_override, deadline->wrapped, NULL); +#else + wrapped_grpc_timeval *deadline = Z_WRAPPED_GRPC_TIMEVAL_P(deadline_obj); +#endif + call->wrapped = + grpc_channel_create_call(channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, + completion_queue, method, host_override, + deadline->wrapped, NULL); call->owned = true; } @@ -257,22 +398,40 @@ PHP_METHOD(Call, __construct) { * @return object Object with results of all actions */ PHP_METHOD(Call, startBatch) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - grpc_op ops[8]; - size_t op_num = 0; - zval *array; zval **value; zval **inner_value; - HashTable *array_hash; HashPosition array_pointer; - HashTable *status_hash; - HashTable *message_hash; zval **message_value; zval **message_flags; char *key; uint key_len; ulong index; + zval *result; + zval *recv_status; + MAKE_STD_ZVAL(result); + object_init(result); +#else + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); + zval *value; + zval *inner_value; + zval *message_value; + zval *message_flags; + zend_string *key; + zend_ulong index; + zval recv_status; + object_init(return_value); +#endif + + grpc_op ops[8]; + size_t op_num = 0; + zval *array; + HashTable *array_hash; + HashTable *status_hash; + HashTable *message_hash; + grpc_metadata_array metadata; grpc_metadata_array trailing_metadata; grpc_metadata_array recv_metadata; @@ -283,17 +442,16 @@ PHP_METHOD(Call, startBatch) { grpc_byte_buffer *message; int cancelled; grpc_call_error error; - zval *result; char *message_str; size_t message_len; - zval *recv_status; + + grpc_metadata_array_init(&metadata); grpc_metadata_array_init(&trailing_metadata); grpc_metadata_array_init(&recv_metadata); grpc_metadata_array_init(&recv_trailing_metadata); - MAKE_STD_ZVAL(result); - object_init(result); memset(ops, 0, sizeof(ops)); + /* "a" == 1 array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { @@ -301,6 +459,9 @@ PHP_METHOD(Call, startBatch) { "start_batch expects an array", 1 TSRMLS_CC); goto cleanup; } + +#if PHP_MAJOR_VERSION < 7 + array_hash = Z_ARRVAL_P(array); for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); zend_hash_get_current_data_ex(array_hash, (void**)&value, @@ -313,124 +474,250 @@ PHP_METHOD(Call, startBatch) { goto cleanup; } switch(index) { - case GRPC_OP_SEND_INITIAL_METADATA: - if (!create_metadata_array(*value, &metadata)) { + case GRPC_OP_SEND_INITIAL_METADATA: + if (!create_metadata_array(*value, &metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad metadata value given", 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_initial_metadata.count = + metadata.count; + ops[op_num].data.send_initial_metadata.metadata = + metadata.metadata; + break; + case GRPC_OP_SEND_MESSAGE: + if (Z_TYPE_PP(value) != IS_ARRAY) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected an array for send message", + 1 TSRMLS_CC); + goto cleanup; + } + message_hash = Z_ARRVAL_PP(value); + if (zend_hash_find(message_hash, "flags", sizeof("flags"), + (void **)&message_flags) == SUCCESS) { + if (Z_TYPE_PP(message_flags) != IS_LONG) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Bad metadata value given", 1 TSRMLS_CC); - goto cleanup; + "Expected an int for message flags", + 1 TSRMLS_CC); } - ops[op_num].data.send_initial_metadata.count = - metadata.count; - ops[op_num].data.send_initial_metadata.metadata = - metadata.metadata; - break; - case GRPC_OP_SEND_MESSAGE: - if (Z_TYPE_PP(value) != IS_ARRAY) { + ops[op_num].flags = Z_LVAL_PP(message_flags) & GRPC_WRITE_USED_MASK; + } + if (zend_hash_find(message_hash, "message", sizeof("message"), + (void **)&message_value) != SUCCESS || + Z_TYPE_PP(message_value) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected a string for send message", + 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_message = + string_to_byte_buffer(Z_STRVAL_PP(message_value), + Z_STRLEN_PP(message_value)); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + status_hash = Z_ARRVAL_PP(value); + if (zend_hash_find(status_hash, "metadata", sizeof("metadata"), + (void **)&inner_value) == SUCCESS) { + if (!create_metadata_array(*inner_value, &trailing_metadata)) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected an array for send message", + "Bad trailing metadata value given", 1 TSRMLS_CC); goto cleanup; } - message_hash = Z_ARRVAL_PP(value); - if (zend_hash_find(message_hash, "flags", sizeof("flags"), - (void **)&message_flags) == SUCCESS) { - if (Z_TYPE_PP(message_flags) != IS_LONG) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected an int for message flags", - 1 TSRMLS_CC); - } - ops[op_num].flags = Z_LVAL_PP(message_flags) & GRPC_WRITE_USED_MASK; + ops[op_num].data.send_status_from_server.trailing_metadata = + trailing_metadata.metadata; + ops[op_num].data.send_status_from_server.trailing_metadata_count = + trailing_metadata.count; + } + if (zend_hash_find(status_hash, "code", sizeof("code"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_PP(inner_value) != IS_LONG) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Status code must be an integer", + 1 TSRMLS_CC); + goto cleanup; } - if (zend_hash_find(message_hash, "message", sizeof("message"), - (void **)&message_value) != SUCCESS || - Z_TYPE_PP(message_value) != IS_STRING) { + ops[op_num].data.send_status_from_server.status = + Z_LVAL_PP(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Integer status code is required", + 1 TSRMLS_CC); + goto cleanup; + } + if (zend_hash_find(status_hash, "details", sizeof("details"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_PP(inner_value) != IS_STRING) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected a string for send message", + "Status details must be a string", 1 TSRMLS_CC); goto cleanup; } - ops[op_num].data.send_message = - string_to_byte_buffer(Z_STRVAL_PP(message_value), - Z_STRLEN_PP(message_value)); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - status_hash = Z_ARRVAL_PP(value); - if (zend_hash_find(status_hash, "metadata", sizeof("metadata"), - (void **)&inner_value) == SUCCESS) { - if (!create_metadata_array(*inner_value, &trailing_metadata)) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Bad trailing metadata value given", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.trailing_metadata = - trailing_metadata.metadata; - ops[op_num].data.send_status_from_server.trailing_metadata_count = - trailing_metadata.count; + ops[op_num].data.send_status_from_server.status_details = + Z_STRVAL_PP(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "String status details is required", + 1 TSRMLS_CC); + goto cleanup; + } + break; + case GRPC_OP_RECV_INITIAL_METADATA: + ops[op_num].data.recv_initial_metadata = &recv_metadata; + break; + case GRPC_OP_RECV_MESSAGE: + ops[op_num].data.recv_message = &message; + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + ops[op_num].data.recv_status_on_client.trailing_metadata = + &recv_trailing_metadata; + ops[op_num].data.recv_status_on_client.status = &status; + ops[op_num].data.recv_status_on_client.status_details = + &status_details; + ops[op_num].data.recv_status_on_client.status_details_capacity = + &status_details_capacity; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + ops[op_num].data.recv_close_on_server.cancelled = &cancelled; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "Unrecognized key in batch", 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].op = (grpc_op_type)index; + ops[op_num].flags = 0; + ops[op_num].reserved = NULL; + op_num++; + } + +#else + +array_hash = HASH_OF(array); + ZEND_HASH_FOREACH_KEY_VAL(array_hash, index, key, value) { + if (key) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "batch keys must be integers", 1); + goto cleanup; + } + + switch(index) { + case GRPC_OP_SEND_INITIAL_METADATA: + if (!create_metadata_array(value, &metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad metadata value given", 1); + goto cleanup; + } + ops[op_num].data.send_initial_metadata.count = metadata.count; + ops[op_num].data.send_initial_metadata.metadata = metadata.metadata; + break; + case GRPC_OP_SEND_MESSAGE: + if (Z_TYPE_P(value) != IS_ARRAY) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected an array for send message", 1); + goto cleanup; + } + message_hash = HASH_OF(value); + if ((message_flags = + zend_hash_str_find(message_hash, "flags", + sizeof("flags") - 1)) != NULL) { + if (Z_TYPE_P(message_flags) != IS_LONG) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected an int for message flags", 1); + } + ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK; + } + if ((message_value = zend_hash_str_find(message_hash, "message", + sizeof("message") - 1)) + == NULL || Z_TYPE_P(message_value) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected a string for send message", 1); + goto cleanup; + } + ops[op_num].data.send_message = + string_to_byte_buffer(Z_STRVAL_P(message_value), + Z_STRLEN_P(message_value)); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + status_hash = HASH_OF(value); + if ((inner_value = zend_hash_str_find(status_hash, "metadata", + sizeof("metadata") - 1)) + != NULL) { + if (!create_metadata_array(inner_value, &trailing_metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad trailing metadata value given", 1); + goto cleanup; } - if (zend_hash_find(status_hash, "code", sizeof("code"), - (void**)&inner_value) == SUCCESS) { - if (Z_TYPE_PP(inner_value) != IS_LONG) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Status code must be an integer", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.status = - Z_LVAL_PP(inner_value); - } else { + ops[op_num].data.send_status_from_server.trailing_metadata = + trailing_metadata.metadata; + ops[op_num].data.send_status_from_server.trailing_metadata_count = + trailing_metadata.count; + } + if ((inner_value = zend_hash_str_find(status_hash, "code", + sizeof("code") - 1)) != NULL) { + if (Z_TYPE_P(inner_value) != IS_LONG) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Integer status code is required", - 1 TSRMLS_CC); + "Status code must be an integer", 1); goto cleanup; } - if (zend_hash_find(status_hash, "details", sizeof("details"), - (void**)&inner_value) == SUCCESS) { - if (Z_TYPE_PP(inner_value) != IS_STRING) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Status details must be a string", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.status_details = - Z_STRVAL_PP(inner_value); - } else { + ops[op_num].data.send_status_from_server.status = + Z_LVAL_P(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Integer status code is required", 1); + goto cleanup; + } + if ((inner_value = zend_hash_str_find(status_hash, "details", + sizeof("details") - 1)) != NULL) { + if (Z_TYPE_P(inner_value) != IS_STRING) { zend_throw_exception(spl_ce_InvalidArgumentException, - "String status details is required", - 1 TSRMLS_CC); + "Status details must be a string", 1); goto cleanup; } - break; - case GRPC_OP_RECV_INITIAL_METADATA: - ops[op_num].data.recv_initial_metadata = &recv_metadata; - break; - case GRPC_OP_RECV_MESSAGE: - ops[op_num].data.recv_message = &message; - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - ops[op_num].data.recv_status_on_client.trailing_metadata = - &recv_trailing_metadata; - ops[op_num].data.recv_status_on_client.status = &status; - ops[op_num].data.recv_status_on_client.status_details = - &status_details; - ops[op_num].data.recv_status_on_client.status_details_capacity = - &status_details_capacity; - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - ops[op_num].data.recv_close_on_server.cancelled = &cancelled; - break; - default: + ops[op_num].data.send_status_from_server.status_details = + Z_STRVAL_P(inner_value); + } else { zend_throw_exception(spl_ce_InvalidArgumentException, - "Unrecognized key in batch", 1 TSRMLS_CC); + "String status details is required", 1); goto cleanup; + } + break; + case GRPC_OP_RECV_INITIAL_METADATA: + ops[op_num].data.recv_initial_metadata = &recv_metadata; + break; + case GRPC_OP_RECV_MESSAGE: + ops[op_num].data.recv_message = &message; + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + ops[op_num].data.recv_status_on_client.trailing_metadata = + &recv_trailing_metadata; + ops[op_num].data.recv_status_on_client.status = &status; + ops[op_num].data.recv_status_on_client.status_details = + &status_details; + ops[op_num].data.recv_status_on_client.status_details_capacity = + &status_details_capacity; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + ops[op_num].data.recv_close_on_server.cancelled = &cancelled; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "Unrecognized key in batch", 1); + goto cleanup; } ops[op_num].op = (grpc_op_type)index; ops[op_num].flags = 0; ops[op_num].reserved = NULL; op_num++; } + ZEND_HASH_FOREACH_END(); + +#endif + error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped, NULL); if (error != GRPC_CALL_OK) { @@ -441,52 +728,98 @@ PHP_METHOD(Call, startBatch) { } grpc_completion_queue_pluck(completion_queue, call->wrapped, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); +#if PHP_MAJOR_VERSION < 7 for (int i = 0; i < op_num; i++) { switch(ops[i].op) { - case GRPC_OP_SEND_INITIAL_METADATA: - add_property_bool(result, "send_metadata", true); - break; - case GRPC_OP_SEND_MESSAGE: - add_property_bool(result, "send_message", true); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - add_property_bool(result, "send_close", true); - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - add_property_bool(result, "send_status", true); - break; - case GRPC_OP_RECV_INITIAL_METADATA: - array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC); - 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); - if (message_str == NULL) { - add_property_null(result, "message"); - } else { - add_property_stringl(result, "message", message_str, message_len, - false); - } - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - MAKE_STD_ZVAL(recv_status); - object_init(recv_status); - array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC); - 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); - break; - default: - break; + case GRPC_OP_SEND_INITIAL_METADATA: + add_property_bool(result, "send_metadata", true); + break; + case GRPC_OP_SEND_MESSAGE: + add_property_bool(result, "send_message", true); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + add_property_bool(result, "send_close", true); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + add_property_bool(result, "send_status", true); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC); + 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); + if (message_str == NULL) { + add_property_null(result, "message"); + } else { + add_property_stringl(result, "message", message_str, message_len, + false); + } + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + MAKE_STD_ZVAL(recv_status); + object_init(recv_status); + array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC); + 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); + break; + default: + break; + } + } +#else + for (int i = 0; i < op_num; i++) { + switch(ops[i].op) { + case GRPC_OP_SEND_INITIAL_METADATA: + add_property_bool(return_value, "send_metadata", true); + break; + case GRPC_OP_SEND_MESSAGE: + add_property_bool(return_value, "send_message", true); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + add_property_bool(return_value, "send_close", true); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + add_property_bool(return_value, "send_status", true); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + grpc_parse_metadata_array(&recv_metadata, array); + add_property_zval(return_value, "metadata", array); + break; + case GRPC_OP_RECV_MESSAGE: + byte_buffer_to_string(message, &message_str, &message_len); + if (message_str == NULL) { + add_property_null(return_value, "message"); + } else { + add_property_stringl(return_value, "message", message_str, + message_len); + } + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + object_init(&recv_status); + grpc_parse_metadata_array(&recv_trailing_metadata, array); + add_property_zval(&recv_status, "metadata", array); + add_property_long(&recv_status, "code", status); + add_property_string(&recv_status, "details", status_details); + add_property_zval(return_value, "status", &recv_status); + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + add_property_bool(return_value, "cancelled", cancelled); + break; + default: + break; } } +#endif + cleanup: grpc_metadata_array_destroy(&metadata); grpc_metadata_array_destroy(&trailing_metadata); @@ -503,7 +836,11 @@ PHP_METHOD(Call, startBatch) { grpc_byte_buffer_destroy(message); } } +#if PHP_MAJOR_VERSION < 7 RETURN_DESTROY_ZVAL(result); +#else + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -511,9 +848,14 @@ PHP_METHOD(Call, startBatch) { * @return string The URI of the endpoint */ PHP_METHOD(Call, getPeer) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); RETURN_STRING(grpc_call_get_peer(call->wrapped), 1); +#else + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); + RETURN_STRING(grpc_call_get_peer(call->wrapped)); +#endif } /** @@ -521,8 +863,12 @@ PHP_METHOD(Call, getPeer) { * has not already ended with another status. */ PHP_METHOD(Call, cancel) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); +#endif grpc_call_cancel(call->wrapped, NULL); } @@ -543,12 +889,17 @@ PHP_METHOD(Call, setCredentials) { return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call_credentials *creds = (wrapped_grpc_call_credentials *)zend_object_store_get_object( creds_obj TSRMLS_CC); - wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_call_credentials *creds = + Z_WRAPPED_GRPC_CALL_CREDS_P(creds_obj); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); +#endif grpc_call_error error = GRPC_CALL_ERROR; error = grpc_call_set_credentials(call->wrapped, creds->wrapped); @@ -556,16 +907,23 @@ PHP_METHOD(Call, setCredentials) { } static zend_function_entry call_methods[] = { - PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC) - PHP_FE_END}; + PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_call(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Call", call_methods); ce.create_object = create_wrapped_grpc_call; grpc_ce_call = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&call_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + call_ce_handlers.offset = XtOffsetOf(wrapped_grpc_call, std); + call_ce_handlers.free_obj = free_wrapped_grpc_call; +#endif } diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h index 36c5f2d272466..9fc52d78209d7 100644 --- a/src/php/ext/grpc/call.h +++ b/src/php/ext/grpc/call.h @@ -48,17 +48,15 @@ /* Class entry for the Call PHP class */ extern zend_class_entry *grpc_ce_call; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_call that can be associated with a PHP object */ typedef struct wrapped_grpc_call { zend_object std; - bool owned; grpc_call *wrapped; } wrapped_grpc_call; -/* Initializes the Call PHP class */ -void grpc_init_call(TSRMLS_D); - /* Creates a Call object that wraps the given grpc_call struct */ zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC); @@ -66,6 +64,36 @@ zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC); * call metadata */ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC); +#else + +/* Wrapper struct for grpc_call that can be associated with a PHP object */ +typedef struct wrapped_grpc_call { + bool owned; + grpc_call *wrapped; + zend_object std; +} wrapped_grpc_call; + +static inline wrapped_grpc_call +*wrapped_grpc_call_from_obj(zend_object *obj) { + return (wrapped_grpc_call*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_call, std)); +} + +#define Z_WRAPPED_GRPC_CALL_P(zv) wrapped_grpc_call_from_obj(Z_OBJ_P((zv))) + +/* Creates a Call object that wraps the given grpc_call struct */ +void grpc_php_wrap_call(grpc_call *wrapped, bool owned, zval *call_object); + +/* Creates and returns a PHP associative array of metadata from a C array of + * call metadata */ +void grpc_parse_metadata_array(grpc_metadata_array *metadata_array, + zval *array); + +#endif /* PHP_MAJOR_VERSION */ + +/* Initializes the Call PHP class */ +void grpc_init_call(TSRMLS_D); + /* Populates a grpc_metadata_array with the data in a PHP array object. Returns true on success and false on failure */ bool create_metadata_array(zval *array, grpc_metadata_array *metadata); diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c index ec0e6b91813c4..70aaffb848ac3 100644 --- a/src/php/ext/grpc/call_credentials.c +++ b/src/php/ext/grpc/call_credentials.c @@ -53,6 +53,8 @@ zend_class_entry *grpc_ce_call_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_call_credentials */ void free_wrapped_grpc_call_credentials(void *object TSRMLS_DC) { wrapped_grpc_call_credentials *creds = @@ -60,6 +62,7 @@ void free_wrapped_grpc_call_credentials(void *object TSRMLS_DC) { if (creds->wrapped != NULL) { grpc_call_credentials_release(creds->wrapped); } + zend_object_std_dtor(&creds->std TSRMLS_CC); efree(creds); } @@ -94,6 +97,43 @@ zval *grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped TSRMLS_DC) { return credentials_object; } +#else + +static zend_object_handlers call_credentials_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_call_credentials */ +static void free_wrapped_grpc_call_credentials(zend_object *object) { + wrapped_grpc_call_credentials *creds = + wrapped_grpc_call_creds_from_obj(object); + if (creds->wrapped != NULL) { + grpc_call_credentials_release(creds->wrapped); + } + zend_object_std_dtor(&creds->std); +} + +/* Initializes an instance of wrapped_grpc_call_credentials to be + * associated with an object of a class specified by class_type */ +zend_object *create_wrapped_grpc_call_credentials(zend_class_entry + *class_type) { + wrapped_grpc_call_credentials *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_call_credentials) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &call_credentials_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped, + zval *credentials_object) { + object_init_ex(credentials_object, grpc_ce_call_credentials); + wrapped_grpc_call_credentials *credentials = + Z_WRAPPED_GRPC_CALL_CREDS_P(credentials_object); + credentials->wrapped = wrapped; +} + +#endif + /** * Create composite credentials from two existing credentials. * @param CallCredentials cred1 The first credential @@ -113,6 +153,7 @@ PHP_METHOD(CallCredentials, createComposite) { 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call_credentials *cred1 = (wrapped_grpc_call_credentials *)zend_object_store_get_object( cred1_obj TSRMLS_CC); @@ -124,6 +165,17 @@ PHP_METHOD(CallCredentials, createComposite) { NULL); zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + wrapped_grpc_call_credentials *cred1 = + Z_WRAPPED_GRPC_CALL_CREDS_P(cred1_obj); + wrapped_grpc_call_credentials *cred2 = + Z_WRAPPED_GRPC_CALL_CREDS_P(cred2_obj); + grpc_call_credentials *creds = + grpc_composite_call_credentials_create(cred1->wrapped, + cred2->wrapped, NULL); + grpc_php_wrap_call_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -141,13 +193,10 @@ PHP_METHOD(CallCredentials, createFromPlugin) { memset(fci_cache, 0, sizeof(zend_fcall_info_cache)); /* "f" == 1 function */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", fci, - fci_cache, - fci->params, - fci->param_count) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f*", fci, fci_cache, + fci->params, fci->param_count) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, - "createFromPlugin expects 1 callback", - 1 TSRMLS_CC); + "createFromPlugin expects 1 callback", 1 TSRMLS_CC); return; } @@ -165,10 +214,15 @@ PHP_METHOD(CallCredentials, createFromPlugin) { plugin.state = (void *)state; plugin.type = ""; - grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin( - plugin, NULL); + grpc_call_credentials *creds = + grpc_metadata_credentials_create_from_plugin(plugin, NULL); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_call_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /* Callback function for plugin creds API */ @@ -181,6 +235,7 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context, /* prepare to call the user callback function with info from the * grpc_auth_metadata_context */ +#if PHP_MAJOR_VERSION < 7 zval **params[1]; zval *arg; zval *retval; @@ -192,21 +247,41 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context, state->fci->param_count = 1; state->fci->params = params; state->fci->retval_ptr_ptr = &retval; +#else + zval arg; + zval retval; + object_init(&arg); + add_property_string(&arg, "service_url", context.service_url); + add_property_string(&arg, "method_name", context.method_name); + state->fci->param_count = 1; + state->fci->params = &arg; + state->fci->retval = &retval; +#endif /* call the user callback function */ zend_call_function(state->fci, state->fci_cache TSRMLS_CC); +#if PHP_MAJOR_VERSION < 7 if (Z_TYPE_P(retval) != IS_ARRAY) { +#else + if (Z_TYPE_P(&retval) != IS_ARRAY) { +#endif zend_throw_exception(spl_ce_InvalidArgumentException, "plugin callback must return metadata array", 1 TSRMLS_CC); + return; } grpc_metadata_array metadata; +#if PHP_MAJOR_VERSION < 7 if (!create_metadata_array(retval, &metadata)) { +#else + if (!create_metadata_array(&retval, &metadata)) { +#endif zend_throw_exception(spl_ce_InvalidArgumentException, "invalid metadata", 1 TSRMLS_CC); grpc_metadata_array_destroy(&metadata); + return; } /* TODO: handle error */ @@ -229,11 +304,21 @@ static zend_function_entry call_credentials_methods[] = { ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(CallCredentials, createFromPlugin, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_FE_END}; + PHP_FE_END +}; void grpc_init_call_credentials(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\CallCredentials", call_credentials_methods); ce.create_object = create_wrapped_grpc_call_credentials; grpc_ce_call_credentials = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&call_credentials_ce_handlers, + zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + call_credentials_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_call_credentials, std); + call_credentials_ce_handlers.free_obj = + free_wrapped_grpc_call_credentials; +#endif } diff --git a/src/php/ext/grpc/call_credentials.h b/src/php/ext/grpc/call_credentials.h index d2f6a92449bf7..e05e14698b2fc 100755 --- a/src/php/ext/grpc/call_credentials.h +++ b/src/php/ext/grpc/call_credentials.h @@ -49,14 +49,37 @@ /* Class entry for the CallCredentials PHP class */ extern zend_class_entry *grpc_ce_call_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_call_credentials that can be associated * with a PHP object */ typedef struct wrapped_grpc_call_credentials { zend_object std; + grpc_call_credentials *wrapped; +} wrapped_grpc_call_credentials; +#else + +/* Wrapper struct for grpc_call_credentials that can be associated + * with a PHP object */ +typedef struct wrapped_grpc_call_credentials { grpc_call_credentials *wrapped; + zend_object std; } wrapped_grpc_call_credentials; +static inline wrapped_grpc_call_credentials +*wrapped_grpc_call_creds_from_obj(zend_object *obj) { + return + (wrapped_grpc_call_credentials*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_call_credentials, + std)); +} + +#define Z_WRAPPED_GRPC_CALL_CREDS_P(zv) \ + wrapped_grpc_call_creds_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Struct to hold callback function for plugin creds API */ typedef struct plugin_state { zend_fcall_info *fci; diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index 8d94c59683e93..ce96457c7c38f 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -57,12 +57,15 @@ zend_class_entry *grpc_ce_channel; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_channel */ void free_wrapped_grpc_channel(void *object TSRMLS_DC) { wrapped_grpc_channel *channel = (wrapped_grpc_channel *)object; if (channel->wrapped != NULL) { grpc_channel_destroy(channel->wrapped); } + zend_object_std_dtor(&channel->std TSRMLS_CC); efree(channel); } @@ -107,23 +110,88 @@ void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_D } args->args[args_index].key = key; switch (Z_TYPE_P(*data)) { - case IS_LONG: - args->args[args_index].value.integer = (int)Z_LVAL_P(*data); - args->args[args_index].type = GRPC_ARG_INTEGER; - break; - case IS_STRING: - args->args[args_index].value.string = Z_STRVAL_P(*data); - args->args[args_index].type = GRPC_ARG_STRING; - break; - default: - zend_throw_exception(spl_ce_InvalidArgumentException, - "args values must be int or string", 1 TSRMLS_CC); - return; + case IS_LONG: + args->args[args_index].value.integer = (int)Z_LVAL_P(*data); + args->args[args_index].type = GRPC_ARG_INTEGER; + break; + case IS_STRING: + args->args[args_index].value.string = Z_STRVAL_P(*data); + args->args[args_index].type = GRPC_ARG_STRING; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "args values must be int or string", 1 TSRMLS_CC); + return; } args_index++; } } +#else + +static zend_object_handlers channel_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_channel */ +static void free_wrapped_grpc_channel(zend_object *object) { + wrapped_grpc_channel *channel = wrapped_grpc_channel_from_obj(object); + if (channel->wrapped != NULL) { + grpc_channel_destroy(channel->wrapped); + } + zend_object_std_dtor(&channel->std); +} + +/* Initializes an instance of wrapped_grpc_channel to be associated with an + * object of a class specified by class_type */ +zend_object *create_wrapped_grpc_channel(zend_class_entry *class_type) { + wrapped_grpc_channel *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_channel) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &channel_ce_handlers; + return &intern->std; +} + +void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args) { + HashTable *array_hash; + int args_index; + zval *data; + zend_string *key; + array_hash = HASH_OF(args_array); + if (!array_hash) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "array_hash is NULL", 1); + return; + } + args->num_args = zend_hash_num_elements(array_hash); + args->args = ecalloc(args->num_args, sizeof(grpc_arg)); + args_index = 0; + ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, data) { + if (key == NULL) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "args keys must be strings", 1); + } + args->args[args_index].key = ZSTR_VAL(key); + switch (Z_TYPE_P(data)) { + case IS_LONG: + args->args[args_index].value.integer = (int)Z_LVAL_P(data); + args->args[args_index].type = GRPC_ARG_INTEGER; + break; + case IS_STRING: + args->args[args_index].value.string = Z_STRVAL_P(data); + args->args[args_index].type = GRPC_ARG_STRING; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "args values must be int or string", 1); + return; + } + args_index++; + } ZEND_HASH_FOREACH_END(); +} + +#endif + /** * Construct an instance of the Channel class. If the $args array contains a * "credentials" key mapping to a ChannelCredentials object, a secure channel @@ -132,16 +200,23 @@ void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_D * @param array $args The arguments to pass to the Channel (optional) */ PHP_METHOD(Channel, __construct) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object( getThis() TSRMLS_CC); - char *target; + zval **creds_obj = NULL; int target_length; +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + zval *creds_obj = NULL; + size_t target_length; +#endif + char *target; zval *args_array = NULL; grpc_channel_args args; HashTable *array_hash; - zval **creds_obj = NULL; wrapped_grpc_channel_credentials *creds = NULL; + /* "sa" == 1 string, 1 array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &target, &target_length, &args_array) == FAILURE) { @@ -149,6 +224,7 @@ PHP_METHOD(Channel, __construct) { "Channel expects a string and an array", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 array_hash = Z_ARRVAL_P(args_array); if (zend_hash_find(array_hash, "credentials", sizeof("credentials"), (void **)&creds_obj) == SUCCESS) { @@ -167,6 +243,24 @@ PHP_METHOD(Channel, __construct) { zend_hash_del(array_hash, "credentials", 12); } } +#else + array_hash = HASH_OF(args_array); + if ((creds_obj = zend_hash_str_find(array_hash, "credentials", + sizeof("credentials") - 1)) != NULL) { + if (Z_TYPE_P(creds_obj) == IS_NULL) { + creds = NULL; + zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1); + } else if (Z_OBJ_P(creds_obj)->ce != grpc_ce_channel_credentials) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "credentials must be a ChannelCredentials object", + 1); + return; + } else { + creds = Z_WRAPPED_GRPC_CHANNEL_CREDS_P(creds_obj); + zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1); + } + } +#endif php_grpc_read_args_array(args_array, &args TSRMLS_CC); if (creds == NULL) { channel->wrapped = grpc_insecure_channel_create(target, &args, NULL); @@ -182,9 +276,14 @@ PHP_METHOD(Channel, __construct) { * @return string The URI of the endpoint */ PHP_METHOD(Channel, getTarget) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); + (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); RETURN_STRING(grpc_channel_get_target(channel->wrapped), 1); +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + RETURN_STRING(grpc_channel_get_target(channel->wrapped)); +#endif } /** @@ -193,12 +292,17 @@ PHP_METHOD(Channel, getTarget) { * @return long The grpc connectivity state */ PHP_METHOD(Channel, getConnectivityState) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); - bool try_to_connect; +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); +#endif + bool try_to_connect = false; + /* "|b" == 1 optional bool */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect) + == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "getConnectivityState expects a bool", 1 TSRMLS_CC); return; @@ -215,10 +319,16 @@ PHP_METHOD(Channel, getConnectivityState) { * before deadline */ PHP_METHOD(Channel, watchConnectivityState) { +#if PHP_MAJOR_VERSION < 7 + long last_state; wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); - long last_state; +#else + zend_long last_state; + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); +#endif zval *deadline_obj; + /* "lO" == 1 long 1 object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO", &last_state, &deadline_obj, grpc_ce_timeval) == FAILURE) { @@ -228,15 +338,20 @@ PHP_METHOD(Channel, watchConnectivityState) { return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *deadline = (wrapped_grpc_timeval *)zend_object_store_get_object( deadline_obj TSRMLS_CC); - grpc_channel_watch_connectivity_state( - channel->wrapped, (grpc_connectivity_state)last_state, - deadline->wrapped, completion_queue, NULL); - grpc_event event = grpc_completion_queue_pluck( - completion_queue, NULL, - gpr_inf_future(GPR_CLOCK_REALTIME), NULL); +#else + wrapped_grpc_timeval *deadline = Z_WRAPPED_GRPC_TIMEVAL_P(deadline_obj); +#endif + grpc_channel_watch_connectivity_state(channel->wrapped, + (grpc_connectivity_state)last_state, + deadline->wrapped, completion_queue, + NULL); + grpc_event event = + grpc_completion_queue_pluck(completion_queue, NULL, + gpr_inf_future(GPR_CLOCK_REALTIME), NULL); RETURN_BOOL(event.success); } @@ -244,8 +359,12 @@ PHP_METHOD(Channel, watchConnectivityState) { * Close the channel */ PHP_METHOD(Channel, close) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); + (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); +#endif if (channel->wrapped != NULL) { grpc_channel_destroy(channel->wrapped); channel->wrapped = NULL; @@ -253,16 +372,24 @@ PHP_METHOD(Channel, close) { } static zend_function_entry channel_methods[] = { - PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) - PHP_FE_END}; + PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_channel(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Channel", channel_methods); ce.create_object = create_wrapped_grpc_channel; grpc_ce_channel = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&channel_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + channel_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_channel, std); + channel_ce_handlers.free_obj = free_wrapped_grpc_channel; +#endif } diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h index cc5823ee7f758..ea5efeaf86401 100755 --- a/src/php/ext/grpc/channel.h +++ b/src/php/ext/grpc/channel.h @@ -48,17 +48,38 @@ /* Class entry for the PHP Channel class */ extern zend_class_entry *grpc_ce_channel; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_channel that can be associated with a PHP object */ typedef struct wrapped_grpc_channel { zend_object std; + grpc_channel *wrapped; +} wrapped_grpc_channel; +#else + +/* Wrapper struct for grpc_channel that can be associated with a PHP object */ +typedef struct wrapped_grpc_channel { grpc_channel *wrapped; + zend_object std; } wrapped_grpc_channel; +static inline wrapped_grpc_channel +*wrapped_grpc_channel_from_obj(zend_object *obj) { + return (wrapped_grpc_channel*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_channel, std)); +} + +#define Z_WRAPPED_GRPC_CHANNEL_P(zv) \ + wrapped_grpc_channel_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the Channel class */ void grpc_init_channel(TSRMLS_D); /* Iterates through a PHP array and populates args with the contents */ -void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_DC); +void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args + TSRMLS_DC); #endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */ diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index b76fb105f3630..10e0acafac4af 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -52,7 +52,6 @@ #include zend_class_entry *grpc_ce_channel_credentials; - static char *default_pem_root_certs = NULL; static grpc_ssl_roots_override_result get_ssl_roots_override( @@ -64,6 +63,8 @@ static grpc_ssl_roots_override_result get_ssl_roots_override( return GRPC_SSL_ROOTS_OVERRIDE_OK; } +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_channel_credentials */ void free_wrapped_grpc_channel_credentials(void *object TSRMLS_DC) { wrapped_grpc_channel_credentials *creds = @@ -71,6 +72,7 @@ void free_wrapped_grpc_channel_credentials(void *object TSRMLS_DC) { if (creds->wrapped != NULL) { grpc_channel_credentials_release(creds->wrapped); } + zend_object_std_dtor(&creds->std TSRMLS_CC); efree(creds); } @@ -105,6 +107,43 @@ zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS return credentials_object; } +#else + +static zend_object_handlers channel_credentials_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_channel_credentials */ +static void free_wrapped_grpc_channel_credentials(zend_object *object) { + wrapped_grpc_channel_credentials *creds = + wrapped_grpc_channel_creds_from_obj(object); + if (creds->wrapped != NULL) { + grpc_channel_credentials_release(creds->wrapped); + } + zend_object_std_dtor(&creds->std); +} + +/* Initializes an instance of wrapped_grpc_channel_credentials to be + * associated with an object of a class specified by class_type */ +zend_object *create_wrapped_grpc_channel_credentials(zend_class_entry + *class_type) { + wrapped_grpc_channel_credentials *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_channel_credentials) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &channel_credentials_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped, + zval *credentials_object) { + object_init_ex(credentials_object, grpc_ce_channel_credentials); + wrapped_grpc_channel_credentials *credentials = + Z_WRAPPED_GRPC_CHANNEL_CREDS_P(credentials_object); + credentials->wrapped = wrapped; +} + +#endif + /** * Set default roots pem. * @param string pem_roots PEM encoding of the server root certificates @@ -112,7 +151,13 @@ zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS */ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { char *pem_roots; +#if PHP_MAJOR_VERSION < 7 int pem_roots_length; +#else + size_t pem_roots_length; +#endif + + /* "s" == 1 string */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &pem_roots, &pem_roots_length) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, @@ -129,8 +174,13 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { */ PHP_METHOD(ChannelCredentials, createDefault) { grpc_channel_credentials *creds = grpc_google_default_credentials_create(); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_channel_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -146,11 +196,15 @@ PHP_METHOD(ChannelCredentials, createSsl) { char *pem_root_certs = NULL; grpc_ssl_pem_key_cert_pair pem_key_cert_pair; +#if PHP_MAJOR_VERSION < 7 int root_certs_length = 0, private_key_length = 0, cert_chain_length = 0; +#else + size_t root_certs_length = 0, private_key_length = 0, cert_chain_length = 0; +#endif pem_key_cert_pair.private_key = pem_key_cert_pair.cert_chain = NULL; - /* "|s!s!s! == 3 optional nullable strings */ + /* "|s!s!s!" == 3 optional nullable strings */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!", &pem_root_certs, &root_certs_length, &pem_key_cert_pair.private_key, @@ -164,8 +218,13 @@ PHP_METHOD(ChannelCredentials, createSsl) { grpc_channel_credentials *creds = grpc_ssl_credentials_create( pem_root_certs, pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_channel_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -178,7 +237,7 @@ PHP_METHOD(ChannelCredentials, createComposite) { zval *cred1_obj; zval *cred2_obj; - /* "OO" == 3 Objects */ + /* "OO" == 2 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj, grpc_ce_channel_credentials, &cred2_obj, grpc_ce_call_credentials) == FAILURE) { @@ -186,6 +245,7 @@ PHP_METHOD(ChannelCredentials, createComposite) { "createComposite expects 2 Credentials", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel_credentials *cred1 = (wrapped_grpc_channel_credentials *)zend_object_store_get_object( cred1_obj TSRMLS_CC); @@ -197,6 +257,17 @@ PHP_METHOD(ChannelCredentials, createComposite) { NULL); zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + wrapped_grpc_channel_credentials *cred1 = + Z_WRAPPED_GRPC_CHANNEL_CREDS_P(cred1_obj); + wrapped_grpc_call_credentials *cred2 = + Z_WRAPPED_GRPC_CALL_CREDS_P(cred2_obj); + grpc_channel_credentials *creds = + grpc_composite_channel_credentials_create(cred1->wrapped, + cred2->wrapped, NULL); + grpc_php_wrap_channel_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -218,7 +289,8 @@ static zend_function_entry channel_credentials_methods[] = { ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(ChannelCredentials, createInsecure, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_FE_END}; + PHP_FE_END +}; void grpc_init_channel_credentials(TSRMLS_D) { zend_class_entry ce; @@ -227,4 +299,13 @@ void grpc_init_channel_credentials(TSRMLS_D) { grpc_set_ssl_roots_override_callback(get_ssl_roots_override); ce.create_object = create_wrapped_grpc_channel_credentials; grpc_ce_channel_credentials = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&channel_credentials_ce_handlers, + zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + channel_credentials_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_channel_credentials, std); + channel_credentials_ce_handlers.free_obj = + free_wrapped_grpc_channel_credentials; +#endif } diff --git a/src/php/ext/grpc/channel_credentials.h b/src/php/ext/grpc/channel_credentials.h index d89984ce60407..44071b10f1079 100755 --- a/src/php/ext/grpc/channel_credentials.h +++ b/src/php/ext/grpc/channel_credentials.h @@ -49,14 +49,37 @@ /* Class entry for the ChannelCredentials PHP class */ extern zend_class_entry *grpc_ce_channel_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_channel_credentials that can be associated * with a PHP object */ typedef struct wrapped_grpc_channel_credentials { zend_object std; + grpc_channel_credentials *wrapped; +} wrapped_grpc_channel_credentials; +#else + +/* Wrapper struct for grpc_channel_credentials that can be associated + * with a PHP object */ +typedef struct wrapped_grpc_channel_credentials { grpc_channel_credentials *wrapped; + zend_object std; } wrapped_grpc_channel_credentials; +static inline wrapped_grpc_channel_credentials +*wrapped_grpc_channel_creds_from_obj(zend_object *obj) { + return + (wrapped_grpc_channel_credentials *) + ((char*)(obj) - + XtOffsetOf(wrapped_grpc_channel_credentials, std)); +} + +#define Z_WRAPPED_GRPC_CHANNEL_CREDS_P(zv) \ + wrapped_grpc_channel_creds_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the ChannelCredentials PHP class */ void grpc_init_channel_credentials(TSRMLS_D); diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 449ba3cd47b8c..5edfa2da7df6b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -64,15 +64,19 @@ const zend_function_entry grpc_functions[] = { */ zend_module_entry grpc_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER, #endif - "grpc", grpc_functions, PHP_MINIT(grpc), - PHP_MSHUTDOWN(grpc), NULL, NULL, - PHP_MINFO(grpc), + "grpc", + grpc_functions, + PHP_MINIT(grpc), + PHP_MSHUTDOWN(grpc), + NULL, + NULL, + PHP_MINFO(grpc), #if ZEND_MODULE_API_NO >= 20010901 - PHP_GRPC_VERSION, + PHP_GRPC_VERSION, #endif - STANDARD_MODULE_PROPERTIES}; + STANDARD_MODULE_PROPERTIES}; /* }}} */ #ifdef COMPILE_DL_GRPC @@ -82,23 +86,24 @@ ZEND_GET_MODULE(grpc) /* {{{ PHP_INI */ /* Remove comments and fill if you need to have entries in php.ini -PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, -global_value, zend_grpc_globals, grpc_globals) - STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, -OnUpdateString, global_string, zend_grpc_globals, grpc_globals) -PHP_INI_END() + PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, + global_value, zend_grpc_globals, grpc_globals) + STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, + OnUpdateString, global_string, zend_grpc_globals, + grpc_globals) + PHP_INI_END() */ /* }}} */ /* {{{ php_grpc_init_globals */ /* Uncomment this function if you have INI entries -static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) -{ - grpc_globals->global_value = 0; - grpc_globals->global_string = NULL; -} + static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) + { + grpc_globals->global_value = 0; + grpc_globals->global_string = NULL; + } */ /* }}} */ @@ -106,7 +111,7 @@ static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) */ PHP_MINIT_FUNCTION(grpc) { /* If you have INI entries, uncomment these lines - REGISTER_INI_ENTRIES(); + REGISTER_INI_ENTRIES(); */ /* Register call error constants */ grpc_init(); @@ -246,7 +251,7 @@ PHP_MINIT_FUNCTION(grpc) { */ PHP_MSHUTDOWN_FUNCTION(grpc) { /* uncomment this line if you have INI entries - UNREGISTER_INI_ENTRIES(); + UNREGISTER_INI_ENTRIES(); */ // WARNING: This function IS being called by PHP when the extension // is unloaded but the logs were somehow suppressed. @@ -265,7 +270,7 @@ PHP_MINFO_FUNCTION(grpc) { php_info_print_table_end(); /* Remove comments if you have entries in php.ini - DISPLAY_INI_ENTRIES(); + DISPLAY_INI_ENTRIES(); */ } /* }}} */ @@ -274,12 +279,3 @@ PHP_MINFO_FUNCTION(grpc) { function definition, where the functions purpose is also documented. Please follow this convention for the convenience of others editing your code. */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index 1d4834c50fa32..bd7ee75a6fb56 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -72,8 +72,8 @@ PHP_MSHUTDOWN_FUNCTION(grpc); PHP_MINFO_FUNCTION(grpc); /* - Declare any global variables you may need between the BEGIN - and END macros here: + Declare any global variables you may need between the BEGIN + and END macros here: ZEND_BEGIN_MODULE_GLOBALS(grpc) ZEND_END_MODULE_GLOBALS(grpc) diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c index c13e7cd1f9240..50fb2d0cf9402 100644 --- a/src/php/ext/grpc/server.c +++ b/src/php/ext/grpc/server.c @@ -58,6 +58,8 @@ zend_class_entry *grpc_ce_server; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_server */ void free_wrapped_grpc_server(void *object TSRMLS_DC) { wrapped_grpc_server *server = (wrapped_grpc_server *)object; @@ -68,6 +70,7 @@ void free_wrapped_grpc_server(void *object TSRMLS_DC) { gpr_inf_future(GPR_CLOCK_REALTIME), NULL); grpc_server_destroy(server->wrapped); } + zend_object_std_dtor(&server->std TSRMLS_CC); efree(server); } @@ -90,15 +93,51 @@ zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type return retval; } +#else + +static zend_object_handlers server_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_server */ +static void free_wrapped_grpc_server(zend_object *object) { + wrapped_grpc_server *server = wrapped_grpc_server_from_obj(object); + if (server->wrapped != NULL) { + grpc_server_shutdown_and_notify(server->wrapped, completion_queue, NULL); + grpc_server_cancel_all_calls(server->wrapped); + grpc_completion_queue_pluck(completion_queue, NULL, + gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + grpc_server_destroy(server->wrapped); + } + zend_object_std_dtor(&server->std); +} + +/* Initializes an instance of wrapped_grpc_call to be associated with an object + * of a class specified by class_type */ +zend_object *create_wrapped_grpc_server(zend_class_entry *class_type) { + wrapped_grpc_server *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_server) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &server_ce_handlers; + return &intern->std; +} + +#endif + /** * Constructs a new instance of the Server class * @param array $args The arguments to pass to the server (optional) */ PHP_METHOD(Server, __construct) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif zval *args_array = NULL; grpc_channel_args args; + /* "|a" == 1 optional array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &args_array) == FAILURE) { @@ -110,6 +149,8 @@ PHP_METHOD(Server, __construct) { if (args_array == NULL) { server->wrapped = grpc_server_create(NULL, NULL); } else { + //TODO(thinkerou): deal it if key of array is long, crash now on php7 + // and update unit test case php_grpc_read_args_array(args_array, &args TSRMLS_CC); server->wrapped = grpc_server_create(&args, NULL); efree(args.args); @@ -126,15 +167,22 @@ PHP_METHOD(Server, __construct) { */ PHP_METHOD(Server, requestCall) { grpc_call_error error_code; - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); grpc_call *call; grpc_call_details details; grpc_metadata_array metadata; - zval *result; grpc_event event; + +#if PHP_MAJOR_VERSION < 7 + wrapped_grpc_server *server = + (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); + zval *result; MAKE_STD_ZVAL(result); object_init(result); +#else + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); + object_init(return_value); +#endif + grpc_call_details_init(&details); grpc_metadata_array_init(&metadata); error_code = @@ -146,23 +194,48 @@ PHP_METHOD(Server, requestCall) { goto cleanup; } event = grpc_completion_queue_pluck(completion_queue, NULL, - gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + gpr_inf_future(GPR_CLOCK_REALTIME), + NULL); if (!event.success) { zend_throw_exception(spl_ce_LogicException, "Failed to request a call for some reason", 1 TSRMLS_CC); goto cleanup; } +#if PHP_MAJOR_VERSION < 7 add_property_zval(result, "call", grpc_php_wrap_call(call, true TSRMLS_CC)); add_property_string(result, "method", details.method, true); add_property_string(result, "host", details.host, true); add_property_zval(result, "absolute_deadline", grpc_php_wrap_timeval(details.deadline TSRMLS_CC)); - add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata TSRMLS_CC)); + add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata + TSRMLS_CC)); + cleanup: grpc_call_details_destroy(&details); grpc_metadata_array_destroy(&metadata); RETURN_DESTROY_ZVAL(result); + +#else + + zval zv_call; + zval zv_timeval; + zval zv_md; + grpc_php_wrap_call(call, true, &zv_call); + grpc_php_wrap_timeval(details.deadline, &zv_timeval); + grpc_parse_metadata_array(&metadata, &zv_md); + + add_property_zval(return_value, "call", &zv_call); + add_property_string(return_value, "method", details.method); + add_property_string(return_value, "host", details.host); + add_property_zval(return_value, "absolute_deadline", &zv_timeval); + add_property_zval(return_value, "metadata", &zv_md); + + cleanup: + grpc_call_details_destroy(&details); + grpc_metadata_array_destroy(&metadata); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -171,13 +244,19 @@ PHP_METHOD(Server, requestCall) { * @return true on success, false on failure */ PHP_METHOD(Server, addHttp2Port) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; +#if PHP_MAJOR_VERSION < 7 int addr_len; + wrapped_grpc_server *server = + (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + size_t addr_len; + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif + /* "s" == 1 string */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) + == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "add_http2_port expects a string", 1 TSRMLS_CC); return; @@ -186,11 +265,17 @@ PHP_METHOD(Server, addHttp2Port) { } PHP_METHOD(Server, addSecureHttp2Port) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; - int addr_len; zval *creds_obj; +#if PHP_MAJOR_VERSION < 7 + int addr_len; + wrapped_grpc_server *server = + (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + size_t addr_len; + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif + /* "sO" == 1 string, 1 object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO", &addr, &addr_len, &creds_obj, grpc_ce_server_credentials) == @@ -200,9 +285,14 @@ PHP_METHOD(Server, addSecureHttp2Port) { "add_http2_port expects a string and a ServerCredentials", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_server_credentials *creds = (wrapped_grpc_server_credentials *)zend_object_store_get_object( creds_obj TSRMLS_CC); +#else + wrapped_grpc_server_credentials *creds = + Z_WRAPPED_GRPC_SERVER_CREDS_P(creds_obj); +#endif RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr, creds->wrapped)); } @@ -212,21 +302,33 @@ PHP_METHOD(Server, addSecureHttp2Port) { * @return Void */ PHP_METHOD(Server, start) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif grpc_server_start(server->wrapped); } static zend_function_entry server_methods[] = { - PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; + PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_server(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Server", server_methods); ce.create_object = create_wrapped_grpc_server; grpc_ce_server = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&server_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + server_ce_handlers.offset = XtOffsetOf(wrapped_grpc_server, std); + server_ce_handlers.free_obj = free_wrapped_grpc_server; +#endif } diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h index 022257f37c3e5..a7df456a11154 100755 --- a/src/php/ext/grpc/server.h +++ b/src/php/ext/grpc/server.h @@ -48,13 +48,33 @@ /* Class entry for the Server PHP class */ extern zend_class_entry *grpc_ce_server; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_server that can be associated with a PHP object */ typedef struct wrapped_grpc_server { zend_object std; + grpc_server *wrapped; +} wrapped_grpc_server; +#else + +/* Wrapper struct for grpc_server that can be associated with a PHP object */ +typedef struct wrapped_grpc_server { grpc_server *wrapped; + zend_object std; } wrapped_grpc_server; +static inline wrapped_grpc_server +*wrapped_grpc_server_from_obj(zend_object *obj) { + return (wrapped_grpc_server*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_server, std)); +} + +#define Z_WRAPPED_GRPC_SERVER_P(zv) \ + wrapped_grpc_server_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the Server class */ void grpc_init_server(TSRMLS_D); diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index 505da10a28288..962b5bc0833bc 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -51,6 +51,8 @@ zend_class_entry *grpc_ce_server_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instace of wrapped_grpc_server_credentials */ void free_wrapped_grpc_server_credentials(void *object TSRMLS_DC) { wrapped_grpc_server_credentials *creds = @@ -58,6 +60,7 @@ void free_wrapped_grpc_server_credentials(void *object TSRMLS_DC) { if (creds->wrapped != NULL) { grpc_server_credentials_release(creds->wrapped); } + zend_object_std_dtor(&creds->std TSRMLS_CC); efree(creds); } @@ -92,6 +95,43 @@ zval *grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped TSRMLS_D return server_credentials_object; } +#else + +static zend_object_handlers server_credentials_ce_handlers; + +/* Frees and destroys an instace of wrapped_grpc_server_credentials */ +static void free_wrapped_grpc_server_credentials(zend_object *object) { + wrapped_grpc_server_credentials *creds = + wrapped_grpc_server_creds_from_obj(object); + if (creds->wrapped != NULL) { + grpc_server_credentials_release(creds->wrapped); + } + zend_object_std_dtor(&creds->std); +} + +/* Initializes an instace of wrapped_grpc_server_credentials to be associated + * with an object of a class specified by class_type */ +zend_object *create_wrapped_grpc_server_credentials(zend_class_entry + *class_type) { + wrapped_grpc_server_credentials *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_server_credentials) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &server_credentials_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped, + zval *server_credentials_object) { + object_init_ex(server_credentials_object, grpc_ce_server_credentials); + wrapped_grpc_server_credentials *server_credentials = + Z_WRAPPED_GRPC_SERVER_CREDS_P(server_credentials_object); + server_credentials->wrapped = wrapped; +} + +#endif + /** * Create SSL credentials. * @param string pem_root_certs PEM encoding of the server root certificates @@ -103,7 +143,11 @@ PHP_METHOD(ServerCredentials, createSsl) { char *pem_root_certs = 0; grpc_ssl_pem_key_cert_pair pem_key_cert_pair; +#if PHP_MAJOR_VERSION < 7 int root_certs_length = 0, private_key_length, cert_chain_length; +#else + size_t root_certs_length = 0, private_key_length, cert_chain_length; +#endif /* "s!ss" == 1 nullable string, 2 strings */ /* TODO: support multiple key cert pairs. */ @@ -120,17 +164,33 @@ PHP_METHOD(ServerCredentials, createSsl) { grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex( pem_root_certs, &pem_key_cert_pair, 1, GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_server_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } static zend_function_entry server_credentials_methods[] = { - PHP_ME(ServerCredentials, createSsl, NULL, - ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; + PHP_ME(ServerCredentials, createSsl, NULL, + ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END + }; void grpc_init_server_credentials(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\ServerCredentials", server_credentials_methods); ce.create_object = create_wrapped_grpc_server_credentials; grpc_ce_server_credentials = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&server_credentials_ce_handlers, + zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + server_credentials_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_server_credentials, std); + server_credentials_ce_handlers.free_obj = + free_wrapped_grpc_server_credentials; +#endif } diff --git a/src/php/ext/grpc/server_credentials.h b/src/php/ext/grpc/server_credentials.h index 7101d650008af..d37fafc0dc08b 100755 --- a/src/php/ext/grpc/server_credentials.h +++ b/src/php/ext/grpc/server_credentials.h @@ -49,14 +49,34 @@ /* Class entry for the Server_Credentials PHP class */ extern zend_class_entry *grpc_ce_server_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_server_credentials that can be associated with a PHP * object */ typedef struct wrapped_grpc_server_credentials { zend_object std; + grpc_server_credentials *wrapped; +} wrapped_grpc_server_credentials; +#else + +typedef struct wrapped_grpc_server_credentials { grpc_server_credentials *wrapped; + zend_object std; } wrapped_grpc_server_credentials; +static inline wrapped_grpc_server_credentials +*wrapped_grpc_server_creds_from_obj(zend_object *obj) { + return (wrapped_grpc_server_credentials*) + ((char*)(obj) - + XtOffsetOf(wrapped_grpc_server_credentials, std)); +} + +#define Z_WRAPPED_GRPC_SERVER_CREDS_P(zv) \ + wrapped_grpc_server_creds_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the Server_Credentials PHP class */ void grpc_init_server_credentials(TSRMLS_D); diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c index 5e242162a8cb6..b54b003535816 100644 --- a/src/php/ext/grpc/timeval.c +++ b/src/php/ext/grpc/timeval.c @@ -52,8 +52,14 @@ zend_class_entry *grpc_ce_timeval; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_call */ -void free_wrapped_grpc_timeval(void *object TSRMLS_DC) { efree(object); } +void free_wrapped_grpc_timeval(void *object TSRMLS_DC) { + wrapped_grpc_timeval *timeval = (wrapped_grpc_timeval *)object; + zend_object_std_dtor(&timeval->std TSRMLS_CC); + efree(timeval); +} /* Initializes an instance of wrapped_grpc_timeval to be associated with an * object of a class specified by class_type */ @@ -83,14 +89,50 @@ zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC) { return timeval_object; } +#else + +static zend_object_handlers timeval_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_call */ +static void free_wrapped_grpc_timeval(zend_object *object) { + wrapped_grpc_timeval *timeval = wrapped_grpc_timeval_from_obj(object); + zend_object_std_dtor(&timeval->std); +} + +/* Initializes an instance of wrapped_grpc_timeval to be associated with an + * object of a class specified by class_type */ +zend_object *create_wrapped_grpc_timeval(zend_class_entry *class_type) { + wrapped_grpc_timeval *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_timeval) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &timeval_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_timeval(gpr_timespec wrapped, zval *timeval_object) { + object_init_ex(timeval_object, grpc_ce_timeval); + wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(timeval_object); + memcpy(&timeval->wrapped, &wrapped, sizeof(gpr_timespec)); +} + +#endif + /** * Constructs a new instance of the Timeval class * @param long $usec The number of microseconds in the interval */ PHP_METHOD(Timeval, __construct) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *timeval = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); long microseconds; +#else + wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + zend_long microseconds; +#endif + /* "l" == 1 long */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", µseconds) == FAILURE) { @@ -110,6 +152,7 @@ PHP_METHOD(Timeval, __construct) { */ PHP_METHOD(Timeval, add) { zval *other_obj; + /* "O" == 1 Object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &other_obj, grpc_ce_timeval) == FAILURE) { @@ -117,6 +160,7 @@ PHP_METHOD(Timeval, add) { "add expects a Timeval", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *self = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); wrapped_grpc_timeval *other = @@ -124,6 +168,14 @@ PHP_METHOD(Timeval, add) { zval *sum = grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) TSRMLS_CC); RETURN_DESTROY_ZVAL(sum); +#else + wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); + + grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped), + return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -134,6 +186,7 @@ PHP_METHOD(Timeval, add) { */ PHP_METHOD(Timeval, subtract) { zval *other_obj; + /* "O" == 1 Object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &other_obj, grpc_ce_timeval) == FAILURE) { @@ -141,6 +194,7 @@ PHP_METHOD(Timeval, subtract) { "subtract expects a Timeval", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *self = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); wrapped_grpc_timeval *other = @@ -148,6 +202,13 @@ PHP_METHOD(Timeval, subtract) { zval *diff = grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) TSRMLS_CC); RETURN_DESTROY_ZVAL(diff); +#else + wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); + grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped), + return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -158,7 +219,9 @@ PHP_METHOD(Timeval, subtract) { * @return long */ PHP_METHOD(Timeval, compare) { - zval *a_obj, *b_obj; + zval *a_obj; + zval *b_obj; + /* "OO" == 2 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &a_obj, grpc_ce_timeval, &b_obj, @@ -167,10 +230,15 @@ PHP_METHOD(Timeval, compare) { "compare expects two Timevals", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *a = (wrapped_grpc_timeval *)zend_object_store_get_object(a_obj TSRMLS_CC); wrapped_grpc_timeval *b = (wrapped_grpc_timeval *)zend_object_store_get_object(b_obj TSRMLS_CC); +#else + wrapped_grpc_timeval *a = Z_WRAPPED_GRPC_TIMEVAL_P(a_obj); + wrapped_grpc_timeval *b = Z_WRAPPED_GRPC_TIMEVAL_P(b_obj); +#endif long result = gpr_time_cmp(a->wrapped, b->wrapped); RETURN_LONG(result); } @@ -183,7 +251,10 @@ PHP_METHOD(Timeval, compare) { * @return bool True if $a and $b are within $threshold, False otherwise */ PHP_METHOD(Timeval, similar) { - zval *a_obj, *b_obj, *thresh_obj; + zval *a_obj; + zval *b_obj; + zval *thresh_obj; + /* "OOO" == 3 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OOO", &a_obj, grpc_ce_timeval, &b_obj, grpc_ce_timeval, @@ -192,6 +263,7 @@ PHP_METHOD(Timeval, similar) { "compare expects three Timevals", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *a = (wrapped_grpc_timeval *)zend_object_store_get_object(a_obj TSRMLS_CC); wrapped_grpc_timeval *b = @@ -199,6 +271,11 @@ PHP_METHOD(Timeval, similar) { wrapped_grpc_timeval *thresh = (wrapped_grpc_timeval *)zend_object_store_get_object( thresh_obj TSRMLS_CC); +#else + wrapped_grpc_timeval *a = Z_WRAPPED_GRPC_TIMEVAL_P(a_obj); + wrapped_grpc_timeval *b = Z_WRAPPED_GRPC_TIMEVAL_P(b_obj); + wrapped_grpc_timeval *thresh = Z_WRAPPED_GRPC_TIMEVAL_P(thresh_obj); +#endif int result = gpr_time_similar(a->wrapped, b->wrapped, thresh->wrapped); RETURN_BOOL(result); } @@ -208,8 +285,13 @@ PHP_METHOD(Timeval, similar) { * @return Timeval The current time */ PHP_METHOD(Timeval, now) { +#if PHP_MAJOR_VERSION < 7 zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(now); +#else + grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME), return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -217,11 +299,18 @@ PHP_METHOD(Timeval, now) { * @return Timeval Zero length time interval */ PHP_METHOD(Timeval, zero) { +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_timeval_zero = grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_ZVAL(grpc_php_timeval_zero, false, /* Copy original before returning? */ true /* Destroy original before returning */); +#else + grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME), return_value); + RETURN_ZVAL(return_value, + false, /* Copy original before returning? */ + true /* Destroy original before returning */); +#endif } /** @@ -229,9 +318,14 @@ PHP_METHOD(Timeval, zero) { * @return Timeval Infinite future time value */ PHP_METHOD(Timeval, infFuture) { +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_timeval_inf_future = grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future); +#else + grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME), return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -239,9 +333,14 @@ PHP_METHOD(Timeval, infFuture) { * @return Timeval Infinite past time value */ PHP_METHOD(Timeval, infPast) { +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_timeval_inf_past = grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past); +#else + grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME), return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -249,28 +348,41 @@ PHP_METHOD(Timeval, infPast) { * @return void */ PHP_METHOD(Timeval, sleepUntil) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *this = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_timeval *this = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); +#endif gpr_sleep_until(this->wrapped); } static zend_function_entry timeval_methods[] = { - PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; + PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; void grpc_init_timeval(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Timeval", timeval_methods); ce.create_object = create_wrapped_grpc_timeval; grpc_ce_timeval = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&timeval_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + timeval_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_timeval, std); + timeval_ce_handlers.free_obj = free_wrapped_grpc_timeval; +#endif } void grpc_shutdown_timeval(TSRMLS_D) {} diff --git a/src/php/ext/grpc/timeval.h b/src/php/ext/grpc/timeval.h index 7456eb6d58ca8..d4eb2facde923 100755 --- a/src/php/ext/grpc/timeval.h +++ b/src/php/ext/grpc/timeval.h @@ -50,12 +50,31 @@ extern zend_class_entry *grpc_ce_timeval; /* Wrapper struct for timeval that can be associated with a PHP object */ +#if PHP_MAJOR_VERSION < 7 + typedef struct wrapped_grpc_timeval { zend_object std; + gpr_timespec wrapped; +} wrapped_grpc_timeval; +#else + +typedef struct wrapped_grpc_timeval { gpr_timespec wrapped; + zend_object std; } wrapped_grpc_timeval; +static inline wrapped_grpc_timeval +*wrapped_grpc_timeval_from_obj(zend_object *obj) { + return (wrapped_grpc_timeval*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_timeval, std)); +} + +#define Z_WRAPPED_GRPC_TIMEVAL_P(zv) \ + wrapped_grpc_timeval_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initialize the Timeval PHP class */ void grpc_init_timeval(TSRMLS_D); @@ -63,6 +82,10 @@ void grpc_init_timeval(TSRMLS_D); void grpc_shutdown_timeval(TSRMLS_D); /* Creates a Timeval object that wraps the given timeval struct */ +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC); +#else +void grpc_php_wrap_timeval(gpr_timespec wrapped, zval *timeval_object); +#endif /* PHP_MAJOR_VERSION */ #endif /* NET_GRPC_PHP_GRPC_TIMEVAL_H_ */ diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php old mode 100755 new mode 100644 index df3fe85d447fc..2fec1bd9cc44a --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -84,8 +84,8 @@ public function __construct($hostname, $opts, $channel = null) } if ($channel) { if (!is_a($channel, 'Channel')) { - throw new \Exception("The channel argument is not a". - "Channel object"); + throw new \Exception('The channel argument is not a'. + 'Channel object'); } $this->channel = $channel; } else { diff --git a/src/php/lib/Grpc/BidiStreamingCall.php b/src/php/lib/Grpc/BidiStreamingCall.php index 95e51c5088daf..c2fdb94b8673d 100644 --- a/src/php/lib/Grpc/BidiStreamingCall.php +++ b/src/php/lib/Grpc/BidiStreamingCall.php @@ -113,6 +113,7 @@ public function getStatus() ]); $this->trailing_metadata = $status_event->status->metadata; + return $status_event->status; } } diff --git a/src/php/lib/Grpc/ClientStreamingCall.php b/src/php/lib/Grpc/ClientStreamingCall.php index 315a406735feb..4050f7ed06d84 100644 --- a/src/php/lib/Grpc/ClientStreamingCall.php +++ b/src/php/lib/Grpc/ClientStreamingCall.php @@ -88,6 +88,7 @@ public function wait() $status = $event->status; $this->trailing_metadata = $status->metadata; + return [$this->deserializeResponse($event->message), $status]; } } diff --git a/src/php/lib/Grpc/ServerStreamingCall.php b/src/php/lib/Grpc/ServerStreamingCall.php index 53599fe4ae841..ba89d9f97216c 100644 --- a/src/php/lib/Grpc/ServerStreamingCall.php +++ b/src/php/lib/Grpc/ServerStreamingCall.php @@ -92,6 +92,7 @@ public function getStatus() ]); $this->trailing_metadata = $status_event->status->metadata; + return $status_event->status; } } diff --git a/src/php/lib/Grpc/UnaryCall.php b/src/php/lib/Grpc/UnaryCall.php index b114b771b8436..a71b05dc93dd3 100644 --- a/src/php/lib/Grpc/UnaryCall.php +++ b/src/php/lib/Grpc/UnaryCall.php @@ -77,6 +77,7 @@ public function wait() $status = $event->status; $this->trailing_metadata = $status->metadata; + return [$this->deserializeResponse($event->message), $status]; } } diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php old mode 100755 new mode 100644 index fa026f0935097..087d295ee0c87 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -50,6 +50,18 @@ public function setUp() Grpc\Timeval::infFuture()); } + public function tearDown() + { + unset($this->call); + unset($this->channel); + } + + public function testConstructor() + { + $this->assertSame('Grpc\Call', get_class($this->call)); + $this->assertObjectHasAttribute('channel', $this->call); + } + public function testAddEmptyMetadata() { $batch = [ @@ -89,6 +101,7 @@ public function testAddSingleAndMultiValueMetadata() public function testGetPeer() { + $this->assertStringStartsWith('localhost:', $this->call->getPeer()); $this->assertTrue(is_string($this->call->getPeer())); } @@ -118,4 +131,38 @@ public function testInvalidMetadataInnerValue() ]; $result = $this->call->startBatch($batch); } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstuctor() + { + $this->call = new Grpc\Call(); + $this->assertNull($this->call); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstuctor2() + { + $this->call = new Grpc\Call('hi', 'hi', 'hi'); + $this->assertNull($this->call); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidSetCredentials() + { + $this->call->setCredentials('hi'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidSetCredentials2() + { + $this->call->setCredentials([]); + } } diff --git a/src/php/tests/unit_tests/ChannelCredentialsTest.php b/src/php/tests/unit_tests/ChannelCredentialsTest.php index 56c1d8f006de6..11779efaa15a4 100644 --- a/src/php/tests/unit_tests/ChannelCredentialsTest.php +++ b/src/php/tests/unit_tests/ChannelCredentialsTest.php @@ -42,10 +42,22 @@ public function tearDown() { } - public function testCreateDefault() + public function testCreateSslWith3Null() { - $channel_credentials = Grpc\ChannelCredentials::createDefault(); - $this->assertSame('Grpc\ChannelCredentials', get_class($channel_credentials)); + $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); + $this->assertNotNull($channel_credentials); + } + + public function testCreateSslWith3NullString() + { + $channel_credentials = Grpc\ChannelCredentials::createSsl('', '', ''); + $this->assertNotNull($channel_credentials); + } + + public function testCreateInsecure() + { + $channel_credentials = Grpc\ChannelCredentials::createInsecure(); + $this->assertNull($channel_credentials); } /** @@ -64,10 +76,4 @@ public function testInvalidCreateComposite() $channel_credentials = Grpc\ChannelCredentials::createComposite( 'something', 'something'); } - - public function testCreateInsecure() - { - $channel_credentials = Grpc\ChannelCredentials::createInsecure(); - $this->assertNull($channel_credentials); - } } diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php index a1f9053c3989b..bf8540a44db1f 100644 --- a/src/php/tests/unit_tests/ChannelTest.php +++ b/src/php/tests/unit_tests/ChannelTest.php @@ -40,6 +40,7 @@ public function setUp() public function tearDown() { + unset($this->channel); } public function testInsecureCredentials() @@ -53,6 +54,82 @@ public function testInsecureCredentials() $this->assertSame('Grpc\Channel', get_class($this->channel)); } + public function testGetConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithInt() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(123); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithString() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState('hello'); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithBool() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(true); + $this->assertEquals(0, $state); + } + + public function testGetTarget() + { + $this->channel = new Grpc\Channel('localhost:8888', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $target = $this->channel->getTarget(); + $this->assertSame('localhost:8888', $target); + } + + public function testWatchConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $time = new Grpc\Timeval(1000); + $state = $this->channel->watchConnectivityState(123, $time); + $this->assertTrue($state); + unset($time); + } + + public function testClose() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->assertNotNull($this->channel); + $this->channel->close(); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstructorWithNull() + { + $this->channel = new Grpc\Channel(); + $this->assertNull($this->channel); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstructorWith() + { + $this->channel = new Grpc\Channel('localhost', 'invalid'); + $this->assertNull($this->channel); + } + /** * @expectedException InvalidArgumentException */ @@ -78,4 +155,34 @@ public function testInvalidOptionsArray() ] ); } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidGetConnectivityStateWithArray() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->getConnectivityState([]); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidWatchConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->watchConnectivityState([]); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidWatchConnectivityState2() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->watchConnectivityState(1, 'hi'); + } } diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php old mode 100755 new mode 100644 diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php old mode 100755 new mode 100644 diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php index 76aaa069704b6..6dd607a533c92 100644 --- a/src/php/tests/unit_tests/ServerTest.php +++ b/src/php/tests/unit_tests/ServerTest.php @@ -36,27 +36,145 @@ class ServerTest extends PHPUnit_Framework_TestCase { public function setUp() { + $this->server = null; } public function tearDown() { + unset($this->server); } + public function testConstructorWithNull() + { + $this->server = new Grpc\Server(); + $this->assertNotNull($this->server); + } + + public function testConstructorWithNullArray() + { + $this->server = new Grpc\Server([]); + $this->assertNotNull($this->server); + } + + public function testConstructorWithArray() + { + // key of array must be string + $this->server = new Grpc\Server(['ip' => '127.0.0.1', + 'port' => '8080', ]); + $this->assertNotNull($this->server); + } + + public function testRequestCall() + { + $this->server = new Grpc\Server(); + $port = $this->server->addHttp2Port('0.0.0.0:8888'); + $this->server->start(); + $channel = new Grpc\Channel('localhost:8888', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + + $deadline = Grpc\Timeval::infFuture(); + $call = new Grpc\Call($channel, 'dummy_method', $deadline); + + $event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, ]); + + $c = $this->server->requestCall(); + $this->assertObjectHasAttribute('call', $c); + $this->assertObjectHasAttribute('method', $c); + $this->assertSame('dummy_method', $c->method); + $this->assertObjectHasAttribute('host', $c); + $this->assertSame('localhost:8888', $c->host); + $this->assertObjectHasAttribute('absolute_deadline', $c); + $this->assertObjectHasAttribute('metadata', $c); + + unset($call); + unset($channel); + } + + private function createSslObj() + { + $server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); + + return $server_credentials; + } +/* + //TODO(thinkerou): make cases of addHttp2Port right + public function testAddHttp2Port() + { + $this->server = new Grpc\Server(); + $port = $this->server->addHttp2Port('127.0.0.1:8080'); + $this->assertEquals(8080, $port); + } + + public function testAddHttp2Port1() + { + $this->server = new Grpc\Server([]); + $port = $this->server->addHttp2Port('127.0.0.1:8080'); + $this->assertEquals(8080, $port); + } + + public function testAddHttp2Port2() + { + $this->server = new Grpc\Server(['ip' => '127.0.0.1', + 'port' => '8888', ]); + $port = $this->server->addHttp2Port('127.0.0.1:8080'); + $this->assertEquals(8080, $port); + } + + public function testAddSecureHttp2Port() + { + $this->server = new Grpc\Server(); + $cred = $this->createSslObj(); + $port = $this->server->addSecureHttp2Port('127.0.0.1:8080', $cred); + $this->assertEquals(8080, $port); + } + + public function testAddSecureHttp2Port1() + { + $this->server = new Grpc\Server([]); + $cred = $this->createSslObj(); + $port = $this->server->addSecureHttp2Port('127.0.0.1:8080', $cred); + $this->assertEquals(8080, $port); + } + + public function testAddSecureHttp2Port2() + { + $this->server = new Grpc\Server(['ip' => '127.0.0.1', + 'port' => '8888', ]); + $cred = $this->createSslObj(); + $port = $this->server->addSecureHttp2Port('127.0.0.1:8080', $cred); + $this->assertEquals(8080, $port); + } +*/ /** * @expectedException InvalidArgumentException */ public function testInvalidConstructor() { - $server = new Grpc\Server('invalid_host'); + $this->server = new Grpc\Server('invalid_host'); + $this->assertNull($this->server); } + /** + * @expectedException InvalidArgumentException + */ +/* public function testInvalidConstructor2() + { + //TODO(thinkerou): it crash when key is long on php7 + $this->server = new Grpc\server(['0.0.0.0:0']); + $this->assertNull($this->server); + } +*/ /** * @expectedException InvalidArgumentException */ public function testInvalidAddHttp2Port() { $this->server = new Grpc\Server([]); - $this->port = $this->server->addHttp2Port(['0.0.0.0:0']); + $port = $this->server->addHttp2Port(['0.0.0.0:0']); } /** @@ -65,6 +183,24 @@ public function testInvalidAddHttp2Port() public function testInvalidAddSecureHttp2Port() { $this->server = new Grpc\Server([]); - $this->port = $this->server->addSecureHttp2Port(['0.0.0.0:0']); + $port = $this->server->addSecureHttp2Port(['0.0.0.0:0']); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidAddSecureHttp2Port2() + { + $this->server = new Grpc\Server(); + $port = $this->server->addSecureHttp2Port('0.0.0.0:0'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidAddSecureHttp2Port3() + { + $this->server = new Grpc\Server(); + $port = $this->server->addSecureHttp2Port('0.0.0.0:0', 'invalid'); } } diff --git a/src/php/tests/unit_tests/TimevalTest.php b/src/php/tests/unit_tests/TimevalTest.php old mode 100755 new mode 100644 index a3dbce079f470..2d19f64c79990 --- a/src/php/tests/unit_tests/TimevalTest.php +++ b/src/php/tests/unit_tests/TimevalTest.php @@ -33,6 +33,57 @@ */ class TimevalTest extends PHPUnit_Framework_TestCase { + public function setUp() + { + } + + public function tearDown() + { + unset($this->time); + } + + public function testConstructorWithInt() + { + $this->time = new Grpc\Timeval(1234); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithNegative() + { + $this->time = new Grpc\Timeval(-123); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithZero() + { + $this->time = new Grpc\Timeval(0); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithOct() + { + $this->time = new Grpc\Timeval(0123); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithHex() + { + $this->time = new Grpc\Timeval(0x1A); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithFloat() + { + $this->time = new Grpc\Timeval(123.456); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + public function testCompareSame() { $zero = Grpc\Timeval::zero(); @@ -70,6 +121,7 @@ public function testNowIsBetweenZeroAndFuture() public function testNowAndAdd() { $now = Grpc\Timeval::now(); + $this->assertNotNull($now); $delta = new Grpc\Timeval(1000); $deadline = $now->add($delta); $this->assertGreaterThan(0, Grpc\Timeval::compare($deadline, $now)); @@ -154,5 +206,6 @@ public function testCompareInvalidParam() public function testSimilarInvalidParam() { $a = Grpc\Timeval::similar(1000, 1100, 1200); + $this->assertNull($delta); } } From b3ce178b28ebb842408f8cdc5b116816a0171095 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 20 Jul 2016 09:25:25 -0700 Subject: [PATCH 116/151] clang-format --- .../chttp2/client/insecure/channel_create.c | 9 ++++---- .../client/secure/secure_channel_create.c | 22 +++++++++---------- .../chttp2/server/insecure/server_chttp2.c | 6 ++--- .../server/secure/server_secure_chttp2.c | 4 ++-- src/core/lib/channel/handshaker.c | 14 +++++------- src/core/lib/channel/handshaker.h | 11 ++++------ 6 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 154c4493ffc10..162cc6bd6abac 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -88,7 +88,7 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { connector *c = user_data; c->result->transport = grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); @@ -114,10 +114,9 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); } else { - grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, - c->args.channel_args, - c->args.deadline, on_handshake_done, - c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, + c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 4554c33c8c64d..dde35f253dd62 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -74,7 +74,7 @@ typedef struct { grpc_handshake_manager *handshake_mgr; // TODO(roth): Remove once we eliminate on_secure_handshake_done(). - grpc_channel_args* tmp_args; + grpc_channel_args *tmp_args; } connector; static void connector_ref(grpc_connector *con) { @@ -117,8 +117,8 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); auth_context_arg = grpc_auth_context_to_arg(auth_context); - c->result->channel_args = grpc_channel_args_copy_and_add( - c->tmp_args, &auth_context_arg, 1); + c->result->channel_args = + grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1); } grpc_closure *notify = c->notify; c->notify = NULL; @@ -126,7 +126,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { connector *c = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() @@ -140,10 +140,9 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, - c->connecting_endpoint, - c->args.channel_args, c->args.deadline, - on_handshake_done, c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, c->connecting_endpoint, c->args.channel_args, + c->args.deadline, on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -163,10 +162,9 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); } else { - grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, - c->args.channel_args, - c->args.deadline, on_handshake_done, - c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, + c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index 920875f694740..b8d816c1279cc 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -55,7 +55,7 @@ typedef struct server_connect_state { } server_connect_state; static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { server_connect_state *state = user_data; /* * Beware that the call to grpc_create_chttp2_transport() has to happen before @@ -64,8 +64,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, * (as in server_secure_chttp2.c) needs to add synchronization to avoid this * case. */ - grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, args, endpoint, 0); + grpc_transport *transport = + grpc_create_chttp2_transport(exec_ctx, args, endpoint, 0); grpc_server_setup_transport(exec_ctx, state->server, transport, state->accepting_pollset, grpc_server_get_channel_args(state->server)); diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index e3184bc1f937e..bc714f4e5bcbb 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -74,7 +74,7 @@ typedef struct server_secure_connect { // TODO(roth): Remove the following two fields when we eliminate // grpc_server_security_connector_do_handshake(). gpr_timespec deadline; - grpc_channel_args* args; + grpc_channel_args *args; } server_secure_connect; static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); } @@ -129,7 +129,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { server_secure_connect *state = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 7dcbe1df9cee9..9191ae6339573 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -129,8 +129,7 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, // handshakers together. static void call_next_handshaker(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, - grpc_channel_args* args, - void* user_data) { + grpc_channel_args* args, void* user_data) { grpc_handshake_manager* mgr = user_data; GPR_ASSERT(mgr->state != NULL); GPR_ASSERT(mgr->state->index < mgr->count); @@ -153,13 +152,10 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, } } -void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, - grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* args, - gpr_timespec deadline, - grpc_handshaker_done_cb cb, - void* user_data) { +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, const grpc_channel_args* args, + gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data) { grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 6a39529150a87..b8aa78c245403 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -131,12 +131,9 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, /// invoking the first handshaker. /// If successful, invokes \a cb with \a user_data after all handshakers /// have completed. -void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, - grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* args, - gpr_timespec deadline, - grpc_handshaker_done_cb cb, - void* user_data); +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, const grpc_channel_args* args, + gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 5682a52cee47d6bbdd71bf1426cd603b306cc2b7 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 20 Jul 2016 09:54:41 -0700 Subject: [PATCH 117/151] Add acceptor parameter. --- .../chttp2/client/insecure/channel_create.c | 2 +- .../chttp2/client/secure/secure_channel_create.c | 4 ++-- .../chttp2/server/insecure/server_chttp2.c | 3 ++- .../chttp2/server/secure/server_secure_chttp2.c | 2 +- src/core/lib/channel/handshaker.c | 13 +++++++++---- src/core/lib/channel/handshaker.h | 12 +++++++++--- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 162cc6bd6abac..645a011748db3 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -116,7 +116,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { } else { grpc_handshake_manager_do_handshake( exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, - c->args.deadline, on_handshake_done, c); + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index dde35f253dd62..01d949add3a82 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -142,7 +142,7 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, connector *c = arg; grpc_handshake_manager_do_handshake( exec_ctx, c->handshake_mgr, c->connecting_endpoint, c->args.channel_args, - c->args.deadline, on_handshake_done, c); + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -164,7 +164,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { } else { grpc_handshake_manager_do_handshake( exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, - c->args.deadline, on_handshake_done, c); + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index b8d816c1279cc..8dac63c33bc74 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -90,7 +90,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(server), - deadline, on_handshake_done, state); + deadline, acceptor, on_handshake_done, + state); } /* Server callback: start listening on our ports */ diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index bc714f4e5bcbb..2b25fa09e6446 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -158,7 +158,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, grpc_handshake_manager_do_handshake( exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(state->state->server), state->deadline, - on_handshake_done, state); + acceptor, on_handshake_done, state); } /* Server callback: start listening on our ports */ diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 9191ae6339573..9db04440ee8c7 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -63,9 +63,10 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, gpr_timespec deadline, + grpc_tcp_server_acceptor *acceptor, grpc_handshaker_done_cb cb, void* user_data) { handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, - deadline, cb, user_data); + deadline, acceptor, cb, user_data); } // @@ -78,6 +79,8 @@ struct grpc_handshaker_state { size_t index; // The deadline for all handshakers. gpr_timespec deadline; + // The acceptor to call the handshakers with. + grpc_tcp_server_acceptor *acceptor; // The final callback and user_data to invoke after the last handshaker. grpc_handshaker_done_cb final_cb; void* final_user_data; @@ -142,8 +145,8 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, } // Invoke handshaker. grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], - endpoint, args, mgr->state->deadline, cb, - user_data); + endpoint, args, mgr->state->deadline, + mgr->state->acceptor, cb, user_data); ++mgr->state->index; // If this is the last handshaker, clean up state. if (mgr->state->index == mgr->count) { @@ -155,7 +158,8 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void grpc_handshake_manager_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, const grpc_channel_args* args, - gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data) { + gpr_timespec deadline, grpc_tcp_server_acceptor *acceptor, + grpc_handshaker_done_cb cb, void* user_data) { grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done @@ -166,6 +170,7 @@ void grpc_handshake_manager_do_handshake( mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); memset(mgr->state, 0, sizeof(*mgr->state)); mgr->state->deadline = deadline; + mgr->state->acceptor = acceptor; mgr->state->final_cb = cb; mgr->state->final_user_data = user_data; call_next_handshaker(exec_ctx, endpoint, args_copy, mgr); diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index b8aa78c245403..b1e91dba4f267 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -40,6 +40,7 @@ #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/tcp_server.h" /// Handshakers are used to perform initial handshakes on a connection /// before the client sends the initial request. Some examples of what @@ -71,10 +72,12 @@ struct grpc_handshaker_vtable { /// Performs handshaking. When finished, calls \a cb with \a user_data. /// Takes ownership of \a args. + /// \a acceptor will be NULL for client-side handshakers. void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, grpc_channel_args* args, - gpr_timespec deadline, grpc_handshaker_done_cb cb, - void* user_data); + gpr_timespec deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data); }; /// Base struct. To subclass, make this the first member of the @@ -99,6 +102,7 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, gpr_timespec deadline, + grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data); /// @@ -129,11 +133,13 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, /// Invokes handshakers in the order they were added. /// Does NOT take ownership of \a args. Instead, makes a copy before /// invoking the first handshaker. +/// \a acceptor will be NULL for client-side handshakers. /// If successful, invokes \a cb with \a user_data after all handshakers /// have completed. void grpc_handshake_manager_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, const grpc_channel_args* args, - gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data); + gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 0b84add2818028cfc881358c6f81bb4a5ac3d135 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 20 Jul 2016 10:08:48 -0700 Subject: [PATCH 118/151] Avoid allocating memory for each individual handshaker. Also fix memory leak. --- src/core/lib/channel/handshaker.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 9db04440ee8c7..ed8eb4a7f84f9 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -100,10 +100,24 @@ grpc_handshake_manager* grpc_handshake_manager_create() { return mgr; } +static bool is_power_of_2(size_t n) { + return (n & (n - 1)) == 0; +} + void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr) { - mgr->handshakers = gpr_realloc(mgr->handshakers, - (mgr->count + 1) * sizeof(grpc_handshaker*)); + // To avoid allocating memory for each handshaker we add, we double + // the number of elements every time we need more. + size_t realloc_count = 0; + if (mgr->count == 0) { + realloc_count = 2; + } else if (mgr->count >= 2 && is_power_of_2(mgr->count)) { + realloc_count = mgr->count * 2; + } + if (realloc_count > 0) { + mgr->handshakers = gpr_realloc(mgr->handshakers, + realloc_count * sizeof(grpc_handshaker*)); + } mgr->handshakers[mgr->count++] = handshaker; } @@ -112,6 +126,7 @@ void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, for (size_t i = 0; i < mgr->count; ++i) { grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); } + gpr_free(mgr->handshakers); gpr_free(mgr); } From bae0cf17065332220519fdd711aee6634bc999b4 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 20 Jul 2016 14:02:33 -0700 Subject: [PATCH 119/151] minor changes. cannot assume hostname unchanged --- src/php/ext/grpc/channel.c | 3 +- src/php/tests/unit_tests/CallTest.php | 1 - src/php/tests/unit_tests/ChannelTest.php | 2 +- src/php/tests/unit_tests/ServerTest.php | 60 +----------------------- 4 files changed, 4 insertions(+), 62 deletions(-) diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index ce96457c7c38f..6737e340f91af 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -86,7 +86,8 @@ zend_object_value create_wrapped_grpc_channel(zend_class_entry *class_type return retval; } -void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_DC) { +void php_grpc_read_args_array(zval *args_array, + grpc_channel_args *args TSRMLS_DC) { HashTable *array_hash; HashPosition array_pointer; int args_index; diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index 087d295ee0c87..8c83772d4c701 100644 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -101,7 +101,6 @@ public function testAddSingleAndMultiValueMetadata() public function testGetPeer() { - $this->assertStringStartsWith('localhost:', $this->call->getPeer()); $this->assertTrue(is_string($this->call->getPeer())); } diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php index bf8540a44db1f..4b35b1a28cc00 100644 --- a/src/php/tests/unit_tests/ChannelTest.php +++ b/src/php/tests/unit_tests/ChannelTest.php @@ -91,7 +91,7 @@ public function testGetTarget() $this->channel = new Grpc\Channel('localhost:8888', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); $target = $this->channel->getTarget(); - $this->assertSame('localhost:8888', $target); + $this->assertTrue(is_string($target)); } public function testWatchConnectivityState() diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php index 6dd607a533c92..a806c72da72ef 100644 --- a/src/php/tests/unit_tests/ServerTest.php +++ b/src/php/tests/unit_tests/ServerTest.php @@ -83,7 +83,7 @@ public function testRequestCall() $this->assertObjectHasAttribute('method', $c); $this->assertSame('dummy_method', $c->method); $this->assertObjectHasAttribute('host', $c); - $this->assertSame('localhost:8888', $c->host); + $this->assertTrue(is_string($c->host)); $this->assertObjectHasAttribute('absolute_deadline', $c); $this->assertObjectHasAttribute('metadata', $c); @@ -100,55 +100,7 @@ private function createSslObj() return $server_credentials; } -/* - //TODO(thinkerou): make cases of addHttp2Port right - public function testAddHttp2Port() - { - $this->server = new Grpc\Server(); - $port = $this->server->addHttp2Port('127.0.0.1:8080'); - $this->assertEquals(8080, $port); - } - - public function testAddHttp2Port1() - { - $this->server = new Grpc\Server([]); - $port = $this->server->addHttp2Port('127.0.0.1:8080'); - $this->assertEquals(8080, $port); - } - - public function testAddHttp2Port2() - { - $this->server = new Grpc\Server(['ip' => '127.0.0.1', - 'port' => '8888', ]); - $port = $this->server->addHttp2Port('127.0.0.1:8080'); - $this->assertEquals(8080, $port); - } - public function testAddSecureHttp2Port() - { - $this->server = new Grpc\Server(); - $cred = $this->createSslObj(); - $port = $this->server->addSecureHttp2Port('127.0.0.1:8080', $cred); - $this->assertEquals(8080, $port); - } - - public function testAddSecureHttp2Port1() - { - $this->server = new Grpc\Server([]); - $cred = $this->createSslObj(); - $port = $this->server->addSecureHttp2Port('127.0.0.1:8080', $cred); - $this->assertEquals(8080, $port); - } - - public function testAddSecureHttp2Port2() - { - $this->server = new Grpc\Server(['ip' => '127.0.0.1', - 'port' => '8888', ]); - $cred = $this->createSslObj(); - $port = $this->server->addSecureHttp2Port('127.0.0.1:8080', $cred); - $this->assertEquals(8080, $port); - } -*/ /** * @expectedException InvalidArgumentException */ @@ -158,16 +110,6 @@ public function testInvalidConstructor() $this->assertNull($this->server); } - /** - * @expectedException InvalidArgumentException - */ -/* public function testInvalidConstructor2() - { - //TODO(thinkerou): it crash when key is long on php7 - $this->server = new Grpc\server(['0.0.0.0:0']); - $this->assertNull($this->server); - } -*/ /** * @expectedException InvalidArgumentException */ From 69c565bd60b1cc23f4d03ea8e56a250288d65a20 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 20 Jul 2016 14:21:35 -0700 Subject: [PATCH 120/151] wrap long lines; --- src/php/ext/grpc/channel_credentials.c | 3 ++- src/php/ext/grpc/server_credentials.c | 3 ++- src/php/ext/grpc/timeval.c | 6 ++++-- src/php/tests/unit_tests/CallCredentialsTest.php | 3 ++- src/php/tests/unit_tests/CallTest.php | 3 ++- src/php/tests/unit_tests/ChannelCredentialsTest.php | 3 ++- src/php/tests/unit_tests/EndToEndTest.php | 3 ++- src/php/tests/unit_tests/ServerTest.php | 3 ++- 8 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index 10e0acafac4af..16ba0368ebbcd 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -96,7 +96,8 @@ zend_object_value create_wrapped_grpc_channel_credentials( return retval; } -zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS_DC) { +zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials + *wrapped TSRMLS_DC) { zval *credentials_object; MAKE_STD_ZVAL(credentials_object); object_init_ex(credentials_object, grpc_ce_channel_credentials); diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index 962b5bc0833bc..296632d5bdd80 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -84,7 +84,8 @@ zend_object_value create_wrapped_grpc_server_credentials( return retval; } -zval *grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped TSRMLS_DC) { +zval *grpc_php_wrap_server_credentials(grpc_server_credentials + *wrapped TSRMLS_DC) { zval *server_credentials_object; MAKE_STD_ZVAL(server_credentials_object); object_init_ex(server_credentials_object, grpc_ce_server_credentials); diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c index b54b003535816..8dc997c2ddae3 100644 --- a/src/php/ext/grpc/timeval.c +++ b/src/php/ext/grpc/timeval.c @@ -166,7 +166,8 @@ PHP_METHOD(Timeval, add) { wrapped_grpc_timeval *other = (wrapped_grpc_timeval *)zend_object_store_get_object(other_obj TSRMLS_CC); zval *sum = - grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) TSRMLS_CC); + grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(sum); #else wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); @@ -200,7 +201,8 @@ PHP_METHOD(Timeval, subtract) { wrapped_grpc_timeval *other = (wrapped_grpc_timeval *)zend_object_store_get_object(other_obj TSRMLS_CC); zval *diff = - grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) TSRMLS_CC); + grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(diff); #else wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); diff --git a/src/php/tests/unit_tests/CallCredentialsTest.php b/src/php/tests/unit_tests/CallCredentialsTest.php index 5fec06cd13395..1994c8afe56e6 100644 --- a/src/php/tests/unit_tests/CallCredentialsTest.php +++ b/src/php/tests/unit_tests/CallCredentialsTest.php @@ -148,7 +148,8 @@ public function testCreateComposite() $this->call_credentials, $call_credentials2 ); - $this->assertSame('Grpc\CallCredentials', get_class($call_credentials3)); + $this->assertSame('Grpc\CallCredentials', + get_class($call_credentials3)); } /** diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index 8c83772d4c701..d736f5154605a 100644 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -93,7 +93,8 @@ public function testAddSingleAndMultiValueMetadata() { $batch = [ Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], - 'key2' => ['value2', 'value3'], ], + 'key2' => ['value2', + 'value3'], ], ]; $result = $this->call->startBatch($batch); $this->assertTrue($result->send_metadata); diff --git a/src/php/tests/unit_tests/ChannelCredentialsTest.php b/src/php/tests/unit_tests/ChannelCredentialsTest.php index 11779efaa15a4..e822929ccdaa8 100644 --- a/src/php/tests/unit_tests/ChannelCredentialsTest.php +++ b/src/php/tests/unit_tests/ChannelCredentialsTest.php @@ -44,7 +44,8 @@ public function tearDown() public function testCreateSslWith3Null() { - $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); + $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, + null); $this->assertNotNull($channel_credentials); } diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php index 2b09f9d112a3a..09364580c01c7 100644 --- a/src/php/tests/unit_tests/EndToEndTest.php +++ b/src/php/tests/unit_tests/EndToEndTest.php @@ -521,7 +521,8 @@ public function testGetTarget() public function testGetConnectivityState() { - $this->assertTrue($this->channel->getConnectivityState() == Grpc\CHANNEL_IDLE); + $this->assertTrue($this->channel->getConnectivityState() == + Grpc\CHANNEL_IDLE); } public function testWatchConnectivityStateFailed() diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php index a806c72da72ef..f2346ab113ee3 100644 --- a/src/php/tests/unit_tests/ServerTest.php +++ b/src/php/tests/unit_tests/ServerTest.php @@ -76,7 +76,8 @@ public function testRequestCall() $call = new Grpc\Call($channel, 'dummy_method', $deadline); $event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, ]); + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + ]); $c = $this->server->requestCall(); $this->assertObjectHasAttribute('call', $c); From 1c2268b453c03a711ef6534e632d4154df6b19ff Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 20 Jul 2016 14:56:07 -0700 Subject: [PATCH 121/151] Correct shell scripting mistake in node package generation code --- tools/run_tests/build_package_node.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/build_package_node.sh b/tools/run_tests/build_package_node.sh index ff4cfdb8bf975..ef4a10cca721b 100755 --- a/tools/run_tests/build_package_node.sh +++ b/tools/run_tests/build_package_node.sh @@ -61,7 +61,7 @@ mkdir -p $output_dir well_known_protos=( any api compiler/plugin descriptor duration empty field_mask source_context struct timestamp type wrappers ) for arch in {x86,x64}; do - case arch in + case $arch in x86) node_arch=ia32 ;; @@ -70,7 +70,7 @@ for arch in {x86,x64}; do ;; esac for plat in {windows,linux,macos}; do - case plat in + case $plat in windows) node_plat=win32 ;; From 9cb9445155804fb65af100b9747d467254fb7ca6 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Wed, 20 Jul 2016 16:39:31 -0700 Subject: [PATCH 122/151] Addressed review comments --- doc/command_line_tool.md | 29 +++++++++++++------ test/cpp/util/grpc_cli.cc | 13 +++++---- test/cpp/util/proto_file_parser.cc | 2 +- .../proto_reflection_descriptor_database.cc | 4 +-- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/doc/command_line_tool.md b/doc/command_line_tool.md index 89a70548b8b23..79a131c041a96 100644 --- a/doc/command_line_tool.md +++ b/doc/command_line_tool.md @@ -15,6 +15,7 @@ The command line tool can do the following things: - Send unary rpc. - Attach metadata and display received metadata. - Handle common authentication to server. +- Infer request/response types from server reflection result. - Find the request/response types from a given proto file. - Read proto request in text form. - Read request in wire form (for protobuf messages, this means serialized binary form). @@ -24,7 +25,6 @@ The command line tool can do the following things: The command line tool should support the following things: - List server services and methods through server reflection. -- Infer request/response types from server reflection result. - Fine-grained auth control (such as, use this oauth token to talk to the server). - Send streaming rpc. @@ -46,24 +46,35 @@ https://github.com/grpc/grpc/blob/master/test/cpp/util/grpc_cli.cc Send a rpc to a helloworld server at `localhost:50051`: ``` -$ bins/opt/grpc_cli call localhost:50051 SayHello examples/protos/helloworld.proto \ - "name: 'world'" --enable_ssl=false +$ bins/opt/grpc_cli call localhost:50051 SayHello "name: 'world'" \ + --enable_ssl=false ``` On success, the tool will print out ``` Rpc succeeded with OK status -Response: +Response: message: "Hello world" ``` The `localhost:50051` part indicates the server you are connecting to. `SayHello` is (part of) the -gRPC method string. Then there is the path to the proto file containing the service definition, -if it is not under current directory, you can use `--proto_path` to specify a new search root. -`"name: 'world'"` is the text format of the request proto message. -We are not using ssl here by `--enable_ssl=false`. For information on more -flags, look at the comments of `grpc_cli.cc`. +gRPC method string. Then `"name: 'world'"` is the text format of the request proto message. We are +not using ssl here by `--enable_ssl=false`. For information on more flags, look at the comments of `grpc_cli.cc`. + +### Use local proto files + +If the server does not have the server reflection service, you will need to provide local proto +files containing the service definition. The tool will try to find request/response types from +them. + +``` +$ bins/opt/grpc_cli call localhost:50051 SayHello "name: 'world'" \ + --protofiles=examples/protos/helloworld.proto --enable_ssl=false +``` + +If the proto files is not under current directory, you can use `--proto_path` to specify a new +search root. ### Send non-proto rpc diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index fdb1a7c2a0035..53529da782ce1 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -35,14 +35,14 @@ A command line tool to talk to a grpc server. Example of talking to grpc interop server: grpc_cli call localhost:50051 UnaryCall "response_size:10" \ - --proto_file=src/proto/grpc/testing/test.proto --enable_ssl=false + --protofiles=src/proto/grpc/testing/test.proto --enable_ssl=false Options: - 1. --proto_file, use this flag to provide a proto file if the server does + 1. --protofiles, use this flag to provide a proto file if the server does does not have the reflection service. 2. --proto_path, if your proto file is not under current working directory, use this flag to provide a search root. It should work similar to the - counterpart in protoc. This option is valid only when proto_file is + counterpart in protoc. This option is valid only when protofiles is provided. 3. --metadata specifies metadata to be sent to the server, such as: --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" @@ -90,7 +90,8 @@ DEFINE_string(output_binary_file, "", DEFINE_string(metadata, "", "Metadata to send to server, in the form of key1:val1:key2:val2"); DEFINE_string(proto_path, ".", "Path to look for the proto file."); -DEFINE_string(proto_file, "", "Name of the proto file."); +// TODO(zyc): support a list of input proto files +DEFINE_string(protofiles, "", "Name of the proto file."); void ParseMetadataFlag( std::multimap* client_metadata) { @@ -173,9 +174,9 @@ int main(int argc, char** argv) { } if (!request_text.empty()) { - if (!FLAGS_proto_file.empty()) { + if (!FLAGS_protofiles.empty()) { parser.reset(new grpc::testing::ProtoFileParser( - FLAGS_proto_path, FLAGS_proto_file, method_name)); + FLAGS_proto_path, FLAGS_protofiles, method_name)); } else { parser.reset(new grpc::testing::ProtoFileParser(channel, method_name)); } diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc index b1bf0471e159e..5b0d925e1c388 100644 --- a/test/cpp/util/proto_file_parser.cc +++ b/test/cpp/util/proto_file_parser.cc @@ -112,7 +112,7 @@ ProtoFileParser::ProtoFileParser(std::shared_ptr channel, LogError( "Failed to get services from the server, " "it may not have the reflection service.\n" - "Please try to use the --proto_file option to provide a proto file."); + "Please try to use the --protofiles option to provide a proto file."); } if (has_error_) { return; diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index 48998551a59d3..2d847012a22d9 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -54,8 +54,8 @@ ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( : stub_(ServerReflection::NewStub(channel)) {} ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { - if (!stream_) { - GetStream()->WritesDone(); + if (stream_) { + stream_->WritesDone(); Status status = stream_->Finish(); if (!status.ok()) { gpr_log(GPR_ERROR, From 6f7d4221afe463e176d9eaf75c83c0ca358e5f44 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Wed, 20 Jul 2016 17:16:07 -0700 Subject: [PATCH 123/151] Upgrade virtualenv pip in Python docgen Also ignore the docgen-generated directories under doc/. --- doc/.gitignore | 2 ++ tools/distrib/python/docgen.py | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 doc/.gitignore diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000000000..95464d3e664d8 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,2 @@ +build/ +src/ diff --git a/tools/distrib/python/docgen.py b/tools/distrib/python/docgen.py index f5e89f1da67ce..15bd8d855f694 100755 --- a/tools/distrib/python/docgen.py +++ b/tools/distrib/python/docgen.py @@ -71,6 +71,8 @@ subprocess_arguments_list = [ {'args': ['virtualenv', VIRTUALENV_DIR], 'env': environment}, + {'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip'], + 'env': environment}, {'args': [VIRTUALENV_PIP_PATH, 'install', '-r', REQUIREMENTS_PATH], 'env': environment}, {'args': [VIRTUALENV_PYTHON_PATH, SETUP_PATH, 'build'], 'env': environment}, From b91cddb2fa41df52a9e7ddef2d5ba7097b7c4cdc Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Wed, 20 Jul 2016 17:40:01 -0700 Subject: [PATCH 124/151] fixed typo --- include/grpc++/impl/codegen/client_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h index a132c9a57aa7f..012bcc2bbe531 100644 --- a/include/grpc++/impl/codegen/client_context.h +++ b/include/grpc++/impl/codegen/client_context.h @@ -41,7 +41,7 @@ /// /// Context settings are only relevant to the call they are invoked with, that /// is to say, they aren't sticky. Some of these settings, such as the -/// compression options, can be made persistant at channel construction time +/// compression options, can be made persistent at channel construction time /// (see \a grpc::CreateCustomChannel). /// /// \warning ClientContext instances should \em not be reused across rpcs. From 12c3811167fc33ab9921f14f00066da35a163b21 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Wed, 20 Jul 2016 17:54:37 -0700 Subject: [PATCH 125/151] Use compiling instead of making --- src/cpp/ext/proto_server_reflection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ext/proto_server_reflection.h b/src/cpp/ext/proto_server_reflection.h index fa3b9406c6ad8..f66f3c2c9ae9f 100644 --- a/src/cpp/ext/proto_server_reflection.h +++ b/src/cpp/ext/proto_server_reflection.h @@ -37,7 +37,7 @@ filegroup `grpc++_reflection_proto`, and GRPC_NO_GENERATED_CODE should not be defined. - If the server reflection library needs to generate `reflection.grpc.pb.h` - from `reflection.proto` at the time of making, the generated header + from `reflection.proto` at compile time, the generated header `grpc++/ext/reflection.grpc.pb.h` should not be installed. In this case, target `grpc++_reflection` should depend on `grpc++_reflection_codegen`, and GRPC_NO_GENERATED_CODE should be defined. From 104ae8dad6fb45e2c3b96f6db321974a30967e02 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Thu, 21 Jul 2016 10:51:45 +0800 Subject: [PATCH 126/151] support php7 on v1.0.x branch --- src/php/ext/grpc/call.c | 692 +++++++++++++----- src/php/ext/grpc/call.h | 36 +- src/php/ext/grpc/call_credentials.c | 103 ++- src/php/ext/grpc/call_credentials.h | 23 + src/php/ext/grpc/channel.c | 194 ++++- src/php/ext/grpc/channel.h | 23 +- src/php/ext/grpc/channel_credentials.c | 92 ++- src/php/ext/grpc/channel_credentials.h | 23 + src/php/ext/grpc/php_grpc.c | 54 +- src/php/ext/grpc/php_grpc.h | 4 +- src/php/ext/grpc/server.c | 136 +++- src/php/ext/grpc/server.h | 20 + src/php/ext/grpc/server_credentials.c | 67 +- src/php/ext/grpc/server_credentials.h | 20 + src/php/ext/grpc/timeval.c | 144 +++- src/php/ext/grpc/timeval.h | 23 + src/php/lib/Grpc/BaseStub.php | 4 +- src/php/lib/Grpc/BidiStreamingCall.php | 1 + src/php/lib/Grpc/ClientStreamingCall.php | 1 + src/php/lib/Grpc/ServerStreamingCall.php | 1 + src/php/lib/Grpc/UnaryCall.php | 1 + src/php/tests/interop/interop_client.php | 10 +- .../tests/unit_tests/CallCredentialsTest.php | 3 +- src/php/tests/unit_tests/CallTest.php | 49 +- .../unit_tests/ChannelCredentialsTest.php | 25 +- src/php/tests/unit_tests/ChannelTest.php | 107 +++ src/php/tests/unit_tests/EndToEndTest.php | 3 +- .../tests/unit_tests/SecureEndToEndTest.php | 0 src/php/tests/unit_tests/ServerTest.php | 85 ++- src/php/tests/unit_tests/TimevalTest.php | 53 ++ 30 files changed, 1690 insertions(+), 307 deletions(-) mode change 100755 => 100644 src/php/lib/Grpc/BaseStub.php mode change 100755 => 100644 src/php/tests/unit_tests/CallTest.php mode change 100755 => 100644 src/php/tests/unit_tests/EndToEndTest.php mode change 100755 => 100644 src/php/tests/unit_tests/SecureEndToEndTest.php mode change 100755 => 100644 src/php/tests/unit_tests/TimevalTest.php diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 2cd45f10dc45b..bd1eccb01b4eb 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -59,12 +59,15 @@ zend_class_entry *grpc_ce_call; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_call */ void free_wrapped_grpc_call(void *object TSRMLS_DC) { wrapped_grpc_call *call = (wrapped_grpc_call *)object; if (call->owned && call->wrapped != NULL) { grpc_call_destroy(call->wrapped); } + zend_object_std_dtor(&call->std TSRMLS_CC); efree(call); } @@ -203,6 +206,131 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { return true; } +#else + +static zend_object_handlers call_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_call */ +static void free_wrapped_grpc_call(zend_object *object) { + wrapped_grpc_call *call = wrapped_grpc_call_from_obj(object); + if (call->owned && call->wrapped != NULL) { + grpc_call_destroy(call->wrapped); + } + zend_object_std_dtor(&call->std); +} + +/* Initializes an instance of wrapped_grpc_call to be associated with an + * object of a class specified by class_type */ +zend_object *create_wrapped_grpc_call(zend_class_entry *class_type) { + wrapped_grpc_call *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_call) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &call_ce_handlers; + return &intern->std; +} + +/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the + struct should be destroyed at the end of the object's lifecycle */ +void grpc_php_wrap_call(grpc_call *wrapped, bool owned, zval *call_object) { + object_init_ex(call_object, grpc_ce_call); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(call_object); + call->wrapped = wrapped; + call->owned = owned; +} + +/* Creates and returns a PHP array object with the data in a + * grpc_metadata_array. Returns NULL on failure */ +void grpc_parse_metadata_array(grpc_metadata_array *metadata_array, + zval *array) { + int count = metadata_array->count; + grpc_metadata *elements = metadata_array->metadata; + int i; + zval *data; + HashTable *array_hash; + zval inner_array; + char *str_key; + char *str_val; + size_t key_len; + + array_init(array); + array_hash = HASH_OF(array); + grpc_metadata *elem; + for (i = 0; i < count; i++) { + elem = &elements[i]; + key_len = strlen(elem->key); + str_key = ecalloc(key_len + 1, sizeof(char)); + memcpy(str_key, elem->key, key_len); + str_val = ecalloc(elem->value_length + 1, sizeof(char)); + memcpy(str_val, elem->value, elem->value_length); + if ((data = zend_hash_str_find(array_hash, str_key, key_len)) != NULL) { + if (Z_TYPE_P(data) != IS_ARRAY) { + zend_throw_exception(zend_exception_get_default(), + "Metadata hash somehow contains wrong types.", + 1); + efree(str_key); + efree(str_val); + return; + } + add_next_index_stringl(data, str_val, elem->value_length); + } else { + array_init(&inner_array); + add_next_index_stringl(&inner_array, str_val, elem->value_length); + add_assoc_zval(array, str_key, &inner_array); + } + } +} + +/* Populates a grpc_metadata_array with the data in a PHP array object. + Returns true on success and false on failure */ +bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { + zval *inner_array; + zval *value; + HashTable *array_hash; + HashTable *inner_array_hash; + zend_string *key; + if (Z_TYPE_P(array) != IS_ARRAY) { + return false; + } + grpc_metadata_array_init(metadata); + array_hash = HASH_OF(array); + + ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, inner_array) { + if (key == NULL) { + return false; + } + if (Z_TYPE_P(inner_array) != IS_ARRAY) { + return false; + } + inner_array_hash = HASH_OF(inner_array); + metadata->capacity += zend_hash_num_elements(inner_array_hash); + } + ZEND_HASH_FOREACH_END(); + + metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata)); + + ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, inner_array) { + if (key == NULL) { + return false; + } + inner_array_hash = HASH_OF(inner_array); + + ZEND_HASH_FOREACH_VAL(inner_array_hash, value) { + if (Z_TYPE_P(value) != IS_STRING) { + return false; + } + metadata->metadata[metadata->count].key = ZSTR_VAL(key); + metadata->metadata[metadata->count].value = Z_STRVAL_P(value); + metadata->metadata[metadata->count].value_length = Z_STRLEN_P(value); + metadata->count += 1; + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + return true; +} + +#endif + /** * Constructs a new instance of the Call class. * @param Channel $channel The channel to associate the call with. Must not be @@ -211,30 +339,38 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { * @param Timeval $absolute_deadline The deadline for completing the call */ PHP_METHOD(Call, __construct) { - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); zval *channel_obj; char *method; - int method_len; zval *deadline_obj; char *host_override = NULL; +#if PHP_MAJOR_VERSION < 7 + int method_len; int host_override_len = 0; + wrapped_grpc_call *call = + (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + size_t method_len; + size_t host_override_len = 0; + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); +#endif + /* "OsO|s" == 1 Object, 1 string, 1 Object, 1 optional string */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", - &channel_obj, grpc_ce_channel, - &method, &method_len, - &deadline_obj, grpc_ce_timeval, - &host_override, &host_override_len) - == FAILURE) { - zend_throw_exception( - spl_ce_InvalidArgumentException, - "Call expects a Channel, a String, a Timeval and an optional String", - 1 TSRMLS_CC); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", &channel_obj, + grpc_ce_channel, &method, &method_len, + &deadline_obj, grpc_ce_timeval, &host_override, + &host_override_len) == FAILURE) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Call expects a Channel, a String, a Timeval and " + "an optional String", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object( channel_obj TSRMLS_CC); +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(channel_obj); +#endif if (channel->wrapped == NULL) { zend_throw_exception(spl_ce_InvalidArgumentException, "Call cannot be constructed from a closed Channel", @@ -242,12 +378,17 @@ PHP_METHOD(Call, __construct) { return; } add_property_zval(getThis(), "channel", channel_obj); +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *deadline = (wrapped_grpc_timeval *)zend_object_store_get_object( deadline_obj TSRMLS_CC); - call->wrapped = grpc_channel_create_call( - channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, completion_queue, method, - host_override, deadline->wrapped, NULL); +#else + wrapped_grpc_timeval *deadline = Z_WRAPPED_GRPC_TIMEVAL_P(deadline_obj); +#endif + call->wrapped = + grpc_channel_create_call(channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, + completion_queue, method, host_override, + deadline->wrapped, NULL); call->owned = true; } @@ -257,22 +398,40 @@ PHP_METHOD(Call, __construct) { * @return object Object with results of all actions */ PHP_METHOD(Call, startBatch) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - grpc_op ops[8]; - size_t op_num = 0; - zval *array; zval **value; zval **inner_value; - HashTable *array_hash; HashPosition array_pointer; - HashTable *status_hash; - HashTable *message_hash; zval **message_value; zval **message_flags; char *key; uint key_len; ulong index; + zval *result; + zval *recv_status; + MAKE_STD_ZVAL(result); + object_init(result); +#else + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); + zval *value; + zval *inner_value; + zval *message_value; + zval *message_flags; + zend_string *key; + zend_ulong index; + zval recv_status; + object_init(return_value); +#endif + + grpc_op ops[8]; + size_t op_num = 0; + zval *array; + HashTable *array_hash; + HashTable *status_hash; + HashTable *message_hash; + grpc_metadata_array metadata; grpc_metadata_array trailing_metadata; grpc_metadata_array recv_metadata; @@ -283,17 +442,16 @@ PHP_METHOD(Call, startBatch) { grpc_byte_buffer *message; int cancelled; grpc_call_error error; - zval *result; char *message_str; size_t message_len; - zval *recv_status; + + grpc_metadata_array_init(&metadata); grpc_metadata_array_init(&trailing_metadata); grpc_metadata_array_init(&recv_metadata); grpc_metadata_array_init(&recv_trailing_metadata); - MAKE_STD_ZVAL(result); - object_init(result); memset(ops, 0, sizeof(ops)); + /* "a" == 1 array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { @@ -301,6 +459,9 @@ PHP_METHOD(Call, startBatch) { "start_batch expects an array", 1 TSRMLS_CC); goto cleanup; } + +#if PHP_MAJOR_VERSION < 7 + array_hash = Z_ARRVAL_P(array); for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); zend_hash_get_current_data_ex(array_hash, (void**)&value, @@ -313,124 +474,250 @@ PHP_METHOD(Call, startBatch) { goto cleanup; } switch(index) { - case GRPC_OP_SEND_INITIAL_METADATA: - if (!create_metadata_array(*value, &metadata)) { + case GRPC_OP_SEND_INITIAL_METADATA: + if (!create_metadata_array(*value, &metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad metadata value given", 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_initial_metadata.count = + metadata.count; + ops[op_num].data.send_initial_metadata.metadata = + metadata.metadata; + break; + case GRPC_OP_SEND_MESSAGE: + if (Z_TYPE_PP(value) != IS_ARRAY) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected an array for send message", + 1 TSRMLS_CC); + goto cleanup; + } + message_hash = Z_ARRVAL_PP(value); + if (zend_hash_find(message_hash, "flags", sizeof("flags"), + (void **)&message_flags) == SUCCESS) { + if (Z_TYPE_PP(message_flags) != IS_LONG) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Bad metadata value given", 1 TSRMLS_CC); - goto cleanup; + "Expected an int for message flags", + 1 TSRMLS_CC); } - ops[op_num].data.send_initial_metadata.count = - metadata.count; - ops[op_num].data.send_initial_metadata.metadata = - metadata.metadata; - break; - case GRPC_OP_SEND_MESSAGE: - if (Z_TYPE_PP(value) != IS_ARRAY) { + ops[op_num].flags = Z_LVAL_PP(message_flags) & GRPC_WRITE_USED_MASK; + } + if (zend_hash_find(message_hash, "message", sizeof("message"), + (void **)&message_value) != SUCCESS || + Z_TYPE_PP(message_value) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected a string for send message", + 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_message = + string_to_byte_buffer(Z_STRVAL_PP(message_value), + Z_STRLEN_PP(message_value)); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + status_hash = Z_ARRVAL_PP(value); + if (zend_hash_find(status_hash, "metadata", sizeof("metadata"), + (void **)&inner_value) == SUCCESS) { + if (!create_metadata_array(*inner_value, &trailing_metadata)) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected an array for send message", + "Bad trailing metadata value given", 1 TSRMLS_CC); goto cleanup; } - message_hash = Z_ARRVAL_PP(value); - if (zend_hash_find(message_hash, "flags", sizeof("flags"), - (void **)&message_flags) == SUCCESS) { - if (Z_TYPE_PP(message_flags) != IS_LONG) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected an int for message flags", - 1 TSRMLS_CC); - } - ops[op_num].flags = Z_LVAL_PP(message_flags) & GRPC_WRITE_USED_MASK; + ops[op_num].data.send_status_from_server.trailing_metadata = + trailing_metadata.metadata; + ops[op_num].data.send_status_from_server.trailing_metadata_count = + trailing_metadata.count; + } + if (zend_hash_find(status_hash, "code", sizeof("code"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_PP(inner_value) != IS_LONG) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Status code must be an integer", + 1 TSRMLS_CC); + goto cleanup; } - if (zend_hash_find(message_hash, "message", sizeof("message"), - (void **)&message_value) != SUCCESS || - Z_TYPE_PP(message_value) != IS_STRING) { + ops[op_num].data.send_status_from_server.status = + Z_LVAL_PP(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Integer status code is required", + 1 TSRMLS_CC); + goto cleanup; + } + if (zend_hash_find(status_hash, "details", sizeof("details"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_PP(inner_value) != IS_STRING) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected a string for send message", + "Status details must be a string", 1 TSRMLS_CC); goto cleanup; } - ops[op_num].data.send_message = - string_to_byte_buffer(Z_STRVAL_PP(message_value), - Z_STRLEN_PP(message_value)); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - status_hash = Z_ARRVAL_PP(value); - if (zend_hash_find(status_hash, "metadata", sizeof("metadata"), - (void **)&inner_value) == SUCCESS) { - if (!create_metadata_array(*inner_value, &trailing_metadata)) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Bad trailing metadata value given", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.trailing_metadata = - trailing_metadata.metadata; - ops[op_num].data.send_status_from_server.trailing_metadata_count = - trailing_metadata.count; + ops[op_num].data.send_status_from_server.status_details = + Z_STRVAL_PP(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "String status details is required", + 1 TSRMLS_CC); + goto cleanup; + } + break; + case GRPC_OP_RECV_INITIAL_METADATA: + ops[op_num].data.recv_initial_metadata = &recv_metadata; + break; + case GRPC_OP_RECV_MESSAGE: + ops[op_num].data.recv_message = &message; + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + ops[op_num].data.recv_status_on_client.trailing_metadata = + &recv_trailing_metadata; + ops[op_num].data.recv_status_on_client.status = &status; + ops[op_num].data.recv_status_on_client.status_details = + &status_details; + ops[op_num].data.recv_status_on_client.status_details_capacity = + &status_details_capacity; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + ops[op_num].data.recv_close_on_server.cancelled = &cancelled; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "Unrecognized key in batch", 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].op = (grpc_op_type)index; + ops[op_num].flags = 0; + ops[op_num].reserved = NULL; + op_num++; + } + +#else + +array_hash = HASH_OF(array); + ZEND_HASH_FOREACH_KEY_VAL(array_hash, index, key, value) { + if (key) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "batch keys must be integers", 1); + goto cleanup; + } + + switch(index) { + case GRPC_OP_SEND_INITIAL_METADATA: + if (!create_metadata_array(value, &metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad metadata value given", 1); + goto cleanup; + } + ops[op_num].data.send_initial_metadata.count = metadata.count; + ops[op_num].data.send_initial_metadata.metadata = metadata.metadata; + break; + case GRPC_OP_SEND_MESSAGE: + if (Z_TYPE_P(value) != IS_ARRAY) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected an array for send message", 1); + goto cleanup; + } + message_hash = HASH_OF(value); + if ((message_flags = + zend_hash_str_find(message_hash, "flags", + sizeof("flags") - 1)) != NULL) { + if (Z_TYPE_P(message_flags) != IS_LONG) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected an int for message flags", 1); + } + ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK; + } + if ((message_value = zend_hash_str_find(message_hash, "message", + sizeof("message") - 1)) + == NULL || Z_TYPE_P(message_value) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected a string for send message", 1); + goto cleanup; + } + ops[op_num].data.send_message = + string_to_byte_buffer(Z_STRVAL_P(message_value), + Z_STRLEN_P(message_value)); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + status_hash = HASH_OF(value); + if ((inner_value = zend_hash_str_find(status_hash, "metadata", + sizeof("metadata") - 1)) + != NULL) { + if (!create_metadata_array(inner_value, &trailing_metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad trailing metadata value given", 1); + goto cleanup; } - if (zend_hash_find(status_hash, "code", sizeof("code"), - (void**)&inner_value) == SUCCESS) { - if (Z_TYPE_PP(inner_value) != IS_LONG) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Status code must be an integer", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.status = - Z_LVAL_PP(inner_value); - } else { + ops[op_num].data.send_status_from_server.trailing_metadata = + trailing_metadata.metadata; + ops[op_num].data.send_status_from_server.trailing_metadata_count = + trailing_metadata.count; + } + if ((inner_value = zend_hash_str_find(status_hash, "code", + sizeof("code") - 1)) != NULL) { + if (Z_TYPE_P(inner_value) != IS_LONG) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Integer status code is required", - 1 TSRMLS_CC); + "Status code must be an integer", 1); goto cleanup; } - if (zend_hash_find(status_hash, "details", sizeof("details"), - (void**)&inner_value) == SUCCESS) { - if (Z_TYPE_PP(inner_value) != IS_STRING) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Status details must be a string", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.status_details = - Z_STRVAL_PP(inner_value); - } else { + ops[op_num].data.send_status_from_server.status = + Z_LVAL_P(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Integer status code is required", 1); + goto cleanup; + } + if ((inner_value = zend_hash_str_find(status_hash, "details", + sizeof("details") - 1)) != NULL) { + if (Z_TYPE_P(inner_value) != IS_STRING) { zend_throw_exception(spl_ce_InvalidArgumentException, - "String status details is required", - 1 TSRMLS_CC); + "Status details must be a string", 1); goto cleanup; } - break; - case GRPC_OP_RECV_INITIAL_METADATA: - ops[op_num].data.recv_initial_metadata = &recv_metadata; - break; - case GRPC_OP_RECV_MESSAGE: - ops[op_num].data.recv_message = &message; - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - ops[op_num].data.recv_status_on_client.trailing_metadata = - &recv_trailing_metadata; - ops[op_num].data.recv_status_on_client.status = &status; - ops[op_num].data.recv_status_on_client.status_details = - &status_details; - ops[op_num].data.recv_status_on_client.status_details_capacity = - &status_details_capacity; - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - ops[op_num].data.recv_close_on_server.cancelled = &cancelled; - break; - default: + ops[op_num].data.send_status_from_server.status_details = + Z_STRVAL_P(inner_value); + } else { zend_throw_exception(spl_ce_InvalidArgumentException, - "Unrecognized key in batch", 1 TSRMLS_CC); + "String status details is required", 1); goto cleanup; + } + break; + case GRPC_OP_RECV_INITIAL_METADATA: + ops[op_num].data.recv_initial_metadata = &recv_metadata; + break; + case GRPC_OP_RECV_MESSAGE: + ops[op_num].data.recv_message = &message; + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + ops[op_num].data.recv_status_on_client.trailing_metadata = + &recv_trailing_metadata; + ops[op_num].data.recv_status_on_client.status = &status; + ops[op_num].data.recv_status_on_client.status_details = + &status_details; + ops[op_num].data.recv_status_on_client.status_details_capacity = + &status_details_capacity; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + ops[op_num].data.recv_close_on_server.cancelled = &cancelled; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "Unrecognized key in batch", 1); + goto cleanup; } ops[op_num].op = (grpc_op_type)index; ops[op_num].flags = 0; ops[op_num].reserved = NULL; op_num++; } + ZEND_HASH_FOREACH_END(); + +#endif + error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped, NULL); if (error != GRPC_CALL_OK) { @@ -441,52 +728,98 @@ PHP_METHOD(Call, startBatch) { } grpc_completion_queue_pluck(completion_queue, call->wrapped, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); +#if PHP_MAJOR_VERSION < 7 for (int i = 0; i < op_num; i++) { switch(ops[i].op) { - case GRPC_OP_SEND_INITIAL_METADATA: - add_property_bool(result, "send_metadata", true); - break; - case GRPC_OP_SEND_MESSAGE: - add_property_bool(result, "send_message", true); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - add_property_bool(result, "send_close", true); - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - add_property_bool(result, "send_status", true); - break; - case GRPC_OP_RECV_INITIAL_METADATA: - array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC); - 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); - if (message_str == NULL) { - add_property_null(result, "message"); - } else { - add_property_stringl(result, "message", message_str, message_len, - false); - } - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - MAKE_STD_ZVAL(recv_status); - object_init(recv_status); - array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC); - 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); - break; - default: - break; + case GRPC_OP_SEND_INITIAL_METADATA: + add_property_bool(result, "send_metadata", true); + break; + case GRPC_OP_SEND_MESSAGE: + add_property_bool(result, "send_message", true); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + add_property_bool(result, "send_close", true); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + add_property_bool(result, "send_status", true); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC); + 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); + if (message_str == NULL) { + add_property_null(result, "message"); + } else { + add_property_stringl(result, "message", message_str, message_len, + false); + } + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + MAKE_STD_ZVAL(recv_status); + object_init(recv_status); + array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC); + 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); + break; + default: + break; + } + } +#else + for (int i = 0; i < op_num; i++) { + switch(ops[i].op) { + case GRPC_OP_SEND_INITIAL_METADATA: + add_property_bool(return_value, "send_metadata", true); + break; + case GRPC_OP_SEND_MESSAGE: + add_property_bool(return_value, "send_message", true); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + add_property_bool(return_value, "send_close", true); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + add_property_bool(return_value, "send_status", true); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + grpc_parse_metadata_array(&recv_metadata, array); + add_property_zval(return_value, "metadata", array); + break; + case GRPC_OP_RECV_MESSAGE: + byte_buffer_to_string(message, &message_str, &message_len); + if (message_str == NULL) { + add_property_null(return_value, "message"); + } else { + add_property_stringl(return_value, "message", message_str, + message_len); + } + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + object_init(&recv_status); + grpc_parse_metadata_array(&recv_trailing_metadata, array); + add_property_zval(&recv_status, "metadata", array); + add_property_long(&recv_status, "code", status); + add_property_string(&recv_status, "details", status_details); + add_property_zval(return_value, "status", &recv_status); + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + add_property_bool(return_value, "cancelled", cancelled); + break; + default: + break; } } +#endif + cleanup: grpc_metadata_array_destroy(&metadata); grpc_metadata_array_destroy(&trailing_metadata); @@ -503,7 +836,11 @@ PHP_METHOD(Call, startBatch) { grpc_byte_buffer_destroy(message); } } +#if PHP_MAJOR_VERSION < 7 RETURN_DESTROY_ZVAL(result); +#else + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -511,9 +848,14 @@ PHP_METHOD(Call, startBatch) { * @return string The URI of the endpoint */ PHP_METHOD(Call, getPeer) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); RETURN_STRING(grpc_call_get_peer(call->wrapped), 1); +#else + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); + RETURN_STRING(grpc_call_get_peer(call->wrapped)); +#endif } /** @@ -521,8 +863,12 @@ PHP_METHOD(Call, getPeer) { * has not already ended with another status. */ PHP_METHOD(Call, cancel) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); +#endif grpc_call_cancel(call->wrapped, NULL); } @@ -543,12 +889,17 @@ PHP_METHOD(Call, setCredentials) { return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call_credentials *creds = (wrapped_grpc_call_credentials *)zend_object_store_get_object( creds_obj TSRMLS_CC); - wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_call_credentials *creds = + Z_WRAPPED_GRPC_CALL_CREDS_P(creds_obj); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); +#endif grpc_call_error error = GRPC_CALL_ERROR; error = grpc_call_set_credentials(call->wrapped, creds->wrapped); @@ -556,16 +907,23 @@ PHP_METHOD(Call, setCredentials) { } static zend_function_entry call_methods[] = { - PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC) - PHP_FE_END}; + PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_call(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Call", call_methods); ce.create_object = create_wrapped_grpc_call; grpc_ce_call = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&call_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + call_ce_handlers.offset = XtOffsetOf(wrapped_grpc_call, std); + call_ce_handlers.free_obj = free_wrapped_grpc_call; +#endif } diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h index 36c5f2d272466..9fc52d78209d7 100644 --- a/src/php/ext/grpc/call.h +++ b/src/php/ext/grpc/call.h @@ -48,17 +48,15 @@ /* Class entry for the Call PHP class */ extern zend_class_entry *grpc_ce_call; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_call that can be associated with a PHP object */ typedef struct wrapped_grpc_call { zend_object std; - bool owned; grpc_call *wrapped; } wrapped_grpc_call; -/* Initializes the Call PHP class */ -void grpc_init_call(TSRMLS_D); - /* Creates a Call object that wraps the given grpc_call struct */ zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC); @@ -66,6 +64,36 @@ zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC); * call metadata */ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC); +#else + +/* Wrapper struct for grpc_call that can be associated with a PHP object */ +typedef struct wrapped_grpc_call { + bool owned; + grpc_call *wrapped; + zend_object std; +} wrapped_grpc_call; + +static inline wrapped_grpc_call +*wrapped_grpc_call_from_obj(zend_object *obj) { + return (wrapped_grpc_call*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_call, std)); +} + +#define Z_WRAPPED_GRPC_CALL_P(zv) wrapped_grpc_call_from_obj(Z_OBJ_P((zv))) + +/* Creates a Call object that wraps the given grpc_call struct */ +void grpc_php_wrap_call(grpc_call *wrapped, bool owned, zval *call_object); + +/* Creates and returns a PHP associative array of metadata from a C array of + * call metadata */ +void grpc_parse_metadata_array(grpc_metadata_array *metadata_array, + zval *array); + +#endif /* PHP_MAJOR_VERSION */ + +/* Initializes the Call PHP class */ +void grpc_init_call(TSRMLS_D); + /* Populates a grpc_metadata_array with the data in a PHP array object. Returns true on success and false on failure */ bool create_metadata_array(zval *array, grpc_metadata_array *metadata); diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c index ec0e6b91813c4..70aaffb848ac3 100644 --- a/src/php/ext/grpc/call_credentials.c +++ b/src/php/ext/grpc/call_credentials.c @@ -53,6 +53,8 @@ zend_class_entry *grpc_ce_call_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_call_credentials */ void free_wrapped_grpc_call_credentials(void *object TSRMLS_DC) { wrapped_grpc_call_credentials *creds = @@ -60,6 +62,7 @@ void free_wrapped_grpc_call_credentials(void *object TSRMLS_DC) { if (creds->wrapped != NULL) { grpc_call_credentials_release(creds->wrapped); } + zend_object_std_dtor(&creds->std TSRMLS_CC); efree(creds); } @@ -94,6 +97,43 @@ zval *grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped TSRMLS_DC) { return credentials_object; } +#else + +static zend_object_handlers call_credentials_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_call_credentials */ +static void free_wrapped_grpc_call_credentials(zend_object *object) { + wrapped_grpc_call_credentials *creds = + wrapped_grpc_call_creds_from_obj(object); + if (creds->wrapped != NULL) { + grpc_call_credentials_release(creds->wrapped); + } + zend_object_std_dtor(&creds->std); +} + +/* Initializes an instance of wrapped_grpc_call_credentials to be + * associated with an object of a class specified by class_type */ +zend_object *create_wrapped_grpc_call_credentials(zend_class_entry + *class_type) { + wrapped_grpc_call_credentials *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_call_credentials) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &call_credentials_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped, + zval *credentials_object) { + object_init_ex(credentials_object, grpc_ce_call_credentials); + wrapped_grpc_call_credentials *credentials = + Z_WRAPPED_GRPC_CALL_CREDS_P(credentials_object); + credentials->wrapped = wrapped; +} + +#endif + /** * Create composite credentials from two existing credentials. * @param CallCredentials cred1 The first credential @@ -113,6 +153,7 @@ PHP_METHOD(CallCredentials, createComposite) { 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_call_credentials *cred1 = (wrapped_grpc_call_credentials *)zend_object_store_get_object( cred1_obj TSRMLS_CC); @@ -124,6 +165,17 @@ PHP_METHOD(CallCredentials, createComposite) { NULL); zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + wrapped_grpc_call_credentials *cred1 = + Z_WRAPPED_GRPC_CALL_CREDS_P(cred1_obj); + wrapped_grpc_call_credentials *cred2 = + Z_WRAPPED_GRPC_CALL_CREDS_P(cred2_obj); + grpc_call_credentials *creds = + grpc_composite_call_credentials_create(cred1->wrapped, + cred2->wrapped, NULL); + grpc_php_wrap_call_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -141,13 +193,10 @@ PHP_METHOD(CallCredentials, createFromPlugin) { memset(fci_cache, 0, sizeof(zend_fcall_info_cache)); /* "f" == 1 function */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", fci, - fci_cache, - fci->params, - fci->param_count) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f*", fci, fci_cache, + fci->params, fci->param_count) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, - "createFromPlugin expects 1 callback", - 1 TSRMLS_CC); + "createFromPlugin expects 1 callback", 1 TSRMLS_CC); return; } @@ -165,10 +214,15 @@ PHP_METHOD(CallCredentials, createFromPlugin) { plugin.state = (void *)state; plugin.type = ""; - grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin( - plugin, NULL); + grpc_call_credentials *creds = + grpc_metadata_credentials_create_from_plugin(plugin, NULL); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_call_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /* Callback function for plugin creds API */ @@ -181,6 +235,7 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context, /* prepare to call the user callback function with info from the * grpc_auth_metadata_context */ +#if PHP_MAJOR_VERSION < 7 zval **params[1]; zval *arg; zval *retval; @@ -192,21 +247,41 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context, state->fci->param_count = 1; state->fci->params = params; state->fci->retval_ptr_ptr = &retval; +#else + zval arg; + zval retval; + object_init(&arg); + add_property_string(&arg, "service_url", context.service_url); + add_property_string(&arg, "method_name", context.method_name); + state->fci->param_count = 1; + state->fci->params = &arg; + state->fci->retval = &retval; +#endif /* call the user callback function */ zend_call_function(state->fci, state->fci_cache TSRMLS_CC); +#if PHP_MAJOR_VERSION < 7 if (Z_TYPE_P(retval) != IS_ARRAY) { +#else + if (Z_TYPE_P(&retval) != IS_ARRAY) { +#endif zend_throw_exception(spl_ce_InvalidArgumentException, "plugin callback must return metadata array", 1 TSRMLS_CC); + return; } grpc_metadata_array metadata; +#if PHP_MAJOR_VERSION < 7 if (!create_metadata_array(retval, &metadata)) { +#else + if (!create_metadata_array(&retval, &metadata)) { +#endif zend_throw_exception(spl_ce_InvalidArgumentException, "invalid metadata", 1 TSRMLS_CC); grpc_metadata_array_destroy(&metadata); + return; } /* TODO: handle error */ @@ -229,11 +304,21 @@ static zend_function_entry call_credentials_methods[] = { ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(CallCredentials, createFromPlugin, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_FE_END}; + PHP_FE_END +}; void grpc_init_call_credentials(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\CallCredentials", call_credentials_methods); ce.create_object = create_wrapped_grpc_call_credentials; grpc_ce_call_credentials = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&call_credentials_ce_handlers, + zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + call_credentials_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_call_credentials, std); + call_credentials_ce_handlers.free_obj = + free_wrapped_grpc_call_credentials; +#endif } diff --git a/src/php/ext/grpc/call_credentials.h b/src/php/ext/grpc/call_credentials.h index d2f6a92449bf7..e05e14698b2fc 100755 --- a/src/php/ext/grpc/call_credentials.h +++ b/src/php/ext/grpc/call_credentials.h @@ -49,14 +49,37 @@ /* Class entry for the CallCredentials PHP class */ extern zend_class_entry *grpc_ce_call_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_call_credentials that can be associated * with a PHP object */ typedef struct wrapped_grpc_call_credentials { zend_object std; + grpc_call_credentials *wrapped; +} wrapped_grpc_call_credentials; +#else + +/* Wrapper struct for grpc_call_credentials that can be associated + * with a PHP object */ +typedef struct wrapped_grpc_call_credentials { grpc_call_credentials *wrapped; + zend_object std; } wrapped_grpc_call_credentials; +static inline wrapped_grpc_call_credentials +*wrapped_grpc_call_creds_from_obj(zend_object *obj) { + return + (wrapped_grpc_call_credentials*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_call_credentials, + std)); +} + +#define Z_WRAPPED_GRPC_CALL_CREDS_P(zv) \ + wrapped_grpc_call_creds_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Struct to hold callback function for plugin creds API */ typedef struct plugin_state { zend_fcall_info *fci; diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index 8d94c59683e93..6737e340f91af 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -57,12 +57,15 @@ zend_class_entry *grpc_ce_channel; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_channel */ void free_wrapped_grpc_channel(void *object TSRMLS_DC) { wrapped_grpc_channel *channel = (wrapped_grpc_channel *)object; if (channel->wrapped != NULL) { grpc_channel_destroy(channel->wrapped); } + zend_object_std_dtor(&channel->std TSRMLS_CC); efree(channel); } @@ -83,7 +86,8 @@ zend_object_value create_wrapped_grpc_channel(zend_class_entry *class_type return retval; } -void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_DC) { +void php_grpc_read_args_array(zval *args_array, + grpc_channel_args *args TSRMLS_DC) { HashTable *array_hash; HashPosition array_pointer; int args_index; @@ -107,23 +111,88 @@ void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_D } args->args[args_index].key = key; switch (Z_TYPE_P(*data)) { - case IS_LONG: - args->args[args_index].value.integer = (int)Z_LVAL_P(*data); - args->args[args_index].type = GRPC_ARG_INTEGER; - break; - case IS_STRING: - args->args[args_index].value.string = Z_STRVAL_P(*data); - args->args[args_index].type = GRPC_ARG_STRING; - break; - default: - zend_throw_exception(spl_ce_InvalidArgumentException, - "args values must be int or string", 1 TSRMLS_CC); - return; + case IS_LONG: + args->args[args_index].value.integer = (int)Z_LVAL_P(*data); + args->args[args_index].type = GRPC_ARG_INTEGER; + break; + case IS_STRING: + args->args[args_index].value.string = Z_STRVAL_P(*data); + args->args[args_index].type = GRPC_ARG_STRING; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "args values must be int or string", 1 TSRMLS_CC); + return; } args_index++; } } +#else + +static zend_object_handlers channel_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_channel */ +static void free_wrapped_grpc_channel(zend_object *object) { + wrapped_grpc_channel *channel = wrapped_grpc_channel_from_obj(object); + if (channel->wrapped != NULL) { + grpc_channel_destroy(channel->wrapped); + } + zend_object_std_dtor(&channel->std); +} + +/* Initializes an instance of wrapped_grpc_channel to be associated with an + * object of a class specified by class_type */ +zend_object *create_wrapped_grpc_channel(zend_class_entry *class_type) { + wrapped_grpc_channel *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_channel) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &channel_ce_handlers; + return &intern->std; +} + +void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args) { + HashTable *array_hash; + int args_index; + zval *data; + zend_string *key; + array_hash = HASH_OF(args_array); + if (!array_hash) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "array_hash is NULL", 1); + return; + } + args->num_args = zend_hash_num_elements(array_hash); + args->args = ecalloc(args->num_args, sizeof(grpc_arg)); + args_index = 0; + ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, data) { + if (key == NULL) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "args keys must be strings", 1); + } + args->args[args_index].key = ZSTR_VAL(key); + switch (Z_TYPE_P(data)) { + case IS_LONG: + args->args[args_index].value.integer = (int)Z_LVAL_P(data); + args->args[args_index].type = GRPC_ARG_INTEGER; + break; + case IS_STRING: + args->args[args_index].value.string = Z_STRVAL_P(data); + args->args[args_index].type = GRPC_ARG_STRING; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "args values must be int or string", 1); + return; + } + args_index++; + } ZEND_HASH_FOREACH_END(); +} + +#endif + /** * Construct an instance of the Channel class. If the $args array contains a * "credentials" key mapping to a ChannelCredentials object, a secure channel @@ -132,16 +201,23 @@ void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_D * @param array $args The arguments to pass to the Channel (optional) */ PHP_METHOD(Channel, __construct) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object( getThis() TSRMLS_CC); - char *target; + zval **creds_obj = NULL; int target_length; +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + zval *creds_obj = NULL; + size_t target_length; +#endif + char *target; zval *args_array = NULL; grpc_channel_args args; HashTable *array_hash; - zval **creds_obj = NULL; wrapped_grpc_channel_credentials *creds = NULL; + /* "sa" == 1 string, 1 array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &target, &target_length, &args_array) == FAILURE) { @@ -149,6 +225,7 @@ PHP_METHOD(Channel, __construct) { "Channel expects a string and an array", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 array_hash = Z_ARRVAL_P(args_array); if (zend_hash_find(array_hash, "credentials", sizeof("credentials"), (void **)&creds_obj) == SUCCESS) { @@ -167,6 +244,24 @@ PHP_METHOD(Channel, __construct) { zend_hash_del(array_hash, "credentials", 12); } } +#else + array_hash = HASH_OF(args_array); + if ((creds_obj = zend_hash_str_find(array_hash, "credentials", + sizeof("credentials") - 1)) != NULL) { + if (Z_TYPE_P(creds_obj) == IS_NULL) { + creds = NULL; + zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1); + } else if (Z_OBJ_P(creds_obj)->ce != grpc_ce_channel_credentials) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "credentials must be a ChannelCredentials object", + 1); + return; + } else { + creds = Z_WRAPPED_GRPC_CHANNEL_CREDS_P(creds_obj); + zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1); + } + } +#endif php_grpc_read_args_array(args_array, &args TSRMLS_CC); if (creds == NULL) { channel->wrapped = grpc_insecure_channel_create(target, &args, NULL); @@ -182,9 +277,14 @@ PHP_METHOD(Channel, __construct) { * @return string The URI of the endpoint */ PHP_METHOD(Channel, getTarget) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); + (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); RETURN_STRING(grpc_channel_get_target(channel->wrapped), 1); +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + RETURN_STRING(grpc_channel_get_target(channel->wrapped)); +#endif } /** @@ -193,12 +293,17 @@ PHP_METHOD(Channel, getTarget) { * @return long The grpc connectivity state */ PHP_METHOD(Channel, getConnectivityState) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); - bool try_to_connect; +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); +#endif + bool try_to_connect = false; + /* "|b" == 1 optional bool */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect) + == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "getConnectivityState expects a bool", 1 TSRMLS_CC); return; @@ -215,10 +320,16 @@ PHP_METHOD(Channel, getConnectivityState) { * before deadline */ PHP_METHOD(Channel, watchConnectivityState) { +#if PHP_MAJOR_VERSION < 7 + long last_state; wrapped_grpc_channel *channel = (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); - long last_state; +#else + zend_long last_state; + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); +#endif zval *deadline_obj; + /* "lO" == 1 long 1 object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO", &last_state, &deadline_obj, grpc_ce_timeval) == FAILURE) { @@ -228,15 +339,20 @@ PHP_METHOD(Channel, watchConnectivityState) { return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *deadline = (wrapped_grpc_timeval *)zend_object_store_get_object( deadline_obj TSRMLS_CC); - grpc_channel_watch_connectivity_state( - channel->wrapped, (grpc_connectivity_state)last_state, - deadline->wrapped, completion_queue, NULL); - grpc_event event = grpc_completion_queue_pluck( - completion_queue, NULL, - gpr_inf_future(GPR_CLOCK_REALTIME), NULL); +#else + wrapped_grpc_timeval *deadline = Z_WRAPPED_GRPC_TIMEVAL_P(deadline_obj); +#endif + grpc_channel_watch_connectivity_state(channel->wrapped, + (grpc_connectivity_state)last_state, + deadline->wrapped, completion_queue, + NULL); + grpc_event event = + grpc_completion_queue_pluck(completion_queue, NULL, + gpr_inf_future(GPR_CLOCK_REALTIME), NULL); RETURN_BOOL(event.success); } @@ -244,8 +360,12 @@ PHP_METHOD(Channel, watchConnectivityState) { * Close the channel */ PHP_METHOD(Channel, close) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); + (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); +#endif if (channel->wrapped != NULL) { grpc_channel_destroy(channel->wrapped); channel->wrapped = NULL; @@ -253,16 +373,24 @@ PHP_METHOD(Channel, close) { } static zend_function_entry channel_methods[] = { - PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) - PHP_FE_END}; + PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_channel(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Channel", channel_methods); ce.create_object = create_wrapped_grpc_channel; grpc_ce_channel = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&channel_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + channel_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_channel, std); + channel_ce_handlers.free_obj = free_wrapped_grpc_channel; +#endif } diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h index cc5823ee7f758..ea5efeaf86401 100755 --- a/src/php/ext/grpc/channel.h +++ b/src/php/ext/grpc/channel.h @@ -48,17 +48,38 @@ /* Class entry for the PHP Channel class */ extern zend_class_entry *grpc_ce_channel; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_channel that can be associated with a PHP object */ typedef struct wrapped_grpc_channel { zend_object std; + grpc_channel *wrapped; +} wrapped_grpc_channel; +#else + +/* Wrapper struct for grpc_channel that can be associated with a PHP object */ +typedef struct wrapped_grpc_channel { grpc_channel *wrapped; + zend_object std; } wrapped_grpc_channel; +static inline wrapped_grpc_channel +*wrapped_grpc_channel_from_obj(zend_object *obj) { + return (wrapped_grpc_channel*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_channel, std)); +} + +#define Z_WRAPPED_GRPC_CHANNEL_P(zv) \ + wrapped_grpc_channel_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the Channel class */ void grpc_init_channel(TSRMLS_D); /* Iterates through a PHP array and populates args with the contents */ -void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_DC); +void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args + TSRMLS_DC); #endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */ diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index b76fb105f3630..16ba0368ebbcd 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -52,7 +52,6 @@ #include zend_class_entry *grpc_ce_channel_credentials; - static char *default_pem_root_certs = NULL; static grpc_ssl_roots_override_result get_ssl_roots_override( @@ -64,6 +63,8 @@ static grpc_ssl_roots_override_result get_ssl_roots_override( return GRPC_SSL_ROOTS_OVERRIDE_OK; } +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_channel_credentials */ void free_wrapped_grpc_channel_credentials(void *object TSRMLS_DC) { wrapped_grpc_channel_credentials *creds = @@ -71,6 +72,7 @@ void free_wrapped_grpc_channel_credentials(void *object TSRMLS_DC) { if (creds->wrapped != NULL) { grpc_channel_credentials_release(creds->wrapped); } + zend_object_std_dtor(&creds->std TSRMLS_CC); efree(creds); } @@ -94,7 +96,8 @@ zend_object_value create_wrapped_grpc_channel_credentials( return retval; } -zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS_DC) { +zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials + *wrapped TSRMLS_DC) { zval *credentials_object; MAKE_STD_ZVAL(credentials_object); object_init_ex(credentials_object, grpc_ce_channel_credentials); @@ -105,6 +108,43 @@ zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS return credentials_object; } +#else + +static zend_object_handlers channel_credentials_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_channel_credentials */ +static void free_wrapped_grpc_channel_credentials(zend_object *object) { + wrapped_grpc_channel_credentials *creds = + wrapped_grpc_channel_creds_from_obj(object); + if (creds->wrapped != NULL) { + grpc_channel_credentials_release(creds->wrapped); + } + zend_object_std_dtor(&creds->std); +} + +/* Initializes an instance of wrapped_grpc_channel_credentials to be + * associated with an object of a class specified by class_type */ +zend_object *create_wrapped_grpc_channel_credentials(zend_class_entry + *class_type) { + wrapped_grpc_channel_credentials *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_channel_credentials) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &channel_credentials_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped, + zval *credentials_object) { + object_init_ex(credentials_object, grpc_ce_channel_credentials); + wrapped_grpc_channel_credentials *credentials = + Z_WRAPPED_GRPC_CHANNEL_CREDS_P(credentials_object); + credentials->wrapped = wrapped; +} + +#endif + /** * Set default roots pem. * @param string pem_roots PEM encoding of the server root certificates @@ -112,7 +152,13 @@ zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS */ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { char *pem_roots; +#if PHP_MAJOR_VERSION < 7 int pem_roots_length; +#else + size_t pem_roots_length; +#endif + + /* "s" == 1 string */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &pem_roots, &pem_roots_length) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, @@ -129,8 +175,13 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { */ PHP_METHOD(ChannelCredentials, createDefault) { grpc_channel_credentials *creds = grpc_google_default_credentials_create(); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_channel_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -146,11 +197,15 @@ PHP_METHOD(ChannelCredentials, createSsl) { char *pem_root_certs = NULL; grpc_ssl_pem_key_cert_pair pem_key_cert_pair; +#if PHP_MAJOR_VERSION < 7 int root_certs_length = 0, private_key_length = 0, cert_chain_length = 0; +#else + size_t root_certs_length = 0, private_key_length = 0, cert_chain_length = 0; +#endif pem_key_cert_pair.private_key = pem_key_cert_pair.cert_chain = NULL; - /* "|s!s!s! == 3 optional nullable strings */ + /* "|s!s!s!" == 3 optional nullable strings */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!", &pem_root_certs, &root_certs_length, &pem_key_cert_pair.private_key, @@ -164,8 +219,13 @@ PHP_METHOD(ChannelCredentials, createSsl) { grpc_channel_credentials *creds = grpc_ssl_credentials_create( pem_root_certs, pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_channel_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -178,7 +238,7 @@ PHP_METHOD(ChannelCredentials, createComposite) { zval *cred1_obj; zval *cred2_obj; - /* "OO" == 3 Objects */ + /* "OO" == 2 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj, grpc_ce_channel_credentials, &cred2_obj, grpc_ce_call_credentials) == FAILURE) { @@ -186,6 +246,7 @@ PHP_METHOD(ChannelCredentials, createComposite) { "createComposite expects 2 Credentials", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_channel_credentials *cred1 = (wrapped_grpc_channel_credentials *)zend_object_store_get_object( cred1_obj TSRMLS_CC); @@ -197,6 +258,17 @@ PHP_METHOD(ChannelCredentials, createComposite) { NULL); zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + wrapped_grpc_channel_credentials *cred1 = + Z_WRAPPED_GRPC_CHANNEL_CREDS_P(cred1_obj); + wrapped_grpc_call_credentials *cred2 = + Z_WRAPPED_GRPC_CALL_CREDS_P(cred2_obj); + grpc_channel_credentials *creds = + grpc_composite_channel_credentials_create(cred1->wrapped, + cred2->wrapped, NULL); + grpc_php_wrap_channel_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -218,7 +290,8 @@ static zend_function_entry channel_credentials_methods[] = { ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(ChannelCredentials, createInsecure, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_FE_END}; + PHP_FE_END +}; void grpc_init_channel_credentials(TSRMLS_D) { zend_class_entry ce; @@ -227,4 +300,13 @@ void grpc_init_channel_credentials(TSRMLS_D) { grpc_set_ssl_roots_override_callback(get_ssl_roots_override); ce.create_object = create_wrapped_grpc_channel_credentials; grpc_ce_channel_credentials = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&channel_credentials_ce_handlers, + zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + channel_credentials_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_channel_credentials, std); + channel_credentials_ce_handlers.free_obj = + free_wrapped_grpc_channel_credentials; +#endif } diff --git a/src/php/ext/grpc/channel_credentials.h b/src/php/ext/grpc/channel_credentials.h index d89984ce60407..44071b10f1079 100755 --- a/src/php/ext/grpc/channel_credentials.h +++ b/src/php/ext/grpc/channel_credentials.h @@ -49,14 +49,37 @@ /* Class entry for the ChannelCredentials PHP class */ extern zend_class_entry *grpc_ce_channel_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_channel_credentials that can be associated * with a PHP object */ typedef struct wrapped_grpc_channel_credentials { zend_object std; + grpc_channel_credentials *wrapped; +} wrapped_grpc_channel_credentials; +#else + +/* Wrapper struct for grpc_channel_credentials that can be associated + * with a PHP object */ +typedef struct wrapped_grpc_channel_credentials { grpc_channel_credentials *wrapped; + zend_object std; } wrapped_grpc_channel_credentials; +static inline wrapped_grpc_channel_credentials +*wrapped_grpc_channel_creds_from_obj(zend_object *obj) { + return + (wrapped_grpc_channel_credentials *) + ((char*)(obj) - + XtOffsetOf(wrapped_grpc_channel_credentials, std)); +} + +#define Z_WRAPPED_GRPC_CHANNEL_CREDS_P(zv) \ + wrapped_grpc_channel_creds_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the ChannelCredentials PHP class */ void grpc_init_channel_credentials(TSRMLS_D); diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 449ba3cd47b8c..5edfa2da7df6b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -64,15 +64,19 @@ const zend_function_entry grpc_functions[] = { */ zend_module_entry grpc_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER, #endif - "grpc", grpc_functions, PHP_MINIT(grpc), - PHP_MSHUTDOWN(grpc), NULL, NULL, - PHP_MINFO(grpc), + "grpc", + grpc_functions, + PHP_MINIT(grpc), + PHP_MSHUTDOWN(grpc), + NULL, + NULL, + PHP_MINFO(grpc), #if ZEND_MODULE_API_NO >= 20010901 - PHP_GRPC_VERSION, + PHP_GRPC_VERSION, #endif - STANDARD_MODULE_PROPERTIES}; + STANDARD_MODULE_PROPERTIES}; /* }}} */ #ifdef COMPILE_DL_GRPC @@ -82,23 +86,24 @@ ZEND_GET_MODULE(grpc) /* {{{ PHP_INI */ /* Remove comments and fill if you need to have entries in php.ini -PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, -global_value, zend_grpc_globals, grpc_globals) - STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, -OnUpdateString, global_string, zend_grpc_globals, grpc_globals) -PHP_INI_END() + PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, + global_value, zend_grpc_globals, grpc_globals) + STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, + OnUpdateString, global_string, zend_grpc_globals, + grpc_globals) + PHP_INI_END() */ /* }}} */ /* {{{ php_grpc_init_globals */ /* Uncomment this function if you have INI entries -static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) -{ - grpc_globals->global_value = 0; - grpc_globals->global_string = NULL; -} + static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) + { + grpc_globals->global_value = 0; + grpc_globals->global_string = NULL; + } */ /* }}} */ @@ -106,7 +111,7 @@ static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) */ PHP_MINIT_FUNCTION(grpc) { /* If you have INI entries, uncomment these lines - REGISTER_INI_ENTRIES(); + REGISTER_INI_ENTRIES(); */ /* Register call error constants */ grpc_init(); @@ -246,7 +251,7 @@ PHP_MINIT_FUNCTION(grpc) { */ PHP_MSHUTDOWN_FUNCTION(grpc) { /* uncomment this line if you have INI entries - UNREGISTER_INI_ENTRIES(); + UNREGISTER_INI_ENTRIES(); */ // WARNING: This function IS being called by PHP when the extension // is unloaded but the logs were somehow suppressed. @@ -265,7 +270,7 @@ PHP_MINFO_FUNCTION(grpc) { php_info_print_table_end(); /* Remove comments if you have entries in php.ini - DISPLAY_INI_ENTRIES(); + DISPLAY_INI_ENTRIES(); */ } /* }}} */ @@ -274,12 +279,3 @@ PHP_MINFO_FUNCTION(grpc) { function definition, where the functions purpose is also documented. Please follow this convention for the convenience of others editing your code. */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index 1d4834c50fa32..bd7ee75a6fb56 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -72,8 +72,8 @@ PHP_MSHUTDOWN_FUNCTION(grpc); PHP_MINFO_FUNCTION(grpc); /* - Declare any global variables you may need between the BEGIN - and END macros here: + Declare any global variables you may need between the BEGIN + and END macros here: ZEND_BEGIN_MODULE_GLOBALS(grpc) ZEND_END_MODULE_GLOBALS(grpc) diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c index c13e7cd1f9240..50fb2d0cf9402 100644 --- a/src/php/ext/grpc/server.c +++ b/src/php/ext/grpc/server.c @@ -58,6 +58,8 @@ zend_class_entry *grpc_ce_server; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_server */ void free_wrapped_grpc_server(void *object TSRMLS_DC) { wrapped_grpc_server *server = (wrapped_grpc_server *)object; @@ -68,6 +70,7 @@ void free_wrapped_grpc_server(void *object TSRMLS_DC) { gpr_inf_future(GPR_CLOCK_REALTIME), NULL); grpc_server_destroy(server->wrapped); } + zend_object_std_dtor(&server->std TSRMLS_CC); efree(server); } @@ -90,15 +93,51 @@ zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type return retval; } +#else + +static zend_object_handlers server_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_server */ +static void free_wrapped_grpc_server(zend_object *object) { + wrapped_grpc_server *server = wrapped_grpc_server_from_obj(object); + if (server->wrapped != NULL) { + grpc_server_shutdown_and_notify(server->wrapped, completion_queue, NULL); + grpc_server_cancel_all_calls(server->wrapped); + grpc_completion_queue_pluck(completion_queue, NULL, + gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + grpc_server_destroy(server->wrapped); + } + zend_object_std_dtor(&server->std); +} + +/* Initializes an instance of wrapped_grpc_call to be associated with an object + * of a class specified by class_type */ +zend_object *create_wrapped_grpc_server(zend_class_entry *class_type) { + wrapped_grpc_server *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_server) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &server_ce_handlers; + return &intern->std; +} + +#endif + /** * Constructs a new instance of the Server class * @param array $args The arguments to pass to the server (optional) */ PHP_METHOD(Server, __construct) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif zval *args_array = NULL; grpc_channel_args args; + /* "|a" == 1 optional array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &args_array) == FAILURE) { @@ -110,6 +149,8 @@ PHP_METHOD(Server, __construct) { if (args_array == NULL) { server->wrapped = grpc_server_create(NULL, NULL); } else { + //TODO(thinkerou): deal it if key of array is long, crash now on php7 + // and update unit test case php_grpc_read_args_array(args_array, &args TSRMLS_CC); server->wrapped = grpc_server_create(&args, NULL); efree(args.args); @@ -126,15 +167,22 @@ PHP_METHOD(Server, __construct) { */ PHP_METHOD(Server, requestCall) { grpc_call_error error_code; - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); grpc_call *call; grpc_call_details details; grpc_metadata_array metadata; - zval *result; grpc_event event; + +#if PHP_MAJOR_VERSION < 7 + wrapped_grpc_server *server = + (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); + zval *result; MAKE_STD_ZVAL(result); object_init(result); +#else + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); + object_init(return_value); +#endif + grpc_call_details_init(&details); grpc_metadata_array_init(&metadata); error_code = @@ -146,23 +194,48 @@ PHP_METHOD(Server, requestCall) { goto cleanup; } event = grpc_completion_queue_pluck(completion_queue, NULL, - gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + gpr_inf_future(GPR_CLOCK_REALTIME), + NULL); if (!event.success) { zend_throw_exception(spl_ce_LogicException, "Failed to request a call for some reason", 1 TSRMLS_CC); goto cleanup; } +#if PHP_MAJOR_VERSION < 7 add_property_zval(result, "call", grpc_php_wrap_call(call, true TSRMLS_CC)); add_property_string(result, "method", details.method, true); add_property_string(result, "host", details.host, true); add_property_zval(result, "absolute_deadline", grpc_php_wrap_timeval(details.deadline TSRMLS_CC)); - add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata TSRMLS_CC)); + add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata + TSRMLS_CC)); + cleanup: grpc_call_details_destroy(&details); grpc_metadata_array_destroy(&metadata); RETURN_DESTROY_ZVAL(result); + +#else + + zval zv_call; + zval zv_timeval; + zval zv_md; + grpc_php_wrap_call(call, true, &zv_call); + grpc_php_wrap_timeval(details.deadline, &zv_timeval); + grpc_parse_metadata_array(&metadata, &zv_md); + + add_property_zval(return_value, "call", &zv_call); + add_property_string(return_value, "method", details.method); + add_property_string(return_value, "host", details.host); + add_property_zval(return_value, "absolute_deadline", &zv_timeval); + add_property_zval(return_value, "metadata", &zv_md); + + cleanup: + grpc_call_details_destroy(&details); + grpc_metadata_array_destroy(&metadata); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -171,13 +244,19 @@ PHP_METHOD(Server, requestCall) { * @return true on success, false on failure */ PHP_METHOD(Server, addHttp2Port) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; +#if PHP_MAJOR_VERSION < 7 int addr_len; + wrapped_grpc_server *server = + (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + size_t addr_len; + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif + /* "s" == 1 string */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) + == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "add_http2_port expects a string", 1 TSRMLS_CC); return; @@ -186,11 +265,17 @@ PHP_METHOD(Server, addHttp2Port) { } PHP_METHOD(Server, addSecureHttp2Port) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; - int addr_len; zval *creds_obj; +#if PHP_MAJOR_VERSION < 7 + int addr_len; + wrapped_grpc_server *server = + (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + size_t addr_len; + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif + /* "sO" == 1 string, 1 object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO", &addr, &addr_len, &creds_obj, grpc_ce_server_credentials) == @@ -200,9 +285,14 @@ PHP_METHOD(Server, addSecureHttp2Port) { "add_http2_port expects a string and a ServerCredentials", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_server_credentials *creds = (wrapped_grpc_server_credentials *)zend_object_store_get_object( creds_obj TSRMLS_CC); +#else + wrapped_grpc_server_credentials *creds = + Z_WRAPPED_GRPC_SERVER_CREDS_P(creds_obj); +#endif RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr, creds->wrapped)); } @@ -212,21 +302,33 @@ PHP_METHOD(Server, addSecureHttp2Port) { * @return Void */ PHP_METHOD(Server, start) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); +#endif grpc_server_start(server->wrapped); } static zend_function_entry server_methods[] = { - PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; + PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_server(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Server", server_methods); ce.create_object = create_wrapped_grpc_server; grpc_ce_server = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&server_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + server_ce_handlers.offset = XtOffsetOf(wrapped_grpc_server, std); + server_ce_handlers.free_obj = free_wrapped_grpc_server; +#endif } diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h index 022257f37c3e5..a7df456a11154 100755 --- a/src/php/ext/grpc/server.h +++ b/src/php/ext/grpc/server.h @@ -48,13 +48,33 @@ /* Class entry for the Server PHP class */ extern zend_class_entry *grpc_ce_server; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_server that can be associated with a PHP object */ typedef struct wrapped_grpc_server { zend_object std; + grpc_server *wrapped; +} wrapped_grpc_server; +#else + +/* Wrapper struct for grpc_server that can be associated with a PHP object */ +typedef struct wrapped_grpc_server { grpc_server *wrapped; + zend_object std; } wrapped_grpc_server; +static inline wrapped_grpc_server +*wrapped_grpc_server_from_obj(zend_object *obj) { + return (wrapped_grpc_server*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_server, std)); +} + +#define Z_WRAPPED_GRPC_SERVER_P(zv) \ + wrapped_grpc_server_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the Server class */ void grpc_init_server(TSRMLS_D); diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index 505da10a28288..296632d5bdd80 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -51,6 +51,8 @@ zend_class_entry *grpc_ce_server_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instace of wrapped_grpc_server_credentials */ void free_wrapped_grpc_server_credentials(void *object TSRMLS_DC) { wrapped_grpc_server_credentials *creds = @@ -58,6 +60,7 @@ void free_wrapped_grpc_server_credentials(void *object TSRMLS_DC) { if (creds->wrapped != NULL) { grpc_server_credentials_release(creds->wrapped); } + zend_object_std_dtor(&creds->std TSRMLS_CC); efree(creds); } @@ -81,7 +84,8 @@ zend_object_value create_wrapped_grpc_server_credentials( return retval; } -zval *grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped TSRMLS_DC) { +zval *grpc_php_wrap_server_credentials(grpc_server_credentials + *wrapped TSRMLS_DC) { zval *server_credentials_object; MAKE_STD_ZVAL(server_credentials_object); object_init_ex(server_credentials_object, grpc_ce_server_credentials); @@ -92,6 +96,43 @@ zval *grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped TSRMLS_D return server_credentials_object; } +#else + +static zend_object_handlers server_credentials_ce_handlers; + +/* Frees and destroys an instace of wrapped_grpc_server_credentials */ +static void free_wrapped_grpc_server_credentials(zend_object *object) { + wrapped_grpc_server_credentials *creds = + wrapped_grpc_server_creds_from_obj(object); + if (creds->wrapped != NULL) { + grpc_server_credentials_release(creds->wrapped); + } + zend_object_std_dtor(&creds->std); +} + +/* Initializes an instace of wrapped_grpc_server_credentials to be associated + * with an object of a class specified by class_type */ +zend_object *create_wrapped_grpc_server_credentials(zend_class_entry + *class_type) { + wrapped_grpc_server_credentials *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_server_credentials) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &server_credentials_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped, + zval *server_credentials_object) { + object_init_ex(server_credentials_object, grpc_ce_server_credentials); + wrapped_grpc_server_credentials *server_credentials = + Z_WRAPPED_GRPC_SERVER_CREDS_P(server_credentials_object); + server_credentials->wrapped = wrapped; +} + +#endif + /** * Create SSL credentials. * @param string pem_root_certs PEM encoding of the server root certificates @@ -103,7 +144,11 @@ PHP_METHOD(ServerCredentials, createSsl) { char *pem_root_certs = 0; grpc_ssl_pem_key_cert_pair pem_key_cert_pair; +#if PHP_MAJOR_VERSION < 7 int root_certs_length = 0, private_key_length, cert_chain_length; +#else + size_t root_certs_length = 0, private_key_length, cert_chain_length; +#endif /* "s!ss" == 1 nullable string, 2 strings */ /* TODO: support multiple key cert pairs. */ @@ -120,17 +165,33 @@ PHP_METHOD(ServerCredentials, createSsl) { grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex( pem_root_certs, &pem_key_cert_pair, 1, GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL); +#if PHP_MAJOR_VERSION < 7 zval *creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); +#else + grpc_php_wrap_server_credentials(creds, return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } static zend_function_entry server_credentials_methods[] = { - PHP_ME(ServerCredentials, createSsl, NULL, - ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; + PHP_ME(ServerCredentials, createSsl, NULL, + ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END + }; void grpc_init_server_credentials(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\ServerCredentials", server_credentials_methods); ce.create_object = create_wrapped_grpc_server_credentials; grpc_ce_server_credentials = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&server_credentials_ce_handlers, + zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + server_credentials_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_server_credentials, std); + server_credentials_ce_handlers.free_obj = + free_wrapped_grpc_server_credentials; +#endif } diff --git a/src/php/ext/grpc/server_credentials.h b/src/php/ext/grpc/server_credentials.h index 7101d650008af..d37fafc0dc08b 100755 --- a/src/php/ext/grpc/server_credentials.h +++ b/src/php/ext/grpc/server_credentials.h @@ -49,14 +49,34 @@ /* Class entry for the Server_Credentials PHP class */ extern zend_class_entry *grpc_ce_server_credentials; +#if PHP_MAJOR_VERSION < 7 + /* Wrapper struct for grpc_server_credentials that can be associated with a PHP * object */ typedef struct wrapped_grpc_server_credentials { zend_object std; + grpc_server_credentials *wrapped; +} wrapped_grpc_server_credentials; +#else + +typedef struct wrapped_grpc_server_credentials { grpc_server_credentials *wrapped; + zend_object std; } wrapped_grpc_server_credentials; +static inline wrapped_grpc_server_credentials +*wrapped_grpc_server_creds_from_obj(zend_object *obj) { + return (wrapped_grpc_server_credentials*) + ((char*)(obj) - + XtOffsetOf(wrapped_grpc_server_credentials, std)); +} + +#define Z_WRAPPED_GRPC_SERVER_CREDS_P(zv) \ + wrapped_grpc_server_creds_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initializes the Server_Credentials PHP class */ void grpc_init_server_credentials(TSRMLS_D); diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c index 5e242162a8cb6..8dc997c2ddae3 100644 --- a/src/php/ext/grpc/timeval.c +++ b/src/php/ext/grpc/timeval.c @@ -52,8 +52,14 @@ zend_class_entry *grpc_ce_timeval; +#if PHP_MAJOR_VERSION < 7 + /* Frees and destroys an instance of wrapped_grpc_call */ -void free_wrapped_grpc_timeval(void *object TSRMLS_DC) { efree(object); } +void free_wrapped_grpc_timeval(void *object TSRMLS_DC) { + wrapped_grpc_timeval *timeval = (wrapped_grpc_timeval *)object; + zend_object_std_dtor(&timeval->std TSRMLS_CC); + efree(timeval); +} /* Initializes an instance of wrapped_grpc_timeval to be associated with an * object of a class specified by class_type */ @@ -83,14 +89,50 @@ zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC) { return timeval_object; } +#else + +static zend_object_handlers timeval_ce_handlers; + +/* Frees and destroys an instance of wrapped_grpc_call */ +static void free_wrapped_grpc_timeval(zend_object *object) { + wrapped_grpc_timeval *timeval = wrapped_grpc_timeval_from_obj(object); + zend_object_std_dtor(&timeval->std); +} + +/* Initializes an instance of wrapped_grpc_timeval to be associated with an + * object of a class specified by class_type */ +zend_object *create_wrapped_grpc_timeval(zend_class_entry *class_type) { + wrapped_grpc_timeval *intern; + intern = ecalloc(1, sizeof(wrapped_grpc_timeval) + + zend_object_properties_size(class_type)); + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &timeval_ce_handlers; + return &intern->std; +} + +void grpc_php_wrap_timeval(gpr_timespec wrapped, zval *timeval_object) { + object_init_ex(timeval_object, grpc_ce_timeval); + wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(timeval_object); + memcpy(&timeval->wrapped, &wrapped, sizeof(gpr_timespec)); +} + +#endif + /** * Constructs a new instance of the Timeval class * @param long $usec The number of microseconds in the interval */ PHP_METHOD(Timeval, __construct) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *timeval = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); long microseconds; +#else + wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + zend_long microseconds; +#endif + /* "l" == 1 long */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", µseconds) == FAILURE) { @@ -110,6 +152,7 @@ PHP_METHOD(Timeval, __construct) { */ PHP_METHOD(Timeval, add) { zval *other_obj; + /* "O" == 1 Object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &other_obj, grpc_ce_timeval) == FAILURE) { @@ -117,13 +160,23 @@ PHP_METHOD(Timeval, add) { "add expects a Timeval", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *self = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); wrapped_grpc_timeval *other = (wrapped_grpc_timeval *)zend_object_store_get_object(other_obj TSRMLS_CC); zval *sum = - grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) TSRMLS_CC); + grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(sum); +#else + wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); + + grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped), + return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -134,6 +187,7 @@ PHP_METHOD(Timeval, add) { */ PHP_METHOD(Timeval, subtract) { zval *other_obj; + /* "O" == 1 Object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &other_obj, grpc_ce_timeval) == FAILURE) { @@ -141,13 +195,22 @@ PHP_METHOD(Timeval, subtract) { "subtract expects a Timeval", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *self = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); wrapped_grpc_timeval *other = (wrapped_grpc_timeval *)zend_object_store_get_object(other_obj TSRMLS_CC); zval *diff = - grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) TSRMLS_CC); + grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(diff); +#else + wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); + grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped), + return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -158,7 +221,9 @@ PHP_METHOD(Timeval, subtract) { * @return long */ PHP_METHOD(Timeval, compare) { - zval *a_obj, *b_obj; + zval *a_obj; + zval *b_obj; + /* "OO" == 2 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &a_obj, grpc_ce_timeval, &b_obj, @@ -167,10 +232,15 @@ PHP_METHOD(Timeval, compare) { "compare expects two Timevals", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *a = (wrapped_grpc_timeval *)zend_object_store_get_object(a_obj TSRMLS_CC); wrapped_grpc_timeval *b = (wrapped_grpc_timeval *)zend_object_store_get_object(b_obj TSRMLS_CC); +#else + wrapped_grpc_timeval *a = Z_WRAPPED_GRPC_TIMEVAL_P(a_obj); + wrapped_grpc_timeval *b = Z_WRAPPED_GRPC_TIMEVAL_P(b_obj); +#endif long result = gpr_time_cmp(a->wrapped, b->wrapped); RETURN_LONG(result); } @@ -183,7 +253,10 @@ PHP_METHOD(Timeval, compare) { * @return bool True if $a and $b are within $threshold, False otherwise */ PHP_METHOD(Timeval, similar) { - zval *a_obj, *b_obj, *thresh_obj; + zval *a_obj; + zval *b_obj; + zval *thresh_obj; + /* "OOO" == 3 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OOO", &a_obj, grpc_ce_timeval, &b_obj, grpc_ce_timeval, @@ -192,6 +265,7 @@ PHP_METHOD(Timeval, similar) { "compare expects three Timevals", 1 TSRMLS_CC); return; } +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *a = (wrapped_grpc_timeval *)zend_object_store_get_object(a_obj TSRMLS_CC); wrapped_grpc_timeval *b = @@ -199,6 +273,11 @@ PHP_METHOD(Timeval, similar) { wrapped_grpc_timeval *thresh = (wrapped_grpc_timeval *)zend_object_store_get_object( thresh_obj TSRMLS_CC); +#else + wrapped_grpc_timeval *a = Z_WRAPPED_GRPC_TIMEVAL_P(a_obj); + wrapped_grpc_timeval *b = Z_WRAPPED_GRPC_TIMEVAL_P(b_obj); + wrapped_grpc_timeval *thresh = Z_WRAPPED_GRPC_TIMEVAL_P(thresh_obj); +#endif int result = gpr_time_similar(a->wrapped, b->wrapped, thresh->wrapped); RETURN_BOOL(result); } @@ -208,8 +287,13 @@ PHP_METHOD(Timeval, similar) { * @return Timeval The current time */ PHP_METHOD(Timeval, now) { +#if PHP_MAJOR_VERSION < 7 zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(now); +#else + grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME), return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -217,11 +301,18 @@ PHP_METHOD(Timeval, now) { * @return Timeval Zero length time interval */ PHP_METHOD(Timeval, zero) { +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_timeval_zero = grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_ZVAL(grpc_php_timeval_zero, false, /* Copy original before returning? */ true /* Destroy original before returning */); +#else + grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME), return_value); + RETURN_ZVAL(return_value, + false, /* Copy original before returning? */ + true /* Destroy original before returning */); +#endif } /** @@ -229,9 +320,14 @@ PHP_METHOD(Timeval, zero) { * @return Timeval Infinite future time value */ PHP_METHOD(Timeval, infFuture) { +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_timeval_inf_future = grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future); +#else + grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME), return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -239,9 +335,14 @@ PHP_METHOD(Timeval, infFuture) { * @return Timeval Infinite past time value */ PHP_METHOD(Timeval, infPast) { +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_timeval_inf_past = grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past); +#else + grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME), return_value); + RETURN_DESTROY_ZVAL(return_value); +#endif } /** @@ -249,28 +350,41 @@ PHP_METHOD(Timeval, infPast) { * @return void */ PHP_METHOD(Timeval, sleepUntil) { +#if PHP_MAJOR_VERSION < 7 wrapped_grpc_timeval *this = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); +#else + wrapped_grpc_timeval *this = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); +#endif gpr_sleep_until(this->wrapped); } static zend_function_entry timeval_methods[] = { - PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; + PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; void grpc_init_timeval(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Timeval", timeval_methods); ce.create_object = create_wrapped_grpc_timeval; grpc_ce_timeval = zend_register_internal_class(&ce TSRMLS_CC); +#if PHP_MAJOR_VERSION >= 7 + memcpy(&timeval_ce_handlers, zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + timeval_ce_handlers.offset = + XtOffsetOf(wrapped_grpc_timeval, std); + timeval_ce_handlers.free_obj = free_wrapped_grpc_timeval; +#endif } void grpc_shutdown_timeval(TSRMLS_D) {} diff --git a/src/php/ext/grpc/timeval.h b/src/php/ext/grpc/timeval.h index 7456eb6d58ca8..d4eb2facde923 100755 --- a/src/php/ext/grpc/timeval.h +++ b/src/php/ext/grpc/timeval.h @@ -50,12 +50,31 @@ extern zend_class_entry *grpc_ce_timeval; /* Wrapper struct for timeval that can be associated with a PHP object */ +#if PHP_MAJOR_VERSION < 7 + typedef struct wrapped_grpc_timeval { zend_object std; + gpr_timespec wrapped; +} wrapped_grpc_timeval; +#else + +typedef struct wrapped_grpc_timeval { gpr_timespec wrapped; + zend_object std; } wrapped_grpc_timeval; +static inline wrapped_grpc_timeval +*wrapped_grpc_timeval_from_obj(zend_object *obj) { + return (wrapped_grpc_timeval*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_timeval, std)); +} + +#define Z_WRAPPED_GRPC_TIMEVAL_P(zv) \ + wrapped_grpc_timeval_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ + /* Initialize the Timeval PHP class */ void grpc_init_timeval(TSRMLS_D); @@ -63,6 +82,10 @@ void grpc_init_timeval(TSRMLS_D); void grpc_shutdown_timeval(TSRMLS_D); /* Creates a Timeval object that wraps the given timeval struct */ +#if PHP_MAJOR_VERSION < 7 zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC); +#else +void grpc_php_wrap_timeval(gpr_timespec wrapped, zval *timeval_object); +#endif /* PHP_MAJOR_VERSION */ #endif /* NET_GRPC_PHP_GRPC_TIMEVAL_H_ */ diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php old mode 100755 new mode 100644 index df3fe85d447fc..2fec1bd9cc44a --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -84,8 +84,8 @@ public function __construct($hostname, $opts, $channel = null) } if ($channel) { if (!is_a($channel, 'Channel')) { - throw new \Exception("The channel argument is not a". - "Channel object"); + throw new \Exception('The channel argument is not a'. + 'Channel object'); } $this->channel = $channel; } else { diff --git a/src/php/lib/Grpc/BidiStreamingCall.php b/src/php/lib/Grpc/BidiStreamingCall.php index 95e51c5088daf..c2fdb94b8673d 100644 --- a/src/php/lib/Grpc/BidiStreamingCall.php +++ b/src/php/lib/Grpc/BidiStreamingCall.php @@ -113,6 +113,7 @@ public function getStatus() ]); $this->trailing_metadata = $status_event->status->metadata; + return $status_event->status; } } diff --git a/src/php/lib/Grpc/ClientStreamingCall.php b/src/php/lib/Grpc/ClientStreamingCall.php index 315a406735feb..4050f7ed06d84 100644 --- a/src/php/lib/Grpc/ClientStreamingCall.php +++ b/src/php/lib/Grpc/ClientStreamingCall.php @@ -88,6 +88,7 @@ public function wait() $status = $event->status; $this->trailing_metadata = $status->metadata; + return [$this->deserializeResponse($event->message), $status]; } } diff --git a/src/php/lib/Grpc/ServerStreamingCall.php b/src/php/lib/Grpc/ServerStreamingCall.php index 53599fe4ae841..ba89d9f97216c 100644 --- a/src/php/lib/Grpc/ServerStreamingCall.php +++ b/src/php/lib/Grpc/ServerStreamingCall.php @@ -92,6 +92,7 @@ public function getStatus() ]); $this->trailing_metadata = $status_event->status->metadata; + return $status_event->status; } } diff --git a/src/php/lib/Grpc/UnaryCall.php b/src/php/lib/Grpc/UnaryCall.php index b114b771b8436..a71b05dc93dd3 100644 --- a/src/php/lib/Grpc/UnaryCall.php +++ b/src/php/lib/Grpc/UnaryCall.php @@ -77,6 +77,7 @@ public function wait() $status = $event->status; $this->trailing_metadata = $status->metadata; + return [$this->deserializeResponse($event->message), $status]; } } diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 43b3199d92c03..bf40549a04f3e 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -450,7 +450,7 @@ function statusCodeAndMessage($stub) { $echo_status = new grpc\testing\EchoStatus(); $echo_status->setCode(2); - $echo_status->setMessage("test status message"); + $echo_status->setMessage('test status message'); $request = new grpc\testing\SimpleRequest(); $request->setResponseStatus($echo_status); @@ -460,7 +460,7 @@ function statusCodeAndMessage($stub) hardAssert($status->code === 2, 'Received unexpected status code'); - hardAssert($status->details === "test status message", + hardAssert($status->details === 'test status message', 'Received unexpected status details'); $streaming_call = $stub->FullDuplexCall(); @@ -473,7 +473,7 @@ function statusCodeAndMessage($stub) $status = $streaming_call->getStatus(); hardAssert($status->code === 2, 'Received unexpected status code'); - hardAssert($status->details === "test status message", + hardAssert($status->details === 'test status message', 'Received unexpected status details'); } @@ -570,9 +570,9 @@ function ($metadata, } if ($test_case == 'unimplemented_method') { - $stub = new grpc\testing\UnimplementedServiceClient($server_address, $opts); + $stub = new grpc\testing\UnimplementedServiceClient($server_address, $opts); } else { - $stub = new grpc\testing\TestServiceClient($server_address, $opts); + $stub = new grpc\testing\TestServiceClient($server_address, $opts); } return $stub; diff --git a/src/php/tests/unit_tests/CallCredentialsTest.php b/src/php/tests/unit_tests/CallCredentialsTest.php index 5fec06cd13395..1994c8afe56e6 100644 --- a/src/php/tests/unit_tests/CallCredentialsTest.php +++ b/src/php/tests/unit_tests/CallCredentialsTest.php @@ -148,7 +148,8 @@ public function testCreateComposite() $this->call_credentials, $call_credentials2 ); - $this->assertSame('Grpc\CallCredentials', get_class($call_credentials3)); + $this->assertSame('Grpc\CallCredentials', + get_class($call_credentials3)); } /** diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php old mode 100755 new mode 100644 index fa026f0935097..d736f5154605a --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -50,6 +50,18 @@ public function setUp() Grpc\Timeval::infFuture()); } + public function tearDown() + { + unset($this->call); + unset($this->channel); + } + + public function testConstructor() + { + $this->assertSame('Grpc\Call', get_class($this->call)); + $this->assertObjectHasAttribute('channel', $this->call); + } + public function testAddEmptyMetadata() { $batch = [ @@ -81,7 +93,8 @@ public function testAddSingleAndMultiValueMetadata() { $batch = [ Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], - 'key2' => ['value2', 'value3'], ], + 'key2' => ['value2', + 'value3'], ], ]; $result = $this->call->startBatch($batch); $this->assertTrue($result->send_metadata); @@ -118,4 +131,38 @@ public function testInvalidMetadataInnerValue() ]; $result = $this->call->startBatch($batch); } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstuctor() + { + $this->call = new Grpc\Call(); + $this->assertNull($this->call); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstuctor2() + { + $this->call = new Grpc\Call('hi', 'hi', 'hi'); + $this->assertNull($this->call); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidSetCredentials() + { + $this->call->setCredentials('hi'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidSetCredentials2() + { + $this->call->setCredentials([]); + } } diff --git a/src/php/tests/unit_tests/ChannelCredentialsTest.php b/src/php/tests/unit_tests/ChannelCredentialsTest.php index 56c1d8f006de6..e822929ccdaa8 100644 --- a/src/php/tests/unit_tests/ChannelCredentialsTest.php +++ b/src/php/tests/unit_tests/ChannelCredentialsTest.php @@ -42,10 +42,23 @@ public function tearDown() { } - public function testCreateDefault() + public function testCreateSslWith3Null() { - $channel_credentials = Grpc\ChannelCredentials::createDefault(); - $this->assertSame('Grpc\ChannelCredentials', get_class($channel_credentials)); + $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, + null); + $this->assertNotNull($channel_credentials); + } + + public function testCreateSslWith3NullString() + { + $channel_credentials = Grpc\ChannelCredentials::createSsl('', '', ''); + $this->assertNotNull($channel_credentials); + } + + public function testCreateInsecure() + { + $channel_credentials = Grpc\ChannelCredentials::createInsecure(); + $this->assertNull($channel_credentials); } /** @@ -64,10 +77,4 @@ public function testInvalidCreateComposite() $channel_credentials = Grpc\ChannelCredentials::createComposite( 'something', 'something'); } - - public function testCreateInsecure() - { - $channel_credentials = Grpc\ChannelCredentials::createInsecure(); - $this->assertNull($channel_credentials); - } } diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php index a1f9053c3989b..4b35b1a28cc00 100644 --- a/src/php/tests/unit_tests/ChannelTest.php +++ b/src/php/tests/unit_tests/ChannelTest.php @@ -40,6 +40,7 @@ public function setUp() public function tearDown() { + unset($this->channel); } public function testInsecureCredentials() @@ -53,6 +54,82 @@ public function testInsecureCredentials() $this->assertSame('Grpc\Channel', get_class($this->channel)); } + public function testGetConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithInt() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(123); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithString() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState('hello'); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithBool() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(true); + $this->assertEquals(0, $state); + } + + public function testGetTarget() + { + $this->channel = new Grpc\Channel('localhost:8888', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $target = $this->channel->getTarget(); + $this->assertTrue(is_string($target)); + } + + public function testWatchConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $time = new Grpc\Timeval(1000); + $state = $this->channel->watchConnectivityState(123, $time); + $this->assertTrue($state); + unset($time); + } + + public function testClose() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->assertNotNull($this->channel); + $this->channel->close(); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstructorWithNull() + { + $this->channel = new Grpc\Channel(); + $this->assertNull($this->channel); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstructorWith() + { + $this->channel = new Grpc\Channel('localhost', 'invalid'); + $this->assertNull($this->channel); + } + /** * @expectedException InvalidArgumentException */ @@ -78,4 +155,34 @@ public function testInvalidOptionsArray() ] ); } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidGetConnectivityStateWithArray() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->getConnectivityState([]); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidWatchConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->watchConnectivityState([]); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidWatchConnectivityState2() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->watchConnectivityState(1, 'hi'); + } } diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php old mode 100755 new mode 100644 index 2b09f9d112a3a..09364580c01c7 --- a/src/php/tests/unit_tests/EndToEndTest.php +++ b/src/php/tests/unit_tests/EndToEndTest.php @@ -521,7 +521,8 @@ public function testGetTarget() public function testGetConnectivityState() { - $this->assertTrue($this->channel->getConnectivityState() == Grpc\CHANNEL_IDLE); + $this->assertTrue($this->channel->getConnectivityState() == + Grpc\CHANNEL_IDLE); } public function testWatchConnectivityStateFailed() diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php old mode 100755 new mode 100644 diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php index 76aaa069704b6..f2346ab113ee3 100644 --- a/src/php/tests/unit_tests/ServerTest.php +++ b/src/php/tests/unit_tests/ServerTest.php @@ -36,10 +36,70 @@ class ServerTest extends PHPUnit_Framework_TestCase { public function setUp() { + $this->server = null; } public function tearDown() { + unset($this->server); + } + + public function testConstructorWithNull() + { + $this->server = new Grpc\Server(); + $this->assertNotNull($this->server); + } + + public function testConstructorWithNullArray() + { + $this->server = new Grpc\Server([]); + $this->assertNotNull($this->server); + } + + public function testConstructorWithArray() + { + // key of array must be string + $this->server = new Grpc\Server(['ip' => '127.0.0.1', + 'port' => '8080', ]); + $this->assertNotNull($this->server); + } + + public function testRequestCall() + { + $this->server = new Grpc\Server(); + $port = $this->server->addHttp2Port('0.0.0.0:8888'); + $this->server->start(); + $channel = new Grpc\Channel('localhost:8888', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + + $deadline = Grpc\Timeval::infFuture(); + $call = new Grpc\Call($channel, 'dummy_method', $deadline); + + $event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + ]); + + $c = $this->server->requestCall(); + $this->assertObjectHasAttribute('call', $c); + $this->assertObjectHasAttribute('method', $c); + $this->assertSame('dummy_method', $c->method); + $this->assertObjectHasAttribute('host', $c); + $this->assertTrue(is_string($c->host)); + $this->assertObjectHasAttribute('absolute_deadline', $c); + $this->assertObjectHasAttribute('metadata', $c); + + unset($call); + unset($channel); + } + + private function createSslObj() + { + $server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); + + return $server_credentials; } /** @@ -47,7 +107,8 @@ public function tearDown() */ public function testInvalidConstructor() { - $server = new Grpc\Server('invalid_host'); + $this->server = new Grpc\Server('invalid_host'); + $this->assertNull($this->server); } /** @@ -56,7 +117,7 @@ public function testInvalidConstructor() public function testInvalidAddHttp2Port() { $this->server = new Grpc\Server([]); - $this->port = $this->server->addHttp2Port(['0.0.0.0:0']); + $port = $this->server->addHttp2Port(['0.0.0.0:0']); } /** @@ -65,6 +126,24 @@ public function testInvalidAddHttp2Port() public function testInvalidAddSecureHttp2Port() { $this->server = new Grpc\Server([]); - $this->port = $this->server->addSecureHttp2Port(['0.0.0.0:0']); + $port = $this->server->addSecureHttp2Port(['0.0.0.0:0']); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidAddSecureHttp2Port2() + { + $this->server = new Grpc\Server(); + $port = $this->server->addSecureHttp2Port('0.0.0.0:0'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidAddSecureHttp2Port3() + { + $this->server = new Grpc\Server(); + $port = $this->server->addSecureHttp2Port('0.0.0.0:0', 'invalid'); } } diff --git a/src/php/tests/unit_tests/TimevalTest.php b/src/php/tests/unit_tests/TimevalTest.php old mode 100755 new mode 100644 index a3dbce079f470..2d19f64c79990 --- a/src/php/tests/unit_tests/TimevalTest.php +++ b/src/php/tests/unit_tests/TimevalTest.php @@ -33,6 +33,57 @@ */ class TimevalTest extends PHPUnit_Framework_TestCase { + public function setUp() + { + } + + public function tearDown() + { + unset($this->time); + } + + public function testConstructorWithInt() + { + $this->time = new Grpc\Timeval(1234); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithNegative() + { + $this->time = new Grpc\Timeval(-123); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithZero() + { + $this->time = new Grpc\Timeval(0); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithOct() + { + $this->time = new Grpc\Timeval(0123); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithHex() + { + $this->time = new Grpc\Timeval(0x1A); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithFloat() + { + $this->time = new Grpc\Timeval(123.456); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + public function testCompareSame() { $zero = Grpc\Timeval::zero(); @@ -70,6 +121,7 @@ public function testNowIsBetweenZeroAndFuture() public function testNowAndAdd() { $now = Grpc\Timeval::now(); + $this->assertNotNull($now); $delta = new Grpc\Timeval(1000); $deadline = $now->add($delta); $this->assertGreaterThan(0, Grpc\Timeval::compare($deadline, $now)); @@ -154,5 +206,6 @@ public function testCompareInvalidParam() public function testSimilarInvalidParam() { $a = Grpc\Timeval::similar(1000, 1100, 1200); + $this->assertNull($delta); } } From ac8df657a56cbb8010eec54755051da0a333cd0e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 21 Jul 2016 07:25:24 -0700 Subject: [PATCH 127/151] clang-format --- src/core/lib/channel/handshaker.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index ed8eb4a7f84f9..b3ee0ed6f93fd 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -63,7 +63,7 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, gpr_timespec deadline, - grpc_tcp_server_acceptor *acceptor, + grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data) { handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, deadline, acceptor, cb, user_data); @@ -80,7 +80,7 @@ struct grpc_handshaker_state { // The deadline for all handshakers. gpr_timespec deadline; // The acceptor to call the handshakers with. - grpc_tcp_server_acceptor *acceptor; + grpc_tcp_server_acceptor* acceptor; // The final callback and user_data to invoke after the last handshaker. grpc_handshaker_done_cb final_cb; void* final_user_data; @@ -100,9 +100,7 @@ grpc_handshake_manager* grpc_handshake_manager_create() { return mgr; } -static bool is_power_of_2(size_t n) { - return (n & (n - 1)) == 0; -} +static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; } void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr) { @@ -115,8 +113,8 @@ void grpc_handshake_manager_add(grpc_handshaker* handshaker, realloc_count = mgr->count * 2; } if (realloc_count > 0) { - mgr->handshakers = gpr_realloc(mgr->handshakers, - realloc_count * sizeof(grpc_handshaker*)); + mgr->handshakers = + gpr_realloc(mgr->handshakers, realloc_count * sizeof(grpc_handshaker*)); } mgr->handshakers[mgr->count++] = handshaker; } @@ -173,7 +171,7 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void grpc_handshake_manager_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, const grpc_channel_args* args, - gpr_timespec deadline, grpc_tcp_server_acceptor *acceptor, + gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data) { grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { From fca59fb2aa4a0be093d12162c763b8563ada4087 Mon Sep 17 00:00:00 2001 From: Sanjay Ghemawat Date: Thu, 21 Jul 2016 09:32:06 -0700 Subject: [PATCH 128/151] Add gpr_slice_new_with_user_data. gpr_slice_new_with_user_data is like gpr_slice_new, but allows the caller to specify a distinct pointer to pass to the destroy function. This is useful when the data is part of a larger data structure that should be destroyed when the data is no longer needed. --- include/grpc/impl/codegen/slice.h | 8 ++++++++ src/core/lib/support/slice.c | 11 +++++++++-- test/core/support/slice_test.c | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h index c684b7587d634..dfc0a774fcc12 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -120,6 +120,14 @@ GPRAPI void gpr_slice_unref(gpr_slice s); passed in at destruction. */ GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)); +/* Equivalent to gpr_slice_new, but with a separate pointer that is + passed to the destroy function. This function can be useful when + the data is part of a larger structure that must be destroyed when + the data is no longer needed. */ +GPRAPI gpr_slice gpr_slice_new_with_user_data(void *p, size_t len, + void (*destroy)(void *), + void *user_data); + /* Equivalent to gpr_slice_new, but with a two argument destroy function that also takes the slice length. */ GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len, diff --git a/src/core/lib/support/slice.c b/src/core/lib/support/slice.c index b9a7c77bda6e6..8a2c0a908657e 100644 --- a/src/core/lib/support/slice.c +++ b/src/core/lib/support/slice.c @@ -94,14 +94,16 @@ static void new_slice_unref(void *p) { } } -gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { +gpr_slice gpr_slice_new_with_user_data(void *p, size_t len, + void (*destroy)(void *), + void *user_data) { gpr_slice slice; new_slice_refcount *rc = gpr_malloc(sizeof(new_slice_refcount)); gpr_ref_init(&rc->refs, 1); rc->rc.ref = new_slice_ref; rc->rc.unref = new_slice_unref; rc->user_destroy = destroy; - rc->user_data = p; + rc->user_data = user_data; slice.refcount = &rc->rc; slice.data.refcounted.bytes = p; @@ -109,6 +111,11 @@ gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { return slice; } +gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { + /* Pass "p" to *destroy when the slice is no longer needed. */ + return gpr_slice_new_with_user_data(p, len, destroy, p); +} + /* gpr_slice_new_with_len support structures - we create a refcount object extended with the user provided data pointer & destroy function */ typedef struct new_with_len_slice_refcount { diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c index 0da483a3216d1..06c364b368078 100644 --- a/test/core/support/slice_test.c +++ b/test/core/support/slice_test.c @@ -85,6 +85,27 @@ static void test_slice_new_returns_something_sensible(void) { gpr_slice_unref(slice); } +/* destroy function that sets a mark to indicate it was called. */ +static void set_mark(void *p) { *((int *)p) = 1; } + +static void test_slice_new_with_user_data(void) { + int marker = 0; + uint8_t buf[2]; + gpr_slice slice; + + buf[0] = 0; + buf[1] = 1; + slice = gpr_slice_new_with_user_data(buf, 2, set_mark, &marker); + GPR_ASSERT(marker == 0); + GPR_ASSERT(GPR_SLICE_LENGTH(slice) == 2); + GPR_ASSERT(GPR_SLICE_START_PTR(slice)[0] == 0); + GPR_ASSERT(GPR_SLICE_START_PTR(slice)[1] == 1); + + /* unref should cause destroy function to run. */ + gpr_slice_unref(slice); + GPR_ASSERT(marker == 1); +} + static int do_nothing_with_len_1_calls = 0; static void do_nothing_with_len_1(void *ignored, size_t len) { @@ -232,6 +253,7 @@ int main(int argc, char **argv) { grpc_test_init(argc, argv); test_slice_malloc_returns_something_sensible(); test_slice_new_returns_something_sensible(); + test_slice_new_with_user_data(); test_slice_new_with_len_returns_something_sensible(); for (length = 0; length < 128; length++) { test_slice_sub_works(length); From 4f37dc3ca9c9fc80337f4e63188d21ad3e9059d6 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 21 Jul 2016 10:22:07 -0700 Subject: [PATCH 129/151] php: fix minor style discrepency --- src/php/tests/interop/interop_client.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 43b3199d92c03..bf40549a04f3e 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -450,7 +450,7 @@ function statusCodeAndMessage($stub) { $echo_status = new grpc\testing\EchoStatus(); $echo_status->setCode(2); - $echo_status->setMessage("test status message"); + $echo_status->setMessage('test status message'); $request = new grpc\testing\SimpleRequest(); $request->setResponseStatus($echo_status); @@ -460,7 +460,7 @@ function statusCodeAndMessage($stub) hardAssert($status->code === 2, 'Received unexpected status code'); - hardAssert($status->details === "test status message", + hardAssert($status->details === 'test status message', 'Received unexpected status details'); $streaming_call = $stub->FullDuplexCall(); @@ -473,7 +473,7 @@ function statusCodeAndMessage($stub) $status = $streaming_call->getStatus(); hardAssert($status->code === 2, 'Received unexpected status code'); - hardAssert($status->details === "test status message", + hardAssert($status->details === 'test status message', 'Received unexpected status details'); } @@ -570,9 +570,9 @@ function ($metadata, } if ($test_case == 'unimplemented_method') { - $stub = new grpc\testing\UnimplementedServiceClient($server_address, $opts); + $stub = new grpc\testing\UnimplementedServiceClient($server_address, $opts); } else { - $stub = new grpc\testing\TestServiceClient($server_address, $opts); + $stub = new grpc\testing\TestServiceClient($server_address, $opts); } return $stub; From 20b8333efaa2bc76fbb3d03c62fd8d27b37117a6 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 21 Jul 2016 19:28:38 +0200 Subject: [PATCH 130/151] Sanitizing master. --- gRPC-Core.podspec | 3 ++- src/core/ext/client_config/channel_connectivity.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 0678f3b3ae7df..f7d87017351db 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -195,6 +195,7 @@ Pod::Spec.new do |s| ss.dependency "#{s.name}/Interface", version ss.dependency 'BoringSSL', '~> 4.0' + # To save you from scrolling, this is the last part of the podspec. ss.source_files = 'src/core/lib/profiling/timers.h', 'src/core/lib/support/backoff.h', 'src/core/lib/support/block_annotate.h', @@ -760,7 +761,7 @@ Pod::Spec.new do |s| 'src/core/ext/census/mlog.h', 'src/core/ext/census/rpc_metric_id.h' end - + s.subspec 'Cronet-Interface' do |ss| ss.header_mappings_dir = 'include/grpc' ss.source_files = 'include/grpc/grpc_cronet.h' diff --git a/src/core/ext/client_config/channel_connectivity.c b/src/core/ext/client_config/channel_connectivity.c index 03db06c2f741c..ce3c13a4ee350 100644 --- a/src/core/ext/client_config/channel_connectivity.c +++ b/src/core/ext/client_config/channel_connectivity.c @@ -59,7 +59,8 @@ grpc_connectivity_state grpc_channel_check_connectivity_state( } gpr_log(GPR_ERROR, "grpc_channel_check_connectivity_state called on something that is " - "not a client channel, but '%s'", client_channel_elem->filter->name); + "not a client channel, but '%s'", + client_channel_elem->filter->name); grpc_exec_ctx_finish(&exec_ctx); return GRPC_CHANNEL_SHUTDOWN; } From b16b1f29c3aa7238814cd70a4abcee0f35dc6b9f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 21 Jul 2016 11:24:32 -0700 Subject: [PATCH 131/151] clang-format --- .../ext/transport/chttp2/server/insecure/server_chttp2.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index 8dac63c33bc74..016ce110fe017 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -88,10 +88,9 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, // args instead of hard-coding it. const gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); - grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, - grpc_server_get_channel_args(server), - deadline, acceptor, on_handshake_done, - state); + grpc_handshake_manager_do_handshake( + exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(server), + deadline, acceptor, on_handshake_done, state); } /* Server callback: start listening on our ports */ From cc17af1681e2d198e7b57190a7e343067989a05f Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 21 Jul 2016 11:08:46 -0700 Subject: [PATCH 132/151] Remove non-manylinux linux .whl artifacts --- tools/run_tests/artifact_targets.py | 1 + tools/run_tests/build_artifact_python.sh | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py index d9f8a2072c8ce..1c480f7a7f4cc 100644 --- a/tools/run_tests/artifact_targets.py +++ b/tools/run_tests/artifact_targets.py @@ -119,6 +119,7 @@ def build_jobspec(self): # need to do this manually... environ['CFLAGS'] = '-DGPR_MANYLINUX1=1' environ['BUILD_HEALTH_CHECKING'] = 'TRUE' + environ['BUILD_MANYLINUX_WHEEL'] = 'TRUE' return create_docker_jobspec(self.name, 'tools/dockerfile/grpc_artifact_python_manylinux_%s' % self.arch, 'tools/run_tests/build_artifact_python.sh', diff --git a/tools/run_tests/build_artifact_python.sh b/tools/run_tests/build_artifact_python.sh index 9c71235e11ca6..8f8330ef24f81 100755 --- a/tools/run_tests/build_artifact_python.sh +++ b/tools/run_tests/build_artifact_python.sh @@ -62,13 +62,15 @@ CFLAGS="$CFLAGS -fno-wrapv" ${SETARCH_CMD} \ ${PYTHON} tools/distrib/python/grpcio_tools/setup.py bdist_wheel mkdir -p artifacts -if command -v ${AUDITWHEEL} +if [ "$BUILD_MANYLINUX_WHEEL" != "" ] then for wheel in dist/*.whl; do ${AUDITWHEEL} repair $wheel -w artifacts/ + rm $wheel done for wheel in tools/distrib/python/grpcio_tools/dist/*.whl; do ${AUDITWHEEL} repair $wheel -w artifacts/ + rm $wheel done fi From 8d3e9ec9c2bfd2586554762374367f2e72325b88 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 21 Jul 2016 14:07:26 -0700 Subject: [PATCH 133/151] Fix cygrpc test --- src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py index 9d1dbc189b8b4..f9a8e2401bbb8 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py @@ -281,8 +281,8 @@ def testEcho(self): ], server_call_tag) self.assertEqual(cygrpc.CallError.ok, server_start_batch_result) - client_event = client_event_future.result() server_event = self.server_completion_queue.poll(cygrpc_deadline) + client_event = client_event_future.result() self.assertEqual(6, len(client_event.batch_operations)) found_client_op_types = set() From 26100cb1fecc20df4ac0afced747665e48bcc91d Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Thu, 21 Jul 2016 16:16:43 -0700 Subject: [PATCH 134/151] Rerun generate_projects.sh --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index bc330b4207cb6..f725f9cd7bf0f 100644 --- a/Makefile +++ b/Makefile @@ -1933,7 +1933,7 @@ $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/ref $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -3786,7 +3786,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a: $(ZLIB_DEP) $(OPENSSL_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBGRPC++_REFLECTION_CODEGEN_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBGRPC++_REFLECTION_CODEGEN_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a endif From f77b9bf2fe5751c3f01f026422b1679f7216b2d0 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Thu, 21 Jul 2016 19:24:51 -0700 Subject: [PATCH 135/151] Removed unused version of async_stream.h --- .../grpc++/impl/codegen/impl/async_stream.h | 486 ------------------ 1 file changed, 486 deletions(-) delete mode 100644 include/grpc++/impl/codegen/impl/async_stream.h diff --git a/include/grpc++/impl/codegen/impl/async_stream.h b/include/grpc++/impl/codegen/impl/async_stream.h deleted file mode 100644 index 7d7a9568077a3..0000000000000 --- a/include/grpc++/impl/codegen/impl/async_stream.h +++ /dev/null @@ -1,486 +0,0 @@ -/* - * - * 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 GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H -#define GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H - -#include -#include -#include -#include -#include -#include - -namespace grpc { - -class CompletionQueue; - -/// Common interface for all client side asynchronous streaming. -class ClientAsyncStreamingInterface { - public: - virtual ~ClientAsyncStreamingInterface() {} - - /// Request notification of the reading of the initial metadata. Completion - /// will be notified by \a tag on the associated completion queue. - /// - /// \param[in] tag Tag identifying this request. - virtual void ReadInitialMetadata(void* tag) = 0; - - /// Request notification completion. - /// - /// \param[out] status To be updated with the operation status. - /// \param[in] tag Tag identifying this request. - virtual void Finish(Status* status, void* tag) = 0; -}; - -/// An interface that yields a sequence of messages of type \a R. -template -class AsyncReaderInterface { - public: - virtual ~AsyncReaderInterface() {} - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - virtual void Read(R* msg, void* tag) = 0; -}; - -/// An interface that can be fed a sequence of messages of type \a W. -template -class AsyncWriterInterface { - public: - virtual ~AsyncWriterInterface() {} - - /// Request the writing of \a msg with identifying tag \a tag. - /// - /// Only one write may be outstanding at any given time. This means that - /// after calling Write, one must wait to receive \a tag from the completion - /// queue BEFORE calling Write again. - /// - /// \param[in] msg The message to be written. - /// \param[in] tag The tag identifying the operation. - virtual void Write(const W& msg, void* tag) = 0; -}; - -template -class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface, - public AsyncReaderInterface {}; - -template -class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface { - public: - /// Create a stream and write the first request out. - template - ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq, - const RpcMethod& method, ClientContext* context, - const W& request, void* tag) - : context_(context), call_(channel->CreateCall(method, context, cq)) { - init_ops_.set_output_tag(tag); - init_ops_.SendInitialMetadata(context->send_initial_metadata_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); - init_ops_.ClientSendClose(); - call_.PerformOps(&init_ops_); - } - - void ReadInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Finish(Status* status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - ClientContext* context_; - Call call_; - CallOpSet - init_ops_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet finish_ops_; -}; - -/// Common interface for client side asynchronous writing. -template -class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface, - public AsyncWriterInterface { - public: - /// Signal the client is done with the writes. - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; - -template -class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface { - public: - template - ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq, - const RpcMethod& method, ClientContext* context, - R* response, void* tag) - : context_(context), call_(channel->CreateCall(method, context, cq)) { - finish_ops_.RecvMessage(response); - - init_ops_.set_output_tag(tag); - init_ops_.SendInitialMetadata(context->send_initial_metadata_); - call_.PerformOps(&init_ops_); - } - - void ReadInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void WritesDone(void* tag) GRPC_OVERRIDE { - writes_done_ops_.set_output_tag(tag); - writes_done_ops_.ClientSendClose(); - call_.PerformOps(&writes_done_ops_); - } - - void Finish(Status* status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - ClientContext* context_; - Call call_; - CallOpSet init_ops_; - CallOpSet meta_ops_; - CallOpSet write_ops_; - CallOpSet writes_done_ops_; - CallOpSet - finish_ops_; -}; - -/// Client-side interface for asynchronous bi-directional streaming. -template -class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface, - public AsyncWriterInterface, - public AsyncReaderInterface { - public: - /// Signal the client is done with the writes. - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; - -template -class ClientAsyncReaderWriter GRPC_FINAL - : public ClientAsyncReaderWriterInterface { - public: - ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq, - const RpcMethod& method, ClientContext* context, - void* tag) - : context_(context), call_(channel->CreateCall(method, context, cq)) { - init_ops_.set_output_tag(tag); - init_ops_.SendInitialMetadata(context->send_initial_metadata_); - call_.PerformOps(&init_ops_); - } - - void ReadInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void WritesDone(void* tag) GRPC_OVERRIDE { - writes_done_ops_.set_output_tag(tag); - writes_done_ops_.ClientSendClose(); - call_.PerformOps(&writes_done_ops_); - } - - void Finish(Status* status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - ClientContext* context_; - Call call_; - CallOpSet init_ops_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet write_ops_; - CallOpSet writes_done_ops_; - CallOpSet finish_ops_; -}; - -template -class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface, - public AsyncReaderInterface { - public: - virtual void Finish(const W& msg, const Status& status, void* tag) = 0; - - virtual void FinishWithError(const Status& status, void* tag) = 0; -}; - -template -class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface { - public: - explicit ServerAsyncReader(ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - void SendInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Finish(const W& msg, const Status& status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (status.ok()) { - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, - finish_ops_.SendMessage(msg)); - } else { - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - } - call_.PerformOps(&finish_ops_); - } - - void FinishWithError(const Status& status, void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!status.ok()); - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; } - - Call call_; - ServerContext* ctx_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet - finish_ops_; -}; - -template -class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface, - public AsyncWriterInterface { - public: - virtual void Finish(const Status& status, void* tag) = 0; -}; - -template -class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface { - public: - explicit ServerAsyncWriter(ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - void SendInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Finish(const Status& status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; } - - Call call_; - ServerContext* ctx_; - CallOpSet meta_ops_; - CallOpSet write_ops_; - CallOpSet finish_ops_; -}; - -/// Server-side interface for asynchronous bi-directional streaming. -template -class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface, - public AsyncWriterInterface, - public AsyncReaderInterface { - public: - virtual void Finish(const Status& status, void* tag) = 0; -}; - -template -class ServerAsyncReaderWriter GRPC_FINAL - : public ServerAsyncReaderWriterInterface { - public: - explicit ServerAsyncReaderWriter(ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - void SendInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Finish(const Status& status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class ::grpc::Server; - - void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; } - - Call call_; - ServerContext* ctx_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet write_ops_; - CallOpSet finish_ops_; -}; - -} // namespace grpc - -#endif // GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H From 31399d20d9d54ec0b3e92166bb791c83cd371acc Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 21 Jul 2016 20:28:11 -0700 Subject: [PATCH 136/151] php: update package.xml to 1.0.0RC2 --- package.xml | 24 +++++++++++++++++++----- templates/package.xml.template | 24 +++++++++++++++++++----- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/package.xml b/package.xml index c5006dade576c..58e70303c02ba 100644 --- a/package.xml +++ b/package.xml @@ -10,7 +10,7 @@ grpc-packages@google.com yes - 2016-07-13 + 2016-07-21 1.0.0 @@ -22,8 +22,7 @@ BSD -- GA release -- Fix shutdown hang problem #4017 +- PHP7 Support #7464 @@ -1087,8 +1086,8 @@ Update to wrap gRPC C Core version 0.10.0 - 1.0.0 - 1.0.0 + 1.0.0RC1 + 1.0.0RC1 stable @@ -1101,5 +1100,20 @@ Update to wrap gRPC C Core version 0.10.0 - Fix shutdown hang problem #4017 + + + 1.0.0RC2 + 1.0.0RC2 + + + stable + stable + + 2016-07-21 + BSD + +- PHP7 Support #7464 + + diff --git a/templates/package.xml.template b/templates/package.xml.template index 153823ece5b68..76c6fff7a7cfc 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,7 +12,7 @@ grpc-packages@google.com yes - 2016-07-13 + 2016-07-21 ${settings.php_version.php()} @@ -24,8 +24,7 @@ BSD - - GA release - - Fix shutdown hang problem #4017 + - PHP7 Support #7464 @@ -206,8 +205,8 @@ - 1.0.0 - 1.0.0 + 1.0.0RC1 + 1.0.0RC1 stable @@ -220,5 +219,20 @@ - Fix shutdown hang problem #4017 + + + 1.0.0RC2 + 1.0.0RC2 + + + stable + stable + + 2016-07-21 + BSD + + - PHP7 Support #7464 + + From 217c385717e3314113a053d6188f0be77ae19e6f Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 21 Jul 2016 22:34:40 -0700 Subject: [PATCH 137/151] php: update composer.json --- composer.json | 2 +- src/php/composer.json | 2 +- templates/composer.json.template | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 0ebe0a1108447..78366208edbee 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "v0.6" }, "require-dev": { "google/auth": "v0.9" diff --git a/src/php/composer.json b/src/php/composer.json index 23bfcedbe6b82..88418206e82e6 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -8,7 +8,7 @@ "version": "1.0.0", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master", + "stanley-cheung/protobuf-php": "v0.6", "google/auth": "v0.9" }, "autoload": { diff --git a/templates/composer.json.template b/templates/composer.json.template index 07ab1f20ebab2..48d3b8892e203 100644 --- a/templates/composer.json.template +++ b/templates/composer.json.template @@ -9,7 +9,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "v0.6" }, "require-dev": { "google/auth": "v0.9" From b8c87fd33d7ec0f44eb6e8c8d0a350809fa2e61f Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 21 Jul 2016 20:28:11 -0700 Subject: [PATCH 138/151] php: update package.xml to 1.0.0RC2 --- package.xml | 24 +++++++++++++++++++----- templates/package.xml.template | 24 +++++++++++++++++++----- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/package.xml b/package.xml index b5d5f4602a985..b5e4f203be730 100644 --- a/package.xml +++ b/package.xml @@ -10,7 +10,7 @@ grpc-packages@google.com yes - 2016-07-13 + 2016-07-21 1.1.0 @@ -22,8 +22,7 @@ BSD -- GA release -- Fix shutdown hang problem #4017 +- PHP7 Support #7464 @@ -1087,8 +1086,8 @@ Update to wrap gRPC C Core version 0.10.0 - 1.0.0 - 1.0.0 + 1.0.0RC1 + 1.0.0RC1 stable @@ -1101,5 +1100,20 @@ Update to wrap gRPC C Core version 0.10.0 - Fix shutdown hang problem #4017 + + + 1.0.0RC2 + 1.0.0RC2 + + + stable + stable + + 2016-07-21 + BSD + +- PHP7 Support #7464 + + diff --git a/templates/package.xml.template b/templates/package.xml.template index 153823ece5b68..76c6fff7a7cfc 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,7 +12,7 @@ grpc-packages@google.com yes - 2016-07-13 + 2016-07-21 ${settings.php_version.php()} @@ -24,8 +24,7 @@ BSD - - GA release - - Fix shutdown hang problem #4017 + - PHP7 Support #7464 @@ -206,8 +205,8 @@ - 1.0.0 - 1.0.0 + 1.0.0RC1 + 1.0.0RC1 stable @@ -220,5 +219,20 @@ - Fix shutdown hang problem #4017 + + + 1.0.0RC2 + 1.0.0RC2 + + + stable + stable + + 2016-07-21 + BSD + + - PHP7 Support #7464 + + From 35d8474c0e877b03c5bbbb99535151446345113c Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 21 Jul 2016 22:34:40 -0700 Subject: [PATCH 139/151] php: update composer.json --- composer.json | 2 +- src/php/composer.json | 2 +- templates/composer.json.template | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 0ebe0a1108447..78366208edbee 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "v0.6" }, "require-dev": { "google/auth": "v0.9" diff --git a/src/php/composer.json b/src/php/composer.json index 23bfcedbe6b82..88418206e82e6 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -8,7 +8,7 @@ "version": "1.0.0", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master", + "stanley-cheung/protobuf-php": "v0.6", "google/auth": "v0.9" }, "autoload": { diff --git a/templates/composer.json.template b/templates/composer.json.template index 07ab1f20ebab2..48d3b8892e203 100644 --- a/templates/composer.json.template +++ b/templates/composer.json.template @@ -9,7 +9,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "v0.6" }, "require-dev": { "google/auth": "v0.9" From 2b7fe5a6c02b0ed73acfad13b1c283872fb65772 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 22 Jul 2016 11:03:31 -0700 Subject: [PATCH 140/151] Actually commit changes to tools/distrib/python/grpcio_tools/setup.py --- tools/distrib/python/grpcio_tools/setup.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 188fc66191ba7..d49d18e957276 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -138,7 +138,6 @@ def package_data(): proto_files.append(relative_target) return {GRPC_PYTHON_TOOLS_PACKAGE: proto_files} -<<<<<<< HEAD def extension_modules(): if BUILD_WITH_CYTHON: plugin_sources = ['grpc/tools/_protoc_compiler.pyx'] @@ -152,19 +151,6 @@ def extension_modules(): plugin_ext = extension.Extension( name='grpc.tools._protoc_compiler', sources=plugin_sources, -======= -def protoc_ext_module(): - plugin_sources = [ - os.path.join('grpc', 'tools', 'main.cc'), - os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [ - os.path.join(CC_INCLUDE, cc_file) - for cc_file in CC_FILES] - plugin_ext = extension.Extension( - name='grpc.tools._protoc_compiler', - sources=( - [os.path.join('grpc', 'tools', '_protoc_compiler.pyx')] + - plugin_sources), ->>>>>>> upstream/v1.0.x include_dirs=[ '.', 'grpc_root', From bc3b6f3130f9e9e2440dc36413d7d35fbb3930e2 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 22 Jul 2016 13:13:28 -0700 Subject: [PATCH 141/151] regenerate template files --- grpc.def | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 +++ 3 files changed, 6 insertions(+) diff --git a/grpc.def b/grpc.def index 0849f84e0bc5c..c2f83f577fea1 100644 --- a/grpc.def +++ b/grpc.def @@ -148,6 +148,7 @@ EXPORTS gpr_slice_ref gpr_slice_unref gpr_slice_new + gpr_slice_new_with_user_data gpr_slice_new_with_len gpr_slice_malloc gpr_slice_from_copied_string diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 9748cb576bada..d7f862cd9cecb 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -186,6 +186,7 @@ gpr_set_log_function_type gpr_set_log_function_import; gpr_slice_ref_type gpr_slice_ref_import; gpr_slice_unref_type gpr_slice_unref_import; gpr_slice_new_type gpr_slice_new_import; +gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import; gpr_slice_new_with_len_type gpr_slice_new_with_len_import; gpr_slice_malloc_type gpr_slice_malloc_import; gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import; @@ -458,6 +459,7 @@ void grpc_rb_load_imports(HMODULE library) { gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref"); gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref"); gpr_slice_new_import = (gpr_slice_new_type) GetProcAddress(library, "gpr_slice_new"); + gpr_slice_new_with_user_data_import = (gpr_slice_new_with_user_data_type) GetProcAddress(library, "gpr_slice_new_with_user_data"); gpr_slice_new_with_len_import = (gpr_slice_new_with_len_type) GetProcAddress(library, "gpr_slice_new_with_len"); gpr_slice_malloc_import = (gpr_slice_malloc_type) GetProcAddress(library, "gpr_slice_malloc"); gpr_slice_from_copied_string_import = (gpr_slice_from_copied_string_type) GetProcAddress(library, "gpr_slice_from_copied_string"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 6f0974e31b425..14da63780cb79 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -509,6 +509,9 @@ extern gpr_slice_unref_type gpr_slice_unref_import; typedef gpr_slice(*gpr_slice_new_type)(void *p, size_t len, void (*destroy)(void *)); extern gpr_slice_new_type gpr_slice_new_import; #define gpr_slice_new gpr_slice_new_import +typedef gpr_slice(*gpr_slice_new_with_user_data_type)(void *p, size_t len, void (*destroy)(void *), void *user_data); +extern gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import; +#define gpr_slice_new_with_user_data gpr_slice_new_with_user_data_import typedef gpr_slice(*gpr_slice_new_with_len_type)(void *p, size_t len, void (*destroy)(void *, size_t)); extern gpr_slice_new_with_len_type gpr_slice_new_with_len_import; #define gpr_slice_new_with_len gpr_slice_new_with_len_import From 224fe989e49d21eaae15b7ceba6c3891d28afe8c Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 22 Jul 2016 13:28:25 -0700 Subject: [PATCH 142/151] Fixed incorrect merges --- src/core/lib/iomgr/network_status_tracker.c | 5 ----- tools/distrib/python/grpcio_tools/setup.py | 14 +++++++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/core/lib/iomgr/network_status_tracker.c b/src/core/lib/iomgr/network_status_tracker.c index a2029c584925e..b4bb7e3cf7b22 100644 --- a/src/core/lib/iomgr/network_status_tracker.c +++ b/src/core/lib/iomgr/network_status_tracker.c @@ -65,11 +65,6 @@ void grpc_destroy_network_status_monitor() { gpr_mu_destroy(&g_endpoint_mutex); } -void grpc_network_status_init(void) { - gpr_mu_init(&g_endpoint_mutex); - // TODO(makarandd): Install callback with OS to monitor network status. -} - void grpc_network_status_register_endpoint(grpc_endpoint *ep) { gpr_mu_lock(&g_endpoint_mutex); if (head == NULL) { diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index d49d18e957276..9d64782fd00d6 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -140,14 +140,14 @@ def package_data(): def extension_modules(): if BUILD_WITH_CYTHON: - plugin_sources = ['grpc/tools/_protoc_compiler.pyx'] + plugin_sources = [os.path.join('grpc', 'tools', '_protoc_compiler.pyx')] else: - plugin_sources = ['grpc/tools/_protoc_compiler.cpp'] - plugin_sources += [ - 'grpc/tools/main.cc', - 'grpc_root/src/compiler/python_generator.cc'] + [ - os.path.join(protoc_lib_deps.CC_INCLUDE, cc_file) - for cc_file in protoc_lib_deps.CC_FILES] + plugin_sources = [os.path.join('grpc', 'tools', '_protoc_compiler.cpp')] + plugin_sources += [ + os.path.join('grpc', 'tools', 'main.cc'), + os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [ + os.path.join(CC_INCLUDE, cc_file) + for cc_file in CC_FILES] plugin_ext = extension.Extension( name='grpc.tools._protoc_compiler', sources=plugin_sources, From fd9cc106f3e06722c2f101b40b7ac14f67836c74 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Thu, 21 Jul 2016 14:20:43 -0700 Subject: [PATCH 143/151] Be more intelligent about Cython in grpcio Before, Cython would *need* to be imported immediately if generated files did not already exist. Now, missing generated files will trigger a `setup_requires` inclusion of Cython and defer cythonization until extension build-time. If cythonization was specified via environment variable and setup could not find Cython, the extensions are poisoned instead of blocking non-extension commands from running. --- setup.py | 65 ++++++++++++--------------------- src/python/grpcio/.gitignore | 1 + src/python/grpcio/commands.py | 67 +++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 42 deletions(-) diff --git a/setup.py b/setup.py index 6dbc169053e4c..5d41cf6e23403 100644 --- a/setup.py +++ b/setup.py @@ -164,55 +164,27 @@ pkg_resources.parse_version('10.7.0')): os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7' - -def cython_extensions(): - module_names = list(CYTHON_EXTENSION_MODULE_NAMES) - extra_sources = list(CYTHON_HELPER_C_FILES) + list(CORE_C_FILES) - include_dirs = list(EXTENSION_INCLUDE_DIRECTORIES) - libraries = list(EXTENSION_LIBRARIES) - define_macros = list(DEFINE_MACROS) - build_with_cython = bool(BUILD_WITH_CYTHON) - # Set compiler directives linetrace argument only if we care about tracing; - # this is due to Cython having different behavior between linetrace being - # False and linetrace being unset. See issue #5689. - cython_compiler_directives = {} - if ENABLE_CYTHON_TRACING: - define_macros = define_macros + [('CYTHON_TRACE_NOGIL', 1)] - cython_compiler_directives['linetrace'] = True - pyx_module_files = [os.path.join(PYTHON_STEM, - name.replace('.', '/') + '.pyx') - for name in module_names] - c_module_files = [os.path.join(PYTHON_STEM, - name.replace('.', '/') + '.c') - for name in module_names] - if not build_with_cython: - for module_file in c_module_files: - if not os.path.isfile(module_file): - sys.stderr.write('Cython-generated files are missing; ' - 'forcing Cython build...\n') - build_with_cython = True - break - module_files = pyx_module_files if build_with_cython else c_module_files +def cython_extensions_and_necessity(): + cython_module_files = [os.path.join(PYTHON_STEM, + name.replace('.', '/') + '.pyx') + for name in CYTHON_EXTENSION_MODULE_NAMES] extensions = [ _extension.Extension( name=module_name, - sources=[module_file] + extra_sources, - include_dirs=include_dirs, libraries=libraries, - define_macros=define_macros, + sources=[module_file] + list(CYTHON_HELPER_C_FILES) + list(CORE_C_FILES), + include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES), + libraries=list(EXTENSION_LIBRARIES), + define_macros=list(DEFINE_MACROS), extra_compile_args=list(CFLAGS), extra_link_args=list(LDFLAGS), - ) for (module_name, module_file) in zip(module_names, module_files) + ) for (module_name, module_file) in zip(list(CYTHON_EXTENSION_MODULE_NAMES), cython_module_files) ] - if build_with_cython: - import Cython.Build - return Cython.Build.cythonize( - extensions, - include_path=include_dirs, - compiler_directives=cython_compiler_directives) - else: - return extensions + need_cython = BUILD_WITH_CYTHON + if not BUILD_WITH_CYTHON: + need_cython = need_cython or not commands.check_and_update_cythonization(extensions) + return commands.try_cythonize(extensions, linetracing=ENABLE_CYTHON_TRACING, mandatory=BUILD_WITH_CYTHON), need_cython -CYTHON_EXTENSION_MODULES = cython_extensions() +CYTHON_EXTENSION_MODULES, need_cython = cython_extensions_and_necessity() PACKAGE_DIRECTORIES = { '': PYTHON_STEM, @@ -232,6 +204,15 @@ def cython_extensions(): 'sphinx_rtd_theme>=0.1.8', 'six>=1.10', ) +if BUILD_WITH_CYTHON: + sys.stderr.write( + "You requested a Cython build via GRPC_PYTHON_BUILD_WITH_CYTHON, " + "but do not have Cython installed. We won't stop you from using " + "other commands, but the extension files will fail to build.\n") +elif need_cython: + sys.stderr.write( + 'We could not find Cython. Setup may take 10-20 minutes.\n') + SETUP_REQUIRES += ('cython>=0.23',) COMMAND_CLASS = { 'doc': commands.SphinxDocumentation, diff --git a/src/python/grpcio/.gitignore b/src/python/grpcio/.gitignore index 7cd8fab2735b3..3309795948cd9 100644 --- a/src/python/grpcio/.gitignore +++ b/src/python/grpcio/.gitignore @@ -14,3 +14,4 @@ doc/ _grpcio_metadata.py htmlcov/ grpc/_cython/_credentials +poison.c diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index 86a73fa8360f4..d36ac2330508b 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -184,6 +184,71 @@ def run(self): build_py.build_py.run(self) +def _poison_extensions(extensions, message): + """Includes a file that will always fail to compile in all extensions.""" + poison_filename = os.path.join(PYTHON_STEM, 'poison.c') + with open(poison_filename, 'w') as poison: + poison.write('#error {}'.format(message)) + for extension in extensions: + extension.sources = [poison_filename] + +def check_and_update_cythonization(extensions): + """Replace .pyx files with their generated counterparts and return whether or + not cythonization still needs to occur.""" + for extension in extensions: + generated_pyx_sources = [] + other_sources = [] + for source in extension.sources: + base, file_ext = os.path.splitext(source) + if file_ext == '.pyx': + generated_pyx_source = next( + (base + gen_ext for gen_ext in ('.c', '.cpp',) + if os.path.isfile(base + gen_ext)), None) + if generated_pyx_source: + generated_pyx_sources.append(generated_pyx_source) + else: + sys.stderr.write('Cython-generated files are missing...\n') + return False + else: + other_sources.append(source) + extension.sources = generated_pyx_sources + other_sources + sys.stderr.write('Found cython-generated files...\n') + return True + +def try_cythonize(extensions, linetracing=False, mandatory=True): + """Attempt to cythonize the extensions. + + Args: + extensions: A list of `distutils.extension.Extension`. + linetracing: A bool indicating whether or not to enable linetracing. + mandatory: Whether or not having Cython-generated files is mandatory. If it + is, extensions will be poisoned when they can't be fully generated. + """ + try: + # Break import style to ensure we have access to Cython post-setup_requires + import Cython.Build + except ImportError: + if mandatory: + sys.stderr.write( + "This package needs to generate C files with Cython but it cannot. " + "Poisoning extension sources to disallow extension commands...") + _poison_extensions( + extensions, + "Extensions have been poisoned due to missing Cython-generated code.") + return extensions + cython_compiler_directives = {} + if linetracing: + additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')] + cython_compiler_directives['linetrace'] = True + return Cython.Build.cythonize( + extensions, + include_path=[ + include_dir for extension in extensions for include_dir in extension.include_dirs + ], + compiler_directives=cython_compiler_directives + ) + + class BuildExt(build_ext.build_ext): """Custom build_ext command to enable compiler-specific flags.""" @@ -201,6 +266,8 @@ def build_extensions(self): if compiler in BuildExt.LINK_OPTIONS: for extension in self.extensions: extension.extra_link_args += list(BuildExt.LINK_OPTIONS[compiler]) + if not check_and_update_cythonization(self.extensions): + self.extensions = try_cythonize(self.extensions) try: build_ext.build_ext.build_extensions(self) except Exception as error: From 4b4266a738bf18d0559737ef3d6c014331eea597 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sat, 23 Jul 2016 00:20:02 +0200 Subject: [PATCH 144/151] Fixing documentation typo. --- src/core/lib/transport/transport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 08c0a237c977f..e33fc5c761f2f 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -138,7 +138,7 @@ typedef struct grpc_transport_stream_op { /** If != GRPC_ERROR_NONE, cancel this stream */ grpc_error *cancel_error; - /** If != GRPC_ERROR, send grpc-status, grpc-message, and close this + /** If != GRPC_ERROR_NONE, send grpc-status, grpc-message, and close this stream for both reading and writing */ grpc_error *close_error; From 20f900dc2322cdddb794bd7c6e90ce01f20d0f8e Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 22 Jul 2016 16:02:20 -0700 Subject: [PATCH 145/151] remove outdated php dockerfile dependency --- src/php/bin/determine_extension_dir.sh | 6 +----- templates/tools/dockerfile/php_deps.include | 6 ------ tools/dockerfile/interoptest/grpc_interop_php/Dockerfile | 6 ------ .../stress_test/grpc_interop_stress_php/Dockerfile | 6 ------ tools/dockerfile/test/multilang_jessie_x64/Dockerfile | 6 ------ tools/dockerfile/test/php_jessie_x64/Dockerfile | 6 ------ 6 files changed, 1 insertion(+), 35 deletions(-) diff --git a/src/php/bin/determine_extension_dir.sh b/src/php/bin/determine_extension_dir.sh index b4342ac89fa8e..a59882506f972 100755 --- a/src/php/bin/determine_extension_dir.sh +++ b/src/php/bin/determine_extension_dir.sh @@ -29,11 +29,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. set -e default_extension_dir=$(php-config --extension-dir) -if command -v brew > /dev/null && \ - brew ls --versions | grep php5[56]-grpc > /dev/null; then - # the grpc php extension was installed by homebrew - : -elif [ ! -e $default_extension_dir/grpc.so ]; then +if [ ! -e $default_extension_dir/grpc.so ]; then # the grpc extension is not found in the default PHP extension dir # try the source modules directory module_dir=../ext/grpc/modules diff --git a/templates/tools/dockerfile/php_deps.include b/templates/tools/dockerfile/php_deps.include index 739049b5ea0c4..da071e23ba4da 100644 --- a/templates/tools/dockerfile/php_deps.include +++ b/templates/tools/dockerfile/php_deps.include @@ -3,11 +3,5 @@ # Install dependencies -RUN /bin/bash -l -c "echo 'deb http://packages.dotdeb.org wheezy-php55 all' ${'\\'} - >> /etc/apt/sources.list.d/dotdeb.list" -RUN /bin/bash -l -c "echo 'deb-src http://packages.dotdeb.org wheezy-php55 all' ${'\\'} - >> /etc/apt/sources.list.d/dotdeb.list" -RUN wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add - - RUN apt-get update && apt-get install -y ${'\\'} git php5 php5-dev phpunit unzip diff --git a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile index 65a8334269af3..ef27af636144c 100644 --- a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile @@ -98,12 +98,6 @@ RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" # Install dependencies -RUN /bin/bash -l -c "echo 'deb http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN /bin/bash -l -c "echo 'deb-src http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add - - RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile index bbbdd4a151826..4adefe5d57b7e 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile @@ -103,12 +103,6 @@ RUN pip install --upgrade google-api-python-client # Install dependencies -RUN /bin/bash -l -c "echo 'deb http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN /bin/bash -l -c "echo 'deb-src http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add - - RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile index 92c8436851bb3..13f7c10f92f01 100644 --- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile @@ -100,12 +100,6 @@ RUN /bin/bash -l -c "nvm alias default 4" # Install dependencies -RUN /bin/bash -l -c "echo 'deb http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN /bin/bash -l -c "echo 'deb-src http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add - - RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index 2ef6e1d47fa74..17ea36b76c498 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -83,12 +83,6 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 # Install dependencies -RUN /bin/bash -l -c "echo 'deb http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN /bin/bash -l -c "echo 'deb-src http://packages.dotdeb.org wheezy-php55 all' \ - >> /etc/apt/sources.list.d/dotdeb.list" -RUN wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add - - RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip From 47168ea6ee63a88429256f78cde24da420c24f13 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 22 Jul 2016 17:55:31 -0700 Subject: [PATCH 146/151] php: remove protobuf-php clone hack --- .../interoptest/grpc_interop_php/Dockerfile.template | 5 ----- .../stress_test/grpc_interop_stress_php/Dockerfile.template | 5 ----- tools/dockerfile/interoptest/grpc_interop_php/Dockerfile | 5 ----- .../stress_test/grpc_interop_stress_php/Dockerfile | 5 ----- 4 files changed, 20 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template index 6232e081eb986..258d29aa970a3 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template @@ -46,11 +46,6 @@ RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer - # As an attempt to work around #4212, try to prefetch Protobuf-PHP dependency - # into composer cache to prevent "composer install" from cloning on each build. - RUN git clone --mirror https://github.com/stanley-cheung/Protobuf-PHP.git ${'\\'} - /root/.composer/cache/vcs/git-github.com-stanley-cheung-Protobuf-PHP.git/ - # Download the patched PHP protobuf so that PHP gRPC clients can be generated # from proto3 schemas. RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php diff --git a/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template b/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template index f8dc07947420c..13a250eb31caf 100644 --- a/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template +++ b/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template @@ -47,11 +47,6 @@ RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer - # As an attempt to work around #4212, try to prefetch Protobuf-PHP dependency - # into composer cache to prevent "composer install" from cloning on each build. - RUN git clone --mirror https://github.com/stanley-cheung/Protobuf-PHP.git ${'\\'} - /root/.composer/cache/vcs/git-github.com-stanley-cheung-Protobuf-PHP.git/ - # Download the patched PHP protobuf so that PHP gRPC clients can be generated # from proto3 schemas. RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php diff --git a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile index ef27af636144c..fd13515a06e0a 100644 --- a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile @@ -122,11 +122,6 @@ RUN /bin/bash -l -c "rvm all do gem install ronn rake" RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer -# As an attempt to work around #4212, try to prefetch Protobuf-PHP dependency -# into composer cache to prevent "composer install" from cloning on each build. -RUN git clone --mirror https://github.com/stanley-cheung/Protobuf-PHP.git \ - /root/.composer/cache/vcs/git-github.com-stanley-cheung-Protobuf-PHP.git/ - # Download the patched PHP protobuf so that PHP gRPC clients can be generated # from proto3 schemas. RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile index 4adefe5d57b7e..0716be5a9ddb6 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile @@ -127,11 +127,6 @@ RUN /bin/bash -l -c "rvm all do gem install ronn rake" RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer -# As an attempt to work around #4212, try to prefetch Protobuf-PHP dependency -# into composer cache to prevent "composer install" from cloning on each build. -RUN git clone --mirror https://github.com/stanley-cheung/Protobuf-PHP.git \ - /root/.composer/cache/vcs/git-github.com-stanley-cheung-Protobuf-PHP.git/ - # Download the patched PHP protobuf so that PHP gRPC clients can be generated # from proto3 schemas. RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php From 2e2cdffe9dba109c7602ec33b99b123eceb071e2 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Sat, 23 Jul 2016 19:07:36 -0700 Subject: [PATCH 147/151] php: add php7 to jenkins basic and interop tests --- .../grpc_interop_php/Dockerfile.template | 25 +--- .../grpc_interop_php7/Dockerfile.template | 37 ++++++ templates/tools/dockerfile/php7_deps.include | 45 +++++++ .../tools/dockerfile/php_common_deps.include | 21 +++ .../test/php7_jessie_x64/Dockerfile.template | 38 ++++++ .../interoptest/grpc_interop_php/Dockerfile | 18 +-- .../interoptest/grpc_interop_php7/Dockerfile | 125 ++++++++++++++++++ .../grpc_interop_php7/build_interop.sh | 52 ++++++++ .../test/php7_jessie_x64/Dockerfile | 105 +++++++++++++++ tools/run_tests/run_interop_tests.py | 28 +++- tools/run_tests/run_tests.py | 37 ++++++ 11 files changed, 491 insertions(+), 40 deletions(-) create mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template create mode 100644 templates/tools/dockerfile/php7_deps.include create mode 100644 templates/tools/dockerfile/php_common_deps.include create mode 100644 templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template create mode 100644 tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile create mode 100755 tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh create mode 100644 tools/dockerfile/test/php7_jessie_x64/Dockerfile diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template index 258d29aa970a3..f37eadad7455c 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2015, Google Inc. + # Copyright 2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,29 +32,8 @@ FROM debian:jessie <%include file="../../apt_get_basic.include"/> - <%include file="../../python_deps.include"/> <%include file="../../ruby_deps.include"/> <%include file="../../php_deps.include"/> <%include file="../../run_tests_addons.include"/> - # ronn: a ruby tool used to convert markdown to man pages, used during the - # install of Protobuf extensions - # - # rake: a ruby version of make used to build the PHP Protobuf extension - RUN /bin/bash -l -c "rvm all do gem install ronn rake" - - # Install composer - RUN curl -sS https://getcomposer.org/installer | php - RUN mv composer.phar /usr/local/bin/composer - - # Download the patched PHP protobuf so that PHP gRPC clients can be generated - # from proto3 schemas. - RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php - - RUN /bin/bash -l -c "rvm use ruby-2.1 ${'\\'} - && cd /var/local/git/protobuf-php ${'\\'} - && rvm all do rake pear:package version=1.0 ${'\\'} - && pear install Protobuf-1.0.tgz" - - # Define the default command. - CMD ["bash"] + <%include file="../../php_common_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template new file mode 100644 index 0000000000000..42157ee062cf6 --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template @@ -0,0 +1,37 @@ +%YAML 1.2 +--- | + # Copyright 2016, Google Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + FROM debian:jessie + + <%include file="../../php7_deps.include"/> + <%include file="../../ruby_deps.include"/> + <%include file="../../run_tests_addons.include"/> + <%include file="../../php_common_deps.include"/> diff --git a/templates/tools/dockerfile/php7_deps.include b/templates/tools/dockerfile/php7_deps.include new file mode 100644 index 0000000000000..a24e5064428df --- /dev/null +++ b/templates/tools/dockerfile/php7_deps.include @@ -0,0 +1,45 @@ +#================= +# PHP7 dependencies + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y ${'\\'} + autoconf ${'\\'} + automake ${'\\'} + build-essential ${'\\'} + ccache ${'\\'} + curl ${'\\'} + git ${'\\'} + libcurl4-openssl-dev ${'\\'} + libgmp-dev ${'\\'} + libgmp3-dev ${'\\'} + libssl-dev ${'\\'} + libtool ${'\\'} + libxml2-dev ${'\\'} + pkg-config ${'\\'} + re2c ${'\\'} + time ${'\\'} + unzip ${'\\'} + wget ${'\\'} + zip && apt-get clean + +# Install other dependencies +RUN ln -sf /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h +RUN wget http://ftp.gnu.org/gnu/bison/bison-2.6.4.tar.gz -O /var/local/bison-2.6.4.tar.gz +RUN cd /var/local ${'\\'} + && tar -zxvf bison-2.6.4.tar.gz ${'\\'} + && cd /var/local/bison-2.6.4 ${'\\'} + && ./configure ${'\\'} + && make ${'\\'} + && make install + +# Compile PHP7 from source +RUN git clone https://github.com/php/php-src /var/local/git/php-src +RUN cd /var/local/git/php-src ${'\\'} + && git checkout PHP-7.0.9 ${'\\'} + && ./buildconf --force ${'\\'} + && ./configure ${'\\'} + --with-gmp ${'\\'} + --with-openssl ${'\\'} + --with-zlib ${'\\'} + && make ${'\\'} + && make install diff --git a/templates/tools/dockerfile/php_common_deps.include b/templates/tools/dockerfile/php_common_deps.include new file mode 100644 index 0000000000000..8839bb51554c2 --- /dev/null +++ b/templates/tools/dockerfile/php_common_deps.include @@ -0,0 +1,21 @@ +# ronn: a ruby tool used to convert markdown to man pages, used during the +# install of Protobuf extensions +# +# rake: a ruby version of make used to build the PHP Protobuf extension +RUN /bin/bash -l -c "rvm all do gem install ronn rake" + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php +RUN mv composer.phar /usr/local/bin/composer + +# Download the patched PHP protobuf so that PHP gRPC clients can be generated +# from proto3 schemas. +RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php + +RUN /bin/bash -l -c "rvm use ruby-2.1 ${'\\'} + && cd /var/local/git/protobuf-php ${'\\'} + && rvm all do rake pear:package version=1.0 ${'\\'} + && pear install Protobuf-1.0.tgz" + +# Define the default command. +CMD ["bash"] diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template new file mode 100644 index 0000000000000..8cd86f03df57d --- /dev/null +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -0,0 +1,38 @@ +%YAML 1.2 +--- | + # Copyright 2015, Google Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + FROM debian:jessie + + <%include file="../../php7_deps.include"/> + <%include file="../../python_deps.include"/> + <%include file="../../run_tests_addons.include"/> + # Define the default command. + CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile index fd13515a06e0a..0d6171c1705a7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -63,21 +63,6 @@ RUN apt-get update && apt-get install -y \ # Build profiling RUN apt-get update && apt-get install -y time && apt-get clean -#==================== -# Python dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -RUN pip install pip --upgrade -RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 - #================== # Ruby dependencies @@ -133,3 +118,4 @@ RUN /bin/bash -l -c "rvm use ruby-2.1 \ # Define the default command. CMD ["bash"] + diff --git a/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile new file mode 100644 index 0000000000000..be8f25f8fface --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile @@ -0,0 +1,125 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM debian:jessie + +#================= +# PHP7 dependencies + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + build-essential \ + ccache \ + curl \ + git \ + libcurl4-openssl-dev \ + libgmp-dev \ + libgmp3-dev \ + libssl-dev \ + libtool \ + libxml2-dev \ + pkg-config \ + re2c \ + time \ + unzip \ + wget \ + zip && apt-get clean + +# Install other dependencies +RUN ln -sf /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h +RUN wget http://ftp.gnu.org/gnu/bison/bison-2.6.4.tar.gz -O /var/local/bison-2.6.4.tar.gz +RUN cd /var/local \ + && tar -zxvf bison-2.6.4.tar.gz \ + && cd /var/local/bison-2.6.4 \ + && ./configure \ + && make \ + && make install + +# Compile PHP7 from source +RUN git clone https://github.com/php/php-src /var/local/git/php-src +RUN cd /var/local/git/php-src \ + && git checkout PHP-7.0.9 \ + && ./buildconf --force \ + && ./configure \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + && make \ + && make install + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.1 +RUN /bin/bash -l -c "rvm install ruby-2.1" +RUN /bin/bash -l -c "rvm use --default ruby-2.1" +RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" + +# Prepare ccache +RUN ln -s /usr/bin/ccache /usr/local/bin/gcc +RUN ln -s /usr/bin/ccache /usr/local/bin/g++ +RUN ln -s /usr/bin/ccache /usr/local/bin/cc +RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN ln -s /usr/bin/ccache /usr/local/bin/clang +RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ + + +RUN mkdir /var/local/jenkins + +# ronn: a ruby tool used to convert markdown to man pages, used during the +# install of Protobuf extensions +# +# rake: a ruby version of make used to build the PHP Protobuf extension +RUN /bin/bash -l -c "rvm all do gem install ronn rake" + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php +RUN mv composer.phar /usr/local/bin/composer + +# Download the patched PHP protobuf so that PHP gRPC clients can be generated +# from proto3 schemas. +RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php + +RUN /bin/bash -l -c "rvm use ruby-2.1 \ + && cd /var/local/git/protobuf-php \ + && rvm all do rake pear:package version=1.0 \ + && pear install Protobuf-1.0.tgz" + +# Define the default command. +CMD ["bash"] + diff --git a/tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh new file mode 100755 index 0000000000000..261dded28216c --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Builds PHP interop server and client in a base image. +set -ex + +mkdir -p /var/local/git +git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc + +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +cd /var/local/git/grpc +rvm --default use ruby-2.1 + +# gRPC core and protobuf need to be installed +make install + +(cd src/php/ext/grpc && phpize && ./configure && make) + +(cd third_party/protobuf && make install) + +(cd src/php && composer install) + +(cd src/php && protoc-gen-php -i tests/interop/ -o tests/interop/ tests/interop/test.proto) diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile new file mode 100644 index 0000000000000..5a0bf28f234a8 --- /dev/null +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -0,0 +1,105 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM debian:jessie + +#================= +# PHP7 dependencies + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + build-essential \ + ccache \ + curl \ + git \ + libcurl4-openssl-dev \ + libgmp-dev \ + libgmp3-dev \ + libssl-dev \ + libtool \ + libxml2-dev \ + pkg-config \ + re2c \ + time \ + unzip \ + wget \ + zip && apt-get clean + +# Install other dependencies +RUN ln -sf /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h +RUN wget http://ftp.gnu.org/gnu/bison/bison-2.6.4.tar.gz -O /var/local/bison-2.6.4.tar.gz +RUN cd /var/local \ + && tar -zxvf bison-2.6.4.tar.gz \ + && cd /var/local/bison-2.6.4 \ + && ./configure \ + && make \ + && make install + +# Compile PHP7 from source +RUN git clone https://github.com/php/php-src /var/local/git/php-src +RUN cd /var/local/git/php-src \ + && git checkout PHP-7.0.9 \ + && ./buildconf --force \ + && ./configure \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + && make \ + && make install + +#==================== +# Python dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + python-all-dev \ + python3-all-dev \ + python-pip + +# Install Python packages from PyPI +RUN pip install pip --upgrade +RUN pip install virtualenv +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0 + +# Prepare ccache +RUN ln -s /usr/bin/ccache /usr/local/bin/gcc +RUN ln -s /usr/bin/ccache /usr/local/bin/g++ +RUN ln -s /usr/bin/ccache /usr/local/bin/cc +RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN ln -s /usr/bin/ccache /usr/local/bin/clang +RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 2e5a2f7721d66..78096b216c647 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -268,6 +268,31 @@ def __str__(self): return 'php' +class PHP7Language: + + def __init__(self): + self.client_cwd = None + self.safename = str(self) + + def client_cmd(self, args): + return ['src/php/bin/interop_client.sh'] + args + + def cloud_to_prod_env(self): + return {} + + def global_env(self): + return {} + + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION + + def unimplemented_test_cases_server(self): + return [] + + def __str__(self): + return 'php7' + + class RubyLanguage: def __init__(self): @@ -346,6 +371,7 @@ def __str__(self): 'java' : JavaLanguage(), 'node' : NodeLanguage(), 'php' : PHPLanguage(), + 'php7' : PHP7Language(), 'ruby' : RubyLanguage(), 'python' : PythonLanguage(), } @@ -409,7 +435,7 @@ def auth_options(language, test_case): default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com' if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: - if language in ['csharp', 'node', 'php', 'python', 'ruby']: + if language in ['csharp', 'node', 'php', 'php7', 'python', 'ruby']: env['GOOGLE_APPLICATION_CREDENTIALS'] = key_filepath else: cmdargs += [key_file_arg] diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 57fff2ec9c430..2aade5a97c1d1 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -378,6 +378,42 @@ def __str__(self): return 'php' +class Php7Language(object): + + def configure(self, config, args): + self.config = config + self.args = args + _check_compiler(self.args.compiler, ['default']) + + def test_specs(self): + return [self.config.job_spec(['src/php/bin/run_tests.sh'], None, + environ=_FORCE_ENVIRON_FOR_WRAPPERS)] + + def pre_build_steps(self): + return [] + + def make_targets(self): + return ['static_c', 'shared_c'] + + def make_options(self): + return [] + + def build_steps(self): + return [['tools/run_tests/build_php.sh']] + + def post_tests_steps(self): + return [['tools/run_tests/post_tests_php.sh']] + + def makefile_name(self): + return 'Makefile' + + def dockerfile_dir(self): + return 'tools/dockerfile/test/php7_jessie_%s' % _docker_arch_suffix(self.args.arch) + + def __str__(self): + return 'php7' + + class PythonConfig(collections.namedtuple('PythonConfig', [ 'name', 'build', 'run'])): """Tuple of commands (named s.t. 'what it says on the tin' applies)""" @@ -746,6 +782,7 @@ def __str__(self): 'c': CLanguage('c', 'c'), 'node': NodeLanguage(), 'php': PhpLanguage(), + 'php7': Php7Language(), 'python': PythonLanguage(), 'ruby': RubyLanguage(), 'csharp': CSharpLanguage(), From 598d5240c0e4613dbe0569a1266693892a248e29 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 25 Jul 2016 09:42:18 -0700 Subject: [PATCH 148/151] Fix merge again --- tools/distrib/python/grpcio_tools/setup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 9d64782fd00d6..bb1f1cf085b65 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -143,11 +143,11 @@ def extension_modules(): plugin_sources = [os.path.join('grpc', 'tools', '_protoc_compiler.pyx')] else: plugin_sources = [os.path.join('grpc', 'tools', '_protoc_compiler.cpp')] - plugin_sources += [ - os.path.join('grpc', 'tools', 'main.cc'), - os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [ - os.path.join(CC_INCLUDE, cc_file) - for cc_file in CC_FILES] + plugin_sources += [ + os.path.join('grpc', 'tools', 'main.cc'), + os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [ + os.path.join(CC_INCLUDE, cc_file) + for cc_file in CC_FILES] plugin_ext = extension.Extension( name='grpc.tools._protoc_compiler', sources=plugin_sources, From 1533e6aab9372d1f3eb667e6d4307eb2e1ee9b3f Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 25 Jul 2016 11:09:23 -0700 Subject: [PATCH 149/151] Rerun generate_projects.sh --- grpc.def | 1 + src/python/grpcio_health_checking/grpc_version.py | 2 +- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 +++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/grpc.def b/grpc.def index 0849f84e0bc5c..c2f83f577fea1 100644 --- a/grpc.def +++ b/grpc.def @@ -148,6 +148,7 @@ EXPORTS gpr_slice_ref gpr_slice_unref gpr_slice_new + gpr_slice_new_with_user_data gpr_slice_new_with_len gpr_slice_malloc gpr_slice_from_copied_string diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 2e48fde8931ee..be0d0ced3cb7f 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION='1.0.0rc1' +VERSION='1.1.0.dev0' diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 9748cb576bada..d7f862cd9cecb 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -186,6 +186,7 @@ gpr_set_log_function_type gpr_set_log_function_import; gpr_slice_ref_type gpr_slice_ref_import; gpr_slice_unref_type gpr_slice_unref_import; gpr_slice_new_type gpr_slice_new_import; +gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import; gpr_slice_new_with_len_type gpr_slice_new_with_len_import; gpr_slice_malloc_type gpr_slice_malloc_import; gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import; @@ -458,6 +459,7 @@ void grpc_rb_load_imports(HMODULE library) { gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref"); gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref"); gpr_slice_new_import = (gpr_slice_new_type) GetProcAddress(library, "gpr_slice_new"); + gpr_slice_new_with_user_data_import = (gpr_slice_new_with_user_data_type) GetProcAddress(library, "gpr_slice_new_with_user_data"); gpr_slice_new_with_len_import = (gpr_slice_new_with_len_type) GetProcAddress(library, "gpr_slice_new_with_len"); gpr_slice_malloc_import = (gpr_slice_malloc_type) GetProcAddress(library, "gpr_slice_malloc"); gpr_slice_from_copied_string_import = (gpr_slice_from_copied_string_type) GetProcAddress(library, "gpr_slice_from_copied_string"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 6f0974e31b425..14da63780cb79 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -509,6 +509,9 @@ extern gpr_slice_unref_type gpr_slice_unref_import; typedef gpr_slice(*gpr_slice_new_type)(void *p, size_t len, void (*destroy)(void *)); extern gpr_slice_new_type gpr_slice_new_import; #define gpr_slice_new gpr_slice_new_import +typedef gpr_slice(*gpr_slice_new_with_user_data_type)(void *p, size_t len, void (*destroy)(void *), void *user_data); +extern gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import; +#define gpr_slice_new_with_user_data gpr_slice_new_with_user_data_import typedef gpr_slice(*gpr_slice_new_with_len_type)(void *p, size_t len, void (*destroy)(void *, size_t)); extern gpr_slice_new_with_len_type gpr_slice_new_with_len_import; #define gpr_slice_new_with_len gpr_slice_new_with_len_import From f7fbdd48752015cba7d1037d24eaaf2320e291fb Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 25 Jul 2016 20:31:22 +0200 Subject: [PATCH 150/151] We should always try to compile the protoc plugins when building tests. --- Makefile | 2 +- templates/Makefile.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 80e8d7434b2ba..00ec4421f39e7 100644 --- a/Makefile +++ b/Makefile @@ -748,8 +748,8 @@ endif endif else PC_LIBS_GRPCXX = -lprotobuf -PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) endif +PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) else ifeq ($(HAS_EMBEDDED_PROTOBUF),true) PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a diff --git a/templates/Makefile.template b/templates/Makefile.template index cb33643dd2a0c..9afc6566e2faf 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -642,8 +642,8 @@ endif else PC_LIBS_GRPCXX = -lprotobuf - PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) endif + PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) else ifeq ($(HAS_EMBEDDED_PROTOBUF),true) PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a From 211a2a0f1266ac741060c0e61a070839e3904cd0 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Mon, 25 Jul 2016 13:01:48 -0700 Subject: [PATCH 151/151] fix copyright --- .../tools/dockerfile/test/php7_jessie_x64/Dockerfile.template | 2 +- tools/dockerfile/test/php7_jessie_x64/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template index 8cd86f03df57d..e6a213d90d30f 100644 --- a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2015, Google Inc. + # Copyright 2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index 5a0bf28f234a8..221338956efc6 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without