All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Stancek <jstancek@redhat.com>
To: ltp-list@lists.sourceforge.net
Subject: [LTP] [PATCH 2/2] waitid02: split code into separate testcases
Date: Fri, 17 May 2013 10:59:22 +0200	[thread overview]
Message-ID: <f86dfe8123738c73c9dc2fd08309bfbe09e925e6.1368780870.git.jstancek@redhat.com> (raw)
In-Reply-To: <4e8cb837f8dd19db77ca70bd3b0094b060b0b0a0.1368780870.git.jstancek@redhat.com>

Previous code in main was:
- using sleep for synchronization
  The sleep make take longer if run in overcommitted
  z/VM environment with considerably high steal time, which
  causes testcase to hang.
- missing wait for last child

This patch splits code from main() into separate testcases,
each with its own setup/cleanup and expected outcome.

Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
 testcases/kernel/syscalls/waitid/waitid02.c |  361 +++++++++++++++++----------
 1 files changed, 230 insertions(+), 131 deletions(-)

diff --git a/testcases/kernel/syscalls/waitid/waitid02.c b/testcases/kernel/syscalls/waitid/waitid02.c
index e265c32..bd5a13c 100644
--- a/testcases/kernel/syscalls/waitid/waitid02.c
+++ b/testcases/kernel/syscalls/waitid/waitid02.c
@@ -50,31 +50,246 @@
 #include "usctest.h"
 #include "linux_syscall_numbers.h"
 
+struct testcase_t {
+	const char *msg;
+	idtype_t idtype;
+	id_t id;
+	pid_t child;
+	int options;
+	int exp_ret;
+	int exp_errno;
+	int pipefd[2];
+	void (*setup) (struct testcase_t *);
+	void (*cleanup) (struct testcase_t *);
+};
+
+static void setup(void);
+static void cleanup(void);
+
+static void setup2(struct testcase_t *);
+static void setup3(struct testcase_t *);
+static void setup4(struct testcase_t *);
+static void setup5(struct testcase_t *);
+static void setup6(struct testcase_t *);
+static void cleanup2(struct testcase_t *);
+static void cleanup5(struct testcase_t *);
+static void cleanup6(struct testcase_t *);
+
+struct testcase_t tdat[] = {
+	{
+		.msg = "WNOHANG",
+		.idtype = P_ALL,
+		.id = 0,
+		.options = WNOHANG,
+		.exp_ret = -1,
+		.exp_errno = EINVAL,
+	},
+	{
+		.msg = "WNOHANG | WEXITED no child",
+		.idtype = P_ALL,
+		.id = 0,
+		.options = WNOHANG | WEXITED,
+		.exp_ret = -1,
+		.exp_errno = ECHILD,
+	},
+	{
+		.msg = "WNOHANG | WEXITED with child",
+		.idtype = P_ALL,
+		.id = 0,
+		.options = WNOHANG | WEXITED,
+		.exp_ret = 0,
+		.setup = setup2,
+		.cleanup = cleanup2
+	},
+	{
+		.msg = "P_PGID, WEXITED wait for child",
+		.idtype = P_PGID,
+		.options = WEXITED,
+		.exp_ret = 0,
+		.setup = setup3,
+	},
+	{
+		.msg = "P_PID, WEXITED wait for child",
+		.idtype = P_PID,
+		.options = WEXITED,
+		.exp_ret = 0,
+		.setup = setup4,
+	},
+	{
+		.msg = "P_PID, WSTOPPED | WNOWAIT",
+		.idtype = P_PID,
+		.options = WSTOPPED | WNOWAIT,
+		.exp_ret = 0,
+		.setup = setup5,
+		.cleanup = cleanup5
+	},
+	{
+		.msg = "P_PID, WCONTINUED",
+		.idtype = P_PID,
+		.options = WCONTINUED,
+		.exp_ret = 0,
+		.setup = setup6,
+		.cleanup = cleanup6
+	},
+
+};
+
 char *TCID = "waitid02";
-int testno;
-int TST_TOTAL = 4;
+static int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]);
 
-static void cleanup(void)
+static void makechild(struct testcase_t *t,
+	void (*childfn)(struct testcase_t *))
 {
-	TEST_CLEANUP;
-	tst_rmdir();
+	t->child = fork();
+	switch (t->child) {
+	case -1:
+		tst_brkm(TBROK | TERRNO, cleanup, "fork");
+		break;
+	case 0:
+		childfn(t);
+		exit(0);
+	}
+}
 
