Module Name:    src
Committed By:   kamil
Date:           Wed Nov  9 17:50:19 UTC 2016

Modified Files:
        src/tests/lib/libc/sys: t_wait_noproc.c

Log Message:
Add new tests in t_wait_noproc and t_wait_noproc to test more options types

Add new tests:
 - waitpid_options
 - waitid_options
 - wait3_options
 - wait4_options
 - wait6_options

These tests are included in t_wait_noproc and t_wait_noproc_wnohang.

waitpid_options, wait3_options, wait4_options test combinations of options
of: bit for WALLSIG, WALTSIG, __WALL, __WCLONE and later a full combination
mask of WNOWAIT, WEXITED, WUNTRACED, WSTOPPED, WTRAPPED and WCONTINUED.

waitid and wait6 test full combination mask of WNOWAIT, WEXITED, WUNTRACED,
WSTOPPED, WTRAPPED and WCONTINUED -- excluded empty value and singular
WNOWAIT.

For compatibility reasons alter waitid and wait6 to test against options
WEXITED | WTRAPPED, as it's equivalent to waitpid, wait3, wait4.

The intention for these tests it to catch any possible issues with slighty
changed behavior of wait(2)-like functions in terms of valid options
values.

All tests pass successfully.

Sponsored by <The NetBSD Foundation>


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/tests/lib/libc/sys/t_wait_noproc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/lib/libc/sys/t_wait_noproc.c
diff -u src/tests/lib/libc/sys/t_wait_noproc.c:1.4 src/tests/lib/libc/sys/t_wait_noproc.c:1.5
--- src/tests/lib/libc/sys/t_wait_noproc.c:1.4	Wed Nov  9 12:44:29 2016
+++ src/tests/lib/libc/sys/t_wait_noproc.c	Wed Nov  9 17:50:19 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: t_wait_noproc.c,v 1.4 2016/11/09 12:44:29 kre Exp $ */
+/* $NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $ */
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -27,12 +27,13 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_wait_noproc.c,v 1.4 2016/11/09 12:44:29 kre Exp $");
+__RCSID("$NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $");
 
 #include <sys/wait.h>
 #include <sys/resource.h>
 
 #include <errno.h>
+#include <stdio.h>
 
 #include <atf-c.h>
 
@@ -78,7 +79,8 @@ ATF_TC_HEAD(waitid, tc)
 ATF_TC_BODY(waitid, tc)
 {
 	ATF_REQUIRE_ERRNO(ECHILD,
-	    waitid(P_ALL, 0, NULL, WEXITED | TWAIT_OPTION) == -1);
+	    waitid(P_ALL, 0, NULL,
+	        WTRAPPED | WEXITED | TWAIT_OPTION) == -1);
 }
 
 ATF_TC(wait3);
