Skip to content

Commit f9ac986

Browse files
committed
WIP: cgroupv2: attempt to update integration tests
1 parent efd562a commit f9ac986

File tree

2 files changed

+162
-32
lines changed

2 files changed

+162
-32
lines changed

cmd/metrics-node-sampler/integration/integration_test.go

+160-32
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,13 @@ func setupTests(t *testing.T, f func([]int) string) {
9999
func(tc *testutil.TestCase) error {
100100
t := tc.T
101101
// create a new container client
102-
var samples samples
102+
var v1samples samplesV1
103+
var v2samples samplesV2
103104
var cfg testConfig
104105
tc.UnmarshalInputsStrict(map[string]interface{}{
105-
"input_samples.yaml": &samples,
106-
"input_test.yaml": &cfg,
106+
"input_samples.yaml": &v1samples,
107+
"input_samples_v2.yaml": &v2samples,
108+
"input_test.yaml": &cfg,
107109
})
108110

109111
// setup the testdata by copying it to a tmp directory
@@ -129,18 +131,36 @@ func setupTests(t *testing.T, f func([]int) string) {
129131
require.NoError(t, os.WriteFile(filepath.Join(testdataCopy, rel), b, 0600))
130132
return nil
131133
})
134+
132135
fs := &fakeFS{
133-
FS: os.DirFS(testdataCopy),
134-
root: testdataCopy,
135-
samples: samples,
136-
index: make(map[string]int),
137-
time: make(map[string]time.Time),
136+
FS: os.DirFS(testdataCopy),
137+
root: testdataCopy,
138+
samplesV1: v1samples,
139+
samplesV2: v2samples,
140+
index: make(map[string]int),
141+
time: make(map[string]time.Time),
138142
}
139143

140144
// get 2 free ports
141145
ports, err := testutil.GetFreePorts(2)
142146
require.NoError(t, err)
143147

148+
var cpuPaths []samplerserverv1alpha1.MetricsFilepath
149+
var memoryPaths []samplerserverv1alpha1.MetricsFilepath
150+
if len(v2samples.CPUSamplesV2) != 0 { // i.e. v2 test
151+
cpuPaths = []samplerserverv1alpha1.MetricsFilepath{
152+
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup"))}
153+
memoryPaths = []samplerserverv1alpha1.MetricsFilepath{
154+
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup"))}
155+
} else {
156+
cpuPaths = []samplerserverv1alpha1.MetricsFilepath{
157+
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup", "cpu")),
158+
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup", "cpuacct")),
159+
}
160+
memoryPaths = []samplerserverv1alpha1.MetricsFilepath{
161+
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup", "memory"))}
162+
}
163+
144164
server := sampler.Server{
145165
SortResults: true, // so the test results are consistent
146166
MetricsNodeSampler: samplerserverv1alpha1.MetricsNodeSampler{
@@ -149,12 +169,8 @@ func setupTests(t *testing.T, f func([]int) string) {
149169
Size: cfg.SampleSize,
150170
},
151171
Reader: samplerserverv1alpha1.Reader{
152-
CPUPaths: []samplerserverv1alpha1.MetricsFilepath{
153-
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup", "cpu")),
154-
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup", "cpuacct")),
155-
},
156-
MemoryPaths: []samplerserverv1alpha1.MetricsFilepath{
157-
samplerserverv1alpha1.MetricsFilepath(filepath.Join("sys", "fs", "cgroup", "memory"))},
172+
CPUPaths: cpuPaths,
173+
MemoryPaths: memoryPaths,
158174
NodeAggregationLevelGlobs: append(samplerserverv1alpha1.DefaultNodeAggregationLevels,
159175
samplerserverv1alpha1.NodeAggregationLevel("system.slice/*"),
160176
samplerserverv1alpha1.NodeAggregationLevel("*"),
@@ -184,6 +200,9 @@ func setupTests(t *testing.T, f func([]int) string) {
184200
var missMatchCount int
185201
require.Eventually(t, func() bool {
186202
tc.Actual = f(ports)
203+
println("Actual: ", tc.Actual)
204+
println("Expected: ", tc.Expected)
205+
println("Actual == Expected ? ", tc.Expected == tc.Actual)
187206
// use protojson because regular json library isn't compatible with proto serialization of int64
188207
require.NoError(t, protojson.Unmarshal([]byte(tc.Actual), &result))
189208
if len(result.Containers) == 0 {
@@ -208,7 +227,7 @@ func setupTests(t *testing.T, f func([]int) string) {
208227
}
209228

210229
return true
211-
}, time.Minute*2, 2*time.Second)
230+
}, time.Second*10, 2*time.Second)
212231

213232
// TODO: test adding a new pod and getting the metrics within ~seconds with
214233
// a reason for the new pod
@@ -221,43 +240,66 @@ func setupTests(t *testing.T, f func([]int) string) {
221240
})
222241
}
223242

224-
type samples struct {
225-
MemorySamples map[string][]MemorySample `yaml:"memorySamples" json:"memorySamples"`
226-
MemoryOOMKillSamples map[string][]MemoryOOMKillSample `yaml:"oomSamples" json:"oomSamples"`
227-
MemoryOOMSamples map[string][]MemoryOOMSample `yaml:"oomKillSamples" json:"oomKillSamples"`
228-
CPUUsageSamples map[string][]CPUUsageSample `yaml:"cpuUsageSamples" json:"cpuUsageSamples"`
229-
CPUThrottlingSamples map[string][]CPUThrottlingSample `yaml:"cpuThrottlingSamples" json:"cpuThrottlingSamples"`
243+
type samplesV1 struct {
244+
MemorySamplesV1 map[string][]MemorySampleV1 `yaml:"memorySamples" json:"memorySamples"`
245+
MemoryOOMKillSamplesV1 map[string][]MemoryOOMKillSampleV1 `yaml:"oomSamples" json:"oomSamples"`
246+
MemoryOOMSamplesV1 map[string][]MemoryOOMSampleV1 `yaml:"oomKillSamples" json:"oomKillSamples"`
247+
CPUUsageSamplesV1 map[string][]CPUUsageSampleV1 `yaml:"cpuUsageSamples" json:"cpuUsageSamples"`
248+
CPUThrottlingSamplesV1 map[string][]CPUThrottlingSampleV1 `yaml:"cpuThrottlingSamples" json:"cpuThrottlingSamples"`
249+
}
250+
251+
type samplesV2 struct {
252+
MemorySamplesV2 map[string][]MemorySampleV2 `yaml:"memorySamples" json:"memorySamples"`
253+
MemoryOOMSamplesV2 map[string][]MemoryOOMSampleV2 `yaml:"memorySamples" json:"oomSamples"`
254+
CPUSamplesV2 map[string][]CPUSampleV2 `yaml:"memorySamples" json:"cpuSamples"`
230255
}
231256

232257
type fakeFS struct {
233-
samples
258+
samplesV1
259+
samplesV2
234260
index map[string]int
235261
time map[string]time.Time
236262
root string
237263
fs.FS
238264
}
239265

240-
type MemorySample struct {
266+
type MemorySampleV1 struct {
241267
RSS int `yaml:"total_rss" json:"total_rss"`
242268
Cache int `yaml:"total_cache" json:"total_cache"`
243269
}
244270

245-
type MemoryOOMKillSample struct {
271+
type MemoryOOMKillSampleV1 struct {
246272
OOMKill int `yaml:"oom_kill" json:"oom_kill"`
247273
}
248274

249-
type MemoryOOMSample int
275+
type MemoryOOMSampleV1 int
250276

251-
type CPUUsageSample struct {
277+
type CPUUsageSampleV1 struct {
252278
Usage int `yaml:"usage" json:"usage"`
253279
}
254280

255-
type CPUThrottlingSample struct {
281+
type CPUThrottlingSampleV1 struct {
256282
ThrottledTime int `yaml:"throttled_time" json:"throttled_time"`
257283
Periods int `yaml:"nr_periods" json:"nr_periods"`
258284
ThrottledPeriods int `yaml:"nr_throttled" json:"nr_throttled"`
259285
}
260286

287+
type MemorySampleV2 struct {
288+
Current int `yaml:"total_rss" json:"usage"`
289+
}
290+
291+
type MemoryOOMSampleV2 struct {
292+
OOMKill int `yaml:"oom_kill" json:"oom_kill"`
293+
OOM int `yaml:"oom_kill" json:"oom"`
294+
}
295+
296+
type CPUSampleV2 struct {
297+
Usage int `yaml:"usage" json:"usage_usec"`
298+
ThrottledTime int `yaml:"throttled_time" json:"throttled_usec"`
299+
Periods int `yaml:"nr_periods" json:"nr_periods"`
300+
ThrottledPeriods int `yaml:"nr_throttled" json:"nr_throttled"`
301+
}
302+
261303
func (fakeFS *fakeFS) Time(name string) time.Time {
262304
t, ok := fakeFS.time[name]
263305
if !ok {
@@ -270,7 +312,7 @@ func (fakeFS *fakeFS) Time(name string) time.Time {
270312
}
271313

272314
func (fakeFS *fakeFS) Open(name string) (fs.File, error) {
273-
if val, ok := fakeFS.MemorySamples[name]; ok {
315+
if val, ok := fakeFS.MemorySamplesV1[name]; ok {
274316
// update the file value by setting its value
275317
index := fakeFS.index[name] % len(val)
276318
fakeFS.index[name] = (index + 1)
@@ -280,7 +322,7 @@ func (fakeFS *fakeFS) Open(name string) (fs.File, error) {
280322
if err != nil {
281323
return nil, err
282324
}
283-
} else if val, ok := fakeFS.CPUUsageSamples[name]; ok {
325+
} else if val, ok := fakeFS.CPUUsageSamplesV1[name]; ok {
284326
var i int
285327
// update the file value by incrementing it
286328
index := fakeFS.index[name] % len(val)
@@ -300,7 +342,7 @@ func (fakeFS *fakeFS) Open(name string) (fs.File, error) {
300342
if err != nil {
301343
return nil, err
302344
}
303-
} else if val, ok := fakeFS.CPUThrottlingSamples[name]; ok {
345+
} else if val, ok := fakeFS.CPUThrottlingSamplesV1[name]; ok {
304346
var throttledTime, periods, periodsThrottled int
305347
// update the file value by incrementing it
306348
index := fakeFS.index[name] % len(val)
@@ -339,7 +381,7 @@ func (fakeFS *fakeFS) Open(name string) (fs.File, error) {
339381
if err != nil {
340382
return nil, err
341383
}
342-
} else if val, ok := fakeFS.MemoryOOMKillSamples[name]; ok {
384+
} else if val, ok := fakeFS.MemoryOOMKillSamplesV1[name]; ok {
343385
// update the file value by setting its value
344386
index := fakeFS.index[name] % len(val)
345387
fakeFS.index[name] = (index + 1)
@@ -359,7 +401,7 @@ func (fakeFS *fakeFS) Open(name string) (fs.File, error) {
359401
if err != nil {
360402
return nil, err
361403
}
362-
} else if val, ok := fakeFS.MemoryOOMSamples[name]; ok {
404+
} else if val, ok := fakeFS.MemoryOOMSamplesV1[name]; ok {
363405
// update the file value by setting its value
364406
index := fakeFS.index[name] % len(val)
365407
fakeFS.index[name] = (index + 1)
@@ -377,6 +419,92 @@ func (fakeFS *fakeFS) Open(name string) (fs.File, error) {
377419
if err != nil {
378420
return nil, err
379421
}
422+
} else if val, ok := fakeFS.MemorySamplesV2[name]; ok {
423+
// update the file value by setting its value
424+
index := fakeFS.index[name] % len(val)
425+
fakeFS.index[name] = (index + 1)
426+
newVal := val[index]
427+
b := fmt.Sprintf("%d\n", newVal.Current)
428+
err := os.WriteFile(filepath.Join(fakeFS.root, name), []byte(b), 0600)
429+
if err != nil {
430+
return nil, err
431+
}
432+
} else if val, ok := fakeFS.CPUSamplesV2[name]; ok {
433+
var usage, throttledTime, periods, periodsThrottled int
434+
// update the file value by incrementing it
435+
index := fakeFS.index[name] % len(val)
436+
fakeFS.index[name] = (index + 1)
437+
inc := val[index]
438+
439+
b, err := os.ReadFile(filepath.Join(fakeFS.root, name))
440+
if err != nil {
441+
return nil, err
442+
}
443+
// parse the value out
444+
for _, line := range strings.Split(string(b), "\n") {
445+
fields := strings.Fields(line)
446+
value, err := strconv.ParseUint(fields[1], 10, 64)
447+
if err != nil {
448+
return nil, err
449+
}
450+
451+
switch fields[0] {
452+
case "usage_usec":
453+
usage = int(value)
454+
case "throttled_usec":
455+
throttledTime = int(value)
456+
case "nr_periods":
457+
periods = int(value)
458+
case "nr_throttled":
459+
periodsThrottled = int(value)
460+
}
461+
}
462+
463+
usage += inc.Usage
464+
throttledTime += inc.ThrottledTime
465+
periods += inc.Periods
466+
periodsThrottled += inc.ThrottledPeriods
467+
468+
err = os.WriteFile(filepath.Join(fakeFS.root, name), []byte(fmt.Sprintf(
469+
"usage_usec %d\nthrottled_usec %d\nnr_periods %d\nnr_throttled %d", usage, throttledTime, periods, periodsThrottled)), 0600)
470+
if err != nil {
471+
return nil, err
472+
}
473+
} else if val, ok := fakeFS.MemoryOOMSamplesV2[name]; ok {
474+
var oom, oomKill int
475+
// update the file value by setting its value
476+
index := fakeFS.index[name] % len(val)
477+
fakeFS.index[name] = (index + 1)
478+
newVal := val[index]
479+
480+
b, err := os.ReadFile(filepath.Join(fakeFS.root, name))
481+
if err != nil {
482+
return nil, err
483+
}
484+
// parse the value out
485+
for _, line := range strings.Split(string(b), "\n") {
486+
fields := strings.Fields(line)
487+
value, err := strconv.ParseUint(fields[1], 10, 64)
488+
if err != nil {
489+
return nil, err
490+
}
491+
492+
switch fields[0] {
493+
case "oom":
494+
oom = int(value)
495+
case "oom_kill":
496+
oomKill = int(value)
497+
}
498+
}
499+
500+
oom += newVal.OOM
501+
oomKill += newVal.OOMKill
502+
503+
err = os.WriteFile(filepath.Join(fakeFS.root, name), []byte(fmt.Sprintf("oom %d\noom_kill %d", oom, oomKill)), 0600)
504+
if err != nil {
505+
return nil, err
506+
}
380507
}
508+
381509
return fakeFS.FS.Open(name)
382510
}

pkg/sampler/cgroup.go

+2
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,10 @@ func (r *metricsReader) GetContainerMemoryMetrics() (memoryMetrics, error) {
240240
var metrics containerMemoryMetrics
241241
var err error
242242
if r.IsCgroupV2() {
243+
println("is cgroupv2")
243244
metrics, err = r.GetLevelMemoryMetricsV2(files)
244245
} else {
246+
println("is not cgroupv2")
245247
metrics, err = r.GetLevelMemoryMetricsV1(files)
246248
}
247249
if err != nil {

0 commit comments

Comments
 (0)