Skip to content

OCPBUGS-55989: E2E: Functional tests for align cpus by UncoreCache Feature - #1302

Merged
openshift-merge-bot[bot] merged 10 commits into
openshift:mainfrom
mrniranjan:llc_take2
May 13, 2025
Merged

OCPBUGS-55989: E2E: Functional tests for align cpus by UncoreCache Feature #1302
openshift-merge-bot[bot] merged 10 commits into
openshift:mainfrom
mrniranjan:llc_take2

Conversation

@mrniranjan

@mrniranjan mrniranjan commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

This PR adds Functional test to UncoreCache CPUManager policy options feature.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 4, 2025
@mrniranjan
mrniranjan marked this pull request as draft March 4, 2025 07:18
@openshift-ci
openshift-ci Bot requested review from ffromani and yanirq March 4, 2025 07:19
@mrniranjan
mrniranjan force-pushed the llc_take2 branch 4 times, most recently from 0259989 to 09870a6 Compare March 5, 2025 06:04
@mrniranjan mrniranjan closed this Apr 2, 2025
@mrniranjan mrniranjan reopened this Apr 2, 2025
@mrniranjan
mrniranjan marked this pull request as ready for review April 2, 2025 13:32
@mrniranjan mrniranjan changed the title [wip] E2E: Functional tests for align cpus by UncoreCache Feature E2E: Functional tests for align cpus by UncoreCache Feature Apr 2, 2025
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 2, 2025
@openshift-ci
openshift-ci Bot requested a review from swatisehgal April 2, 2025 13:35
// be running, so in the test we check if the deployment has reached the desiredStatus before
// quering its pods
func WaitForDesiredDeploymentStatus(ctx context.Context, deployment *appsv1.Deployment, cli client.Client, namespace, name string, desiredStatus appsv1.DeploymentStatus) error {
return wait.PollUntilContextTimeout(context.TODO(), 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ctx here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

Comment on lines +55 to +57
func TaggedInfof(tag string, format string, args ...interface{}) {
logf("[INFO]", fmt.Sprintf("[%s] %s", tag, format), args...)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a fan, we should use contextual logging, but for the time being I guess we can use this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack


// GetL3SharedCPUs creates a function that retrieves cpus for a given Node
// takes a worker cnf node and returns a closure when called with cpuId returns
// the corresponding cpus of core complex to which cpuId is part of

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the benefit of returning a closure?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benefit is i can call the GetL3SharedCPU's once with actual node and fetch the shared L3 CPU multiple times without the need to pass the node information everytime and also i can re use the same code if there are multiple nodes. In some test cases where we have multiple pods or multiple containers per pods , i think this would be helpful

Expect(err).ToNot(HaveOccurred())
ctx := context.Background()
for _, cnfnode := range workerRTNodes {
numaInfo, err := nodes.GetNumaNodes(context.TODO(), &cnfnode)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ctx here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

// Modify the profile such that we give 1 whole ccx to reserved cpus
By("Modifying the profile")
for _, node := range workerRTNodes {
numaCoreSiblings, err = nodes.GetCoreSiblings(context.TODO(), &node)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ctx here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

// Assign one whole L3 Cache group for reserved cpus.
for reservedCores := 0; reservedCores < 8; reservedCores++ {
cpusiblings := nodes.GetAndRemoveCpuSiblingsFromMap(numaCoreSiblings, reservedCores)
reserved = append(reserved, cpusiblings...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use a cpuset?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean to use cpuset.CPUset ?, Performance profile expects reserved and isolated to be of type string
https://github.com/openshift/cluster-node-tuning-operator/blob/81e7ec52274d/pkg/apis/performanceprofile/v2/performanceprofile_types.go#L95

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we can use a cpuset for higher level operations on it and translate to string only when needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ffromani To convert, i need to first modify https://github.com/openshift/cluster-node-tuning-operator/blob/main/test/e2e/performanceprofile/functests/utils/nodes/nodes.go#L389 to return []int and then convert to cpuset.cpu using cpuset.new([]int..)

I can do it but this will break all the existing automation , i can address this in another PR if that's okay with you.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ffromani i have created another PR for addressing this: #1321

err := testclient.DataPlaneClient.Delete(ctx, dp)
Expect(err).ToNot(HaveOccurred())
// Wait for some time for deployment to be deleted
time.Sleep(deploymentDeletionTime)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be better to check the pod to be gone, sleeps tend to fail randomly creating hard to debug issues

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

testlog.TaggedInfof("L3 Cache Group", "L3 Cache group associated with Pod %s using cpu %d is: %q", testpod.Name, cgroupCpuset.List()[0], cpus)
})

It("[test_id:77726] Multiple Pods are not sharing same L3 cache", func() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this may be possible per the latest KEP though, we need to check against the KEP goals/non-goals

@mrniranjan
mrniranjan force-pushed the llc_take2 branch 2 times, most recently from 55148e2 to cf52930 Compare April 10, 2025 20:56
@mrniranjan

Copy link
Copy Markdown
Contributor Author

/retest-required

@mrniranjan

Copy link
Copy Markdown
Contributor Author

/test okd-scos-e2e-aws-ovn

// Assign one whole L3 Cache group for reserved cpus.
for reservedCores := 0; reservedCores < 8; reservedCores++ {
cpusiblings := nodes.GetAndRemoveCpuSiblingsFromMap(numaCoreSiblings, reservedCores)
reserved = append(reserved, cpusiblings...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we can use a cpuset for higher level operations on it and translate to string only when needed.

})

It("[test_id:77725] Align Guaranteed pod requesting 16 cpus to the whole CCX if available", func() {
ctx := context.Background()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can get a context from ginkgo:

It("[test_id:77725] Align Guaranteed pod requesting 16 cpus to the whole CCX if available", func(ctx context.Context) {

we will need to handle interruptions, but that's a good thing to do anyway

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

cpusetCfg := &controller.CpuSet{}
deploymentName := "test-deployment1"
rl := &corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("16"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how 16 was decided? can't we use the CCX size? we should never assume the CCX size is 16

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

})

It("[test_id:77725] Verify guaranteed pod consumes the whole Uncore group after reboot", func() {
ctx := context.Background()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

deploymentName := "test-deployment2"
getCCX := nodes.GetL3SharedCPUs(&targetNode)
rl := &corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("16"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the latest commit

@mrniranjan

Copy link
Copy Markdown
Contributor Author

/test okd-scos-e2e-aws-ovn

@ffromani ffromani left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

almost there

Comment on lines +250 to +251
// Get cpu siblings from core 0-7
// Assign one whole L3 Cache group for reserved cpus.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit fragile but without machineinfo or similar is challenging to improve

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, for now i have used cpuset.CPUSet . addressed in the latest commit

testlog.TaggedInfof("L3 Cache Group", "L3 Cache group associated with Pod %s using cpu %d is %q: ", testpod.Name, cgroupCpuset.List()[0], cpus)
})

It("[test_id:77725] Verify guaranteed pod consumes the whole Uncore group after kubelet restart", func(ctx context.Context) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can safely infer this invariant from other tests though. If the CPU assignment doesn't change across kubelet restart, because how the silicon phisically is, then the L3 affinity/assignment can't change either.

I guess we should keep this test for the sake of being explicity though.


It("[test_id:77726] Multiple Pods are not sharing same L3 cache", func(ctx context.Context) {
targetNode := workerRTNodes[0]
// create 2 deployments creating 2 gu pods asking for 8 cpus each

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should ask for number of cpus in a L3 group size /2 rather than hardcode 8

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in latest commit

testlog.TaggedInfof("L3 Cache Group", "L3 Cache group associated with Pod %s using cpu %d is: %q", testpod.Name, cgroupCpuset.List()[0], cpus)
})

It("[test_id:77726] Multiple Pods are not sharing same L3 cache", func(ctx context.Context) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the test name must be changed because comments at the bottom of the test acknowledge pods can indeed share the same L3 block

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in latest commit

@mrniranjan
mrniranjan force-pushed the llc_take2 branch 2 times, most recently from be0c3dc to 9963e02 Compare April 16, 2025 13:34
@mrniranjan

Copy link
Copy Markdown
Contributor Author

/retest-required

Add function WaitForDesiredDeploymentStatus to wait
for deployment to be in the desired status. This is
needed in cases where we reboot the node and want
to ascertain if the deployment has reached the desired
status

Minor fix: use existing context variable instead of creating
new context

Signed-off-by: Niranjan M.R <mrniranjan@redhat.com>
Signed-off-by: Niranjan M.R <mrniranjan@redhat.com>
cpus.

Signed-off-by: Niranjan M.R <mrniranjan@redhat.com>
Instead of using hard coded value , fetch the value
of L3 Cache group size and  use that value for the
guaranteed pod that we create

Signed-off-by: Niranjan M.R <mrniranjan@redhat.com>
Signed-off-by: Niranjan M.R <mrniranjan@redhat.com>
Use cpuset.CPUSet type for all reserved, isolated
variables when modifying performance profile

Signed-off-by: Niranjan M.R <mrniranjan@redhat.com>
Uncomment lines related to saving initialProfile

Signed-off-by: Niranjan M.R <mrniranjan@redhat.com>
@mrniranjan

Copy link
Copy Markdown
Contributor Author

/retest-required

@ffromani ffromani left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/approve
/lgtm

we can improve later if needed

llcPolicy string
mc *machineconfigv1.MachineConfig
getter cgroup.ControllersGetter
cgroupV2 bool

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can this a local variable in BeforeAll?

getCCX := nodes.GetL3SharedCPUs(&cnfnode)
reserved, err = getCCX(0)
Expect(err).ToNot(HaveOccurred())
onlineCPUSet, err = nodes.GetOnlineCPUsSet(context.TODO(), &cnfnode)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should use ctx

Comment on lines +260 to +261
By(fmt.Sprintf("Applying changes in performance profile and waiting until %s will start updating", poolName))
profilesupdate.WaitForTuningUpdating(ctx, profile)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this wait is proven fragile though. A better approach seems to be to record the object ResourceVersion, then send the update, then wait for the object to become Updated with resourceVersion != oldResourceVersion

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label May 8, 2025
@openshift-ci

openshift-ci Bot commented May 8, 2025

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ffromani, mrniranjan

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 8, 2025
@mrniranjan mrniranjan changed the title E2E: Functional tests for align cpus by UncoreCache Feature OCPBUGS-55989: E2E: Functional tests for align cpus by UncoreCache Feature May 9, 2025
@openshift-ci-robot openshift-ci-robot added jira/severity-low Referenced Jira bug's severity is low for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels May 9, 2025
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@mrniranjan: This pull request references Jira Issue OCPBUGS-55989, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.20.0) matches configured target version for branch (4.20.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @mrniranjan

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

This PR adds Functional test to UncoreCache CPUManager policy options feature.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci

openshift-ci Bot commented May 9, 2025

Copy link
Copy Markdown
Contributor

@openshift-ci-robot: GitHub didn't allow me to request PR reviews from the following users: mrniranjan.

Note that only openshift members and repo collaborators can review this PR, and authors cannot review their own PRs.

Details

In response to this:

@mrniranjan: This pull request references Jira Issue OCPBUGS-55989, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.20.0) matches configured target version for branch (4.20.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @mrniranjan

The bug has been updated to refer to the pull request using the external bug tracker.

In response to this:

This PR adds Functional test to UncoreCache CPUManager policy options feature.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@yanirq

yanirq commented May 12, 2025

Copy link
Copy Markdown
Contributor

/retest-required

@openshift-ci-robot

Copy link
Copy Markdown
Contributor

/retest-required

Remaining retests: 0 against base HEAD a3371e1 and 2 for PR HEAD 893e5eb in total

1 similar comment
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

/retest-required

Remaining retests: 0 against base HEAD a3371e1 and 2 for PR HEAD 893e5eb in total

@openshift-ci

openshift-ci Bot commented May 13, 2025

Copy link
Copy Markdown
Contributor

@mrniranjan: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 488ca89 into openshift:main May 13, 2025
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@mrniranjan: Jira Issue OCPBUGS-55989: All pull requests linked via external trackers have merged:

Jira Issue OCPBUGS-55989 has been moved to the MODIFIED state.

Details

In response to this:

This PR adds Functional test to UncoreCache CPUManager policy options feature.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-bot

Copy link
Copy Markdown
Contributor

[ART PR BUILD NOTIFIER]

Distgit: cluster-node-tuning-operator
This PR has been included in build cluster-node-tuning-operator-container-v4.20.0-202505140744.p0.g488ca89.assembly.stream.el9.
All builds following this will include this PR.

@mrniranjan

Copy link
Copy Markdown
Contributor Author

/cherry-pick release-4.19

@openshift-cherrypick-robot

Copy link
Copy Markdown

@mrniranjan: new pull request created: #1336

Details

In response to this:

/cherry-pick release-4.19

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/severity-low Referenced Jira bug's severity is low for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants