hs-test: Add CPU pinning tests for 'relative' keyword 87/41187/23
authorHadi Rayan Al-Sandid <[email protected]>
Tue, 25 Jun 2024 21:38:54 +0000 (23:38 +0200)
committerFlorin Coras <[email protected]>
Tue, 15 Apr 2025 20:37:52 +0000 (20:37 +0000)
Type: test

Added tests to cpu_pinning_suite.go to verify that
VPP launches with different CPU configurations, including
configurations with the 'relative' keyword.

Change-Id: Ia6bef88ca22ebad5d37480230c8a84cabebab4a9
Signed-off-by: Hadi Rayan Al-Sandid <[email protected]>
extras/hs-test/cpu_pinning_test.go
extras/hs-test/infra/vppinstance.go

index f1f689c..efcc6b4 100644 (file)
@@ -5,26 +5,149 @@ import (
 )
 
 func init() {
-       RegisterCpuPinningSoloTests(DefaultCpuConfigurationTest, SkipCoresTest)
+       RegisterCpuPinningSoloTests(DefaultCpuConfigurationTest, MainThreadOnlyNoPinningTest, MainThreadOnlyTest, CorelistWorkersTest, RelativeMainThreadOnlyTest, RelativeAutoWorkersTest, RelativeAutoWorkersSkipCoresTest, RelativeCorelistWorkersTest, RelativeCorelistWorkersSkipCoresTest)
 }
 
-// TODO: Add more CPU configuration tests
+/* Following test-cases verify that VPP CPU pinning configuration work as expected.
+
+Certain configuration are not tested here, as they are expected to fail in the CI environment.
+
+Assuming the vpp CI container is allocated CPUs [37 38 39]:
+Config #1: 'cpu {main-core x workers y}'
+e.g. 'cpu {main-core 37 workers 2}' will fail as workers will be assigned automatically to CPUs 1 and 2, outside the allowed cpuset
+Config #2: 'cpu {main-core x corelist-workers y skip-cores z}'
+e.g. 'cpu {main-core 37 corelist-workers 38-39 skip-cores 1}' will not behave as expected, as CPU 0 will be skipped
+*/
 
 func DefaultCpuConfigurationTest(s *CpuPinningSuite) {
        vpp := s.Containers.Vpp.VppInstance
        s.AssertNil(vpp.Start())
 }
 
-func SkipCoresTest(s *CpuPinningSuite) {
+// cpu {} (main thread is pinned on CPU that VPP launches on)
+func MainThreadOnlyNoPinningTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
+               PinMainCpu:         false,
+               UseWorkers:         false,
+               PinWorkersCorelist: false,
+               RelativeCores:      false,
+               SkipCores:          0,
+       }
+
+       vpp := s.Containers.Vpp.VppInstance
+       vpp.CpuConfig = vppCpuConfig
+
+       s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x}
+func MainThreadOnlyTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
+               PinMainCpu:         true,
+               UseWorkers:         false,
+               PinWorkersCorelist: false,
+               RelativeCores:      false,
+               SkipCores:          0,
+       }
+
+       vpp := s.Containers.Vpp.VppInstance
+       vpp.CpuConfig = vppCpuConfig
+
+       s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x corelist-workers y}
+func CorelistWorkersTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
+               PinMainCpu:         true,
+               UseWorkers:         true,
+               PinWorkersCorelist: true,
+               RelativeCores:      false,
+               SkipCores:          0,
+       }
+
+       vpp := s.Containers.Vpp.VppInstance
+       vpp.CpuConfig = vppCpuConfig
+
+       s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x relative}
+func RelativeMainThreadOnlyTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
+               PinMainCpu:         true,
+               UseWorkers:         false,
+               PinWorkersCorelist: false,
+               RelativeCores:      true,
+               SkipCores:          0,
+       }
+
+       vpp := s.Containers.Vpp.VppInstance
+       vpp.CpuConfig = vppCpuConfig
+
+       s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x workers y relative}
+func RelativeAutoWorkersTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
+               PinMainCpu:         true,
+               UseWorkers:         true,
+               PinWorkersCorelist: false,
+               RelativeCores:      true,
+               SkipCores:          0,
+       }
+
+       vpp := s.Containers.Vpp.VppInstance
+       vpp.CpuConfig = vppCpuConfig
+
+       s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x workers y skip-cores z relative}
+func RelativeAutoWorkersSkipCoresTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
+               PinMainCpu:         true,
+               UseWorkers:         true,
+               PinWorkersCorelist: false,
+               RelativeCores:      true,
+               SkipCores:          1, /* skip 1 core */
+       }
+
+       vpp := s.Containers.Vpp.VppInstance
+       vpp.CpuConfig = vppCpuConfig
+
+       s.AssertNil(vpp.Start())
+}
+
+// cpu {main-core x corelist-workers y relative}
+func RelativeCorelistWorkersTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
+               PinMainCpu:         true,
+               UseWorkers:         true,
+               PinWorkersCorelist: true,
+               RelativeCores:      true,
+               SkipCores:          0,
+       }
+
+       vpp := s.Containers.Vpp.VppInstance
+       vpp.CpuConfig = vppCpuConfig
+
+       s.AssertNil(vpp.Start())
+}
 
