Home > Blockchain >  grpc testing code exit 1 with 'rpc error: code = Unimplemented desc = method Hello not implemen
grpc testing code exit 1 with 'rpc error: code = Unimplemented desc = method Hello not implemen

Time:12-11

Environment

go version go1.17.4 linux/amd64

libprotoc 3.6.1

Problem

I'm testing grpc server and client implemented by Go.
First, I made proto definition and generate pb codes by protoc command. I referred this solution. Following the error is printed by minimum codes to reproduce my error.

Error

$ go test
--- FAIL: TestHello (0.00s)
    main_test.go:49: failed to Hello: rpc error: code = Unimplemented desc = method Hello not implemented
FAIL
exit status 1
FAIL    github.com/Asuha-a/test/test    0.003s

Code

hello.proto

syntax = "proto3";

option go_package = "github.com/Asuha-a/test/pb";

package hello;

service Hello {
  rpc Hello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string foo = 1;
}

message HelloReply {
  string bar = 1;
}

main_test.go

package hello_test

import (
    "context"
    "log"
    "net"
    "testing"

    "github.com/Asuha-a/test/pb"
    "google.golang.org/grpc"
    "google.golang.org/grpc/test/bufconn"
)

type server struct {
    pb.UnimplementedHelloServer
}

const bufSize = 1024 * 1024

var lis *bufconn.Listener

func init() {
    lis = bufconn.Listen(bufSize)
    s := grpc.NewServer()
    pb.RegisterHelloServer(s, &server{})
    go func() {
        if err := s.Serve(lis); err != nil {
            log.Fatalf("server exited with error: %v", err)
        }
    }()
}

func bufDialer(context.Context, string) (net.Conn, error) {
    return lis.Dial()
}

func TestHello(t *testing.T) {
    ctx := context.Background()
    conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
    if err != nil {
        t.Fatalf("failed to dial bufnet: %v", err)
    }
    defer conn.Close()
    client := pb.NewHelloClient(conn)
    r, err := client.Hello(ctx, &pb.HelloRequest{
        Foo: "foo",
    })
    if err != nil {
        t.Fatalf("failed to Hello: %v", err) //49th line prints the error
    }
    log.Println(r)
}

CodePudding user response:

In your test you are calling pb.RegisterHelloServer(s, &server{}) using the server struct. However this struct only embeds pb.UnimplementedHelloServer and declares no methods. Hence, you can only get codes.Unimplemented back when calling any of its RPCs.

You have to implement the Hello rpc on the server struct:

func (s *server) Hello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{}, nil
}

Note: embedding pb.UnimplementedHelloServer makes the gRPC server implementations forward compatible at the expense of compile-time checks. To forgo forward compatibility and catch these errors at compile time, you can embed instead pb.UnsafeHelloServer.

  • Related