[node operator] ScalingGroupController env test

Signed-off-by: Malte Poll <mp@edgeless.systems>
This commit is contained in:
Malte Poll 2022-06-29 16:47:13 +02:00 committed by Malte Poll
parent 8bc1db609f
commit d62ae3add3
3 changed files with 158 additions and 0 deletions

View File

@ -0,0 +1,110 @@
package controllers
import (
"context"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
updatev1alpha1 "github.com/edgelesssys/constellation/operators/constellation-node-operator/api/v1alpha1"
)
var _ = Describe("ScalingGroup controller", func() {
// Define utility constants for object names and testing timeouts/durations and intervals.
const (
nodeImageName = "node-image"
scalingGroupName = "test-group"
timeout = time.Second * 10
duration = time.Second * 2
interval = time.Millisecond * 250
)
nodeImageLookupKey := types.NamespacedName{Name: nodeImageName}
Context("When changing a node image resource spec", func() {
It("Should update corresponding scaling group images", func() {
By("creating a node image resource")
ctx := context.Background()
nodeImage := &updatev1alpha1.NodeImage{
TypeMeta: metav1.TypeMeta{
APIVersion: "update.edgeless.systems/v1alpha1",
Kind: "NodeImage",
},
ObjectMeta: metav1.ObjectMeta{
Name: nodeImageName,
},
Spec: updatev1alpha1.NodeImageSpec{
ImageReference: "image-1",
},
}
Expect(k8sClient.Create(ctx, nodeImage)).Should(Succeed())
createdNodeImage := &updatev1alpha1.NodeImage{}
Eventually(func() error {
return k8sClient.Get(ctx, nodeImageLookupKey, createdNodeImage)
}, timeout, interval).Should(Succeed())
Expect(createdNodeImage.Spec.ImageReference).Should(Equal("image-1"))
By("creating a scaling group")
scalingGroup := &updatev1alpha1.ScalingGroup{
TypeMeta: metav1.TypeMeta{
APIVersion: "update.edgeless.systems/v1alpha1",
Kind: "ScalingGroup",
},
ObjectMeta: metav1.ObjectMeta{
Name: scalingGroupName,
},
Spec: updatev1alpha1.ScalingGroupSpec{
NodeImage: nodeImageName,
GroupID: "group-id",
},
}
Expect(k8sClient.Create(ctx, scalingGroup)).Should(Succeed())
scalingGroupLookupKey := types.NamespacedName{Name: scalingGroupName}
createdScalingGroup := &updatev1alpha1.ScalingGroup{}
Eventually(func() error {
return k8sClient.Get(ctx, scalingGroupLookupKey, createdScalingGroup)
}, timeout, interval).Should(Succeed())
By("checking the scaling group status shows the correct image")
Eventually(func() string {
image, _ := fakes.scalingGroupUpdater.GetScalingGroupImage(ctx, "group-id")
return image
}, timeout, interval).Should(Equal("image-1"))
Consistently(func() (string, error) {
err := k8sClient.Get(ctx, scalingGroupLookupKey, createdScalingGroup)
if err != nil {
return "", err
}
return createdScalingGroup.Status.ImageReference, nil
}, duration, interval).Should(Equal("image-1"))
By("updating the node image")
Expect(k8sClient.Get(ctx, nodeImageLookupKey, nodeImage)).Should(Succeed())
nodeImage.Spec.ImageReference = "image-2"
Expect(k8sClient.Update(ctx, nodeImage)).Should(Succeed())
By("checking the scaling group eventually uses the latest image")
Eventually(func() string {
image, _ := fakes.scalingGroupUpdater.GetScalingGroupImage(ctx, "group-id")
return image
}, timeout, interval).Should(Equal("image-2"))
By("checking the scaling group status shows the latest image")
Consistently(func() (string, error) {
err := k8sClient.Get(ctx, scalingGroupLookupKey, createdScalingGroup)
if err != nil {
return "", err
}
return createdScalingGroup.Status.ImageReference, nil
}, duration, interval).Should(Equal("image-2"))
By("cleaning up all resources")
Expect(k8sClient.Delete(ctx, createdNodeImage)).Should(Succeed())
Expect(k8sClient.Delete(ctx, scalingGroup)).Should(Succeed())
})
})
})

View File

@ -0,0 +1,30 @@
package controllers
import (
"context"
"sync"
)
type fakeScalingGroupUpdater struct {
sync.RWMutex
scalingGroupImage map[string]string
}
func newFakeScalingGroupUpdater() *fakeScalingGroupUpdater {
return &fakeScalingGroupUpdater{
scalingGroupImage: make(map[string]string),
}
}
func (u *fakeScalingGroupUpdater) GetScalingGroupImage(ctx context.Context, scalingGroupID string) (string, error) {
u.RLock()
defer u.RUnlock()
return u.scalingGroupImage[scalingGroupID], nil
}
func (u *fakeScalingGroupUpdater) SetScalingGroupImage(ctx context.Context, scalingGroupID, imageURI string) error {
u.Lock()
defer u.Unlock()
u.scalingGroupImage[scalingGroupID] = imageURI
return nil
}

View File

@ -31,6 +31,7 @@ var (
testEnv *envtest.Environment
ctx context.Context
cancel context.CancelFunc
fakes = newFakes()
)
func TestAPIs(t *testing.T) {
@ -77,6 +78,13 @@ var _ = BeforeSuite(func() {
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())
err = (&ScalingGroupReconciler{
scalingGroupUpdater: fakes.scalingGroupUpdater,
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())
go func() {
defer GinkgoRecover()
err = k8sManager.Start(ctx)
@ -90,3 +98,13 @@ var _ = AfterSuite(func() {
err := testEnv.Stop()
Expect(err).NotTo(HaveOccurred())
})
type fakeCollection struct {
scalingGroupUpdater *fakeScalingGroupUpdater
}
func newFakes() fakeCollection {
return fakeCollection{
scalingGroupUpdater: newFakeScalingGroupUpdater(),
}
}