mockgcp

package module
v0.0.0-...-8078c5c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2024 License: Apache-2.0 Imports: 45 Imported by: 0

README

MockGCP

MockGCP contains stub implementations of GCP APIs, for use with testing KCC. The implementations don't do anything (there is no "backend") - creating a mock VM does not launch a VM. Instead, the goal is to provide just-enough consistent CRUD operations to test the KCC providers. If the tests pass, we consider that to be a "good enough" mock for GCP. When we discover an issue that the mocks failed to catch, we should update mockgcp to more accurately simulate GCP, ideally triggering the bug and then showing that the fix addresses the issue.

At their core, most GCP APIs are CRUD-based, so implementing a basic implementation is fairly straightforward. We are establishing some patterns to make the implementation as simple as possible, such as a simple storage driver that works with the existing protos.

In general, we use the protos published by GCP at https://github.com/googleapis/googleapis.git. These protos make it relatively easy to implement the CRUD operations needed.

In addition, the protos have the annotations needed for GRPC <-> HTTP interop. We use grpc-gateway to create HTTP servers from GRPC servers.

It is then fairly straightforward to inject our own HTTP handlers directly into the serving paths for tests, so we don't even need to start a real webserver (i.e. we don't even need to listen on a port)

Adding a new service

To add a new service, the easiest way is to copy one of the existing CLs. Example CL: mockGCP for cloudfunctions

