Skip to content

Commit 3fb7917

Browse files
committed
test: add condition validation to E2E conformance tests
Add condition assertions to conformance tests: Fixtures: - Add assertCondition helper for verifying condition status - Support SriovNetwork, SriovNetworkPoolConfig, SriovNetworkNodePolicy Network Pool Tests (test_networkpool.go): - Verify PoolConfig Ready=True after RDMA mode configuration - Verify PoolConfig Progressing=False after configuration completes - Verify MatchedNodeCount is updated correctly - Add test for NoMatchingNodes when selector matches nothing Policy Configuration Tests (test_policy_configuration.go): - Verify Policy Ready=True after VF configuration - Verify Policy Progressing=False after configuration completes - Add condition checks for MTU and partition policies - Add condition checks for VFIO and netdevice policies Operator Tests (test_sriov_operator.go): - Verify SriovNetwork Ready=True after provisioning - Verify SriovNetwork Degraded=False when healthy - Add condition checks for various network configurations - Add condition validation for trust and spoofChk settings These tests ensure conditions are correctly set during real cluster operations and validate the end-to-end observability improvements. Signed-off-by: Sebastian Sch <sebassch@gmail.com>
1 parent bf05104 commit 3fb7917

File tree

4 files changed

+147
-3
lines changed

4 files changed

+147
-3
lines changed

test/conformance/tests/fixtures.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
package tests
22

33
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
48
. "github.com/onsi/ginkgo/v2"
59
. "github.com/onsi/gomega"
610

11+
"k8s.io/apimachinery/pkg/api/meta"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"sigs.k8s.io/controller-runtime/pkg/client"
14+
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
15+
16+
sriovv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1"
717
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts"
818
"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/clean"
919
"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/cluster"
@@ -67,3 +77,30 @@ var _ = AfterSuite(func() {
6777
err := clean.All()
6878
Expect(err).NotTo(HaveOccurred())
6979
})
80+
81+
// assertCondition verifies that a SR-IOV resource has the expected condition status.
82+
// Supported object types: *sriovv1.SriovNetwork, *sriovv1.SriovNetworkPoolConfig, *sriovv1.SriovNetworkNodePolicy
83+
func assertCondition(obj client.Object, name, namespace, conditionType string, expectedStatus metav1.ConditionStatus) {
84+
EventuallyWithOffset(1, func(g Gomega) {
85+
err := clients.Get(context.Background(),
86+
runtimeclient.ObjectKey{Name: name, Namespace: namespace}, obj)
87+
g.Expect(err).ToNot(HaveOccurred())
88+
89+
var conditions []metav1.Condition
90+
switch o := obj.(type) {
91+
case *sriovv1.SriovNetwork:
92+
conditions = o.Status.Conditions
93+
case *sriovv1.SriovNetworkPoolConfig:
94+
conditions = o.Status.Conditions
95+
case *sriovv1.SriovNetworkNodePolicy:
96+
conditions = o.Status.Conditions
97+
default:
98+
g.Expect(fmt.Errorf("unsupported object type %T", obj)).ToNot(HaveOccurred())
99+
}
100+
101+
cond := meta.FindStatusCondition(conditions, conditionType)
102+
g.Expect(cond).ToNot(BeNil(), "Condition %s not found on %T %s/%s", conditionType, obj, namespace, name)
103+
g.Expect(cond.Status).To(Equal(expectedStatus),
104+
"Expected condition %s to be %s but got %s", conditionType, expectedStatus, cond.Status)
105+
}, 2*time.Minute, time.Second).Should(Succeed())
106+
}

test/conformance/tests/test_networkpool.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
corev1 "k8s.io/api/core/v1"
1414
"k8s.io/apimachinery/pkg/api/errors"
15+
"k8s.io/apimachinery/pkg/api/meta"
1516
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1617
"sigs.k8s.io/controller-runtime/pkg/client"
1718

