git: 8d775cafb653 - stable/13 - cap_dns tests: Convert to ATF, avoid failing when lookups don't resolve

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 06 Apr 2023 15:07:04 UTC
The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=8d775cafb6537b9d5bb110eb05673f3853a460df

commit 8d775cafb6537b9d5bb110eb05673f3853a460df
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2023-03-30 23:27:36 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-04-06 14:57:31 +0000

    cap_dns tests: Convert to ATF, avoid failing when lookups don't resolve
    
    The cap_dns tests require Internet access.  Currently they fail when
    that's not available, which for CI purposes is undesirable.  Let's
    instead skip the tests if none of the non-casper name/addr lookups
    succeed.
    
    To that end:
    - Convert the tests to ATF so that skipping is easier to implement.
    - Break up the tests into separate test cases.
    - If one of the system (i.e., non-casper) lookup functions fails, skip
      the test if all of them failed, otherwise fail the tests, since
      partial failure indicates something is flaky and deserves a closer
      look.
    
    Reviewed by:    oshogbo
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D39241
    
    (cherry picked from commit 615bf03e33e466ca10e3f1d203f4c27188d28fc3)
---
 lib/libcasper/services/cap_dns/tests/Makefile   |   2 +-
 lib/libcasper/services/cap_dns/tests/dns_test.c | 636 ++++++++++++------------
 2 files changed, 328 insertions(+), 310 deletions(-)

diff --git a/lib/libcasper/services/cap_dns/tests/Makefile b/lib/libcasper/services/cap_dns/tests/Makefile
index f79e872049d1..564b4984e4f8 100644
--- a/lib/libcasper/services/cap_dns/tests/Makefile
+++ b/lib/libcasper/services/cap_dns/tests/Makefile
@@ -2,7 +2,7 @@
 
 .include <src.opts.mk>
 
-TAP_TESTS_C=	dns_test
+ATF_TESTS_C=	dns_test
 
 .if ${MK_CASPER} != "no"
 LIBADD+=	casper
diff --git a/lib/libcasper/services/cap_dns/tests/dns_test.c b/lib/libcasper/services/cap_dns/tests/dns_test.c
index e25caf9c1c92..06856574fce9 100644
--- a/lib/libcasper/services/cap_dns/tests/dns_test.c
+++ b/lib/libcasper/services/cap_dns/tests/dns_test.c
@@ -48,29 +48,9 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 
 #include <libcasper.h>
-
 #include <casper/cap_dns.h>
 
-static int ntest = 1;
-
-#define CHECK(expr)     do {						\
-	if ((expr))							\
-		printf("ok %d # %s:%u\n", ntest, __FILE__, __LINE__);	\
-	else								\
-		printf("not ok %d # %s:%u\n", ntest, __FILE__, __LINE__); \
-	fflush(stdout);							\
-	ntest++;							\
-} while (0)
-#define CHECKX(expr)     do {						\
-	if ((expr)) {							\
-		printf("ok %d # %s:%u\n", ntest, __FILE__, __LINE__);	\
-	} else {							\
-		printf("not ok %d # %s:%u\n", ntest, __FILE__, __LINE__); \
-		exit(1);						\
-	}								\
-	fflush(stdout);							\
-	ntest++;							\
-} while (0)
+#include <atf-c.h>
 
 #define	GETHOSTBYNAME			0x01
 #define	GETHOSTBYNAME2_AF_INET		0x02
@@ -219,37 +199,47 @@ hostent_compare(const struct hostent *hp0, const struct hostent *hp1)
 	return (true);
 }
 
