diff --git a/test/conformance/runtime/cgroup_test.go b/test/conformance/runtime/cgroup_test.go index 5934473244f9..b933332938db 100644 --- a/test/conformance/runtime/cgroup_test.go +++ b/test/conformance/runtime/cgroup_test.go @@ -22,6 +22,7 @@ package runtime import ( "errors" "fmt" + "math" "strconv" "strings" "testing" @@ -53,6 +54,25 @@ func isCgroupsV2(mounts []*types.Mount) (bool, error) { return false, errors.New("Failed to find cgroup mount on /sys/fs/cgroup") } +// from https://github.com/opencontainers/cgroups/pull/20/files +func convertCPUSharesToCgroupV2Value(cpuShares uint64) uint64 { + // The value of 0 means "unset". + if cpuShares == 0 { + return 0 + } + if cpuShares <= 2 { + return 1 + } + if cpuShares >= 262144 { + return 10000 + } + l := math.Log2(float64(cpuShares)) + // Quadratic function which fits min, max, and default. + exponent := (l*l+125*l)/612.0 - 7.0/34.0 + + return uint64(math.Ceil(math.Pow(10, exponent))) +} + // TestMustHaveCgroupConfigured verifies that the Linux cgroups are configured based on the specified // resource limits and requests as delared by "MUST" in the runtime-contract. func TestMustHaveCgroupConfigured(t *testing.T) { @@ -84,6 +104,9 @@ func TestMustHaveCgroupConfigured(t *testing.T) { "/sys/fs/cgroup/cpu.weight": strconv.FormatInt(((((resources.Requests.Cpu().MilliValue()*1024/1000)-2)*9999)/262142)+1, 10), } + // cpu.weight conversion depends on runtime version, see https://github.com/kubernetes/kubernetes/issues/131216 + expectedCgroupsV2CpuWeightAlternativeFormula := strconv.FormatUint(convertCPUSharesToCgroupV2Value(uint64(resources.Requests.Cpu().MilliValue()*1024/1000)), 10) + cgroups := ri.Host.Cgroups cgroupV2, err := isCgroupsV2(ri.Host.Mounts) if err != nil { @@ -122,6 +145,16 @@ func TestMustHaveCgroupConfigured(t *testing.T) { periodV2 = strings.Split(*cgroup.Value, " ")[1] } + // cpu.weight conversion depends on runtime version, let's try the new formula first, + // if it fails, we fall back to the original formula we have in `expectedCgroups` + if cgroup.Name == "/sys/fs/cgroup/cpu.weight" { + if *cgroup.Value == expectedCgroupsV2CpuWeightAlternativeFormula { + continue + } else { + t.Logf("%s = %s, want: %s, falling back to the original cpu.weight formula", cgroup.Name, *cgroup.Value, expectedCgroupsV2CpuWeightAlternativeFormula) + } + } + if _, ok := expectedCgroups[cgroup.Name]; !ok { // Service returned a value we don't test t.Logf("%v cgroup returned, but not validated", cgroup.Name)