siso: proxy longrunning GetOperation

reapi.Client will call longrunning GetOperation in Client.executeOperation,
so should proxy the grpc method.

Change-Id: I7379caa3548796aa0acab060880636d46b490ec7
Reviewed-on: https://chromium-review.googlesource.com/c/build/+/8161564
Reviewed-by: Yuke Liao <liaoyuke@google.com>
Commit-Queue: Fumitoshi Ukai <ukai@google.com>
Auto-Submit: Fumitoshi Ukai <ukai@google.com>
diff --git a/siso/reapi/proxy.go b/siso/reapi/proxy.go
index 2b0b6e0..54c8084 100644
--- a/siso/reapi/proxy.go
+++ b/siso/reapi/proxy.go
@@ -132,6 +132,9 @@
 	ep := &executionProxy{client: rpb.NewExecutionClient(p.client.conn)}
 	rpb.RegisterExecutionServer(server, ep)
 
+	op := &operationsProxy{client: longrunningpb.NewOperationsClient(p.client.conn)}
+	longrunningpb.RegisterOperationsServer(server, op)
+
 	bsp := &byteStreamProxy{client: bspb.NewByteStreamClient(p.client.casDataConn)}
 	bspb.RegisterByteStreamServer(server, bsp)
 
@@ -390,3 +393,12 @@
 		}
 	}
 }
+
+type operationsProxy struct {
+	longrunningpb.UnimplementedOperationsServer
+	client longrunningpb.OperationsClient
+}
+
+func (op *operationsProxy) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest) (*longrunningpb.Operation, error) {
+	return op.client.GetOperation(ctx, req)
+}
diff --git a/siso/reapi/proxy_test.go b/siso/reapi/proxy_test.go
index 6f2d811..451e88e 100644
--- a/siso/reapi/proxy_test.go
+++ b/siso/reapi/proxy_test.go
@@ -9,9 +9,12 @@
 	"net"
 	"testing"
 
+	"cloud.google.com/go/longrunning/autogen/longrunningpb"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/credentials/insecure"
 	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
 	"google.golang.org/grpc/test/bufconn"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/types/known/emptypb"
@@ -141,3 +144,68 @@
 		t.Errorf("outgoing metadata = %v, want none", md)
 	}
 }
+
+type fakeOperationsServer struct {
+	longrunningpb.UnimplementedOperationsServer
+	op *longrunningpb.Operation
+}
+
+func (f *fakeOperationsServer) GetOperation(_ context.Context, req *longrunningpb.GetOperationRequest) (*longrunningpb.Operation, error) {
+	if req.GetName() == f.op.GetName() {
+		return f.op, nil
+	}
+	return nil, status.Error(codes.NotFound, "operation not found")
+}
+
+func TestOperationsProxy_GetOperation(t *testing.T) {
+	wantOp := &longrunningpb.Operation{
+		Name: "operations/test-op-123",
+		Done: true,
+	}
+	fake := &fakeOperationsServer{op: wantOp}
+
+	backendLis := bufconn.Listen(1 << 20)
+	srv := grpc.NewServer()
+	longrunningpb.RegisterOperationsServer(srv, fake)
+	go srv.Serve(backendLis)
+	t.Cleanup(srv.Stop)
+
+	conn, err := grpc.NewClient("passthrough:///bufnet",
+		grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
+			return backendLis.DialContext(ctx)
+		}),
+		grpc.WithTransportCredentials(insecure.NewCredentials()),
+	)
+	if err != nil {
+		t.Fatalf("NewClient: %v", err)
+	}
+	t.Cleanup(func() { conn.Close() })
+
+	opProxy := &operationsProxy{client: longrunningpb.NewOperationsClient(conn)}
+
+	proxyLis := bufconn.Listen(1 << 20)
+	proxySrv := grpc.NewServer()
+	longrunningpb.RegisterOperationsServer(proxySrv, opProxy)
+	go proxySrv.Serve(proxyLis)
+	t.Cleanup(proxySrv.Stop)
+
+	proxyConn, err := grpc.NewClient("passthrough:///bufnet",
+		grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
+			return proxyLis.DialContext(ctx)
+		}),
+		grpc.WithTransportCredentials(insecure.NewCredentials()),
+	)
+	if err != nil {
+		t.Fatalf("NewClient proxy: %v", err)
+	}
+	t.Cleanup(func() { proxyConn.Close() })
+
+	cli := longrunningpb.NewOperationsClient(proxyConn)
+	gotOp, err := cli.GetOperation(t.Context(), &longrunningpb.GetOperationRequest{Name: "operations/test-op-123"})
+	if err != nil {
+		t.Fatalf("GetOperation failed: %v", err)
+	}
+	if gotOp.GetName() != wantOp.GetName() || gotOp.GetDone() != wantOp.GetDone() {
+		t.Errorf("GetOperation = %v, want %v", gotOp, wantOp)
+	}
+}