-static unsigned int
-runtest(cap_channel_t *capdns)
+static void
+runtest(cap_channel_t *capdns, unsigned int expected)
 {
-	unsigned int result;
+	unsigned int result, failure;
 	struct addrinfo *ais, *aic, hints, *hintsp;
 	struct hostent *hps, *hpc;
 	struct in_addr ip4;
 	struct in6_addr ip6;
+	int caperr, syserr;
 
-	result = 0;
+	failure = result = 0;
 
 	hps = gethostbyname("example.com");
-	if (hps == NULL)
+	if (hps == NULL) {
+		failure |= GETHOSTBYNAME;
 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
-	hpc = cap_gethostbyname(capdns, "example.com");
-	if (hostent_compare(hps, hpc))
-		result |= GETHOSTBYNAME;
+	} else {
+		hpc = cap_gethostbyname(capdns, "example.com");
+		if (hostent_compare(hps, hpc))
+			result |= GETHOSTBYNAME;
+	}
 
 	hps = gethostbyname2("example.com", AF_INET);
-	if (hps == NULL)
+	if (hps == NULL) {
+		failure |= GETHOSTBYNAME2_AF_INET;
 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
-	hpc = cap_gethostbyname2(capdns, "example.com", AF_INET);
-	if (hostent_compare(hps, hpc))
-		result |= GETHOSTBYNAME2_AF_INET;
+	} else {
+		hpc = cap_gethostbyname2(capdns, "example.com", AF_INET);
+		if (hostent_compare(hps, hpc))
+			result |= GETHOSTBYNAME2_AF_INET;
+	}
 
 	hps = gethostbyname2("example.com", AF_INET6);
-	if (hps == NULL)
+	if (hps == NULL) {
+		failure |= GETHOSTBYNAME2_AF_INET6;
 		fprintf(stderr, "Unable to resolve %s IPv6.\n", "example.com");
-	hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6);
-	if (hostent_compare(hps, hpc))
-		result |= GETHOSTBYNAME2_AF_INET6;
+	} else {
+		hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6);
+		if (hostent_compare(hps, hpc))
+			result |= GETHOSTBYNAME2_AF_INET6;
+	}
 
 	hints.ai_flags = 0;
 	hints.ai_family = AF_UNSPEC;
@@ -262,42 +252,57 @@ runtest(cap_channel_t *capdns)
 
 	hintsp = &hints;
 
-	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
+	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
+	if (syserr != 0) {
+		failure |= GETADDRINFO_AF_UNSPEC;
 		fprintf(stderr,
 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
-		    gai_strerror(errno));
-	}
-	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
-		if (addrinfo_compare(ais, aic))
-			result |= GETADDRINFO_AF_UNSPEC;
-		freeaddrinfo(ais);
-		freeaddrinfo(aic);
+		    gai_strerror(syserr));
+	} else {
+		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
+		    &aic);
+		if (caperr == 0) {
+			if (addrinfo_compare(ais, aic))
+				result |= GETADDRINFO_AF_UNSPEC;
+			freeaddrinfo(ais);
+			freeaddrinfo(aic);
+		}
 	}
 
 	hints.ai_family = AF_INET;
-	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
+	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
+	if (syserr != 0) {
+		failure |= GETADDRINFO_AF_INET;
 		fprintf(stderr,
 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
-		    gai_strerror(errno));
-	}
-	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
-		if (addrinfo_compare(ais, aic))
-			result |= GETADDRINFO_AF_INET;
-		freeaddrinfo(ais);
-		freeaddrinfo(aic);
+		    gai_strerror(syserr));
+	} else {
+		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
+		    &aic);
+		if (caperr == 0) {
+			if (addrinfo_compare(ais, aic))
+				result |= GETADDRINFO_AF_INET;
+			freeaddrinfo(ais);
+			freeaddrinfo(aic);
+		}
 	}
 
 	hints.ai_family = AF_INET6;
