@@ -12,7 +12,6 @@ import (
1212
1313 appsv1 "k8s.io/api/apps/v1"
1414 corev1 "k8s.io/api/core/v1"
15- "k8s.io/apimachinery/pkg/api/errors"
1615 "k8s.io/apimachinery/pkg/api/resource"
1716 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1817 "k8s.io/apimachinery/pkg/labels"
@@ -247,7 +246,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
247246 })
248247
249248 AfterEach (func () {
250- deleteTestPod ( context .TODO (), testpod )
249+ Expect ( pods . Delete ( context .TODO (), testpod )). To ( BeTrue (), "Failed to delete pod" )
251250 })
252251
253252 DescribeTable ("Verify CPU usage by stress PODs" , func (ctx context.Context , guaranteed bool ) {
@@ -338,7 +337,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
338337 Expect (err ).ToNot (HaveOccurred ())
339338 })
340339 AfterEach (func () {
341- deleteTestPod ( context .TODO (), testpod )
340+ Expect ( pods . Delete ( context .TODO (), testpod )). To ( BeTrue (), "Failed to delete pod" )
342341 })
343342 When ("kubelet is restart" , func () {
344343 It ("[test_id: 73501] defaultCpuset should not change" , func () {
@@ -421,7 +420,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
421420
422421 AfterEach (func () {
423422 if testpod != nil {
424- deleteTestPod ( context .TODO (), testpod )
423+ Expect ( pods . Delete ( context .TODO (), testpod )). To ( BeTrue (), "Failed to delete pod" )
425424 }
426425 })
427426
@@ -480,7 +479,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
480479 fmt .Sprintf ("IRQ still active on CPU%s" , psr ))
481480
482481 By ("Checking that after removing POD default smp affinity is returned back to all active CPUs" )
483- deleteTestPod ( context .TODO (), testpod )
482+ Expect ( pods . Delete ( context .TODO (), testpod )). To ( BeTrue (), "Failed to delete pod" )
484483 defaultSmpAffinitySet , err = nodes .GetDefaultSmpAffinitySet (context .TODO (), workerRTNode )
485484 Expect (err ).ToNot (HaveOccurred ())
486485
@@ -579,7 +578,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
579578 if testpod == nil {
580579 return
581580 }
582- deleteTestPod ( context .TODO (), testpod )
581+ Expect ( pods . Delete ( context .TODO (), testpod )). To ( BeTrue (), "Failed to delete pod" )
583582 })
584583
585584 It ("[test_id:49149] should reject pods which request integral CPUs not aligned with machine SMT level" , func () {
@@ -632,7 +631,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
632631 if testpod == nil {
633632 return
634633 }
635- deleteTestPod ( context .TODO (), testpod )
634+ Expect ( pods . Delete ( context .TODO (), testpod )). To ( BeTrue (), "Failed to delete pod" )
636635 })
637636
638637 DescribeTable ("Verify Hyper-Thread aware scheduling for guaranteed pods" ,
@@ -679,7 +678,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
679678 testpod = startHTtestPod (ctx , cpuCount )
680679 Expect (checkPodHTSiblings (ctx , testpod )).To (BeTrue (), "Pod cpu set does not map to host cpu sibling pairs" )
681680 By ("Deleting test pod..." )
682- deleteTestPod ( ctx , testpod )
681+ Expect ( pods . Delete ( ctx , testpod )). To ( BeTrue (), "Failed to delete pod" )
683682 }
684683 },
685684
@@ -982,7 +981,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
982981 defer func () {
983982 if guaranteedPod != nil {
984983 testlog .Infof ("deleting pod %q" , guaranteedPod .Name )
985- deleteTestPod ( ctx , guaranteedPod )
984+ Expect ( pods . Delete ( ctx , guaranteedPod )). To ( BeTrue (), "Failed to delete guaranteed pod" )
986985 }
987986 }()
988987
@@ -1013,7 +1012,7 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
10131012 defer func () {
10141013 if bestEffortPod != nil {
10151014 testlog .Infof ("deleting pod %q" , bestEffortPod .Name )
1016- deleteTestPod ( ctx , bestEffortPod )
1015+ Expect ( pods . Delete ( ctx , bestEffortPod )). To ( BeTrue (), "Failed to delete best-effort pod" )
10171016 }
10181017 }()
10191018
@@ -1067,6 +1066,63 @@ var _ = Describe("[rfe_id:27363][performance] CPU Management", Ordered, func() {
10671066 })
10681067 })
10691068
1069+ Context ("Check exec-cpu-affinity feature" , func () {
1070+ When ("exec-cpu-affinity is enabled (default in PP)" , func () {
1071+ // shared-cpus case is covered in 11_mixedcpus test
1072+ // legacy test is covered in 2_performance_update
1073+
1074+ BeforeEach (func () {
1075+ By ("Checking if exec-cpu-affinity is enabled by default in the profile" )
1076+ profile , _ := profiles .GetByNodeLabels (testutils .NodeSelectorLabels )
1077+ Expect (profile ).ToNot (BeNil (), "Failed to get performance profile" )
1078+ if profile .Annotations != nil {
1079+ val , ok := profile .Annotations [performancev2 .PerformanceProfileDisableExecCPUAffinityAnnotation ]
1080+ if ok && val == "true" {
1081+ // fail loadly because the default should be enabled
1082+ Fail ("exec-cpu-affinity is disabled in the profile" )
1083+ }
1084+ }
1085+ })
1086+
1087+ It ("should pin exec process to first CPU dedicated to the container - guratanteed pod" , func () {
1088+ By ("Creating a guaranteed test pod" )
1089+ testPod := makePod (ctx , workerRTNode , true )
1090+ Expect (testclient .Client .Create (ctx , testPod )).To (Succeed (), "Failed to create test pod" )
1091+ testPod , err = pods .WaitForCondition (ctx , client .ObjectKeyFromObject (testPod ), corev1 .PodReady , corev1 .ConditionTrue , 5 * time .Minute )
1092+ Expect (err ).ToNot (HaveOccurred ())
1093+ defer func () {
1094+ if testPod != nil {
1095+ testlog .Infof ("deleting pod %q" , testPod .Name )
1096+ Expect (pods .Delete (ctx , testPod )).To (BeTrue (), "Failed to delete test pod" )
1097+ }
1098+ }()
1099+
1100+ cpusetCfg := & controller.CpuSet {}
1101+ Expect (getter .Container (ctx , testPod , testPod .Spec .Containers [0 ].Name , cpusetCfg )).To (Succeed (), "Failed to get cpuset config for test pod" )
1102+
1103+ // assuming no shared cpus are used
1104+ cpusList := strings .Split (cpusetCfg .Cpus , "," )
1105+ Expect (cpusList ).ToNot (BeEmpty ())
1106+ firstExclusiveCPU := strings .TrimSpace (cpusList [0 ])
1107+ testlog .Infof ("first exclusive CPU: %s" , firstExclusiveCPU )
1108+
1109+ cpuRequest := testPod .Spec .Containers [0 ].Resources .Requests .Name (corev1 .ResourceCPU , resource .DecimalSI ).Value ()
1110+ retries := int (10 / cpuRequest )
1111+ By ("Run exec command on the pod and verify the process is pinned to the first exclusive CPU" )
1112+
1113+ for i := 0 ; i < retries ; i ++ {
1114+ cmd := []string {"/bin/bash" , "-c" , "sleep 10 & SLPID=$!; ps -o psr -p $SLPID;" }
1115+ output , err := pods .ExecCommandOnPod (testclient .K8sClient , testPod , testPod .Spec .Containers [0 ].Name , cmd )
1116+ Expect (err ).ToNot (HaveOccurred (), "Failed to exec command on the pod; retry %d" , i )
1117+ testlog .Infof ("exec command output: %s" , string (output ))
1118+
1119+ execProcessCPUs := strings .TrimSpace (string (output ))
1120+ Expect (execProcessCPUs ).ToNot (BeEmpty (), "Failed to get exec process CPU; retry %d" , i )
1121+ Expect (execProcessCPUs ).To (Equal (firstExclusiveCPU ), "Exec process CPU is not the first exclusive CPU; retry %d" , i )
1122+ }
1123+ })
1124+ })
1125+ })
10701126})
10711127
10721128func extractConfigInfo (output string ) (* ContainerConfig , error ) {
@@ -1317,24 +1373,6 @@ func getTestPodWithAnnotations(annotations map[string]string, cpus int) *corev1.
13171373 return testpod
13181374}
13191375
1320- func deleteTestPod (ctx context.Context , testpod * corev1.Pod ) (types.UID , bool ) {
1321- // it possible that the pod already was deleted as part of the test, in this case we want to skip teardown
1322- err := testclient .DataPlaneClient .Get (ctx , client .ObjectKeyFromObject (testpod ), testpod )
1323- if errors .IsNotFound (err ) {
1324- return "" , false
1325- }
1326-
1327- testpodUID := testpod .UID
1328-
1329- err = testclient .DataPlaneClient .Delete (ctx , testpod )
1330- Expect (err ).ToNot (HaveOccurred ())
1331-
1332- err = pods .WaitForDeletion (ctx , testpod , pods .DefaultDeletionTimeout * time .Second )
1333- Expect (err ).ToNot (HaveOccurred ())
1334-
1335- return testpodUID , true
1336- }
1337-
13381376func cpuSpecToString (cpus * performancev2.CPU ) (string , error ) {
13391377 if cpus == nil {
13401378 return "" , fmt .Errorf ("performance CPU field is nil" )
0 commit comments