xref: /freebsd/lib/libc/tests/gen/fts_options_test.c (revision d30a84ab442e13ba0ed9ac3b01743e49f94dcb41)
1*d30a84abSDag-Erling Smørgrav /*-
2*d30a84abSDag-Erling Smørgrav  * Copyright (c) 2025 Klara, Inc.
3*d30a84abSDag-Erling Smørgrav  *
4*d30a84abSDag-Erling Smørgrav  * SPDX-License-Identifier: BSD-2-Clause
5*d30a84abSDag-Erling Smørgrav  */
6*d30a84abSDag-Erling Smørgrav 
7*d30a84abSDag-Erling Smørgrav #include <sys/stat.h>
8*d30a84abSDag-Erling Smørgrav 
9*d30a84abSDag-Erling Smørgrav #include <fcntl.h>
10*d30a84abSDag-Erling Smørgrav #include <fts.h>
11*d30a84abSDag-Erling Smørgrav #include <stdbool.h>
12*d30a84abSDag-Erling Smørgrav #include <stdio.h>
13*d30a84abSDag-Erling Smørgrav #include <stdlib.h>
14*d30a84abSDag-Erling Smørgrav #include <unistd.h>
15*d30a84abSDag-Erling Smørgrav 
16*d30a84abSDag-Erling Smørgrav #include <atf-c.h>
17*d30a84abSDag-Erling Smørgrav 
18*d30a84abSDag-Erling Smørgrav struct fts_expect {
19*d30a84abSDag-Erling Smørgrav 	int fts_info;
20*d30a84abSDag-Erling Smørgrav 	const char *fts_name;
21*d30a84abSDag-Erling Smørgrav 	const char *fts_accpath;
22*d30a84abSDag-Erling Smørgrav };
23*d30a84abSDag-Erling Smørgrav 
24*d30a84abSDag-Erling Smørgrav struct fts_testcase {
25*d30a84abSDag-Erling Smørgrav 	char **paths;
26*d30a84abSDag-Erling Smørgrav 	int fts_options;
27*d30a84abSDag-Erling Smørgrav 	struct fts_expect *fts_expect;
28*d30a84abSDag-Erling Smørgrav };
29*d30a84abSDag-Erling Smørgrav 
30*d30a84abSDag-Erling Smørgrav static char *all_paths[] = {
31*d30a84abSDag-Erling Smørgrav 	"dir",
32*d30a84abSDag-Erling Smørgrav 	"dirl",
33*d30a84abSDag-Erling Smørgrav 	"file",
34*d30a84abSDag-Erling Smørgrav 	"filel",
35*d30a84abSDag-Erling Smørgrav 	"dead",
36*d30a84abSDag-Erling Smørgrav 	"noent",
37*d30a84abSDag-Erling Smørgrav 	NULL
38*d30a84abSDag-Erling Smørgrav };
39*d30a84abSDag-Erling Smørgrav 
40*d30a84abSDag-Erling Smørgrav /* shorter name for dead links */
41*d30a84abSDag-Erling Smørgrav #define FTS_DL FTS_SLNONE
42*d30a84abSDag-Erling Smørgrav 
43*d30a84abSDag-Erling Smørgrav /* are we being debugged? */
44*d30a84abSDag-Erling Smørgrav static bool debug;
45*d30a84abSDag-Erling Smørgrav 
46*d30a84abSDag-Erling Smørgrav /*
47*d30a84abSDag-Erling Smørgrav  * Prepare the files and directories we will be inspecting.
48*d30a84abSDag-Erling Smørgrav  */
49*d30a84abSDag-Erling Smørgrav static void
fts_options_prepare(const struct atf_tc * tc)50*d30a84abSDag-Erling Smørgrav fts_options_prepare(const struct atf_tc *tc)
51*d30a84abSDag-Erling Smørgrav {
52*d30a84abSDag-Erling Smørgrav 	debug = !getenv("__RUNNING_INSIDE_ATF_RUN") &&
53*d30a84abSDag-Erling Smørgrav 	    isatty(STDERR_FILENO);
54*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, mkdir("dir", 0755));
55*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, close(creat("file", 0644)));
56*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, close(creat("dir/file", 0644)));
57*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, symlink("..", "dir/up"));
58*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, symlink("dir", "dirl"));
59*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, symlink("file", "filel"));
60*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, symlink("noent", "dead"));
61*d30a84abSDag-Erling Smørgrav }
62*d30a84abSDag-Erling Smørgrav 
63*d30a84abSDag-Erling Smørgrav /*
64*d30a84abSDag-Erling Smørgrav  * Lexical order for reproducability.
65*d30a84abSDag-Erling Smørgrav  */
66*d30a84abSDag-Erling Smørgrav static int
fts_options_compar(const FTSENT * const * a,const FTSENT * const * b)67*d30a84abSDag-Erling Smørgrav fts_options_compar(const FTSENT * const *a, const FTSENT * const *b)
68*d30a84abSDag-Erling Smørgrav {
69*d30a84abSDag-Erling Smørgrav 	return (strcmp((*a)->fts_name, (*b)->fts_name));
70*d30a84abSDag-Erling Smørgrav }
71*d30a84abSDag-Erling Smørgrav 
72*d30a84abSDag-Erling Smørgrav /*
73*d30a84abSDag-Erling Smørgrav  * Run FTS with the specified paths and options and verify that it
74*d30a84abSDag-Erling Smørgrav  * produces the expected result in the correct order.
75*d30a84abSDag-Erling Smørgrav  */
76*d30a84abSDag-Erling Smørgrav static void
fts_options_test(const struct atf_tc * tc,const struct fts_testcase * fts_tc)77*d30a84abSDag-Erling Smørgrav fts_options_test(const struct atf_tc *tc, const struct fts_testcase *fts_tc)
78*d30a84abSDag-Erling Smørgrav {
79*d30a84abSDag-Erling Smørgrav 	FTS *fts;
80*d30a84abSDag-Erling Smørgrav 	FTSENT *ftse;
81*d30a84abSDag-Erling Smørgrav 	const struct fts_expect *expect = fts_tc->fts_expect;
82*d30a84abSDag-Erling Smørgrav 	long level = 0;
83*d30a84abSDag-Erling Smørgrav 
84*d30a84abSDag-Erling Smørgrav 	fts = fts_open(fts_tc->paths, fts_tc->fts_options, fts_options_compar);
85*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_MSG(fts != NULL, "fts_open(): %m");
86*d30a84abSDag-Erling Smørgrav 	while ((ftse = fts_read(fts)) != NULL && expect->fts_name != NULL) {
87*d30a84abSDag-Erling Smørgrav 		if (expect->fts_info == FTS_DP)
88*d30a84abSDag-Erling Smørgrav 			level--;
89*d30a84abSDag-Erling Smørgrav 		if (debug) {
90*d30a84abSDag-Erling Smørgrav 			fprintf(stderr, "%2ld %2d %s\n", level,
91*d30a84abSDag-Erling Smørgrav 			    ftse->fts_info, ftse->fts_name);
92*d30a84abSDag-Erling Smørgrav 		}
93*d30a84abSDag-Erling Smørgrav 		ATF_CHECK_STREQ(expect->fts_name, ftse->fts_name);
94*d30a84abSDag-Erling Smørgrav 		ATF_CHECK_STREQ(expect->fts_accpath, ftse->fts_accpath);
95*d30a84abSDag-Erling Smørgrav 		ATF_CHECK_INTEQ(expect->fts_info, ftse->fts_info);
96*d30a84abSDag-Erling Smørgrav 		ATF_CHECK_INTEQ(level, ftse->fts_level);
97*d30a84abSDag-Erling Smørgrav 		if (expect->fts_info == FTS_D)
98*d30a84abSDag-Erling Smørgrav 			level++;
99*d30a84abSDag-Erling Smørgrav 		expect++;
100*d30a84abSDag-Erling Smørgrav 	}
101*d30a84abSDag-Erling Smørgrav 	ATF_CHECK_EQ(NULL, ftse);
102*d30a84abSDag-Erling Smørgrav 	ATF_CHECK_EQ(NULL, expect->fts_name);
103*d30a84abSDag-Erling Smørgrav 	ATF_REQUIRE_EQ_MSG(0, fts_close(fts), "fts_close(): %m");
104*d30a84abSDag-Erling Smørgrav }
105*d30a84abSDag-Erling Smørgrav 
106*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_logical);
ATF_TC_HEAD(fts_options_logical,tc)107*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_logical, tc)
108*d30a84abSDag-Erling Smørgrav {
109*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL");
110*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_logical,tc)111*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_logical, tc)
112*d30a84abSDag-Erling Smørgrav {
113*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
114*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
115*d30a84abSDag-Erling Smørgrav 		    all_paths,
116*d30a84abSDag-Erling Smørgrav 		    FTS_LOGICAL,
117*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
118*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dead"		},
119*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
120*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dir/file"	},
121*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"up",		"dir/up"	},
122*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dir/up/dead"	},
123*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dir",		"dir/up/dir"	},
124*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dirl",		"dir/up/dirl"	},
125*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dir/up/file"	},
126*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"dir/up/filel"	},
127*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"up",		"dir/up"	},
128*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
129*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dirl",		"dirl"		},
130*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dirl/file"	},
131*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"up",		"dirl/up"	},
132*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dirl/up/dead"	},
133*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dir",		"dirl/up/dir"	},
134*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dirl",		"dirl/up/dirl"	},
135*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dirl/up/file"	},
136*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"dirl/up/filel"	},
137*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"up",		"dirl/up"	},
138*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dirl",		"dirl"		},
139*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
140*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"filel"		},
141*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
142*d30a84abSDag-Erling Smørgrav 			    { 0 }
143*d30a84abSDag-Erling Smørgrav 		    },
144*d30a84abSDag-Erling Smørgrav 	    });
145*d30a84abSDag-Erling Smørgrav }
146*d30a84abSDag-Erling Smørgrav 
147*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_logical_nostat);
ATF_TC_HEAD(fts_options_logical_nostat,tc)148*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_logical_nostat, tc)
149*d30a84abSDag-Erling Smørgrav {
150*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL | FTS_NOSTAT");
151*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_logical_nostat,tc)152*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_logical_nostat, tc)
153*d30a84abSDag-Erling Smørgrav {
154*d30a84abSDag-Erling Smørgrav 	/*
155*d30a84abSDag-Erling Smørgrav 	 * While FTS_LOGICAL is not documented as being incompatible with
156*d30a84abSDag-Erling Smørgrav 	 * FTS_NOSTAT, and FTS does not clear FTS_NOSTAT if FTS_LOGICAL is
157*d30a84abSDag-Erling Smørgrav 	 * set, FTS_LOGICAL effectively nullifies FTS_NOSTAT by overriding
158*d30a84abSDag-Erling Smørgrav 	 * the follow check in fts_stat().  In theory, FTS could easily be
159*d30a84abSDag-Erling Smørgrav 	 * changed to only stat links (to check what they point to) in the
160*d30a84abSDag-Erling Smørgrav 	 * FTS_LOGICAL | FTS_NOSTAT case, which would produce a different
161*d30a84abSDag-Erling Smørgrav 	 * result here, so keep the test around in case that ever happens.
162*d30a84abSDag-Erling Smørgrav 	 */
163*d30a84abSDag-Erling Smørgrav 	atf_tc_expect_fail("FTS_LOGICAL nullifies FTS_NOSTAT");
164*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
165*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
166*d30a84abSDag-Erling Smørgrav 		    all_paths,
167*d30a84abSDag-Erling Smørgrav 		    FTS_LOGICAL | FTS_NOSTAT,
168*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
169*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dead"		},
170*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
171*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"file",		"dir/file"	},
172*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"up",		"dir/up"	},
173*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dir/up/dead"	},
174*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dir",		"dir/up/dir"	},
175*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dirl",		"dir/up/dirl"	},
176*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"file",		"dir/up/file"	},
177*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"filel",	"dir/up/filel"	},
178*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"up",		"dir/up"	},
179*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
180*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dirl",		"dirl"		},
181*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"file",		"dirl/file"	},
182*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"up",		"dirl/up"	},
183*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dirl/up/dead"	},
184*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dir",		"dirl/up/dir"	},
185*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dirl",		"dirl/up/dirl"	},
186*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"file",		"dirl/up/file"	},
187*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"filel",	"dirl/up/filel"	},
188*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"up",		"dirl/up"	},
189*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dirl",		"dirl"		},
190*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
191*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"filel"		},
192*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
193*d30a84abSDag-Erling Smørgrav 			    { 0 }
194*d30a84abSDag-Erling Smørgrav 		    },
195*d30a84abSDag-Erling Smørgrav 	    });
196*d30a84abSDag-Erling Smørgrav }
197*d30a84abSDag-Erling Smørgrav 
198*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_logical_seedot);
ATF_TC_HEAD(fts_options_logical_seedot,tc)199*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_logical_seedot, tc)
200*d30a84abSDag-Erling Smørgrav {
201*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL | FTS_SEEDOT");
202*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_logical_seedot,tc)203*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_logical_seedot, tc)
204*d30a84abSDag-Erling Smørgrav {
205*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
206*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
207*d30a84abSDag-Erling Smørgrav 		    all_paths,
208*d30a84abSDag-Erling Smørgrav 		    FTS_LOGICAL | FTS_SEEDOT,
209*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
210*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dead"		},
211*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
212*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	".",		"dir/."		},
213*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	"..",		"dir/.."	},
214*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dir/file"	},
215*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"up",		"dir/up"	},
216*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	".",		"dir/up/."	},
217*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	"..",		"dir/up/.."	},
218*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dir/up/dead"	},
219*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dir",		"dir/up/dir"	},
220*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dirl",		"dir/up/dirl"	},
221*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dir/up/file"	},
222*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"dir/up/filel"	},
223*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"up",		"dir/up"	},
224*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
225*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dirl",		"dirl"		},
226*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	".",		"dirl/."	},
227*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	"..",		"dirl/.."	},
228*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dirl/file"	},
229*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"up",		"dirl/up"	},
230*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	".",		"dirl/up/."	},
231*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	"..",		"dirl/up/.."	},
232*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dirl/up/dead"	},
233*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dir",		"dirl/up/dir"	},
234*d30a84abSDag-Erling Smørgrav 			    { FTS_DC,	"dirl",		"dirl/up/dirl"	},
235*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dirl/up/file"	},
236*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"dirl/up/filel"	},
237*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"up",		"dirl/up"	},
238*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dirl",		"dirl"		},
239*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
240*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"filel"		},
241*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
242*d30a84abSDag-Erling Smørgrav 			    { 0 }
243*d30a84abSDag-Erling Smørgrav 		    },
244*d30a84abSDag-Erling Smørgrav 	    });
245*d30a84abSDag-Erling Smørgrav }
246*d30a84abSDag-Erling Smørgrav 
247*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical);
ATF_TC_HEAD(fts_options_physical,tc)248*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical, tc)
249*d30a84abSDag-Erling Smørgrav {
250*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL");
251*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical,tc)252*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical, tc)
253*d30a84abSDag-Erling Smørgrav {
254*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
255*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
256*d30a84abSDag-Erling Smørgrav 		    all_paths,
257*d30a84abSDag-Erling Smørgrav 		    FTS_PHYSICAL,
258*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
259*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dead",		"dead"		},
260*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
261*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
262*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"up"		},
263*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
264*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dirl",		"dirl"		},
265*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
266*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"filel",	"filel"		},
267*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
268*d30a84abSDag-Erling Smørgrav 			    { 0 }
269*d30a84abSDag-Erling Smørgrav 		    },
270*d30a84abSDag-Erling Smørgrav 	    });
271*d30a84abSDag-Erling Smørgrav }
272*d30a84abSDag-Erling Smørgrav 
273*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_nochdir);
ATF_TC_HEAD(fts_options_physical_nochdir,tc)274*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_nochdir, tc)
275*d30a84abSDag-Erling Smørgrav {
276*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOCHDIR");
277*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_nochdir,tc)278*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_nochdir, tc)
279*d30a84abSDag-Erling Smørgrav {
280*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
281*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
282*d30a84abSDag-Erling Smørgrav 		    all_paths,
283*d30a84abSDag-Erling Smørgrav 		    FTS_PHYSICAL | FTS_NOCHDIR,
284*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
285*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dead",		"dead"		},
286*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
287*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"dir/file"	},
288*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"dir/up"	},
289*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
290*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dirl",		"dirl"		},
291*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
292*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"filel",	"filel"		},
293*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
294*d30a84abSDag-Erling Smørgrav 			    { 0 }
295*d30a84abSDag-Erling Smørgrav 		    },
296*d30a84abSDag-Erling Smørgrav 	    });
297*d30a84abSDag-Erling Smørgrav }
298*d30a84abSDag-Erling Smørgrav 
299*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_comfollow);
ATF_TC_HEAD(fts_options_physical_comfollow,tc)300*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_comfollow, tc)
301*d30a84abSDag-Erling Smørgrav {
302*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_COMFOLLOW");
303*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_comfollow,tc)304*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_comfollow, tc)
305*d30a84abSDag-Erling Smørgrav {
306*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
307*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
308*d30a84abSDag-Erling Smørgrav 		    all_paths,
309*d30a84abSDag-Erling Smørgrav 		    FTS_PHYSICAL | FTS_COMFOLLOW,
310*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
311*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dead"		},
312*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
313*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
314*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"up"		},
315*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
316*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dirl",		"dirl"		},
317*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
318*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"up"		},
319*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dirl",		"dirl"		},
320*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
321*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"filel",	"filel"		},
322*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
323*d30a84abSDag-Erling Smørgrav 			    { 0 }
324*d30a84abSDag-Erling Smørgrav 		    },
325*d30a84abSDag-Erling Smørgrav 	    });
326*d30a84abSDag-Erling Smørgrav }
327*d30a84abSDag-Erling Smørgrav 
328*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_comfollowdir);
ATF_TC_HEAD(fts_options_physical_comfollowdir,tc)329*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_comfollowdir, tc)
330*d30a84abSDag-Erling Smørgrav {
331*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_COMFOLLOWDIR");
332*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_comfollowdir,tc)333*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_comfollowdir, tc)
334*d30a84abSDag-Erling Smørgrav {
335*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
336*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
337*d30a84abSDag-Erling Smørgrav 		    all_paths,
338*d30a84abSDag-Erling Smørgrav 		    FTS_PHYSICAL | FTS_COMFOLLOWDIR,
339*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
340*d30a84abSDag-Erling Smørgrav 			    { FTS_DL,	"dead",		"dead"		},
341*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
342*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
343*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"up"		},
344*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
345*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dirl",		"dirl"		},
346*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
347*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"up"		},
348*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dirl",		"dirl"		},
349*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
350*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"filel",	"filel"		},
351*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
352*d30a84abSDag-Erling Smørgrav 			    { 0 }
353*d30a84abSDag-Erling Smørgrav 		    },
354*d30a84abSDag-Erling Smørgrav 	    });
355*d30a84abSDag-Erling Smørgrav }
356*d30a84abSDag-Erling Smørgrav 
357*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_nostat);
ATF_TC_HEAD(fts_options_physical_nostat,tc)358*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_nostat, tc)
359*d30a84abSDag-Erling Smørgrav {
360*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOSTAT");
361*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_nostat,tc)362*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_nostat, tc)
363*d30a84abSDag-Erling Smørgrav {
364*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
365*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
366*d30a84abSDag-Erling Smørgrav 		    all_paths,
367*d30a84abSDag-Erling Smørgrav 		    FTS_PHYSICAL | FTS_NOSTAT,
368*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
369*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dead",		"dead"		},
370*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
371*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"file",		"file"		},
372*d30a84abSDag-Erling Smørgrav 			    { FTS_NSOK,	"up",		"up"		},
373*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
374*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dirl",		"dirl"		},
375*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
376*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"filel",	"filel"		},
377*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
378*d30a84abSDag-Erling Smørgrav 			    { 0 }
379*d30a84abSDag-Erling Smørgrav 		    },
380*d30a84abSDag-Erling Smørgrav 	    });
381*d30a84abSDag-Erling Smørgrav }
382*d30a84abSDag-Erling Smørgrav 
383*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_nostat_type);
ATF_TC_HEAD(fts_options_physical_nostat_type,tc)384*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_nostat_type, tc)
385*d30a84abSDag-Erling Smørgrav {
386*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOSTAT_TYPE");
387*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_nostat_type,tc)388*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_nostat_type, tc)
389*d30a84abSDag-Erling Smørgrav {
390*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
391*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
392*d30a84abSDag-Erling Smørgrav 		    all_paths,
393*d30a84abSDag-Erling Smørgrav 		    FTS_PHYSICAL | FTS_NOSTAT_TYPE,
394*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
395*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dead",		"dead"		},
396*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
397*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
398*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"up"		},
399*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
400*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dirl",		"dirl"		},
401*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
402*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"filel",	"filel"		},
403*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
404*d30a84abSDag-Erling Smørgrav 			    { 0 }
405*d30a84abSDag-Erling Smørgrav 		    },
406*d30a84abSDag-Erling Smørgrav 	    });
407*d30a84abSDag-Erling Smørgrav }
408*d30a84abSDag-Erling Smørgrav 
409*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_seedot);
ATF_TC_HEAD(fts_options_physical_seedot,tc)410*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_seedot, tc)
411*d30a84abSDag-Erling Smørgrav {
412*d30a84abSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_SEEDOT");
413*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_seedot,tc)414*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_seedot, tc)
415*d30a84abSDag-Erling Smørgrav {
416*d30a84abSDag-Erling Smørgrav 	fts_options_prepare(tc);
417*d30a84abSDag-Erling Smørgrav 	fts_options_test(tc, &(struct fts_testcase){
418*d30a84abSDag-Erling Smørgrav 		    all_paths,
419*d30a84abSDag-Erling Smørgrav 		    FTS_PHYSICAL | FTS_SEEDOT,
420*d30a84abSDag-Erling Smørgrav 		    (struct fts_expect[]){
421*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dead",		"dead"		},
422*d30a84abSDag-Erling Smørgrav 			    { FTS_D,	"dir",		"dir"		},
423*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	".",		"."		},
424*d30a84abSDag-Erling Smørgrav 			    { FTS_DOT,	"..",		".."		},
425*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
426*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"up",		"up"		},
427*d30a84abSDag-Erling Smørgrav 			    { FTS_DP,	"dir",		"dir"		},
428*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"dirl",		"dirl"		},
429*d30a84abSDag-Erling Smørgrav 			    { FTS_F,	"file",		"file"		},
430*d30a84abSDag-Erling Smørgrav 			    { FTS_SL,	"filel",	"filel"		},
431*d30a84abSDag-Erling Smørgrav 			    { FTS_NS,	"noent",	"noent"		},
432*d30a84abSDag-Erling Smørgrav 			    { 0 }
433*d30a84abSDag-Erling Smørgrav 		    },
434*d30a84abSDag-Erling Smørgrav 	    });
435*d30a84abSDag-Erling Smørgrav }
436*d30a84abSDag-Erling Smørgrav 
437*d30a84abSDag-Erling Smørgrav /*
438*d30a84abSDag-Erling Smørgrav  * TODO: Add tests for FTS_XDEV and FTS_WHITEOUT
439*d30a84abSDag-Erling Smørgrav  */
440*d30a84abSDag-Erling Smørgrav 
ATF_TP_ADD_TCS(tp)441*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TCS(tp)
442*d30a84abSDag-Erling Smørgrav {
443*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_logical);
444*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_logical_nostat);
445*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_logical_seedot);
446*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_physical);
447*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_physical_nochdir);
448*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_physical_comfollow);
449*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_physical_comfollowdir);
450*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_physical_nostat);
451*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_physical_nostat_type);
452*d30a84abSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fts_options_physical_seedot);
453*d30a84abSDag-Erling Smørgrav 	return (atf_no_error());
454*d30a84abSDag-Erling Smørgrav }
455