chiark / gitweb /
Allow for the use of @ in remote host calls
[elogind.git] / src / test / test-cgroup-util.c
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
22 #include <assert.h>
23
24 #include "util.h"
25 #include "cgroup-util.h"
26
27 static void check_p_d_u(const char *path, int code, const char *result) {
28         _cleanup_free_ char *unit = NULL;
29
30         assert_se(cg_path_decode_unit(path, &unit) == code);
31         assert_se(streq_ptr(unit, result));
32 }
33
34 static void test_path_decode_unit(void) {
35         check_p_d_u("getty@.service/getty@tty2.service", 0, "getty@tty2.service");
36         check_p_d_u("getty@.service/getty@tty2.service/xxx", 0, "getty@tty2.service");
37         check_p_d_u("getty@.service/", -EINVAL, NULL);
38         check_p_d_u("getty@.service", -EINVAL, NULL);
39         check_p_d_u("getty.service", 0, "getty.service");
40         check_p_d_u("getty", -EINVAL, NULL);
41 }
42
43 static void check_p_g_u(const char *path, int code, const char *result) {
44         _cleanup_free_ char *unit = NULL;
45
46         assert_se(cg_path_get_unit(path, &unit) == code);
47         assert_se(streq_ptr(unit, result));
48 }
49
50 static void check_p_g_u_u(const char *path, int code, const char *result) {
51         _cleanup_free_ char *unit = NULL;
52
53         assert_se(cg_path_get_user_unit(path, &unit) == code);
54         assert_se(streq_ptr(unit, result));
55 }
56
57 static void test_path_get_unit(void) {
58         check_p_g_u("/system/foobar.service/sdfdsaf", 0, "foobar.service");
59         check_p_g_u("/system/getty@.service/getty@tty5.service", 0, "getty@tty5.service");
60         check_p_g_u("/system/getty@.service/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service");
61         check_p_g_u("/system/getty@.service/getty@tty5.service/", 0, "getty@tty5.service");
62         check_p_g_u("/system/getty@tty6.service/tty5", 0, "getty@tty6.service");
63         check_p_g_u("sadfdsafsda", -ENOENT, NULL);
64         check_p_g_u("/system/getty####@tty6.service/tty5", -EINVAL, NULL);
65 }
66
67 static void test_path_get_user_unit(void) {
68         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service", 0, "foobar.service");
69         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service/waldo", 0, "foobar.service");
70         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service/waldo/uuuux", 0, "foobar.service");
71         check_p_g_u_u("/user/lennart/2/systemd-21548/waldo/waldo/uuuux", -EINVAL, NULL);
72         check_p_g_u_u("/user/lennart/2/foobar.service", -ENOENT, NULL);
73         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service");
74 }
75
76 static void test_get_paths(void) {
77         _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL;
78
79         assert_se(cg_get_root_path(&a) >= 0);
80         log_info("Root = %s", a);
81
82         assert_se(cg_get_system_path(&b) >= 0);
83         log_info("System = %s", b);
84
85         assert_se(cg_get_user_path(&c) >= 0);
86         log_info("User = %s", c);
87
88         assert_se(cg_get_machine_path("harley", &d) >= 0);
89         log_info("Machine = %s", d);
90 }
91
92 static void test_proc(void) {
93         _cleanup_closedir_ DIR *d = NULL;
94         struct dirent *de;
95         int r;
96
97         d = opendir("/proc");
98         assert_se(d);
99
100         FOREACH_DIRENT(de, d, break) {
101                 _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *prefix = NULL;
102                 pid_t pid;
103                 uid_t uid = (uid_t) -1;
104
105                 if (de->d_type != DT_DIR &&
106                     de->d_type != DT_UNKNOWN)
107                         continue;
108
109                 r = parse_pid(de->d_name, &pid);
110                 if (r < 0)
111                         continue;
112
113                 if (is_kernel_thread(pid))
114                         continue;
115
116                 cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &path);
117                 cg_pid_get_path_shifted(pid, &prefix, &path_shifted);
118                 cg_pid_get_owner_uid(pid, &uid);
119                 cg_pid_get_session(pid, &session);
120                 cg_pid_get_unit(pid, &unit);
121                 cg_pid_get_user_unit(pid, &user_unit);
122                 cg_pid_get_machine_name(pid, &machine);
123
124                 printf("%lu\t%s\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\n",
125                        (unsigned long) pid,
126                        path,
127                        prefix,
128                        path_shifted,
129                        (unsigned long) uid,
130                        session,
131                        unit,
132                        user_unit,
133                        machine);
134         }
135 }
136
137 static void test_escape_one(const char *s, const char *r) {
138         _cleanup_free_ char *b;
139
140         b = cg_escape(s);
141         assert_se(b);
142         assert_se(streq(b, r));
143
144         assert_se(streq(cg_unescape(b), s));
145 }
146
147 static void test_escape(void) {
148         test_escape_one("foobar", "foobar");
149         test_escape_one(".foobar", "_.foobar");
150         test_escape_one("foobar.service", "foobar.service");
151         test_escape_one("cgroup.service", "_cgroup.service");
152         test_escape_one("cpu.service", "_cpu.service");
153         test_escape_one("tasks", "_tasks");
154         test_escape_one("_foobar", "__foobar");
155         test_escape_one("", "_");
156         test_escape_one("_", "__");
157         test_escape_one(".", "_.");
158 }
159
160 static void test_controller_is_valid(void) {
161         assert_se(cg_controller_is_valid("foobar", false));
162         assert_se(cg_controller_is_valid("foo_bar", false));
163         assert_se(cg_controller_is_valid("name=foo", true));
164         assert_se(!cg_controller_is_valid("", false));
165         assert_se(!cg_controller_is_valid("name=", true));
166         assert_se(!cg_controller_is_valid("=", false));
167         assert_se(!cg_controller_is_valid("cpu,cpuacct", false));
168         assert_se(!cg_controller_is_valid("_", false));
169         assert_se(!cg_controller_is_valid("_foobar", false));
170         assert_se(!cg_controller_is_valid("tatü", false));
171 }
172
173 int main(void) {
174         test_path_decode_unit();
175         test_path_get_unit();
176         test_path_get_user_unit();
177         test_get_paths();
178         test_proc();
179         test_escape();
180         test_controller_is_valid();
181
182         return 0;
183 }