github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/cgroups/fs/memory_test.go (about) 1 // +build linux 2 3 package fs 4 5 import ( 6 "strconv" 7 "testing" 8 9 "github.com/opencontainers/runc/libcontainer/cgroups" 10 ) 11 12 const ( 13 memoryStatContents = `cache 512 14 rss 1024` 15 memoryUsageContents = "2048\n" 16 memoryMaxUsageContents = "4096\n" 17 memoryFailcnt = "100\n" 18 memoryLimitContents = "8192\n" 19 ) 20 21 func TestMemorySetMemory(t *testing.T) { 22 helper := NewCgroupTestUtil("memory", t) 23 defer helper.cleanup() 24 25 const ( 26 memoryBefore = 314572800 // 300M 27 memoryAfter = 524288000 // 500M 28 reservationBefore = 209715200 // 200M 29 reservationAfter = 314572800 // 300M 30 ) 31 32 helper.writeFileContents(map[string]string{ 33 "memory.limit_in_bytes": strconv.Itoa(memoryBefore), 34 "memory.soft_limit_in_bytes": strconv.Itoa(reservationBefore), 35 }) 36 37 helper.CgroupData.config.Resources.Memory = memoryAfter 38 helper.CgroupData.config.Resources.MemoryReservation = reservationAfter 39 memory := &MemoryGroup{} 40 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 41 t.Fatal(err) 42 } 43 44 value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes") 45 if err != nil { 46 t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err) 47 } 48 if value != memoryAfter { 49 t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.") 50 } 51 52 value, err = getCgroupParamUint(helper.CgroupPath, "memory.soft_limit_in_bytes") 53 if err != nil { 54 t.Fatalf("Failed to parse memory.soft_limit_in_bytes - %s", err) 55 } 56 if value != reservationAfter { 57 t.Fatal("Got the wrong value, set memory.soft_limit_in_bytes failed.") 58 } 59 } 60 61 func TestMemorySetMemoryswap(t *testing.T) { 62 helper := NewCgroupTestUtil("memory", t) 63 defer helper.cleanup() 64 65 const ( 66 memoryswapBefore = 314572800 // 300M 67 memoryswapAfter = 524288000 // 500M 68 ) 69 70 helper.writeFileContents(map[string]string{ 71 "memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore), 72 }) 73 74 helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter 75 memory := &MemoryGroup{} 76 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 77 t.Fatal(err) 78 } 79 80 value, err := getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes") 81 if err != nil { 82 t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err) 83 } 84 if value != memoryswapAfter { 85 t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.") 86 } 87 } 88 89 func TestMemorySetNegativeMemoryswap(t *testing.T) { 90 helper := NewCgroupTestUtil("memory", t) 91 defer helper.cleanup() 92 93 const ( 94 memoryBefore = 314572800 // 300M 95 memoryAfter = 524288000 // 500M 96 memoryswapBefore = 629145600 // 600M 97 memoryswapAfter = 629145600 // 600M 98 ) 99 100 helper.writeFileContents(map[string]string{ 101 "memory.limit_in_bytes": strconv.Itoa(memoryBefore), 102 "memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore), 103 }) 104 105 helper.CgroupData.config.Resources.Memory = memoryAfter 106 // Negative value means not change 107 helper.CgroupData.config.Resources.MemorySwap = -1 108 memory := &MemoryGroup{} 109 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 110 t.Fatal(err) 111 } 112 113 value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes") 114 if err != nil { 115 t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err) 116 } 117 if value != memoryAfter { 118 t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.") 119 } 120 121 value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes") 122 if err != nil { 123 t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err) 124 } 125 if value != memoryswapAfter { 126 t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.") 127 } 128 } 129 130 func TestMemorySetMemoryLargerThanSwap(t *testing.T) { 131 helper := NewCgroupTestUtil("memory", t) 132 defer helper.cleanup() 133 134 const ( 135 memoryBefore = 314572800 // 300M 136 memoryswapBefore = 524288000 // 500M 137 memoryAfter = 629145600 // 600M 138 memoryswapAfter = 838860800 // 800M 139 ) 140 141 helper.writeFileContents(map[string]string{ 142 "memory.limit_in_bytes": strconv.Itoa(memoryBefore), 143 "memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore), 144 // Set will call getMemoryData when memory and swap memory are 145 // both set, fake these fields so we don't get error. 146 "memory.usage_in_bytes": "0", 147 "memory.max_usage_in_bytes": "0", 148 "memory.failcnt": "0", 149 }) 150 151 helper.CgroupData.config.Resources.Memory = memoryAfter 152 helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter 153 memory := &MemoryGroup{} 154 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 155 t.Fatal(err) 156 } 157 158 value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes") 159 if err != nil { 160 t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err) 161 } 162 if value != memoryAfter { 163 t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.") 164 } 165 value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes") 166 if err != nil { 167 t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err) 168 } 169 if value != memoryswapAfter { 170 t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.") 171 } 172 } 173 174 func TestMemorySetSwapSmallerThanMemory(t *testing.T) { 175 helper := NewCgroupTestUtil("memory", t) 176 defer helper.cleanup() 177 178 const ( 179 memoryBefore = 629145600 // 600M 180 memoryswapBefore = 838860800 // 800M 181 memoryAfter = 314572800 // 300M 182 memoryswapAfter = 524288000 // 500M 183 ) 184 185 helper.writeFileContents(map[string]string{ 186 "memory.limit_in_bytes": strconv.Itoa(memoryBefore), 187 "memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore), 188 // Set will call getMemoryData when memory and swap memory are 189 // both set, fake these fields so we don't get error. 190 "memory.usage_in_bytes": "0", 191 "memory.max_usage_in_bytes": "0", 192 "memory.failcnt": "0", 193 }) 194 195 helper.CgroupData.config.Resources.Memory = memoryAfter 196 helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter 197 memory := &MemoryGroup{} 198 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 199 t.Fatal(err) 200 } 201 202 value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes") 203 if err != nil { 204 t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err) 205 } 206 if value != memoryAfter { 207 t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.") 208 } 209 value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes") 210 if err != nil { 211 t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err) 212 } 213 if value != memoryswapAfter { 214 t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.") 215 } 216 } 217 218 func TestMemorySetKernelMemory(t *testing.T) { 219 helper := NewCgroupTestUtil("memory", t) 220 defer helper.cleanup() 221 222 const ( 223 kernelMemoryBefore = 314572800 // 300M 224 kernelMemoryAfter = 524288000 // 500M 225 ) 226 227 helper.writeFileContents(map[string]string{ 228 "memory.kmem.limit_in_bytes": strconv.Itoa(kernelMemoryBefore), 229 }) 230 231 helper.CgroupData.config.Resources.KernelMemory = kernelMemoryAfter 232 memory := &MemoryGroup{} 233 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 234 t.Fatal(err) 235 } 236 237 value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.limit_in_bytes") 238 if err != nil { 239 t.Fatalf("Failed to parse memory.kmem.limit_in_bytes - %s", err) 240 } 241 if value != kernelMemoryAfter { 242 t.Fatal("Got the wrong value, set memory.kmem.limit_in_bytes failed.") 243 } 244 } 245 246 func TestMemorySetKernelMemoryTCP(t *testing.T) { 247 helper := NewCgroupTestUtil("memory", t) 248 defer helper.cleanup() 249 250 const ( 251 kernelMemoryTCPBefore = 314572800 // 300M 252 kernelMemoryTCPAfter = 524288000 // 500M 253 ) 254 255 helper.writeFileContents(map[string]string{ 256 "memory.kmem.tcp.limit_in_bytes": strconv.Itoa(kernelMemoryTCPBefore), 257 }) 258 259 helper.CgroupData.config.Resources.KernelMemoryTCP = kernelMemoryTCPAfter 260 memory := &MemoryGroup{} 261 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 262 t.Fatal(err) 263 } 264 265 value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.tcp.limit_in_bytes") 266 if err != nil { 267 t.Fatalf("Failed to parse memory.kmem.tcp.limit_in_bytes - %s", err) 268 } 269 if value != kernelMemoryTCPAfter { 270 t.Fatal("Got the wrong value, set memory.kmem.tcp.limit_in_bytes failed.") 271 } 272 } 273 274 func TestMemorySetMemorySwappinessDefault(t *testing.T) { 275 helper := NewCgroupTestUtil("memory", t) 276 defer helper.cleanup() 277 278 swappinessBefore := 60 //default is 60 279 swappinessAfter := int64(0) 280 281 helper.writeFileContents(map[string]string{ 282 "memory.swappiness": strconv.Itoa(swappinessBefore), 283 }) 284 285 helper.CgroupData.config.Resources.MemorySwappiness = &swappinessAfter 286 memory := &MemoryGroup{} 287 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 288 t.Fatal(err) 289 } 290 291 value, err := getCgroupParamUint(helper.CgroupPath, "memory.swappiness") 292 if err != nil { 293 t.Fatalf("Failed to parse memory.swappiness - %s", err) 294 } 295 if int64(value) != swappinessAfter { 296 t.Fatalf("Got the wrong value (%d), set memory.swappiness = %d failed.", value, swappinessAfter) 297 } 298 } 299 300 func TestMemoryStats(t *testing.T) { 301 helper := NewCgroupTestUtil("memory", t) 302 defer helper.cleanup() 303 helper.writeFileContents(map[string]string{ 304 "memory.stat": memoryStatContents, 305 "memory.usage_in_bytes": memoryUsageContents, 306 "memory.limit_in_bytes": memoryLimitContents, 307 "memory.max_usage_in_bytes": memoryMaxUsageContents, 308 "memory.failcnt": memoryFailcnt, 309 "memory.memsw.usage_in_bytes": memoryUsageContents, 310 "memory.memsw.max_usage_in_bytes": memoryMaxUsageContents, 311 "memory.memsw.failcnt": memoryFailcnt, 312 "memory.memsw.limit_in_bytes": memoryLimitContents, 313 "memory.kmem.usage_in_bytes": memoryUsageContents, 314 "memory.kmem.max_usage_in_bytes": memoryMaxUsageContents, 315 "memory.kmem.failcnt": memoryFailcnt, 316 "memory.kmem.limit_in_bytes": memoryLimitContents, 317 }) 318 319 memory := &MemoryGroup{} 320 actualStats := *cgroups.NewStats() 321 err := memory.GetStats(helper.CgroupPath, &actualStats) 322 if err != nil { 323 t.Fatal(err) 324 } 325 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}} 326 expectMemoryStatEquals(t, expectedStats, actualStats.MemoryStats) 327 } 328 329 func TestMemoryStatsNoStatFile(t *testing.T) { 330 helper := NewCgroupTestUtil("memory", t) 331 defer helper.cleanup() 332 helper.writeFileContents(map[string]string{ 333 "memory.usage_in_bytes": memoryUsageContents, 334 "memory.max_usage_in_bytes": memoryMaxUsageContents, 335 "memory.limit_in_bytes": memoryLimitContents, 336 }) 337 338 memory := &MemoryGroup{} 339 actualStats := *cgroups.NewStats() 340 err := memory.GetStats(helper.CgroupPath, &actualStats) 341 if err != nil { 342 t.Fatal(err) 343 } 344 } 345 346 func TestMemoryStatsNoUsageFile(t *testing.T) { 347 helper := NewCgroupTestUtil("memory", t) 348 defer helper.cleanup() 349 helper.writeFileContents(map[string]string{ 350 "memory.stat": memoryStatContents, 351 "memory.max_usage_in_bytes": memoryMaxUsageContents, 352 "memory.limit_in_bytes": memoryLimitContents, 353 }) 354 355 memory := &MemoryGroup{} 356 actualStats := *cgroups.NewStats() 357 err := memory.GetStats(helper.CgroupPath, &actualStats) 358 if err == nil { 359 t.Fatal("Expected failure") 360 } 361 } 362 363 func TestMemoryStatsNoMaxUsageFile(t *testing.T) { 364 helper := NewCgroupTestUtil("memory", t) 365 defer helper.cleanup() 366 helper.writeFileContents(map[string]string{ 367 "memory.stat": memoryStatContents, 368 "memory.usage_in_bytes": memoryUsageContents, 369 "memory.limit_in_bytes": memoryLimitContents, 370 }) 371 372 memory := &MemoryGroup{} 373 actualStats := *cgroups.NewStats() 374 err := memory.GetStats(helper.CgroupPath, &actualStats) 375 if err == nil { 376 t.Fatal("Expected failure") 377 } 378 } 379 380 func TestMemoryStatsNoLimitInBytesFile(t *testing.T) { 381 helper := NewCgroupTestUtil("memory", t) 382 defer helper.cleanup() 383 helper.writeFileContents(map[string]string{ 384 "memory.stat": memoryStatContents, 385 "memory.usage_in_bytes": memoryUsageContents, 386 "memory.max_usage_in_bytes": memoryMaxUsageContents, 387 }) 388 389 memory := &MemoryGroup{} 390 actualStats := *cgroups.NewStats() 391 err := memory.GetStats(helper.CgroupPath, &actualStats) 392 if err == nil { 393 t.Fatal("Expected failure") 394 } 395 } 396 397 func TestMemoryStatsBadStatFile(t *testing.T) { 398 helper := NewCgroupTestUtil("memory", t) 399 defer helper.cleanup() 400 helper.writeFileContents(map[string]string{ 401 "memory.stat": "rss rss", 402 "memory.usage_in_bytes": memoryUsageContents, 403 "memory.max_usage_in_bytes": memoryMaxUsageContents, 404 "memory.limit_in_bytes": memoryLimitContents, 405 }) 406 407 memory := &MemoryGroup{} 408 actualStats := *cgroups.NewStats() 409 err := memory.GetStats(helper.CgroupPath, &actualStats) 410 if err == nil { 411 t.Fatal("Expected failure") 412 } 413 } 414 415 func TestMemoryStatsBadUsageFile(t *testing.T) { 416 helper := NewCgroupTestUtil("memory", t) 417 defer helper.cleanup() 418 helper.writeFileContents(map[string]string{ 419 "memory.stat": memoryStatContents, 420 "memory.usage_in_bytes": "bad", 421 "memory.max_usage_in_bytes": memoryMaxUsageContents, 422 "memory.limit_in_bytes": memoryLimitContents, 423 }) 424 425 memory := &MemoryGroup{} 426 actualStats := *cgroups.NewStats() 427 err := memory.GetStats(helper.CgroupPath, &actualStats) 428 if err == nil { 429 t.Fatal("Expected failure") 430 } 431 } 432 433 func TestMemoryStatsBadMaxUsageFile(t *testing.T) { 434 helper := NewCgroupTestUtil("memory", t) 435 defer helper.cleanup() 436 helper.writeFileContents(map[string]string{ 437 "memory.stat": memoryStatContents, 438 "memory.usage_in_bytes": memoryUsageContents, 439 "memory.max_usage_in_bytes": "bad", 440 "memory.limit_in_bytes": memoryLimitContents, 441 }) 442 443 memory := &MemoryGroup{} 444 actualStats := *cgroups.NewStats() 445 err := memory.GetStats(helper.CgroupPath, &actualStats) 446 if err == nil { 447 t.Fatal("Expected failure") 448 } 449 } 450 451 func TestMemoryStatsBadLimitInBytesFile(t *testing.T) { 452 helper := NewCgroupTestUtil("memory", t) 453 defer helper.cleanup() 454 helper.writeFileContents(map[string]string{ 455 "memory.stat": memoryStatContents, 456 "memory.usage_in_bytes": memoryUsageContents, 457 "memory.max_usage_in_bytes": memoryMaxUsageContents, 458 "memory.limit_in_bytes": "bad", 459 }) 460 461 memory := &MemoryGroup{} 462 actualStats := *cgroups.NewStats() 463 err := memory.GetStats(helper.CgroupPath, &actualStats) 464 if err == nil { 465 t.Fatal("Expected failure") 466 } 467 } 468 469 func TestMemorySetOomControl(t *testing.T) { 470 helper := NewCgroupTestUtil("memory", t) 471 defer helper.cleanup() 472 473 const ( 474 oomKillDisable = 1 // disable oom killer, default is 0 475 ) 476 477 helper.writeFileContents(map[string]string{ 478 "memory.oom_control": strconv.Itoa(oomKillDisable), 479 }) 480 481 memory := &MemoryGroup{} 482 if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { 483 t.Fatal(err) 484 } 485 486 value, err := getCgroupParamUint(helper.CgroupPath, "memory.oom_control") 487 if err != nil { 488 t.Fatalf("Failed to parse memory.oom_control - %s", err) 489 } 490 491 if value != oomKillDisable { 492 t.Fatalf("Got the wrong value, set memory.oom_control failed.") 493 } 494 }