]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-path.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / test / test-path.c
CommitLineData
bc999297
RC
1/***
2 This file is part of systemd.
3
4 Copyright 2014 Ronny Chevalier
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
bc999297 20#include <stdbool.h>
07630cea 21#include <stdio.h>
bc999297 22
bc999297 23#include "macro.h"
07630cea 24#include "manager.h"
bc999297 25#include "mkdir.h"
c6878637 26#include "rm-rf.h"
07630cea
LP
27#include "string-util.h"
28#include "strv.h"
29#include "unit.h"
30#include "util.h"
bc999297
RC
31
32typedef void (*test_function_t)(Manager *m);
33
34static int setup_test(Manager **m) {
35 char **tests_path = STRV_MAKE("exists", "existsglobFOOBAR", "changed", "modified", "unit",
36 "directorynotempty", "makedirectory");
37 char **test_path;
a7f7d1bd 38 Manager *tmp = NULL;
bc999297
RC
39 int r;
40
41 assert_se(m);
42
b2c23da8 43 r = manager_new(MANAGER_USER, true, &tmp);
3b3a64d7 44 if (IN_SET(r, -EPERM, -EACCES, -EADDRINUSE, -EHOSTDOWN, -ENOENT, -ENOEXEC)) {
bc999297
RC
45 printf("Skipping test: manager_new: %s", strerror(-r));
46 return -EXIT_TEST_SKIP;
47 }
48 assert_se(r >= 0);
49 assert_se(manager_startup(tmp, NULL, NULL) >= 0);
50
51 STRV_FOREACH(test_path, tests_path) {
c6878637
LP
52 _cleanup_free_ char *p = NULL;
53
54 p = strjoin("/tmp/test-path_", *test_path, NULL);
55 assert_se(p);
56
57 (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
bc999297
RC
58 }
59
60 *m = tmp;
61
62 return 0;
63}
64
65static void shutdown_test(Manager *m) {
66 assert_se(m);
67
68 manager_free(m);
69}
70
71static void check_stop_unlink(Manager *m, Unit *unit, const char *test_path, const char *service_name) {
72 _cleanup_free_ char *tmp = NULL;
73 Unit *service_unit = NULL;
74 Service *service = NULL;
75 usec_t ts;
76 usec_t timeout = 2 * USEC_PER_SEC;
77
78 assert_se(m);
79 assert_se(unit);
80 assert_se(test_path);
81
82 if (!service_name) {
83 assert_se(tmp = strreplace(unit->id, ".path", ".service"));
84 service_unit = manager_get_unit(m, tmp);
85 } else
86 service_unit = manager_get_unit(m, service_name);
87 assert_se(service_unit);
88 service = SERVICE(service_unit);
89
90 ts = now(CLOCK_MONOTONIC);
f131770b 91 /* We process events until the service related to the path has been successfully started */
bc999297
RC
92 while(service->result != SERVICE_SUCCESS || service->state != SERVICE_START) {
93 usec_t n;
94 int r;
95
96 r = sd_event_run(m->event, 100 * USEC_PER_MSEC);
97 assert_se(r >= 0);
98
99 printf("%s: state = %s; result = %s \n",
100 service_unit->id,
101 service_state_to_string(service->state),
102 service_result_to_string(service->result));
103
104
105 /* But we timeout if the service has not been started in the allocated time */
106 n = now(CLOCK_MONOTONIC);
107 if (ts + timeout < n) {
108 log_error("Test timeout when testing %s", unit->id);
109 exit(EXIT_FAILURE);
110 }
111 }
112
113 assert_se(UNIT_VTABLE(unit)->stop(unit) >= 0);
c6878637 114 (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL);
bc999297
RC
115}
116
117static void test_path_exists(Manager *m) {
118 const char *test_path = "/tmp/test-path_exists";
119 Unit *unit = NULL;
120
121 assert_se(m);
122
123 assert_se(manager_load_unit(m, "path-exists.path", NULL, NULL, &unit) >= 0);
124 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
125
126 assert_se(touch(test_path) >= 0);
127
128 check_stop_unlink(m, unit, test_path, NULL);
129}
130
131static void test_path_existsglob(Manager *m) {
132 const char *test_path = "/tmp/test-path_existsglobFOOBAR";
133 Unit *unit = NULL;
134
135 assert_se(m);
136 assert_se(manager_load_unit(m, "path-existsglob.path", NULL, NULL, &unit) >= 0);
137 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
138
139 assert_se(touch(test_path) >= 0);
140
141 check_stop_unlink(m, unit, test_path, NULL);
142}
143
144static void test_path_changed(Manager *m) {
145 const char *test_path = "/tmp/test-path_changed";
146 FILE *f;
147 Unit *unit = NULL;
148
149 assert_se(m);
150
151 assert_se(touch(test_path) >= 0);
152
153 assert_se(manager_load_unit(m, "path-changed.path", NULL, NULL, &unit) >= 0);
154 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
155
156 f = fopen(test_path, "w");
157 assert_se(f);
158 fclose(f);
159
160 check_stop_unlink(m, unit, test_path, NULL);
161}
162
163static void test_path_modified(Manager *m) {
164 _cleanup_fclose_ FILE *f = NULL;
165 const char *test_path = "/tmp/test-path_modified";
166 Unit *unit = NULL;
167
168 assert_se(m);
169
170 assert_se(touch(test_path) >= 0);
171
172 assert_se(manager_load_unit(m, "path-modified.path", NULL, NULL, &unit) >= 0);
173 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
174
175 f = fopen(test_path, "w");
176 assert_se(f);
177 fputs("test", f);
178
179 check_stop_unlink(m, unit, test_path, NULL);
180}
181
182static void test_path_unit(Manager *m) {
183 const char *test_path = "/tmp/test-path_unit";
184 Unit *unit = NULL;
185
186 assert_se(m);
187
188 assert_se(manager_load_unit(m, "path-unit.path", NULL, NULL, &unit) >= 0);
189 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
190
191 assert_se(touch(test_path) >= 0);
192
193 check_stop_unlink(m, unit, test_path, "path-mycustomunit.service");
194}
195
196static void test_path_directorynotempty(Manager *m) {
197 const char *test_path = "/tmp/test-path_directorynotempty/";
198 Unit *unit = NULL;
199
200 assert_se(m);
201
202 assert_se(access(test_path, F_OK) < 0);
203
204 assert_se(manager_load_unit(m, "path-directorynotempty.path", NULL, NULL, &unit) >= 0);
205 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
206
207 /* MakeDirectory default to no */
208 assert_se(access(test_path, F_OK) < 0);
209
210 assert_se(mkdir_p(test_path, 0755) >= 0);
63c372cb 211 assert_se(touch(strjoina(test_path, "test_file")) >= 0);
bc999297
RC
212
213 check_stop_unlink(m, unit, test_path, NULL);
214}
215
216static void test_path_makedirectory_directorymode(Manager *m) {
217 const char *test_path = "/tmp/test-path_makedirectory/";
218 Unit *unit = NULL;
219 struct stat s;
220
221 assert_se(m);
222
223 assert_se(access(test_path, F_OK) < 0);
224
225 assert_se(manager_load_unit(m, "path-makedirectory.path", NULL, NULL, &unit) >= 0);
226 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
227
228 /* Check if the directory has been created */
229 assert_se(access(test_path, F_OK) >= 0);
230
231 /* Check the mode we specified with DirectoryMode=0744 */
232 assert_se(stat(test_path, &s) >= 0);
233 assert_se((s.st_mode & S_IRWXU) == 0700);
234 assert_se((s.st_mode & S_IRWXG) == 0040);
235 assert_se((s.st_mode & S_IRWXO) == 0004);
236
237 assert_se(UNIT_VTABLE(unit)->stop(unit) >= 0);
c6878637 238 (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL);
bc999297
RC
239}
240
241int main(int argc, char *argv[]) {
242 test_function_t tests[] = {
243 test_path_exists,
244 test_path_existsglob,
245 test_path_changed,
246 test_path_modified,
247 test_path_unit,
248 test_path_directorynotempty,
249 test_path_makedirectory_directorymode,
250 NULL,
251 };
252 test_function_t *test = NULL;
253 Manager *m = NULL;
254
255 log_parse_environment();
256 log_open();
257
ca909b84 258 assert_se(set_unit_path(TEST_DIR) >= 0);
bc999297
RC
259
260 for (test = tests; test && *test; test++) {
261 int r;
262
263 /* We create a clean environment for each test */
264 r = setup_test(&m);
265 if (r < 0)
266 return -r;
267
268 (*test)(m);
269
270 shutdown_test(m);
271 }
272
273 return 0;
274}