mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
c1adc99a20
In manager.Apply() method, a path to each subsystem is obtained by calling d.path(sys.Name()), and the sys.Apply() is called that does the same call to d.path() again. d.path() is an expensive call, so rather than to call it twice, let's reuse the result. This results the number of times we parse mountinfo during container start from 62 to 34 on my setup. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
213 lines
5.6 KiB
Go
213 lines
5.6 KiB
Go
// +build linux
|
|
|
|
package fs
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
|
)
|
|
|
|
func TestCpuSetShares(t *testing.T) {
|
|
helper := NewCgroupTestUtil("cpu", t)
|
|
defer helper.cleanup()
|
|
|
|
const (
|
|
sharesBefore = 1024
|
|
sharesAfter = 512
|
|
)
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
"cpu.shares": strconv.Itoa(sharesBefore),
|
|
})
|
|
|
|
helper.CgroupData.config.Resources.CpuShares = sharesAfter
|
|
cpu := &CpuGroup{}
|
|
if err := cpu.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
value, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cpu.shares")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cpu.shares - %s", err)
|
|
}
|
|
|
|
if value != sharesAfter {
|
|
t.Fatal("Got the wrong value, set cpu.shares failed.")
|
|
}
|
|
}
|
|
|
|
func TestCpuSetBandWidth(t *testing.T) {
|
|
helper := NewCgroupTestUtil("cpu", t)
|
|
defer helper.cleanup()
|
|
|
|
const (
|
|
quotaBefore = 8000
|
|
quotaAfter = 5000
|
|
periodBefore = 10000
|
|
periodAfter = 7000
|
|
rtRuntimeBefore = 8000
|
|
rtRuntimeAfter = 5000
|
|
rtPeriodBefore = 10000
|
|
rtPeriodAfter = 7000
|
|
)
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
"cpu.cfs_quota_us": strconv.Itoa(quotaBefore),
|
|
"cpu.cfs_period_us": strconv.Itoa(periodBefore),
|
|
"cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
|
|
"cpu.rt_period_us": strconv.Itoa(rtPeriodBefore),
|
|
})
|
|
|
|
helper.CgroupData.config.Resources.CpuQuota = quotaAfter
|
|
helper.CgroupData.config.Resources.CpuPeriod = periodAfter
|
|
helper.CgroupData.config.Resources.CpuRtRuntime = rtRuntimeAfter
|
|
helper.CgroupData.config.Resources.CpuRtPeriod = rtPeriodAfter
|
|
cpu := &CpuGroup{}
|
|
if err := cpu.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
quota, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cpu.cfs_quota_us")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cpu.cfs_quota_us - %s", err)
|
|
}
|
|
if quota != quotaAfter {
|
|
t.Fatal("Got the wrong value, set cpu.cfs_quota_us failed.")
|
|
}
|
|
|
|
period, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cpu.cfs_period_us")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cpu.cfs_period_us - %s", err)
|
|
}
|
|
if period != periodAfter {
|
|
t.Fatal("Got the wrong value, set cpu.cfs_period_us failed.")
|
|
}
|
|
rtRuntime, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cpu.rt_runtime_us")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cpu.rt_runtime_us - %s", err)
|
|
}
|
|
if rtRuntime != rtRuntimeAfter {
|
|
t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
|
|
}
|
|
rtPeriod, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cpu.rt_period_us")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cpu.rt_period_us - %s", err)
|
|
}
|
|
if rtPeriod != rtPeriodAfter {
|
|
t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
|
|
}
|
|
}
|
|
|
|
func TestCpuStats(t *testing.T) {
|
|
helper := NewCgroupTestUtil("cpu", t)
|
|
defer helper.cleanup()
|
|
|
|
const (
|
|
nrPeriods = 2000
|
|
nrThrottled = 200
|
|
throttledTime = uint64(18446744073709551615)
|
|
)
|
|
|
|
cpuStatContent := fmt.Sprintf("nr_periods %d\n nr_throttled %d\n throttled_time %d\n",
|
|
nrPeriods, nrThrottled, throttledTime)
|
|
helper.writeFileContents(map[string]string{
|
|
"cpu.stat": cpuStatContent,
|
|
})
|
|
|
|
cpu := &CpuGroup{}
|
|
actualStats := *cgroups.NewStats()
|
|
err := cpu.GetStats(helper.CgroupPath, &actualStats)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expectedStats := cgroups.ThrottlingData{
|
|
Periods: nrPeriods,
|
|
ThrottledPeriods: nrThrottled,
|
|
ThrottledTime: throttledTime}
|
|
|
|
expectThrottlingDataEquals(t, expectedStats, actualStats.CpuStats.ThrottlingData)
|
|
}
|
|
|
|
func TestNoCpuStatFile(t *testing.T) {
|
|
helper := NewCgroupTestUtil("cpu", t)
|
|
defer helper.cleanup()
|
|
|
|
cpu := &CpuGroup{}
|
|
actualStats := *cgroups.NewStats()
|
|
err := cpu.GetStats(helper.CgroupPath, &actualStats)
|
|
if err != nil {
|
|
t.Fatal("Expected not to fail, but did")
|
|
}
|
|
}
|
|
|
|
func TestInvalidCpuStat(t *testing.T) {
|
|
helper := NewCgroupTestUtil("cpu", t)
|
|
defer helper.cleanup()
|
|
cpuStatContent := `nr_periods 2000
|
|
nr_throttled 200
|
|
throttled_time fortytwo`
|
|
helper.writeFileContents(map[string]string{
|
|
"cpu.stat": cpuStatContent,
|
|
})
|
|
|
|
cpu := &CpuGroup{}
|
|
actualStats := *cgroups.NewStats()
|
|
err := cpu.GetStats(helper.CgroupPath, &actualStats)
|
|
if err == nil {
|
|
t.Fatal("Expected failed stat parsing.")
|
|
}
|
|
}
|
|
|
|
func TestCpuSetRtSchedAtApply(t *testing.T) {
|
|
helper := NewCgroupTestUtil("cpu", t)
|
|
defer helper.cleanup()
|
|
|
|
const (
|
|
rtRuntimeBefore = 0
|
|
rtRuntimeAfter = 5000
|
|
rtPeriodBefore = 0
|
|
rtPeriodAfter = 7000
|
|
)
|
|
|
|
helper.writeFileContents(map[string]string{
|
|
"cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
|
|
"cpu.rt_period_us": strconv.Itoa(rtPeriodBefore),
|
|
})
|
|
|
|
helper.CgroupData.config.Resources.CpuRtRuntime = rtRuntimeAfter
|
|
helper.CgroupData.config.Resources.CpuRtPeriod = rtPeriodAfter
|
|
cpu := &CpuGroup{}
|
|
|
|
helper.CgroupData.pid = 1234
|
|
if err := cpu.Apply(helper.CgroupPath, helper.CgroupData); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
rtRuntime, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cpu.rt_runtime_us")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cpu.rt_runtime_us - %s", err)
|
|
}
|
|
if rtRuntime != rtRuntimeAfter {
|
|
t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
|
|
}
|
|
rtPeriod, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cpu.rt_period_us")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cpu.rt_period_us - %s", err)
|
|
}
|
|
if rtPeriod != rtPeriodAfter {
|
|
t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
|
|
}
|
|
pid, err := fscommon.GetCgroupParamUint(helper.CgroupPath, "cgroup.procs")
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse cgroup.procs - %s", err)
|
|
}
|
|
if pid != 1234 {
|
|
t.Fatal("Got the wrong value, set cgroup.procs failed.")
|
|
}
|
|
}
|