cloudrunci

package
v0.0.0-...-3b29460 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2020 License: Apache-2.0 Imports: 13 Imported by: 0

README

Cloud Run CI

This utility facilitates deploying temporary Cloud Run services for testing purposes.

It has a hard dependency on gcloud, the Cloud SDK.

Please install and authenticate gcloud before using cloudrunci in your test.

Installation

import "github.com/GoogleCloudPlatform/golang-samples/internal/cloudrunci"

Configuration

Use the GCLOUD_BIN environment variable to override the gcloud path.

Documentation

Overview

Package cloudrunci facilitates end-to-end testing against the production Cloud Run.

This is a specialized tool that could be used in addition to unit tests. It calls the `gcloud beta run` command directly.

gcloud (https://cloud.google.com/sdk) must be installed. You must be authorized via the gcloud command-line tool (`gcloud auth login`).

You may specify the location of gcloud via the GCLOUD_BIN environment variable.

Package cloudrunci is a testing utility that facilitates end-to-end system testing on Cloud Run.

cloudrunci facilitates management of ephemeral (temporary) Cloud Run services on all Cloud Run platforms.

Example Usage

package main_test

import (
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"

	"github.com/GoogleCloudPlatform/golang-samples/internal/cloudrunci"
)

// TestMyService shows the simplest approach to create e2e tests with cloudrun-ci.
// It uses Cloud Run (fully managed) in the us-central1 region.
func TestMyService(t *testing.T) {
	myService := cloudrunci.NewService("my-service", os.Getenv("GOOGLE_CLOUD_PROJECT"))
	if err := myService.Deploy(); err != nil {
		t.Fatalf("could not deploy %s: %v", myService.Name, err)
	}
	defer myService.Clean()

	resp, err := myService.Request("GET", "/")
	if err != nil {
		t.Errorf("Get: %v", err)
		return
	}
	defer resp.Body.Close()

	got, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("ioutil.ReadAll: %q", err)
	}

	want := "Hello World!"
	if got := string(got); !strings.Contains(got, want) {
		t.Errorf("got\n----\n%s\n----\nWant to contain:\n----\n%s\n", got, shouldContain)
	}
}

Configure a pre-built image for testing:

projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")
myService := cloudrunci.NewService("my-service", projectID)
myService.Image = "gcr.io/" + projectID + "/my-service:v1.0"

Configure the service to deploy to Cloud Run (fully managed) in the us-east1 region:

myService := &cloudrunci.Service{
	Name:      "my-service",
	ProjectID: os.Getenv("GOOGLE_CLOUD_PROJECT"),
	Platform:  cloudrunci.ManagedPlatform{"us-east1"},
}

Configure the service for deploying to a Cloud Run for Anthos on GKE cluster:

myService := &cloudrunci.Service{
	Name:      "my-service",
	ProjectID: os.Getenv("GOOGLE_CLOUD_PROJECT"),
	Platform:  cloudrunci.GKEPlatform{Cluster: "my-cluster", ClusterLocation: "us-central1-c"},
}

Configure the service for deploying to a Cloud Run for Anthos on VMWare cluster:

