mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Add devicemanager tests for TopologyHint consumption
This commit is contained in:
parent
cc567afaf0
commit
dcc9f66311
@ -29,6 +29,14 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/socketmask"
|
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/socketmask"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type mockAffinityStore struct {
|
||||||
|
hint topologymanager.TopologyHint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockAffinityStore) GetAffinity(podUID string, containerName string) topologymanager.TopologyHint {
|
||||||
|
return m.hint
|
||||||
|
}
|
||||||
|
|
||||||
func makeNUMADevice(id string, numa int) pluginapi.Device {
|
func makeNUMADevice(id string, numa int) pluginapi.Device {
|
||||||
return pluginapi.Device{
|
return pluginapi.Device{
|
||||||
ID: id,
|
ID: id,
|
||||||
@ -261,3 +269,211 @@ func TestGetTopologyHints(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTopologyAlignedAllocation(t *testing.T) {
|
||||||
|
tcases := []struct {
|
||||||
|
description string
|
||||||
|
resource string
|
||||||
|
request int
|
||||||
|
devices []pluginapi.Device
|
||||||
|
hint topologymanager.TopologyHint
|
||||||
|
expectedAllocation int
|
||||||
|
expectedAlignment map[int]int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "Single Request, no alignment",
|
||||||
|
resource: "resource",
|
||||||
|
request: 1,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
{ID: "Dev1"},
|
||||||
|
{ID: "Dev2"},
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(0, 1),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 1,
|
||||||
|
expectedAlignment: map[int]int{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Request for 1, partial alignment",
|
||||||
|
resource: "resource",
|
||||||
|
request: 1,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
{ID: "Dev1"},
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(1),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 1,
|
||||||
|
expectedAlignment: map[int]int{1: 1},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Single Request, socket 0",
|
||||||
|
resource: "resource",
|
||||||
|
request: 1,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
makeNUMADevice("Dev1", 0),
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(0),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 1,
|
||||||
|
expectedAlignment: map[int]int{0: 1},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Single Request, socket 1",
|
||||||
|
resource: "resource",
|
||||||
|
request: 1,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
makeNUMADevice("Dev1", 0),
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(1),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 1,
|
||||||
|
expectedAlignment: map[int]int{1: 1},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Request for 2, socket 0",
|
||||||
|
resource: "resource",
|
||||||
|
request: 2,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
makeNUMADevice("Dev1", 0),
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
makeNUMADevice("Dev3", 0),
|
||||||
|
makeNUMADevice("Dev4", 1),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(0),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 2,
|
||||||
|
expectedAlignment: map[int]int{0: 2},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Request for 2, socket 1",
|
||||||
|
resource: "resource",
|
||||||
|
request: 2,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
makeNUMADevice("Dev1", 0),
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
makeNUMADevice("Dev3", 0),
|
||||||
|
makeNUMADevice("Dev4", 1),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(1),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 2,
|
||||||
|
expectedAlignment: map[int]int{1: 2},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Request for 4, unsatisfiable, prefer socket 0",
|
||||||
|
resource: "resource",
|
||||||
|
request: 4,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
makeNUMADevice("Dev1", 0),
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
makeNUMADevice("Dev3", 0),
|
||||||
|
makeNUMADevice("Dev4", 1),
|
||||||
|
makeNUMADevice("Dev5", 0),
|
||||||
|
makeNUMADevice("Dev6", 1),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(0),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 4,
|
||||||
|
expectedAlignment: map[int]int{0: 3, 1: 1},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Request for 4, unsatisfiable, prefer socket 1",
|
||||||
|
resource: "resource",
|
||||||
|
request: 4,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
makeNUMADevice("Dev1", 0),
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
makeNUMADevice("Dev3", 0),
|
||||||
|
makeNUMADevice("Dev4", 1),
|
||||||
|
makeNUMADevice("Dev5", 0),
|
||||||
|
makeNUMADevice("Dev6", 1),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(1),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 4,
|
||||||
|
expectedAlignment: map[int]int{0: 1, 1: 3},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Request for 4, multisocket",
|
||||||
|
resource: "resource",
|
||||||
|
request: 4,
|
||||||
|
devices: []pluginapi.Device{
|
||||||
|
makeNUMADevice("Dev1", 0),
|
||||||
|
makeNUMADevice("Dev2", 1),
|
||||||
|
makeNUMADevice("Dev3", 2),
|
||||||
|
makeNUMADevice("Dev4", 3),
|
||||||
|
makeNUMADevice("Dev5", 0),
|
||||||
|
makeNUMADevice("Dev6", 1),
|
||||||
|
makeNUMADevice("Dev7", 2),
|
||||||
|
makeNUMADevice("Dev8", 3),
|
||||||
|
},
|
||||||
|
hint: topologymanager.TopologyHint{
|
||||||
|
NUMANodeAffinity: makeSocketMask(1, 3),
|
||||||
|
Preferred: true,
|
||||||
|
},
|
||||||
|
expectedAllocation: 4,
|
||||||
|
expectedAlignment: map[int]int{1: 2, 3: 2},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tcases {
|
||||||
|
m := ManagerImpl{
|
||||||
|
allDevices: make(map[string]map[string]pluginapi.Device),
|
||||||
|
healthyDevices: make(map[string]sets.String),
|
||||||
|
allocatedDevices: make(map[string]sets.String),
|
||||||
|
podDevices: make(podDevices),
|
||||||
|
sourcesReady: &sourcesReadyStub{},
|
||||||
|
activePods: func() []*v1.Pod { return []*v1.Pod{} },
|
||||||
|
topologyAffinityStore: &mockAffinityStore{tc.hint},
|
||||||
|
}
|
||||||
|
|
||||||
|
m.allDevices[tc.resource] = make(map[string]pluginapi.Device)
|
||||||
|
m.healthyDevices[tc.resource] = sets.NewString()
|
||||||
|
|
||||||
|
for _, d := range tc.devices {
|
||||||
|
m.allDevices[tc.resource][d.ID] = d
|
||||||
|
m.healthyDevices[tc.resource].Insert(d.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
allocated, err := m.devicesToAllocate("podUID", "containerName", tc.resource, tc.request, sets.NewString())
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(allocated) != tc.expectedAllocation {
|
||||||
|
t.Errorf("%v. expected allocation: %v but got: %v", tc.description, tc.expectedAllocation, len(allocated))
|
||||||
|
}
|
||||||
|
|
||||||
|
alignment := make(map[int]int)
|
||||||
|
if m.deviceHasTopologyAlignment(tc.resource) {
|
||||||
|
for d := range allocated {
|
||||||
|
if m.allDevices[tc.resource][d].Topology != nil {
|
||||||
|
alignment[int(m.allDevices[tc.resource][d].Topology.Nodes[0].ID)]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(alignment, tc.expectedAlignment) {
|
||||||
|
t.Errorf("%v. expected alignment: %v but got: %v", tc.description, tc.expectedAlignment, alignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user