@@ -72,6 +73,15 @@ var _ = Describe("[sriov] NetworkPool", Ordered, func() {
7273
By("configure rdma mode to exclusive")
7374
err := clients.Create(context.Background(), networkPool)
7475
Expect(err).ToNot(HaveOccurred())
76+
77+
By("Verifying PoolConfig has matched node")
78+
Eventually(func(g Gomega) {
79+
pool := &sriovv1.SriovNetworkPoolConfig{}
80+
err = clients.Get(context.Background(), client.ObjectKey{Name: testNode, Namespace: operatorNamespace}, pool)
81+
g.Expect(err).ToNot(HaveOccurred())
82+
g.Expect(pool.Status.MatchedNodeCount).To(Equal(1))
83+
}, 2*time.Minute, 5*time.Second).Should(Succeed())
84+
7585
By("waiting for operator to finish the configuration")
7686
WaitForSRIOVStable()
7787
nodeState := &sriovv1.SriovNetworkNodeState{}
@@ -82,6 +92,10 @@ var _ = Describe("[sriov] NetworkPool", Ordered, func() {
8292
g.Expect(nodeState.Status.System.RdmaMode).To(Equal(consts.RdmaSubsystemModeExclusive))
8393
}, 20*time.Minute, 5*time.Second).Should(Succeed())
8494

95+
By("Verifying PoolConfig Ready condition after exclusive mode configuration")
96+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
97+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
98+
8599
By("Checking rdma mode and kernel args")
86100
cmdlineOutput, _, err := runCommandOnConfigDaemon(testNode, "/bin/bash", "-c", "cat /host/proc/cmdline")
87101
errDescription := fmt.Sprintf("kernel args are not right, printing current kernel args %s", cmdlineOutput)
@@ -111,6 +125,10 @@ var _ = Describe("[sriov] NetworkPool", Ordered, func() {
111125
g.Expect(nodeState.Status.System.RdmaMode).To(Equal(consts.RdmaSubsystemModeShared))
112126
}, 20*time.Minute, 5*time.Second).Should(Succeed())
113127

128+
By("Verifying PoolConfig Ready condition after shared mode configuration")
129+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
130+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
131+
114132
By("Checking rdma mode and kernel args")
115133
cmdlineOutput, _, err = runCommandOnConfigDaemon(testNode, "/bin/bash", "-c", "cat /host/proc/cmdline")
116134
errDescription = fmt.Sprintf("kernel args are not right, printing current kernel args %s", cmdlineOutput)
@@ -219,6 +237,10 @@ var _ = Describe("[sriov] NetworkPool", Ordered, func() {
219237
g.Expect(nodeState.Spec.System.RdmaMode).To(Equal(consts.RdmaSubsystemModeExclusive))
220238
g.Expect(nodeState.Status.System.RdmaMode).To(Equal(consts.RdmaSubsystemModeExclusive))
221239
}, 20*time.Minute, 5*time.Second).Should(Succeed())
240+
241+
By("Verifying PoolConfig Ready condition")
242+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
243+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
222244
})
223245

224246
It("should run pod with RDMA cni and expose nic metrics and another one without rdma info", func() {
@@ -347,6 +369,10 @@ var _ = Describe("[sriov] NetworkPool", Ordered, func() {
347369
g.Expect(nodeState.Spec.System.RdmaMode).To(Equal(consts.RdmaSubsystemModeShared))
348370
g.Expect(nodeState.Status.System.RdmaMode).To(Equal(consts.RdmaSubsystemModeShared))
349371
}, 20*time.Minute, 5*time.Second).Should(Succeed())
372+
373+
By("Verifying PoolConfig Ready condition")
374+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
375+
assertCondition(&sriovv1.SriovNetworkPoolConfig{}, testNode, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
350376
})
351377

352378
It("should run pod without RDMA cni and not expose nic metrics", func() {
@@ -372,4 +398,42 @@ var _ = Describe("[sriov] NetworkPool", Ordered, func() {
372398
Expect(num).To(BeNumerically("==", 0))
373399
})
374400
})
401+
402+
Context("PoolConfig Status Conditions Edge Cases", func() {
403+
It("should report NoMatchingNodes when nodeSelector matches nothing", func() {
404+
pool := &sriovv1.SriovNetworkPoolConfig{
405+
ObjectMeta: metav1.ObjectMeta{
406+
Name: "no-match-pool",
407+
Namespace: operatorNamespace,
408+
},
409+
Spec: sriovv1.SriovNetworkPoolConfigSpec{
410+
NodeSelector: &metav1.LabelSelector{
411+
MatchLabels: map[string]string{
412+
"non-existent-label": "value",
413+
},
414+
},
415+
},
416+
}
417+
err := clients.Create(context.Background(), pool)
418+
Expect(err).ToNot(HaveOccurred())
419+
defer func() {
420+
err := clients.Delete(context.Background(), pool)
421+
Expect(err).ToNot(HaveOccurred())
422+
}()
423+
424+
Eventually(func(g Gomega) {
425+
err = clients.Get(context.Background(), client.ObjectKey{
426+
Name: pool.Name,
427+
Namespace: operatorNamespace,
428+
}, pool)
429+
g.Expect(err).ToNot(HaveOccurred())
430+
431+
cond := meta.FindStatusCondition(pool.Status.Conditions, sriovv1.ConditionReady)
432+
g.Expect(cond).ToNot(BeNil())
433+
g.Expect(cond.Status).To(Equal(metav1.ConditionFalse))
434+
g.Expect(cond.Reason).To(Equal(sriovv1.ReasonNoMatchingNodes))
435+
g.Expect(pool.Status.MatchedNodeCount).To(Equal(0))
436+
}, 30*time.Second, 1*time.Second).Should(Succeed())
437+
})
438+
})
375439
})

