mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-14 10:24:24 -05:00
266 lines
7.8 KiB
Go
266 lines
7.8 KiB
Go
|
/*
|
||
|
Copyright (c) Edgeless Systems GmbH
|
||
|
|
||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||
|
*/
|
||
|
|
||
|
package sgreconciler
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"sync"
|
||
|
"testing"
|
||
|
|
||
|
mainconstants "github.com/edgelesssys/constellation/v2/internal/constants"
|
||
|
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"
|
||
|
cspapi "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/internal/cloud/api"
|
||
|
"github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/internal/constants"
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
|
||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||
|
"k8s.io/apimachinery/pkg/types"
|
||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||
|
)
|
||
|
|
||
|
func TestCreateScalingGroupIfNotExists(t *testing.T) {
|
||
|
testCases := map[string]struct {
|
||
|
createErr error
|
||
|
wantScalingGroup *updatev1alpha1.ScalingGroup
|
||
|
wantErr bool
|
||
|
}{
|
||
|
"create works": {
|
||
|
wantScalingGroup: &updatev1alpha1.ScalingGroup{
|
||
|
TypeMeta: metav1.TypeMeta{APIVersion: "update.edgeless.systems/v1alpha1", Kind: "ScalingGroup"},
|
||
|
ObjectMeta: metav1.ObjectMeta{
|
||
|
Name: "resource-name",
|
||
|
},
|
||
|
Spec: updatev1alpha1.ScalingGroupSpec{
|
||
|
NodeVersion: mainconstants.NodeVersionResourceName,
|
||
|
GroupID: "group-id",
|
||
|
AutoscalerGroupName: "autoscaling-group-name",
|
||
|
NodeGroupName: "node-group-name",
|
||
|
Min: 1,
|
||
|
Max: 10,
|
||
|
Role: updatev1alpha1.WorkerRole,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"create fails": {
|
||
|
createErr: errors.New("create failed"),
|
||
|
wantErr: true,
|
||
|
},
|
||
|
"scaling group exists": {
|
||
|
createErr: k8sErrors.NewAlreadyExists(schema.GroupResource{}, constants.AutoscalingStrategyResourceName),
|
||
|
wantScalingGroup: &updatev1alpha1.ScalingGroup{
|
||
|
TypeMeta: metav1.TypeMeta{APIVersion: "update.edgeless.systems/v1alpha1", Kind: "ScalingGroup"},
|
||
|
ObjectMeta: metav1.ObjectMeta{
|
||
|
Name: "resource-name",
|
||
|
},
|
||
|
Spec: updatev1alpha1.ScalingGroupSpec{
|
||
|
NodeVersion: mainconstants.NodeVersionResourceName,
|
||
|
GroupID: "group-id",
|
||
|
AutoscalerGroupName: "autoscaling-group-name",
|
||
|
NodeGroupName: "node-group-name",
|
||
|
Min: 1,
|
||
|
Max: 10,
|
||
|
Role: updatev1alpha1.WorkerRole,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for name, tc := range testCases {
|
||
|
t.Run(name, func(t *testing.T) {
|
||
|
assert := assert.New(t)
|
||
|
require := require.New(t)
|
||
|
|
||
|
k8sClient := &fakeK8sClient{createErr: tc.createErr}
|
||
|
newScalingGroupConfig := newScalingGroupConfig{
|
||
|
k8sClient: k8sClient,
|
||
|
resourceName: "resource-name",
|
||
|
groupID: "group-id",
|
||
|
nodeGroupName: "node-group-name",
|
||
|
autoscalingGroupName: "autoscaling-group-name",
|
||
|
role: updatev1alpha1.WorkerRole,
|
||
|
}
|
||
|
err := createScalingGroupIfNotExists(context.Background(), newScalingGroupConfig)
|
||
|
if tc.wantErr {
|
||
|
assert.Error(err)
|
||
|
return
|
||
|
}
|
||
|
require.NoError(err)
|
||
|
assert.Len(k8sClient.createdObjects, 1)
|
||
|
assert.Equal(tc.wantScalingGroup, k8sClient.createdObjects[0])
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestPatchNodeGroupName(t *testing.T) {
|
||
|
testCases := map[string]struct {
|
||
|
getRes client.Object
|
||
|
getErr error
|
||
|
updateErr error
|
||
|
wantExists bool
|
||
|
wantErr bool
|
||
|
}{
|
||
|
"patching works": {
|
||
|
getRes: &updatev1alpha1.ScalingGroup{
|
||
|
TypeMeta: metav1.TypeMeta{APIVersion: "update.edgeless.systems/v1alpha1", Kind: "ScalingGroup"},
|
||
|
ObjectMeta: metav1.ObjectMeta{
|
||
|
Name: "resource-name",
|
||
|
},
|
||
|
Spec: updatev1alpha1.ScalingGroupSpec{
|
||
|
NodeVersion: mainconstants.NodeVersionResourceName,
|
||
|
GroupID: "group-id",
|
||
|
AutoscalerGroupName: "autoscaling-group-name",
|
||
|
Autoscaling: true,
|
||
|
Min: 1,
|
||
|
Max: 10,
|
||
|
Role: updatev1alpha1.ControlPlaneRole,
|
||
|
},
|
||
|
},
|
||
|
wantExists: true,
|
||
|
},
|
||
|
"name already set": {
|
||
|
getRes: &updatev1alpha1.ScalingGroup{
|
||
|
TypeMeta: metav1.TypeMeta{APIVersion: "update.edgeless.systems/v1alpha1", Kind: "ScalingGroup"},
|
||
|
ObjectMeta: metav1.ObjectMeta{
|
||
|
Name: "resource-name",
|
||
|
},
|
||
|
Spec: updatev1alpha1.ScalingGroupSpec{
|
||
|
NodeVersion: mainconstants.NodeVersionResourceName,
|
||
|
GroupID: "group-id",
|
||
|
NodeGroupName: "node-group-name",
|
||
|
AutoscalerGroupName: "autoscaling-group-name",
|
||
|
Autoscaling: true,
|
||
|
Min: 1,
|
||
|
Max: 10,
|
||
|
Role: updatev1alpha1.ControlPlaneRole,
|
||
|
},
|
||
|
},
|
||
|
wantExists: true,
|
||
|
},
|
||
|
"does not exist": {
|
||
|
getErr: k8sErrors.NewNotFound(schema.GroupResource{}, "resource-name"),
|
||
|
wantExists: false,
|
||
|
},
|
||
|
"getting fails": {
|
||
|
getErr: errors.New("get failed"),
|
||
|
wantErr: true,
|
||
|
},
|
||
|
"patching fails": {
|
||
|
getRes: &updatev1alpha1.ScalingGroup{
|
||
|
TypeMeta: metav1.TypeMeta{APIVersion: "update.edgeless.systems/v1alpha1", Kind: "ScalingGroup"},
|
||
|
ObjectMeta: metav1.ObjectMeta{
|
||
|
Name: "resource-name",
|
||
|
},
|
||
|
Spec: updatev1alpha1.ScalingGroupSpec{
|
||
|
NodeVersion: mainconstants.NodeVersionResourceName,
|
||
|
GroupID: "group-id",
|
||
|
AutoscalerGroupName: "autoscaling-group-name",
|
||
|
Autoscaling: true,
|
||
|
Min: 1,
|
||
|
Max: 10,
|
||
|
Role: updatev1alpha1.ControlPlaneRole,
|
||
|
},
|
||
|
},
|
||
|
updateErr: errors.New("patch failed"),
|
||
|
wantErr: true,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for name, tc := range testCases {
|
||
|
t.Run(name, func(t *testing.T) {
|
||
|
assert := assert.New(t)
|
||
|
require := require.New(t)
|
||
|
|
||
|
k8sClient := &fakeK8sClient{
|
||
|
getRes: tc.getRes,
|
||
|
getErr: tc.getErr,
|
||
|
updateErr: tc.updateErr,
|
||
|
}
|
||
|
gotExists, gotErr := patchNodeGroupName(context.Background(), k8sClient, "resource-name", "node-group-name")
|
||
|
if tc.wantErr {
|
||
|
assert.Error(gotErr)
|
||
|
return
|
||
|
}
|
||
|
require.NoError(gotErr)
|
||
|
assert.Equal(tc.wantExists, gotExists)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type fakeK8sClient struct {
|
||
|
getRes client.Object
|
||
|
createdObjects []client.Object
|
||
|
createErr error
|
||
|
listErr error
|
||
|
getErr error
|
||
|
updateErr error
|
||
|
client.Client
|
||
|
}
|
||
|
|
||
|
func (s *fakeK8sClient) Create(_ context.Context, obj client.Object, _ ...client.CreateOption) error {
|
||
|
for _, o := range s.createdObjects {
|
||
|
if obj.GetName() == o.GetName() {
|
||
|
return k8sErrors.NewAlreadyExists(schema.GroupResource{}, obj.GetName())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
s.createdObjects = append(s.createdObjects, obj.DeepCopyObject().(client.Object))
|
||
|
return s.createErr
|
||
|
}
|
||
|
|
||
|
func (s *fakeK8sClient) Get(_ context.Context, _ types.NamespacedName, out client.Object, _ ...client.GetOption) error {
|
||
|
if s.getErr != nil {
|
||
|
return s.getErr
|
||
|
}
|
||
|
obj := s.getRes.DeepCopyObject()
|
||
|
outVal := reflect.ValueOf(out)
|
||
|
objVal := reflect.ValueOf(obj)
|
||
|
if !objVal.Type().AssignableTo(outVal.Type()) {
|
||
|
return fmt.Errorf("fake had type %s, but %s was asked for", objVal.Type(), outVal.Type())
|
||
|
}
|
||
|
reflect.Indirect(outVal).Set(reflect.Indirect(objVal))
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (s *fakeK8sClient) Update(_ context.Context, _ client.Object, _ ...client.UpdateOption) error {
|
||
|
return s.updateErr
|
||
|
}
|
||
|
|
||
|
func (s *fakeK8sClient) List(_ context.Context, _ client.ObjectList, _ ...client.ListOption) error {
|
||
|
return s.listErr
|
||
|
}
|
||
|
|
||
|
type stubScalingGroupDiscoverer struct {
|
||
|
sync.RWMutex
|
||
|
groups []cspapi.ScalingGroup
|
||
|
}
|
||
|
|
||
|
func (d *stubScalingGroupDiscoverer) ListScalingGroups(_ context.Context, _ string,
|
||
|
) ([]cspapi.ScalingGroup, error) {
|
||
|
d.RLock()
|
||
|
defer d.RUnlock()
|
||
|
ret := make([]cspapi.ScalingGroup, len(d.groups))
|
||
|
copy(ret, d.groups)
|
||
|
return ret, nil
|
||
|
}
|
||
|
|
||
|
func (d *stubScalingGroupDiscoverer) set(groups []cspapi.ScalingGroup) {
|
||
|
d.Lock()
|
||
|
defer d.Unlock()
|
||
|
d.groups = groups
|
||
|
}
|
||
|
|
||
|
func (d *stubScalingGroupDiscoverer) reset() {
|
||
|
d.Lock()
|
||
|
defer d.Unlock()
|
||
|
d.groups = nil
|
||
|
}
|