| package fs |
| |
| import ( |
| "reflect" |
| "testing" |
| |
| "github.com/opencontainers/runc/libcontainer/cgroups" |
| "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" |
| "github.com/opencontainers/runc/libcontainer/configs" |
| ) |
| |
| const ( |
| cpus = "0-2,7,12-14\n" |
| cpuExclusive = "1\n" |
| mems = "1-4,6,9\n" |
| memHardwall = "0\n" |
| memExclusive = "0\n" |
| memoryMigrate = "1\n" |
| memorySpreadPage = "0\n" |
| memorySpeadSlab = "1\n" |
| memoryPressure = "34377\n" |
| schedLoadBalance = "1\n" |
| schedRelaxDomainLevel = "-1\n" |
| ) |
| |
| var cpusetTestFiles = map[string]string{ |
| "cpuset.cpus": cpus, |
| "cpuset.cpu_exclusive": cpuExclusive, |
| "cpuset.mems": mems, |
| "cpuset.mem_hardwall": memHardwall, |
| "cpuset.mem_exclusive": memExclusive, |
| "cpuset.memory_migrate": memoryMigrate, |
| "cpuset.memory_spread_page": memorySpreadPage, |
| "cpuset.memory_spread_slab": memorySpeadSlab, |
| "cpuset.memory_pressure": memoryPressure, |
| "cpuset.sched_load_balance": schedLoadBalance, |
| "cpuset.sched_relax_domain_level": schedRelaxDomainLevel, |
| } |
| |
| func TestCPUSetSetCpus(t *testing.T) { |
| path := tempDir(t, "cpuset") |
| |
| const ( |
| cpusBefore = "0" |
| cpusAfter = "1-3" |
| ) |
| |
| writeFileContents(t, path, map[string]string{ |
| "cpuset.cpus": cpusBefore, |
| }) |
| |
| r := &configs.Resources{ |
| CpusetCpus: cpusAfter, |
| } |
| cpuset := &CpusetGroup{} |
| if err := cpuset.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| |
| value, err := fscommon.GetCgroupParamString(path, "cpuset.cpus") |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != cpusAfter { |
| t.Fatal("Got the wrong value, set cpuset.cpus failed.") |
| } |
| } |
| |
| func TestCPUSetSetMems(t *testing.T) { |
| path := tempDir(t, "cpuset") |
| |
| const ( |
| memsBefore = "0" |
| memsAfter = "1" |
| ) |
| |
| writeFileContents(t, path, map[string]string{ |
| "cpuset.mems": memsBefore, |
| }) |
| |
| r := &configs.Resources{ |
| CpusetMems: memsAfter, |
| } |
| cpuset := &CpusetGroup{} |
| if err := cpuset.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| |
| value, err := fscommon.GetCgroupParamString(path, "cpuset.mems") |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != memsAfter { |
| t.Fatal("Got the wrong value, set cpuset.mems failed.") |
| } |
| } |
| |
| func TestCPUSetStatsCorrect(t *testing.T) { |
| path := tempDir(t, "cpuset") |
| writeFileContents(t, path, cpusetTestFiles) |
| |
| cpuset := &CpusetGroup{} |
| actualStats := *cgroups.NewStats() |
| err := cpuset.GetStats(path, &actualStats) |
| if err != nil { |
| t.Fatal(err) |
| } |
| expectedStats := cgroups.CPUSetStats{ |
| CPUs: []uint16{0, 1, 2, 7, 12, 13, 14}, |
| CPUExclusive: 1, |
| Mems: []uint16{1, 2, 3, 4, 6, 9}, |
| MemoryMigrate: 1, |
| MemHardwall: 0, |
| MemExclusive: 0, |
| MemorySpreadPage: 0, |
| MemorySpreadSlab: 1, |
| MemoryPressure: 34377, |
| SchedLoadBalance: 1, |
| SchedRelaxDomainLevel: -1, |
| } |
| if !reflect.DeepEqual(expectedStats, actualStats.CPUSetStats) { |
| t.Fatalf("Expected Cpuset stats usage %#v but found %#v", |
| expectedStats, actualStats.CPUSetStats) |
| } |
| } |
| |
| func TestCPUSetStatsMissingFiles(t *testing.T) { |
| for _, testCase := range []struct { |
| desc string |
| filename, contents string |
| removeFile bool |
| }{ |
| { |
| desc: "empty cpus file", |
| filename: "cpuset.cpus", |
| contents: "", |
| removeFile: false, |
| }, |
| { |
| desc: "empty mems file", |
| filename: "cpuset.mems", |
| contents: "", |
| removeFile: false, |
| }, |
| { |
| desc: "corrupted cpus file", |
| filename: "cpuset.cpus", |
| contents: "0-3,*4^2", |
| removeFile: false, |
| }, |
| { |
| desc: "corrupted mems file", |
| filename: "cpuset.mems", |
| contents: "0,1,2-5,8-7", |
| removeFile: false, |
| }, |
| { |
| desc: "missing cpu_exclusive file", |
| filename: "cpuset.cpu_exclusive", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing memory_migrate file", |
| filename: "cpuset.memory_migrate", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing mem_hardwall file", |
| filename: "cpuset.mem_hardwall", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing mem_exclusive file", |
| filename: "cpuset.mem_exclusive", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing memory_spread_page file", |
| filename: "cpuset.memory_spread_page", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing memory_spread_slab file", |
| filename: "cpuset.memory_spread_slab", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing memory_pressure file", |
| filename: "cpuset.memory_pressure", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing sched_load_balance file", |
| filename: "cpuset.sched_load_balance", |
| contents: "", |
| removeFile: true, |
| }, |
| { |
| desc: "missing sched_relax_domain_level file", |
| filename: "cpuset.sched_relax_domain_level", |
| contents: "", |
| removeFile: true, |
| }, |
| } { |
| t.Run(testCase.desc, func(t *testing.T) { |
| path := tempDir(t, "cpuset") |
| |
| tempCpusetTestFiles := map[string]string{} |
| for i, v := range cpusetTestFiles { |
| tempCpusetTestFiles[i] = v |
| } |
| |
| if testCase.removeFile { |
| delete(tempCpusetTestFiles, testCase.filename) |
| writeFileContents(t, path, tempCpusetTestFiles) |
| cpuset := &CpusetGroup{} |
| actualStats := *cgroups.NewStats() |
| err := cpuset.GetStats(path, &actualStats) |
| if err != nil { |
| t.Errorf("failed unexpectedly: %q", err) |
| } |
| } else { |
| tempCpusetTestFiles[testCase.filename] = testCase.contents |
| writeFileContents(t, path, tempCpusetTestFiles) |
| cpuset := &CpusetGroup{} |
| actualStats := *cgroups.NewStats() |
| err := cpuset.GetStats(path, &actualStats) |
| |
| if err == nil { |
| t.Error("failed to return expected error") |
| } |
| } |
| }) |
| } |
| } |