]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-cgroup-util.c
update TODO
[thirdparty/systemd.git] / src / test / test-cgroup-util.c
CommitLineData
6c03089c
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Zbigniew Jędrzejewski-Szmek
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
96cde13a
ZJS
22
23#include "util.h"
24#include "cgroup-util.h"
143bfdaf 25#include "test-helper.h"
6482f626 26#include "formats-util.h"
0b452006 27#include "process-util.h"
96cde13a 28
7027ff61 29static void check_p_d_u(const char *path, int code, const char *result) {
6c03089c 30 _cleanup_free_ char *unit = NULL;
d4fffc4b 31 int r;
96cde13a 32
d4fffc4b
ZJS
33 r = cg_path_decode_unit(path, &unit);
34 printf("%s: %s → %s %d expected %s %d\n", __func__, path, unit, r, result, code);
35 assert_se(r == code);
6c03089c
LP
36 assert_se(streq_ptr(unit, result));
37}
96cde13a 38
7027ff61 39static void test_path_decode_unit(void) {
d7bd3de0
LP
40 check_p_d_u("getty@tty2.service", 0, "getty@tty2.service");
41 check_p_d_u("getty@tty2.service/", 0, "getty@tty2.service");
42 check_p_d_u("getty@tty2.service/xxx", 0, "getty@tty2.service");
cfeaa44a
LP
43 check_p_d_u("getty@.service/", -ENXIO, NULL);
44 check_p_d_u("getty@.service", -ENXIO, NULL);
7027ff61 45 check_p_d_u("getty.service", 0, "getty.service");
cfeaa44a
LP
46 check_p_d_u("getty", -ENXIO, NULL);
47 check_p_d_u("getty/waldo", -ENXIO, NULL);
d7bd3de0 48 check_p_d_u("_cpu.service", 0, "cpu.service");
6c03089c
LP
49}
50
51static void check_p_g_u(const char *path, int code, const char *result) {
52 _cleanup_free_ char *unit = NULL;
d4fffc4b 53 int r;
6c03089c 54
d4fffc4b
ZJS
55 r = cg_path_get_unit(path, &unit);
56 printf("%s: %s → %s %d expected %s %d\n", __func__, path, unit, r, result, code);
57 assert_se(r == code);
6c03089c
LP
58 assert_se(streq_ptr(unit, result));
59}
60
9444b1f2
LP
61static void test_path_get_unit(void) {
62 check_p_g_u("/system.slice/foobar.service/sdfdsaf", 0, "foobar.service");
d7bd3de0
LP
63 check_p_g_u("/system.slice/getty@tty5.service", 0, "getty@tty5.service");
64 check_p_g_u("/system.slice/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service");
65 check_p_g_u("/system.slice/getty@tty5.service/", 0, "getty@tty5.service");
9444b1f2 66 check_p_g_u("/system.slice/getty@tty6.service/tty5", 0, "getty@tty6.service");
cfeaa44a
LP
67 check_p_g_u("sadfdsafsda", -ENXIO, NULL);
68 check_p_g_u("/system.slice/getty####@tty6.service/xxx", -ENXIO, NULL);
9444b1f2 69 check_p_g_u("/system.slice/system-waldo.slice/foobar.service/sdfdsaf", 0, "foobar.service");
d7bd3de0 70 check_p_g_u("/system.slice/system-waldo.slice/_cpu.service/sdfdsaf", 0, "cpu.service");
d4fffc4b 71 check_p_g_u("/user.slice/user-1000.slice/user@1000.service/server.service", 0, "user@1000.service");
cfeaa44a 72 check_p_g_u("/user.slice/user-1000.slice/user@.service/server.service", -ENXIO, NULL);
9444b1f2
LP
73}
74
6c03089c
LP
75static void check_p_g_u_u(const char *path, int code, const char *result) {
76 _cleanup_free_ char *unit = NULL;
d4fffc4b 77 int r;
6c03089c 78
d4fffc4b
ZJS
79 r = cg_path_get_user_unit(path, &unit);
80 printf("%s: %s → %s %d expected %s %d\n", __func__, path, unit, r, result, code);
81 assert_se(r == code);
6c03089c
LP
82 assert_se(streq_ptr(unit, result));
83}
84
9444b1f2 85static void test_path_get_user_unit(void) {
374ec6ab
LP
86 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "foobar.service");
87 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo.slice/foobar.service", 0, "foobar.service");
88 check_p_g_u_u("/user.slice/user-1002.slice/session-2.scope/foobar.service/waldo", 0, "foobar.service");
89 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service/waldo/uuuux", 0, "foobar.service");
cfeaa44a 90 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo/waldo/uuuux", -ENXIO, NULL);
d7bd3de0
LP
91 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service");
92 check_p_g_u_u("/session-2.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service");
93 check_p_g_u_u("/xyz.slice/xyz-waldo.slice/session-77.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service");
cfeaa44a 94 check_p_g_u_u("/meh.service", -ENXIO, NULL);
d7bd3de0 95 check_p_g_u_u("/session-3.scope/_cpu.service", 0, "cpu.service");
d4fffc4b 96 check_p_g_u_u("/user.slice/user-1000.slice/user@1000.service/server.service", 0, "server.service");
32081481 97 check_p_g_u_u("/user.slice/user-1000.slice/user@1000.service/foobar.slice/foobar@pie.service", 0, "foobar@pie.service");
cfeaa44a 98 check_p_g_u_u("/user.slice/user-1000.slice/user@.service/server.service", -ENXIO, NULL);
7027ff61 99}
6c03089c 100
9444b1f2
LP
101static void check_p_g_s(const char *path, int code, const char *result) {
102 _cleanup_free_ char *s = NULL;
103
104 assert_se(cg_path_get_session(path, &s) == code);
105 assert_se(streq_ptr(s, result));
96cde13a
ZJS
106}
107
9444b1f2 108static void test_path_get_session(void) {
374ec6ab
LP
109 check_p_g_s("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "2");
110 check_p_g_s("/session-3.scope", 0, "3");
cfeaa44a
LP
111 check_p_g_s("/session-.scope", -ENXIO, NULL);
112 check_p_g_s("", -ENXIO, NULL);
9444b1f2 113}
7027ff61 114
9444b1f2
LP
115static void check_p_g_o_u(const char *path, int code, uid_t result) {
116 uid_t uid = 0;
7027ff61 117
9444b1f2
LP
118 assert_se(cg_path_get_owner_uid(path, &uid) == code);
119 assert_se(uid == result);
120}
121
122static void test_path_get_owner_uid(void) {
374ec6ab
LP
123 check_p_g_o_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, 1000);
124 check_p_g_o_u("/user.slice/user-1006.slice", 0, 1006);
cfeaa44a 125 check_p_g_o_u("", -ENXIO, 0);
9444b1f2 126}
7027ff61 127
8b0849e9
LP
128static void check_p_g_slice(const char *path, int code, const char *result) {
129 _cleanup_free_ char *s = NULL;
130
131 assert_se(cg_path_get_slice(path, &s) == code);
132 assert_se(streq_ptr(s, result));
133}
134
135static void test_path_get_slice(void) {
136 check_p_g_slice("/user.slice", 0, "user.slice");
137 check_p_g_slice("/foobar", 0, "-.slice");
138 check_p_g_slice("/user.slice/user-waldo.slice", 0, "user-waldo.slice");
139 check_p_g_slice("", 0, "-.slice");
140 check_p_g_slice("foobar", 0, "-.slice");
141 check_p_g_slice("foobar.slice", 0, "foobar.slice");
142 check_p_g_slice("foo.slice/foo-bar.slice/waldo.service", 0, "foo-bar.slice");
143}
144
9444b1f2
LP
145static void test_get_paths(void) {
146 _cleanup_free_ char *a = NULL;
147
148 assert_se(cg_get_root_path(&a) >= 0);
149 log_info("Root = %s", a);
7027ff61
LP
150}
151
aff38e74
LP
152static void test_proc(void) {
153 _cleanup_closedir_ DIR *d = NULL;
154 struct dirent *de;
155 int r;
156
157 d = opendir("/proc");
158 assert_se(d);
159
160 FOREACH_DIRENT(de, d, break) {
e9174f29 161 _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *slice = NULL;
aff38e74 162 pid_t pid;
fed1e721 163 uid_t uid = UID_INVALID;
aff38e74
LP
164
165 if (de->d_type != DT_DIR &&
166 de->d_type != DT_UNKNOWN)
167 continue;
168
169 r = parse_pid(de->d_name, &pid);
170 if (r < 0)
171 continue;
172
ae018d9b
LP
173 if (is_kernel_thread(pid))
174 continue;
175
aff38e74 176 cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &path);
e9174f29 177 cg_pid_get_path_shifted(pid, NULL, &path_shifted);
ae018d9b 178 cg_pid_get_owner_uid(pid, &uid);
aff38e74
LP
179 cg_pid_get_session(pid, &session);
180 cg_pid_get_unit(pid, &unit);
181 cg_pid_get_user_unit(pid, &user_unit);
182 cg_pid_get_machine_name(pid, &machine);
1021b21b 183 cg_pid_get_slice(pid, &slice);
aff38e74 184
de0671ee
ZJS
185 printf(PID_FMT"\t%s\t%s\t"UID_FMT"\t%s\t%s\t%s\t%s\t%s\n",
186 pid,
aff38e74 187 path,
aff38e74 188 path_shifted,
de0671ee 189 uid,
aff38e74
LP
190 session,
191 unit,
192 user_unit,
1021b21b
LP
193 machine,
194 slice);
aff38e74
LP
195 }
196}
197
ae018d9b
LP
198static void test_escape_one(const char *s, const char *r) {
199 _cleanup_free_ char *b;
200
201 b = cg_escape(s);
202 assert_se(b);
203 assert_se(streq(b, r));
204
205 assert_se(streq(cg_unescape(b), s));
206}
207
208static void test_escape(void) {
209 test_escape_one("foobar", "foobar");
a0ab5665 210 test_escape_one(".foobar", "_.foobar");
ae018d9b
LP
211 test_escape_one("foobar.service", "foobar.service");
212 test_escape_one("cgroup.service", "_cgroup.service");
ae018d9b 213 test_escape_one("tasks", "_tasks");
e13bb5d2
KS
214 if (access("/sys/fs/cgroup/cpu", F_OK) == 0)
215 test_escape_one("cpu.service", "_cpu.service");
ae018d9b 216 test_escape_one("_foobar", "__foobar");
a0ab5665
LP
217 test_escape_one("", "_");
218 test_escape_one("_", "__");
219 test_escape_one(".", "_.");
ae018d9b
LP
220}
221
78edb35a
LP
222static void test_controller_is_valid(void) {
223 assert_se(cg_controller_is_valid("foobar", false));
224 assert_se(cg_controller_is_valid("foo_bar", false));
225 assert_se(cg_controller_is_valid("name=foo", true));
226 assert_se(!cg_controller_is_valid("", false));
227 assert_se(!cg_controller_is_valid("name=", true));
228 assert_se(!cg_controller_is_valid("=", false));
229 assert_se(!cg_controller_is_valid("cpu,cpuacct", false));
230 assert_se(!cg_controller_is_valid("_", false));
231 assert_se(!cg_controller_is_valid("_foobar", false));
232 assert_se(!cg_controller_is_valid("tatü", false));
233}
234
a016b922
LP
235static void test_slice_to_path_one(const char *unit, const char *path, int error) {
236 _cleanup_free_ char *ret = NULL;
237
238 assert_se(cg_slice_to_path(unit, &ret) == error);
239 assert_se(streq_ptr(ret, path));
240}
241
242static void test_slice_to_path(void) {
243
244 test_slice_to_path_one("foobar.slice", "foobar.slice", 0);
245 test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0);
246 test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL);
247 test_slice_to_path_one("-.slice", NULL, -EINVAL);
248 test_slice_to_path_one("-foo-.slice", NULL, -EINVAL);
249 test_slice_to_path_one("-foo.slice", NULL, -EINVAL);
250 test_slice_to_path_one("a-b.slice", "a.slice/a-b.slice", 0);
251 test_slice_to_path_one("a-b-c-d-e.slice", "a.slice/a-b.slice/a-b-c.slice/a-b-c-d.slice/a-b-c-d-e.slice", 0);
252}
253
751bc6ac
LP
254static void test_shift_path_one(const char *raw, const char *root, const char *shifted) {
255 const char *s = NULL;
256
257 assert_se(cg_shift_path(raw, root, &s) >= 0);
258 assert_se(streq(s, shifted));
259}
260
261static void test_shift_path(void) {
262
263 test_shift_path_one("/foobar/waldo", "/", "/foobar/waldo");
264 test_shift_path_one("/foobar/waldo", "", "/foobar/waldo");
265 test_shift_path_one("/foobar/waldo", "/foobar", "/waldo");
266 test_shift_path_one("/foobar/waldo", "/fuckfuck", "/foobar/waldo");
267}
268
96cde13a 269int main(void) {
7027ff61 270 test_path_decode_unit();
6c03089c 271 test_path_get_unit();
7027ff61 272 test_path_get_user_unit();
9444b1f2
LP
273 test_path_get_session();
274 test_path_get_owner_uid();
8b0849e9 275 test_path_get_slice();
143bfdaf 276 TEST_REQ_RUNNING_SYSTEMD(test_get_paths());
aff38e74 277 test_proc();
143bfdaf 278 TEST_REQ_RUNNING_SYSTEMD(test_escape());
78edb35a 279 test_controller_is_valid();
a016b922 280 test_slice_to_path();
751bc6ac 281 test_shift_path();
96cde13a
ZJS
282
283 return 0;
284}