aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Yang Gao <yangg@google.com>2015-06-16 00:43:25 -0700
committerGravatar Yang Gao <yangg@google.com>2015-06-16 00:43:25 -0700
commit102eccb63238f2b40e89d2ec1ed93a7771a82798 (patch)
tree08d6e3b841ba37ccf88fbf18281115bbb062d01f
parentac366f9c2e3736815c4445baa4ad4745d2b0b511 (diff)
Support sending and showing received metadata in grpc_cli
-rw-r--r--test/cpp/util/cli_call.cc24
-rw-r--r--test/cpp/util/cli_call.h12
-rw-r--r--test/cpp/util/cli_call_test.cc20
-rw-r--r--test/cpp/util/grpc_cli.cc74
4 files changed, 109 insertions, 21 deletions
diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc
index eb67b8d314..5c2b2adb5c 100644
--- a/test/cpp/util/cli_call.cc
+++ b/test/cpp/util/cli_call.cc
@@ -52,11 +52,20 @@ namespace {
void* tag(int i) { return (void*)(gpr_intptr) i; }
} // namespace
-void CliCall::Call(std::shared_ptr<grpc::ChannelInterface> channel,
- const grpc::string& method, const grpc::string& request,
- grpc::string* response) {
+Status CliCall::Call(std::shared_ptr<grpc::ChannelInterface> channel,
+ const grpc::string& method, const grpc::string& request,
+ grpc::string* response, const MetadataContainer& metadata,
+ MetadataContainer* server_initial_metadata,
+ MetadataContainer* server_trailing_metadata) {
std::unique_ptr<grpc::GenericStub> stub(new grpc::GenericStub(channel));
grpc::ClientContext ctx;
+ if (!metadata.empty()) {
+ for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
+ metadata.begin();
+ iter != metadata.end(); ++iter) {
+ ctx.AddMetadata(iter->first, iter->second);
+ }
+ }
grpc::CompletionQueue cq;
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> call(
stub->Call(&ctx, method, &cq, tag(1)));
@@ -79,7 +88,7 @@ void CliCall::Call(std::shared_ptr<grpc::ChannelInterface> channel,
cq.Next(&got_tag, &ok);
if (!ok) {
std::cout << "Failed to read response." << std::endl;
- return;
+ return Status(StatusCode::INTERNAL, "Failed to read response");
}
grpc::Status status;
call->Finish(&status, tag(5));
@@ -87,7 +96,6 @@ void CliCall::Call(std::shared_ptr<grpc::ChannelInterface> channel,
GPR_ASSERT(ok);
if (status.IsOk()) {
- std::cout << "RPC finished with OK status." << std::endl;
std::vector<grpc::Slice> slices;
recv_buffer.Dump(&slices);
@@ -96,10 +104,10 @@ void CliCall::Call(std::shared_ptr<grpc::ChannelInterface> channel,
response->append(reinterpret_cast<const char*>(slices[i].begin()),
slices[i].size());
}
- } else {
- std::cout << "RPC finished with status code " << status.code()
- << " details: " << status.details() << std::endl;
}
+ *server_initial_metadata = ctx.GetServerInitialMetadata();
+ *server_trailing_metadata = ctx.GetServerTrailingMetadata();
+ return status;
}
} // namespace testing
diff --git a/test/cpp/util/cli_call.h b/test/cpp/util/cli_call.h
index 7be8bb63c4..8d114c9cb5 100644
--- a/test/cpp/util/cli_call.h
+++ b/test/cpp/util/cli_call.h
@@ -34,17 +34,23 @@
#ifndef GRPC_TEST_CPP_UTIL_CLI_CALL_H
#define GRPC_TEST_CPP_UTIL_CLI_CALL_H
+#include <map>
+
#include <grpc++/channel_interface.h>
#include <grpc++/config.h>
+#include <grpc++/status.h>
namespace grpc {
namespace testing {
class CliCall GRPC_FINAL {
public:
- static void Call(std::shared_ptr<grpc::ChannelInterface> channel,
- const grpc::string& method, const grpc::string& request,
- grpc::string* response);
+ typedef std::multimap<grpc::string, grpc::string> MetadataContainer;
+ static Status Call(std::shared_ptr<grpc::ChannelInterface> channel,
+ const grpc::string& method, const grpc::string& request,
+ grpc::string* response, const MetadataContainer& metadata,
+ MetadataContainer* server_initial_metadata,
+ MetadataContainer* server_trailing_metadata);
};
} // namespace testing
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
index 457a5e77de..fb6e926367 100644
--- a/test/cpp/util/cli_call_test.cc
+++ b/test/cpp/util/cli_call_test.cc
@@ -60,6 +60,14 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
public:
Status Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) GRPC_OVERRIDE {
+ if (!context->client_metadata().empty()) {
+ for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
+ context->client_metadata().begin();
+ iter != context->client_metadata().end(); ++iter) {
+ context->AddInitialMetadata(iter->first, iter->second);
+ }
+ }
+ context->AddTrailingMetadata("trailing_key", "trailing_value");
response->set_message(request->message());
return Status::OK;
}
@@ -106,6 +114,7 @@ TEST_F(CliCallTest, SimpleRpc) {
request.set_message("Hello");
ClientContext context;
+ context.AddMetadata("key1", "val1");
Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(s.IsOk());
@@ -114,8 +123,17 @@ TEST_F(CliCallTest, SimpleRpc) {
grpc::string request_bin, response_bin, expected_response_bin;
EXPECT_TRUE(request.SerializeToString(&request_bin));
EXPECT_TRUE(response.SerializeToString(&expected_response_bin));
- CliCall::Call(channel_, kMethod, request_bin, &response_bin);
+ std::multimap<grpc::string, grpc::string> client_metadata,
+ server_initial_metadata, server_trailing_metadata;
+ client_metadata.insert(std::pair<grpc::string, grpc::string>("key1", "val1"));
+ Status s2 = CliCall::Call(channel_, kMethod, request_bin, &response_bin,
+ client_metadata, &server_initial_metadata,
+ &server_trailing_metadata);
+ EXPECT_TRUE(s2.IsOk());
+
EXPECT_EQ(expected_response_bin, response_bin);
+ EXPECT_EQ(context.GetServerInitialMetadata(), server_initial_metadata);
+ EXPECT_EQ(context.GetServerTrailingMetadata(), server_trailing_metadata);
}
} // namespace testing
diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc
index ad3c0af877..06a7029a6d 100644
--- a/test/cpp/util/grpc_cli.cc
+++ b/test/cpp/util/grpc_cli.cc
@@ -41,8 +41,8 @@
body: "hello world"
}
b. under grpc/ run
- protoc --proto_path=test/cpp/interop/ \
- --encode=grpc.testing.SimpleRequest test/cpp/interop/messages.proto \
+ protoc --proto_path=test/proto/ \
+ --encode=grpc.testing.SimpleRequest test/proto/messages.proto \
< input.txt > input.bin
2. Start a server
make interop_server && bins/opt/interop_server --port=50051
@@ -51,10 +51,12 @@
/grpc.testing.TestService/UnaryCall --enable_ssl=false \
--input_binary_file=input.bin --output_binary_file=output.bin
4. Decode response
- protoc --proto_path=test/cpp/interop/ \
- --decode=grpc.testing.SimpleResponse test/cpp/interop/messages.proto \
+ protoc --proto_path=test/proto/ \
+ --decode=grpc.testing.SimpleResponse test/proto/messages.proto \
< output.bin > output.txt
5. Now the text form of response should be in output.txt
+ Optionally, metadata can be passed to server via flag --metadata, e.g.
+ --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2"
*/
#include <fstream>
@@ -77,6 +79,44 @@ DEFINE_string(input_binary_file, "",
"Path to input file containing serialized request.");
DEFINE_string(output_binary_file, "output.bin",
"Path to output file to write serialized response.");
+DEFINE_string(metadata, "",
+ "Metadata to send to server, in the form of key1:val1:key2:val2");
+
+void ParseMetadataFlag(
+ std::multimap<grpc::string, grpc::string>* client_metadata) {
+ if (FLAGS_metadata.empty()) {
+ return;
+ }
+ std::vector<grpc::string> fields;
+ grpc::string delim(":");
+ size_t cur, next = -1;
+ do {
+ cur = next + 1;
+ next = FLAGS_metadata.find_first_of(delim, cur);
+ fields.push_back(FLAGS_metadata.substr(cur, next - cur));
+ } while (next != grpc::string::npos);
+ if (fields.size() % 2) {
+ std::cout << "Failed to parse metadata flag" << std::endl;
+ exit(1);
+ }
+ for (size_t i = 0; i < fields.size(); i += 2) {
+ client_metadata->insert(
+ std::pair<grpc::string, grpc::string>(fields[i], fields[i + 1]));
+ }
+}
+
+void PrintMetadata(const std::multimap<grpc::string, grpc::string>& m,
+ const grpc::string& message) {
+ if (m.empty()) {
+ return;
+ }
+ std::cout << message << std::endl;
+ for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
+ m.begin();
+ iter != m.end(); ++iter) {
+ std::cout << iter->first << " : " << iter->second << std::endl;
+ }
+}
int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
@@ -118,11 +158,27 @@ int main(int argc, char** argv) {
grpc::CreateChannel(server_address, creds, grpc::ChannelArguments());
grpc::string response;
- grpc::testing::CliCall::Call(channel, method, input_stream.str(), &response);
- if (!response.empty()) {
- std::ofstream output_file(FLAGS_output_binary_file,
- std::ios::trunc | std::ios::binary);
- output_file << response;
+ std::multimap<grpc::string, grpc::string> client_metadata,
+ server_initial_metadata, server_trailing_metadata;
+ ParseMetadataFlag(&client_metadata);
+ PrintMetadata(client_metadata, "Sending client initial metadata:");
+ grpc::Status s = grpc::testing::CliCall::Call(
+ channel, method, input_stream.str(), &response, client_metadata,
+ &server_initial_metadata, &server_trailing_metadata);
+ PrintMetadata(server_initial_metadata,
+ "Received initial metadata from server:");
+ PrintMetadata(server_trailing_metadata,
+ "Received trailing metadata from server:");
+ if (s.IsOk()) {
+ std::cout << "Rpc succeeded with OK status" << std::endl;
+ if (!response.empty()) {
+ std::ofstream output_file(FLAGS_output_binary_file,
+ std::ios::trunc | std::ios::binary);
+ output_file << response;
+ }
+ } else {
+ std::cout << "Rpc failed with status code " << s.code() << " error message "
+ << s.details() << std::endl;
}
return 0;