-	tst_exit();
+static void wait4child(pid_t pid)
+{
+	int status;
+	if (waitpid(pid, &status, 0) == -1)
+		tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
+	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+		tst_resm(TFAIL, "child returns %d", status);
+}
+
+static void dummy_child(struct testcase_t *t)
+{
+}
+
+static void waiting_child(struct testcase_t *t)
+{
+	int dummy;
+	read(t->pipefd[0], &dummy, 1);
+}
+
+static void stopped_child(struct testcase_t *t)
+{
+	int dummy;
+	kill(getpid(), SIGSTOP);
+	read(t->pipefd[0], &dummy, 1);
+}
+
+static void setup2(struct testcase_t *t)
+{
+	if (pipe(t->pipefd) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "pipe");
+	makechild(t, waiting_child);
+}
+
+static void cleanup2(struct testcase_t *t)
+{
+	write(t->pipefd[1], "", 1);
+	wait4child(t->child);
+	close(t->pipefd[0]);
+	close(t->pipefd[1]);
+}
+
+static void setup3(struct testcase_t *t)
+{
+	t->id = getpgid(0);
+	makechild(t, dummy_child);
+}
+
+static void setup4(struct testcase_t *t)
+{
+	makechild(t, dummy_child);
+	t->id = t->child;
+}
+
+static void setup5(struct testcase_t *t)
+{
+	if (pipe(t->pipefd) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "pipe");
+	makechild(t, stopped_child);
+	t->id = t->child;
+}
+
+static void cleanup5(struct testcase_t *t)
+{
+	kill(t->child, SIGCONT);
+	write(t->pipefd[1], "", 1);
+	wait4child(t->child);
+	close(t->pipefd[0]);
+	close(t->pipefd[1]);
+}
+
+static void setup6(struct testcase_t *t)
+{
+	siginfo_t infop;
+	if (pipe(t->pipefd) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "pipe");
+	makechild(t, stopped_child);
+	t->id = t->child;
+	if (waitid(P_PID, t->child, &infop, WSTOPPED) != 0)
+		tst_brkm(TBROK | TERRNO, cleanup, "waitpid setup6");
+	kill(t->child, SIGCONT);
+}
+
+static void cleanup6(struct testcase_t *t)
+{
+	write(t->pipefd[1], "", 1);
+	wait4child(t->child);
+	close(t->pipefd[0]);
+	close(t->pipefd[1]);
 }
 
 static void setup(void)
 {
 	TEST_PAUSE;
-	tst_tmpdir();
 }
 
-int main(int ac, char **av)
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+	tst_exit();
+}
+
+static void test_waitid(struct testcase_t *t)
 {
-	id_t pgid;
-	id_t id1, id2, id3;
 	siginfo_t infop;
 
-	int lc;
+	if (t->setup)
+		t->setup(t);
+
+	tst_resm(TINFO, "%s", t->msg);
+	tst_resm(TINFO, "(%d) waitid(%d, %d, %p, %d)", getpid(), t->idtype,
+			t->id, &infop, t->options);
+	memset(&infop, 0, sizeof(infop));
+
+	TEST(waitid(t->idtype, t->id, &infop, t->options));
+	if (TEST_RETURN == t->exp_ret) {
+		if (TEST_RETURN == -1) {
+			if (TEST_ERRNO == t->exp_errno)
+				tst_resm(TPASS, "exp_errno=%d", t->exp_errno);
+			else
+				tst_resm(TFAIL|TTERRNO, "exp_errno=%d",
+					t->exp_errno);
+		} else {
+			tst_resm(TPASS, "ret: %d", t->exp_ret);
+		}
+	} else {
+		tst_resm(TFAIL|TTERRNO, "ret=%ld expected=%d",
+			TEST_RETURN, t->exp_ret);
+	}
+	tst_resm(TINFO, "si_pid = %d ; si_code = %d ; si_status = %d",
+			infop.si_pid, infop.si_code,
+			infop.si_status);
+
+	if (t->cleanup)
+		t->cleanup(t);
+}
+
+int main(int ac, char **av)
+{
+	int lc, testno;
 	char *msg;
 
 	msg = parse_opts(ac, av, NULL, NULL);
@@ -84,127 +299,11 @@ int main(int ac, char **av)
 	}
 
 	setup();
