github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/libcontainer/cgroups/fs/cpu_test.go (about)

     1  package fs
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"testing"
     7  
     8  	"github.com/opencontainers/runc/libcontainer/cgroups"
     9  	"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
    10  	"github.com/opencontainers/runc/libcontainer/configs"
    11  )
    12  
    13  func TestCpuSetShares(t *testing.T) {
    14  	path := tempDir(t, "cpu")
    15  
    16  	const (
    17  		sharesBefore = 1024
    18  		sharesAfter  = 512
    19  	)
    20  
    21  	writeFileContents(t, path, map[string]string{
    22  		"cpu.shares": strconv.Itoa(sharesBefore),
    23  	})
    24  
    25  	r := &configs.Resources{
    26  		CpuShares: sharesAfter,
    27  	}
    28  	cpu := &CpuGroup{}
    29  	if err := cpu.Set(path, r); err != nil {
    30  		t.Fatal(err)
    31  	}
    32  
    33  	value, err := fscommon.GetCgroupParamUint(path, "cpu.shares")
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	if value != sharesAfter {
    38  		t.Fatal("Got the wrong value, set cpu.shares failed.")
    39  	}
    40  }
    41  
    42  func TestCpuSetBandWidth(t *testing.T) {
    43  	path := tempDir(t, "cpu")
    44  
    45  	const (
    46  		quotaBefore     = 8000
    47  		quotaAfter      = 5000
    48  		burstBefore     = 2000
    49  		periodBefore    = 10000
    50  		periodAfter     = 7000
    51  		rtRuntimeBefore = 8000
    52  		rtRuntimeAfter  = 5000
    53  		rtPeriodBefore  = 10000
    54  		rtPeriodAfter   = 7000
    55  	)
    56  	burstAfter := uint64(1000)
    57  
    58  	writeFileContents(t, path, map[string]string{
    59  		"cpu.cfs_quota_us":  strconv.Itoa(quotaBefore),
    60  		"cpu.cfs_burst_us":  strconv.Itoa(burstBefore),
    61  		"cpu.cfs_period_us": strconv.Itoa(periodBefore),
    62  		"cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
    63  		"cpu.rt_period_us":  strconv.Itoa(rtPeriodBefore),
    64  	})
    65  
    66  	r := &configs.Resources{
    67  		CpuQuota:     quotaAfter,
    68  		CpuBurst:     &burstAfter,
    69  		CpuPeriod:    periodAfter,
    70  		CpuRtRuntime: rtRuntimeAfter,
    71  		CpuRtPeriod:  rtPeriodAfter,
    72  	}
    73  	cpu := &CpuGroup{}
    74  	if err := cpu.Set(path, r); err != nil {
    75  		t.Fatal(err)
    76  	}
    77  
    78  	quota, err := fscommon.GetCgroupParamUint(path, "cpu.cfs_quota_us")
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	if quota != quotaAfter {
    83  		t.Fatal("Got the wrong value, set cpu.cfs_quota_us failed.")
    84  	}
    85  
    86  	burst, err := fscommon.GetCgroupParamUint(path, "cpu.cfs_burst_us")
    87  	if err != nil {
    88  		t.Fatal(err)
    89  	}
    90  	if burst != burstAfter {
    91  		t.Fatal("Got the wrong value, set cpu.cfs_burst_us failed.")
    92  	}
    93  
    94  	period, err := fscommon.GetCgroupParamUint(path, "cpu.cfs_period_us")
    95  	if err != nil {
    96  		t.Fatal(err)
    97  	}
    98  	if period != periodAfter {
    99  		t.Fatal("Got the wrong value, set cpu.cfs_period_us failed.")
   100  	}
   101  
   102  	rtRuntime, err := fscommon.GetCgroupParamUint(path, "cpu.rt_runtime_us")
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	if rtRuntime != rtRuntimeAfter {
   107  		t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
   108  	}
   109  
   110  	rtPeriod, err := fscommon.GetCgroupParamUint(path, "cpu.rt_period_us")
   111  	if err != nil {
   112  		t.Fatal(err)
   113  	}
   114  	if rtPeriod != rtPeriodAfter {
   115  		t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
   116  	}
   117  }
   118  
   119  func TestCpuStats(t *testing.T) {
   120  	path := tempDir(t, "cpu")
   121  
   122  	const (
   123  		nrPeriods     = 2000
   124  		nrThrottled   = 200
   125  		throttledTime = uint64(18446744073709551615)
   126  	)
   127  
   128  	cpuStatContent := fmt.Sprintf("nr_periods %d\nnr_throttled %d\nthrottled_time %d\n",
   129  		nrPeriods, nrThrottled, throttledTime)
   130  	writeFileContents(t, path, map[string]string{
   131  		"cpu.stat": cpuStatContent,
   132  	})
   133  
   134  	cpu := &CpuGroup{}
   135  	actualStats := *cgroups.NewStats()
   136  	err := cpu.GetStats(path, &actualStats)
   137  	if err != nil {
   138  		t.Fatal(err)
   139  	}
   140  
   141  	expectedStats := cgroups.ThrottlingData{
   142  		Periods:          nrPeriods,
   143  		ThrottledPeriods: nrThrottled,
   144  		ThrottledTime:    throttledTime,
   145  	}
   146  
   147  	expectThrottlingDataEquals(t, expectedStats, actualStats.CpuStats.ThrottlingData)
   148  }
   149  
   150  func TestNoCpuStatFile(t *testing.T) {
   151  	path := tempDir(t, "cpu")
   152  
   153  	cpu := &CpuGroup{}
   154  	actualStats := *cgroups.NewStats()
   155  	err := cpu.GetStats(path, &actualStats)
   156  	if err != nil {
   157  		t.Fatal("Expected not to fail, but did")
   158  	}
   159  }
   160  
   161  func TestInvalidCpuStat(t *testing.T) {
   162  	path := tempDir(t, "cpu")
   163  
   164  	cpuStatContent := `nr_periods 2000
   165  	nr_throttled 200
   166  	throttled_time fortytwo`
   167  	writeFileContents(t, path, map[string]string{
   168  		"cpu.stat": cpuStatContent,
   169  	})
   170  
   171  	cpu := &CpuGroup{}
   172  	actualStats := *cgroups.NewStats()
   173  	err := cpu.GetStats(path, &actualStats)
   174  	if err == nil {
   175  		t.Fatal("Expected failed stat parsing.")
   176  	}
   177  }
   178  
   179  func TestCpuSetRtSchedAtApply(t *testing.T) {
   180  	path := tempDir(t, "cpu")
   181  
   182  	const (
   183  		rtRuntimeBefore = 0
   184  		rtRuntimeAfter  = 5000
   185  		rtPeriodBefore  = 0
   186  		rtPeriodAfter   = 7000
   187  	)
   188  
   189  	writeFileContents(t, path, map[string]string{
   190  		"cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
   191  		"cpu.rt_period_us":  strconv.Itoa(rtPeriodBefore),
   192  	})
   193  
   194  	r := &configs.Resources{
   195  		CpuRtRuntime: rtRuntimeAfter,
   196  		CpuRtPeriod:  rtPeriodAfter,
   197  	}
   198  	cpu := &CpuGroup{}
   199  
   200  	if err := cpu.Apply(path, r, 1234); err != nil {
   201  		t.Fatal(err)
   202  	}
   203  
   204  	rtRuntime, err := fscommon.GetCgroupParamUint(path, "cpu.rt_runtime_us")
   205  	if err != nil {
   206  		t.Fatal(err)
   207  	}
   208  	if rtRuntime != rtRuntimeAfter {
   209  		t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
   210  	}
   211  
   212  	rtPeriod, err := fscommon.GetCgroupParamUint(path, "cpu.rt_period_us")
   213  	if err != nil {
   214  		t.Fatal(err)
   215  	}
   216  	if rtPeriod != rtPeriodAfter {
   217  		t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
   218  	}
   219  
   220  	pid, err := fscommon.GetCgroupParamUint(path, "cgroup.procs")
   221  	if err != nil {
   222  		t.Fatal(err)
   223  	}
   224  	if pid != 1234 {
   225  		t.Fatal("Got the wrong value, set cgroup.procs failed.")
   226  	}
   227  }