Broadly the steps are:

  1. Add the proto to the Makefile and run make gen-proto (or just make, as it's the default target).

    All google services are located in googleapis Github repo, refer to your resource's API documentation to identify the service name, for example privateca. Once you identify the service, find the proper path to the proto files, for example: cloud/security/privateca/v1/*.proto. Then replace the prefix googleapis/google/ to ./third_party/googleapis/mockgcp/, and add into the Makefile.

  2. (Optional). If you're adding an API outside of googleapis/google/cloud, you may need to add commands to rename the API o mockgcp in fixup-third-party.sh. Example:

    ...
    mv google/logging/ mockgcp/
    ...
    find . -type f -print0 | xargs -0 sed -i -e "s@google/logging/@mockgcp/logging/@g"
    find . -type f -print0 | xargs -0 sed -i -e "s@google\.logging@mockgcp.logging@g"
    ...
    
  3. Add a subdirectory called mock<servicename>.

    Copying one of the existing ones. mockprivateca is a reasonable basic one. Keep the files names.go and service.go, rename the third one to <resourcename>.go.

  4. Adjust your mock to use your protos (change the import paths), rename the types, etc.

  5. Implement the core CRUD methods in <resourcename>.go.

    In the example file capool.go, we have GET, CREATE and DELETE implemented. More probably, you will need to implement some more CRUD methods. In the log, you should see some errors indicating which method is not supported. For those methods, go into the service definition and implement a basic implementation - we have examples of most of the CRUD operations at this point.

  6. Register the mock service of your resource in the service.go file. Example.

  7. Add the service handler of your resource in the service.go file. Example.

  8. Add your service to mock_http_roundtrip.go, something like services = append(services, mockcloudbilling.New(env, storage)).

  9. Add the kind(s) you are adding support for to func MaybeSkip in harness.go.

  10. Run the tests.

    Example command: E2E_KUBE_TARGET=envtest RUN_E2E=1 E2E_GCP_TARGET=mock go test -test.count=1 -timeout 3600s -v ./tests/e2e -run TestAllInSeries/fixtures 2>&1 | tee log.

    You can also specify a single test to run to save time, for example, TestAllInSeries/fixtures/privatecacapool, or reduce the timeout from 3600s to 600s or any other reasonable value depends on your test.

If you are lucky, everything will "just work" and you will see that your new tests are being invoked.

If something is not behaving as you would expect, you should be able to launch a debugger because it all runs in one process. You can also use ARTIFACTS=artifacts to get detailed HTTP logs of the traffic, which is useful if you want to see the json requests & responses. If you also use E2E_GCP_TARGET=real you can run against the real (non-mocked) GCP, and easily see what the actual behaviour should be. Usually however, this is not necessary; the most common failure mode is that terraform or KCC expects a field to be automatically populated, and it normally logs an error like "foo not set" (in this case, simply add that to your mock implementation.)

Capture HTTP golden logs

Capture HTTP logs against real GCP:

Example command: E2E_KUBE_TARGET=envtest RUN_E2E=1 E2E_GCP_TARGET=real GOLDEN_REQUEST_CHECKS=1 WRITE_GOLDEN_OUTPUT=1 go test -test.count=1 -timeout 3600s -v ./tests/e2e -run TestAllInSeries/fixtures/test-name.

Capture HTTP logs against mock GCP:

We can consider getting HTTP logs against mockGCP after implementing the mockGCP service. For certain resources that are difficult to run against real GCP (for example, AttachedCluster requires an external cluster and EdgeContainer requires a physical machine, and etc), it's acceptable to capture the golden HTTP logs from the mock service.

Example command: E2E_KUBE_TARGET=envtest RUN_E2E=1 E2E_GCP_TARGET=mock GOLDEN_REQUEST_CHECKS=1 WRITE_GOLDEN_OUTPUT=1 go test -test.count=1 -timeout 3600s -v ./tests/e2e -run TestAllInSeries/fixtures/test-name.

A new file named "_http.log" will be created in the test folder during the first time the command is executed, that's our golden HTTP log. We will compare new HTTP logs with the golden HTTP log as a part of the mockGCP test if GOLDEN_REQUEST_CHECKS is specified.

To prevent any problems when comparing with the golden logs, it is necessary to replace all generated values in the HTTP log with identical values.

See here to get some ideas.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewMockRoundTripper

func NewMockRoundTripper(t *testing.T, k8sClient client.Client, storage storage.Storage) *mockRoundTripper

Types

type MockService

type MockService interface {
	// Register initializes the service, normally registering the GRPC service.
	Register(grpcServer *grpc.Server)

	// NewHTTPMux creates an HTTP mux for serving http traffic
	NewHTTPMux(ctx context.Context, conn *grpc.ClientConn) (http.Handler, error)

	// ExpectedHost is the hostname we serve on e.g. foo.googleapis.com
	ExpectedHost() string
}

MockService is the interface implemented by all services

Directories

Path Synopsis
generated
mockgcp/api/apikeys/v2
Package apikeyspb is a reverse proxy.
Package apikeyspb is a reverse proxy.
mockgcp/api/serviceusage/v1
Package serviceusagepb is a reverse proxy.
Package serviceusagepb is a reverse proxy.
mockgcp/api/serviceusage/v1beta1
Package serviceusage is a reverse proxy.
Package serviceusage is a reverse proxy.
mockgcp/cloud/aiplatform/v1beta1
Package aiplatformpb is a reverse proxy.
Package aiplatformpb is a reverse proxy.
mockgcp/cloud/alloydb/v1beta
Package alloydbpb is a reverse proxy.
Package alloydbpb is a reverse proxy.
mockgcp/cloud/bigquery/v2
Package bigquerypb is a reverse proxy.
Package bigquerypb is a reverse proxy.
mockgcp/cloud/billing/v1
Package billingpb is a reverse proxy.
Package billingpb is a reverse proxy.
mockgcp/cloud/certificatemanager/v1
Package certificatemanagerpb is a reverse proxy.
Package certificatemanagerpb is a reverse proxy.
mockgcp/cloud/compute/v1
Package computepb is a reverse proxy.
Package computepb is a reverse proxy.
mockgcp/cloud/edgecontainer/v1
Package edgecontainerpb is a reverse proxy.
Package edgecontainerpb is a reverse proxy.
mockgcp/cloud/edgenetwork/v1
Package edgenetworkpb is a reverse proxy.
Package edgenetworkpb is a reverse proxy.
mockgcp/cloud/functions/v1
Package functionspb is a reverse proxy.
Package functionspb is a reverse proxy.
mockgcp/cloud/gkehub/v1beta
Package gkehubpb is a reverse proxy.
Package gkehubpb is a reverse proxy.
mockgcp/cloud/gkemulticloud/v1
Package gkemulticloudpb is a reverse proxy.
Package gkemulticloudpb is a reverse proxy.
mockgcp/cloud/networkservices/v1
Package networkservicespb is a reverse proxy.
Package networkservicespb is a reverse proxy.
mockgcp/cloud/pubsublite/v1
Package pubsublitepb is a reverse proxy.
Package pubsublitepb is a reverse proxy.
mockgcp/cloud/redis/v1beta1
Package redispb is a reverse proxy.
Package redispb is a reverse proxy.
mockgcp/cloud/resourcemanager/v1
Package resourcemanagerpb is a reverse proxy.
Package resourcemanagerpb is a reverse proxy.
mockgcp/cloud/resourcemanager/v3
Package resourcemanagerpb is a reverse proxy.
Package resourcemanagerpb is a reverse proxy.
mockgcp/cloud/secretmanager/v1
Package secretmanagerpb is a reverse proxy.
Package secretmanagerpb is a reverse proxy.
mockgcp/cloud/security/privateca/v1
Package privatecapb is a reverse proxy.
Package privatecapb is a reverse proxy.
mockgcp/container/v1beta1
Package containerpb is a reverse proxy.
Package containerpb is a reverse proxy.
mockgcp/devtools/artifactregistry/v1
Package artifactregistrypb is a reverse proxy.
Package artifactregistrypb is a reverse proxy.
mockgcp/iam/admin/v1
Package adminpb is a reverse proxy.
Package adminpb is a reverse proxy.
mockgcp/logging/v2
Package loggingpb is a reverse proxy.
Package loggingpb is a reverse proxy.
mockgcp/monitoring/dashboard/v1
Package dashboardpb is a reverse proxy.
Package dashboardpb is a reverse proxy.
mockgcp/storage/v1
Package storagepb is a reverse proxy.
Package storagepb is a reverse proxy.
pkg
tools

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL