xref: /netbsd-src/external/bsd/kyua-testers/dist/fs_test.c (revision 63dd2c4874872d80b37ddca02243878f37000ebd)
1 // Copyright 2012 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 //   notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 //   notice, this list of conditions and the following disclaimer in the
12 //   documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 //   may be used to endorse or promote products derived from this software
15 //   without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include "fs.h"
30 
31 #include <sys/stat.h>
32 #include <sys/wait.h>
33 
34 #include <assert.h>
35 #include <dirent.h>
36 #include <err.h>
37 #include <errno.h>
38 #include <signal.h>
39 #include <stdbool.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 
45 #include <atf-c.h>
46 
47 #include "error.h"
48 
49 
50 static void run_mount_tmpfs(const char*) KYUA_DEFS_NORETURN;
51 
52 
53 /// Operating systems recognized by the code below.
54 enum os_type {
55     os_unsupported = 0,
56     os_freebsd,
57     os_linux,
58     os_netbsd,
59     os_sunos,
60 };
61 
62 
63 /// The current operating system.
64 static enum os_type current_os =
65 #if defined(__FreeBSD__)
66     os_freebsd
67 #elif defined(__linux__)
68     os_linux
69 #elif defined(__NetBSD__)
70     os_netbsd
71 #elif defined(__SunOS__)
72     os_sunos
73 #else
74     os_unsupported
75 #endif
76     ;
77 
78 
79 /// Checks if a directory entry exists and matches a specific type.
80 ///
81 /// \param dir The directory in which to look for the entry.
82 /// \param name The name of the entry to look up.
83 /// \param expected_type The expected type of the file as given by dir(5).
84 ///
85 /// \return True if the entry exists and matches the given type; false
86 /// otherwise.
87 static bool
lookup(const char * dir,const char * name,const int expected_type)88 lookup(const char* dir, const char* name, const int expected_type)
89 {
90     DIR* dirp = opendir(dir);
91     ATF_REQUIRE(dirp != NULL);
92 
93     bool found = false;
94     struct dirent* dp;
95     while (!found && (dp = readdir(dirp)) != NULL) {
96         if (strcmp(dp->d_name, name) == 0 &&
97             dp->d_type == expected_type) {
98             found = true;
99         }
100     }
101     closedir(dirp);
102     return found;
103 }
104 
105 
106 /// Executes 'mount -t tmpfs' (or a similar variant).
107 ///
108 /// This function must be called from a subprocess, as it never returns.
109 ///
110 /// \param mount_point Location on which to mount a tmpfs.
111 static void
run_mount_tmpfs(const char * mount_point)112 run_mount_tmpfs(const char* mount_point)
113 {
114     const char* mount_args[16];
115 
116     size_t last = 0;
117     switch (current_os) {
118     case os_freebsd:
119         mount_args[last++] = "mdmfs";
120         mount_args[last++] = "-s16m";
121         mount_args[last++] = "md";
122         mount_args[last++] = mount_point;
123         break;
124 
125     case os_linux:
126         mount_args[last++] = "mount";
127         mount_args[last++] = "-ttmpfs";
128         mount_args[last++] = "tmpfs";
129         mount_args[last++] = mount_point;
130         break;
131 
132     case os_netbsd:
133         mount_args[last++] = "mount";
134         mount_args[last++] = "-ttmpfs";
135         mount_args[last++] = "tmpfs";
136         mount_args[last++] = mount_point;
137         break;
138 
139     case os_sunos:
140         mount_args[last++] = "mount";
141         mount_args[last++] = "-Ftmpfs";
142         mount_args[last++] = "tmpfs";
143         mount_args[last++] = mount_point;
144         break;
145 
146     default:
147         err(123, "Don't know how to mount a file system for testing "
148             "purposes");
149     }
150     mount_args[last] = NULL;
151 
152     const char** arg;
153     printf("Mounting tmpfs onto %s with:", mount_point);
154     for (arg = &mount_args[0]; *arg != NULL; arg++)
155         printf(" %s", *arg);
156     printf("\n");
157 
158     const int ret = execvp(mount_args[0], KYUA_DEFS_UNCONST(mount_args));
159     assert(ret == -1);
160     err(EXIT_FAILURE, "Failed to exec %s", mount_args[0]);
161 };
162 
163 
164 /// Mounts a temporary file system.
165 ///
166 /// This is only provided for testing purposes.  The mounted file system
167 /// contains no valuable data.
168 ///
169 /// Note that the calling test case is skipped if the current operating system
170 /// is not supported.
171 ///
172 /// \param mount_point The path on which the file system will be mounted.
173 static void
mount_tmpfs(const char * mount_point)174 mount_tmpfs(const char* mount_point)
175 {
176     // SunOS's mount(8) requires paths to be absolute.  To err on the side of
177     // caution, let's make it absolute in all cases.
178     //const fspath abs_mount_point = mount_point.is_absolute() ?
179     //    mount_point : mount_point.to_absolute();
180 
181     pid_t pid = fork();
182     ATF_REQUIRE(pid != -1);
183     if (pid == 0)
184         run_mount_tmpfs(mount_point);
185     int status;
186     ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
187     ATF_REQUIRE(WIFEXITED(status));
188     if (WEXITSTATUS(status) == 123)
189         atf_tc_skip("Don't know how to mount a file system for testing "
190                     "purposes");
191     else
192         ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
193 }
194 
195 
196 static bool
lchmod_fails(void)197 lchmod_fails(void)
198 {
199     ATF_REQUIRE(mkdir("test", 0755) != -1);
200     return lchmod("test", 0700) == -1 && chmod("test", 0700) != -1;
201 }
202 
203 
204 ATF_TC_WITHOUT_HEAD(cleanup__file);
ATF_TC_BODY(cleanup__file,tc)205 ATF_TC_BODY(cleanup__file, tc)
206 {
207     atf_utils_create_file("root", "%s", "");
208     ATF_REQUIRE(lookup(".", "root", DT_REG));
209     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
210     ATF_REQUIRE(!lookup(".", "root", DT_REG));
211 }
212 
213 
214 ATF_TC_WITHOUT_HEAD(cleanup__subdir__empty);
ATF_TC_BODY(cleanup__subdir__empty,tc)215 ATF_TC_BODY(cleanup__subdir__empty, tc)
216 {
217     ATF_REQUIRE(mkdir("root", 0755) != -1);
218     ATF_REQUIRE(lookup(".", "root", DT_DIR));
219     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
220     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
221 }
222 
223 
224 ATF_TC_WITHOUT_HEAD(cleanup__subdir__files_and_directories);
ATF_TC_BODY(cleanup__subdir__files_and_directories,tc)225 ATF_TC_BODY(cleanup__subdir__files_and_directories, tc)
226 {
227     ATF_REQUIRE(mkdir("root", 0755) != -1);
228     atf_utils_create_file("root/.hidden_file", "%s", "");
229     ATF_REQUIRE(mkdir("root/.hidden_dir", 0755) != -1);
230     atf_utils_create_file("root/.hidden_dir/a", "%s", "");
231     atf_utils_create_file("root/file", "%s", "");
232     atf_utils_create_file("root/with spaces", "%s", "");
233     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
234     ATF_REQUIRE(mkdir("root/dir1/dir2", 0755) != -1);
235     atf_utils_create_file("root/dir1/dir2/file", "%s", "");
236     ATF_REQUIRE(mkdir("root/dir1/dir3", 0755) != -1);
237     ATF_REQUIRE(lookup(".", "root", DT_DIR));
238     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
239     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
240 }
241 
242 
243 ATF_TC_WITHOUT_HEAD(cleanup__subdir__unprotect_regular);
ATF_TC_BODY(cleanup__subdir__unprotect_regular,tc)244 ATF_TC_BODY(cleanup__subdir__unprotect_regular, tc)
245 {
246     ATF_REQUIRE(mkdir("root", 0755) != -1);
247     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
248     ATF_REQUIRE(mkdir("root/dir1/dir2", 0755) != -1);
249     atf_utils_create_file("root/dir1/dir2/file", "%s", "");
250     ATF_REQUIRE(chmod("root/dir1/dir2/file", 0000) != -1);
251     ATF_REQUIRE(chmod("root/dir1/dir2", 0000) != -1);
252     ATF_REQUIRE(chmod("root/dir1", 0000) != -1);
253     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
254     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
255 }
256 
257 
258 ATF_TC(cleanup__subdir__unprotect_symlink);
ATF_TC_HEAD(cleanup__subdir__unprotect_symlink,tc)259 ATF_TC_HEAD(cleanup__subdir__unprotect_symlink, tc)
260 {
261     atf_tc_set_md_var(tc, "require.progs", "/bin/ls");
262     // We are ensuring that chmod is not run on the target of a symlink, so
263     // we cannot be root (nor we don't want to, to prevent unprotecting a
264     // system file!).
265     atf_tc_set_md_var(tc, "require.user", "unprivileged");
266 }
ATF_TC_BODY(cleanup__subdir__unprotect_symlink,tc)267 ATF_TC_BODY(cleanup__subdir__unprotect_symlink, tc)
268 {
269     ATF_REQUIRE(mkdir("root", 0755) != -1);
270     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
271     ATF_REQUIRE(symlink("/bin/ls", "root/dir1/ls") != -1);
272     ATF_REQUIRE(chmod("root/dir1", 0555) != -1);
273     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
274     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
275 }
276 
277 
278 ATF_TC_WITHOUT_HEAD(cleanup__subdir__links);
ATF_TC_BODY(cleanup__subdir__links,tc)279 ATF_TC_BODY(cleanup__subdir__links, tc)
280 {
281     ATF_REQUIRE(mkdir("root", 0755) != -1);
282     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
283     ATF_REQUIRE(symlink("../../root", "root/dir1/loop") != -1);
284     ATF_REQUIRE(symlink("non-existent", "root/missing") != -1);
285     ATF_REQUIRE(lookup(".", "root", DT_DIR));
286     kyua_error_t error = kyua_fs_cleanup("root");
287     if (kyua_error_is_set(error)) {
288         if (lchmod_fails())
289             atf_tc_expect_fail("lchmod(2) is not implemented in your system");
290         kyua_error_free(error);
291         atf_tc_fail("kyua_fs_cleanup returned an error");
292     }
293     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
294 }
295 
296 
297 ATF_TC(cleanup__mount_point__simple);
ATF_TC_HEAD(cleanup__mount_point__simple,tc)298 ATF_TC_HEAD(cleanup__mount_point__simple, tc)
299 {
300     atf_tc_set_md_var(tc, "require.user", "root");
301 }
ATF_TC_BODY(cleanup__mount_point__simple,tc)302 ATF_TC_BODY(cleanup__mount_point__simple, tc)
303 {
304     ATF_REQUIRE(mkdir("root", 0755) != -1);
305     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
306     atf_utils_create_file("root/zz", "%s", "");
307     mount_tmpfs("root/dir1");
308     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
309     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
310 }
311 
312 
313 ATF_TC(cleanup__mount_point__overlayed);
ATF_TC_HEAD(cleanup__mount_point__overlayed,tc)314 ATF_TC_HEAD(cleanup__mount_point__overlayed, tc)
315 {
316     atf_tc_set_md_var(tc, "require.user", "root");
317 }
ATF_TC_BODY(cleanup__mount_point__overlayed,tc)318 ATF_TC_BODY(cleanup__mount_point__overlayed, tc)
319 {
320     ATF_REQUIRE(mkdir("root", 0755) != -1);
321     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
322     atf_utils_create_file("root/zz", "%s", "");
323     mount_tmpfs("root/dir1");
324     mount_tmpfs("root/dir1");
325     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
326     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
327 }
328 
329 
330 ATF_TC(cleanup__mount_point__nested);
ATF_TC_HEAD(cleanup__mount_point__nested,tc)331 ATF_TC_HEAD(cleanup__mount_point__nested, tc)
332 {
333     atf_tc_set_md_var(tc, "require.user", "root");
334 }
ATF_TC_BODY(cleanup__mount_point__nested,tc)335 ATF_TC_BODY(cleanup__mount_point__nested, tc)
336 {
337     ATF_REQUIRE(mkdir("root", 0755) != -1);
338     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
339     ATF_REQUIRE(mkdir("root/dir1/dir2", 0755) != -1);
340     ATF_REQUIRE(mkdir("root/dir3", 0755) != -1);
341     mount_tmpfs("root/dir1/dir2");
342     mount_tmpfs("root/dir3");
343     ATF_REQUIRE(mkdir("root/dir1/dir2/dir4", 0755) != -1);
344     mount_tmpfs("root/dir1/dir2/dir4");
345     ATF_REQUIRE(mkdir("root/dir1/dir2/not-mount-point", 0755) != -1);
346     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
347     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
348 }
349 
350 
351 ATF_TC(cleanup__mount_point__links);
ATF_TC_HEAD(cleanup__mount_point__links,tc)352 ATF_TC_HEAD(cleanup__mount_point__links, tc)
353 {
354     atf_tc_set_md_var(tc, "require.user", "root");
355 }
ATF_TC_BODY(cleanup__mount_point__links,tc)356 ATF_TC_BODY(cleanup__mount_point__links, tc)
357 {
358     ATF_REQUIRE(mkdir("root", 0755) != -1);
359     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
360     ATF_REQUIRE(mkdir("root/dir3", 0755) != -1);
361     mount_tmpfs("root/dir1");
362     ATF_REQUIRE(symlink("../dir3", "root/dir1/link") != -1);
363     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
364     ATF_REQUIRE(!lookup(".", "root", DT_DIR));
365 }
366 
367 
368 ATF_TC(cleanup__mount_point__busy);
ATF_TC_HEAD(cleanup__mount_point__busy,tc)369 ATF_TC_HEAD(cleanup__mount_point__busy, tc)
370 {
371     atf_tc_set_md_var(tc, "require.user", "root");
372 }
ATF_TC_BODY(cleanup__mount_point__busy,tc)373 ATF_TC_BODY(cleanup__mount_point__busy, tc)
374 {
375     ATF_REQUIRE(mkdir("root", 0755) != -1);
376     ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
377     mount_tmpfs("root/dir1");
378 
379     pid_t pid = fork();
380     ATF_REQUIRE(pid != -1);
381     if (pid == 0) {
382         if (chdir("root/dir1") == -1)
383             abort();
384 
385         atf_utils_create_file("dont-delete-me", "%s", "");
386         atf_utils_create_file("../../done", "%s", "");
387 
388         pause();
389         exit(EXIT_SUCCESS);
390     } else {
391         fprintf(stderr, "Waiting for child to finish preparations\n");
392         while (!atf_utils_file_exists("done")) {}
393         fprintf(stderr, "Child done; cleaning up\n");
394 
395         ATF_REQUIRE(kyua_error_is_set(kyua_fs_cleanup("root")));
396         ATF_REQUIRE(atf_utils_file_exists("root/dir1/dont-delete-me"));
397 
398         fprintf(stderr, "Killing child\n");
399         ATF_REQUIRE(kill(pid, SIGKILL) != -1);
400         int status;
401         ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
402 
403         ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
404         ATF_REQUIRE(!lookup(".", "root", DT_DIR));
405     }
406 }
407 
408 
409 ATF_TC_WITHOUT_HEAD(concat__one);
ATF_TC_BODY(concat__one,tc)410 ATF_TC_BODY(concat__one, tc)
411 {
412     char* path;
413     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_concat(&path, "foo", NULL)));
414     ATF_REQUIRE_STREQ("foo", path);
415     free(path);
416 }
417 
418 
419 ATF_TC_WITHOUT_HEAD(concat__two);
ATF_TC_BODY(concat__two,tc)420 ATF_TC_BODY(concat__two, tc)
421 {
422     char* path;
423     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_concat(&path, "foo", "bar", NULL)));
424     ATF_REQUIRE_STREQ("foo/bar", path);
425     free(path);
426 }
427 
428 
429 ATF_TC_WITHOUT_HEAD(concat__several);
ATF_TC_BODY(concat__several,tc)430 ATF_TC_BODY(concat__several, tc)
431 {
432     char* path;
433     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_concat(&path, "/usr", ".", "bin",
434                                                   "ls", NULL)));
435     ATF_REQUIRE_STREQ("/usr/./bin/ls", path);
436     free(path);
437 }
438 
439 
440 ATF_TC_WITHOUT_HEAD(current_path__ok);
ATF_TC_BODY(current_path__ok,tc)441 ATF_TC_BODY(current_path__ok, tc)
442 {
443     char* previous;
444     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_current_path(&previous)));
445 
446     ATF_REQUIRE(mkdir("root", 0755) != -1);
447     ATF_REQUIRE(chdir("root") != -1);
448     char* cwd;
449     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_current_path(&cwd)));
450 
451     char* exp_cwd;
452     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_concat(&exp_cwd, previous, "root",
453                                                   NULL)));
454     ATF_REQUIRE_STREQ(exp_cwd, cwd);
455 
456     free(exp_cwd);
457     free(cwd);
458     free(previous);
459 }
460 
461 
462 ATF_TC_WITHOUT_HEAD(current_path__enoent);
ATF_TC_BODY(current_path__enoent,tc)463 ATF_TC_BODY(current_path__enoent, tc)
464 {
465     char* previous;
466     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_current_path(&previous)));
467 
468     ATF_REQUIRE(mkdir("root", 0755) != -1);
469     ATF_REQUIRE(chdir("root") != -1);
470     ATF_REQUIRE(rmdir("../root") != -1);
471     char* cwd = (char*)0xdeadbeef;
472     kyua_error_t error = kyua_fs_current_path(&cwd);
473     ATF_REQUIRE(kyua_error_is_set(error));
474     ATF_REQUIRE(kyua_error_is_type(error, "libc"));
475     ATF_REQUIRE_EQ(ENOENT, kyua_libc_error_errno(error));
476     ATF_REQUIRE_EQ((char*)0xdeadbeef, cwd);
477     kyua_error_free(error);
478 
479     free(previous);
480 }
481 
482 
483 ATF_TC_WITHOUT_HEAD(make_absolute__absolute);
ATF_TC_BODY(make_absolute__absolute,tc)484 ATF_TC_BODY(make_absolute__absolute, tc)
485 {
486     char* absolute;
487     ATF_REQUIRE(!kyua_error_is_set(kyua_fs_make_absolute(
488         "/this/is/absolute", &absolute)));
489     ATF_REQUIRE_STREQ("/this/is/absolute", absolute);
490     free(absolute);
491 }
492 
493 
494 ATF_TC_WITHOUT_HEAD(make_absolute__relative);
ATF_TC_BODY(make_absolute__relative,tc)495 ATF_TC_BODY(make_absolute__relative, tc)
496 {
497     kyua_error_t error;
498     char* absolute;
499 
500     DIR* previous = opendir(".");
501     ATF_REQUIRE(previous != NULL);
502     ATF_REQUIRE(chdir("/usr") != -1);
503     error = kyua_fs_make_absolute("bin/foobar", &absolute);
504     const int previous_fd = dirfd(previous);
505     ATF_REQUIRE(fchdir(previous_fd) != -1);
506     close(previous_fd);
507 
508     ATF_REQUIRE(!kyua_error_is_set(error));
509     ATF_REQUIRE_STREQ("/usr/bin/foobar", absolute);
510     free(absolute);
511 }
512 
513 
514 ATF_TC(unmount__ok);
ATF_TC_HEAD(unmount__ok,tc)515 ATF_TC_HEAD(unmount__ok, tc)
516 {
517     atf_tc_set_md_var(tc, "require.user", "root");
518 }
ATF_TC_BODY(unmount__ok,tc)519 ATF_TC_BODY(unmount__ok, tc)
520 {
521     ATF_REQUIRE(mkdir("mount_point", 0755) != -1);
522 
523     atf_utils_create_file("mount_point/test1", "%s", "");
524     mount_tmpfs("mount_point");
525     atf_utils_create_file("mount_point/test2", "%s", "");
526 
527     ATF_REQUIRE(!atf_utils_file_exists("mount_point/test1"));
528     ATF_REQUIRE( atf_utils_file_exists("mount_point/test2"));
529     kyua_fs_unmount("mount_point");
530     ATF_REQUIRE( atf_utils_file_exists("mount_point/test1"));
531     ATF_REQUIRE(!atf_utils_file_exists("mount_point/test2"));
532 }
533 
534 
535 ATF_TC(unmount__fail);
ATF_TC_HEAD(unmount__fail,tc)536 ATF_TC_HEAD(unmount__fail, tc)
537 {
538     atf_tc_set_md_var(tc, "require.user", "root");
539 }
ATF_TC_BODY(unmount__fail,tc)540 ATF_TC_BODY(unmount__fail, tc)
541 {
542     kyua_error_t error = kyua_fs_unmount("mount_point");
543     ATF_REQUIRE(kyua_error_is_set(error));
544     kyua_error_free(error);
545 }
546 
547 
ATF_TP_ADD_TCS(tp)548 ATF_TP_ADD_TCS(tp)
549 {
550     ATF_TP_ADD_TC(tp, cleanup__file);
551     ATF_TP_ADD_TC(tp, cleanup__subdir__empty);
552     ATF_TP_ADD_TC(tp, cleanup__subdir__files_and_directories);
553     ATF_TP_ADD_TC(tp, cleanup__subdir__unprotect_regular);
554     ATF_TP_ADD_TC(tp, cleanup__subdir__unprotect_symlink);
555     ATF_TP_ADD_TC(tp, cleanup__subdir__links);
556     ATF_TP_ADD_TC(tp, cleanup__mount_point__simple);
557     ATF_TP_ADD_TC(tp, cleanup__mount_point__overlayed);
558     ATF_TP_ADD_TC(tp, cleanup__mount_point__nested);
559     ATF_TP_ADD_TC(tp, cleanup__mount_point__links);
560     ATF_TP_ADD_TC(tp, cleanup__mount_point__busy);
561 
562     ATF_TP_ADD_TC(tp, concat__one);
563     ATF_TP_ADD_TC(tp, concat__two);
564     ATF_TP_ADD_TC(tp, concat__several);
565 
566     ATF_TP_ADD_TC(tp, current_path__ok);
567     ATF_TP_ADD_TC(tp, current_path__enoent);
568 
569     ATF_TP_ADD_TC(tp, make_absolute__absolute);
570     ATF_TP_ADD_TC(tp, make_absolute__relative);
571 
572     ATF_TP_ADD_TC(tp, unmount__ok);
573     ATF_TP_ADD_TC(tp, unmount__fail);
574 
575     return atf_no_error();
576 }
577