github.com/opencontainers/runtime-tools@v0.9.0/validation/linux_cgroups_cpus/linux_cgroups_cpus.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "runtime" 8 9 "github.com/mndrix/tap-go" 10 "github.com/opencontainers/runtime-tools/cgroups" 11 "github.com/opencontainers/runtime-tools/validation/util" 12 ) 13 14 const ( 15 defaultRealtimePeriod uint64 = 1000000 16 defaultRealtimeRuntime int64 = 950000 17 ) 18 19 func testCPUCgroups() error { 20 t := tap.New() 21 t.Header(0) 22 defer t.AutoPlan() 23 24 CPUrange := fmt.Sprintf("0-%d", runtime.NumCPU()-1) 25 26 // Test with different combinations of values. 27 // NOTE: most systems have only one memory node (mems=="0"), so we cannot 28 // simply test with multiple values of mems. 29 cases := []struct { 30 shares uint64 31 period uint64 32 quota int64 33 cpus string 34 mems string 35 }{ 36 {1024, 100000, 50000, "0", "0"}, 37 {1024, 100000, 50000, CPUrange, "0"}, 38 {1024, 100000, 200000, "0", "0"}, 39 {1024, 100000, 200000, CPUrange, "0"}, 40 {1024, 500000, 50000, "0", "0"}, 41 {1024, 500000, 50000, CPUrange, "0"}, 42 {1024, 500000, 200000, "0", "0"}, 43 {1024, 500000, 200000, CPUrange, "0"}, 44 {2048, 100000, 50000, "0", "0"}, 45 {2048, 100000, 50000, CPUrange, "0"}, 46 {2048, 100000, 200000, "0", "0"}, 47 {2048, 100000, 200000, CPUrange, "0"}, 48 {2048, 500000, 50000, "0", "0"}, 49 {2048, 500000, 50000, CPUrange, "0"}, 50 {2048, 500000, 200000, "0", "0"}, 51 {2048, 500000, 200000, CPUrange, "0"}, 52 } 53 54 for _, c := range cases { 55 g, err := util.GetDefaultGenerator() 56 if err != nil { 57 return fmt.Errorf("cannot get default config from generator: %v", err) 58 } 59 60 g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath) 61 62 if c.shares > 0 { 63 g.SetLinuxResourcesCPUShares(c.shares) 64 } 65 66 if c.period > 0 { 67 g.SetLinuxResourcesCPUPeriod(c.period) 68 } 69 70 if c.quota > 0 { 71 g.SetLinuxResourcesCPUQuota(c.quota) 72 } 73 74 if c.cpus != "" { 75 g.SetLinuxResourcesCPUCpus(c.cpus) 76 } 77 78 if c.mems != "" { 79 g.SetLinuxResourcesCPUMems(c.mems) 80 } 81 82 // NOTE: On most systems where CONFIG_RT_GROUP & CONFIG_RT_GROUP_SCHED are not enabled, 83 // the following tests will fail, because sysfs knobs like 84 // /sys/fs/cgroup/cpu,cpuacct/cpu.rt_{period,runtime}_us do not exist. 85 // So we need to check if the sysfs knobs exist before setting the variables. 86 if _, err := os.Stat(filepath.Join(util.CPUCgroupPrefix, "cpu.rt_period_us")); !os.IsNotExist(err) { 87 g.SetLinuxResourcesCPURealtimePeriod(defaultRealtimePeriod) 88 } 89 90 if _, err := os.Stat(filepath.Join(util.CPUCgroupPrefix, "cpu.rt_runtime_us")); !os.IsNotExist(err) { 91 g.SetLinuxResourcesCPURealtimeRuntime(defaultRealtimeRuntime) 92 } 93 94 if err := util.RuntimeOutsideValidate(g, t, util.ValidateLinuxResourcesCPU); err != nil { 95 return fmt.Errorf("cannot validate CPU cgroups: %v", err) 96 } 97 } 98 99 return nil 100 } 101 102 func testEmptyCPU() error { 103 t := tap.New() 104 t.Header(0) 105 defer t.AutoPlan() 106 107 g, err := util.GetDefaultGenerator() 108 if err != nil { 109 return fmt.Errorf("cannot get default config from generator: %v", err) 110 } 111 g.InitConfigLinuxResourcesCPU() 112 g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath) 113 114 if err := util.RuntimeOutsideValidate(g, t, util.ValidateLinuxResourcesCPUEmpty); err != nil { 115 return fmt.Errorf("cannot validate empty CPU cgroups: %v", err) 116 } 117 118 return nil 119 } 120 121 func main() { 122 if "linux" != runtime.GOOS { 123 util.Fatal(fmt.Errorf("linux-specific cgroup test")) 124 } 125 126 if err := testCPUCgroups(); err != nil { 127 util.Fatal(err) 128 } 129 130 if err := testEmptyCPU(); err != nil { 131 util.Fatal(err) 132 } 133 }