Testing your gRPC services using grpc_cli

This post may be helpful for you if you are building gRPC services and want a convenient way to test your service using a command line tool. Similar to using cURL when testing HTTP(s) services, I wanted an easy way to test the gRPC services that I’m building.

Originally, I had originally planned to whip together a tiny C++ program that sends protobuf messages to my MapReduce service that I’m building for advanced operating systems course. Fortunately, a testing tool already exists: grpc_cli. Even better is that the tool ships with the grpc source code.

So follow along if you want to install the grpc command line tool, enable server reflection, and execute a few examples.

Note: This post assumes that you are programming in C++ and your operating system is Ubuntu

Install grpc_cli

Follow the steps below if you are running on Ubuntu. If you are running gRPC on your mac, then you’ll want to substitute the apt-get command with brew install, as described in the grpc command line documentation.

  1. Clone the grpc repository
    git clone git@github.com:grpc/grpc.git
  2. Add submodules
    $ git submodule update --init
  3. Install libflags-dev
    $ sudo apt-get install libgflags-dev
  4. Compile grpc
    $ mkdir -p cmake/build
    $ cd cmake/build
    $ cmake -DgRPC_BUILD_TESTS=ON ../..
    $ make grpc_cli
    

Enable Reflection for your service

In your grpc service code, before you bind and listen, you’ll need to enable reflection. Although not entirely necessary for interacting with your service, not having reflection enabled means you cannot use many of the grpc_cli commands like list.

grpc::reflection::InitProtoReflectionServerBuilderPlugin();
grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
...

Add grpc++_reflection library

Make sure that you are adding grpc++ library when building your project. If you are a student in advanced operating systems, you’ll need to update GeneratedProtos.cmake and link the gRPC::grpc++_reflection library as follows:

% git diff
diff --git a/src/GenerateProtos.cmake b/src/GenerateProtos.cmake
index c6a80bc..cce2d51 100644
--- a/src/GenerateProtos.cmake
+++ b/src/GenerateProtos.cmake
@@ -75,5 +75,5 @@ add_custom_command(
)

add_library(p4protolib ${ProtoHeaders} ${ProtoSources})
-target_link_libraries(p4protolib PUBLIC protobuf::libprotobuf gRPC::grpc++)
+target_link_libraries(p4protolib PUBLIC protobuf::libprotobuf gRPC::grpc++ gRPC::grpc++_reflection)
target_include_directories(p4protolib PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})

 

Using grpc_cli

I’d encourage you to explore the grpc_cli by checking out the official user guide. However, for the purpose of this post, I want to show you how to list your service as well as how to invoke the “MapReduce” service.

Examples

Start your gRPC service

In the example below, I’m staring my worker process that listens on localhost:50051. Here’s a snippet of my very bare service:

service MapReduce {
rpc map(MapRequest) returns (MapResponse) {}
rpc reduce(ReduceRequest) returns (ReduceResponse) {}

Starting the service

$ ./mr_worker localhost:50051
Listening on ip address: localhost
Listening on port: 50051
Server listening on localhost:50051

List the services

After starting my service (that has reflection enabled), the service shows up when I execute the list command:

$ ./grpc_cli ls localhost:50051
masterworker.MapReduce
grpc.reflection.v1alpha.ServerReflection
grpc.health.v1.Health

Invoking “MapReduce”

$ ./grpc_cli call localhost:50051 masterworker.MapReduce.map "shard_data: '123'"
connecting to localhost:50051
Rpc succeeded with OK status

Passing in multiple fields

$ ./grpc_cli call localhost:50051 masterworker.MapReduce.reduce "filename: '123' worker_hostname: 'localhost' worker_port: 50051"
connecting to localhost:50051
Rpc succeeded with OK status

References

  • https://grpc.github.io/grpc/cpp/md_doc_server_reflection_tutorial.html
  • https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md
  • https://stackoverflow.com/questions/61641174/unable-to-link-the-grpc-libraries-in-windows