Skip to content

Commit 7ace458

Browse files
committed
test(e2e): Add test for NFD addon
1 parent 56a6e95 commit 7ace458

File tree

5 files changed

+228
-30
lines changed

5 files changed

+228
-30
lines changed

pkg/handlers/generic/lifecycle/nfd/handler.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,13 @@ func (n *DefaultNFD) AfterControlPlaneInitialized(
103103
log.Error(err, "failed to apply NFD ConfigMap for cluster")
104104
return
105105
}
106-
err = utils.EnsureCRSForClusterFromConfigMaps(ctx, cm.Name, n.client, &req.Cluster, cm)
106+
err = utils.EnsureCRSForClusterFromConfigMaps(
107+
ctx,
108+
cm.Name+"-"+req.Cluster.Name,
109+
n.client,
110+
&req.Cluster,
111+
cm,
112+
)
107113
if err != nil {
108114
resp.SetStatus(runtimehooksv1.ResponseStatusFailure)
109115
log.Error(err, "failed to apply NFD ClusterResourceSet for cluster")

test/e2e/addon_helpers.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//go:build e2e
2+
3+
// Copyright 2024 D2iQ, Inc. All rights reserved.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package e2e
7+
8+
import (
9+
"context"
10+
11+
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
12+
"sigs.k8s.io/cluster-api/test/framework"
13+
14+
"github.com/d2iq-labs/capi-runtime-extensions/api/v1alpha1"
15+
)
16+
17+
type WaitForAddonsToBeReadyInWorkloadClusterInput struct {
18+
AddonsConfig v1alpha1.Addons
19+
WorkloadCluster *capiv1.Cluster
20+
ClusterProxy framework.ClusterProxy
21+
DeploymentIntervals []interface{}
22+
DaemonSetIntervals []interface{}
23+
HelmReleaseIntervals []interface{}
24+
ClusterResourceSetIntervals []interface{}
25+
}
26+
27+
func WaitForAddonsToBeReadyInWorkloadCluster(
28+
ctx context.Context,
29+
input WaitForAddonsToBeReadyInWorkloadClusterInput, //nolint:gocritic // This hugeParam is OK in tests.
30+
) {
31+
WaitForCNIToBeReadyInWorkloadCluster(
32+
ctx,
33+
WaitForCNIToBeReadyInWorkloadClusterInput{
34+
CNI: input.AddonsConfig.CNI,
35+
WorkloadCluster: input.WorkloadCluster,
36+
ClusterProxy: input.ClusterProxy,
37+
DeploymentIntervals: input.DeploymentIntervals,
38+
DaemonSetIntervals: input.DaemonSetIntervals,
39+
HelmReleaseIntervals: input.HelmReleaseIntervals,
40+
ClusterResourceSetIntervals: input.ClusterResourceSetIntervals,
41+
},
42+
)
43+
44+
WaitForNFDToBeReadyInWorkloadCluster(
45+
ctx,
46+
WaitForNFDToBeReadyInWorkloadClusterInput{
47+
NFD: input.AddonsConfig.NFD,
48+
WorkloadCluster: input.WorkloadCluster,
49+
ClusterProxy: input.ClusterProxy,
50+
DeploymentIntervals: input.DeploymentIntervals,
51+
DaemonSetIntervals: input.DaemonSetIntervals,
52+
HelmReleaseIntervals: input.HelmReleaseIntervals,
53+
ClusterResourceSetIntervals: input.ClusterResourceSetIntervals,
54+
},
55+
)
56+
}

test/e2e/clusterresourceset_helpers.go

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ package e2e
77

88
import (
99
"context"
10+
"fmt"
1011

12+
. "github.com/onsi/ginkgo/v2"
1113
. "github.com/onsi/gomega"
14+
corev1 "k8s.io/api/core/v1"
1215
"k8s.io/apimachinery/pkg/types"
1316
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1417
addonsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1"
1518
"sigs.k8s.io/cluster-api/test/framework"
19+
"sigs.k8s.io/controller-runtime/pkg/client"
1620
)
1721

1822
type waitForClusterResourceSetToApplyResourcesInClusterInput struct {
@@ -31,7 +35,7 @@ func waitForClusterResourceSetToApplyResourcesInCluster(
3135
ctx, types.NamespacedName{Name: input.name, Namespace: input.cluster.Namespace}, crs,
3236
)).To(Succeed())
3337

34-
framework.WaitForClusterResourceSetToApplyResources(
38+
waitForClusterResourceSetToApplyResources(
3539
ctx,
3640
framework.WaitForClusterResourceSetToApplyResourcesInput{
3741
ClusterProxy: input.clusterProxy,
@@ -41,3 +45,83 @@ func waitForClusterResourceSetToApplyResourcesInCluster(
4145
input.intervals...,
4246
)
4347
}
48+
49+
// Copied from upstream to fix bug checking bindings. Need to contribute fix back upstream and use it from there once
50+
// available.
51+
//
52+
// waitForClusterResourceSetToApplyResources wait until all ClusterResourceSet resources are created in the matching
53+
// cluster.
54+
func waitForClusterResourceSetToApplyResources(
55+
ctx context.Context,
56+
input framework.WaitForClusterResourceSetToApplyResourcesInput,
57+
intervals ...interface{},
58+
) {
59+
Expect(ctx).NotTo(BeNil(), "ctx is required for WaitForClusterResourceSetToApplyResources")
60+
Expect(
61+
input.ClusterProxy,
62+
).ToNot(
63+
BeNil(),
64+
"Invalid argument. input.ClusterProxy can't be nil when calling WaitForClusterResourceSetToApplyResources",
65+
)
66+
Expect(
67+
input.Cluster,
68+
).ToNot(
69+
BeNil(),
70+
"Invalid argument. input.Cluster can't be nil when calling WaitForClusterResourceSetToApplyResources",
71+
)
72+
Expect(
73+
input.ClusterResourceSet,
74+
).NotTo(
75+
BeNil(),
76+
"Invalid argument. input.ClusterResourceSet can't be nil when calling WaitForClusterResourceSetToApplyResources",
77+
)
78+
79+
fmt.Fprintln(GinkgoWriter, "Waiting until the binding is created for the workload cluster")
80+
Eventually(func() bool {
81+
binding := &addonsv1.ClusterResourceSetBinding{}
82+
err := input.ClusterProxy.GetClient().
83+
Get(ctx, types.NamespacedName{Name: input.Cluster.Name, Namespace: input.Cluster.Namespace}, binding)
84+
return err == nil
85+
}, intervals...).Should(BeTrue())
86+
87+
fmt.Fprintln(GinkgoWriter, "Waiting until the resource is created in the workload cluster")
88+
Eventually(func() bool {
89+
binding := &addonsv1.ClusterResourceSetBinding{}
90+
Expect(
91+
input.ClusterProxy.GetClient().
92+
Get(ctx, types.NamespacedName{Name: input.Cluster.Name, Namespace: input.Cluster.Namespace}, binding),
93+
).To(Succeed())
94+
95+
for _, resource := range input.ClusterResourceSet.Spec.Resources {
96+
var configSource client.Object
97+
98+
switch resource.Kind {
99+
case string(addonsv1.SecretClusterResourceSetResourceKind):
100+
configSource = &corev1.Secret{}
101+
case string(addonsv1.ConfigMapClusterResourceSetResourceKind):
102+
configSource = &corev1.ConfigMap{}
103+
}
104+
105+
if err := input.ClusterProxy.GetClient().Get(
106+
ctx, types.NamespacedName{Name: resource.Name, Namespace: input.ClusterResourceSet.Namespace}, configSource,
107+
); err != nil {
108+
// If the resource is missing, CRS will not requeue but retry at each reconcile,
109+
// because this is not an error. So, we are only interested in seeing the resources that exist to be applied by CRS.
110+
continue
111+
}
112+
113+
// Fix a bug from upstream to check all bindings.
114+
resourceApplied := false
115+
for _, binding := range binding.Spec.Bindings {
116+
if binding.IsApplied(resource) {
117+
resourceApplied = true
118+
break
119+
}
120+
}
121+
if !resourceApplied {
122+
return false
123+
}
124+
}
125+
return true
126+
}, intervals...).Should(BeTrue())
127+
}

test/e2e/cni_helpers.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,6 @@ import (
1818
"github.com/d2iq-labs/capi-runtime-extensions/api/v1alpha1"
1919
)
2020

21-
type WaitForAddonsToBeReadyInWorkloadClusterInput struct {
22-
AddonsConfig v1alpha1.Addons
23-
WorkloadCluster *capiv1.Cluster
24-
ClusterProxy framework.ClusterProxy
25-
DeploymentIntervals []interface{}
26-
DaemonSetIntervals []interface{}
27-
HelmReleaseIntervals []interface{}
28-
ClusterResourceSetIntervals []interface{}
29-
}
30-
31-
func WaitForAddonsToBeReadyInWorkloadCluster(
32-
ctx context.Context,
33-
input WaitForAddonsToBeReadyInWorkloadClusterInput, //nolint:gocritic // This hugeParam is OK in tests.
34-
) {
35-
WaitForCNIToBeReadyInWorkloadCluster(
36-
ctx,
37-
WaitForCNIToBeReadyInWorkloadClusterInput{
38-
CNI: input.AddonsConfig.CNI,
39-
WorkloadCluster: input.WorkloadCluster,
40-
ClusterProxy: input.ClusterProxy,
41-
DeploymentIntervals: input.DeploymentIntervals,
42-
DaemonSetIntervals: input.DaemonSetIntervals,
43-
HelmReleaseIntervals: input.HelmReleaseIntervals,
44-
ClusterResourceSetIntervals: input.ClusterResourceSetIntervals,
45-
},
46-
)
47-
}
48-
4921
type WaitForCNIToBeReadyInWorkloadClusterInput struct {
5022
CNI *v1alpha1.CNI
5123
WorkloadCluster *capiv1.Cluster

test/e2e/nfd_helpers.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//go:build e2e
2+
3+
// Copyright 2024 D2iQ, Inc. All rights reserved.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package e2e
7+
8+
import (
9+
"context"
10+
11+
appsv1 "k8s.io/api/apps/v1"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
14+
"sigs.k8s.io/cluster-api/test/framework"
15+
16+
"github.com/d2iq-labs/capi-runtime-extensions/api/v1alpha1"
17+
)
18+
19+
type WaitForNFDToBeReadyInWorkloadClusterInput struct {
20+
NFD *v1alpha1.NFD
21+
WorkloadCluster *capiv1.Cluster
22+
ClusterProxy framework.ClusterProxy
23+
DeploymentIntervals []interface{}
24+
DaemonSetIntervals []interface{}
25+
HelmReleaseIntervals []interface{}
26+
ClusterResourceSetIntervals []interface{}
27+
}
28+
29+
func WaitForNFDToBeReadyInWorkloadCluster(
30+
ctx context.Context,
31+
input WaitForNFDToBeReadyInWorkloadClusterInput, //nolint:gocritic // This hugeParam is OK in tests.
32+
) {
33+
if input.NFD == nil {
34+
return
35+
}
36+
37+
waitForClusterResourceSetToApplyResourcesInCluster(
38+
ctx,
39+
waitForClusterResourceSetToApplyResourcesInClusterInput{
40+
name: "node-feature-discovery-" + input.WorkloadCluster.Name,
41+
clusterProxy: input.ClusterProxy,
42+
cluster: input.WorkloadCluster,
43+
intervals: input.ClusterResourceSetIntervals,
44+
},
45+
)
46+
47+
workloadClusterClient := input.ClusterProxy.GetWorkloadCluster(
48+
ctx, input.WorkloadCluster.Namespace, input.WorkloadCluster.Name,
49+
).GetClient()
50+
51+
WaitForDeploymentsAvailable(ctx, framework.WaitForDeploymentsAvailableInput{
52+
Getter: workloadClusterClient,
53+
Deployment: &appsv1.Deployment{
54+
ObjectMeta: metav1.ObjectMeta{
55+
Name: "node-feature-discovery-gc",
56+
Namespace: "node-feature-discovery",
57+
},
58+
},
59+
}, input.DeploymentIntervals...)
60+
61+
WaitForDeploymentsAvailable(ctx, framework.WaitForDeploymentsAvailableInput{
62+
Getter: workloadClusterClient,
63+
Deployment: &appsv1.Deployment{
64+
ObjectMeta: metav1.ObjectMeta{
65+
Name: "node-feature-discovery-master",
66+
Namespace: "node-feature-discovery",
67+
},
68+
},
69+
}, input.DeploymentIntervals...)
70+
71+
WaitForDaemonSetsAvailable(ctx, WaitForDaemonSetsAvailableInput{
72+
Getter: workloadClusterClient,
73+
DaemonSet: &appsv1.DaemonSet{
74+
ObjectMeta: metav1.ObjectMeta{
75+
Name: "node-feature-discovery-worker",
76+
Namespace: "node-feature-discovery",
77+
},
78+
},
79+
}, input.DaemonSetIntervals...)
80+
}

0 commit comments

Comments
 (0)