mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
04041f21ac
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
863 lines
30 KiB
Go
863 lines
30 KiB
Go
package fs
|
|
|
|
import (
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
|
)
|
|
|
|
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 := &cgroups.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 := cgroups.NewWeightDevice(8, 0, 500, 0)
|
|
weightDeviceAfter := wd.WeightString()
|
|
r := &cgroups.Resources{
|
|
BlkioWeightDevice: []*cgroups.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 := cgroups.NewWeightDevice(8, 0, 500, 0)
|
|
wd2 := cgroups.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 := &cgroups.Resources{
|
|
BlkioWeightDevice: []*cgroups.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 := cgroups.NewThrottleDevice(8, 0, 2048)
|
|
throttleAfter := td.String()
|
|
|
|
writeFileContents(t, path, map[string]string{
|
|
"blkio.throttle.read_bps_device": throttleBefore,
|
|
})
|
|
|
|
r := &cgroups.Resources{
|
|
BlkioThrottleReadBpsDevice: []*cgroups.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 := cgroups.NewThrottleDevice(8, 0, 2048)
|
|
throttleAfter := td.String()
|
|
|
|
writeFileContents(t, path, map[string]string{
|
|
"blkio.throttle.write_bps_device": throttleBefore,
|
|
})
|
|
|
|
r := &cgroups.Resources{
|
|
BlkioThrottleWriteBpsDevice: []*cgroups.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 := cgroups.NewThrottleDevice(8, 0, 2048)
|
|
throttleAfter := td.String()
|
|
|
|
writeFileContents(t, path, map[string]string{
|
|
"blkio.throttle.read_iops_device": throttleBefore,
|
|
})
|
|
|
|
r := &cgroups.Resources{
|
|
BlkioThrottleReadIOPSDevice: []*cgroups.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 := cgroups.NewThrottleDevice(8, 0, 2048)
|
|
throttleAfter := td.String()
|
|
|
|
writeFileContents(t, path, map[string]string{
|
|
"blkio.throttle.write_iops_device": throttleBefore,
|
|
})
|
|
|
|
r := &cgroups.Resources{
|
|
BlkioThrottleWriteIOPSDevice: []*cgroups.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.")
|
|
}
|
|
}
|