diff --git a/test/envtest/reconciler_setupwithmanager_test.go b/test/envtest/reconciler_setupwithmanager_test.go index c6f46497f..f47a2391a 100644 --- a/test/envtest/reconciler_setupwithmanager_test.go +++ b/test/envtest/reconciler_setupwithmanager_test.go @@ -10,6 +10,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" k8stypes "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" @@ -27,34 +28,31 @@ import ( ) func TestNewKonnectEntityReconciler(t *testing.T) { - testNewKonnectEntityReconciler(t, konnectv1alpha1.KonnectGatewayControlPlane{}, konnectGatewayControlPlaneTestCases) - testNewKonnectEntityReconciler(t, configurationv1alpha1.KongService{}, nil) - testNewKonnectEntityReconciler(t, configurationv1.KongConsumer{}, nil) - testNewKonnectEntityReconciler(t, configurationv1alpha1.KongRoute{}, nil) - testNewKonnectEntityReconciler(t, configurationv1beta1.KongConsumerGroup{}, nil) - testNewKonnectEntityReconciler(t, configurationv1alpha1.KongPluginBinding{}, nil) + // Setup up the envtest environment and share it across the test cases. + cfg := Setup(t, scheme.Get()) + + testNewKonnectEntityReconciler(t, cfg, konnectv1alpha1.KonnectGatewayControlPlane{}, konnectGatewayControlPlaneTestCases) + testNewKonnectEntityReconciler(t, cfg, configurationv1alpha1.KongService{}, nil) + testNewKonnectEntityReconciler(t, cfg, configurationv1.KongConsumer{}, nil) + testNewKonnectEntityReconciler(t, cfg, configurationv1alpha1.KongRoute{}, nil) + testNewKonnectEntityReconciler(t, cfg, configurationv1beta1.KongConsumerGroup{}, nil) + testNewKonnectEntityReconciler(t, cfg, configurationv1alpha1.KongPluginBinding{}, nil) } -const ( - testNamespaceName = "test" - envTestWaitDuration = time.Second - envTestWaitTick = 20 * time.Millisecond -) - type konnectEntityReconcilerTestCase struct { name string - objectOps func(ctx context.Context, t *testing.T, cl client.Client) - eventuallyPredicate func(ctx context.Context, t *testing.T, cl client.Client) bool + objectOps func(ctx context.Context, t *testing.T, cl client.Client, ns *corev1.Namespace) + eventuallyPredicate func(ctx context.Context, t *testing.T, cl client.Client, ns *corev1.Namespace) bool } var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ { name: "should resolve auth", - objectOps: func(ctx context.Context, t *testing.T, cl client.Client) { + objectOps: func(ctx context.Context, t *testing.T, cl client.Client, ns *corev1.Namespace) { auth := &konnectv1alpha1.KonnectAPIAuthConfiguration{ ObjectMeta: metav1.ObjectMeta{ Name: "auth", - Namespace: testNamespaceName, + Namespace: ns.Name, }, Spec: konnectv1alpha1.KonnectAPIAuthConfigurationSpec{ Type: konnectv1alpha1.KonnectAPIAuthTypeToken, @@ -65,7 +63,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ cp := &konnectv1alpha1.KonnectGatewayControlPlane{ ObjectMeta: metav1.ObjectMeta{ Name: "cp-1", - Namespace: testNamespaceName, + Namespace: ns.Name, }, Spec: konnectv1alpha1.KonnectGatewayControlPlaneSpec{ KonnectConfiguration: konnectv1alpha1.KonnectConfiguration{ @@ -77,10 +75,17 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ } require.NoError(t, cl.Create(ctx, cp)) }, - eventuallyPredicate: func(ctx context.Context, t *testing.T, cl client.Client) bool { + eventuallyPredicate: func(ctx context.Context, t *testing.T, cl client.Client, ns *corev1.Namespace) bool { cp := &konnectv1alpha1.KonnectGatewayControlPlane{} - err := cl.Get(ctx, k8stypes.NamespacedName{Namespace: testNamespaceName, Name: "cp-1"}, cp) - require.NoError(t, err) + require.NoError(t, + cl.Get(ctx, + k8stypes.NamespacedName{ + Namespace: ns.Name, + Name: "cp-1", + }, + cp, + ), + ) // TODO: setup mock Konnect SDK and verify that Konnect CP is "Created". return lo.ContainsBy(cp.Status.Conditions, func(condition metav1.Condition) bool { return condition.Type == conditions.KonnectEntityAPIAuthConfigurationResolvedRefConditionType && condition.Status == metav1.ConditionTrue @@ -89,27 +94,28 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ }, } +// testNewKonnectEntityReconciler is a helper function to test Konnect entity reconcilers. +// It creates a new namespace for each test case and starts a new controller manager. +// The provided rest.Config designates the Kubernetes API server to use for the tests. func testNewKonnectEntityReconciler[ T constraints.SupportedKonnectEntityType, TEnt constraints.EntityType[T], ]( t *testing.T, + cfg *rest.Config, ent T, testCases []konnectEntityReconcilerTestCase, ) { t.Helper() - sdkFactory := &ops.MockSDKFactory{} - t.Run(ent.GetTypeName(), func(t *testing.T) { - s := scheme.Get() - cfg := Setup(t, s) + t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: s, + Scheme: scheme.Get(), Metrics: metricsserver.Options{ // We do not need metrics server so we set BindAddress to 0 to disable it. BindAddress: "0", @@ -118,15 +124,15 @@ func testNewKonnectEntityReconciler[ require.NoError(t, err) cl := mgr.GetClient() - reconciler := konnect.NewKonnectEntityReconciler[T, TEnt](sdkFactory, false, cl) + reconciler := konnect.NewKonnectEntityReconciler[T, TEnt](&ops.MockSDKFactory{}, false, cl) require.NoError(t, reconciler.SetupWithManager(ctx, mgr)) - err = cl.Create(context.Background(), &corev1.Namespace{ + ns := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ - Name: "test", + GenerateName: "test-", }, - }) - require.NoError(t, err) + } + require.NoError(t, cl.Create(ctx, ns)) t.Logf("Starting manager for test case %s", t.Name()) go func() { @@ -134,12 +140,17 @@ func testNewKonnectEntityReconciler[ require.NoError(t, err) }() + const ( + wait = time.Second + tick = 20 * time.Millisecond + ) + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - tc.objectOps(ctx, t, cl) + tc.objectOps(ctx, t, cl, ns) require.Eventually(t, func() bool { - return tc.eventuallyPredicate(ctx, t, cl) - }, envTestWaitDuration, envTestWaitTick) + return tc.eventuallyPredicate(ctx, t, cl, ns) + }, wait, tick) }) } })