xref: /freebsd/lib/libc/tests/gen/fts_test.h (revision ae07a5805b1906f29e786f415d67bef334557bd3)
1 /*-
2  * Copyright (c) 2025 Klara, Inc.
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #ifndef FTS_TEST_H_INCLUDED
8 #define FTS_TEST_H_INCLUDED
9 
10 struct fts_expect {
11 	int fts_info;
12 	const char *fts_name;
13 	const char *fts_accpath;
14 };
15 
16 struct fts_testcase {
17 	char **paths;
18 	int fts_options;
19 	struct fts_expect *fts_expect;
20 };
21 
22 /* shorter name for dead links */
23 #define FTS_DL FTS_SLNONE
24 
25 /* are we being debugged? */
26 static bool fts_test_debug;
27 
28 /*
29  * Set debug flag if appropriate.
30  */
31 static void
32 fts_check_debug(void)
33 {
34 	fts_test_debug = !getenv("__RUNNING_INSIDE_ATF_RUN") &&
35 	    isatty(STDERR_FILENO);
36 }
37 
38 /*
39  * Lexical order for reproducability.
40  */
41 static int
42 fts_lexical_compar(const FTSENT * const *a, const FTSENT * const *b)
43 {
44 	return (strcmp((*a)->fts_name, (*b)->fts_name));
45 }
46 
47 /*
48  * Run FTS with the specified paths and options and verify that it
49  * produces the expected result in the correct order.
50  */
51 static void
52 fts_test(const struct atf_tc *tc, const struct fts_testcase *fts_tc)
53 {
54 	FTS *fts;
55 	FTSENT *ftse;
56 	const struct fts_expect *expect = fts_tc->fts_expect;
57 	long level = 0;
58 
59 	fts = fts_open(fts_tc->paths, fts_tc->fts_options, fts_lexical_compar);
60 	ATF_REQUIRE_MSG(fts != NULL, "fts_open(): %m");
61 	while ((ftse = fts_read(fts)) != NULL && expect->fts_name != NULL) {
62 		if (expect->fts_info == FTS_DP || expect->fts_info == FTS_DNR)
63 			level--;
64 		if (fts_test_debug) {
65 			fprintf(stderr, "%2ld %2d %s\n", level,
66 			    ftse->fts_info, ftse->fts_name);
67 		}
68 		ATF_CHECK_STREQ(expect->fts_name, ftse->fts_name);
69 		ATF_CHECK_STREQ(expect->fts_accpath, ftse->fts_accpath);
70 		ATF_CHECK_INTEQ(expect->fts_info, ftse->fts_info);
71 		ATF_CHECK_INTEQ(level, ftse->fts_level);
72 		if (expect->fts_info == FTS_D)
73 			level++;
74 		expect++;
75 	}
76 	ATF_CHECK_EQ(NULL, ftse);
77 	ATF_CHECK_EQ(NULL, expect->fts_name);
78 	ATF_REQUIRE_EQ_MSG(0, fts_close(fts), "fts_close(): %m");
79 }
80 
81 #endif /* FTS_TEST_H_INCLUDED */
82