package hwstats
import (
"os"
"path/filepath"
"strconv"
"testing"
"github.com/stretchr/testify/require"
)
const (
testCgroupCharged = uint64(3 << 30)
testCgroupInactiveFile = uint64(1 << 30)
testCgroupWorkingSet = testCgroupCharged - testCgroupInactiveFile
)
func writeCgroupFiles(t *testing.T, usagePath, limitPath, statPath *string, limit, inactiveFileKey string) {
dir := t.TempDir()
files := map[*string]string{
usagePath: strconv.FormatUint(testCgroupCharged, 10) + "\n",
limitPath: limit + "\n",
statPath: "anon 1024\n" + inactiveFileKey + " " + strconv.FormatUint(testCgroupInactiveFile, 10) + "\n",
}
for ptr, content := range files {
path := filepath.Join(dir, filepath.Base(*ptr))
require.NoError(t, os.WriteFile(path, []byte(content), 0o644))
orig := *ptr
*ptr = path
t.Cleanup(func() { *ptr = orig })
}
}
func nodeMemory(t *testing.T) uint64 {
osStat, err := newOSStatMemoryGetter()
require.NoError(t, err)
_, total, err := osStat.getMemory()
require.NoError(t, err)
return total
}
func TestMemInfoGetterV2(t *testing.T) {
nodeTotal := nodeMemory(t)
osStat, err := newOSStatMemoryGetter()
require.NoError(t, err)
cg := newMemInfoGetterV2(osStat)
t.Run("limit set", func(t *testing.T) {
limit := nodeTotal / 2
writeCgroupFiles(t, &memCurrentPathV2, &memMaxPathV2, &memStatPathV2, strconv.FormatUint(limit, 10), inactiveFileV2)
usage, total, err := cg.getMemory()
require.NoError(t, err)
require.Equal(t, testCgroupWorkingSet, usage)
require.Equal(t, limit, total)
})
t.Run("unlimited keeps cgroup usage", func(t *testing.T) {
writeCgroupFiles(t, &memCurrentPathV2, &memMaxPathV2, &memStatPathV2, "max", inactiveFileV2)
usage, total, err := cg.getMemory()
require.NoError(t, err)
require.Equal(t, testCgroupWorkingSet, usage)
require.Equal(t, nodeTotal, total)
})
}
func TestMemInfoGetterV1(t *testing.T) {
nodeTotal := nodeMemory(t)
osStat, err := newOSStatMemoryGetter()
require.NoError(t, err)
cg := newMemInfoGetterV1(osStat)
t.Run("limit set", func(t *testing.T) {
limit := nodeTotal / 2
writeCgroupFiles(t, &memUsagePathV1, &memLimitPathV1, &memStatPathV1, strconv.FormatUint(limit, 10), totalInactiveFileV1)
usage, total, err := cg.getMemory()
require.NoError(t, err)
require.Equal(t, testCgroupWorkingSet, usage)
require.Equal(t, limit, total)
})
t.Run("limit above physical keeps cgroup usage", func(t *testing.T) {
writeCgroupFiles(t, &memUsagePathV1, &memLimitPathV1, &memStatPathV1, "9223372036854771712", totalInactiveFileV1)
usage, total, err := cg.getMemory()
require.NoError(t, err)
require.Equal(t, testCgroupWorkingSet, usage)
require.Equal(t, nodeTotal, total)
})
}