test/conformance/tests/test_policy_configuration.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
7676
By("waiting the sriov to be stable on the node")
7777
WaitForSRIOVStable()
7878

79+
By("Verifying Policy conditions are set correctly")
80+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, vfioPolicy.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
81+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, vfioPolicy.Name, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
82+
7983
By("waiting for the resources to be available")
8084
Eventually(func() int64 {
8185
testedNode, err := clients.CoreV1Interface.Nodes().Get(context.Background(), vfioNode, metav1.GetOptions{})
@@ -152,7 +156,7 @@ var _ = Describe("[sriov] operator", Ordered, func() {
152156
}
153157
By("Using device " + vfioNic.Name + " on node " + vfioNode)
154158

155-
_, err := network.CreateSriovPolicy(clients, "test-policy-", operatorNamespace, vfioNic.Name+"#2-4", vfioNode, 5, testResourceName, "netdevice")
159+
firstPolicy, err := network.CreateSriovPolicy(clients, "test-policy-", operatorNamespace, vfioNic.Name+"#2-4", vfioNode, 5, testResourceName, "netdevice")
156160
Expect(err).ToNot(HaveOccurred())
157161

158162
Eventually(func() sriovv1.Interfaces {
@@ -177,6 +181,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
177181

178182
WaitForSRIOVStable()
179183

184+
By("Verifying Policy conditions are set correctly")
185+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, firstPolicy.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
186+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, firstPolicy.Name, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
187+
180188
Eventually(func() int64 {
181189
testedNode, err := clients.CoreV1Interface.Nodes().Get(context.Background(), vfioNode, metav1.GetOptions{})
182190
Expect(err).ToNot(HaveOccurred())
@@ -252,7 +260,7 @@ var _ = Describe("[sriov] operator", Ordered, func() {
252260
Expect(err).ToNot(HaveOccurred())
253261
By("Using device " + intf.Name + " on node " + node)
254262

255-
_, err = network.CreateSriovPolicy(clients, "test-policy-", operatorNamespace, intf.Name+"#0-1", node, 5, testResourceName, "netdevice", func(policy *sriovv1.SriovNetworkNodePolicy) {
263+
mtuPartitionPolicy, err := network.CreateSriovPolicy(clients, "test-policy-", operatorNamespace, intf.Name+"#0-1", node, 5, testResourceName, "netdevice", func(policy *sriovv1.SriovNetworkNodePolicy) {
256264
policy.Spec.Mtu = newMtu
257265
})
258266
Expect(err).ToNot(HaveOccurred())
@@ -280,6 +288,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
280288

281289
WaitForSRIOVStable()
282290

291+
By("Verifying Policy conditions are set correctly")
292+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, mtuPartitionPolicy.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
293+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, mtuPartitionPolicy.Name, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
294+
283295
Eventually(func() int64 {
284296
testedNode, err := clients.CoreV1Interface.Nodes().Get(context.Background(), node, metav1.GetOptions{})
285297
Expect(err).ToNot(HaveOccurred())
@@ -403,9 +415,15 @@ var _ = Describe("[sriov] operator", Ordered, func() {
403415
Expect(err).ToNot(HaveOccurred())
404416

405417
By("Creating a netdevice policy")
406-
_, err = network.CreateSriovPolicy(clients, "test-policy-", operatorNamespace, vfioNic.Name+"#2-4", vfioNode, 5, "resnetdevice", "netdevice")
418+
netdevPolicy, err := network.CreateSriovPolicy(clients, "test-policy-", operatorNamespace, vfioNic.Name+"#2-4", vfioNode, 5, "resnetdevice", "netdevice")
407419
Expect(err).ToNot(HaveOccurred())
408420

421+
WaitForSRIOVStable()
422+
423+
By("Verifying Policy conditions are set correctly")
424+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, vfiopolicy.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
425+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, netdevPolicy.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
426+
409427
By("Checking the SriovNetworkNodeState is correctly configured")
410428
assertNodeStateHasVFMatching(vfioNode,
411429
Fields{"VfID": Equal(0), "Driver": Equal("vfio-pci")})
@@ -593,6 +611,11 @@ var _ = Describe("[sriov] operator", Ordered, func() {
593611
Expect(err).ToNot(HaveOccurred())
594612

595613
WaitForSRIOVStable()
614+
615+
By("Verifying Policy conditions are set correctly")
616+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, mtuPolicy.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
617+
assertCondition(&sriovv1.SriovNetworkNodePolicy{}, mtuPolicy.Name, operatorNamespace, sriovv1.ConditionProgressing, metav1.ConditionFalse)
618+
596619
By("waiting for the resources to be available")
597620
Eventually(func() int64 {
598621
testedNode, err := clients.CoreV1Interface.Nodes().Get(context.Background(), node, metav1.GetOptions{})

test/conformance/tests/test_sriov_operator.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
141141
return clients.Get(context.Background(), runtimeclient.ObjectKey{Name: "test-apivolnetwork", Namespace: namespaces.Test}, netAttDef)
142142
}, (10+snoTimeoutMultiplier*110)*time.Second, 1*time.Second).ShouldNot(HaveOccurred())
143143

144+
By("Verifying SriovNetwork conditions are set correctly")
145+
assertCondition(&sriovv1.SriovNetwork{}, sriovNetwork.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
146+
assertCondition(&sriovv1.SriovNetwork{}, sriovNetwork.Name, operatorNamespace, sriovv1.ConditionDegraded, metav1.ConditionFalse)
147+
144148
podDefinition := pod.DefineWithNetworks([]string{sriovNetwork.Name})
145149
created, err := clients.Pods(namespaces.Test).Create(context.Background(), podDefinition, metav1.CreateOptions{})
146150
Expect(err).ToNot(HaveOccurred())
@@ -194,6 +198,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
194198
return clients.Get(context.Background(), runtimeclient.ObjectKey{Name: "test-apivolnetwork", Namespace: namespaces.Test}, netAttDef)
195199
}, (10+snoTimeoutMultiplier*110)*time.Second, 1*time.Second).ShouldNot(HaveOccurred())
196200

201+
By("Verifying SriovNetwork conditions are set correctly")
202+
assertCondition(&sriovv1.SriovNetwork{}, sriovNetwork.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
203+
assertCondition(&sriovv1.SriovNetwork{}, sriovNetwork.Name, operatorNamespace, sriovv1.ConditionDegraded, metav1.ConditionFalse)
204+
197205
podDefinition := pod.DefineWithNetworks([]string{sriovNetwork.Name})
198206
podDefinition.ObjectMeta.Labels = map[string]string{"anyname": "anyvalue"}
199207
created, err := clients.Pods(namespaces.Test).Create(context.Background(), podDefinition, metav1.CreateOptions{})
@@ -323,6 +331,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
323331

324332
validateNetworkFields(copyObj, spoofChkStatusValidation)
325333

334+
By("Verifying SriovNetwork conditions are set correctly")
335+
assertCondition(&sriovv1.SriovNetwork{}, copyObj.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
336+
assertCondition(&sriovv1.SriovNetwork{}, copyObj.Name, operatorNamespace, sriovv1.ConditionDegraded, metav1.ConditionFalse)
337+
326338
By("removing sriov network")
327339
err = clients.Delete(context.Background(), sriovNetwork)
328340
Expect(err).ToNot(HaveOccurred())
@@ -366,6 +378,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
366378

367379
validateNetworkFields(copyObj, trustChkStatusValidation)
368380

381+
By("Verifying SriovNetwork conditions are set correctly")
382+
assertCondition(&sriovv1.SriovNetwork{}, copyObj.Name, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
383+
assertCondition(&sriovv1.SriovNetwork{}, copyObj.Name, operatorNamespace, sriovv1.ConditionDegraded, metav1.ConditionFalse)
384+
369385
By("removing sriov network")
370386
err = clients.Delete(context.Background(), sriovNetwork)
371387
Expect(err).ToNot(HaveOccurred())
@@ -583,6 +599,10 @@ var _ = Describe("[sriov] operator", Ordered, func() {
583599
Expect(err).ToNot(HaveOccurred())
584600
waitForNetAttachDef(sriovNetworkName, ns1)
585601

602+
By("Verifying SriovNetwork conditions are set correctly")
603+
assertCondition(&sriovv1.SriovNetwork{}, sriovNetworkName, operatorNamespace, sriovv1.ConditionReady, metav1.ConditionTrue)
604+
assertCondition(&sriovv1.SriovNetwork{}, sriovNetworkName, operatorNamespace, sriovv1.ConditionDegraded, metav1.ConditionFalse)
605+
586606
srNetwork := &sriovv1.SriovNetwork{}
587607
err = clients.Get(context.Background(), runtimeclient.ObjectKey{Namespace: operatorNamespace, Name: sriovNetworkName}, srNetwork)
588608
Expect(err).ToNot(HaveOccurred())

0 commit comments

Comments
 (0)