myService := &cloudrunci.Service{
	Name:      "my-service",
	ProjectID: os.Getenv("GOOGLE_CLOUD_PROJECT"),
	Platform:  cloudrunci.KubernetesPlatform{Kubeconfig: "~/.kubeconfig", Context: "my-cluster"},
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateIDToken

func CreateIDToken(_ string) (string, error)

CreateIDToken generates an ID token for requests to the fully managed platform. In the future the URL of the targeted service will be used to scope the audience.

Types

type EnvVars

type EnvVars map[string]string

EnvVars is a collection of environment variables.

func (EnvVars) KeyString

func (e EnvVars) KeyString() string

KeyString converts the environment variables names to a comma-delimited list.

func (EnvVars) String

func (e EnvVars) String() string

func (EnvVars) Validate

func (e EnvVars) Validate() error

Validate confirms all environment variables are valid.

func (EnvVars) Variable

func (e EnvVars) Variable(k string) string

Variable retrieves an environment variable assignment as a string.

type GKEPlatform

type GKEPlatform struct {
	Cluster         string
	ClusterLocation string
	// contains filtered or unexported fields
}

GKEPlatform defines the GKE platform for Cloud Run services.

func (GKEPlatform) CommandFlags

func (p GKEPlatform) CommandFlags() []string

CommandFlags retrieves the common gcloud flags for targeting a GKE cluster.

func (GKEPlatform) Name

func (p GKEPlatform) Name() string

Name retrieves the ID for the GKE platform.

func (GKEPlatform) NewRequest

func (p GKEPlatform) NewRequest(method, url string) (*http.Request, error)

func (GKEPlatform) Validate

func (p GKEPlatform) Validate() error

Validate confirms required properties are set.

type KubernetesPlatform

type KubernetesPlatform struct {
	Kubeconfig string
	Context    string
	// contains filtered or unexported fields
}

KubernetesPlatform defines use of a knative-compatible kubernetes cluster beyond GKE.

func (KubernetesPlatform) CommandFlags

func (p KubernetesPlatform) CommandFlags() []string

CommandFlags retrieves the common gcloud flags for targeting a Kubernetes cluster.

func (KubernetesPlatform) Name

func (p KubernetesPlatform) Name() string

Name retrieves the ID for the Kubernetes platform.

func (KubernetesPlatform) NewRequest

func (p KubernetesPlatform) NewRequest(method, url string) (*http.Request, error)

func (KubernetesPlatform) Validate

func (p KubernetesPlatform) Validate() error

Validate confirms required properties are set.

type ManagedPlatform

type ManagedPlatform struct {
	Region string
	// contains filtered or unexported fields
}

ManagedPlatform defines the Cloud Run (fully managed) hosting platform.

func (ManagedPlatform) CommandFlags

func (p ManagedPlatform) CommandFlags() []string

CommandFlags retrieves the common gcloud flags for targeting the full managed platform in a given region.

func (ManagedPlatform) Name

func (p ManagedPlatform) Name() string

Name retrieves the ID for the full managed platform.

func (ManagedPlatform) NewRequest

func (p ManagedPlatform) NewRequest(method, url string) (*http.Request, error)

NewRequest creates an HTTP request for a URL on the platform.

func (ManagedPlatform) Validate

func (p ManagedPlatform) Validate() error

Validate confirms required properties are set.

type Platform

type Platform interface {
	Name() string
	CommandFlags() []string
	Validate() error
	NewRequest(method, url string) (*http.Request, error)
}

Platform describes how platforms are defined.

type Service

type Service struct {
	// Name is an ID, used for logging and to generate a unique version to this run.
	Name string

	// The root directory containing the service's source code.
	Dir string

	// The container image name to deploy. If left blank the container will be built
	// and pushed to gcr.io/[ProjectID]/[Name]:[Revision]
	Image string

	// The project to deploy to.
	ProjectID string

	// Allow unauthenticated request.
	AllowUnauthenticated bool

	// The platform to deploy to.
	Platform Platform

	// Additional runtime environment variable overrides for the app.
	Env EnvVars
	// contains filtered or unexported fields
}

Service describes a Cloud Run service

func NewService

func NewService(name, projectID string) *Service

NewService creates a new Service based on the name and projectID provided. It will default to the ManagedPlatform in region us-central1, and build a container image as needed for deployment.

func (*Service) Build

func (s *Service) Build() error

Build builds a container image if one has not already been built. If service.Image is specified and this is directly called, it could overwrite an existing container image. If service.Image is not specified, the service.Deploy() function will call Build().

Example

ExampleService_Build shows how to build once, deploy many.

package main

import (
	"fmt"
	"os"

	"github.com/GoogleCloudPlatform/golang-samples/internal/cloudrunci"
)

func main() {
	projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")
	version := os.Getenv("BUILD_ID")

	myService := cloudrunci.NewService("my-service", projectID)
	myService.Image = fmt.Sprintf("gcr.io/%s/my-service:%s", projectID, version)
	myService.Dir = "example"
	myService.Build()

	myService.Env = map[string]string{
		"CUSTOM_VARIABLE": "42",
	}
	myService.Deploy()

	myService.Env = map[string]string{
		"CUSTOM_VARIABLE": "88",
	}
	myService.Deploy()
}
Output:

func (*Service) Clean

func (s *Service) Clean() error

Clean deletes the created Cloud Run service.

func (*Service) Deploy

func (s *Service) Deploy() error

Deploy deploys the service to Cloud Run. If an image has not been specified or previously built, it will call Build. If the deployment fails, it tries to clean up the failed deployment.

func (*Service) Deployed

func (s *Service) Deployed() bool

Deployed reports whether the service has been deployed.

func (*Service) Host

func (s *Service) Host() (string, error)

Host returns the host:port of the service to facilitate new gRPC connections.

func (*Service) NewRequest

func (s *Service) NewRequest(method, path string) (*http.Request, error)

NewRequest creates a new http.Request for the deployed service.

Example

ExampleService_Request shows how to run a customized HTTP request.

package main

import (
	"fmt"
	"net/http"
	"os"

	"github.com/GoogleCloudPlatform/golang-samples/internal/cloudrunci"
)

func main() {
	projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")

	myService := cloudrunci.NewService("my-service", projectID)
	myService.Dir = "example"
	if err := myService.Deploy(); err != nil {
		fmt.Printf("service.Deploy: %q", err)
		return
	}

	req, err := myService.NewRequest("GET", "/")
	if err != nil {
		fmt.Printf("service.NewRequest: %q", err)
		return
	}
	req.Header.Set("Custom-Header", "42")

	myClient := &http.Client{}
	resp, err := myClient.Do(req)
	if err != nil {
		fmt.Printf("http.Client: %q", err)
		return
	}

	fmt.Println(resp.StatusCode)
}
Output:

func (*Service) ParsedURL

func (s *Service) ParsedURL() (*url.URL, error)

ParsedURL retrieves the parsed URL of the service. This URL is stored on the service struct for repeated retrieval.

func (*Service) Request

func (s *Service) Request(method, path string) (*http.Response, error)

Request issues an HTTP request to the deployed service.

Example

ExampleService_Request shows how to send an HTTP request to a service using defaults.

package main

import (
	"fmt"
	"os"

	"github.com/GoogleCloudPlatform/golang-samples/internal/cloudrunci"
)

func main() {
	projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")

	myService := cloudrunci.NewService("my-service", projectID)
	myService.Dir = "example"
	myService.Deploy()

	resp, err := myService.Request("GET", "/")
	if err != nil {
		fmt.Printf("myService.Get: %q", err)
	}

	fmt.Println(resp.StatusCode)
}
Output:

func (*Service) URL

func (s *Service) URL(p string) (string, error)

URL prepends the deployed service's base URL to the given path. Returns an error if the application has not been deployed.

Jump to

Keyboard shortcuts

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