From nobody Thu May 8 14:29:43 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4ZtZK40sBZz5v8Ms; Thu, 08 May 2025 14:29:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ZtZK33qXtz3HQp; Thu, 08 May 2025 14:29:43 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1746714583; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=2yaKQNCW2OoviUx6oGMwgZ/bmMY9B8qOQNQvXn5FUus=; b=oHTe9RdtzWizHoyEz3H2CFxGBQP0a6IvrgC1mOA2v1zTSHqSQmSrVwyMjPsC/EhRtAb+BK fOnfgTuOUre3BC/OiIi4+krS6UxXtRQlZtNSqWYBMTY5SMChazhLeScHDzZ0wKZwQfYlKi zqFej2ydwS76P5PXJExUNI7ghXN/+xOV9ShvCdoh5wlcYJqyoVeE2cI9lbYjp2YOD2upIe lW0omzi46N44PJT3p9D+kaM0ZGKGFYkVJuEtad0mjvKd5kQbm6wooe8kRYDfkYviUyiUJ3 L01vGcFP1Vk+pb12EsL4htlt/hWlNAqpMkb5Zpot+3ZFG1tKXfyZw0i6GJqAyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1746714583; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=2yaKQNCW2OoviUx6oGMwgZ/bmMY9B8qOQNQvXn5FUus=; b=WiTFBJ9kU1HZT2VujX85/OAO1i9xhAXN+2z8yjhqPhINp6fzt5AVk2C40IqbvbHSHgJ+Lc o+86oCvkyc1zD/EmgU3/v0SBRkuQX4ePgYD6E+Spb4Jz3uLGGotaMyHKsq9IVbPfr7XGmj Z3OBltbMt466nDgQSE8LReX9lZzoCWonnJ9B+rW5eGsIHWp/cvIY4wbF8myx8FV15LmxkW 250G2U41r4dO1+l5H7gXWGv5GFjnKxLRDcQ/qIZK9kv1FIA3gIEXyXGn39P+Bz2XQE2rQW qpWQxGHi6b8udJ+2mG2dGXaelhctHNXkhjh5fdbcSkmrOnnKacHf2/gmp5/adw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1746714583; a=rsa-sha256; cv=none; b=AOYCeuW6rl5iUDSPGzbYSVRbA1FI5RBTSZ1/VhStgAQ+cO61hoHv4exzg14fO2yPbtNE0+ EEGgeU8n4GgIS3cuWB2VVR53qeiGzY9neoUSILmxlHWPOnVgoFRLWiZPVpaGKpZkYFeI5J EWDoRuAWeb8Z+z4NcOj37Bj+u+joPZnw0PJ4huRvWSLNrNGXV7Wk2m4GnJjtlLQVPrZ0oo ymS/UXzPo36ppmm3wiAh4OBwd7JSrn0NYGP+SJTz0x5xoqVwvsFlWTDW8jqx/3nCk7OTs6 VWjmTk/ihJub5j33ok3bpYc/iQ1cFnlTsz8aHSxXszx5oI9kCIoXadTDRQT7SQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4ZtZK33B4gz3pn; Thu, 08 May 2025 14:29:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 548ETh9O086633; Thu, 8 May 2025 14:29:43 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 548EThfh086628; Thu, 8 May 2025 14:29:43 GMT (envelope-from git) Date: Thu, 8 May 2025 14:29:43 GMT Message-Id: <202505081429.548EThfh086628@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: d2da6ed98494 - main - fts: Add tests for most FTS options. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d2da6ed98494a66c0119b10345bb11daaa297ae3 Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=d2da6ed98494a66c0119b10345bb11daaa297ae3 commit d2da6ed98494a66c0119b10345bb11daaa297ae3 Author: Dag-Erling Smørgrav AuthorDate: 2025-05-08 14:29:02 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2025-05-08 14:29:15 +0000 fts: Add tests for most FTS options. Sponsored by: Klara, Inc. Reviewed by: kevans, imp Differential Revision: https://reviews.freebsd.org/D50234 --- lib/libc/tests/gen/Makefile | 1 + lib/libc/tests/gen/fts_options.c | 454 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 455 insertions(+) diff --git a/lib/libc/tests/gen/Makefile b/lib/libc/tests/gen/Makefile index 247b44f50484..04710293c37e 100644 --- a/lib/libc/tests/gen/Makefile +++ b/lib/libc/tests/gen/Makefile @@ -10,6 +10,7 @@ ATF_TESTS_C+= fpclassify2_test .if ${COMPILER_FEATURES:Mblocks} ATF_TESTS_C+= fts_blocks_test .endif +ATF_TESTS_C+= fts_options ATF_TESTS_C+= ftw_test ATF_TESTS_C+= getentropy_test ATF_TESTS_C+= getmntinfo_test diff --git a/lib/libc/tests/gen/fts_options.c b/lib/libc/tests/gen/fts_options.c new file mode 100644 index 000000000000..c80474b70ac7 --- /dev/null +++ b/lib/libc/tests/gen/fts_options.c @@ -0,0 +1,454 @@ +/*- + * Copyright (c) 2025 Klara, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +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; +}; + +static char *all_paths[] = { + "dir", + "dirl", + "file", + "filel", + "dead", + "noent", + NULL +}; + +/* shorter name for dead links */ +#define FTS_DL FTS_SLNONE + +/* are we being debugged? */ +static bool debug; + +/* + * Prepare the files and directories we will be inspecting. + */ +static void +fts_options_prepare(const struct atf_tc *tc) +{ + debug = !getenv("__RUNNING_INSIDE_ATF_RUN") && + isatty(STDERR_FILENO); + ATF_REQUIRE_EQ(0, mkdir("dir", 0755)); + ATF_REQUIRE_EQ(0, close(creat("file", 0644))); + ATF_REQUIRE_EQ(0, close(creat("dir/file", 0644))); + ATF_REQUIRE_EQ(0, symlink("..", "dir/up")); + ATF_REQUIRE_EQ(0, symlink("dir", "dirl")); + ATF_REQUIRE_EQ(0, symlink("file", "filel")); + ATF_REQUIRE_EQ(0, symlink("noent", "dead")); +} + +/* + * Lexical order for reproducability. + */ +static int +fts_options_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_options_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_options_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) + level--; + if (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"); +} + +ATF_TC(fts_options_logical); +ATF_TC_HEAD(fts_options_logical, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL"); +} +ATF_TC_BODY(fts_options_logical, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_LOGICAL, + (struct fts_expect[]){ + { FTS_DL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_F, "file", "dir/file" }, + { FTS_D, "up", "dir/up" }, + { FTS_DL, "dead", "dir/up/dead" }, + { FTS_DC, "dir", "dir/up/dir" }, + { FTS_DC, "dirl", "dir/up/dirl" }, + { FTS_F, "file", "dir/up/file" }, + { FTS_F, "filel", "dir/up/filel" }, + { FTS_DP, "up", "dir/up" }, + { FTS_DP, "dir", "dir" }, + { FTS_D, "dirl", "dirl" }, + { FTS_F, "file", "dirl/file" }, + { FTS_D, "up", "dirl/up" }, + { FTS_DL, "dead", "dirl/up/dead" }, + { FTS_DC, "dir", "dirl/up/dir" }, + { FTS_DC, "dirl", "dirl/up/dirl" }, + { FTS_F, "file", "dirl/up/file" }, + { FTS_F, "filel", "dirl/up/filel" }, + { FTS_DP, "up", "dirl/up" }, + { FTS_DP, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_F, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_logical_nostat); +ATF_TC_HEAD(fts_options_logical_nostat, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL | FTS_NOSTAT"); +} +ATF_TC_BODY(fts_options_logical_nostat, tc) +{ + /* + * While FTS_LOGICAL is not documented as being incompatible with + * FTS_NOSTAT, and FTS does not clear FTS_NOSTAT if FTS_LOGICAL is + * set, FTS_LOGICAL effectively nullifies FTS_NOSTAT by overriding + * the follow check in fts_stat(). In theory, FTS could easily be + * changed to only stat links (to check what they point to) in the + * FTS_LOGICAL | FTS_NOSTAT case, which would produce a different + * result here, so keep the test around in case that ever happens. + */ + atf_tc_expect_fail("FTS_LOGICAL nullifies FTS_NOSTAT"); + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_LOGICAL | FTS_NOSTAT, + (struct fts_expect[]){ + { FTS_DL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_NSOK, "file", "dir/file" }, + { FTS_D, "up", "dir/up" }, + { FTS_DL, "dead", "dir/up/dead" }, + { FTS_DC, "dir", "dir/up/dir" }, + { FTS_DC, "dirl", "dir/up/dirl" }, + { FTS_NSOK, "file", "dir/up/file" }, + { FTS_NSOK, "filel", "dir/up/filel" }, + { FTS_DP, "up", "dir/up" }, + { FTS_DP, "dir", "dir" }, + { FTS_D, "dirl", "dirl" }, + { FTS_NSOK, "file", "dirl/file" }, + { FTS_D, "up", "dirl/up" }, + { FTS_DL, "dead", "dirl/up/dead" }, + { FTS_DC, "dir", "dirl/up/dir" }, + { FTS_DC, "dirl", "dirl/up/dirl" }, + { FTS_NSOK, "file", "dirl/up/file" }, + { FTS_NSOK, "filel", "dirl/up/filel" }, + { FTS_DP, "up", "dirl/up" }, + { FTS_DP, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_F, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_logical_seedot); +ATF_TC_HEAD(fts_options_logical_seedot, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL | FTS_SEEDOT"); +} +ATF_TC_BODY(fts_options_logical_seedot, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_LOGICAL | FTS_SEEDOT, + (struct fts_expect[]){ + { FTS_DL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_DOT, ".", "dir/." }, + { FTS_DOT, "..", "dir/.." }, + { FTS_F, "file", "dir/file" }, + { FTS_D, "up", "dir/up" }, + { FTS_DOT, ".", "dir/up/." }, + { FTS_DOT, "..", "dir/up/.." }, + { FTS_DL, "dead", "dir/up/dead" }, + { FTS_DC, "dir", "dir/up/dir" }, + { FTS_DC, "dirl", "dir/up/dirl" }, + { FTS_F, "file", "dir/up/file" }, + { FTS_F, "filel", "dir/up/filel" }, + { FTS_DP, "up", "dir/up" }, + { FTS_DP, "dir", "dir" }, + { FTS_D, "dirl", "dirl" }, + { FTS_DOT, ".", "dirl/." }, + { FTS_DOT, "..", "dirl/.." }, + { FTS_F, "file", "dirl/file" }, + { FTS_D, "up", "dirl/up" }, + { FTS_DOT, ".", "dirl/up/." }, + { FTS_DOT, "..", "dirl/up/.." }, + { FTS_DL, "dead", "dirl/up/dead" }, + { FTS_DC, "dir", "dirl/up/dir" }, + { FTS_DC, "dirl", "dirl/up/dirl" }, + { FTS_F, "file", "dirl/up/file" }, + { FTS_F, "filel", "dirl/up/filel" }, + { FTS_DP, "up", "dirl/up" }, + { FTS_DP, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_F, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_physical); +ATF_TC_HEAD(fts_options_physical, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL"); +} +ATF_TC_BODY(fts_options_physical, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_PHYSICAL, + (struct fts_expect[]){ + { FTS_SL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_F, "file", "file" }, + { FTS_SL, "up", "up" }, + { FTS_DP, "dir", "dir" }, + { FTS_SL, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_physical_nochdir); +ATF_TC_HEAD(fts_options_physical_nochdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOCHDIR"); +} +ATF_TC_BODY(fts_options_physical_nochdir, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_PHYSICAL | FTS_NOCHDIR, + (struct fts_expect[]){ + { FTS_SL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_F, "file", "dir/file" }, + { FTS_SL, "up", "dir/up" }, + { FTS_DP, "dir", "dir" }, + { FTS_SL, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_physical_comfollow); +ATF_TC_HEAD(fts_options_physical_comfollow, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_COMFOLLOW"); +} +ATF_TC_BODY(fts_options_physical_comfollow, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_PHYSICAL | FTS_COMFOLLOW, + (struct fts_expect[]){ + { FTS_DL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_F, "file", "file" }, + { FTS_SL, "up", "up" }, + { FTS_DP, "dir", "dir" }, + { FTS_D, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "up", "up" }, + { FTS_DP, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_F, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_physical_comfollowdir); +ATF_TC_HEAD(fts_options_physical_comfollowdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_COMFOLLOWDIR"); +} +ATF_TC_BODY(fts_options_physical_comfollowdir, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_PHYSICAL | FTS_COMFOLLOWDIR, + (struct fts_expect[]){ + { FTS_DL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_F, "file", "file" }, + { FTS_SL, "up", "up" }, + { FTS_DP, "dir", "dir" }, + { FTS_D, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "up", "up" }, + { FTS_DP, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_physical_nostat); +ATF_TC_HEAD(fts_options_physical_nostat, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOSTAT"); +} +ATF_TC_BODY(fts_options_physical_nostat, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_PHYSICAL | FTS_NOSTAT, + (struct fts_expect[]){ + { FTS_SL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_NSOK, "file", "file" }, + { FTS_NSOK, "up", "up" }, + { FTS_DP, "dir", "dir" }, + { FTS_SL, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_physical_nostat_type); +ATF_TC_HEAD(fts_options_physical_nostat_type, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOSTAT_TYPE"); +} +ATF_TC_BODY(fts_options_physical_nostat_type, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_PHYSICAL | FTS_NOSTAT_TYPE, + (struct fts_expect[]){ + { FTS_SL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_F, "file", "file" }, + { FTS_SL, "up", "up" }, + { FTS_DP, "dir", "dir" }, + { FTS_SL, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +ATF_TC(fts_options_physical_seedot); +ATF_TC_HEAD(fts_options_physical_seedot, tc) +{ + atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_SEEDOT"); +} +ATF_TC_BODY(fts_options_physical_seedot, tc) +{ + fts_options_prepare(tc); + fts_options_test(tc, &(struct fts_testcase){ + all_paths, + FTS_PHYSICAL | FTS_SEEDOT, + (struct fts_expect[]){ + { FTS_SL, "dead", "dead" }, + { FTS_D, "dir", "dir" }, + { FTS_DOT, ".", "." }, + { FTS_DOT, "..", ".." }, + { FTS_F, "file", "file" }, + { FTS_SL, "up", "up" }, + { FTS_DP, "dir", "dir" }, + { FTS_SL, "dirl", "dirl" }, + { FTS_F, "file", "file" }, + { FTS_SL, "filel", "filel" }, + { FTS_NS, "noent", "noent" }, + { 0 } + }, + }); +} + +/* + * TODO: Add tests for FTS_XDEV and FTS_WHITEOUT + */ + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fts_options_logical); + ATF_TP_ADD_TC(tp, fts_options_logical_nostat); + ATF_TP_ADD_TC(tp, fts_options_logical_seedot); + ATF_TP_ADD_TC(tp, fts_options_physical); + ATF_TP_ADD_TC(tp, fts_options_physical_nochdir); + ATF_TP_ADD_TC(tp, fts_options_physical_comfollow); + ATF_TP_ADD_TC(tp, fts_options_physical_comfollowdir); + ATF_TP_ADD_TC(tp, fts_options_physical_nostat); + ATF_TP_ADD_TC(tp, fts_options_physical_nostat_type); + ATF_TP_ADD_TC(tp, fts_options_physical_seedot); + return (atf_no_error()); +}