From 45c1746f0d75f91d895ef60ce3f07e111e45cfa0 Mon Sep 17 00:00:00 2001 From: Talor Itzhak Date: Thu, 16 Oct 2025 18:16:56 +0300 Subject: [PATCH 1/2] e2e: check PerformanceProfile replacement Check that PerformanceProfile replacement doesn't add additional configmap status. This test is excersing the bug to avoid regressions in the future. Signed-off-by: Talor Itzhak --- .../functests/0_config/config.go | 2 +- .../functests/3_performance_status/status.go | 75 ++++++++++++++++++- .../functests/utils/hypershift/hypershift.go | 4 +- .../functests/utils/nodepools/nodepools.go | 20 +++++ 4 files changed, 97 insertions(+), 4 deletions(-) diff --git a/test/e2e/performanceprofile/functests/0_config/config.go b/test/e2e/performanceprofile/functests/0_config/config.go index 5b302e3600..2335244cfc 100644 --- a/test/e2e/performanceprofile/functests/0_config/config.go +++ b/test/e2e/performanceprofile/functests/0_config/config.go @@ -264,7 +264,7 @@ func printEnvs() { name, _ := os.LookupEnv(hypershift.HostedClusterNameEnv) testlog.Infof("%s=%s", hypershift.HostedClusterNameEnv, name) - v, _ := hypershift.GetManagementClusterNamespace() + v, _ := hypershift.GetHostedControlPlaneNamespace() testlog.Infof("%s=%s", hypershift.HostedControlPlaneNamespaceEnv, v) kcPath, _ := os.LookupEnv(hypershift.ManagementClusterKubeConfigEnv) diff --git a/test/e2e/performanceprofile/functests/3_performance_status/status.go b/test/e2e/performanceprofile/functests/3_performance_status/status.go index 5806a6a2ef..147f4dc6eb 100644 --- a/test/e2e/performanceprofile/functests/3_performance_status/status.go +++ b/test/e2e/performanceprofile/functests/3_performance_status/status.go @@ -3,11 +3,12 @@ package __performance_status import ( "context" "encoding/json" + "fmt" "time" "github.com/onsi/gomega/gcustom" types2 "github.com/onsi/gomega/types" - tunedutils "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/tuned" + "k8s.io/apimachinery/pkg/labels" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -21,8 +22,11 @@ import ( ign2types "github.com/coreos/ignition/config/v2_2/types" machineconfigv1 "github.com/openshift/api/machineconfiguration/v1" + performancev2 "github.com/openshift/cluster-node-tuning-operator/pkg/apis/performanceprofile/v2" tunedv1 "github.com/openshift/cluster-node-tuning-operator/pkg/apis/tuned/v1" "github.com/openshift/cluster-node-tuning-operator/pkg/performanceprofile/controller/performanceprofile/components" + "github.com/openshift/cluster-node-tuning-operator/pkg/performanceprofile/controller/performanceprofile/hypershift" + hypershiftconsts "github.com/openshift/cluster-node-tuning-operator/pkg/performanceprofile/controller/performanceprofile/hypershift/consts" testutils "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils" testclient "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/client" "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/discovery" @@ -32,6 +36,7 @@ import ( "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/nodepools" "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/nodes" "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/profiles" + tunedutils "github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/tuned" v1 "github.com/openshift/custom-resource-status/conditions/v1" ) @@ -139,6 +144,74 @@ var _ = Describe("Status testing of performance profile", Ordered, func() { profiles.WaitForCondition(testutils.NodeSelectorLabels, v1.ConditionDegraded, corev1.ConditionTrue) }) }) + + Context("Hypershift specific status validation", Label(string(label.HyperShift)), func() { + var profile *performancev2.PerformanceProfile + ctx := context.Background() + BeforeEach(func() { + profile, err = profiles.GetByNodeLabels(testutils.NodeSelectorLabels) + Expect(err).ToNot(HaveOccurred()) + }) + + It("Should have ConfigMap status when running on HyperShift platform", Label(string(label.HyperShift)), func() { + hcpNs, err := hypershiftutils.GetHostedControlPlaneNamespace() + Expect(err).ToNot(HaveOccurred()) + + np, err := nodepools.GetNodePool(ctx, testclient.ControlPlaneClient) + Expect(err).ToNot(HaveOccurred()) + + cm := &corev1.ConfigMap{} + cmName := hypershift.GetStatusConfigMapName(fmt.Sprintf("%s-%s", profile.GetName(), np.GetName())) + key := client.ObjectKey{Namespace: hcpNs, Name: cmName} + Expect(testclient.ControlPlaneClient.Get(ctx, key, cm)).To(Succeed(), "failed to find ConfigMap %s/%s", hcpNs, cmName) + }) + + It("Should not create more than a single ConfigMap status per nodePool when PerformanceProfile gets replace or updated", Label(string(label.HyperShift)), func() { + hcpNs, err := hypershiftutils.GetHostedControlPlaneNamespace() + Expect(err).ToNot(HaveOccurred()) + + np, err := nodepools.GetNodePool(ctx, testclient.ControlPlaneClient) + Expect(err).ToNot(HaveOccurred()) + + newProfile := profile.DeepCopy() + newProfile.Name = fmt.Sprintf("%s-2", profile.Name) + Expect(testclient.ControlPlaneClient.Create(ctx, newProfile)).To(Succeed()) + + // Cleanup: revert back to the original profile and delete the temporary one + defer func() { + By("Reverting back to the original profile") + Expect(nodepools.ReplaceTuningObject(ctx, testclient.ControlPlaneClient, profile, newProfile)).To(Succeed()) + + By("Waiting for node pool configuration to revert") + Expect(nodepools.WaitForConfigToBeReady(ctx, testclient.ControlPlaneClient, np.Name, np.Namespace)).To(Succeed()) + + By("Deleting the temporary profile") + Expect(testclient.ControlPlaneClient.Delete(ctx, newProfile)).To(Succeed()) + }() + + Expect(nodepools.ReplaceTuningObject(ctx, testclient.ControlPlaneClient, newProfile, profile)).To(Succeed()) + + // nothing changed in the profile but the name, so the nodepool will be transition into updating state for a really + // short time. + // to make sure it's not being missing, the test will only wait for updated state. + By("Waiting to see no more than a single configmap status created") + Consistently(func() { + cmList := &corev1.ConfigMapList{} + opts := &client.ListOptions{ + Namespace: hcpNs, + LabelSelector: labels.SelectorFromSet(map[string]string{ + hypershiftconsts.NTOGeneratedPerformanceProfileStatusConfigMapLabel: "true", + hypershiftconsts.NodePoolNameLabel: np.GetName(), + }), + } + Expect(testclient.ControlPlaneClient.List(ctx, cmList, opts)).To(Succeed()) + Expect(cmList.Items).To(HaveLen(1), "More than a single ConfigMap status was found") + }).WithPolling(time.Second * 10).WithTimeout(time.Minute * 2) + + By("Waiting for the node pool configuration to be ready") + Expect(nodepools.WaitForConfigToBeReady(ctx, testclient.ControlPlaneClient, np.Name, np.Namespace)).To(Succeed()) + }) + }) }) func createBadMachineConfig(name string) *machineconfigv1.MachineConfig { diff --git a/test/e2e/performanceprofile/functests/utils/hypershift/hypershift.go b/test/e2e/performanceprofile/functests/utils/hypershift/hypershift.go index 3ef961cfb1..977f36fc72 100644 --- a/test/e2e/performanceprofile/functests/utils/hypershift/hypershift.go +++ b/test/e2e/performanceprofile/functests/utils/hypershift/hypershift.go @@ -34,7 +34,7 @@ func BuildControlPlaneClient() (client.Client, error) { if err != nil { return nil, err } - ns, err := GetManagementClusterNamespace() + ns, err := GetHostedControlPlaneNamespace() if err != nil { return nil, fmt.Errorf("failed to build management-cluster client for hypershift; err %v", err) } @@ -57,7 +57,7 @@ func GetHostedClusterName() (string, error) { return v, nil } -func GetManagementClusterNamespace() (string, error) { +func GetHostedControlPlaneNamespace() (string, error) { ns, ok := os.LookupEnv(HostedControlPlaneNamespaceEnv) if !ok { return "", fmt.Errorf("failed to retrieve management cluster namespace; %q environment var is not set", HostedControlPlaneNamespaceEnv) diff --git a/test/e2e/performanceprofile/functests/utils/nodepools/nodepools.go b/test/e2e/performanceprofile/functests/utils/nodepools/nodepools.go index fe61fb868e..4f84de3f4f 100644 --- a/test/e2e/performanceprofile/functests/utils/nodepools/nodepools.go +++ b/test/e2e/performanceprofile/functests/utils/nodepools/nodepools.go @@ -156,6 +156,26 @@ func AttachTuningObjectToNodePool(ctx context.Context, cli client.Client, object return nil } +// ReplaceTuningObject works similar to AttachTuningObject but replaces one object with another instead of appending +func ReplaceTuningObject(ctx context.Context, cli client.Client, newObject, oldObject client.Object) error { + var err error + np, err := GetNodePool(ctx, cli) + if err != nil { + return err + } + + updatedTuningConfig := corev1.LocalObjectReference{Name: newObject.GetName()} + for i, tuningConfig := range np.Spec.TuningConfig { + if tuningConfig.Name == oldObject.GetName() { + np.Spec.TuningConfig[i] = updatedTuningConfig + } + } + if cli.Update(ctx, np) != nil { + return err + } + return nil +} + func DeattachTuningObject(ctx context.Context, cli client.Client, object client.Object) error { np, err := GetNodePool(ctx, cli) if err != nil { From 3e57d6daccb5edfed24f57d47c098562b0e01a15 Mon Sep 17 00:00:00 2001 From: Talor Itzhak Date: Tue, 4 Nov 2025 14:39:48 +0200 Subject: [PATCH 2/2] makefile: filter hypershift tests from the non-hypershift lane Signed-off-by: Talor Itzhak --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9b3850f80e..14368a79fd 100644 --- a/Makefile +++ b/Makefile @@ -220,7 +220,7 @@ pao-functests-updating-profile: cluster-label-worker-cnf pao-functests-update-on pao-functests-update-only: $(BINDATA) @echo "Cluster Version" hack/show-cluster-version.sh - hack/run-test.sh -t "test/e2e/performanceprofile/functests/0_config test/e2e/performanceprofile/functests/2_performance_update test/e2e/performanceprofile/functests/3_performance_status test/e2e/performanceprofile/functests/7_performance_kubelet_node test/e2e/performanceprofile/functests/9_reboot test/e2e/performanceprofile/functests/13_llc" -p "-v -r --fail-fast --flake-attempts=2 --timeout=5h --junit-report=report.xml" -m "Running Functional Tests" + hack/run-test.sh -t "test/e2e/performanceprofile/functests/0_config test/e2e/performanceprofile/functests/2_performance_update test/e2e/performanceprofile/functests/3_performance_status test/e2e/performanceprofile/functests/7_performance_kubelet_node test/e2e/performanceprofile/functests/9_reboot test/e2e/performanceprofile/functests/13_llc" -p "-v -r --label-filter=!(hypershift) --fail-fast --flake-attempts=2 --timeout=5h --junit-report=report.xml" -m "Running Functional Tests" .PHONY: pao-functests-update-only-hypershift pao-functests-update-only-hypershift: $(BINDATA)