mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-07-25 00:05:17 -04:00
monorepo
Co-authored-by: Malte Poll <mp@edgeless.systems> Co-authored-by: katexochen <katexochen@users.noreply.github.com> Co-authored-by: Daniel Weiße <dw@edgeless.systems> Co-authored-by: Thomas Tendyck <tt@edgeless.systems> Co-authored-by: Benedict Schlueter <bs@edgeless.systems> Co-authored-by: leongross <leon.gross@rub.de> Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com>
This commit is contained in:
commit
2d8fcd9bf4
362 changed files with 50980 additions and 0 deletions
755
coordinator/cloudprovider/gcp/client_test.go
Normal file
755
coordinator/cloudprovider/gcp/client_test.go
Normal file
|
@ -0,0 +1,755 @@
|
|||
package gcp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
compute "cloud.google.com/go/compute/apiv1"
|
||||
"github.com/edgelesssys/constellation/coordinator/core"
|
||||
"github.com/edgelesssys/constellation/coordinator/role"
|
||||
gax "github.com/googleapis/gax-go/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
"google.golang.org/api/iterator"
|
||||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
goleak.VerifyTestMain(m,
|
||||
// https://github.com/census-instrumentation/opencensus-go/issues/1262
|
||||
goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"),
|
||||
// https://github.com/kubernetes/klog/issues/282, https://github.com/kubernetes/klog/issues/188
|
||||
goleak.IgnoreTopFunction("k8s.io/klog/v2.(*loggingT).flushDaemon"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestRetrieveInstances(t *testing.T) {
|
||||
uid := "1234"
|
||||
someErr := errors.New("failed")
|
||||
newTestIter := func() *stubInstanceIterator {
|
||||
return &stubInstanceIterator{
|
||||
instances: []*computepb.Instance{
|
||||
{
|
||||
Name: proto.String("someInstance"),
|
||||
Metadata: &computepb.Metadata{
|
||||
Items: []*computepb.Items{
|
||||
{
|
||||
Key: proto.String("ssh-keys"),
|
||||
Value: proto.String("bob:ssh-rsa bobskey"),
|
||||
},
|
||||
{
|
||||
Key: proto.String("key-2"),
|
||||
Value: proto.String("value-2"),
|
||||
},
|
||||
{
|
||||
Key: proto.String(core.ConstellationUIDMetadataKey),
|
||||
Value: proto.String(uid),
|
||||
},
|
||||
{
|
||||
Key: proto.String(core.RoleMetadataKey),
|
||||
Value: proto.String(role.Coordinator.String()),
|
||||
},
|
||||
},
|
||||
},
|
||||
NetworkInterfaces: []*computepb.NetworkInterface{
|
||||
{NetworkIP: proto.String("192.0.2.0")},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubInstancesClient
|
||||
metadata stubMetadataClient
|
||||
instanceIter *stubInstanceIterator
|
||||
instanceIterMutator func(*stubInstanceIterator)
|
||||
expectedInstances []core.Instance
|
||||
expectErr bool
|
||||
}{
|
||||
"retrieve works": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceValue: uid},
|
||||
instanceIter: newTestIter(),
|
||||
expectedInstances: []core.Instance{
|
||||
{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
Role: role.Coordinator,
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"instance name is null": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceValue: uid},
|
||||
instanceIter: newTestIter(),
|
||||
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].Name = nil },
|
||||
expectErr: true,
|
||||
},
|
||||
"no instance with network ip": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceValue: uid},
|
||||
instanceIter: newTestIter(),
|
||||
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].NetworkInterfaces = nil },
|
||||
expectedInstances: []core.Instance{
|
||||
{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
Role: role.Coordinator,
|
||||
IPs: []string{},
|
||||
SSHKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"network ip is nil": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceValue: uid},
|
||||
instanceIter: newTestIter(),
|
||||
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].NetworkInterfaces[0].NetworkIP = nil },
|
||||
expectedInstances: []core.Instance{
|
||||
{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
Role: role.Coordinator,
|
||||
IPs: []string{},
|
||||
SSHKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"constellation id is not set": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceValue: uid},
|
||||
instanceIter: newTestIter(),
|
||||
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].Metadata.Items[2].Key = proto.String("") },
|
||||
expectedInstances: []core.Instance{},
|
||||
},
|
||||
"constellation retrieval fails": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceErr: someErr},
|
||||
instanceIter: newTestIter(),
|
||||
expectErr: true,
|
||||
},
|
||||
"role is not set": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceValue: uid},
|
||||
instanceIter: newTestIter(),
|
||||
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].Metadata.Items[3].Key = proto.String("") },
|
||||
expectedInstances: []core.Instance{
|
||||
{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
Role: role.Unknown,
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"instance iterator Next() errors": {
|
||||
client: stubInstancesClient{},
|
||||
metadata: stubMetadataClient{InstanceValue: uid},
|
||||
instanceIter: &stubInstanceIterator{nextErr: someErr},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
if tc.instanceIterMutator != nil {
|
||||
tc.instanceIterMutator(tc.instanceIter)
|
||||
}
|
||||
tc.client.ListInstanceIterator = tc.instanceIter
|
||||
client := Client{
|
||||
instanceAPI: tc.client,
|
||||
metadataAPI: tc.metadata,
|
||||
}
|
||||
|
||||
instances, err := client.RetrieveInstances(context.Background(), "someProject", "someZone")
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.expectedInstances, instances)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieveInstance(t *testing.T) {
|
||||
newTestInstance := func() *computepb.Instance {
|
||||
return &computepb.Instance{
|
||||
Name: proto.String("someInstance"),
|
||||
Metadata: &computepb.Metadata{
|
||||
Items: []*computepb.Items{
|
||||
{
|
||||
Key: proto.String("key-1"),
|
||||
Value: proto.String("value-1"),
|
||||
},
|
||||
{
|
||||
Key: proto.String("key-2"),
|
||||
Value: proto.String("value-2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
NetworkInterfaces: []*computepb.NetworkInterface{
|
||||
{NetworkIP: proto.String("192.0.2.0")},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubInstancesClient
|
||||
clientInstance *computepb.Instance
|
||||
clientInstanceMutator func(*computepb.Instance)
|
||||
expectedInstance core.Instance
|
||||
expectErr bool
|
||||
}{
|
||||
"retrieve works": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"retrieve with SSH key works": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
clientInstanceMutator: func(i *computepb.Instance) {
|
||||
i.Metadata.Items[0].Key = proto.String("ssh-keys")
|
||||
i.Metadata.Items[0].Value = proto.String("bob:ssh-rsa bobskey")
|
||||
},
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}},
|
||||
},
|
||||
},
|
||||
"retrieve with Role works": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
clientInstanceMutator: func(i *computepb.Instance) {
|
||||
i.Metadata.Items[0].Key = proto.String(core.RoleMetadataKey)
|
||||
i.Metadata.Items[0].Value = proto.String(role.Coordinator.String())
|
||||
},
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
Role: role.Coordinator,
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"retrieve fails": {
|
||||
client: stubInstancesClient{
|
||||
GetErr: errors.New("retrieve error"),
|
||||
},
|
||||
clientInstance: nil,
|
||||
expectErr: true,
|
||||
},
|
||||
"metadata item is null": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
clientInstanceMutator: func(i *computepb.Instance) { i.Metadata.Items[0] = nil },
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"metadata key is null": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
clientInstanceMutator: func(i *computepb.Instance) { i.Metadata.Items[0].Key = nil },
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"metadata value is null": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
clientInstanceMutator: func(i *computepb.Instance) { i.Metadata.Items[0].Value = nil },
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
IPs: []string{"192.0.2.0"},
|
||||
SSHKeys: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"instance without network ip": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
clientInstanceMutator: func(i *computepb.Instance) { i.NetworkInterfaces[0] = nil },
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
IPs: []string{},
|
||||
SSHKeys: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"network ip is nil": {
|
||||
client: stubInstancesClient{},
|
||||
clientInstance: newTestInstance(),
|
||||
clientInstanceMutator: func(i *computepb.Instance) { i.NetworkInterfaces[0].NetworkIP = nil },
|
||||
expectedInstance: core.Instance{
|
||||
Name: "someInstance",
|
||||
ProviderID: "gce://someProject/someZone/someInstance",
|
||||
IPs: []string{},
|
||||
SSHKeys: map[string][]string{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
if tc.clientInstanceMutator != nil {
|
||||
tc.clientInstanceMutator(tc.clientInstance)
|
||||
}
|
||||
tc.client.GetInstance = tc.clientInstance
|
||||
client := Client{instanceAPI: tc.client}
|
||||
|
||||
instance, err := client.RetrieveInstance(context.Background(), "someProject", "someZone", "someInstance")
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.expectedInstance, instance)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieveProjectID(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubMetadataClient
|
||||
expectedValue string
|
||||
expectErr bool
|
||||
}{
|
||||
"retrieve works": {
|
||||
client: stubMetadataClient{ProjectIDValue: "someProjectID"},
|
||||
expectedValue: "someProjectID",
|
||||
},
|
||||
"retrieve fails": {
|
||||
client: stubMetadataClient{ProjectIDErr: someErr},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
client := Client{metadataAPI: tc.client}
|
||||
value, err := client.RetrieveProjectID()
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.expectedValue, value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieveZone(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubMetadataClient
|
||||
expectedValue string
|
||||
expectErr bool
|
||||
}{
|
||||
"retrieve works": {
|
||||
client: stubMetadataClient{ZoneValue: "someZone"},
|
||||
expectedValue: "someZone",
|
||||
},
|
||||
"retrieve fails": {
|
||||
client: stubMetadataClient{ZoneErr: someErr},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
client := Client{metadataAPI: tc.client}
|
||||
value, err := client.RetrieveZone()
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.expectedValue, value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieveInstanceName(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubMetadataClient
|
||||
expectedValue string
|
||||
expectErr bool
|
||||
}{
|
||||
"retrieve works": {
|
||||
client: stubMetadataClient{InstanceNameValue: "someInstanceName"},
|
||||
expectedValue: "someInstanceName",
|
||||
},
|
||||
"retrieve fails": {
|
||||
client: stubMetadataClient{InstanceNameErr: someErr},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
client := Client{metadataAPI: tc.client}
|
||||
value, err := client.RetrieveInstanceName()
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.expectedValue, value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieveInstanceMetadata(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
attr := "someAttribute"
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubMetadataClient
|
||||
attr string
|
||||
expectedValue string
|
||||
expectErr bool
|
||||
}{
|
||||
"retrieve works": {
|
||||
client: stubMetadataClient{
|
||||
InstanceValue: "someValue",
|
||||
InstanceErr: nil,
|
||||
},
|
||||
expectedValue: "someValue",
|
||||
},
|
||||
"retrieve fails": {
|
||||
client: stubMetadataClient{
|
||||
InstanceValue: "",
|
||||
InstanceErr: someErr,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
client := Client{metadataAPI: tc.client}
|
||||
value, err := client.RetrieveInstanceMetadata(attr)
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.expectedValue, value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetInstanceMetadata(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubInstancesClient
|
||||
expectErr bool
|
||||
}{
|
||||
"set works": {
|
||||
client: stubInstancesClient{
|
||||
GetInstance: &computepb.Instance{
|
||||
Metadata: &computepb.Metadata{
|
||||
Fingerprint: proto.String("someFingerprint"),
|
||||
Kind: proto.String("compute#metadata"),
|
||||
Items: []*computepb.Items{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"retrieve fails": {
|
||||
client: stubInstancesClient{
|
||||
GetErr: someErr,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
"retrieve returns nil": {
|
||||
expectErr: true,
|
||||
},
|
||||
"setting fails": {
|
||||
client: stubInstancesClient{
|
||||
GetInstance: &computepb.Instance{
|
||||
Metadata: &computepb.Metadata{
|
||||
Fingerprint: proto.String("someFingerprint"),
|
||||
Kind: proto.String("compute#metadata"),
|
||||
Items: []*computepb.Items{},
|
||||
},
|
||||
},
|
||||
SetMetadataErr: someErr,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
client := Client{instanceAPI: tc.client}
|
||||
err := client.SetInstanceMetadata(context.Background(), "project", "zone", "instanceName", "key", "value")
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsetInstanceMetadata(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
testCases := map[string]struct {
|
||||
client stubInstancesClient
|
||||
expectErr bool
|
||||
}{
|
||||
"unset works": {
|
||||
client: stubInstancesClient{
|
||||
GetInstance: &computepb.Instance{
|
||||
Metadata: &computepb.Metadata{
|
||||
Fingerprint: proto.String("someFingerprint"),
|
||||
Kind: proto.String("compute#metadata"),
|
||||
Items: []*computepb.Items{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"unset with existing key works": {
|
||||
client: stubInstancesClient{
|
||||
GetInstance: &computepb.Instance{
|
||||
Metadata: &computepb.Metadata{
|
||||
Fingerprint: proto.String("someFingerprint"),
|
||||
Kind: proto.String("compute#metadata"),
|
||||
Items: []*computepb.Items{
|
||||
{
|
||||
Key: proto.String("key"),
|
||||
Value: proto.String("value"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"retrieve fails": {
|
||||
client: stubInstancesClient{GetErr: someErr},
|
||||
expectErr: true,
|
||||
},
|
||||
"retrieve returns nil": {
|
||||
expectErr: true,
|
||||
},
|
||||
"setting fails": {
|
||||
client: stubInstancesClient{
|
||||
GetInstance: &computepb.Instance{
|
||||
Metadata: &computepb.Metadata{
|
||||
Fingerprint: proto.String("someFingerprint"),
|
||||
Kind: proto.String("compute#metadata"),
|
||||
Items: []*computepb.Items{},
|
||||
},
|
||||
},
|
||||
SetMetadataErr: someErr,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
client := Client{instanceAPI: tc.client}
|
||||
err := client.UnsetInstanceMetadata(context.Background(), "project", "zone", "instanceName", "key")
|
||||
|
||||
if tc.expectErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
client := Client{instanceAPI: stubInstancesClient{}}
|
||||
assert.NoError(client.Close())
|
||||
|
||||
client = Client{instanceAPI: stubInstancesClient{CloseErr: someErr}}
|
||||
assert.Error(client.Close())
|
||||
}
|
||||
|
||||
func TestFetchSSHKeys(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
metadata map[string]string
|
||||
expectedKeys map[string][]string
|
||||
}{
|
||||
"fetch works": {
|
||||
metadata: map[string]string{"ssh-keys": "bob:ssh-rsa bobskey"},
|
||||
expectedKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}},
|
||||
},
|
||||
"google ssh key metadata is ignored": {
|
||||
metadata: map[string]string{"ssh-keys": "bob:ssh-rsa bobskey google-ssh {\"userName\":\"bob\",\"expireOn\":\"2021-06-14T16:59:03+0000\"}"},
|
||||
expectedKeys: map[string][]string{"bob": {"ssh-rsa bobskey"}},
|
||||
},
|
||||
"ssh key format error is ignored": {
|
||||
metadata: map[string]string{"ssh-keys": "incorrect-format"},
|
||||
expectedKeys: map[string][]string{},
|
||||
},
|
||||
"ssh key format space error is ignored": {
|
||||
metadata: map[string]string{"ssh-keys": "user:incorrect-key-format"},
|
||||
expectedKeys: map[string][]string{},
|
||||
},
|
||||
"metadata field empty": {
|
||||
metadata: map[string]string{"ssh-keys": ""},
|
||||
expectedKeys: map[string][]string{},
|
||||
},
|
||||
"metadata field missing": {
|
||||
metadata: map[string]string{},
|
||||
expectedKeys: map[string][]string{},
|
||||
},
|
||||
"multiple keys": {
|
||||
metadata: map[string]string{"ssh-keys": "bob:ssh-rsa bobskey\nalice:ssh-rsa alicekey"},
|
||||
expectedKeys: map[string][]string{
|
||||
"bob": {"ssh-rsa bobskey"},
|
||||
"alice": {"ssh-rsa alicekey"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
keys := extractSSHKeys(tc.metadata)
|
||||
assert.Equal(tc.expectedKeys, keys)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type stubInstanceIterator struct {
|
||||
instances []*computepb.Instance
|
||||
nextErr error
|
||||
|
||||
internalCounter int
|
||||
}
|
||||
|
||||
func (i *stubInstanceIterator) Next() (*computepb.Instance, error) {
|
||||
if i.nextErr != nil {
|
||||
return nil, i.nextErr
|
||||
}
|
||||
if i.internalCounter >= len(i.instances) {
|
||||
i.internalCounter = 0
|
||||
return nil, iterator.Done
|
||||
}
|
||||
resp := i.instances[i.internalCounter]
|
||||
i.internalCounter++
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
type stubInstancesClient struct {
|
||||
GetInstance *computepb.Instance
|
||||
GetErr error
|
||||
ListInstanceIterator InstanceIterator
|
||||
SetMetadataOperation *compute.Operation
|
||||
SetMetadataErr error
|
||||
CloseErr error
|
||||
}
|
||||
|
||||
func (s stubInstancesClient) Get(ctx context.Context, req *computepb.GetInstanceRequest, opts ...gax.CallOption) (*computepb.Instance, error) {
|
||||
return s.GetInstance, s.GetErr
|
||||
}
|
||||
|
||||
func (s stubInstancesClient) List(ctx context.Context, req *computepb.ListInstancesRequest, opts ...gax.CallOption) InstanceIterator {
|
||||
return s.ListInstanceIterator
|
||||
}
|
||||
|
||||
func (s stubInstancesClient) SetMetadata(ctx context.Context, req *computepb.SetMetadataInstanceRequest, opts ...gax.CallOption) (*compute.Operation, error) {
|
||||
return s.SetMetadataOperation, s.SetMetadataErr
|
||||
}
|
||||
|
||||
func (s stubInstancesClient) Close() error {
|
||||
return s.CloseErr
|
||||
}
|
||||
|
||||
type stubMetadataClient struct {
|
||||
InstanceValue string
|
||||
InstanceErr error
|
||||
ProjectIDValue string
|
||||
ProjectIDErr error
|
||||
ZoneValue string
|
||||
ZoneErr error
|
||||
InstanceNameValue string
|
||||
InstanceNameErr error
|
||||
}
|
||||
|
||||
func (s stubMetadataClient) InstanceAttributeValue(attr string) (string, error) {
|
||||
return s.InstanceValue, s.InstanceErr
|
||||
}
|
||||
|
||||
func (s stubMetadataClient) ProjectID() (string, error) {
|
||||
return s.ProjectIDValue, s.ProjectIDErr
|
||||
}
|
||||
|
||||
func (s stubMetadataClient) Zone() (string, error) {
|
||||
return s.ZoneValue, s.ZoneErr
|
||||
}
|
||||
|
||||
func (s stubMetadataClient) InstanceName() (string, error) {
|
||||
return s.InstanceNameValue, s.InstanceNameErr
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue