Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-46584: Adjust Workload Hints test cases based on Intel or AMD #1258

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package __performance_workloadhints
import (
"context"
"fmt"
"github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/infrastructure"
"path/filepath"
"reflect"
"strconv"
Expand Down Expand Up @@ -55,6 +56,8 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
poolName string
err error
ctx context.Context = context.Background()
isIntel bool
isAMD bool
)

nodeLabel := testutils.NodeSelectorLabels
Expand All @@ -67,6 +70,11 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
profile, err = profiles.GetByNodeLabels(nodeLabel)
Expect(err).ToNot(HaveOccurred())
klog.Infof("using profile: %q", profile.Name)
// Check if one of the nodes is intel or AMD using Vendor ID
isIntel, err = infrastructure.IsIntel(ctx, &workerRTNodes[0])
Expect(err).ToNot(HaveOccurred(), "Unable to fetch Vendor ID")
isAMD, err = infrastructure.IsAMD(ctx, &workerRTNodes[0])
Expect(err).ToNot(HaveOccurred(), "Unable to fetch Vendor ID")
if !hypershift.IsHypershiftCluster() {
poolName, err = mcps.GetByProfile(profile)
Expect(err).ToNot(HaveOccurred())
Expand Down Expand Up @@ -237,8 +245,10 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
"kernel.sched_rt_runtime_us": "950000",
"vm.stat_interval": "10",
}
kernelParameters := []string{"processor.max_cstate=1", "intel_idle.max_cstate=0"}

kernelParameters := []string{"processor.max_cstate=1"}
if isIntel {
kernelParameters = append(kernelParameters, "intel_idle.max_cstate=0")
}
wg := sync.WaitGroup{}
By("Waiting for TuneD to start on nodes")
for i := 0; i < len(workerRTNodes); i++ {
Expand Down Expand Up @@ -296,8 +306,10 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
"vm.stat_interval": "10",
}
kernelParameters := []string{noHzParam, "tsc=reliable", "nosoftlockup", "nmi_watchdog=0", "mce=off", "skew_tick=1",
"processor.max_cstate=1", "intel_idle.max_cstate=0", "idle=poll"}

"processor.max_cstate=1", "idle=poll"}
if isIntel {
kernelParameters = append(kernelParameters, "intel_idle.max_cstate=0")
}
wg := sync.WaitGroup{}
By("Waiting for TuneD to start on nodes")
for i := 0; i < len(workerRTNodes); i++ {
Expand All @@ -319,6 +331,7 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific

By(fmt.Sprintf("Checking TuneD parameters on %q", node.Name))
kernelParameters = append(kernelParameters, utilstuned.AddPstateParameter(context.TODO(), node))

utilstuned.CheckParameters(context.TODO(), node, sysctlMap, kernelParameters, stalldEnabled, rtKernel)
}()
}
Expand Down Expand Up @@ -349,9 +362,15 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
By("Verifying node kernel arguments")
cmdline, err := nodes.ExecCommand(context.TODO(), &workerRTNodes[0], []string{"cat", "/proc/cmdline"})
Expect(err).ToNot(HaveOccurred())
Expect(cmdline).To(ContainSubstring("intel_pstate=passive"))
Expect(cmdline).ToNot(ContainSubstring("intel_pstate=active"))

if isIntel {
Expect(cmdline).To(ContainSubstring("intel_pstate=passive"))
Expect(cmdline).ToNot(ContainSubstring("intel_pstate=active"))
}
if isAMD {
Expect(cmdline).To(ContainSubstring("amd_pstate=passive"))
Expect(cmdline).ToNot(ContainSubstring("amd_pstate=active"))
}
By("Verifying tuned profile")
key := types.NamespacedName{
Name: components.GetComponentName(profile.Name, components.ProfileNamePerformance),
Expand All @@ -371,6 +390,7 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
// This test requires real hardware with powermanagement settings done on BIOS
// Using numa nodes to check if we are running on real hardware.
checkHardwareCapability(context.TODO(), workerRTNodes)

// First enable HighPowerConsumption
currentWorkloadHints := profile.Spec.WorkloadHints
By("Modifying profile")
Expand Down Expand Up @@ -404,8 +424,10 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
"vm.stat_interval": "10",
}
kernelParameters := []string{noHzParam, "tsc=reliable", "nosoftlockup", "nmi_watchdog=0", "mce=off", "skew_tick=1",
"processor.max_cstate=1", "intel_idle.max_cstate=0", "idle=poll"}

"processor.max_cstate=1", "idle=poll"}
if isIntel {
kernelParameters = append(kernelParameters, "intel_idle.max_cstate=0")
}
wg := sync.WaitGroup{}
By("Waiting for TuneD to start on nodes")
for i := 0; i < len(workerRTNodes); i++ {
Expand Down Expand Up @@ -461,8 +483,15 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
"kernel.sched_rt_runtime_us": "-1",
"vm.stat_interval": "10",
}
kernelParameters = []string{noHzParam, "tsc=reliable", "nosoftlockup", "nmi_watchdog=0", "mce=off", "skew_tick=1", "intel_pstate=passive"}
kernelParameters = []string{noHzParam, "tsc=reliable", "nosoftlockup", "nmi_watchdog=0", "mce=off", "skew_tick=1"}

// Note: Here if it's not intel, its AMD
if isIntel {
kernelParameters = append(kernelParameters, "intel_pstate=passive")
}
if isAMD {
kernelParameters = append(kernelParameters, "amd_pstate=passive")
}
wg = sync.WaitGroup{}
By("Waiting for TuneD to start on nodes")
for i := 0; i < len(workerRTNodes); i++ {
Expand Down Expand Up @@ -526,7 +555,12 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
"vm.stat_interval": "10",
}
kernelParameters := []string{noHzParam, "tsc=reliable", "nosoftlockup", "nmi_watchdog=0", "mce=off", "skew_tick=1", "intel_pstate=passive"}

if isIntel {
kernelParameters = append(kernelParameters, "intel_pstate=passive")
}
if isAMD {
kernelParameters = append(kernelParameters, "amd_pstate=passive")
}
wg := sync.WaitGroup{}
By("Waiting for TuneD to start on nodes")
for i := 0; i < len(workerRTNodes); i++ {
Expand Down Expand Up @@ -581,8 +615,11 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
"vm.stat_interval": "10",
}
kernelParameters = []string{noHzParam, "tsc=reliable", "nosoftlockup", "nmi_watchdog=0", "mce=off", "skew_tick=1",
"processor.max_cstate=1", "intel_idle.max_cstate=0", "idle=poll"}
"processor.max_cstate=1", "idle=poll"}

if isIntel {
kernelParameters = append(kernelParameters, "intel_idle.max_cstate=0")
}
wg = sync.WaitGroup{}
By("Waiting for TuneD to start on nodes")
for i := 0; i < len(workerRTNodes); i++ {
Expand Down Expand Up @@ -648,6 +685,9 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
var err error
// This test requires real hardware with powermanagement settings done on BIOS
// Using numa nodes to check if we are running on real hardware.
if isAMD {
Skip("Crio Powersave annotations test can only be run on Intel systems")
}
checkHardwareCapability(context.TODO(), workerRTNodes)
currentWorkloadHints := profile.Spec.WorkloadHints
profile.Spec.WorkloadHints = &performancev2.WorkloadHints{
Expand Down Expand Up @@ -752,6 +792,9 @@ var _ = Describe("[rfe_id:49062][workloadHints] Telco friendly workload specific
// This test requires real hardware with powermanagement settings done on BIOS
// Using numa nodes to check if we are running on real hardware
var containerCgroup, fullPath string
if isAMD {
Skip("Crio Performance annotations test can only be run on Intel systems")
}
checkHardwareCapability(context.TODO(), workerRTNodes)
currentWorkloadHints := profile.Spec.WorkloadHints
profile.Spec.WorkloadHints = &performancev2.WorkloadHints{
Expand Down
103 changes: 103 additions & 0 deletions test/e2e/performanceprofile/functests/utils/infrastructure/cpu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package infrastructure

import (
"context"
"encoding/json"
"fmt"
"github.com/openshift/cluster-node-tuning-operator/test/e2e/performanceprofile/functests/utils/nodes"
corev1 "k8s.io/api/core/v1"
)

// CpuArchitecture struct to represent CPU Details
type CpuArchitecture struct {
Lscpu []cpuField `json:"lscpu"`
}
type cpuField struct {
Field string `json:"field"`
Data string `json:"data"`
}

const (
IntelVendorID = "GenuineIntel"
AMDVendorID = "AuthenticAMD"
)

// lscpuPraser parses lscpu output and returns its fields in struct
func lscpuPraser(ctx context.Context, node *corev1.Node) (CpuArchitecture, error) {
cmd := []string{"lscpu", "-J"}
var cpuinfo CpuArchitecture
out, err := nodes.ExecCommand(ctx, node, cmd)
if err != nil {
return cpuinfo, fmt.Errorf("error executing lscpu command: %v", err)
}
err = json.Unmarshal(out, &cpuinfo)
if err != nil {
return cpuinfo, fmt.Errorf("error unmarshalling cpu info: %v", err)
}
return cpuinfo, nil
}

// CPUArchitecture returns CPU Architecture from lscpu output
func CPUArchitecture(ctx context.Context, node *corev1.Node) (string, error) {
cpuInfo, err := lscpuPraser(ctx, node)
if err != nil {
return "", fmt.Errorf("Unable to parse lscpu output")
}
for _, v := range cpuInfo.Lscpu {
if v.Field == "Architecture:" {
return v.Data, nil
}
}
return "", fmt.Errorf("could not fetch CPU architecture")
}

// CPUVendorId returns Vendor ID information from lscpu output
func CPUVendorId(ctx context.Context, node *corev1.Node) (string, error) {
cpuInfo, err := lscpuPraser(ctx, node)
if err != nil {
return "", fmt.Errorf("Unable to parse lscpu output")
}
for _, v := range cpuInfo.Lscpu {
if v.Field == "Vendor ID:" {
return v.Data, nil
}
}
return "", fmt.Errorf("could not fetch CPU Vendor ID")
}

// IsCPUVendor checks if the CPU Vendor ID matches the given vendor string
func IsCPUVendor(ctx context.Context, node *corev1.Node, vendor string) (bool, error) {
vendorData, err := CPUVendorId(ctx, node)
if err != nil {
return false, err
}
return vendorData == vendor, nil
}

// IsIntel returns if Vendor ID is GenuineIntel in lscpu output
func IsIntel(ctx context.Context, node *corev1.Node) (bool, error) {
isIntel, err := IsCPUVendor(ctx, node, IntelVendorID)
if err != nil {
return false, err
}
return isIntel, nil
}

// IsAMD returns if Vendor ID is AuthenticAMD in lscpu output
func IsAMD(ctx context.Context, node *corev1.Node) (bool, error) {
isAMD, err := IsCPUVendor(ctx, node, AMDVendorID)
if err != nil {
return false, err
}
return isAMD, nil
}

// IsARM returns if Architecture is aarch64
func IsARM(ctx context.Context, node *corev1.Node) (bool, error) {
architectureData, err := CPUArchitecture(ctx, node)
if err != nil {
return false, err
}

return architectureData == "aarch64", nil
}