github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/libcontainer/cgroups/fs/cpuset_test.go (about) 1 package fs 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/opencontainers/runc/libcontainer/cgroups" 8 "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" 9 "github.com/opencontainers/runc/libcontainer/configs" 10 ) 11 12 const ( 13 cpus = "0-2,7,12-14\n" 14 cpuExclusive = "1\n" 15 mems = "1-4,6,9\n" 16 memHardwall = "0\n" 17 memExclusive = "0\n" 18 memoryMigrate = "1\n" 19 memorySpreadPage = "0\n" 20 memorySpeadSlab = "1\n" 21 memoryPressure = "34377\n" 22 schedLoadBalance = "1\n" 23 schedRelaxDomainLevel = "-1\n" 24 ) 25 26 var cpusetTestFiles = map[string]string{ 27 "cpuset.cpus": cpus, 28 "cpuset.cpu_exclusive": cpuExclusive, 29 "cpuset.mems": mems, 30 "cpuset.mem_hardwall": memHardwall, 31 "cpuset.mem_exclusive": memExclusive, 32 "cpuset.memory_migrate": memoryMigrate, 33 "cpuset.memory_spread_page": memorySpreadPage, 34 "cpuset.memory_spread_slab": memorySpeadSlab, 35 "cpuset.memory_pressure": memoryPressure, 36 "cpuset.sched_load_balance": schedLoadBalance, 37 "cpuset.sched_relax_domain_level": schedRelaxDomainLevel, 38 } 39 40 func TestCPUSetSetCpus(t *testing.T) { 41 path := tempDir(t, "cpuset") 42 43 const ( 44 cpusBefore = "0" 45 cpusAfter = "1-3" 46 ) 47 48 writeFileContents(t, path, map[string]string{ 49 "cpuset.cpus": cpusBefore, 50 }) 51 52 r := &configs.Resources{ 53 CpusetCpus: cpusAfter, 54 } 55 cpuset := &CpusetGroup{} 56 if err := cpuset.Set(path, r); err != nil { 57 t.Fatal(err) 58 } 59 60 value, err := fscommon.GetCgroupParamString(path, "cpuset.cpus") 61 if err != nil { 62 t.Fatal(err) 63 } 64 if value != cpusAfter { 65 t.Fatal("Got the wrong value, set cpuset.cpus failed.") 66 } 67 } 68 69 func TestCPUSetSetMems(t *testing.T) { 70 path := tempDir(t, "cpuset") 71 72 const ( 73 memsBefore = "0" 74 memsAfter = "1" 75 ) 76 77 writeFileContents(t, path, map[string]string{ 78 "cpuset.mems": memsBefore, 79 }) 80 81 r := &configs.Resources{ 82 CpusetMems: memsAfter, 83 } 84 cpuset := &CpusetGroup{} 85 if err := cpuset.Set(path, r); err != nil { 86 t.Fatal(err) 87 } 88 89 value, err := fscommon.GetCgroupParamString(path, "cpuset.mems") 90 if err != nil { 91 t.Fatal(err) 92 } 93 if value != memsAfter { 94 t.Fatal("Got the wrong value, set cpuset.mems failed.") 95 } 96 } 97 98 func TestCPUSetStatsCorrect(t *testing.T) { 99 path := tempDir(t, "cpuset") 100 writeFileContents(t, path, cpusetTestFiles) 101 102 cpuset := &CpusetGroup{} 103 actualStats := *cgroups.NewStats() 104 err := cpuset.GetStats(path, &actualStats) 105 if err != nil { 106 t.Fatal(err) 107 } 108 expectedStats := cgroups.CPUSetStats{ 109 CPUs: []uint16{0, 1, 2, 7, 12, 13, 14}, 110 CPUExclusive: 1, 111 Mems: []uint16{1, 2, 3, 4, 6, 9}, 112 MemoryMigrate: 1, 113 MemHardwall: 0, 114 MemExclusive: 0, 115 MemorySpreadPage: 0, 116 MemorySpreadSlab: 1, 117 MemoryPressure: 34377, 118 SchedLoadBalance: 1, 119 SchedRelaxDomainLevel: -1, 120 } 121 if !reflect.DeepEqual(expectedStats, actualStats.CPUSetStats) { 122 t.Fatalf("Expected Cpuset stats usage %#v but found %#v", 123 expectedStats, actualStats.CPUSetStats) 124 } 125 } 126 127 func TestCPUSetStatsMissingFiles(t *testing.T) { 128 for _, testCase := range []struct { 129 desc string 130 filename, contents string 131 removeFile bool 132 }{ 133 { 134 desc: "empty cpus file", 135 filename: "cpuset.cpus", 136 contents: "", 137 removeFile: false, 138 }, 139 { 140 desc: "empty mems file", 141 filename: "cpuset.mems", 142 contents: "", 143 removeFile: false, 144 }, 145 { 146 desc: "corrupted cpus file", 147 filename: "cpuset.cpus", 148 contents: "0-3,*4^2", 149 removeFile: false, 150 }, 151 { 152 desc: "corrupted mems file", 153 filename: "cpuset.mems", 154 contents: "0,1,2-5,8-7", 155 removeFile: false, 156 }, 157 { 158 desc: "missing cpu_exclusive file", 159 filename: "cpuset.cpu_exclusive", 160 contents: "", 161 removeFile: true, 162 }, 163 { 164 desc: "missing memory_migrate file", 165 filename: "cpuset.memory_migrate", 166 contents: "", 167 removeFile: true, 168 }, 169 { 170 desc: "missing mem_hardwall file", 171 filename: "cpuset.mem_hardwall", 172 contents: "", 173 removeFile: true, 174 }, 175 { 176 desc: "missing mem_exclusive file", 177 filename: "cpuset.mem_exclusive", 178 contents: "", 179 removeFile: true, 180 }, 181 { 182 desc: "missing memory_spread_page file", 183 filename: "cpuset.memory_spread_page", 184 contents: "", 185 removeFile: true, 186 }, 187 { 188 desc: "missing memory_spread_slab file", 189 filename: "cpuset.memory_spread_slab", 190 contents: "", 191 removeFile: true, 192 }, 193 { 194 desc: "missing memory_pressure file", 195 filename: "cpuset.memory_pressure", 196 contents: "", 197 removeFile: true, 198 }, 199 { 200 desc: "missing sched_load_balance file", 201 filename: "cpuset.sched_load_balance", 202 contents: "", 203 removeFile: true, 204 }, 205 { 206 desc: "missing sched_relax_domain_level file", 207 filename: "cpuset.sched_relax_domain_level", 208 contents: "", 209 removeFile: true, 210 }, 211 } { 212 t.Run(testCase.desc, func(t *testing.T) { 213 path := tempDir(t, "cpuset") 214 215 tempCpusetTestFiles := map[string]string{} 216 for i, v := range cpusetTestFiles { 217 tempCpusetTestFiles[i] = v 218 } 219 220 if testCase.removeFile { 221 delete(tempCpusetTestFiles, testCase.filename) 222 writeFileContents(t, path, tempCpusetTestFiles) 223 cpuset := &CpusetGroup{} 224 actualStats := *cgroups.NewStats() 225 err := cpuset.GetStats(path, &actualStats) 226 if err != nil { 227 t.Errorf("failed unexpectedly: %q", err) 228 } 229 } else { 230 tempCpusetTestFiles[testCase.filename] = testCase.contents 231 writeFileContents(t, path, tempCpusetTestFiles) 232 cpuset := &CpusetGroup{} 233 actualStats := *cgroups.NewStats() 234 err := cpuset.GetStats(path, &actualStats) 235 236 if err == nil { 237 t.Error("failed to return expected error") 238 } 239 } 240 }) 241 } 242 }