@@ -118,7 +120,202 @@ ATF_TC_HEAD(wait6, tc)
 ATF_TC_BODY(wait6, tc)
 {
 	ATF_REQUIRE_ERRNO(ECHILD,
-	    wait6(P_ALL, 0, NULL, WEXITED | TWAIT_OPTION, NULL, NULL) == -1);
+	    wait6(P_ALL, 0, NULL,
+	        WTRAPPED | WEXITED | TWAIT_OPTION, NULL, NULL) == -1);
+}
+
+/*
+ * Generator of valid combinations of options
+ * Usage: i = 0; while ((o = get_options_wait6(i++)) != -1) {}
+ */
+static int
+get_options6(size_t pos)
+{
+	int rv = 0;
+	size_t n;
+
+	/*
+	 * waitid(2) must specify at least one of WEXITED, WUNTRACED,
+	 * WSTOPPED, WTRAPPED or WCONTINUED. Single option WNOWAIT
+	 * isn't valid.
+	 */
+
+	const int matrix[] = {
+		WNOWAIT,	/* First in order to blacklist it easily */
+		WEXITED,
+		WUNTRACED,
+		WSTOPPED,	/* SUS compatibility, equal to WUNTRACED */
+		WTRAPPED,
+		WCONTINUED
+	};
+
+	const size_t M = (1 << __arraycount(matrix)) - 1;
+
+	/* Skip empty and sole WNOWAIT option */
+	pos+=2;
+
+	if (pos > M)
+		return -1;
+
+	for (n = 0; n < __arraycount(matrix); n++) {
+		if (pos & __BIT(n))
+			rv |= matrix[n];
+	}
+
+	return rv;
+}
+
+/*
+ * Generator of valid combinations of options
+ * Usage: i = 0; while ((o = get_options_wait4(i++)) != -1) {}
+ */
+static int
+get_options4(size_t pos)
+{
+	int rv = 0;
+	size_t n;
+
+	const int special[] = {
+		0,
+		WALLSIG,
+		WALTSIG,
+		__WALL,		/* Linux compatibility, equal to WALLSIG */
+		__WCLONE	/* Linux compatibility, equal to WALTSIG */
+	};
+
+	const int matrix[] = {
+		WNOWAIT,
+		WEXITED,
+		WUNTRACED,
+		WSTOPPED,	/* SUS compatibility, equal to WUNTRACED */
+		WTRAPPED,
+		WCONTINUED
+	};
+
+	const size_t M = (1 << __arraycount(special)) - 1;
+
+	if (pos < __arraycount(special))
+		return special[pos];
+
+	pos -= __arraycount(special);
+
+	++pos; /* Don't start with empty mask */
+
+	if (pos > M)
+		return -1;
+
+	for (n = 0; n < __arraycount(special); n++) {
+		if (pos & __BIT(n))
+			rv |= matrix[n];
+	}
+
+	return rv;
+}
+
+ATF_TC(waitpid_options);
+ATF_TC_HEAD(waitpid_options, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Test that waitpid(2) returns ECHILD for WAIT_ANY and valid "
+	    "combination of options with%s WNOHANG",
+	    TWAIT_OPTION == 0 ? "out" : "");
+}
+
+ATF_TC_BODY(waitpid_options, tc)
+{
+	size_t i = 0;
+	int o;
+
+	while((o = get_options4(i++)) != -1) {
+		printf("Testing waitpid(2) with options %x\n", o);
+
+		ATF_REQUIRE_ERRNO(ECHILD,
+		    waitpid(WAIT_ANY, NULL, o | TWAIT_OPTION) == -1);
+	}
+}
+
+ATF_TC(waitid_options);
+ATF_TC_HEAD(waitid_options, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Test that waitid(2) returns ECHILD for P_ALL and valid "
+	    "combination of options with%s WNOHANG",
+	    TWAIT_OPTION == 0 ? "out" : "");
+}
+
+ATF_TC_BODY(waitid_options, tc)
+{
+	size_t i = 0;
+	int o;
+
+	while((o = get_options6(i++)) != -1) {
+		printf("Testing waitid(2) with options %x\n", o);
+
+		ATF_REQUIRE_ERRNO(ECHILD,
+		    waitid(P_ALL, 0, NULL, o | TWAIT_OPTION) == -1);
+	}
+}
+
+ATF_TC(wait3_options);
+ATF_TC_HEAD(wait3_options, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Test that wait3(2) returns ECHILD for no child");
+}
+
+ATF_TC_BODY(wait3_options, tc)
+{
+	size_t i = 0;
+	int o;
+
+	while((o = get_options4(i++)) != -1) {
+		printf("Testing wait3(2) with options %x\n", o);
+
+		ATF_REQUIRE_ERRNO(ECHILD,
+		    wait3(NULL, o | TWAIT_OPTION, NULL) == -1);
+	}
+}
+
+ATF_TC(wait4_options);
+ATF_TC_HEAD(wait4_options, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s",
+	    ___STRING(TWAIT_OPTION));
+}
+
+ATF_TC_BODY(wait4_options, tc)
+{
+	size_t i = 0;
+	int o;
+
+	while((o = get_options4(i++)) != -1) {
+		printf("Testing wait4(2) with options %x\n", o);
+
+		ATF_REQUIRE_ERRNO(ECHILD,
+		    wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1);
+	}
+}
+
+ATF_TC(wait6_options);
+ATF_TC_HEAD(wait6_options, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Test that wait6(2) returns ECHILD for P_ALL and option %s",
+	    ___STRING(TWAIT_OPTION));
+}
+
+ATF_TC_BODY(wait6_options, tc)
+{
+	size_t i = 0;
+	int o;
+
+	while((o = get_options6(i++)) != -1) {
+		printf("Testing wait6(2) with options %x\n", o);
+
+		ATF_REQUIRE_ERRNO(ECHILD,
+		    wait6(P_ALL, 0, NULL, o | TWAIT_OPTION, NULL, NULL) == -1);
+	}
 }
 
 ATF_TP_ADD_TCS(tp)
@@ -133,5 +330,11 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, wait4);
 	ATF_TP_ADD_TC(tp, wait6);
 
+	ATF_TP_ADD_TC(tp, waitpid_options);
+	ATF_TP_ADD_TC(tp, waitid_options);
+	ATF_TP_ADD_TC(tp, wait3_options);
+	ATF_TP_ADD_TC(tp, wait4_options);
+	ATF_TP_ADD_TC(tp, wait6_options);
+
 	return atf_no_error();
 }

Reply via email to