mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
3f65946756
A cgroup manager's Set method sets cgroup resources, but historically it was accepting configs.Cgroups. Refactor it to accept resources only. This is an improvement from the API point of view, as the method can not change cgroup configuration (such as path to the cgroup etc), it can only set (modify) its resources/limits. This also lays the foundation for complicated resource updates, as now Set has two sets of resources -- the one that was previously specified during cgroup manager creation (or the previous Set), and the one passed in the argument, so it could deduce the difference between these. This is a long term goal though. 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.Resources); 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.Resources); 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\nnr_throttled %d\nthrottled_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.")
|
|
}
|
|
}
|