| package fs |
| |
| import ( |
| "strconv" |
| "testing" |
| |
| "github.com/opencontainers/runc/libcontainer/cgroups" |
| "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" |
| "github.com/opencontainers/runc/libcontainer/configs" |
| ) |
| |
| const ( |
| sectorsRecursiveContents = `8:0 1024` |
| sectorsRecursiveContentsBFQ = `8:0 2048` |
| serviceBytesRecursiveContents = `8:0 Read 100 |
| 8:0 Write 200 |
| 8:0 Sync 300 |
| 8:0 Async 500 |
| 8:0 Total 500 |
| Total 500` |
| |
| serviceBytesRecursiveContentsBFQ = `8:0 Read 1100 |
| 8:0 Write 1200 |
| 8:0 Sync 1300 |
| 8:0 Async 1500 |
| 8:0 Total 1500 |
| Total 1500` |
| servicedRecursiveContents = `8:0 Read 10 |
| 8:0 Write 40 |
| 8:0 Sync 20 |
| 8:0 Async 30 |
| 8:0 Total 50 |
| Total 50` |
| servicedRecursiveContentsBFQ = `8:0 Read 11 |
| 8:0 Write 41 |
| 8:0 Sync 21 |
| 8:0 Async 31 |
| 8:0 Total 51 |
| Total 51` |
| queuedRecursiveContents = `8:0 Read 1 |
| 8:0 Write 4 |
| 8:0 Sync 2 |
| 8:0 Async 3 |
| 8:0 Total 5 |
| Total 5` |
| queuedRecursiveContentsBFQ = `8:0 Read 2 |
| 8:0 Write 3 |
| 8:0 Sync 4 |
| 8:0 Async 5 |
| 8:0 Total 6 |
| Total 6` |
| serviceTimeRecursiveContents = `8:0 Read 173959 |
| 8:0 Write 0 |
| 8:0 Sync 0 |
| 8:0 Async 173959 |
| 8:0 Total 17395 |
| Total 17395` |
| serviceTimeRecursiveContentsBFQ = `8:0 Read 173959 |
| 8:0 Write 0 |
| 8:0 Sync 0 |
| 8:0 Async 173 |
| 8:0 Total 174 |
| Total 174` |
| waitTimeRecursiveContents = `8:0 Read 15571 |
| 8:0 Write 0 |
| 8:0 Sync 0 |
| 8:0 Async 15571 |
| 8:0 Total 15571` |
| waitTimeRecursiveContentsBFQ = `8:0 Read 1557 |
| 8:0 Write 0 |
| 8:0 Sync 0 |
| 8:0 Async 1557 |
| 8:0 Total 1557` |
| mergedRecursiveContents = `8:0 Read 5 |
| 8:0 Write 10 |
| 8:0 Sync 0 |
| 8:0 Async 0 |
| 8:0 Total 15 |
| Total 15` |
| mergedRecursiveContentsBFQ = `8:0 Read 51 |
| 8:0 Write 101 |
| 8:0 Sync 0 |
| 8:0 Async 0 |
| 8:0 Total 151 |
| Total 151` |
| timeRecursiveContents = `8:0 8` |
| timeRecursiveContentsBFQ = `8:0 16` |
| throttleServiceBytes = `8:0 Read 11030528 |
| 8:0 Write 23 |
| 8:0 Sync 42 |
| 8:0 Async 11030528 |
| 8:0 Total 11030528 |
| 252:0 Read 11030528 |
| 252:0 Write 23 |
| 252:0 Sync 42 |
| 252:0 Async 11030528 |
| 252:0 Total 11030528 |
| Total 22061056` |
| throttleServiceBytesRecursive = `8:0 Read 110305281 |
| 8:0 Write 231 |
| 8:0 Sync 421 |
| 8:0 Async 110305281 |
| 8:0 Total 110305281 |
| 252:0 Read 110305281 |
| 252:0 Write 231 |
| 252:0 Sync 421 |
| 252:0 Async 110305281 |
| 252:0 Total 110305281 |
| Total 220610561` |
| throttleServiced = `8:0 Read 164 |
| 8:0 Write 23 |
| 8:0 Sync 42 |
| 8:0 Async 164 |
| 8:0 Total 164 |
| 252:0 Read 164 |
| 252:0 Write 23 |
| 252:0 Sync 42 |
| 252:0 Async 164 |
| 252:0 Total 164 |
| Total 328` |
| throttleServicedRecursive = `8:0 Read 1641 |
| 8:0 Write 231 |
| 8:0 Sync 421 |
| 8:0 Async 1641 |
| 8:0 Total 1641 |
| 252:0 Read 1641 |
| 252:0 Write 231 |
| 252:0 Sync 421 |
| 252:0 Async 1641 |
| 252:0 Total 1641 |
| Total 3281` |
| ) |
| |
| var blkioBFQDebugStatsTestFiles = map[string]string{ |
| "blkio.bfq.io_service_bytes_recursive": serviceBytesRecursiveContentsBFQ, |
| "blkio.bfq.io_serviced_recursive": servicedRecursiveContentsBFQ, |
| "blkio.bfq.io_queued_recursive": queuedRecursiveContentsBFQ, |
| "blkio.bfq.io_service_time_recursive": serviceTimeRecursiveContentsBFQ, |
| "blkio.bfq.io_wait_time_recursive": waitTimeRecursiveContentsBFQ, |
| "blkio.bfq.io_merged_recursive": mergedRecursiveContentsBFQ, |
| "blkio.bfq.time_recursive": timeRecursiveContentsBFQ, |
| "blkio.bfq.sectors_recursive": sectorsRecursiveContentsBFQ, |
| } |
| |
| var blkioBFQStatsTestFiles = map[string]string{ |
| "blkio.bfq.io_service_bytes_recursive": serviceBytesRecursiveContentsBFQ, |
| "blkio.bfq.io_serviced_recursive": servicedRecursiveContentsBFQ, |
| } |
| |
| var blkioCFQStatsTestFiles = map[string]string{ |
| "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, |
| "blkio.io_serviced_recursive": servicedRecursiveContents, |
| "blkio.io_queued_recursive": queuedRecursiveContents, |
| "blkio.io_service_time_recursive": serviceTimeRecursiveContents, |
| "blkio.io_wait_time_recursive": waitTimeRecursiveContents, |
| "blkio.io_merged_recursive": mergedRecursiveContents, |
| "blkio.time_recursive": timeRecursiveContents, |
| "blkio.sectors_recursive": sectorsRecursiveContents, |
| } |
| |
| type blkioStatFailureTestCase struct { |
| desc string |
| filename string |
| } |
| |
| func appendBlkioStatEntry(blkioStatEntries *[]cgroups.BlkioStatEntry, major, minor, value uint64, op string) { //nolint:unparam |
| *blkioStatEntries = append(*blkioStatEntries, cgroups.BlkioStatEntry{Major: major, Minor: minor, Value: value, Op: op}) |
| } |
| |
| func TestBlkioSetWeight(t *testing.T) { |
| const ( |
| weightBefore = 100 |
| weightAfter = 200 |
| ) |
| |
| for _, legacyIOScheduler := range []bool{false, true} { |
| // Populate cgroup |
| path := tempDir(t, "blkio") |
| weightFilename := "blkio.bfq.weight" |
| if legacyIOScheduler { |
| weightFilename = "blkio.weight" |
| } |
| writeFileContents(t, path, map[string]string{ |
| weightFilename: strconv.Itoa(weightBefore), |
| }) |
| // Apply new configuration |
| r := &configs.Resources{ |
| BlkioWeight: weightAfter, |
| } |
| blkio := &BlkioGroup{} |
| if err := blkio.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| // Verify results |
| if weightFilename != blkio.weightFilename { |
| t.Fatalf("weight filename detection failed: expected %q, detected %q", weightFilename, blkio.weightFilename) |
| } |
| value, err := fscommon.GetCgroupParamUint(path, weightFilename) |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != weightAfter { |
| t.Fatalf("Got the wrong value, set %s failed.", weightFilename) |
| } |
| } |
| } |
| |
| func TestBlkioSetWeightDevice(t *testing.T) { |
| const ( |
| weightDeviceBefore = "8:0 400" |
| ) |
| |
| for _, legacyIOScheduler := range []bool{false, true} { |
| // Populate cgroup |
| path := tempDir(t, "blkio") |
| weightFilename := "blkio.bfq.weight" |
| weightDeviceFilename := "blkio.bfq.weight_device" |
| if legacyIOScheduler { |
| weightFilename = "blkio.weight" |
| weightDeviceFilename = "blkio.weight_device" |
| } |
| writeFileContents(t, path, map[string]string{ |
| weightFilename: "", |
| weightDeviceFilename: weightDeviceBefore, |
| }) |
| // Apply new configuration |
| wd := configs.NewWeightDevice(8, 0, 500, 0) |
| weightDeviceAfter := wd.WeightString() |
| r := &configs.Resources{ |
| BlkioWeightDevice: []*configs.WeightDevice{wd}, |
| } |
| blkio := &BlkioGroup{} |
| if err := blkio.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| // Verify results |
| if weightDeviceFilename != blkio.weightDeviceFilename { |
| t.Fatalf("weight_device filename detection failed: expected %q, detected %q", weightDeviceFilename, blkio.weightDeviceFilename) |
| } |
| value, err := fscommon.GetCgroupParamString(path, weightDeviceFilename) |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != weightDeviceAfter { |
| t.Fatalf("Got the wrong value, set %s failed.", weightDeviceFilename) |
| } |
| } |
| } |
| |
| // regression #274 |
| func TestBlkioSetMultipleWeightDevice(t *testing.T) { |
| path := tempDir(t, "blkio") |
| |
| const ( |
| weightDeviceBefore = "8:0 400" |
| ) |
| |
| wd1 := configs.NewWeightDevice(8, 0, 500, 0) |
| wd2 := configs.NewWeightDevice(8, 16, 500, 0) |
| // we cannot actually set and check both because normal os.WriteFile |
| // when writing to cgroup file will overwrite the whole file content instead |
| // of updating it as the kernel is doing. Just check the second device |
| // is present will suffice for the test to ensure multiple writes are done. |
| weightDeviceAfter := wd2.WeightString() |
| |
| blkio := &BlkioGroup{} |
| blkio.detectWeightFilenames(path) |
| if blkio.weightDeviceFilename != "blkio.bfq.weight_device" { |
| t.Fatalf("when blkio controller is unavailable, expected to use \"blkio.bfq.weight_device\", tried to use %q", blkio.weightDeviceFilename) |
| } |
| writeFileContents(t, path, map[string]string{ |
| blkio.weightDeviceFilename: weightDeviceBefore, |
| }) |
| |
| r := &configs.Resources{ |
| BlkioWeightDevice: []*configs.WeightDevice{wd1, wd2}, |
| } |
| if err := blkio.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| |
| value, err := fscommon.GetCgroupParamString(path, blkio.weightDeviceFilename) |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != weightDeviceAfter { |
| t.Fatalf("Got the wrong value, set %s failed.", blkio.weightDeviceFilename) |
| } |
| } |
| |
| func TestBlkioBFQDebugStats(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, blkioBFQDebugStatsTestFiles) |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectedStats := cgroups.BlkioStats{} |
| appendBlkioStatEntry(&expectedStats.SectorsRecursive, 8, 0, 2048, "") |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1100, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1200, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1300, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 11, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 41, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 21, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 31, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 51, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 2, "Read") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 3, "Write") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 4, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 5, "Async") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 6, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 174, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Read") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Write") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Async") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 51, "Read") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 101, "Write") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Async") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 151, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoTimeRecursive, 8, 0, 16, "") |
| |
| expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) |
| } |
| |
| func TestBlkioMultipleStatsFiles(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, blkioBFQDebugStatsTestFiles) |
| writeFileContents(t, path, blkioCFQStatsTestFiles) |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectedStats := cgroups.BlkioStats{} |
| appendBlkioStatEntry(&expectedStats.SectorsRecursive, 8, 0, 2048, "") |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1100, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1200, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1300, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 11, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 41, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 21, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 31, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 51, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 2, "Read") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 3, "Write") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 4, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 5, "Async") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 6, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 174, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Read") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Write") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Async") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 1557, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 51, "Read") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 101, "Write") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Async") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 151, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoTimeRecursive, 8, 0, 16, "") |
| |
| expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) |
| } |
| |
| func TestBlkioBFQStats(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, blkioBFQStatsTestFiles) |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectedStats := cgroups.BlkioStats{} |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1100, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1200, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1300, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 1500, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 11, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 41, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 21, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 31, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 51, "Total") |
| |
| expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) |
| } |
| |
| func TestBlkioStatsNoFilesBFQDebug(t *testing.T) { |
| if testing.Short() { |
| t.Skip("skipping test in short mode.") |
| } |
| testCases := []blkioStatFailureTestCase{ |
| { |
| desc: "missing blkio.bfq.io_service_bytes_recursive file", |
| filename: "blkio.bfq.io_service_bytes_recursive", |
| }, |
| { |
| desc: "missing blkio.bfq.io_serviced_recursive file", |
| filename: "blkio.bfq.io_serviced_recursive", |
| }, |
| { |
| desc: "missing blkio.bfq.io_queued_recursive file", |
| filename: "blkio.bfq.io_queued_recursive", |
| }, |
| { |
| desc: "missing blkio.bfq.sectors_recursive file", |
| filename: "blkio.bfq.sectors_recursive", |
| }, |
| { |
| desc: "missing blkio.bfq.io_service_time_recursive file", |
| filename: "blkio.bfq.io_service_time_recursive", |
| }, |
| { |
| desc: "missing blkio.bfq.io_wait_time_recursive file", |
| filename: "blkio.bfq.io_wait_time_recursive", |
| }, |
| { |
| desc: "missing blkio.bfq.io_merged_recursive file", |
| filename: "blkio.bfq.io_merged_recursive", |
| }, |
| { |
| desc: "missing blkio.bfq.time_recursive file", |
| filename: "blkio.bfq.time_recursive", |
| }, |
| } |
| |
| for _, testCase := range testCases { |
| path := tempDir(t, "cpuset") |
| |
| tempBlkioTestFiles := map[string]string{} |
| for i, v := range blkioBFQDebugStatsTestFiles { |
| tempBlkioTestFiles[i] = v |
| } |
| delete(tempBlkioTestFiles, testCase.filename) |
| |
| writeFileContents(t, path, tempBlkioTestFiles) |
| cpuset := &CpusetGroup{} |
| actualStats := *cgroups.NewStats() |
| err := cpuset.GetStats(path, &actualStats) |
| if err != nil { |
| t.Errorf("%s: want no error, got: %+v", testCase.desc, err) |
| } |
| } |
| } |
| |
| func TestBlkioCFQStats(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, blkioCFQStatsTestFiles) |
| |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| // Verify expected stats. |
| expectedStats := cgroups.BlkioStats{} |
| appendBlkioStatEntry(&expectedStats.SectorsRecursive, 8, 0, 1024, "") |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 100, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 200, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 300, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 500, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 500, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 10, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 40, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 20, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 30, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 50, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 1, "Read") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 4, "Write") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 2, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 3, "Async") |
| appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 5, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 17395, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Read") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Write") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Async") |
| appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 5, "Read") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 10, "Write") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Async") |
| appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 15, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoTimeRecursive, 8, 0, 8, "") |
| |
| expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) |
| } |
| |
| func TestBlkioStatsNoFilesCFQ(t *testing.T) { |
| if testing.Short() { |
| t.Skip("skipping test in short mode.") |
| } |
| testCases := []blkioStatFailureTestCase{ |
| { |
| desc: "missing blkio.io_service_bytes_recursive file", |
| filename: "blkio.io_service_bytes_recursive", |
| }, |
| { |
| desc: "missing blkio.io_serviced_recursive file", |
| filename: "blkio.io_serviced_recursive", |
| }, |
| { |
| desc: "missing blkio.io_queued_recursive file", |
| filename: "blkio.io_queued_recursive", |
| }, |
| { |
| desc: "missing blkio.sectors_recursive file", |
| filename: "blkio.sectors_recursive", |
| }, |
| { |
| desc: "missing blkio.io_service_time_recursive file", |
| filename: "blkio.io_service_time_recursive", |
| }, |
| { |
| desc: "missing blkio.io_wait_time_recursive file", |
| filename: "blkio.io_wait_time_recursive", |
| }, |
| { |
| desc: "missing blkio.io_merged_recursive file", |
| filename: "blkio.io_merged_recursive", |
| }, |
| { |
| desc: "missing blkio.time_recursive file", |
| filename: "blkio.time_recursive", |
| }, |
| } |
| |
| for _, testCase := range testCases { |
| path := tempDir(t, "cpuset") |
| |
| tempBlkioTestFiles := map[string]string{} |
| for i, v := range blkioCFQStatsTestFiles { |
| tempBlkioTestFiles[i] = v |
| } |
| delete(tempBlkioTestFiles, testCase.filename) |
| |
| writeFileContents(t, path, tempBlkioTestFiles) |
| cpuset := &CpusetGroup{} |
| actualStats := *cgroups.NewStats() |
| err := cpuset.GetStats(path, &actualStats) |
| if err != nil { |
| t.Errorf("%s: want no error, got %+v", testCase.desc, err) |
| } |
| } |
| } |
| |
| func TestBlkioStatsUnexpectedNumberOfFields(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, map[string]string{ |
| "blkio.io_service_bytes_recursive": "8:0 Read 100 100", |
| "blkio.io_serviced_recursive": servicedRecursiveContents, |
| "blkio.io_queued_recursive": queuedRecursiveContents, |
| "blkio.sectors_recursive": sectorsRecursiveContents, |
| "blkio.io_service_time_recursive": serviceTimeRecursiveContents, |
| "blkio.io_wait_time_recursive": waitTimeRecursiveContents, |
| "blkio.io_merged_recursive": mergedRecursiveContents, |
| "blkio.time_recursive": timeRecursiveContents, |
| }) |
| |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err == nil { |
| t.Fatal("Expected to fail, but did not") |
| } |
| } |
| |
| func TestBlkioStatsUnexpectedFieldType(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, map[string]string{ |
| "blkio.io_service_bytes_recursive": "8:0 Read Write", |
| "blkio.io_serviced_recursive": servicedRecursiveContents, |
| "blkio.io_queued_recursive": queuedRecursiveContents, |
| "blkio.sectors_recursive": sectorsRecursiveContents, |
| "blkio.io_service_time_recursive": serviceTimeRecursiveContents, |
| "blkio.io_wait_time_recursive": waitTimeRecursiveContents, |
| "blkio.io_merged_recursive": mergedRecursiveContents, |
| "blkio.time_recursive": timeRecursiveContents, |
| }) |
| |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err == nil { |
| t.Fatal("Expected to fail, but did not") |
| } |
| } |
| |
| func TestThrottleRecursiveBlkioStats(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, map[string]string{ |
| "blkio.io_service_bytes_recursive": "", |
| "blkio.io_serviced_recursive": "", |
| "blkio.io_queued_recursive": "", |
| "blkio.sectors_recursive": "", |
| "blkio.io_service_time_recursive": "", |
| "blkio.io_wait_time_recursive": "", |
| "blkio.io_merged_recursive": "", |
| "blkio.time_recursive": "", |
| "blkio.throttle.io_service_bytes_recursive": throttleServiceBytesRecursive, |
| "blkio.throttle.io_serviced_recursive": throttleServicedRecursive, |
| }) |
| |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| // Verify expected stats. |
| expectedStats := cgroups.BlkioStats{} |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 110305281, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 231, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 421, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 110305281, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 110305281, "Total") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 110305281, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 231, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 421, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 110305281, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 110305281, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 1641, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 231, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 421, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 1641, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 1641, "Total") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 1641, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 231, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 421, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 1641, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 1641, "Total") |
| |
| expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) |
| } |
| |
| func TestThrottleBlkioStats(t *testing.T) { |
| path := tempDir(t, "blkio") |
| writeFileContents(t, path, map[string]string{ |
| "blkio.io_service_bytes_recursive": "", |
| "blkio.io_serviced_recursive": "", |
| "blkio.io_queued_recursive": "", |
| "blkio.sectors_recursive": "", |
| "blkio.io_service_time_recursive": "", |
| "blkio.io_wait_time_recursive": "", |
| "blkio.io_merged_recursive": "", |
| "blkio.time_recursive": "", |
| "blkio.throttle.io_service_bytes": throttleServiceBytes, |
| "blkio.throttle.io_serviced": throttleServiced, |
| }) |
| |
| blkio := &BlkioGroup{} |
| actualStats := *cgroups.NewStats() |
| err := blkio.GetStats(path, &actualStats) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| // Verify expected stats. |
| expectedStats := cgroups.BlkioStats{} |
| |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 23, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 42, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Total") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 23, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 42, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Total") |
| |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 23, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 42, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Total") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Read") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 23, "Write") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 42, "Sync") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Async") |
| appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Total") |
| |
| expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) |
| } |
| |
| func TestBlkioSetThrottleReadBpsDevice(t *testing.T) { |
| path := tempDir(t, "blkio") |
| |
| const ( |
| throttleBefore = `8:0 1024` |
| ) |
| |
| td := configs.NewThrottleDevice(8, 0, 2048) |
| throttleAfter := td.String() |
| |
| writeFileContents(t, path, map[string]string{ |
| "blkio.throttle.read_bps_device": throttleBefore, |
| }) |
| |
| r := &configs.Resources{ |
| BlkioThrottleReadBpsDevice: []*configs.ThrottleDevice{td}, |
| } |
| blkio := &BlkioGroup{} |
| if err := blkio.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| |
| value, err := fscommon.GetCgroupParamString(path, "blkio.throttle.read_bps_device") |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != throttleAfter { |
| t.Fatal("Got the wrong value, set blkio.throttle.read_bps_device failed.") |
| } |
| } |
| |
| func TestBlkioSetThrottleWriteBpsDevice(t *testing.T) { |
| path := tempDir(t, "blkio") |
| |
| const ( |
| throttleBefore = `8:0 1024` |
| ) |
| |
| td := configs.NewThrottleDevice(8, 0, 2048) |
| throttleAfter := td.String() |
| |
| writeFileContents(t, path, map[string]string{ |
| "blkio.throttle.write_bps_device": throttleBefore, |
| }) |
| |
| r := &configs.Resources{ |
| BlkioThrottleWriteBpsDevice: []*configs.ThrottleDevice{td}, |
| } |
| blkio := &BlkioGroup{} |
| if err := blkio.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| |
| value, err := fscommon.GetCgroupParamString(path, "blkio.throttle.write_bps_device") |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != throttleAfter { |
| t.Fatal("Got the wrong value, set blkio.throttle.write_bps_device failed.") |
| } |
| } |
| |
| func TestBlkioSetThrottleReadIOpsDevice(t *testing.T) { |
| path := tempDir(t, "blkio") |
| |
| const ( |
| throttleBefore = `8:0 1024` |
| ) |
| |
| td := configs.NewThrottleDevice(8, 0, 2048) |
| throttleAfter := td.String() |
| |
| writeFileContents(t, path, map[string]string{ |
| "blkio.throttle.read_iops_device": throttleBefore, |
| }) |
| |
| r := &configs.Resources{ |
| BlkioThrottleReadIOPSDevice: []*configs.ThrottleDevice{td}, |
| } |
| blkio := &BlkioGroup{} |
| if err := blkio.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| |
| value, err := fscommon.GetCgroupParamString(path, "blkio.throttle.read_iops_device") |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != throttleAfter { |
| t.Fatal("Got the wrong value, set blkio.throttle.read_iops_device failed.") |
| } |
| } |
| |
| func TestBlkioSetThrottleWriteIOpsDevice(t *testing.T) { |
| path := tempDir(t, "blkio") |
| |
| const ( |
| throttleBefore = `8:0 1024` |
| ) |
| |
| td := configs.NewThrottleDevice(8, 0, 2048) |
| throttleAfter := td.String() |
| |
| writeFileContents(t, path, map[string]string{ |
| "blkio.throttle.write_iops_device": throttleBefore, |
| }) |
| |
| r := &configs.Resources{ |
| BlkioThrottleWriteIOPSDevice: []*configs.ThrottleDevice{td}, |
| } |
| blkio := &BlkioGroup{} |
| if err := blkio.Set(path, r); err != nil { |
| t.Fatal(err) |
| } |
| |
| value, err := fscommon.GetCgroupParamString(path, "blkio.throttle.write_iops_device") |
| if err != nil { |
| t.Fatal(err) |
| } |
| if value != throttleAfter { |
| t.Fatal("Got the wrong value, set blkio.throttle.write_iops_device failed.") |
| } |
| } |