Skip to content

Commit 5b7afc1

Browse files
committed
e2e: serial: add serial test for Performance Profile updates and NRT reconciliation
Signed-off-by: Sargun Narula <snarula@redhat.com>
1 parent 182ad86 commit 5b7afc1

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

test/e2e/serial/tests/configuration.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
k8swait "k8s.io/apimachinery/pkg/util/wait"
3636
"k8s.io/klog/v2"
3737
"sigs.k8s.io/controller-runtime/pkg/client"
38+
"sigs.k8s.io/yaml"
3839

3940
"github.com/google/go-cmp/cmp"
4041
depnodes "github.com/k8stopologyawareschedwg/deployer/pkg/clientutil/nodes"
@@ -55,13 +56,16 @@ import (
5556
"github.com/openshift-kni/numaresources-operator/pkg/validation"
5657
rteconfig "github.com/openshift-kni/numaresources-operator/rte/pkg/config"
5758
"github.com/openshift-kni/numaresources-operator/test/e2e/label"
59+
e2eclient "github.com/openshift-kni/numaresources-operator/test/internal/clients"
5860
"github.com/openshift-kni/numaresources-operator/test/internal/configuration"
5961
e2efixture "github.com/openshift-kni/numaresources-operator/test/internal/fixture"
6062
e2enrt "github.com/openshift-kni/numaresources-operator/test/internal/noderesourcetopologies"
6163
"github.com/openshift-kni/numaresources-operator/test/internal/nrosched"
6264
"github.com/openshift-kni/numaresources-operator/test/internal/objects"
6365

6466
serialconfig "github.com/openshift-kni/numaresources-operator/test/e2e/serial/config"
67+
"github.com/openshift-kni/numaresources-operator/test/internal/hypershift"
68+
"github.com/openshift-kni/numaresources-operator/test/internal/nodepools"
6569
)
6670

