mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-28 00:49:26 -05:00
bd63aa3c6b
sed -i '1i/*\nCopyright (c) Edgeless Systems GmbH\n\nSPDX-License-Identifier: AGPL-3.0-only\n*/\n' `grep -rL --include='*.go' 'DO NOT EDIT'` gofumpt -w .
286 lines
11 KiB
Go
286 lines
11 KiB
Go
/*
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
package client
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/edgelesssys/constellation/internal/cloud/cloudtypes"
|
|
"github.com/stretchr/testify/assert"
|
|
"google.golang.org/api/googleapi"
|
|
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
func TestCreateInstances(t *testing.T) {
|
|
testInstances := []*computepb.Instance{
|
|
{
|
|
Name: proto.String("instance-name-1"),
|
|
NetworkInterfaces: []*computepb.NetworkInterface{
|
|
{
|
|
AccessConfigs: []*computepb.AccessConfig{
|
|
{NatIP: proto.String("public-ip")},
|
|
},
|
|
NetworkIP: proto.String("private-ip"),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: proto.String("instance-name-2"),
|
|
NetworkInterfaces: []*computepb.NetworkInterface{
|
|
{
|
|
AccessConfigs: []*computepb.AccessConfig{
|
|
{NatIP: proto.String("public-ip")},
|
|
},
|
|
NetworkIP: proto.String("private-ip"),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
testManagedInstances := []*computepb.ManagedInstance{
|
|
{CurrentAction: proto.String(computepb.ManagedInstance_NONE.String())},
|
|
{CurrentAction: proto.String(computepb.ManagedInstance_NONE.String())},
|
|
}
|
|
testInput := CreateInstancesInput{
|
|
CountControlPlanes: 3,
|
|
CountWorkers: 4,
|
|
ImageID: "img",
|
|
InstanceType: "n2d-standard-4",
|
|
KubeEnv: "kube-env",
|
|
}
|
|
someErr := errors.New("failed")
|
|
|
|
testCases := map[string]struct {
|
|
instanceAPI instanceAPI
|
|
operationZoneAPI operationZoneAPI
|
|
operationGlobalAPI operationGlobalAPI
|
|
instanceTemplateAPI instanceTemplateAPI
|
|
instanceGroupManagersAPI instanceGroupManagersAPI
|
|
input CreateInstancesInput
|
|
network string
|
|
wantErr bool
|
|
}{
|
|
"successful create": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{instances: testInstances}},
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{listIterator: &stubManagedInstanceIterator{instances: testManagedInstances}},
|
|
network: "network",
|
|
input: testInput,
|
|
},
|
|
"failed no network": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{instances: testInstances}},
|
|
operationZoneAPI: stubOperationZoneAPI{waitErr: someErr},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{listIterator: &stubManagedInstanceIterator{instances: testManagedInstances}},
|
|
input: testInput,
|
|
wantErr: true,
|
|
},
|
|
"failed wait zonal op": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{instances: testInstances}},
|
|
operationZoneAPI: stubOperationZoneAPI{waitErr: someErr},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{listIterator: &stubManagedInstanceIterator{instances: testManagedInstances}},
|
|
network: "network",
|
|
input: testInput,
|
|
wantErr: true,
|
|
},
|
|
"failed wait global op": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{instances: testInstances}},
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{waitErr: someErr},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{listIterator: &stubManagedInstanceIterator{instances: testManagedInstances}},
|
|
network: "network",
|
|
input: testInput,
|
|
wantErr: true,
|
|
},
|
|
"failed insert template": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{instances: testInstances}},
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{insertErr: someErr},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{listIterator: &stubManagedInstanceIterator{instances: testManagedInstances}},
|
|
input: testInput,
|
|
network: "network",
|
|
wantErr: true,
|
|
},
|
|
"failed insert instanceGroupManager": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{instances: testInstances}},
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{insertErr: someErr},
|
|
network: "network",
|
|
input: testInput,
|
|
wantErr: true,
|
|
},
|
|
"failed instanceGroupManager iterator": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{instances: testInstances}},
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{listIterator: &stubManagedInstanceIterator{nextErr: someErr}},
|
|
network: "network",
|
|
input: testInput,
|
|
wantErr: true,
|
|
},
|
|
"failed instance iterator": {
|
|
instanceAPI: stubInstanceAPI{listIterator: &stubInstanceIterator{nextErr: someErr}},
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{listIterator: &stubManagedInstanceIterator{instances: testManagedInstances}},
|
|
network: "network",
|
|
input: testInput,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
ctx := context.Background()
|
|
client := Client{
|
|
project: "project",
|
|
zone: "zone",
|
|
name: "name",
|
|
uid: "uid",
|
|
network: tc.network,
|
|
subnetwork: "subnetwork",
|
|
secondarySubnetworkRange: "secondary-range",
|
|
instanceAPI: tc.instanceAPI,
|
|
operationZoneAPI: tc.operationZoneAPI,
|
|
operationGlobalAPI: tc.operationGlobalAPI,
|
|
instanceTemplateAPI: tc.instanceTemplateAPI,
|
|
instanceGroupManagersAPI: tc.instanceGroupManagersAPI,
|
|
workers: make(cloudtypes.Instances),
|
|
controlPlanes: make(cloudtypes.Instances),
|
|
}
|
|
|
|
if tc.wantErr {
|
|
assert.Error(client.CreateInstances(ctx, tc.input))
|
|
} else {
|
|
assert.NoError(client.CreateInstances(ctx, tc.input))
|
|
assert.Equal([]string{"public-ip", "public-ip"}, client.workers.PublicIPs())
|
|
assert.Equal([]string{"private-ip", "private-ip"}, client.workers.PrivateIPs())
|
|
assert.Equal([]string{"public-ip", "public-ip"}, client.controlPlanes.PublicIPs())
|
|
assert.Equal([]string{"private-ip", "private-ip"}, client.controlPlanes.PrivateIPs())
|
|
assert.NotNil(client.workerInstanceGroup)
|
|
assert.NotNil(client.controlPlaneInstanceGroup)
|
|
assert.NotNil(client.controlPlaneTemplate)
|
|
assert.NotNil(client.workerTemplate)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTerminateInstances(t *testing.T) {
|
|
someErr := errors.New("failed")
|
|
notFoundErr := &googleapi.Error{Code: http.StatusNotFound}
|
|
|
|
testCases := map[string]struct {
|
|
operationZoneAPI operationZoneAPI
|
|
operationGlobalAPI operationGlobalAPI
|
|
instanceTemplateAPI instanceTemplateAPI
|
|
instanceGroupManagersAPI instanceGroupManagersAPI
|
|
|
|
missingWorkerInstanceGroup bool
|
|
wantErr bool
|
|
}{
|
|
"successful terminate": {
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{},
|
|
},
|
|
"successful terminate with missing worker instance group": {
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{},
|
|
missingWorkerInstanceGroup: true,
|
|
},
|
|
"instances not found": {
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{deleteErr: notFoundErr},
|
|
},
|
|
"templates not found": {
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{deleteErr: notFoundErr},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{},
|
|
},
|
|
"fail delete instanceGroupManager": {
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{deleteErr: someErr},
|
|
wantErr: true,
|
|
},
|
|
"fail delete instanceTemplate": {
|
|
operationZoneAPI: stubOperationZoneAPI{},
|
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
|
instanceTemplateAPI: stubInstanceTemplateAPI{deleteErr: someErr},
|
|
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
ctx := context.Background()
|
|
client := Client{
|
|
project: "project",
|
|
zone: "zone",
|
|
name: "name",
|
|
uid: "uid",
|
|
operationZoneAPI: tc.operationZoneAPI,
|
|
operationGlobalAPI: tc.operationGlobalAPI,
|
|
instanceTemplateAPI: tc.instanceTemplateAPI,
|
|
instanceGroupManagersAPI: tc.instanceGroupManagersAPI,
|
|
workers: cloudtypes.Instances{"worker-id-1": cloudtypes.Instance{}, "worker-id-2": cloudtypes.Instance{}},
|
|
controlPlanes: cloudtypes.Instances{"controlplane-id-1": cloudtypes.Instance{}},
|
|
firewalls: []string{"firewall-1", "firewall-2"},
|
|
network: "network-id-1",
|
|
workerInstanceGroup: "workerInstanceGroup-id-1",
|
|
controlPlaneInstanceGroup: "controlplaneInstanceGroup-id-1",
|
|
workerTemplate: "template-id-1",
|
|
controlPlaneTemplate: "template-id-1",
|
|
}
|
|
if tc.missingWorkerInstanceGroup {
|
|
client.workerInstanceGroup = ""
|
|
client.workers = cloudtypes.Instances{}
|
|
}
|
|
|
|
if tc.wantErr {
|
|
assert.Error(client.TerminateInstances(ctx))
|
|
} else {
|
|
assert.NoError(client.TerminateInstances(ctx))
|
|
assert.Nil(client.workers.PublicIPs())
|
|
assert.Nil(client.workers.PrivateIPs())
|
|
assert.Nil(client.controlPlanes.PublicIPs())
|
|
assert.Nil(client.controlPlanes.PrivateIPs())
|
|
assert.Empty(client.workerInstanceGroup)
|
|
assert.Empty(client.controlPlaneInstanceGroup)
|
|
assert.Empty(client.controlPlaneTemplate)
|
|
assert.Empty(client.workerTemplate)
|
|
}
|
|
})
|
|
}
|
|
}
|