sandbox_test: Add test to verify memory hotplug behavior

Augment the mock hypervisor so that we can validate that ACPI memory hotplug
is carried out as expected.

We'll augment the number of memory slots in the hypervisor config each
time the memory of the hypervisor is changed. In this way we can ensure
that large memory hotplugs are broken up into appropriately sized
pieces in the unit test.

Signed-off-by: Eric Ernst <eric_ernst@apple.com>
This commit is contained in:
Eric Ernst 2022-07-22 19:35:34 -07:00 committed by Snir Sheriber
parent 928654b5cd
commit f174fac0d6
3 changed files with 29 additions and 13 deletions

View File

@ -17,6 +17,7 @@ import (
var MockHybridVSockPath = "/tmp/kata-mock-hybrid-vsock.socket"
type mockHypervisor struct {
config HypervisorConfig
mockPid int
}
@ -27,10 +28,11 @@ func (m *mockHypervisor) Capabilities(ctx context.Context) types.Capabilities {
}
func (m *mockHypervisor) HypervisorConfig() HypervisorConfig {
return HypervisorConfig{}
return m.config
}
func (m *mockHypervisor) setConfig(config *HypervisorConfig) error {
m.config = *config
return nil
}
@ -38,7 +40,7 @@ func (m *mockHypervisor) CreateVM(ctx context.Context, id string, network Networ
if err := m.setConfig(hypervisorConfig); err != nil {
return err
}
m.config.MemSlots = 0
return nil
}
@ -92,6 +94,11 @@ func (m *mockHypervisor) GetVMConsole(ctx context.Context, sandboxID string) (st
}
func (m *mockHypervisor) ResizeMemory(ctx context.Context, memMB uint32, memorySectionSizeMB uint32, probe bool) (uint32, MemoryDevice, error) {
if m.config.MemorySize != memMB {
// For testing, we'll use MemSlots to track how many times we resized memory
m.config.MemSlots += 1
m.config.MemorySize = memMB
}
return 0, MemoryDevice{}, nil
}
func (m *mockHypervisor) ResizeVCPUs(ctx context.Context, cpus uint32) (uint32, uint32, error) {
@ -99,7 +106,7 @@ func (m *mockHypervisor) ResizeVCPUs(ctx context.Context, cpus uint32) (uint32,
}
func (m *mockHypervisor) GetTotalMemoryMB(ctx context.Context) uint32 {
return 0
return m.config.MemorySize
}
func (m *mockHypervisor) Disconnect(ctx context.Context) {
}

View File

@ -14,7 +14,7 @@ import (
)
func TestMockHypervisorCreateVM(t *testing.T) {
var m *mockHypervisor
m := &mockHypervisor{}
assert := assert.New(t)
sandbox := &Sandbox{

View File

@ -41,6 +41,7 @@ func newHypervisorConfig(kernelParams []Param, hParams []Param) HypervisorConfig
HypervisorPath: filepath.Join(testDir, testHypervisor),
KernelParams: kernelParams,
HypervisorParams: hParams,
MemorySize: 1,
}
}
@ -1360,7 +1361,6 @@ func TestSandboxUpdateResources(t *testing.T) {
contConfig1 := newTestContainerConfigNoop("cont-00001")
contConfig2 := newTestContainerConfigNoop("cont-00002")
hConfig := newHypervisorConfig(nil, nil)
defer cleanUp()
// create a sandbox
s, err := testCreateSandbox(t,
@ -1370,28 +1370,37 @@ func TestSandboxUpdateResources(t *testing.T) {
NetworkConfig{},
[]ContainerConfig{contConfig1, contConfig2},
nil)
assert.NoError(t, err)
err = s.updateResources(context.Background())
assert.NoError(t, err)
containerMemLimit := int64(1000)
// For mock hypervisor, we MemSlots to be 0 since the memory wasn't changed.
assert.Equal(t, s.hypervisor.HypervisorConfig().MemSlots, uint32(0))
containerMemLimit := int64(4 * 1024 * 1024 * 1024)
containerCPUPeriod := uint64(1000)
containerCPUQouta := int64(5)
for _, c := range s.config.Containers {
c.Resources.Memory = &specs.LinuxMemory{
for idx := range s.config.Containers {
s.config.Containers[idx].Resources.Memory = &specs.LinuxMemory{
Limit: new(int64),
}
c.Resources.CPU = &specs.LinuxCPU{
s.config.Containers[idx].Resources.CPU = &specs.LinuxCPU{
Period: new(uint64),
Quota: new(int64),
}
c.Resources.Memory.Limit = &containerMemLimit
c.Resources.CPU.Period = &containerCPUPeriod
c.Resources.CPU.Quota = &containerCPUQouta
s.config.Containers[idx].Resources.Memory.Limit = &containerMemLimit
s.config.Containers[idx].Resources.CPU.Period = &containerCPUPeriod
s.config.Containers[idx].Resources.CPU.Quota = &containerCPUQouta
}
err = s.updateResources(context.Background())
assert.NoError(t, err)
// Since we're starting with a memory of 1 MB, we expect it to take 3 hotplugs to add 4GiB of memory when using ACPI hotplug:
// +48MB
// +2352MB
// +the remaining
assert.Equal(t, s.hypervisor.HypervisorConfig().MemSlots, uint32(3))
}
func TestSandboxExperimentalFeature(t *testing.T) {