-
 	for (lc = 0; TEST_LOOPING(lc); ++lc) {
-		tst_count = 0;
-		for (testno = 0; testno < TST_TOTAL; ++testno) {
-
-			TEST(waitid(P_ALL, 0, &infop, WNOHANG));
-			if (TEST_RETURN == -1)
-				tst_resm(TPASS, "Success1 ... -1 is returned."
-					" error is %d.", TEST_ERRNO);
-			else {
-				tst_resm(TFAIL, "%s Failed1 ...", TCID);
-			}
-
-			/* option == WEXITED | WCONTINUED | WSTOPPED |
-			 * WNOHANG | WNOWAIT */
-
-			TEST(id1 = fork());
-			if (TEST_RETURN == 0) {
-				tst_resm(TINFO,
-					 "I'm a child 1,my id is %d,gpid is %d",
-					 id1 = getpid(), __getpgid(0));
-				sleep(1);
-				exit(5);
-			}
-
-			TEST(id2 = fork());
-			if (TEST_RETURN == 0) {
-				sleep(3);
-				tst_resm(TINFO,
-					 "I'm a child 2,my id is %d,gpid is %d",
-					 id2 = getpid(), __getpgid(0));
-				exit(7);
-			}
-
-			TEST(id3 = fork());
-			if (TEST_RETURN == 0) {
-				sleep(2);
-				TEST(kill(id2, SIGCONT));
-				tst_resm(TINFO,
-					 "I'm a child 3,my id is %d,gpid is %d",
-					 id3 = getpid(), __getpgid(0));
-				exit(6);
-			}
-
-			TEST(waitid(P_ALL, 0, &infop, WNOHANG | WEXITED));
-			if (TEST_RETURN == 0)
-				tst_resm(TPASS, "Success 2 ...0 is returned.."
-					" error is %d.", TEST_ERRNO);
-			else {
-				tst_resm(TFAIL | TTERRNO, "%s Failed 2", TCID);
-				tst_exit();
-			}
-
-			tst_resm(TINFO, "I'm a Parent,my id is %d,gpid is %d",
-				 getpid(), pgid = __getpgid(0));
-
-			TEST(waitid(P_PGID, pgid, &infop, WEXITED));
-			if (TEST_RETURN == 0) {
-				tst_resm(TPASS, "Success3 ... 0 is returned.");
-				tst_resm(TINFO, "si_pid = %d ; si_code = %d ;"
-					" si_status = %d",
-					 infop.si_pid, infop.si_code,
-					 infop.si_status);
-			} else {
-				tst_resm(TFAIL | TTERRNO,
-					 "Fail3 ...  %ld is returned",
-					 TEST_RETURN);
-				tst_exit();
-			}
-
-			TEST(kill(id2, SIGSTOP));
-
-			TEST(waitid(P_PID, id2, &infop, WSTOPPED | WNOWAIT));
-			if (TEST_RETURN == 0) {
-				/*EINVAL*/
-				tst_resm(TINFO,	"si_pid = %d, si_code = %d,"
-					" si_status = %d",
-					infop.si_pid, infop.si_code,
-					infop.si_status);
-				tst_resm(TPASS, "Success4 ... 0 is returned");
-			} else {
-				tst_resm(TFAIL | TTERRNO,
-					"Fail4 ...  %ld is returned",
-					TEST_RETURN);
-				tst_exit();
-			}
-
-			TEST(waitid(P_PID, id3, &infop, WEXITED));
-			if (TEST_RETURN == 0) {
-				/*NOCHILD*/
-				tst_resm(TINFO,
-					"si_pid = %d, si_code = %d, "
-					"si_status = %d",
-					infop.si_pid, infop.si_code,
-					infop.si_status);
-				tst_resm(TPASS, "Success5 ... 0 is returned");
-			} else {
-				tst_resm(TFAIL | TTERRNO,
-					 "Fail5 ...  %ld is returned",
-					 TEST_RETURN);
-				tst_exit();
-			}
-
-			TEST(waitid(P_PID, id2, &infop, WCONTINUED));
-			if (TEST_RETURN == 0) {
-				/*EINVAL*/
-				tst_resm(TINFO,
-					"si_pid = %d, si_code = %d, "
-					"si_status = %d",
-					infop.si_pid, infop.si_code,
-					infop.si_status);
-				tst_resm(TPASS, "Success6 ... 0 is returned");
-			} else {
-				tst_resm(TFAIL | TTERRNO,
-					 "Fail6 ...  %ld is returned",
-					 TEST_RETURN);
-				tst_exit();
-			}
-
-			sleep(3);
-		}
+		/* setup alarm for unlikely event that test blocks */
+		alarm(5);
+		for (testno = 0; testno < TST_TOTAL; testno++)
+			test_waitid(&tdat[testno]);
 	}
 	cleanup();
 	tst_exit();
-- 
1.7.1


------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

  reply	other threads:[~2013-05-17  8:59 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-17  8:59 [LTP] [PATCH 1/2] waitid02: cleanup Jan Stancek
2013-05-17  8:59 ` Jan Stancek [this message]
2013-05-17  9:39   ` [LTP] [PATCH 2/2] waitid02: split code into separate testcases Wanlong Gao
2013-05-20 14:48   ` chrubis
     [not found]     ` <1279126164.4640384.1369062925009.JavaMail.root@redhat.com>
2013-05-20 15:21       ` chrubis
2013-05-20 15:42         ` chrubis
2013-05-21  7:14   ` [LTP] [PATCH v2 " Jan Stancek
2013-05-22 15:02     ` chrubis
2013-05-23  8:24     ` [LTP] [PATCH v3 " Jan Stancek
2013-05-27 16:20       ` chrubis
2013-05-27 17:02       ` [LTP] [PATCH v4 " Jan Stancek
2013-05-27 17:17         ` chrubis
2013-05-17  9:39 ` [LTP] [PATCH 1/2] waitid02: cleanup Wanlong Gao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f86dfe8123738c73c9dc2fd08309bfbe09e925e6.1368780870.git.jstancek@redhat.com \
    --to=jstancek@redhat.com \
    --cc=ltp-list@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.