Skip to content

Commit 17ac7f2

Browse files
committed
Fix the new e2e2 test
Signed-off-by: jose.vazquez <[email protected]>
1 parent 4c95b36 commit 17ac7f2

File tree

6 files changed

+162
-115
lines changed

6 files changed

+162
-115
lines changed

test/e2e2/flexcluster_test.go

Lines changed: 146 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ import (
2323
. "github.com/onsi/ginkgo/v2"
2424
. "github.com/onsi/gomega"
2525
corev1 "k8s.io/api/core/v1"
26-
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2726
"k8s.io/apimachinery/pkg/api/meta"
2827
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29-
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3028
"sigs.k8s.io/controller-runtime/pkg/client"
3129

3230
nextapiv1 "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/nextapi/generated/v1"
@@ -45,14 +43,25 @@ const (
4543
GroupCRDName = "groups.atlas.generated.mongodb.com"
4644
)
4745

46+
// yamlPlaceholders holds all placeholder values for YAML template replacement.
47+
type yamlPlaceholders struct {
48+
GroupID string
49+
OrgID string
50+
GroupName string
51+
OperatorNamespace string
52+
CredentialsSecretName string
53+
}
54+
4855
var _ = Describe("FlexCluster CRUD", Ordered, Label("flexcluster-ctlr"), func() {
4956
var ctx context.Context
5057
var kubeClient client.Client
5158
var ako operator.Operator
5259
var testNamespace *corev1.Namespace
60+
var sharedGroupNamespace *corev1.Namespace
5361
var testGroup *nextapiv1.Group
5462
var groupID string
5563
var orgID string
64+
var sharedPlaceholders yamlPlaceholders
5665

5766
_ = BeforeAll(func() {
5867
if !version.IsExperimental() {
@@ -70,45 +79,41 @@ var _ = Describe("FlexCluster CRUD", Ordered, Label("flexcluster-ctlr"), func()
7079
testClient, err := kube.NewTestClient()
7180
Expect(err).To(Succeed())
7281
kubeClient = testClient
73-
Expect(kube.AssertCRDs(ctx, kubeClient,
74-
&apiextensionsv1.CustomResourceDefinition{
75-
ObjectMeta: v1.ObjectMeta{Name: FlexClusterCRDName},
76-
},
77-
&apiextensionsv1.CustomResourceDefinition{
78-
ObjectMeta: v1.ObjectMeta{Name: GroupCRDName},
79-
},
80-
)).To(Succeed())
82+
Expect(kube.AssertCRDNames(ctx, kubeClient, FlexClusterCRDName, GroupCRDName)).To(Succeed())
83+
84+
By("Create namespace and credentials for shared test Group", func() {
85+
sharedGroupNamespace = &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{
86+
Name: utils.RandomName("flex-shared-grp-ns"),
87+
}}
88+
Expect(kubeClient.Create(ctx, sharedGroupNamespace)).To(Succeed())
89+
copyCredentialsToNamespace(ctx, kubeClient, sharedGroupNamespace.Name)
90+
})
8191

8292
By("Create test Group", func() {
83-
operatorNamespace := control.MustEnvVar("OPERATOR_NAMESPACE")
8493
groupName := utils.RandomName("flexcluster-test-group")
94+
// Set up shared placeholders for Group YAML template
95+
sharedPlaceholders = yamlPlaceholders{
96+
GroupName: groupName,
97+
OperatorNamespace: sharedGroupNamespace.Name,
98+
CredentialsSecretName: DefaultGlobalCredentials,
99+
OrgID: orgID,
100+
}
85101
// Replace placeholders in the Group YAML template
86-
groupYAML := strings.ReplaceAll(string(flexsamples.TestGroup), "__GROUP_NAME__", groupName)
87-
groupYAML = strings.ReplaceAll(groupYAML, "__OPERATOR_NAMESPACE__", operatorNamespace)
88-
groupYAML = strings.ReplaceAll(groupYAML, "__CREDENTIALS_SECRET_NAME__", DefaultGlobalCredentials)
89-
groupYAML = strings.ReplaceAll(groupYAML, "__ORG_ID__", orgID)
102+
groupYAML := replaceYAMLPlaceholders(string(flexsamples.TestGroup), sharedPlaceholders)
90103
objs := yml.MustParseObjects(strings.NewReader(groupYAML))
91104
Expect(len(objs)).To(Equal(1))
92105
testGroup = objs[0].(*nextapiv1.Group)
93106
Expect(kubeClient.Create(ctx, testGroup)).To(Succeed())
94107
})
95108

96109
By("Wait for Group to be Ready and get its ID", func() {
97-
Eventually(func(g Gomega) bool {
98-
g.Expect(
99-
kubeClient.Get(ctx, client.ObjectKeyFromObject(testGroup), testGroup),
100-
).To(Succeed())
101-
if condition := meta.FindStatusCondition(testGroup.GetConditions(), "Ready"); condition != nil {
102-
if condition.Status == metav1.ConditionTrue {
103-
if testGroup.Status.V20250312 != nil && testGroup.Status.V20250312.Id != nil {
104-
groupID = *testGroup.Status.V20250312.Id
105-
return true
106-
}
107-
}
108-
}
109-
return false
110-
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).To(BeTrue())
110+
waitForResourceReady(ctx, kubeClient, testGroup)
111+
Expect(testGroup.Status.V20250312).NotTo(BeNil())
112+
Expect(testGroup.Status.V20250312.Id).NotTo(BeNil())
113+
groupID = *testGroup.Status.V20250312.Id
111114
Expect(groupID).NotTo(BeEmpty())
115+
// Update shared placeholders with groupID now that it's available
116+
sharedPlaceholders.GroupID = groupID
112117
})
113118
})
114119

@@ -122,6 +127,14 @@ var _ = Describe("FlexCluster CRUD", Ordered, Label("flexcluster-ctlr"), func()
122127
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).NotTo(Succeed())
123128
})
124129
}
130+
if kubeClient != nil && sharedGroupNamespace != nil {
131+
By("Clean up shared group namespace", func() {
132+
Expect(kubeClient.Delete(ctx, sharedGroupNamespace)).To(Succeed())
133+
Eventually(func(g Gomega) bool {
134+
return kubeClient.Get(ctx, client.ObjectKeyFromObject(sharedGroupNamespace), sharedGroupNamespace) == nil
135+
}).WithTimeout(time.Minute).WithPolling(time.Second).To(BeFalse())
136+
})
137+
}
125138
if ako != nil {
126139
ako.Stop(GinkgoT())
127140
}
@@ -149,49 +162,33 @@ var _ = Describe("FlexCluster CRUD", Ordered, Label("flexcluster-ctlr"), func()
149162

150163
DescribeTable("FlexCluster CRUD lifecycle",
151164
func(createYAML, updateYAML []byte, clusterName string) {
165+
// Generate randomized group name for this test run (cluster names are unique per group)
166+
groupName := utils.RandomName("flex-grp")
167+
168+
// Set up placeholders for this test case (reuse shared values, override groupName)
169+
testPlaceholders := sharedPlaceholders
170+
testPlaceholders.GroupName = groupName
171+
172+
// Track created objects for cleanup
173+
var createdObjects []client.Object
174+
152175
By("Copy credentials secret to test namespace", func() {
153-
globalCredsKey := client.ObjectKey{
154-
Name: DefaultGlobalCredentials,
155-
Namespace: control.MustEnvVar("OPERATOR_NAMESPACE"),
156-
}
157-
credentialsSecret, err := copySecretToNamespace(ctx, kubeClient, globalCredsKey, testNamespace.Name)
158-
Expect(err).NotTo(HaveOccurred())
159-
Expect(
160-
kubeClient.Patch(ctx, credentialsSecret, client.Apply, client.ForceOwnership, GinkGoFieldOwner),
161-
).To(Succeed())
176+
copyCredentialsToNamespace(ctx, kubeClient, testNamespace.Name)
162177
})
163178

164179
By("Create resources from YAML", func() {
165-
// Replace placeholders with actual values
166-
createYAMLStr := strings.ReplaceAll(string(createYAML), "__GROUP_ID__", groupID)
167-
createYAMLStr = strings.ReplaceAll(createYAMLStr, "__ORG_ID__", orgID)
168-
objs := yml.MustParseObjects(strings.NewReader(createYAMLStr))
169-
for _, obj := range objs {
170-
objToApply := kube.WithRenamedNamespace(obj, testNamespace.Name)
171-
Expect(
172-
kubeClient.Patch(ctx, objToApply, client.Apply, client.ForceOwnership, GinkGoFieldOwner),
173-
).To(Succeed())
174-
}
180+
objs := applyYAMLToNamespace(ctx, kubeClient, createYAML, testPlaceholders, testNamespace.Name)
181+
createdObjects = append(createdObjects, objs...)
175182
})
176183

177184
By("Wait for Group to be Ready (if using groupRef)", func() {
178-
createYAMLStr := strings.ReplaceAll(string(createYAML), "__GROUP_ID__", groupID)
179-
createYAMLStr = strings.ReplaceAll(createYAMLStr, "__ORG_ID__", orgID)
185+
createYAMLStr := replaceYAMLPlaceholders(string(createYAML), testPlaceholders)
180186
objs := yml.MustParseObjects(strings.NewReader(createYAMLStr))
181187
for _, obj := range objs {
182188
if group, ok := obj.(*nextapiv1.Group); ok {
183-
groupInKube := nextapiv1.Group{
189+
waitForResourceReady(ctx, kubeClient, &nextapiv1.Group{
184190
ObjectMeta: metav1.ObjectMeta{Name: group.Name, Namespace: testNamespace.Name},
185-
}
186-
Eventually(func(g Gomega) bool {
187-
g.Expect(
188-
kubeClient.Get(ctx, client.ObjectKeyFromObject(&groupInKube), &groupInKube),
189-
).To(Succeed())
190-
if condition := meta.FindStatusCondition(groupInKube.GetConditions(), "Ready"); condition != nil {
191-
return condition.Status == metav1.ConditionTrue
192-
}
193-
return false
194-
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).To(BeTrue())
191+
})
195192
}
196193
}
197194
})
@@ -201,15 +198,7 @@ var _ = Describe("FlexCluster CRUD", Ordered, Label("flexcluster-ctlr"), func()
201198
}
202199

203200
By("Wait for FlexCluster to be Ready", func() {
204-
Eventually(func(g Gomega) bool {
205-
g.Expect(
206-
kubeClient.Get(ctx, client.ObjectKeyFromObject(&cluster), &cluster),
207-
).To(Succeed())
208-
if condition := meta.FindStatusCondition(cluster.GetConditions(), "Ready"); condition != nil {
209-
return condition.Status == metav1.ConditionTrue
210-
}
211-
return false
212-
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).To(BeTrue())
201+
waitForResourceReady(ctx, kubeClient, &cluster)
213202
})
214203

215204
By("Verify cluster was created", func() {
@@ -220,48 +209,26 @@ var _ = Describe("FlexCluster CRUD", Ordered, Label("flexcluster-ctlr"), func()
220209

221210
By("Update FlexCluster", func() {
222211
if len(updateYAML) > 0 {
223-
// Replace placeholders with actual values
224-
updateYAMLStr := strings.ReplaceAll(string(updateYAML), "__GROUP_ID__", groupID)
225-
updateYAMLStr = strings.ReplaceAll(updateYAMLStr, "__ORG_ID__", orgID)
226-
updateObjs := yml.MustParseObjects(strings.NewReader(updateYAMLStr))
227-
for _, obj := range updateObjs {
228-
objToPatch := kube.WithRenamedNamespace(obj, testNamespace.Name)
229-
Expect(
230-
kubeClient.Patch(ctx, objToPatch, client.Apply, client.ForceOwnership, GinkGoFieldOwner),
231-
).To(Succeed())
232-
}
212+
applyYAMLToNamespace(ctx, kubeClient, updateYAML, testPlaceholders, testNamespace.Name)
233213
}
234214
})
235215

236216
By("Wait for FlexCluster to be Ready & updated", func() {
237217
if len(updateYAML) > 0 {
238-
Eventually(func(g Gomega) bool {
239-
g.Expect(
240-
kubeClient.Get(ctx, client.ObjectKeyFromObject(&cluster), &cluster),
241-
).To(Succeed())
242-
ready := false
243-
if condition := meta.FindStatusCondition(cluster.GetConditions(), "Ready"); condition != nil {
244-
ready = (condition.Status == metav1.ConditionTrue)
245-
}
246-
if ready {
247-
if condition := meta.FindStatusCondition(cluster.GetConditions(), "State"); condition != nil {
248-
return state.ResourceState(condition.Reason) == state.StateUpdated
249-
}
250-
}
251-
return false
252-
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).To(BeTrue())
218+
waitForResourceUpdated(ctx, kubeClient, &cluster)
253219
}
254220
})
255221

256-
By("Delete FlexCluster", func() {
257-
Expect(kubeClient.Delete(ctx, &cluster)).To(Succeed())
222+
By("Delete all created resources", func() {
223+
for _, obj := range createdObjects {
224+
_ = kubeClient.Delete(ctx, obj)
225+
}
258226
})
259227

260-
By("Wait for FlexCluster to be deleted", func() {
261-
Eventually(func(g Gomega) error {
262-
err := kubeClient.Get(ctx, client.ObjectKeyFromObject(&cluster), &cluster)
263-
return err
264-
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).NotTo(Succeed())
228+
By("Wait for all resources to be deleted", func() {
229+
for _, obj := range createdObjects {
230+
waitForResourceDeleted(ctx, kubeClient, obj)
231+
}
265232
})
266233
},
267234
Entry("With direct groupId",
@@ -276,3 +243,80 @@ var _ = Describe("FlexCluster CRUD", Ordered, Label("flexcluster-ctlr"), func()
276243
),
277244
)
278245
})
246+
247+
// replaceYAMLPlaceholders replaces placeholders in YAML templates with actual values from the struct.
248+
func replaceYAMLPlaceholders(yaml string, p yamlPlaceholders) string {
249+
result := yaml
250+
result = strings.ReplaceAll(result, "__GROUP_ID__", p.GroupID)
251+
result = strings.ReplaceAll(result, "__ORG_ID__", p.OrgID)
252+
result = strings.ReplaceAll(result, "__GROUP_NAME__", p.GroupName)
253+
result = strings.ReplaceAll(result, "__OPERATOR_NAMESPACE__", p.OperatorNamespace)
254+
result = strings.ReplaceAll(result, "__CREDENTIALS_SECRET_NAME__", p.CredentialsSecretName)
255+
return result
256+
}
257+
258+
// copyCredentialsToNamespace copies the default global credentials secret to the specified namespace.
259+
func copyCredentialsToNamespace(ctx context.Context, kubeClient client.Client, namespace string) {
260+
globalCredsKey := client.ObjectKey{
261+
Name: DefaultGlobalCredentials,
262+
Namespace: control.MustEnvVar("OPERATOR_NAMESPACE"),
263+
}
264+
credentialsSecret, err := copySecretToNamespace(ctx, kubeClient, globalCredsKey, namespace)
265+
Expect(err).NotTo(HaveOccurred())
266+
Expect(
267+
kubeClient.Patch(ctx, credentialsSecret, client.Apply, client.ForceOwnership, GinkGoFieldOwner),
268+
).To(Succeed())
269+
}
270+
271+
// applyYAMLToNamespace applies YAML objects to a namespace after replacing placeholders.
272+
// Returns the list of applied objects.
273+
func applyYAMLToNamespace(ctx context.Context, kubeClient client.Client, yaml []byte, placeholders yamlPlaceholders, namespace string) []client.Object {
274+
yamlStr := replaceYAMLPlaceholders(string(yaml), placeholders)
275+
objs := yml.MustParseObjects(strings.NewReader(yamlStr))
276+
for _, obj := range objs {
277+
obj.SetNamespace(namespace)
278+
Expect(
279+
kubeClient.Patch(ctx, obj, client.Apply, client.ForceOwnership, GinkGoFieldOwner),
280+
).To(Succeed())
281+
}
282+
return objs
283+
}
284+
285+
// waitForResourceReady waits for a resource to have Ready condition set to True.
286+
func waitForResourceReady(ctx context.Context, kubeClient client.Client, obj kube.ObjectWithStatus) {
287+
Eventually(func(g Gomega) bool {
288+
g.Expect(
289+
kubeClient.Get(ctx, client.ObjectKeyFromObject(obj), obj),
290+
).To(Succeed())
291+
if condition := meta.FindStatusCondition(obj.GetConditions(), "Ready"); condition != nil {
292+
return condition.Status == metav1.ConditionTrue
293+
}
294+
return false
295+
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).To(BeTrue())
296+
}
297+
298+
// waitForResourceUpdated waits for a resource to be Ready and in Updated state.
299+
func waitForResourceUpdated(ctx context.Context, kubeClient client.Client, obj kube.ObjectWithStatus) {
300+
Eventually(func(g Gomega) bool {
301+
g.Expect(
302+
kubeClient.Get(ctx, client.ObjectKeyFromObject(obj), obj),
303+
).To(Succeed())
304+
ready := false
305+
if condition := meta.FindStatusCondition(obj.GetConditions(), "Ready"); condition != nil {
306+
ready = (condition.Status == metav1.ConditionTrue)
307+
}
308+
if ready {
309+
if condition := meta.FindStatusCondition(obj.GetConditions(), "State"); condition != nil {
310+
return state.ResourceState(condition.Reason) == state.StateUpdated
311+
}
312+
}
313+
return false
314+
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).To(BeTrue())
315+
}
316+
317+
// waitForResourceDeleted waits for a resource to be deleted from the cluster.
318+
func waitForResourceDeleted(ctx context.Context, kubeClient client.Client, obj client.Object) {
319+
Eventually(func(g Gomega) error {
320+
return kubeClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)
321+
}).WithTimeout(5 * time.Minute).WithPolling(5 * time.Second).ShouldNot(Succeed())
322+
}

test/e2e2/flexsamples/with_groupid_create.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ apiVersion: atlas.generated.mongodb.com/v1
22
kind: FlexCluster
33
metadata:
44
name: flexy
5-
namespace: mongodb-atlas-system
65
spec:
76
connectionSecretRef:
87
name: mongodb-atlas-operator-api-key
@@ -14,4 +13,3 @@ spec:
1413
providerSettings:
1514
backingProviderName: GCP
1615
regionName: CENTRAL_US
17-

test/e2e2/flexsamples/with_groupid_update.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ apiVersion: atlas.generated.mongodb.com/v1
22
kind: FlexCluster
33
metadata:
44
name: flexy
5-
namespace: mongodb-atlas-system
65
spec:
76
connectionSecretRef:
87
name: mongodb-atlas-operator-api-key
@@ -14,4 +13,3 @@ spec:
1413
providerSettings:
1514
backingProviderName: GCP
1615
regionName: CENTRAL_US
17-

0 commit comments

Comments
 (0)