-	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
+	syserr = getaddrinfo("freebsd.org", "25", hintsp, &ais);
+	if (syserr != 0) {
+		failure |= GETADDRINFO_AF_INET6;
 		fprintf(stderr,
 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
-		    gai_strerror(errno));
-	}
-	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
-		if (addrinfo_compare(ais, aic))
-			result |= GETADDRINFO_AF_INET6;
-		freeaddrinfo(ais);
-		freeaddrinfo(aic);
+		    gai_strerror(syserr));
+	} else {
+		caperr = cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp,
+		    &aic);
+		if (caperr == 0) {
+			if (addrinfo_compare(ais, aic))
+				result |= GETADDRINFO_AF_INET6;
+			freeaddrinfo(ais);
+			freeaddrinfo(aic);
+		}
 	}
 
 	/* XXX: hardcoded addresses for "google-public-dns-a.google.com". */
@@ -306,397 +311,410 @@ runtest(cap_channel_t *capdns)
 
 	inet_pton(AF_INET, GOOGLE_DNS_IPV4, &ip4);
 	hps = gethostbyaddr(&ip4, sizeof(ip4), AF_INET);
-	if (hps == NULL)
+	if (hps == NULL) {
+		failure |= GETHOSTBYADDR_AF_INET;
 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV4);
-	hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET);
-	if (hostent_compare(hps, hpc))
-		result |= GETHOSTBYADDR_AF_INET;
+	} else {
+		hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET);
+		if (hostent_compare(hps, hpc))
+			result |= GETHOSTBYADDR_AF_INET;
+	}
 
 	inet_pton(AF_INET6, GOOGLE_DNS_IPV6, &ip6);
 	hps = gethostbyaddr(&ip6, sizeof(ip6), AF_INET6);
 	if (hps == NULL) {
+		failure |= GETHOSTBYADDR_AF_INET6;
 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV6);
+	} else {
+		hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6);
+		if (hostent_compare(hps, hpc)) {
+			caperr = h_errno;
+			result |= GETHOSTBYADDR_AF_INET6;
+		}
+	}
+
+	/*
+	 * If we had any failures, make sure that all lookups failed.  If some
+	 * succeeded and some failed, there's a problem with the test or the DNS
+	 * and we should not fail silently.
+	 */
+	if (failure != 0) {
+		ATF_REQUIRE_MSG(failure == (GETHOSTBYNAME |
+		    GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
+		    GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET |
+		    GETADDRINFO_AF_INET6 |
+		    GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6),
+		    "expected all tests to fail, got 0x%x", failure);
+		atf_tc_skip(
+		    "no name lookups succeeded, tests require Internet access");
 	}
-	hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6);
-	if (hostent_compare(hps, hpc))
-		result |= GETHOSTBYADDR_AF_INET6;
-	return (result);
+	ATF_REQUIRE_MSG(result == expected,
+	    "expected 0x%x, got 0x%x", expected, result);
 }
 
-int
-main(void)
+static cap_channel_t *
+cap_dns_init(void)
 {
-	cap_channel_t *capcas, *capdns, *origcapdns;
-	const char *types[2];
-	int families[2];
-
-	printf("1..91\n");
-	fflush(stdout);
+	cap_channel_t *capcas, *capdns;
 
 	capcas = cap_init();
-	CHECKX(capcas != NULL);
+	ATF_REQUIRE(capcas != NULL);
 
-	origcapdns = capdns = cap_service_open(capcas, "system.dns");
-	CHECKX(capdns != NULL);
+	capdns = cap_service_open(capcas, "system.dns");
+	ATF_REQUIRE(capdns != NULL);
 
 	cap_close(capcas);
 
-	/* No limits set. */
+	return (capdns);
+}
+
+ATF_TC(dns_no_limits);
+ATF_TC_HEAD(dns_no_limits, tc)
+{
+}
+ATF_TC_BODY(dns_no_limits, tc)
+{
+	cap_channel_t *capdns;
+
+	capdns = cap_dns_init();
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
-	     GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
+	     GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET |
+	     GETADDRINFO_AF_INET6));
 
