2015-05-14 06:42:16 +08:00
|
|
|
// +build linux
|
|
|
|
|
2014-05-15 06:21:44 +08:00
|
|
|
package fs
|
|
|
|
|
|
|
|
import (
|
2015-02-27 11:00:17 +08:00
|
|
|
"strconv"
|
2014-05-15 06:21:44 +08:00
|
|
|
"testing"
|
2014-05-28 08:01:08 +08:00
|
|
|
|
2015-06-22 10:29:59 +08:00
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
2014-05-15 06:21:44 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
memoryStatContents = `cache 512
|
|
|
|
rss 1024`
|
|
|
|
memoryUsageContents = "2048\n"
|
|
|
|
memoryMaxUsageContents = "4096\n"
|
2014-06-04 14:41:03 +08:00
|
|
|
memoryFailcnt = "100\n"
|
2016-02-04 03:00:48 +08:00
|
|
|
memoryLimitContents = "8192\n"
|
2014-05-15 06:21:44 +08:00
|
|
|
)
|
|
|
|
|
2015-02-27 11:00:17 +08:00
|
|
|
func TestMemorySetMemory(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
|
|
|
|
const (
|
|
|
|
memoryBefore = 314572800 // 300M
|
|
|
|
memoryAfter = 524288000 // 500M
|
|
|
|
reservationBefore = 209715200 // 200M
|
|
|
|
reservationAfter = 314572800 // 300M
|
|
|
|
)
|
|
|
|
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.limit_in_bytes": strconv.Itoa(memoryBefore),
|
|
|
|
"memory.soft_limit_in_bytes": strconv.Itoa(reservationBefore),
|
|
|
|
})
|
|
|
|
|
2015-12-15 08:26:29 +08:00
|
|
|
helper.CgroupData.config.Resources.Memory = memoryAfter
|
|
|
|
helper.CgroupData.config.Resources.MemoryReservation = reservationAfter
|
2015-02-27 11:00:17 +08:00
|
|
|
memory := &MemoryGroup{}
|
2015-11-05 18:52:14 +08:00
|
|
|
if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
|
2015-02-27 11:00:17 +08:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err)
|
|
|
|
}
|
|
|
|
if value != memoryAfter {
|
|
|
|
t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.")
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err = getCgroupParamUint(helper.CgroupPath, "memory.soft_limit_in_bytes")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to parse memory.soft_limit_in_bytes - %s", err)
|
|
|
|
}
|
|
|
|
if value != reservationAfter {
|
|
|
|
t.Fatal("Got the wrong value, set memory.soft_limit_in_bytes failed.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-09 10:25:12 +08:00
|
|
|
func TestMemorySetMemoryswap(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
|
|
|
|
const (
|
|
|
|
memoryswapBefore = 314572800 // 300M
|
|
|
|
memoryswapAfter = 524288000 // 500M
|
|
|
|
)
|
|
|
|
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore),
|
|
|
|
})
|
|
|
|
|
2015-12-15 08:26:29 +08:00
|
|
|
helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter
|
2015-03-09 10:25:12 +08:00
|
|
|
memory := &MemoryGroup{}
|
2015-11-05 18:52:14 +08:00
|
|
|
if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
|
2015-03-09 10:25:12 +08:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err := getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err)
|
|
|
|
}
|
|
|
|
if value != memoryswapAfter {
|
|
|
|
t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-15 14:24:56 +08:00
|
|
|
func TestMemorySetKernelMemory(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
|
|
|
|
const (
|
|
|
|
kernelMemoryBefore = 314572800 // 300M
|
|
|
|
kernelMemoryAfter = 524288000 // 500M
|
|
|
|
)
|
|
|
|
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.kmem.limit_in_bytes": strconv.Itoa(kernelMemoryBefore),
|
|
|
|
})
|
|
|
|
|
2015-12-15 08:26:29 +08:00
|
|
|
helper.CgroupData.config.Resources.KernelMemory = kernelMemoryAfter
|
2015-05-15 14:24:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2016-01-13 22:05:08 +08:00
|
|
|
if err := memory.SetKernelMemory(helper.CgroupPath, helper.CgroupData.config); err != nil {
|
2015-05-15 14:24:56 +08:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.limit_in_bytes")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to parse memory.kmem.limit_in_bytes - %s", err)
|
|
|
|
}
|
|
|
|
if value != kernelMemoryAfter {
|
|
|
|
t.Fatal("Got the wrong value, set memory.kmem.limit_in_bytes failed.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-11 19:26:03 +08:00
|
|
|
func TestMemorySetMemorySwappinessDefault(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
|
|
|
|
const (
|
|
|
|
swappinessBefore = 60 //deafult is 60
|
|
|
|
swappinessAfter = 0
|
|
|
|
)
|
|
|
|
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.swappiness": strconv.Itoa(swappinessBefore),
|
|
|
|
})
|
|
|
|
|
2015-12-15 08:26:29 +08:00
|
|
|
helper.CgroupData.config.Resources.Memory = swappinessAfter
|
2015-06-11 19:26:03 +08:00
|
|
|
memory := &MemoryGroup{}
|
2015-11-05 18:52:14 +08:00
|
|
|
if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
|
2015-06-11 19:26:03 +08:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err := getCgroupParamUint(helper.CgroupPath, "memory.swappiness")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to parse memory.swappiness - %s", err)
|
|
|
|
}
|
|
|
|
if value != swappinessAfter {
|
|
|
|
t.Fatal("Got the wrong value, set memory.swappiness failed.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-15 06:21:44 +08:00
|
|
|
func TestMemoryStats(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
2015-05-15 17:37:58 +08:00
|
|
|
"memory.stat": memoryStatContents,
|
|
|
|
"memory.usage_in_bytes": memoryUsageContents,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.limit_in_bytes": memoryLimitContents,
|
2015-05-15 17:37:58 +08:00
|
|
|
"memory.max_usage_in_bytes": memoryMaxUsageContents,
|
|
|
|
"memory.failcnt": memoryFailcnt,
|
|
|
|
"memory.memsw.usage_in_bytes": memoryUsageContents,
|
|
|
|
"memory.memsw.max_usage_in_bytes": memoryMaxUsageContents,
|
|
|
|
"memory.memsw.failcnt": memoryFailcnt,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.memsw.limit_in_bytes": memoryLimitContents,
|
2015-05-15 17:37:58 +08:00
|
|
|
"memory.kmem.usage_in_bytes": memoryUsageContents,
|
|
|
|
"memory.kmem.max_usage_in_bytes": memoryMaxUsageContents,
|
|
|
|
"memory.kmem.failcnt": memoryFailcnt,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.kmem.limit_in_bytes": memoryLimitContents,
|
2014-05-15 06:21:44 +08:00
|
|
|
})
|
|
|
|
|
2014-06-20 21:13:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2014-08-27 19:42:38 +08:00
|
|
|
actualStats := *cgroups.NewStats()
|
2014-06-20 21:13:56 +08:00
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
2014-05-15 06:21:44 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2016-02-04 03:00:48 +08:00
|
|
|
expectedStats := cgroups.MemoryStats{Cache: 512, Usage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, SwapUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, KernelUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, Stats: map[string]uint64{"cache": 512, "rss": 1024}}
|
2014-05-28 08:01:08 +08:00
|
|
|
expectMemoryStatEquals(t, expectedStats, actualStats.MemoryStats)
|
2014-05-15 06:21:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsNoStatFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.usage_in_bytes": memoryUsageContents,
|
|
|
|
"memory.max_usage_in_bytes": memoryMaxUsageContents,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.limit_in_bytes": memoryLimitContents,
|
2014-05-15 06:21:44 +08:00
|
|
|
})
|
|
|
|
|
2014-06-20 21:13:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2014-08-27 19:42:38 +08:00
|
|
|
actualStats := *cgroups.NewStats()
|
2014-06-20 21:13:56 +08:00
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
2014-07-09 05:25:55 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
2014-05-15 06:21:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsNoUsageFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.stat": memoryStatContents,
|
|
|
|
"memory.max_usage_in_bytes": memoryMaxUsageContents,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.limit_in_bytes": memoryLimitContents,
|
2014-05-15 06:21:44 +08:00
|
|
|
})
|
|
|
|
|
2014-06-20 21:13:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2014-08-27 19:42:38 +08:00
|
|
|
actualStats := *cgroups.NewStats()
|
2014-06-20 21:13:56 +08:00
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
2014-05-15 06:21:44 +08:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Expected failure")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsNoMaxUsageFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.stat": memoryStatContents,
|
|
|
|
"memory.usage_in_bytes": memoryUsageContents,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.limit_in_bytes": memoryLimitContents,
|
|
|
|
})
|
|
|
|
|
|
|
|
memory := &MemoryGroup{}
|
|
|
|
actualStats := *cgroups.NewStats()
|
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Expected failure")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsNoLimitInBytesFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.stat": memoryStatContents,
|
|
|
|
"memory.usage_in_bytes": memoryUsageContents,
|
|
|
|
"memory.max_usage_in_bytes": memoryMaxUsageContents,
|
2014-05-15 06:21:44 +08:00
|
|
|
})
|
|
|
|
|
2014-06-20 21:13:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2014-08-27 19:42:38 +08:00
|
|
|
actualStats := *cgroups.NewStats()
|
2014-06-20 21:13:56 +08:00
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
2014-05-15 06:21:44 +08:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Expected failure")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsBadStatFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.stat": "rss rss",
|
|
|
|
"memory.usage_in_bytes": memoryUsageContents,
|
|
|
|
"memory.max_usage_in_bytes": memoryMaxUsageContents,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.limit_in_bytes": memoryLimitContents,
|
2014-05-15 06:21:44 +08:00
|
|
|
})
|
|
|
|
|
2014-06-20 21:13:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2014-08-27 19:42:38 +08:00
|
|
|
actualStats := *cgroups.NewStats()
|
2014-06-20 21:13:56 +08:00
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
2014-05-15 06:21:44 +08:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Expected failure")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsBadUsageFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.stat": memoryStatContents,
|
|
|
|
"memory.usage_in_bytes": "bad",
|
|
|
|
"memory.max_usage_in_bytes": memoryMaxUsageContents,
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.limit_in_bytes": memoryLimitContents,
|
2014-05-15 06:21:44 +08:00
|
|
|
})
|
|
|
|
|
2014-06-20 21:13:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2014-08-27 19:42:38 +08:00
|
|
|
actualStats := *cgroups.NewStats()
|
2014-06-20 21:13:56 +08:00
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
2014-05-15 06:21:44 +08:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Expected failure")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsBadMaxUsageFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.stat": memoryStatContents,
|
|
|
|
"memory.usage_in_bytes": memoryUsageContents,
|
|
|
|
"memory.max_usage_in_bytes": "bad",
|
2016-02-04 03:00:48 +08:00
|
|
|
"memory.limit_in_bytes": memoryLimitContents,
|
|
|
|
})
|
|
|
|
|
|
|
|
memory := &MemoryGroup{}
|
|
|
|
actualStats := *cgroups.NewStats()
|
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Expected failure")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryStatsBadLimitInBytesFile(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.stat": memoryStatContents,
|
|
|
|
"memory.usage_in_bytes": memoryUsageContents,
|
|
|
|
"memory.max_usage_in_bytes": memoryMaxUsageContents,
|
|
|
|
"memory.limit_in_bytes": "bad",
|
2014-05-15 06:21:44 +08:00
|
|
|
})
|
|
|
|
|
2014-06-20 21:13:56 +08:00
|
|
|
memory := &MemoryGroup{}
|
2014-08-27 19:42:38 +08:00
|
|
|
actualStats := *cgroups.NewStats()
|
2014-06-20 21:13:56 +08:00
|
|
|
err := memory.GetStats(helper.CgroupPath, &actualStats)
|
2014-05-15 06:21:44 +08:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Expected failure")
|
|
|
|
}
|
|
|
|
}
|
2015-03-07 02:30:55 +08:00
|
|
|
|
|
|
|
func TestMemorySetOomControl(t *testing.T) {
|
|
|
|
helper := NewCgroupTestUtil("memory", t)
|
|
|
|
defer helper.cleanup()
|
|
|
|
|
|
|
|
const (
|
|
|
|
oom_kill_disable = 1 // disable oom killer, default is 0
|
|
|
|
)
|
|
|
|
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
|
|
"memory.oom_control": strconv.Itoa(oom_kill_disable),
|
|
|
|
})
|
|
|
|
|
|
|
|
memory := &MemoryGroup{}
|
2015-11-05 18:52:14 +08:00
|
|
|
if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
|
2015-03-07 02:30:55 +08:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err := getCgroupParamUint(helper.CgroupPath, "memory.oom_control")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to parse memory.oom_control - %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if value != oom_kill_disable {
|
|
|
|
t.Fatalf("Got the wrong value, set memory.oom_control failed.")
|
|
|
|
}
|
|
|
|
}
|