-       skipCoresConfiguration := VppCpuConfig{
+// cpu {main-core x corelist-workers y skip-cores z relative}
+func RelativeCorelistWorkersSkipCoresTest(s *CpuPinningSuite) {
+       vppCpuConfig := VppCpuConfig{
                PinMainCpu:         true,
+               UseWorkers:         true,
                PinWorkersCorelist: true,
-               SkipCores:          1,
+               RelativeCores:      true,
+               SkipCores:          1, /* skip 1 core */
        }
 
        vpp := s.Containers.Vpp.VppInstance
-       vpp.CpuConfig = skipCoresConfiguration
+       vpp.CpuConfig = vppCpuConfig
 
        s.AssertNil(vpp.Start())
 }
index 59d17de..1d07c74 100644 (file)
@@ -95,7 +95,9 @@ type VppInstance struct {
 
 type VppCpuConfig struct {
        PinMainCpu         bool
+       UseWorkers         bool
        PinWorkersCorelist bool
+       RelativeCores      bool
        SkipCores          int
 }
 
@@ -603,7 +605,9 @@ func (vpp *VppInstance) Disconnect() {
 
 func (vpp *VppInstance) setDefaultCpuConfig() {
        vpp.CpuConfig.PinMainCpu = true
+       vpp.CpuConfig.UseWorkers = true
        vpp.CpuConfig.PinWorkersCorelist = true
+       vpp.CpuConfig.RelativeCores = false
        vpp.CpuConfig.SkipCores = 0
 }
 
@@ -617,6 +621,11 @@ func (vpp *VppInstance) generateVPPCpuConfig() string {
 
        c.NewStanza("cpu")
 
+       if vpp.CpuConfig.RelativeCores {
+               c.Append("relative")
+               vpp.getSuite().Log("relative")
+       }
+
        // If skip-cores is valid, use as start value to assign main/workers CPUs
        if vpp.CpuConfig.SkipCores != 0 {
                c.Append(fmt.Sprintf("skip-cores %d", vpp.CpuConfig.SkipCores))
@@ -628,19 +637,32 @@ func (vpp *VppInstance) generateVPPCpuConfig() string {
        }
 
        if vpp.CpuConfig.PinMainCpu {
-               c.Append(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
-               vpp.getSuite().Log(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
+               if vpp.CpuConfig.RelativeCores {
+                       c.Append(fmt.Sprintf("main-core %d", startCpu))
+                       vpp.getSuite().Log(fmt.Sprintf("main-core %d", startCpu))
+               } else {
+                       c.Append(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
+                       vpp.getSuite().Log(fmt.Sprintf("main-core %d", vpp.Cpus[startCpu]))
+               }
        }
 
        workers := vpp.Cpus[startCpu+1:]
+       workersRelativeCpu := startCpu + 1
 
-       if len(workers) > 0 {
+       if len(workers) > 0 && vpp.CpuConfig.UseWorkers {
                if vpp.CpuConfig.PinWorkersCorelist {
                        for i := 0; i < len(workers); i++ {
                                if i != 0 {
                                        s = s + ", "
                                }
-                               s = s + fmt.Sprintf("%d", workers[i])
+
+                               if vpp.CpuConfig.RelativeCores {
+                                       s = s + fmt.Sprintf("%d", workersRelativeCpu)
+                                       workersRelativeCpu++
+                               } else {
+                                       s = s + fmt.Sprintf("%d", workers[i])
+                               }
+
                        }
                        c.Append(fmt.Sprintf("corelist-workers %s", s))
                        vpp.getSuite().Log("corelist-workers " + s)