-	/*
-	 * Allow:
-	 * type: NAME, ADDR
-	 * family: AF_INET, AF_INET6
-	 */
+	cap_close(capdns);
+}
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+ATF_TC(dns_all_limits);
+ATF_TC_HEAD(dns_all_limits, tc)
+{
+}
+ATF_TC_BODY(dns_all_limits, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
+
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
 	families[0] = AF_INET;
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, NULL, 0) == -1);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, NULL, 0) == -1);
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
 	     GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
 
 	cap_close(capdns);
+}
 
-	/*
-	 * Allow:
-	 * type: NAME
-	 * family: AF_INET, AF_INET6
-	 */
+ATF_TC(dns_name_limit);
+ATF_TC_HEAD(dns_name_limit, tc)
+{
+}
+ATF_TC_BODY(dns_name_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 2) == -1);
 	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 1) == -1);
 	families[0] = AF_INET;
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
 	    GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
 
 	cap_close(capdns);
+}
 
-	/*
-	 * Allow:
-	 * type: ADDR
-	 * family: AF_INET, AF_INET6
-	 */
+ATF_TC(dns_addr_limit);
+ATF_TC_HEAD(dns_addr_limit, tc)
+{
+}
+ATF_TC_BODY(dns_addr_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
 	types[1] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 2) == -1);
 	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 1) == -1);
 	families[0] = AF_INET;
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));
+
 	cap_close(capdns);
+}
 
-	/*
-	 * Allow:
-	 * type: NAME, ADDR
-	 * family: AF_INET
-	 */
+ATF_TC(dns_inet_limit);
+ATF_TC_HEAD(dns_inet_limit, tc)
+{
+}
+ATF_TC_BODY(dns_inet_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
 	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 2) == -1);
 	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 1) == -1);
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET |
 	    GETADDRINFO_AF_INET));
 
 	cap_close(capdns);
+}
 
-	/*
-	 * Allow:
-	 * type: NAME, ADDR
-	 * family: AF_INET6
-	 */
+ATF_TC(dns_inet6_limit);
+ATF_TC_HEAD(dns_inet6_limit, tc)
+{
+}
+ATF_TC_BODY(dns_inet6_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
 	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
 	families[1] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 2) == -1);
 	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 1) == -1);
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6 |
 	    GETADDRINFO_AF_INET6));
 
 	cap_close(capdns);
+}
 
-	/* Below we also test further limiting capability. */
-
-	/*
-	 * Allow:
-	 * type: NAME
-	 * family: AF_INET
-	 */
+ATF_TC(dns_name_inet_limit);
+ATF_TC_HEAD(dns_name_inet_limit, tc)
+{
+}
+ATF_TC_BODY(dns_name_inet_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
 	families[0] = AF_INET;
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
 	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 2) == -1);
 	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 1) == -1);
 	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 2) == -1);
 	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 1) == -1);
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETADDRINFO_AF_INET));
 
 	cap_close(capdns);
+}
 
-	/*
-	 * Allow:
-	 * type: NAME
-	 * family: AF_INET6
-	 */
+ATF_TC(dns_name_inet6_limit);
+ATF_TC_HEAD(dns_name_inet6_limit, tc)
+{
+}
+ATF_TC_BODY(dns_name_inet6_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
-	families[0] = AF_INET;
-	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
+	families[0] = AF_INET6;
+	families[1] = AF_INET;
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
 	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 2) == -1);
 	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 1) == -1);
 	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
 	families[1] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 2) == -1);
 	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 1) == -1);
 
-	CHECK(runtest(capdns) ==
+	runtest(capdns,
 	    (GETHOSTBYNAME2_AF_INET6 | GETADDRINFO_AF_INET6));
 
 	cap_close(capdns);
+}
 
-	/*
-	 * Allow:
-	 * type: ADDR
-	 * family: AF_INET
-	 */
+ATF_TC(dns_addr_inet_limit);
+ATF_TC_HEAD(dns_addr_inet_limit, tc)
+{
+}
+ATF_TC_BODY(dns_addr_inet_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
 	families[0] = AF_INET;
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
 	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
 	types[1] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 2) == -1);
 	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 1) == -1);
 	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
 	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 2) == -1);
 	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 1) == -1);
 
