]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-cgroup-util.c
bus: fix return message if StartServiceByName() in the driver fails due
[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#include <assert.h>
23
24#include "util.h"
25#include "cgroup-util.h"
143bfdaf 26#include "test-helper.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
ZJS
95 check_p_g_u_u("/user.slice/user-1000.slice/user@1000.service/server.service", 0, "server.service");
96 check_p_g_u_u("/user.slice/user-1000.slice/user@.service/server.service", -ENOENT, NULL);
7027ff61 97}
6c03089c 98
9444b1f2
LP
99static void check_p_g_s(const char *path, int code, const char *result) {
100 _cleanup_free_ char *s = NULL;
101
102 assert_se(cg_path_get_session(path, &s) == code);
103 assert_se(streq_ptr(s, result));
96cde13a
ZJS
104}
105
9444b1f2 106static void test_path_get_session(void) {
374ec6ab
LP
107 check_p_g_s("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "2");
108 check_p_g_s("/session-3.scope", 0, "3");
9444b1f2
LP
109 check_p_g_s("", -ENOENT, 0);
110}
7027ff61 111
9444b1f2
LP
112static void check_p_g_o_u(const char *path, int code, uid_t result) {
113 uid_t uid = 0;
7027ff61 114
9444b1f2
LP
115 assert_se(cg_path_get_owner_uid(path, &uid) == code);
116 assert_se(uid == result);
117}
118
119static void test_path_get_owner_uid(void) {
374ec6ab
LP
120 check_p_g_o_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, 1000);
121 check_p_g_o_u("/user.slice/user-1006.slice", 0, 1006);
9444b1f2
LP
122 check_p_g_o_u("", -ENOENT, 0);
123}
7027ff61 124
9444b1f2
LP
125static void check_p_g_m_n(const char *path, int code, const char *result) {
126 _cleanup_free_ char *m = NULL;
7027ff61 127
9444b1f2
LP
128 assert_se(cg_path_get_machine_name(path, &m) == code);
129 assert_se(streq_ptr(m, result));
130}
131
132static void test_path_get_machine_name(void) {
374ec6ab
LP
133 check_p_g_m_n("/user.slice/machine-foobar.scope", 0, "foobar");
134 check_p_g_m_n("/machine-foobar.scope", 0, "foobar");
135 check_p_g_m_n("/user.slice/user-kuux.slice/machine-foobar.scope", 0, "foobar");
136 check_p_g_m_n("/user.slice/user-kuux.slice/machine-foobar.scope/asjhdkj", 0, "foobar");
9444b1f2
LP
137 check_p_g_m_n("", -ENOENT, NULL);
138}
139
140static void test_get_paths(void) {
141 _cleanup_free_ char *a = NULL;
142
143 assert_se(cg_get_root_path(&a) >= 0);
144 log_info("Root = %s", a);
7027ff61
LP
145}
146
aff38e74
LP
147static void test_proc(void) {
148 _cleanup_closedir_ DIR *d = NULL;
149 struct dirent *de;
150 int r;
151
152 d = opendir("/proc");
153 assert_se(d);
154
155 FOREACH_DIRENT(de, d, break) {
e9174f29 156 _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *slice = NULL;
aff38e74 157 pid_t pid;
ae018d9b 158 uid_t uid = (uid_t) -1;
aff38e74
LP
159
160 if (de->d_type != DT_DIR &&
161 de->d_type != DT_UNKNOWN)
162 continue;
163
164 r = parse_pid(de->d_name, &pid);
165 if (r < 0)
166 continue;
167
ae018d9b
LP
168 if (is_kernel_thread(pid))
169 continue;
170
aff38e74 171 cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &path);
e9174f29 172 cg_pid_get_path_shifted(pid, NULL, &path_shifted);
ae018d9b 173 cg_pid_get_owner_uid(pid, &uid);
aff38e74
LP
174 cg_pid_get_session(pid, &session);
175 cg_pid_get_unit(pid, &unit);
176 cg_pid_get_user_unit(pid, &user_unit);
177 cg_pid_get_machine_name(pid, &machine);
1021b21b 178 cg_pid_get_slice(pid, &slice);
aff38e74 179
e9174f29 180 printf("%lu\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\t%s\n",
aff38e74
LP
181 (unsigned long) pid,
182 path,
aff38e74 183 path_shifted,
ae018d9b 184 (unsigned long) uid,
aff38e74
LP
185 session,
186 unit,
187 user_unit,
1021b21b
LP
188 machine,
189 slice);
aff38e74
LP
190 }
191}
192
ae018d9b
LP
193static void test_escape_one(const char *s, const char *r) {
194 _cleanup_free_ char *b;
195
196 b = cg_escape(s);
197 assert_se(b);
198 assert_se(streq(b, r));
199
200 assert_se(streq(cg_unescape(b), s));
201}
202
203static void test_escape(void) {
204 test_escape_one("foobar", "foobar");
a0ab5665 205 test_escape_one(".foobar", "_.foobar");
ae018d9b
LP
206 test_escape_one("foobar.service", "foobar.service");
207 test_escape_one("cgroup.service", "_cgroup.service");
ae018d9b 208 test_escape_one("tasks", "_tasks");
e13bb5d2
KS
209 if (access("/sys/fs/cgroup/cpu", F_OK) == 0)
210 test_escape_one("cpu.service", "_cpu.service");
ae018d9b 211 test_escape_one("_foobar", "__foobar");
a0ab5665
LP
212 test_escape_one("", "_");
213 test_escape_one("_", "__");
214 test_escape_one(".", "_.");
ae018d9b
LP
215}
216
78edb35a
LP
217static void test_controller_is_valid(void) {
218 assert_se(cg_controller_is_valid("foobar", false));
219 assert_se(cg_controller_is_valid("foo_bar", false));
220 assert_se(cg_controller_is_valid("name=foo", true));
221 assert_se(!cg_controller_is_valid("", false));
222 assert_se(!cg_controller_is_valid("name=", true));
223 assert_se(!cg_controller_is_valid("=", false));
224 assert_se(!cg_controller_is_valid("cpu,cpuacct", false));
225 assert_se(!cg_controller_is_valid("_", false));
226 assert_se(!cg_controller_is_valid("_foobar", false));
227 assert_se(!cg_controller_is_valid("tatü", false));
228}
229
a016b922
LP
230static void test_slice_to_path_one(const char *unit, const char *path, int error) {
231 _cleanup_free_ char *ret = NULL;
232
233 assert_se(cg_slice_to_path(unit, &ret) == error);
234 assert_se(streq_ptr(ret, path));
235}
236
237static void test_slice_to_path(void) {
238
239 test_slice_to_path_one("foobar.slice", "foobar.slice", 0);
240 test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0);
241 test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL);
242 test_slice_to_path_one("-.slice", NULL, -EINVAL);
243 test_slice_to_path_one("-foo-.slice", NULL, -EINVAL);
244 test_slice_to_path_one("-foo.slice", NULL, -EINVAL);
245 test_slice_to_path_one("a-b.slice", "a.slice/a-b.slice", 0);
246 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);
247}
248
96cde13a 249int main(void) {
7027ff61 250 test_path_decode_unit();
6c03089c 251 test_path_get_unit();
7027ff61 252 test_path_get_user_unit();
9444b1f2
LP
253 test_path_get_session();
254 test_path_get_owner_uid();
255 test_path_get_machine_name();
143bfdaf 256 TEST_REQ_RUNNING_SYSTEMD(test_get_paths());
aff38e74 257 test_proc();
143bfdaf 258 TEST_REQ_RUNNING_SYSTEMD(test_escape());
78edb35a 259 test_controller_is_valid();
a016b922 260 test_slice_to_path();
96cde13a
ZJS
261
262 return 0;
263}