diff options
Diffstat (limited to 'test/cpp/util')
-rw-r--r-- | test/cpp/util/byte_buffer_proto_helper.cc | 2 | ||||
-rw-r--r-- | test/cpp/util/byte_buffer_test.cc | 2 | ||||
-rw-r--r-- | test/cpp/util/cli_call.cc | 2 | ||||
-rw-r--r-- | test/cpp/util/cli_call.h | 2 | ||||
-rw-r--r-- | test/cpp/util/cli_call_test.cc | 6 | ||||
-rw-r--r-- | test/cpp/util/grpc_tool.cc | 152 | ||||
-rw-r--r-- | test/cpp/util/grpc_tool_test.cc | 193 | ||||
-rw-r--r-- | test/cpp/util/metrics_server.cc | 1 | ||||
-rw-r--r-- | test/cpp/util/metrics_server.h | 6 | ||||
-rw-r--r-- | test/cpp/util/proto_file_parser.cc | 21 | ||||
-rw-r--r-- | test/cpp/util/proto_reflection_descriptor_database.cc | 13 | ||||
-rw-r--r-- | test/cpp/util/proto_reflection_descriptor_database.h | 24 | ||||
-rw-r--r-- | test/cpp/util/service_describer.cc | 108 | ||||
-rw-r--r-- | test/cpp/util/service_describer.h | 57 | ||||
-rw-r--r-- | test/cpp/util/test_credentials_provider.cc | 27 |
15 files changed, 537 insertions, 79 deletions
diff --git a/test/cpp/util/byte_buffer_proto_helper.cc b/test/cpp/util/byte_buffer_proto_helper.cc index 2512c9bdf8..d625d6f3f4 100644 --- a/test/cpp/util/byte_buffer_proto_helper.cc +++ b/test/cpp/util/byte_buffer_proto_helper.cc @@ -38,7 +38,7 @@ namespace testing { bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) { std::vector<Slice> slices; - buffer->Dump(&slices); + (void)buffer->Dump(&slices); grpc::string buf; buf.reserve(buffer->Length()); for (auto s = slices.begin(); s != slices.end(); s++) { diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc index 1167c790d4..2089a62011 100644 --- a/test/cpp/util/byte_buffer_test.cc +++ b/test/cpp/util/byte_buffer_test.cc @@ -100,7 +100,7 @@ TEST_F(ByteBufferTest, Dump) { slices.push_back(Slice(world, Slice::STEAL_REF)); ByteBuffer buffer(&slices[0], 2); slices.clear(); - buffer.Dump(&slices); + (void)buffer.Dump(&slices); EXPECT_TRUE(SliceEqual(slices[0], hello)); EXPECT_TRUE(SliceEqual(slices[1], world)); } diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc index 98b9d930d6..1edffbe08e 100644 --- a/test/cpp/util/cli_call.cc +++ b/test/cpp/util/cli_call.cc @@ -94,7 +94,7 @@ Status CliCall::Call(std::shared_ptr<grpc::Channel> channel, if (status.ok()) { std::vector<grpc::Slice> slices; - recv_buffer.Dump(&slices); + (void)recv_buffer.Dump(&slices); response->clear(); for (size_t i = 0; i < slices.size(); i++) { diff --git a/test/cpp/util/cli_call.h b/test/cpp/util/cli_call.h index 2fbc9618b6..65da86bd4e 100644 --- a/test/cpp/util/cli_call.h +++ b/test/cpp/util/cli_call.h @@ -43,7 +43,7 @@ namespace grpc { namespace testing { -class CliCall GRPC_FINAL { +class CliCall final { public: typedef std::multimap<grpc::string, grpc::string> OutgoingMetadataContainer; typedef std::multimap<grpc::string_ref, grpc::string_ref> diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 75e90f824f..2e8501b2c3 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -56,7 +56,7 @@ namespace testing { class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { public: Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) GRPC_OVERRIDE { + EchoResponse* response) override { if (!context->client_metadata().empty()) { for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter = context->client_metadata().begin(); @@ -75,7 +75,7 @@ class CliCallTest : public ::testing::Test { protected: CliCallTest() {} - void SetUp() GRPC_OVERRIDE { + void SetUp() override { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; // Setup server @@ -86,7 +86,7 @@ class CliCallTest : public ::testing::Test { server_ = builder.BuildAndStart(); } - void TearDown() GRPC_OVERRIDE { server_->Shutdown(); } + void TearDown() override { server_->Shutdown(); } void ResetStub() { channel_ = diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 4af00cdc96..03c33abe9f 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -51,8 +51,12 @@ #include "test/cpp/util/cli_call.h" #include "test/cpp/util/proto_file_parser.h" #include "test/cpp/util/proto_reflection_descriptor_database.h" -#include "test/cpp/util/test_config.h" +#include "test/cpp/util/service_describer.h" +namespace grpc { +namespace testing { + +DEFINE_bool(l, false, "Use a long listing format"); DEFINE_bool(remotedb, true, "Use server types to parse and format messages"); DEFINE_string(metadata, "", "Metadata to send to server, in the form of key1:val1:key2:val2"); @@ -62,8 +66,6 @@ DEFINE_bool(binary_input, false, "Input in binary format"); DEFINE_bool(binary_output, false, "Output in binary format"); DEFINE_string(infile, "", "Input file (default is stdin)"); -namespace grpc { -namespace testing { namespace { class GrpcTool { @@ -75,11 +77,13 @@ class GrpcTool { GrpcToolOutputCallback callback); bool CallMethod(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback); + bool ListServices(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + bool PrintType(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); // TODO(zyc): implement the following methods // bool ListServices(int argc, const char** argv, GrpcToolOutputCallback // callback); - // bool PrintType(int argc, const char** argv, GrpcToolOutputCallback - // callback); // bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback // callback); // bool ParseMessage(int argc, const char** argv, GrpcToolOutputCallback @@ -165,10 +169,10 @@ struct Command { const Command ops[] = { {"help", BindWith5Args(&GrpcTool::Help), 0, INT_MAX}, - // {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3}, - // {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3}, {"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3}, - // {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2}, + {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2}, // {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3}, // {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3}, // {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3}, @@ -178,9 +182,9 @@ void Usage(const grpc::string& msg) { fprintf( stderr, "%s\n" - // " grpc_cli ls ... ; List services\n" + " grpc_cli ls ... ; List services\n" " grpc_cli call ... ; Call method\n" - // " grpc_cli type ... ; Print type\n" + " grpc_cli type ... ; Print type\n" // " grpc_cli parse ... ; Parse message\n" // " grpc_cli totext ... ; Convert binary message to text\n" // " grpc_cli tobinary ... ; Convert text message to binary\n" @@ -257,6 +261,134 @@ bool GrpcTool::Help(int argc, const char** argv, const CliCredentials& cred, return true; } +bool GrpcTool::ListServices(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "List services\n" + " grpc_cli ls <address> [<service>[/<method>]]\n" + " <address> ; host:port\n" + " <service> ; Exported service name\n" + " <method> ; Method name\n" + " --l ; Use a long listing format\n" + " --outfile ; Output filename (defaults to stdout)\n" + + cred.GetCredentialUsage()); + + grpc::string server_address(argv[0]); + std::shared_ptr<grpc::Channel> channel = + grpc::CreateChannel(server_address, cred.GetCredentials()); + grpc::ProtoReflectionDescriptorDatabase desc_db(channel); + grpc::protobuf::DescriptorPool desc_pool(&desc_db); + + std::vector<grpc::string> service_list; + if (!desc_db.GetServices(&service_list)) { + return false; + } + + // If no service is specified, dump the list of services. + grpc::string output; + if (argc < 2) { + // List all services, if --l is passed, then include full description, + // otherwise include a summarized list only. + if (FLAGS_l) { + output = DescribeServiceList(service_list, desc_pool); + } else { + for (auto it = service_list.begin(); it != service_list.end(); it++) { + auto const& service = *it; + output.append(service); + output.append("\n"); + } + } + } else { + grpc::string service_name; + grpc::string method_name; + std::stringstream ss(argv[1]); + + // Remove leading slashes. + while (ss.peek() == '/') { + ss.get(); + } + + // Parse service and method names. Support the following patterns: + // Service + // Service Method + // Service.Method + // Service/Method + if (argc == 3) { + std::getline(ss, service_name, '/'); + method_name = argv[2]; + } else { + if (std::getline(ss, service_name, '/')) { + std::getline(ss, method_name); + } + } + + const grpc::protobuf::ServiceDescriptor* service = + desc_pool.FindServiceByName(service_name); + if (service != nullptr) { + if (method_name.empty()) { + output = FLAGS_l ? DescribeService(service) : SummarizeService(service); + } else { + method_name.insert(0, 1, '.'); + method_name.insert(0, service_name); + const grpc::protobuf::MethodDescriptor* method = + desc_pool.FindMethodByName(method_name); + if (method != nullptr) { + output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); + } else { + fprintf(stderr, "Method %s not found in service %s.\n", + method_name.c_str(), service_name.c_str()); + return false; + } + } + } else { + if (!method_name.empty()) { + fprintf(stderr, "Service %s not found.\n", service_name.c_str()); + return false; + } else { + const grpc::protobuf::MethodDescriptor* method = + desc_pool.FindMethodByName(service_name); + if (method != nullptr) { + output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); + } else { + fprintf(stderr, "Service or method %s not found.\n", + service_name.c_str()); + return false; + } + } + } + } + return callback(output); +} + +bool GrpcTool::PrintType(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Print type\n" + " grpc_cli type <address> <type>\n" + " <address> ; host:port\n" + " <type> ; Protocol buffer type name\n" + + cred.GetCredentialUsage()); + + grpc::string server_address(argv[0]); + std::shared_ptr<grpc::Channel> channel = + grpc::CreateChannel(server_address, cred.GetCredentials()); + grpc::ProtoReflectionDescriptorDatabase desc_db(channel); + grpc::protobuf::DescriptorPool desc_pool(&desc_db); + + grpc::string output; + const grpc::protobuf::Descriptor* descriptor = + desc_pool.FindMessageTypeByName(argv[1]); + if (descriptor != nullptr) { + output = descriptor->DebugString(); + } else { + fprintf(stderr, "Type %s not found.\n", argv[1]); + return false; + } + return callback(output); +} + bool GrpcTool::CallMethod(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback) { diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index b96afaf50c..5ab054d04a 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -35,6 +35,7 @@ #include <sstream> +#include <gflags/gflags.h> #include <grpc++/channel.h> #include <grpc++/client_context.h> #include <grpc++/create_channel.h> @@ -55,25 +56,68 @@ using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; +#define USAGE_REGEX "( grpc_cli .+\n){2,10}" + +#define ECHO_TEST_SERVICE_SUMMARY \ + "Echo\n" \ + "RequestStream\n" \ + "ResponseStream\n" \ + "BidiStream\n" \ + "Unimplemented\n" + +#define ECHO_TEST_SERVICE_DESCRIPTION \ + "filename: src/proto/grpc/testing/echo.proto\n" \ + "package: grpc.testing;\n" \ + "service EchoTestService {\n" \ + " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ + "{}\n" \ + " rpc RequestStream(stream grpc.testing.EchoRequest) returns " \ + "(grpc.testing.EchoResponse) {}\n" \ + " rpc ResponseStream(grpc.testing.EchoRequest) returns (stream " \ + "grpc.testing.EchoResponse) {}\n" \ + " rpc BidiStream(stream grpc.testing.EchoRequest) returns (stream " \ + "grpc.testing.EchoResponse) {}\n" \ + " rpc Unimplemented(grpc.testing.EchoRequest) returns " \ + "(grpc.testing.EchoResponse) {}\n" \ + "}\n" \ + "\n" + +#define ECHO_METHOD_DESCRIPTION \ + " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ + "{}\n" + namespace grpc { namespace testing { + +DECLARE_bool(l); + namespace { -class TestCliCredentials GRPC_FINAL : public grpc::testing::CliCredentials { +class TestCliCredentials final : public grpc::testing::CliCredentials { public: - std::shared_ptr<grpc::ChannelCredentials> GetCredentials() const - GRPC_OVERRIDE { + std::shared_ptr<grpc::ChannelCredentials> GetCredentials() const override { return InsecureChannelCredentials(); } - const grpc::string GetCredentialUsage() const GRPC_OVERRIDE { return ""; } + const grpc::string GetCredentialUsage() const override { return ""; } }; +bool PrintStream(std::stringstream* ss, const grpc::string& output) { + (*ss) << output; + return true; +} + +template <typename T> +size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); +} + } // namespame class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { public: Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) GRPC_OVERRIDE { + EchoResponse* response) override { if (!context->client_metadata().empty()) { for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter = context->client_metadata().begin(); @@ -109,24 +153,19 @@ class GrpcToolTest : public ::testing::Test { void ShutdownServer() { server_->Shutdown(); } + void ExitWhenError(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + int result = GrpcToolMainLib(argc, argv, cred, callback); + if (result) { + exit(result); + } + } + std::unique_ptr<Server> server_; TestServiceImpl service_; reflection::ProtoServerReflectionPlugin plugin_; }; -static bool PrintStream(std::stringstream* ss, const grpc::string& output) { - (*ss) << output << std::endl; - return true; -} - -template <typename T> -static size_t ArraySize(T& a) { - return ((sizeof(a) / sizeof(*(a))) / - static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); -} - -#define USAGE_REGEX "( grpc_cli .+\n){2,10}" - TEST_F(GrpcToolTest, NoCommand) { // Test input "grpc_cli" std::stringstream output_stream; @@ -168,8 +207,122 @@ TEST_F(GrpcToolTest, HelpCommand) { EXPECT_TRUE(0 == output_stream.tellp()); } +TEST_F(GrpcToolTest, ListCommand) { + // Test input "grpc_cli list localhost:<port>" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "ls", server_address.c_str()}; + + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + "grpc.testing.EchoTestService\n" + "grpc.reflection.v1alpha.ServerReflection\n")); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, ListOneService) { + // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), + "grpc.testing.EchoTestService"}; + // without -l flag + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_TEST_SERVICE_SUMMARY + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_SUMMARY)); + + // with -l flag + output_stream.str(grpc::string()); + output_stream.clear(); + FLAGS_l = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_TEST_SERVICE_DESCRIPTION + EXPECT_TRUE( + 0 == strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_DESCRIPTION)); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, TypeCommand) { + // Test input "grpc_cli type localhost:<port> grpc.testing.EchoRequest" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "type", server_address.c_str(), + "grpc.testing.EchoRequest"}; + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + const grpc::protobuf::Descriptor* desc = + grpc::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName( + "grpc.testing.EchoRequest"); + // Expected output: the DebugString of grpc.testing.EchoRequest + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), desc->DebugString().c_str())); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, ListOneMethod) { + // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), + "grpc.testing.EchoTestService.Echo"}; + // without -l flag + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "Echo" + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), "Echo\n")); + + // with -l flag + output_stream.str(grpc::string()); + output_stream.clear(); + FLAGS_l = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_METHOD_DESCRIPTION + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), ECHO_METHOD_DESCRIPTION)); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, TypeNotFound) { + // Test input "grpc_cli type localhost:<port> grpc.testing.DummyRequest" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "type", server_address.c_str(), + "grpc.testing.DummyRequest"}; + + EXPECT_DEATH(ExitWhenError(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1)), + ".*Type grpc.testing.DummyRequest not found.*"); + + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommand) { - // Test input "grpc_cli call Echo" + // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" std::stringstream output_stream; const grpc::string server_address = SetUpServer(); @@ -186,7 +339,7 @@ TEST_F(GrpcToolTest, CallCommand) { } TEST_F(GrpcToolTest, TooFewArguments) { - // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" + // Test input "grpc_cli call Echo" std::stringstream output_stream; const char* argv[] = {"grpc_cli", "call", "Echo"}; diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc index 1c7cd6382a..9296d6515e 100644 --- a/test/cpp/util/metrics_server.cc +++ b/test/cpp/util/metrics_server.cc @@ -35,6 +35,7 @@ #include <grpc++/server.h> #include <grpc++/server_builder.h> +#include <grpc/support/log.h> #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" diff --git a/test/cpp/util/metrics_server.h b/test/cpp/util/metrics_server.h index aa9bfed23d..4f1e393a63 100644 --- a/test/cpp/util/metrics_server.h +++ b/test/cpp/util/metrics_server.h @@ -83,13 +83,13 @@ class QpsGauge { std::mutex num_queries_mu_; }; -class MetricsServiceImpl GRPC_FINAL : public MetricsService::Service { +class MetricsServiceImpl final : public MetricsService::Service { public: grpc::Status GetAllGauges(ServerContext* context, const EmptyMessage* request, - ServerWriter<GaugeResponse>* writer) GRPC_OVERRIDE; + ServerWriter<GaugeResponse>* writer) override; grpc::Status GetGauge(ServerContext* context, const GaugeRequest* request, - GaugeResponse* response) GRPC_OVERRIDE; + GaugeResponse* response) override; // Create a QpsGauge with name 'name'. is_present is set to true if the Gauge // is already present in the map. diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc index 0c88c24448..3e524227e5 100644 --- a/test/cpp/util/proto_file_parser.cc +++ b/test/cpp/util/proto_file_parser.cc @@ -36,6 +36,7 @@ #include <algorithm> #include <iostream> #include <sstream> +#include <unordered_set> #include <grpc++/support/config.h> @@ -60,7 +61,7 @@ class ErrorPrinter : public protobuf::compiler::MultiFileErrorCollector { explicit ErrorPrinter(ProtoFileParser* parser) : parser_(parser) {} void AddError(const grpc::string& filename, int line, int column, - const grpc::string& message) GRPC_OVERRIDE { + const grpc::string& message) override { std::ostringstream oss; oss << "error " << filename << " " << line << " " << column << " " << message << "\n"; @@ -68,7 +69,7 @@ class ErrorPrinter : public protobuf::compiler::MultiFileErrorCollector { } void AddWarning(const grpc::string& filename, int line, int column, - const grpc::string& message) GRPC_OVERRIDE { + const grpc::string& message) override { std::cerr << "warning " << filename << " " << line << " " << column << " " << message << std::endl; } @@ -81,12 +82,13 @@ ProtoFileParser::ProtoFileParser(std::shared_ptr<grpc::Channel> channel, const grpc::string& proto_path, const grpc::string& protofiles) : has_error_(false) { - std::vector<std::string> service_list; + std::vector<grpc::string> service_list; if (channel) { reflection_db_.reset(new grpc::ProtoReflectionDescriptorDatabase(channel)); reflection_db_->GetServices(&service_list); } + std::unordered_set<grpc::string> known_services; if (!protofiles.empty()) { source_tree_.MapPath("", proto_path); error_printer_.reset(new ErrorPrinter(this)); @@ -100,6 +102,7 @@ ProtoFileParser::ProtoFileParser(std::shared_ptr<grpc::Channel> channel, if (file_desc) { for (int i = 0; i < file_desc->service_count(); i++) { service_desc_list_.push_back(file_desc->service(i)); + known_services.insert(file_desc->service(i)->full_name()); } } else { std::cerr << file_name << " not found" << std::endl; @@ -127,9 +130,12 @@ ProtoFileParser::ProtoFileParser(std::shared_ptr<grpc::Channel> channel, dynamic_factory_.reset(new protobuf::DynamicMessageFactory(desc_pool_.get())); for (auto it = service_list.begin(); it != service_list.end(); it++) { - if (const protobuf::ServiceDescriptor* service_desc = - desc_pool_->FindServiceByName(*it)) { - service_desc_list_.push_back(service_desc); + if (known_services.find(*it) == known_services.end()) { + if (const protobuf::ServiceDescriptor* service_desc = + desc_pool_->FindServiceByName(*it)) { + service_desc_list_.push_back(service_desc); + known_services.insert(*it); + } } } } @@ -146,7 +152,8 @@ grpc::string ProtoFileParser::GetFullMethodName(const grpc::string& method) { const auto* method_desc = service_desc->method(j); if (MethodNameMatch(method_desc->full_name(), method)) { if (method_descriptor) { - std::ostringstream error_stream("Ambiguous method names: "); + std::ostringstream error_stream; + error_stream << "Ambiguous method names: "; error_stream << method_descriptor->full_name() << " "; error_stream << method_desc->full_name(); LogError(error_stream.str()); diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index f0d14c686a..54790be496 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -255,7 +255,7 @@ bool ProtoReflectionDescriptorDatabase::FindAllExtensionNumbers( } bool ProtoReflectionDescriptorDatabase::GetServices( - std::vector<std::string>* output) { + std::vector<grpc::string>* output) { ServerReflectionRequest request; request.set_list_services(""); ServerReflectionResponse response; @@ -288,7 +288,7 @@ bool ProtoReflectionDescriptorDatabase::GetServices( const protobuf::FileDescriptorProto ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse( - const std::string& byte_fd_proto) { + const grpc::string& byte_fd_proto) { protobuf::FileDescriptorProto file_desc_proto; file_desc_proto.ParseFromString(byte_fd_proto); return file_desc_proto; @@ -314,13 +314,16 @@ ProtoReflectionDescriptorDatabase::GetStream() { return stream_; } -void ProtoReflectionDescriptorDatabase::DoOneRequest( +bool ProtoReflectionDescriptorDatabase::DoOneRequest( const ServerReflectionRequest& request, ServerReflectionResponse& response) { + bool success = false; stream_mutex_.lock(); - GetStream()->Write(request); - GetStream()->Read(&response); + if (GetStream()->Write(request) && GetStream()->Read(&response)) { + success = true; + } stream_mutex_.unlock(); + return success; } } // namespace grpc diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index eb7cf4907d..259277ebbe 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -38,13 +38,10 @@ #include <unordered_set> #include <vector> -// 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 -#include <grpc++/ext/reflection.grpc.pb.h> -#endif // GRPC_NO_GENERATED_CODE #include <grpc++/grpc++.h> +#include <grpc++/impl/codegen/config_protobuf.h> +#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" + namespace grpc { // ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and @@ -65,14 +62,13 @@ class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { // 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, - protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; + protobuf::FileDescriptorProto* output) 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, - protobuf::FileDescriptorProto* output) - GRPC_OVERRIDE; + protobuf::FileDescriptorProto* output) override; // Find the file which defines an extension extending the given message type // with the given field number. If found, fills in *output and returns true, @@ -80,7 +76,7 @@ class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { // must be a fully-qualified type name. bool FindFileContainingExtension( const string& containing_type, int field_number, - protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; + protobuf::FileDescriptorProto* output) override; // Finds the tag numbers used by all known extensions of // extendee_type, and appends them to output in an undefined @@ -90,10 +86,10 @@ class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { // numbers. Returns true if the search was successful, otherwise // returns false and leaves output unchanged. bool FindAllExtensionNumbers(const string& extendee_type, - std::vector<int>* output) GRPC_OVERRIDE; + std::vector<int>* output) override; // Provide a list of full names of registered services - bool GetServices(std::vector<std::string>* output); + bool GetServices(std::vector<grpc::string>* output); private: typedef ClientReaderWriter< @@ -102,14 +98,14 @@ class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { ClientStream; const protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse( - const std::string& byte_fd_proto); + const grpc::string& byte_fd_proto); void AddFileFromResponse( const grpc::reflection::v1alpha::FileDescriptorResponse& response); const std::shared_ptr<ClientStream> GetStream(); - void DoOneRequest( + bool DoOneRequest( const grpc::reflection::v1alpha::ServerReflectionRequest& request, grpc::reflection::v1alpha::ServerReflectionResponse& response); diff --git a/test/cpp/util/service_describer.cc b/test/cpp/util/service_describer.cc new file mode 100644 index 0000000000..4fe4a74805 --- /dev/null +++ b/test/cpp/util/service_describer.cc @@ -0,0 +1,108 @@ +/* + * + * 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 "test/cpp/util/service_describer.h" + +#include <iostream> +#include <sstream> +#include <string> +#include <vector> + +namespace grpc { +namespace testing { + +grpc::string DescribeServiceList(std::vector<grpc::string> service_list, + grpc::protobuf::DescriptorPool& desc_pool) { + std::stringstream result; + for (auto it = service_list.begin(); it != service_list.end(); it++) { + auto const& service = *it; + const grpc::protobuf::ServiceDescriptor* service_desc = + desc_pool.FindServiceByName(service); + if (service_desc != nullptr) { + result << DescribeService(service_desc); + } + } + return result.str(); +} + +grpc::string DescribeService(const grpc::protobuf::ServiceDescriptor* service) { + grpc::string result; + if (service->options().deprecated()) { + result.append("DEPRECATED\n"); + } + result.append("filename: " + service->file()->name() + "\n"); + + grpc::string package = service->full_name(); + size_t pos = package.rfind("." + service->name()); + if (pos != grpc::string::npos) { + package.erase(pos); + result.append("package: " + package + ";\n"); + } + result.append("service " + service->name() + " {\n"); + for (int i = 0; i < service->method_count(); ++i) { + result.append(DescribeMethod(service->method(i))); + } + result.append("}\n\n"); + return result; +} + +grpc::string DescribeMethod(const grpc::protobuf::MethodDescriptor* method) { + std::stringstream result; + result << " rpc " << method->name() + << (method->client_streaming() ? "(stream " : "(") + << method->input_type()->full_name() << ") returns " + << (method->server_streaming() ? "(stream " : "(") + << method->output_type()->full_name() << ") {}\n"; + if (method->options().deprecated()) { + result << " DEPRECATED"; + } + return result.str(); +} + +grpc::string SummarizeService( + const grpc::protobuf::ServiceDescriptor* service) { + grpc::string result; + for (int i = 0; i < service->method_count(); ++i) { + result.append(SummarizeMethod(service->method(i))); + } + return result; +} + +grpc::string SummarizeMethod(const grpc::protobuf::MethodDescriptor* method) { + grpc::string result = method->name(); + result.append("\n"); + return result; +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/service_describer.h b/test/cpp/util/service_describer.h new file mode 100644 index 0000000000..02c58e84c4 --- /dev/null +++ b/test/cpp/util/service_describer.h @@ -0,0 +1,57 @@ +/* + * + * 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_TEST_CPP_UTIL_SERVICE_DESCRIBER_H +#define GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H + +#include <grpc++/support/config.h> +#include "test/cpp/util/config_grpc_cli.h" + +namespace grpc { +namespace testing { + +grpc::string DescribeServiceList(std::vector<grpc::string> service_list, + grpc::protobuf::DescriptorPool& desc_pool); + +grpc::string DescribeService(const grpc::protobuf::ServiceDescriptor* service); + +grpc::string DescribeMethod(const grpc::protobuf::MethodDescriptor* method); + +grpc::string SummarizeService(const grpc::protobuf::ServiceDescriptor* service); + +grpc::string SummarizeMethod(const grpc::protobuf::MethodDescriptor* method); + +} // namespase testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 6e68f59e6a..0456b96667 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -34,9 +34,10 @@ #include "test/cpp/util/test_credentials_provider.h" +#include <mutex> #include <unordered_map> -#include <grpc++/impl/sync.h> +#include <grpc/support/log.h> #include <grpc/support/sync.h> #include "test/core/end2end/data/ssl_test_data.h" @@ -63,14 +64,14 @@ class CredentialsProvider { class DefaultCredentialsProvider : public CredentialsProvider { public: - ~DefaultCredentialsProvider() GRPC_OVERRIDE {} + ~DefaultCredentialsProvider() override {} - void AddSecureType(const grpc::string& type, - std::unique_ptr<CredentialTypeProvider> type_provider) - GRPC_OVERRIDE { + void AddSecureType( + const grpc::string& type, + std::unique_ptr<CredentialTypeProvider> type_provider) override { // This clobbers any existing entry for type, except the defaults, which // can't be clobbered. - grpc::unique_lock<grpc::mutex> lock(mu_); + std::unique_lock<std::mutex> lock(mu_); auto it = std::find(added_secure_type_names_.begin(), added_secure_type_names_.end(), type); if (it == added_secure_type_names_.end()) { @@ -83,7 +84,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { } std::shared_ptr<ChannelCredentials> GetChannelCredentials( - const grpc::string& type, ChannelArguments* args) GRPC_OVERRIDE { + const grpc::string& type, ChannelArguments* args) override { if (type == grpc::testing::kInsecureCredentialsType) { return InsecureChannelCredentials(); } else if (type == grpc::testing::kTlsCredentialsType) { @@ -91,7 +92,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { args->SetSslTargetNameOverride("foo.test.google.fr"); return SslCredentials(ssl_opts); } else { - grpc::unique_lock<grpc::mutex> lock(mu_); + std::unique_lock<std::mutex> lock(mu_); auto it(std::find(added_secure_type_names_.begin(), added_secure_type_names_.end(), type)); if (it == added_secure_type_names_.end()) { @@ -104,7 +105,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { } std::shared_ptr<ServerCredentials> GetServerCredentials( - const grpc::string& type) GRPC_OVERRIDE { + const grpc::string& type) override { if (type == grpc::testing::kInsecureCredentialsType) { return InsecureServerCredentials(); } else if (type == grpc::testing::kTlsCredentialsType) { @@ -115,7 +116,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { ssl_opts.pem_key_cert_pairs.push_back(pkcp); return SslServerCredentials(ssl_opts); } else { - grpc::unique_lock<grpc::mutex> lock(mu_); + std::unique_lock<std::mutex> lock(mu_); auto it(std::find(added_secure_type_names_.begin(), added_secure_type_names_.end(), type)); if (it == added_secure_type_names_.end()) { @@ -126,10 +127,10 @@ class DefaultCredentialsProvider : public CredentialsProvider { ->GetServerCredentials(); } } - std::vector<grpc::string> GetSecureCredentialsTypeList() GRPC_OVERRIDE { + std::vector<grpc::string> GetSecureCredentialsTypeList() override { std::vector<grpc::string> types; types.push_back(grpc::testing::kTlsCredentialsType); - grpc::unique_lock<grpc::mutex> lock(mu_); + std::unique_lock<std::mutex> lock(mu_); for (auto it = added_secure_type_names_.begin(); it != added_secure_type_names_.end(); it++) { types.push_back(*it); @@ -138,7 +139,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { } private: - grpc::mutex mu_; + std::mutex mu_; std::vector<grpc::string> added_secure_type_names_; std::vector<std::unique_ptr<CredentialTypeProvider>> added_secure_type_providers_; |