-	CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET);
+	runtest(capdns, GETHOSTBYADDR_AF_INET);
 
 	cap_close(capdns);
+}
 
-	/*
-	 * Allow:
-	 * type: ADDR
-	 * family: AF_INET6
-	 */
+ATF_TC(dns_addr_inet6_limit);
+ATF_TC_HEAD(dns_addr_inet6_limit, tc)
+{
+}
+ATF_TC_BODY(dns_addr_inet6_limit, tc)
+{
+	cap_channel_t *capdns;
+	const char *types[2];
+	int families[2];
 
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
+	capdns = cap_dns_init();
 
 	types[0] = "NAME2ADDR";
 	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
-	families[0] = AF_INET;
-	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 2) == 0);
+	families[0] = AF_INET6;
+	families[1] = AF_INET;
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 2) == 0);
 	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
+	ATF_REQUIRE(cap_dns_type_limit(capdns, types, 1) == 0);
 	types[1] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 2) == -1);
 	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_type_limit(capdns, types, 1) == -1);
 	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
+	ATF_REQUIRE(cap_dns_family_limit(capdns, families, 1) == 0);
 	families[1] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 2) == -1);
 	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
+	ATF_REQUIRE_ERRNO(ENOTCAPABLE,
+	    cap_dns_family_limit(capdns, families, 1) == -1);
 
-	CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6);
+	runtest(capdns, GETHOSTBYADDR_AF_INET6);
 
 	cap_close(capdns);
+}
 
-	/* Trying to rise the limits. */
-
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
-
-	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
-	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
-
-	types[0] = "NAME2ADDR";
-	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
-	families[0] = AF_INET;
-	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
-
-	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
-	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
-
-	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
-	    errno == ENOTCAPABLE);
-	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
-	    errno == ENOTCAPABLE);
-
-	/* Do the limits still hold? */
-	CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET |
-	    GETADDRINFO_AF_INET));
-
-	cap_close(capdns);
-
-	capdns = cap_clone(origcapdns);
-	CHECK(capdns != NULL);
-
-	types[0] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
-	families[0] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
-
-	types[0] = "NAME2ADDR";
-	types[1] = "ADDR2NAME";
-	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
-	    errno == ENOTCAPABLE);
-	families[0] = AF_INET;
-	families[1] = AF_INET6;
-	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
-	    errno == ENOTCAPABLE);
-
-	types[0] = "NAME2ADDR";
-	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
-	    errno == ENOTCAPABLE);
-	families[0] = AF_INET;
-	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
-	    errno == ENOTCAPABLE);
-
-	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
-	    errno == ENOTCAPABLE);
-	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
-	    errno == ENOTCAPABLE);
-
-	/* Do the limits still hold? */
-	CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6);
-
-	cap_close(capdns);
-
-	cap_close(origcapdns);
-
-	exit(0);
+ATF_TP_ADD_TCS(tp)
+{
+	ATF_TP_ADD_TC(tp, dns_no_limits);
+	ATF_TP_ADD_TC(tp, dns_all_limits);
+	ATF_TP_ADD_TC(tp, dns_name_limit);
+	ATF_TP_ADD_TC(tp, dns_addr_limit);
+	ATF_TP_ADD_TC(tp, dns_inet_limit);
+	ATF_TP_ADD_TC(tp, dns_inet6_limit);
+	ATF_TP_ADD_TC(tp, dns_name_inet_limit);
+	ATF_TP_ADD_TC(tp, dns_name_inet6_limit);
+	ATF_TP_ADD_TC(tp, dns_addr_inet_limit);
+	ATF_TP_ADD_TC(tp, dns_addr_inet6_limit);
+
+	return atf_no_error();
 }