Skip to content

Commit

Permalink
tests: record grpc requests in our golden tests
Browse files Browse the repository at this point in the history
We aim to construct a readable version of the GRPC requests.
  • Loading branch information
justinsb committed Apr 26, 2024
1 parent eb371a4 commit 12841dd
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
43 changes: 43 additions & 0 deletions config/tests/samples/create/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package create

import (
"context"
"fmt"
"net/http"
"os"
"path/filepath"
Expand All @@ -29,6 +30,9 @@ import (
"golang.org/x/oauth2/google"
cloudresourcemanagerv1 "google.golang.org/api/cloudresourcemanager/v1"
"google.golang.org/api/option"
"google.golang.org/grpc"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"gopkg.in/dnaeon/go-vcr.v3/recorder"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand Down Expand Up @@ -253,11 +257,14 @@ func NewHarnessWithOptions(ctx context.Context, t *testing.T, opts *HarnessOptio
}
}

var mockCloudGRPCClientConnection *grpc.ClientConn
if targetGCP := os.Getenv("E2E_GCP_TARGET"); targetGCP == "mock" {
t.Logf("creating mock gcp")

mockCloud := mockgcp.NewMockRoundTripper(t, h.client, storage.NewInMemoryStorage())

mockCloudGRPCClientConnection = mockCloud.NewGRPCConnection(ctx)

roundTripper := http.RoundTripper(mockCloud)

ctx = context.WithValue(ctx, httpRoundTripperKey, roundTripper)
Expand Down Expand Up @@ -414,6 +421,42 @@ func NewHarnessWithOptions(ctx context.Context, t *testing.T, opts *HarnessOptio
return ret
}
} else {
// Intercept (and log) GRPC requests
grpcUnaryInterceptor := func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
entry := &test.LogEntry{}

entry.Request.URL = method
entry.Request.Method = "GRPC"

if req != nil {
requestBytes, _ := protojson.Marshal(req.(proto.Message))
entry.Request.Body = string(requestBytes)
}

if mockCloudGRPCClientConnection != nil {
cc = mockCloudGRPCClientConnection
}
err := invoker(ctx, method, req, reply, cc, opts...)

if reply != nil {
replyBytes, _ := protojson.Marshal(reply.(proto.Message))
entry.Response.Body = string(replyBytes)
}

if err != nil {
entry.Response.Status = fmt.Sprintf("error: %v", err)
} else {
entry.Response.Status = "OK"
}

for _, eventSink := range eventSinks {
eventSink.AddHTTPEvent(ctx, entry)
}
return err
}

transport_tpg.GRPCUnaryClientInterceptor = grpcUnaryInterceptor

// Intercept (and log) DCL requests
if len(eventSinks) != 0 {
if kccConfig.HTTPClient == nil {
Expand Down
5 changes: 5 additions & 0 deletions mockgcp/common/operations/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

pb "google.golang.org/genproto/googleapis/longrunning"
rpcstatus "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
Expand All @@ -44,6 +45,10 @@ func NewOperationsService(storage storage.Storage) *Operations {
}
}

func (s *Operations) RegisterGRPCServices(grpcServer *grpc.Server) {
pb.RegisterOperationsServer(grpcServer, s)
}

func (s *Operations) NewLRO(ctx context.Context) (*pb.Operation, error) {
now := time.Now()
millis := now.UnixMilli()
Expand Down
14 changes: 14 additions & 0 deletions mockgcp/mock_http_roundtrip.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp/common"
Expand Down Expand Up @@ -176,6 +177,19 @@ func NewMockRoundTripper(t *testing.T, k8sClient client.Client, storage storage.
return mockRoundTripper
}

func (m *mockRoundTripper) NewGRPCConnection(ctx context.Context) *grpc.ClientConn {
endpoint := m.grpcListener.Addr().String()

var opts []grpc.DialOption
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
// opts = append(opts, grpc.WithUnaryInterceptor(unaryInterceptor))
conn, err := grpc.DialContext(ctx, endpoint, opts...)
if err != nil {
klog.Fatalf("error dialing grpc endpoint %q: %v", endpoint, err)
}
return conn
}

func (m *mockRoundTripper) prefilterRequest(req *http.Request) error {
if req.Body != nil {
var requestBody bytes.Buffer
Expand Down

0 comments on commit 12841dd

Please sign in to comment.