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 periodBefore = 10000
49 periodAfter = 7000
50 rtRuntimeBefore = 8000
51 rtRuntimeAfter = 5000
52 rtPeriodBefore = 10000
53 rtPeriodAfter = 7000
54 )
55
56 writeFileContents(t, path, map[string]string{
57 "cpu.cfs_quota_us": strconv.Itoa(quotaBefore),
58 "cpu.cfs_period_us": strconv.Itoa(periodBefore),
59 "cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
60 "cpu.rt_period_us": strconv.Itoa(rtPeriodBefore),
61 })
62
63 r := &configs.Resources{
64 CpuQuota: quotaAfter,
65 CpuPeriod: periodAfter,
66 CpuRtRuntime: rtRuntimeAfter,
67 CpuRtPeriod: rtPeriodAfter,
68 }
69 cpu := &CpuGroup{}
70 if err := cpu.Set(path, r); err != nil {
71 t.Fatal(err)
72 }
73
74 quota, err := fscommon.GetCgroupParamUint(path, "cpu.cfs_quota_us")
75 if err != nil {
76 t.Fatal(err)
77 }
78 if quota != quotaAfter {
79 t.Fatal("Got the wrong value, set cpu.cfs_quota_us failed.")
80 }
81
82 period, err := fscommon.GetCgroupParamUint(path, "cpu.cfs_period_us")
83 if err != nil {
84 t.Fatal(err)
85 }
86 if period != periodAfter {
87 t.Fatal("Got the wrong value, set cpu.cfs_period_us failed.")
88 }
89
90 rtRuntime, err := fscommon.GetCgroupParamUint(path, "cpu.rt_runtime_us")
91 if err != nil {
92 t.Fatal(err)
93 }
94 if rtRuntime != rtRuntimeAfter {
95 t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
96 }
97
98 rtPeriod, err := fscommon.GetCgroupParamUint(path, "cpu.rt_period_us")
99 if err != nil {
100 t.Fatal(err)
101 }
102 if rtPeriod != rtPeriodAfter {
103 t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
104 }
105 }
106
107 func TestCpuStats(t *testing.T) {
108 path := tempDir(t, "cpu")
109
110 const (
111 nrPeriods = 2000
112 nrThrottled = 200
113 throttledTime = uint64(18446744073709551615)
114 )
115
116 cpuStatContent := fmt.Sprintf("nr_periods %d\nnr_throttled %d\nthrottled_time %d\n",
117 nrPeriods, nrThrottled, throttledTime)
118 writeFileContents(t, path, map[string]string{
119 "cpu.stat": cpuStatContent,
120 })
121
122 cpu := &CpuGroup{}
123 actualStats := *cgroups.NewStats()
124 err := cpu.GetStats(path, &actualStats)
125 if err != nil {
126 t.Fatal(err)
127 }
128
129 expectedStats := cgroups.ThrottlingData{
130 Periods: nrPeriods,
131 ThrottledPeriods: nrThrottled,
132 ThrottledTime: throttledTime,
133 }
134
135 expectThrottlingDataEquals(t, expectedStats, actualStats.CpuStats.ThrottlingData)
136 }
137
138 func TestNoCpuStatFile(t *testing.T) {
139 path := tempDir(t, "cpu")
140
141 cpu := &CpuGroup{}
142 actualStats := *cgroups.NewStats()
143 err := cpu.GetStats(path, &actualStats)
144 if err != nil {
145 t.Fatal("Expected not to fail, but did")
146 }
147 }
148
149 func TestInvalidCpuStat(t *testing.T) {
150 path := tempDir(t, "cpu")
151
152 cpuStatContent := `nr_periods 2000
153 nr_throttled 200
154 throttled_time fortytwo`
155 writeFileContents(t, path, map[string]string{
156 "cpu.stat": cpuStatContent,
157 })
158
159 cpu := &CpuGroup{}
160 actualStats := *cgroups.NewStats()
161 err := cpu.GetStats(path, &actualStats)
162 if err == nil {
163 t.Fatal("Expected failed stat parsing.")
164 }
165 }
166
167 func TestCpuSetRtSchedAtApply(t *testing.T) {
168 path := tempDir(t, "cpu")
169
170 const (
171 rtRuntimeBefore = 0
172 rtRuntimeAfter = 5000
173 rtPeriodBefore = 0
174 rtPeriodAfter = 7000
175 )
176
177 writeFileContents(t, path, map[string]string{
178 "cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
179 "cpu.rt_period_us": strconv.Itoa(rtPeriodBefore),
180 })
181
182 r := &configs.Resources{
183 CpuRtRuntime: rtRuntimeAfter,
184 CpuRtPeriod: rtPeriodAfter,
185 }
186 cpu := &CpuGroup{}
187
188 if err := cpu.Apply(path, r, 1234); err != nil {
189 t.Fatal(err)
190 }
191
192 rtRuntime, err := fscommon.GetCgroupParamUint(path, "cpu.rt_runtime_us")
193 if err != nil {
194 t.Fatal(err)
195 }
196 if rtRuntime != rtRuntimeAfter {
197 t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
198 }
199
200 rtPeriod, err := fscommon.GetCgroupParamUint(path, "cpu.rt_period_us")
201 if err != nil {
202 t.Fatal(err)
203 }
204 if rtPeriod != rtPeriodAfter {
205 t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
206 }
207
208 pid, err := fscommon.GetCgroupParamUint(path, "cgroup.procs")
209 if err != nil {
210 t.Fatal(err)
211 }
212 if pid != 1234 {
213 t.Fatal("Got the wrong value, set cgroup.procs failed.")
214 }
215 }
216
View as plain text