mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
93 lines
2.7 KiB
Go
93 lines
2.7 KiB
Go
//go:build linux
|
|
|
|
package cgutil
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/nomad/client/testutil"
|
|
"github.com/hashicorp/nomad/helper/testlog"
|
|
"github.com/hashicorp/nomad/helper/uuid"
|
|
"github.com/hashicorp/nomad/lib/cpuset"
|
|
"github.com/hashicorp/nomad/nomad/mock"
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// Note: these tests need to run on GitHub Actions runners with only 2 cores.
|
|
// It is not possible to write more cores to a cpuset than are actually available,
|
|
// so make sure tests account for that by setting systemCores as the full set of
|
|
// usable cores.
|
|
var systemCores = []uint16{0, 1}
|
|
|
|
func TestCpusetManager_V2_AddAlloc(t *testing.T) {
|
|
testutil.CgroupsCompatibleV2(t)
|
|
testutil.MinimumCores(t, 2)
|
|
|
|
logger := testlog.HCLogger(t)
|
|
parent := uuid.Short() + ".scope"
|
|
create(t, parent)
|
|
cleanup(t, parent)
|
|
|
|
// setup the cpuset manager
|
|
manager := NewCpusetManagerV2(parent, logger)
|
|
require.NoError(t, manager.Init(systemCores))
|
|
|
|
// add our first alloc, isolating 1 core
|
|
t.Run("first", func(t *testing.T) {
|
|
alloc := mock.Alloc()
|
|
alloc.AllocatedResources.Tasks["web"].Cpu.ReservedCores = cpuset.New(0).ToSlice()
|
|
manager.AddAlloc(alloc)
|
|
cpusetIs(t, "0-1", parent, alloc.ID, "web")
|
|
})
|
|
|
|
// add second alloc, isolating 1 core
|
|
t.Run("second", func(t *testing.T) {
|
|
alloc := mock.Alloc()
|
|
alloc.AllocatedResources.Tasks["web"].Cpu.ReservedCores = cpuset.New(1).ToSlice()
|
|
manager.AddAlloc(alloc)
|
|
cpusetIs(t, "1", parent, alloc.ID, "web")
|
|
})
|
|
|
|
// note that the scheduler, not the cpuset manager, is what prevents over-subscription
|
|
// and as such no logic exists here to prevent that
|
|
}
|
|
|
|
func cpusetIs(t *testing.T, exp, parent, allocID, task string) {
|
|
scope := makeScope(makeID(allocID, task))
|
|
value, err := cgroups.ReadFile(filepath.Join(CgroupRoot, parent, scope), "cpuset.cpus")
|
|
require.NoError(t, err)
|
|
require.Equal(t, exp, strings.TrimSpace(value))
|
|
}
|
|
|
|
func TestCpusetManager_V2_RemoveAlloc(t *testing.T) {
|
|
testutil.CgroupsCompatibleV2(t)
|
|
testutil.MinimumCores(t, 2)
|
|
|
|
logger := testlog.HCLogger(t)
|
|
parent := uuid.Short() + ".scope"
|
|
create(t, parent)
|
|
cleanup(t, parent)
|
|
|
|
// setup the cpuset manager
|
|
manager := NewCpusetManagerV2(parent, logger)
|
|
require.NoError(t, manager.Init(systemCores))
|
|
|
|
// alloc1 gets core 0
|
|
alloc1 := mock.Alloc()
|
|
alloc1.AllocatedResources.Tasks["web"].Cpu.ReservedCores = cpuset.New(0).ToSlice()
|
|
manager.AddAlloc(alloc1)
|
|
|
|
// alloc2 gets core 1
|
|
alloc2 := mock.Alloc()
|
|
alloc2.AllocatedResources.Tasks["web"].Cpu.ReservedCores = cpuset.New(1).ToSlice()
|
|
manager.AddAlloc(alloc2)
|
|
cpusetIs(t, "1", parent, alloc2.ID, "web")
|
|
|
|
// with alloc1 gone, alloc2 gets the now shared core
|
|
manager.RemoveAlloc(alloc1.ID)
|
|
cpusetIs(t, "0-1", parent, alloc2.ID, "web")
|
|
}
|