6771
/*
@@ -83,6 +87,14 @@ type mcpInfo struct {
8387
sampleNode corev1.Node
8488
}
8589

90+
type Tuning struct {
91+
Profile struct {
92+
CPU struct {
93+
TopologyManagerPolicy string `yaml:"topologyManagerPolicy"`
94+
} `yaml:"cpu"`
95+
} `yaml:"profile"`
96+
}
97+
8698
func (i mcpInfo) ToString() string {
8799
mcpname := ""
88100
if i.mcpObj != nil {
@@ -285,6 +297,90 @@ var _ = Describe("[serial][disruptive] numaresources configuration management",
285297
Expect(schedOK).To(BeTrue(), "pod %s/%s not scheduled with expected scheduler %s", updatedPod.Namespace, updatedPod.Name, serialconfig.SchedulerTestName)
286298
})
287299

300+
It("[test_id:80821] Verify Performance Profile updates on management cluster reflect in NRT resources", Label("reboot_required", label.Slow, label.HyperShift), func() {
301+
fxt.IsRebootTest = true
302+
303+
By("fetching the initial TM policy set in NRT")
304+
initialNrtList := nrtv1alpha2.NodeResourceTopologyList{}
305+
initialNrtList, err := e2enrt.GetUpdated(fxt.Client, initialNrtList, timeout)
306+
Expect(err).ToNot(HaveOccurred(), "cannot get any NodeResourceTopology object from the cluster")
307+
Expect(initialNrtList.Items).ToNot(BeEmpty(), "no NodeResourceTopology items found")
308+
309+
initialNrt := initialNrtList.Items[0]
310+
var initialTMPolicy string
311+
for _, attr := range initialNrt.Attributes {
312+
if attr.Name == "topologyManagerPolicy" {
313+
initialTMPolicy = attr.Value
314+
break
315+
}
316+
}
317+
Expect(initialTMPolicy).ToNot(BeEmpty(), "topologyManagerPolicy not found in initial NRT")
318+
newTMPolicy := getNewTopologyManagerPolicyValue(initialTMPolicy)
319+
Expect(initialTMPolicy).ToNot(Equal(newTMPolicy), "new TM policy should differ from the initial one")
320+
321+
By("retrieving the PerformanceProfile configmap from the management cluster")
322+
hostedClusterName, err := hypershift.GetHostedClusterName()
323+
Expect(err).ToNot(HaveOccurred())
324+
nodePool, err := nodepools.GetByClusterName(context.TODO(), e2eclient.MNGClient, hostedClusterName)
325+
Expect(err).ToNot(HaveOccurred())
326+
327+
By("validating the tuningConfig name against ConfigMaps in the management cluster")
328+
tuningConfigName := nodePool.Spec.TuningConfig[0].Name
329+
Expect(tuningConfigName).ToNot(BeEmpty(), "NodePool tuningConfig name is empty")
330+
331+
cmList := &corev1.ConfigMapList{}
332+
err = e2eclient.MNGClient.List(context.TODO(), cmList, &client.ListOptions{
333+
Namespace: "clusters",
334+
})
335+
Expect(err).ToNot(HaveOccurred(), "failed to list ConfigMaps in namespace: clusters")
336+
337+
var targetCM *corev1.ConfigMap
338+
for i := range cmList.Items {
339+
if cmList.Items[i].Name == tuningConfigName {
340+
targetCM = &cmList.Items[i]
341+
break
342+
}
343+
}
344+
Expect(targetCM).ToNot(BeNil(), fmt.Sprintf("ConfigMap %q not found in namespace: clusters", tuningConfigName))
345+
346+
By("updating the ConfigMap with the new TM policy")
347+
yamlData := targetCM.Data["tuning"]
348+
Expect(yamlData).ToNot(BeEmpty(), "tuning section not found in ConfigMap")
349+
350+
var tuning Tuning
351+
err = yaml.Unmarshal([]byte(yamlData), &tuning)
352+
Expect(err).ToNot(HaveOccurred(), "failed to unmarshal ConfigMap tuning YAML")
353+
Expect(tuning.Profile.CPU.TopologyManagerPolicy).To(Equal(initialTMPolicy), "unexpected initial TM policy in parsed YAML")
354+
355+
tuning.Profile.CPU.TopologyManagerPolicy = newTMPolicy
356+
357+
modifiedYamlBytes, err := yaml.Marshal(&tuning)
358+
Expect(err).ToNot(HaveOccurred(), "failed to marshal modified tuning YAML")
359+
modifiedYaml := string(modifiedYamlBytes)
360+
Expect(modifiedYaml).ToNot(Equal(yamlData), "no changes applied to ConfigMap YAML")
361+
362+
targetCM.Data["tuning"] = modifiedYaml
363+
err = e2eclient.MNGClient.Update(context.TODO(), targetCM)
364+
Expect(err).ToNot(HaveOccurred(), "failed to update the ConfigMap with new TM policy")
365+
366+
By("waiting for the NRT to reflect the new TM policy")
367+
Eventually(func(g Gomega) {
368+
updatedNrtList := nrtv1alpha2.NodeResourceTopologyList{}
369+
updatedNrtList, err = e2enrt.GetUpdated(fxt.Client, updatedNrtList, timeout)
370+
g.Expect(err).ToNot(HaveOccurred())
371+
g.Expect(updatedNrtList.Items).ToNot(BeEmpty())
372+
373+
var updatedTM string
374+
for _, attr := range updatedNrtList.Items[0].Attributes {
375+
if attr.Name == "topologyManagerPolicy" {
376+
updatedTM = attr.Value
377+
break
378+
}
379+
}
380+
g.Expect(updatedTM).To(Equal(newTMPolicy), "Expected updated TM policy %q, but got %q", newTMPolicy, updatedTM)
381+
}, 10*time.Minute, 25*time.Second).Should(Succeed(), "NRT did not reflect updated TM policy in time")
382+
})
383+
288384
It("should report the NodeGroupConfig in the status", Label("tier2", "openshift"), func() {
289385
nroKey := objects.NROObjectKey()
290386
nroOperObj := nropv1.NUMAResourcesOperator{}
@@ -732,6 +828,14 @@ func objRefListToStringList(objRefs []configv1.ObjectReference) []string {
732828
return ret
733829
}
734830

831+
func getNewTopologyManagerPolicyValue(oldTopologyManagerPolicyValue string) string {
832+
newTopologyManagerPolicyValue := "best-effort"
833+
if oldTopologyManagerPolicyValue == newTopologyManagerPolicyValue || oldTopologyManagerPolicyValue == "" {
834+
newTopologyManagerPolicyValue = "single-numa-node"
835+
}
836+
return newTopologyManagerPolicyValue
837+
}
838+
735839
func toJSON(obj interface{}) string {
736840
data, err := json.Marshal(obj)
737841
if err != nil {

0 commit comments

Comments
 (0)