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  }