]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-path.c
test-path: remove unnecessary check
[thirdparty/systemd.git] / src / test / test-path.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
bc999297 2
bc999297 3#include <stdbool.h>
07630cea 4#include <stdio.h>
edb3ca0d
FB
5#include <sys/stat.h>
6#include <sys/types.h>
bc999297 7
b5efdb8a 8#include "alloc-util.h"
57b7a260 9#include "all-units.h"
f4f15635
LP
10#include "fd-util.h"
11#include "fs-util.h"
bc999297 12#include "macro.h"
07630cea 13#include "manager.h"
bc999297 14#include "mkdir.h"
55890a40 15#include "path-util.h"
c6878637 16#include "rm-rf.h"
07630cea
LP
17#include "string-util.h"
18#include "strv.h"
d2120590 19#include "tests.h"
07630cea
LP
20#include "unit.h"
21#include "util.h"
bc999297
RC
22
23typedef void (*test_function_t)(Manager *m);
24
25static int setup_test(Manager **m) {
26 char **tests_path = STRV_MAKE("exists", "existsglobFOOBAR", "changed", "modified", "unit",
27 "directorynotempty", "makedirectory");
28 char **test_path;
a7f7d1bd 29 Manager *tmp = NULL;
bc999297
RC
30 int r;
31
32 assert_se(m);
33
64ad9e08 34 r = enter_cgroup_subroot(NULL);
317bb217
ZJS
35 if (r == -ENOMEDIUM)
36 return log_tests_skipped("cgroupfs not available");
8c759b33 37
e8112e67 38 r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &tmp);
5eecb103 39 if (manager_errno_skip_test(r))
730d989a 40 return log_tests_skipped_errno(r, "manager_new");
bc999297
RC
41 assert_se(r >= 0);
42 assert_se(manager_startup(tmp, NULL, NULL) >= 0);
43
44 STRV_FOREACH(test_path, tests_path) {
c6878637
LP
45 _cleanup_free_ char *p = NULL;
46
605405c6 47 p = strjoin("/tmp/test-path_", *test_path);
c6878637
LP
48 assert_se(p);
49
50 (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
bc999297
RC
51 }
52
53 *m = tmp;
54
55 return 0;
56}
57
58static void shutdown_test(Manager *m) {
59 assert_se(m);
60
61 manager_free(m);
62}
63
708961c7 64static Service *service_for_path(Manager *m, Path *path, const char *service_name) {
bc999297
RC
65 _cleanup_free_ char *tmp = NULL;
66 Unit *service_unit = NULL;
bc999297
RC
67
68 assert_se(m);
708961c7 69 assert_se(path);
bc999297
RC
70
71 if (!service_name) {
708961c7 72 assert_se(tmp = strreplace(UNIT(path)->id, ".path", ".service"));
bc999297
RC
73 service_unit = manager_get_unit(m, tmp);
74 } else
75 service_unit = manager_get_unit(m, service_name);
76 assert_se(service_unit);
708961c7
MC
77
78 return SERVICE(service_unit);
79}
80
81static void check_states(Manager *m, Path *path, Service *service, PathState path_state, ServiceState service_state) {
708961c7
MC
82 assert_se(m);
83 assert_se(service);
bc999297 84
500727c2 85 usec_t end = now(CLOCK_MONOTONIC) + 30 * USEC_PER_SEC;
708961c7
MC
86
87 while (path->result != PATH_SUCCESS || service->result != SERVICE_SUCCESS ||
88 path->state != path_state || service->state != service_state) {
bc999297 89
500727c2 90 assert_se(sd_event_run(m->event, 100 * USEC_PER_MSEC) >= 0);
bc999297
RC
91
92 printf("%s: state = %s; result = %s \n",
708961c7
MC
93 UNIT(path)->id,
94 path_state_to_string(path->state),
95 path_result_to_string(path->result));
96 printf("%s: state = %s; result = %s \n",
97 UNIT(service)->id,
bc999297
RC
98 service_state_to_string(service->state),
99 service_result_to_string(service->result));
100
500727c2 101 if (now(CLOCK_MONOTONIC) >= end) {
708961c7 102 log_error("Test timeout when testing %s", UNIT(path)->id);
bc999297
RC
103 exit(EXIT_FAILURE);
104 }
105 }
bc999297
RC
106}
107
108static void test_path_exists(Manager *m) {
109 const char *test_path = "/tmp/test-path_exists";
110 Unit *unit = NULL;
708961c7
MC
111 Path *path = NULL;
112 Service *service = NULL;
bc999297
RC
113
114 assert_se(m);
115
ba412430 116 assert_se(manager_load_startable_unit_or_warn(m, "path-exists.path", NULL, &unit) >= 0);
708961c7
MC
117
118 path = PATH(unit);
119 service = service_for_path(m, path, NULL);
120
bd7989a3 121 assert_se(unit_start(unit) >= 0);
708961c7 122 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297
RC
123
124 assert_se(touch(test_path) >= 0);
708961c7
MC
125 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
126
127 /* Service restarts if file still exists */
128 assert_se(unit_stop(UNIT(service)) >= 0);
129 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
130
131 assert_se(rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
132 assert_se(unit_stop(UNIT(service)) >= 0);
133 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297 134
708961c7 135 assert_se(unit_stop(unit) >= 0);
bc999297
RC
136}
137
138static void test_path_existsglob(Manager *m) {
139 const char *test_path = "/tmp/test-path_existsglobFOOBAR";
140 Unit *unit = NULL;
708961c7
MC
141 Path *path = NULL;
142 Service *service = NULL;
bc999297
RC
143
144 assert_se(m);
708961c7 145
ba412430 146 assert_se(manager_load_startable_unit_or_warn(m, "path-existsglob.path", NULL, &unit) >= 0);
708961c7
MC
147
148 path = PATH(unit);
149 service = service_for_path(m, path, NULL);
150
bd7989a3 151 assert_se(unit_start(unit) >= 0);
708961c7 152 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297
RC
153
154 assert_se(touch(test_path) >= 0);
708961c7
MC
155 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
156
157 /* Service restarts if file still exists */
158 assert_se(unit_stop(UNIT(service)) >= 0);
159 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
bc999297 160
708961c7
MC
161 assert_se(rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
162 assert_se(unit_stop(UNIT(service)) >= 0);
163 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
164
165 assert_se(unit_stop(unit) >= 0);
bc999297
RC
166}
167
168static void test_path_changed(Manager *m) {
169 const char *test_path = "/tmp/test-path_changed";
170 FILE *f;
171 Unit *unit = NULL;
708961c7
MC
172 Path *path = NULL;
173 Service *service = NULL;
bc999297
RC
174
175 assert_se(m);
176
ba412430 177 assert_se(manager_load_startable_unit_or_warn(m, "path-changed.path", NULL, &unit) >= 0);
708961c7
MC
178
179 path = PATH(unit);
180 service = service_for_path(m, path, NULL);
181
bd7989a3 182 assert_se(unit_start(unit) >= 0);
708961c7
MC
183 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
184
185 assert_se(touch(test_path) >= 0);
186 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
187
188 /* Service does not restart if file still exists */
189 assert_se(unit_stop(UNIT(service)) >= 0);
190 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297
RC
191
192 f = fopen(test_path, "w");
193 assert_se(f);
194 fclose(f);
195
708961c7
MC
196 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
197
198 assert_se(unit_stop(UNIT(service)) >= 0);
199 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
200
201 (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL);
202 assert_se(unit_stop(unit) >= 0);
bc999297
RC
203}
204
205static void test_path_modified(Manager *m) {
206 _cleanup_fclose_ FILE *f = NULL;
207 const char *test_path = "/tmp/test-path_modified";
208 Unit *unit = NULL;
708961c7
MC
209 Path *path = NULL;
210 Service *service = NULL;
bc999297
RC
211
212 assert_se(m);
213
ba412430 214 assert_se(manager_load_startable_unit_or_warn(m, "path-modified.path", NULL, &unit) >= 0);
708961c7
MC
215
216 path = PATH(unit);
217 service = service_for_path(m, path, NULL);
218
bd7989a3 219 assert_se(unit_start(unit) >= 0);
708961c7
MC
220 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
221
222 assert_se(touch(test_path) >= 0);
223 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
224
225 /* Service does not restart if file still exists */
226 assert_se(unit_stop(UNIT(service)) >= 0);
227 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297
RC
228
229 f = fopen(test_path, "w");
230 assert_se(f);
231 fputs("test", f);
232
708961c7
MC
233 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
234
235 assert_se(unit_stop(UNIT(service)) >= 0);
236 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
237
238 (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL);
239 assert_se(unit_stop(unit) >= 0);
bc999297
RC
240}
241
242static void test_path_unit(Manager *m) {
243 const char *test_path = "/tmp/test-path_unit";
244 Unit *unit = NULL;
708961c7
MC
245 Path *path = NULL;
246 Service *service = NULL;
bc999297
RC
247
248 assert_se(m);
249
ba412430 250 assert_se(manager_load_startable_unit_or_warn(m, "path-unit.path", NULL, &unit) >= 0);
708961c7
MC
251
252 path = PATH(unit);
253 service = service_for_path(m, path, "path-mycustomunit.service");
254
bd7989a3 255 assert_se(unit_start(unit) >= 0);
708961c7 256 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297
RC
257
258 assert_se(touch(test_path) >= 0);
708961c7
MC
259 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
260
261 assert_se(rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
262 assert_se(unit_stop(UNIT(service)) >= 0);
263 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297 264
708961c7 265 assert_se(unit_stop(unit) >= 0);
bc999297
RC
266}
267
268static void test_path_directorynotempty(Manager *m) {
269 const char *test_path = "/tmp/test-path_directorynotempty/";
270 Unit *unit = NULL;
708961c7
MC
271 Path *path = NULL;
272 Service *service = NULL;
bc999297
RC
273
274 assert_se(m);
275
708961c7
MC
276 assert_se(manager_load_startable_unit_or_warn(m, "path-directorynotempty.path", NULL, &unit) >= 0);
277
278 path = PATH(unit);
279 service = service_for_path(m, path, NULL);
280
bc999297
RC
281 assert_se(access(test_path, F_OK) < 0);
282
bd7989a3 283 assert_se(unit_start(unit) >= 0);
708961c7 284 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297
RC
285
286 /* MakeDirectory default to no */
287 assert_se(access(test_path, F_OK) < 0);
288
289 assert_se(mkdir_p(test_path, 0755) >= 0);
63c372cb 290 assert_se(touch(strjoina(test_path, "test_file")) >= 0);
708961c7
MC
291 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
292
293 /* Service restarts if directory is still not empty */
294 assert_se(unit_stop(UNIT(service)) >= 0);
295 check_states(m, path, service, PATH_RUNNING, SERVICE_RUNNING);
296
297 assert_se(rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
298 assert_se(unit_stop(UNIT(service)) >= 0);
299 check_states(m, path, service, PATH_WAITING, SERVICE_DEAD);
bc999297 300
708961c7 301 assert_se(unit_stop(unit) >= 0);
bc999297
RC
302}
303
304static void test_path_makedirectory_directorymode(Manager *m) {
305 const char *test_path = "/tmp/test-path_makedirectory/";
306 Unit *unit = NULL;
307 struct stat s;
308
309 assert_se(m);
310
708961c7
MC
311 assert_se(manager_load_startable_unit_or_warn(m, "path-makedirectory.path", NULL, &unit) >= 0);
312
bc999297
RC
313 assert_se(access(test_path, F_OK) < 0);
314
bd7989a3 315 assert_se(unit_start(unit) >= 0);
bc999297
RC
316
317 /* Check if the directory has been created */
318 assert_se(access(test_path, F_OK) >= 0);
319
320 /* Check the mode we specified with DirectoryMode=0744 */
321 assert_se(stat(test_path, &s) >= 0);
322 assert_se((s.st_mode & S_IRWXU) == 0700);
323 assert_se((s.st_mode & S_IRWXG) == 0040);
324 assert_se((s.st_mode & S_IRWXO) == 0004);
325
bd7989a3 326 assert_se(unit_stop(unit) >= 0);
c6878637 327 (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL);
bc999297
RC
328}
329
330int main(int argc, char *argv[]) {
d2120590 331 static const test_function_t tests[] = {
bc999297
RC
332 test_path_exists,
333 test_path_existsglob,
334 test_path_changed,
335 test_path_modified,
336 test_path_unit,
337 test_path_directorynotempty,
338 test_path_makedirectory_directorymode,
339 NULL,
340 };
d2120590 341
55890a40 342 _cleanup_free_ char *test_path = NULL;
e3643b00 343 _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
bc999297 344
edb3ca0d
FB
345 umask(022);
346
6d7c4033 347 test_setup_logging(LOG_INFO);
bc999297 348
7b432953 349 assert_se(get_testdata_dir("test-path", &test_path) >= 0);
55890a40 350 assert_se(set_unit_path(test_path) >= 0);
3e29e810 351 assert_se(runtime_dir = setup_fake_runtime_dir());
bc999297 352
c87d0661 353 for (const test_function_t *test = tests; *test; test++) {
e3643b00 354 Manager *m = NULL;
bc999297
RC
355 int r;
356
357 /* We create a clean environment for each test */
358 r = setup_test(&m);
317bb217
ZJS
359 if (r != 0)
360 return r;
bc999297
RC
361
362 (*test)(m);
363
364 shutdown_test(m);
365 }
366
367 return 0;
368}