]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-cgroup-util.c
shared: add formats-util.h
[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"
96cde13a 27
7027ff61 28static void check_p_d_u(const char *path, int code, const char *result) {
6c03089c 29 _cleanup_free_ char *unit = NULL;
d4fffc4b 30 int r;
96cde13a 31
d4fffc4b
ZJS
32 r = cg_path_decode_unit(path, &unit);
33 printf("%s: %s → %s %d expected %s %d\n", __func__, path, unit, r, result, code);
34 assert_se(r == code);
6c03089c
LP
35 assert_se(streq_ptr(unit, result));
36}
96cde13a 37
7027ff61 38static void test_path_decode_unit(void) {
d7bd3de0
LP
39 check_p_d_u("getty@tty2.service", 0, "getty@tty2.service");
40 check_p_d_u("getty@tty2.service/", 0, "getty@tty2.service");
41 check_p_d_u("getty@tty2.service/xxx", 0, "getty@tty2.service");
7027ff61
LP
42 check_p_d_u("getty@.service/", -EINVAL, NULL);
43 check_p_d_u("getty@.service", -EINVAL, NULL);
44 check_p_d_u("getty.service", 0, "getty.service");
45 check_p_d_u("getty", -EINVAL, NULL);
d7bd3de0
LP
46 check_p_d_u("getty/waldo", -EINVAL, NULL);
47 check_p_d_u("_cpu.service", 0, "cpu.service");
6c03089c
LP
48}
49
50static void check_p_g_u(const char *path, int code, const char *result) {
51 _cleanup_free_ char *unit = NULL;
d4fffc4b 52 int r;
6c03089c 53
d4fffc4b
ZJS
54 r = cg_path_get_unit(path, &unit);
55 printf("%s: %s → %s %d expected %s %d\n", __func__, path, unit, r, result, code);
56 assert_se(r == code);
6c03089c
LP
57 assert_se(streq_ptr(unit, result));
58}
59
9444b1f2
LP
60static void test_path_get_unit(void) {
61 check_p_g_u("/system.slice/foobar.service/sdfdsaf", 0, "foobar.service");
d7bd3de0
LP
62 check_p_g_u("/system.slice/getty@tty5.service", 0, "getty@tty5.service");
63 check_p_g_u("/system.slice/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service");
64 check_p_g_u("/system.slice/getty@tty5.service/", 0, "getty@tty5.service");
9444b1f2
LP
65 check_p_g_u("/system.slice/getty@tty6.service/tty5", 0, "getty@tty6.service");
66 check_p_g_u("sadfdsafsda", -EINVAL, NULL);
d7bd3de0 67 check_p_g_u("/system.slice/getty####@tty6.service/xxx", -EINVAL, NULL);
9444b1f2 68 check_p_g_u("/system.slice/system-waldo.slice/foobar.service/sdfdsaf", 0, "foobar.service");
d7bd3de0 69 check_p_g_u("/system.slice/system-waldo.slice/_cpu.service/sdfdsaf", 0, "cpu.service");
d4fffc4b
ZJS
70 check_p_g_u("/user.slice/user-1000.slice/user@1000.service/server.service", 0, "user@1000.service");
71 check_p_g_u("/user.slice/user-1000.slice/user@.service/server.service", -EINVAL, NULL);
9444b1f2
LP
72}
73
6c03089c
LP
74static void check_p_g_u_u(const char *path, int code, const char *result) {
75 _cleanup_free_ char *unit = NULL;
d4fffc4b 76 int r;
6c03089c 77
d4fffc4b
ZJS
78 r = cg_path_get_user_unit(path, &unit);
79 printf("%s: %s → %s %d expected %s %d\n", __func__, path, unit, r, result, code);
80 assert_se(r == code);
6c03089c
LP
81 assert_se(streq_ptr(unit, result));
82}
83
9444b1f2 84static void test_path_get_user_unit(void) {
374ec6ab
LP
85 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "foobar.service");
86 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo.slice/foobar.service", 0, "foobar.service");
87 check_p_g_u_u("/user.slice/user-1002.slice/session-2.scope/foobar.service/waldo", 0, "foobar.service");
88 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service/waldo/uuuux", 0, "foobar.service");
89 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo/waldo/uuuux", -EINVAL, NULL);
d7bd3de0
LP
90 check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service");
91 check_p_g_u_u("/session-2.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service");
92 check_p_g_u_u("/xyz.slice/xyz-waldo.slice/session-77.scope/foobar@pie.service/pa/po", 0, "foobar@pie.service");
9444b1f2 93 check_p_g_u_u("/meh.service", -ENOENT, NULL);
d7bd3de0 94 check_p_g_u_u("/session-3.scope/_cpu.service", 0, "cpu.service");
d4fffc4b 95 check_p_g_u_u("/user.slice/user-1000.slice/user@1000.service/server.service", 0, "server.service");
32081481 96 check_p_g_u_u("/user.slice/user-1000.slice/user@1000.service/foobar.slice/foobar@pie.service", 0, "foobar@pie.service");
d4fffc4b 97 check_p_g_u_u("/user.slice/user-1000.slice/user@.service/server.service", -ENOENT, NULL);
7027ff61 98}
6c03089c 99
9444b1f2
LP
100static void check_p_g_s(const char *path, int code, const char *result) {
101 _cleanup_free_ char *s = NULL;
102
103 assert_se(cg_path_get_session(path, &s) == code);
104 assert_se(streq_ptr(s, result));
96cde13a
ZJS
105}
106
9444b1f2 107static void test_path_get_session(void) {
374ec6ab
LP
108 check_p_g_s("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "2");
109 check_p_g_s("/session-3.scope", 0, "3");
a13ee4c7
ZJS
110 check_p_g_s("/session-.scope", -ENOENT, NULL);
111 check_p_g_s("", -ENOENT, NULL);
9444b1f2 112}
7027ff61 113
9444b1f2
LP
114static void check_p_g_o_u(const char *path, int code, uid_t result) {
115 uid_t uid = 0;
7027ff61 116
9444b1f2
LP
117 assert_se(cg_path_get_owner_uid(path, &uid) == code);
118 assert_se(uid == result);
119}
120
121static void test_path_get_owner_uid(void) {
374ec6ab
LP
122 check_p_g_o_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, 1000);
123 check_p_g_o_u("/user.slice/user-1006.slice", 0, 1006);
9444b1f2
LP
124 check_p_g_o_u("", -ENOENT, 0);
125}
7027ff61 126
9444b1f2
LP
127static void test_get_paths(void) {
128 _cleanup_free_ char *a = NULL;
129
130 assert_se(cg_get_root_path(&a) >= 0);
131 log_info("Root = %s", a);
7027ff61
LP
132}
133
aff38e74
LP
134static void test_proc(void) {
135 _cleanup_closedir_ DIR *d = NULL;
136 struct dirent *de;
137 int r;
138
139 d = opendir("/proc");
140 assert_se(d);
141
142 FOREACH_DIRENT(de, d, break) {
e9174f29 143 _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *slice = NULL;
aff38e74 144 pid_t pid;
fed1e721 145 uid_t uid = UID_INVALID;
aff38e74
LP
146
147 if (de->d_type != DT_DIR &&
148 de->d_type != DT_UNKNOWN)
149 continue;
150
151 r = parse_pid(de->d_name, &pid);
152 if (r < 0)
153 continue;
154
ae018d9b
LP
155 if (is_kernel_thread(pid))
156 continue;
157
aff38e74 158 cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &path);
e9174f29 159 cg_pid_get_path_shifted(pid, NULL, &path_shifted);
ae018d9b 160 cg_pid_get_owner_uid(pid, &uid);
aff38e74
LP
161 cg_pid_get_session(pid, &session);
162 cg_pid_get_unit(pid, &unit);
163 cg_pid_get_user_unit(pid, &user_unit);
164 cg_pid_get_machine_name(pid, &machine);
1021b21b 165 cg_pid_get_slice(pid, &slice);
aff38e74 166
de0671ee
ZJS
167 printf(PID_FMT"\t%s\t%s\t"UID_FMT"\t%s\t%s\t%s\t%s\t%s\n",
168 pid,
aff38e74 169 path,
aff38e74 170 path_shifted,
de0671ee 171 uid,
aff38e74
LP
172 session,
173 unit,
174 user_unit,
1021b21b
LP
175 machine,
176 slice);
aff38e74
LP
177 }
178}
179
ae018d9b
LP
180static void test_escape_one(const char *s, const char *r) {
181 _cleanup_free_ char *b;
182
183 b = cg_escape(s);
184 assert_se(b);
185 assert_se(streq(b, r));
186
187 assert_se(streq(cg_unescape(b), s));
188}
189
190static void test_escape(void) {
191 test_escape_one("foobar", "foobar");
a0ab5665 192 test_escape_one(".foobar", "_.foobar");
ae018d9b
LP
193 test_escape_one("foobar.service", "foobar.service");
194 test_escape_one("cgroup.service", "_cgroup.service");
ae018d9b 195 test_escape_one("tasks", "_tasks");
e13bb5d2
KS
196 if (access("/sys/fs/cgroup/cpu", F_OK) == 0)
197 test_escape_one("cpu.service", "_cpu.service");
ae018d9b 198 test_escape_one("_foobar", "__foobar");
a0ab5665
LP
199 test_escape_one("", "_");
200 test_escape_one("_", "__");
201 test_escape_one(".", "_.");
ae018d9b
LP
202}
203
78edb35a
LP
204static void test_controller_is_valid(void) {
205 assert_se(cg_controller_is_valid("foobar", false));
206 assert_se(cg_controller_is_valid("foo_bar", false));
207 assert_se(cg_controller_is_valid("name=foo", true));
208 assert_se(!cg_controller_is_valid("", false));
209 assert_se(!cg_controller_is_valid("name=", true));
210 assert_se(!cg_controller_is_valid("=", false));
211 assert_se(!cg_controller_is_valid("cpu,cpuacct", false));
212 assert_se(!cg_controller_is_valid("_", false));
213 assert_se(!cg_controller_is_valid("_foobar", false));
214 assert_se(!cg_controller_is_valid("tatü", false));
215}
216
a016b922
LP
217static void test_slice_to_path_one(const char *unit, const char *path, int error) {
218 _cleanup_free_ char *ret = NULL;
219
220 assert_se(cg_slice_to_path(unit, &ret) == error);
221 assert_se(streq_ptr(ret, path));
222}
223
224static void test_slice_to_path(void) {
225
226 test_slice_to_path_one("foobar.slice", "foobar.slice", 0);
227 test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0);
228 test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL);
229 test_slice_to_path_one("-.slice", NULL, -EINVAL);
230 test_slice_to_path_one("-foo-.slice", NULL, -EINVAL);
231 test_slice_to_path_one("-foo.slice", NULL, -EINVAL);
232 test_slice_to_path_one("a-b.slice", "a.slice/a-b.slice", 0);
233 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);
234}
235
751bc6ac
LP
236static void test_shift_path_one(const char *raw, const char *root, const char *shifted) {
237 const char *s = NULL;
238
239 assert_se(cg_shift_path(raw, root, &s) >= 0);
240 assert_se(streq(s, shifted));
241}
242
243static void test_shift_path(void) {
244
245 test_shift_path_one("/foobar/waldo", "/", "/foobar/waldo");
246 test_shift_path_one("/foobar/waldo", "", "/foobar/waldo");
247 test_shift_path_one("/foobar/waldo", "/foobar", "/waldo");
248 test_shift_path_one("/foobar/waldo", "/fuckfuck", "/foobar/waldo");
249}
250
96cde13a 251int main(void) {
7027ff61 252 test_path_decode_unit();
6c03089c 253 test_path_get_unit();
7027ff61 254 test_path_get_user_unit();
9444b1f2
LP
255 test_path_get_session();
256 test_path_get_owner_uid();
143bfdaf 257 TEST_REQ_RUNNING_SYSTEMD(test_get_paths());
aff38e74 258 test_proc();
143bfdaf 259 TEST_REQ_RUNNING_SYSTEMD(test_escape());
78edb35a 260 test_controller_is_valid();
a016b922 261 test_slice_to_path();
751bc6ac 262 test_shift_path();
96cde13a
ZJS
263
264 return 0;
265}