Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/common-go/cgroups/cgroups_test.go
2498 views
1
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package cgroups
6
7
import (
8
"math"
9
"os"
10
"path/filepath"
11
"testing"
12
13
"github.com/stretchr/testify/assert"
14
)
15
16
var cgroupPath = []string{"/kubepods", "burstable", "pods234sdf", "234as8df34"}
17
18
func createHierarchy(t *testing.T, cpuEnabled bool) (string, string) {
19
testRoot := t.TempDir()
20
if err := os.WriteFile(filepath.Join(testRoot, "cgroup.controllers"), []byte(""), 0755); err != nil {
21
t.Fatal(err)
22
}
23
24
if err := os.WriteFile(filepath.Join(testRoot, "cgroup.subtree_control"), []byte(""), 0755); err != nil {
25
t.Fatal(err)
26
}
27
28
testCgroup := ""
29
for i, level := range cgroupPath {
30
testCgroup = filepath.Join(testCgroup, level)
31
fullPath := filepath.Join(testRoot, testCgroup)
32
if err := os.Mkdir(fullPath, 0o755); err != nil {
33
t.Fatal(err)
34
}
35
36
ctrlFile, err := os.Create(filepath.Join(fullPath, "cgroup.controllers"))
37
if err != nil {
38
t.Fatal(err)
39
}
40
defer ctrlFile.Close()
41
42
if cpuEnabled {
43
if _, err := ctrlFile.WriteString("cpu"); err != nil {
44
t.Fatal(err)
45
}
46
}
47
48
subTreeFile, err := os.Create(filepath.Join(fullPath, "cgroup.subtree_control"))
49
if err != nil {
50
t.Fatal(err)
51
}
52
defer subTreeFile.Close()
53
54
if cpuEnabled && i < len(cgroupPath)-1 {
55
if _, err := subTreeFile.WriteString("cpu"); err != nil {
56
t.Fatal(err)
57
}
58
}
59
}
60
61
return testRoot, testCgroup
62
}
63
64
func TestEnableController(t *testing.T) {
65
root, cgroup := createHierarchy(t, false)
66
if err := EnsureCpuControllerEnabled(root, cgroup); err != nil {
67
t.Fatal(err)
68
}
69
70
levelPath := root
71
for _, level := range cgroupPath {
72
verifyCpuControllerToggled(t, levelPath, true)
73
levelPath = filepath.Join(levelPath, level)
74
}
75
76
verifyCpuControllerToggled(t, levelPath, false)
77
}
78
79
func verifyCpuControllerToggled(t *testing.T, path string, enabled bool) {
80
t.Helper()
81
82
content, err := os.ReadFile(filepath.Join(path, "cgroup.subtree_control"))
83
if err != nil {
84
t.Fatal(err)
85
}
86
87
if enabled && string(content) != "+cpu" {
88
t.Fatalf("%s should have enabled cpu controller", path)
89
} else if !enabled && string(content) == "+cpu" {
90
t.Fatalf("%s should not have enabled cpu controller", path)
91
}
92
}
93
94
func TestReadSingleValue(t *testing.T) {
95
scenarios := []struct {
96
name string
97
content string
98
expected uint64
99
}{
100
{
101
name: "cgroup2 max value",
102
content: "max",
103
expected: math.MaxUint64,
104
},
105
{
106
name: "cgroup1 max value",
107
content: "-1",
108
expected: math.MaxUint64,
109
},
110
{
111
name: "valid value",
112
content: "100000",
113
expected: 100_000,
114
},
115
}
116
117
for _, s := range scenarios {
118
t.Run(s.name, func(t *testing.T) {
119
f, err := os.CreateTemp("", "cgroup_test*")
120
if err != nil {
121
t.Fatal(err)
122
}
123
124
if _, err := f.Write([]byte(s.content)); err != nil {
125
t.Fatal(err)
126
}
127
128
v, err := ReadSingleValue(f.Name())
129
if err != nil {
130
t.Fatal(err)
131
}
132
133
assert.Equal(t, s.expected, v)
134
})
135
}
136
}
137
138
func TestReadPSI(t *testing.T) {
139
scenarios := []struct {
140
name string
141
content string
142
expected PSI
143
}{
144
{
145
name: "psi some",
146
content: "some avg10=61.00 avg60=64.28 avg300=29.94 total=149969752",
147
expected: PSI{
148
Some: 149969752,
149
Full: 0,
150
},
151
},
152
{
153
name: "psi full",
154
content: "full avg10=36.27 avg60=37.15 avg300=17.59 total=93027571",
155
expected: PSI{
156
Some: 0,
157
Full: 93027571,
158
},
159
},
160
{
161
name: "psi some and full",
162
content: "some avg10=61.00 avg60=64.28 avg300=29.94 total=149969752\nfull avg10=36.27 avg60=37.15 avg300=17.59 total=93027571",
163
expected: PSI{
164
Some: 149969752,
165
Full: 93027571,
166
},
167
},
168
}
169
170
for _, s := range scenarios {
171
t.Run(s.name, func(t *testing.T) {
172
f, err := os.CreateTemp("", "cgroup_test*")
173
if err != nil {
174
t.Fatal(err)
175
}
176
defer os.Remove(f.Name())
177
178
if _, err := f.Write([]byte(s.content)); err != nil {
179
t.Fatal(err)
180
}
181
182
v, err := ReadPSIValue(f.Name())
183
if err != nil {
184
t.Fatal(err)
185
}
186
187
assert.Equal(t, s.expected, v)
188
})
189
}
190
}
191
192