testing setup (#639)

This commit is contained in:
chaodaiG 2019-09-06 14:08:07 -07:00 committed by Knative Prow Robot
parent 014d54e62f
commit c92533920c
2 changed files with 283 additions and 34 deletions

View File

@ -96,8 +96,7 @@ func (gsc *GKESDKClient) get(project, location, cluster string) (*container.Clus
// nodeType: default to n1-standard-4 if not provided
// region: default to regional cluster if not provided, and use default backup regions
// zone: default is none, must be provided together with region
func (gs *GKEClient) Setup(numNodes *int64, nodeType *string, region *string, zone *string, project *string) (ClusterOperations, error) {
var err error
func (gs *GKEClient) Setup(numNodes *int64, nodeType *string, region *string, zone *string, project *string) ClusterOperations {
gc := &GKECluster{
Request: &GKERequest{
NumNodes: DefaultGKENumNodes,
@ -107,60 +106,70 @@ func (gs *GKEClient) Setup(numNodes *int64, nodeType *string, region *string, zo
BackupRegions: DefaultGKEBackupRegions},
}
ctx := context.Background()
if nil != project { // use provided project and create cluster
gc.Project = project
gc.NeedCleanup = true
}
if nil != numNodes {
gc.Request.NumNodes = *numNodes
}
if nil != nodeType {
gc.Request.NodeType = *nodeType
}
if nil != region {
gc.Request.Region = *region
}
if "" != common.GetOSEnv(regionEnv) {
gc.Request.Region = common.GetOSEnv(regionEnv)
}
if "" != common.GetOSEnv(backupRegionEnv) {
gc.Request.BackupRegions = strings.Split(common.GetOSEnv(backupRegionEnv), " ")
}
if nil != zone {
gc.Request.Zone = *zone
gc.Request.BackupRegions = make([]string, 0)
}
ctx := context.Background()
c, err := google.DefaultClient(ctx, container.CloudPlatformScope)
if nil != err {
return nil, fmt.Errorf("failed create google client: '%v'", err)
log.Fatalf("failed create google client: '%v'", err)
}
containerService, err := container.New(c)
if nil != err {
return nil, fmt.Errorf("failed create container service: '%v'", err)
log.Fatalf("failed create container service: '%v'", err)
}
gc.operations = &GKESDKClient{containerService}
if nil != project { // use provided project and create cluster
gc.Project = project
gc.NeedCleanup = true
} else if err := gc.checkEnvironment(); nil != err {
return nil, fmt.Errorf("failed checking existing cluster: '%v'", err)
} else if nil != gc.Cluster { // return if Cluster was already set by kubeconfig
return gc, nil
return gc
}
// Initialize sets up GKE SDK client, checks environment for cluster and
// projects to decide whether use existing cluster/project or creating new ones.
func (gc *GKECluster) Initialize() error {
if nil == gc.Project {
if err := gc.checkEnvironment(); nil != err {
return fmt.Errorf("failed checking existing cluster: '%v'", err)
} else if nil != gc.Cluster { // return if Cluster was already set by kubeconfig
return nil
}
}
if nil == gc.Cluster {
if common.IsProw() {
project, err := boskos.AcquireGKEProject(nil)
if nil != err {
return nil, fmt.Errorf("failed acquire boskos project: '%v'", err)
return fmt.Errorf("failed acquire boskos project: '%v'", err)
}
gc.Project = &project.Name
}
if nil != numNodes {
gc.Request.NumNodes = *numNodes
}
if nil != nodeType {
gc.Request.NodeType = *nodeType
}
if nil != region {
gc.Request.Region = *region
}
if "" != common.GetOSEnv(regionEnv) {
gc.Request.Region = common.GetOSEnv(regionEnv)
}
if "" != common.GetOSEnv(backupRegionEnv) {
gc.Request.BackupRegions = strings.Split(common.GetOSEnv(backupRegionEnv), " ")
}
if nil != zone {
gc.Request.Zone = *zone
gc.Request.BackupRegions = make([]string, 0)
}
}
if nil == gc.Project || "" == *gc.Project {
return nil, fmt.Errorf("gcp project must be set")
return fmt.Errorf("gcp project must be set")
}
log.Printf("use project '%s' for running test", *gc.Project)
return gc, nil
return nil
}
// Provider returns gke

View File

@ -18,6 +18,8 @@ package clustermanager
import (
"fmt"
"io/ioutil"
"os"
"reflect"
"strings"
"testing"
@ -90,6 +92,244 @@ func (fgsc *FakeGKESDKClient) get(project, location, cluster string) (*container
return nil, fmt.Errorf("cluster not found")
}
func TestSetup(t *testing.T) {
numNodesOverride := int64(2)
nodeTypeOverride := "foonode"
regionOverride := "fooregion"
zoneOverride := "foozone"
datas := []struct {
numNodes *int64
nodeType, region, zone, project *string
regionEnv, backupRegionEnv string
expClusterOperations *GKECluster
}{
{
// Defaults
nil, nil, nil, nil, nil, "", "",
&GKECluster{
Request: &GKERequest{
NumNodes: 1,
NodeType: "n1-standard-4",
Region: "us-central1",
Zone: "",
BackupRegions: []string{"us-west1", "us-east1"},
},
},
}, {
// Project provided
nil, nil, nil, nil, &fakeProj, "", "",
&GKECluster{
Request: &GKERequest{
NumNodes: 1,
NodeType: "n1-standard-4",
Region: "us-central1",
Zone: "",
BackupRegions: []string{"us-west1", "us-east1"},
},
Project: &fakeProj,
NeedCleanup: true,
},
}, {
// Override other parts
&numNodesOverride, &nodeTypeOverride, &regionOverride, &zoneOverride, nil, "", "",
&GKECluster{
Request: &GKERequest{
NumNodes: 2,
NodeType: "foonode",
Region: "fooregion",
Zone: "foozone",
BackupRegions: []string{},
},
},
}, {
// Override other parts but not zone
&numNodesOverride, &nodeTypeOverride, &regionOverride, nil, nil, "", "",
&GKECluster{
Request: &GKERequest{
NumNodes: 2,
NodeType: "foonode",
Region: "fooregion",
Zone: "",
BackupRegions: []string{"us-west1", "us-east1"},
},
},
}, {
// Set env Region
nil, nil, nil, nil, nil, "customregion", "",
&GKECluster{
Request: &GKERequest{
NumNodes: 1,
NodeType: "n1-standard-4",
Region: "customregion",
Zone: "",
BackupRegions: []string{"us-west1", "us-east1"},
},
},
}, {
// Set env backupzone
nil, nil, nil, nil, nil, "", "backupregion1 backupregion2",
&GKECluster{
Request: &GKERequest{
NumNodes: 1,
NodeType: "n1-standard-4",
Region: "us-central1",
Zone: "",
BackupRegions: []string{"backupregion1", "backupregion2"},
},
},
},
}
// mock GetOSEnv for testing
oldEnvFunc := common.GetOSEnv
oldExecFunc := common.StandardExec
oldDefaultCred := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
tf, _ := ioutil.TempFile("", "foo")
tf.WriteString(`{"type": "service_account"}`)
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", tf.Name())
defer func() {
// restore
common.GetOSEnv = oldEnvFunc
common.StandardExec = oldExecFunc
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", oldDefaultCred)
os.Remove(tf.Name())
}()
// mock as kubectl not set and gcloud set as "b", so check environment
// return project as "b"
common.StandardExec = func(name string, args ...string) ([]byte, error) {
var out []byte
var err error
switch name {
case "gcloud":
out = []byte("b")
err = nil
case "kubectl":
out = []byte("")
err = fmt.Errorf("kubectl not set")
default:
out, err = oldExecFunc(name)
}
return out, err
}
for _, data := range datas {
common.GetOSEnv = func(s string) string {
switch s {
case "E2E_CLUSTER_REGION":
return data.regionEnv
case "E2E_CLUSTER_BACKUP_REGIONS":
return data.backupRegionEnv
}
return oldEnvFunc(s)
}
c := GKEClient{}
co := c.Setup(data.numNodes, data.nodeType, data.region, data.zone, data.project)
errPrefix := fmt.Sprintf("testing setup with:\n\tnumNodes: %v\n\tnodeType: %v\n\tregion: %v\n\tone: %v\n\tproject: %v\n\tregionEnv: %v\n\tbackupRegionEnv: %v",
data.numNodes, data.nodeType, data.region, data.zone, data.project, data.regionEnv, data.backupRegionEnv)
gotCo := co.(*GKECluster)
// mock for easier comparison
gotCo.operations = nil
if !reflect.DeepEqual(co, data.expClusterOperations) {
t.Fatalf("%s\nwant GKECluster:\n'%v'\ngot GKECluster:\n'%v'", errPrefix, data.expClusterOperations, co)
}
}
}
func TestInitialize(t *testing.T) {
customProj := "customproj"
datas := []struct {
project *string
clusterExist bool
gcloudSet bool
expProj *string
expCluster *container.Cluster
expErr error
}{
{
// User defines project
&fakeProj, false, false, &fakeProj, nil, nil,
}, {
// kubeconfig set
nil, true, false, &fakeProj, &container.Cluster{
Name: "d",
Location: "c",
Status: "RUNNING",
}, nil,
}, {
// kubeconfig not set and gcloud not set
nil, false, true, &customProj, nil, nil,
}, {
// kubeconfig not set and gcloud set
nil, false, false, nil, nil, fmt.Errorf("gcp project must be set"),
},
}
oldEnvFunc := common.GetOSEnv
oldExecFunc := common.StandardExec
defer func() {
// restore
common.GetOSEnv = oldEnvFunc
common.StandardExec = oldExecFunc
}()
// Mock to make IsProw() always return false, otherwise it will actually
// acquire a boskos project
common.GetOSEnv = func(s string) string {
switch s {
case "PROW_JOB_ID":
return ""
}
return oldEnvFunc(s)
}
for _, data := range datas {
fgc := setupFakeGKECluster()
if nil != data.project {
fgc.Project = data.project
}
if data.clusterExist {
parts := strings.Split("gke_b_c_d", "_")
fgc.operations.create(parts[1], parts[2], &container.CreateClusterRequest{
Cluster: &container.Cluster{
Name: parts[3],
},
ProjectId: parts[1],
})
}
// mock for testing
common.StandardExec = func(name string, args ...string) ([]byte, error) {
var out []byte
var err error
switch name {
case "gcloud":
out = []byte("")
err = nil
if data.gcloudSet {
out = []byte(customProj)
err = nil
}
case "kubectl":
out = []byte("")
err = fmt.Errorf("kubectl not set")
if data.clusterExist {
out = []byte("gke_b_c_d")
err = nil
}
default:
out, err = oldExecFunc(name, args...)
}
return out, err
}
err := fgc.Initialize()
if !reflect.DeepEqual(err, data.expErr) || !reflect.DeepEqual(fgc.Project, data.expProj) || !reflect.DeepEqual(fgc.Cluster, data.expCluster) {
t.Errorf("test initialize with:\n\tpreset project: '%v'\n\tkubeconfig set: '%v'\n\tgcloud set: '%v'\n"+
"want:\n\tproject - '%v'\n\tcluster - '%v'\n\terr - '%v'\ngot:\n\tproject - '%v'\n\tcluster - '%v'\n\terr - '%v'",
data.project, data.clusterExist, data.gcloudSet, data.expProj, data.expCluster, data.expErr, fgc.Project, fgc.Cluster, err)
}
}
}
func TestGKECheckEnvironment(t *testing.T) {
datas := []struct {
kubectlOut string