Add extensive unit testing for TopologyManager hint generation algorithm

Signed-off-by: Kevin Klues <kklues@nvidia.com>
This commit is contained in:
Kevin Klues 2022-03-01 14:39:18 +00:00
parent 99c57828ce
commit e370b7335c

View File

@ -21,6 +21,7 @@ import (
"testing" "testing"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
) )
type policyMergeTestCase struct { type policyMergeTestCase struct {
@ -1119,3 +1120,283 @@ func testPolicyMerge(policy Policy, tcases []policyMergeTestCase, t *testing.T)
} }
} }
} }
func TestMaxOfMinAffinityCounts(t *testing.T) {
tcases := []struct {
hints [][]TopologyHint
expected int
}{
{
[][]TopologyHint{},
0,
},
{
[][]TopologyHint{
{
TopologyHint{NewTestBitMask(), true},
},
},
0,
},
{
[][]TopologyHint{
{
TopologyHint{NewTestBitMask(0), true},
},
},
1,
},
{
[][]TopologyHint{
{
TopologyHint{NewTestBitMask(0, 1), true},
},
},
2,
},
{
[][]TopologyHint{
{
TopologyHint{NewTestBitMask(0, 1), true},
TopologyHint{NewTestBitMask(0, 1, 2), true},
},
},
2,
},
{
[][]TopologyHint{
{
TopologyHint{NewTestBitMask(0, 1), true},
TopologyHint{NewTestBitMask(0, 1, 2), true},
},
{
TopologyHint{NewTestBitMask(0, 1, 2), true},
},
},
3,
},
{
[][]TopologyHint{
{
TopologyHint{NewTestBitMask(0, 1), true},
TopologyHint{NewTestBitMask(0, 1, 2), true},
},
{
TopologyHint{NewTestBitMask(0, 1, 2), true},
TopologyHint{NewTestBitMask(0, 1, 2, 3), true},
},
},
3,
},
}
for _, tc := range tcases {
t.Run("", func(t *testing.T) {
result := maxOfMinAffinityCounts(tc.hints)
if result != tc.expected {
t.Errorf("Expected result to be %v, got %v", tc.expected, result)
}
})
}
}
func TestCompareHints(t *testing.T) {
tcases := []struct {
description string
bestNonPreferredAffinityCount int
current *TopologyHint
candidate *TopologyHint
expected string
}{
{
"candidate.NUMANodeAffinity.Count() == 0 (1)",
-1,
nil,
&TopologyHint{bitmask.NewEmptyBitMask(), false},
"current",
},
{
"candidate.NUMANodeAffinity.Count() == 0 (2)",
-1,
&TopologyHint{NewTestBitMask(), true},
&TopologyHint{NewTestBitMask(), false},
"current",
},
{
"current == nil (1)",
-1,
nil,
&TopologyHint{NewTestBitMask(0), true},
"candidate",
},
{
"current == nil (2)",
-1,
nil,
&TopologyHint{NewTestBitMask(0), false},
"candidate",
},
{
"!current.Preferred && candidate.Preferred",
-1,
&TopologyHint{NewTestBitMask(0), false},
&TopologyHint{NewTestBitMask(0), true},
"candidate",
},
{
"current.Preferred && !candidate.Preferred",
-1,
&TopologyHint{NewTestBitMask(0), true},
&TopologyHint{NewTestBitMask(0), false},
"current",
},
{
"current.Preferred && candidate.Preferred (1)",
-1,
&TopologyHint{NewTestBitMask(0), true},
&TopologyHint{NewTestBitMask(0), true},
"current",
},
{
"current.Preferred && candidate.Preferred (2)",
-1,
&TopologyHint{NewTestBitMask(0, 1), true},
&TopologyHint{NewTestBitMask(0), true},
"candidate",
},
{
"current.Preferred && candidate.Preferred (3)",
-1,
&TopologyHint{NewTestBitMask(0), true},
&TopologyHint{NewTestBitMask(0, 1), true},
"current",
},
{
"!current.Preferred && !candidate.Preferred (1.1)",
1,
&TopologyHint{NewTestBitMask(0, 1), false},
&TopologyHint{NewTestBitMask(0, 1), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (1.2)",
1,
&TopologyHint{NewTestBitMask(1, 2), false},
&TopologyHint{NewTestBitMask(0, 1), false},
"candidate",
},
{
"!current.Preferred && !candidate.Preferred (1.3)",
1,
&TopologyHint{NewTestBitMask(0, 1), false},
&TopologyHint{NewTestBitMask(1, 2), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (2.1)",
2,
&TopologyHint{NewTestBitMask(0, 1), false},
&TopologyHint{NewTestBitMask(0), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (2.2)",
2,
&TopologyHint{NewTestBitMask(0, 1), false},
&TopologyHint{NewTestBitMask(0, 1), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (2.3)",
2,
&TopologyHint{NewTestBitMask(1, 2), false},
&TopologyHint{NewTestBitMask(0, 1), false},
"candidate",
},
{
"!current.Preferred && !candidate.Preferred (2.4)",
2,
&TopologyHint{NewTestBitMask(0, 1), false},
&TopologyHint{NewTestBitMask(1, 2), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (3a)",
2,
&TopologyHint{NewTestBitMask(0), false},
&TopologyHint{NewTestBitMask(0, 1, 2), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (3b)",
2,
&TopologyHint{NewTestBitMask(0), false},
&TopologyHint{NewTestBitMask(0, 1), false},
"candidate",
},
{
"!current.Preferred && !candidate.Preferred (3ca.1)",
3,
&TopologyHint{NewTestBitMask(0), false},
&TopologyHint{NewTestBitMask(0, 1), false},
"candidate",
},
{
"!current.Preferred && !candidate.Preferred (3ca.2)",
3,
&TopologyHint{NewTestBitMask(0), false},
&TopologyHint{NewTestBitMask(1, 2), false},
"candidate",
},
{
"!current.Preferred && !candidate.Preferred (3ca.3)",
4,
&TopologyHint{NewTestBitMask(0, 1), false},
&TopologyHint{NewTestBitMask(1, 2, 3), false},
"candidate",
},
{
"!current.Preferred && !candidate.Preferred (3cb)",
4,
&TopologyHint{NewTestBitMask(1, 2, 3), false},
&TopologyHint{NewTestBitMask(0, 1), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (3cc.1)",
4,
&TopologyHint{NewTestBitMask(0, 1, 2), false},
&TopologyHint{NewTestBitMask(0, 1, 2), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (3cc.2)",
4,
&TopologyHint{NewTestBitMask(0, 1, 2), false},
&TopologyHint{NewTestBitMask(1, 2, 3), false},
"current",
},
{
"!current.Preferred && !candidate.Preferred (3cc.3)",
4,
&TopologyHint{NewTestBitMask(1, 2, 3), false},
&TopologyHint{NewTestBitMask(0, 1, 2), false},
"candidate",
},
}
for _, tc := range tcases {
t.Run(tc.description, func(t *testing.T) {
result := compareHints(tc.bestNonPreferredAffinityCount, tc.current, tc.candidate)
if result != tc.current && result != tc.candidate {
t.Errorf("Expected result to be either 'current' or 'candidate' hint")
}
if tc.expected == "current" && result != tc.current {
t.Errorf("Expected result to be %v, got %v", tc.current, result)
}
if tc.expected == "candidate" && result != tc.candidate {
t.Errorf("Expected result to be %v, got %v", tc.candidate, result)
}
})
}
}