aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/tests/gen/fts_test.h
blob: b3f15050f265eea6c400addd6dd1a552b491095c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*-
 * Copyright (c) 2025 Klara, Inc.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#ifndef FTS_TEST_H_INCLUDED
#define FTS_TEST_H_INCLUDED

struct fts_expect {
	int fts_info;
	const char *fts_name;
	const char *fts_accpath;
};

struct fts_testcase {
	char **paths;
	int fts_options;
	struct fts_expect *fts_expect;
};

/* shorter name for dead links */
#define FTS_DL FTS_SLNONE

/* are we being debugged? */
static bool fts_test_debug;

/*
 * Set debug flag if appropriate.
 */
static void
fts_check_debug(void)
{
	fts_test_debug = !getenv("__RUNNING_INSIDE_ATF_RUN") &&
	    isatty(STDERR_FILENO);
}

/*
 * Lexical order for reproducability.
 */
static int
fts_lexical_compar(const FTSENT * const *a, const FTSENT * const *b)
{
	return (strcmp((*a)->fts_name, (*b)->fts_name));
}

/*
 * Run FTS with the specified paths and options and verify that it
 * produces the expected result in the correct order.
 */
static void
fts_test(const struct atf_tc *tc, const struct fts_testcase *fts_tc)
{
	FTS *fts;
	FTSENT *ftse;
	const struct fts_expect *expect = fts_tc->fts_expect;
	long level = 0;

	fts = fts_open(fts_tc->paths, fts_tc->fts_options, fts_lexical_compar);
	ATF_REQUIRE_MSG(fts != NULL, "fts_open(): %m");
	while ((ftse = fts_read(fts)) != NULL && expect->fts_name != NULL) {
		if (expect->fts_info == FTS_DP || expect->fts_info == FTS_DNR)
			level--;
		if (fts_test_debug) {
			fprintf(stderr, "%2ld %2d %s\n", level,
			    ftse->fts_info, ftse->fts_name);
		}
		ATF_CHECK_STREQ(expect->fts_name, ftse->fts_name);
		ATF_CHECK_STREQ(expect->fts_accpath, ftse->fts_accpath);
		ATF_CHECK_INTEQ(expect->fts_info, ftse->fts_info);
		ATF_CHECK_INTEQ(level, ftse->fts_level);
		if (expect->fts_info == FTS_D)
			level++;
		expect++;
	}
	ATF_CHECK_EQ(NULL, ftse);
	ATF_CHECK_EQ(NULL, expect->fts_name);
	ATF_REQUIRE_EQ_MSG(0, fts_close(fts), "fts_close(): %m");
}

#endif /* FTS_TEST_H_INCLUDED */