public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
To: Jan Stancek <jstancek@redhat.com>
Cc: ltp-list@lists.sourceforge.net
Subject: Re: [LTP] [PATCH 2/2] waitid02: split code into separate testcases
Date: Fri, 17 May 2013 17:39:21 +0800	[thread overview]
Message-ID: <5195FAC9.40301@cn.fujitsu.com> (raw)
In-Reply-To: <f86dfe8123738c73c9dc2fd08309bfbe09e925e6.1368780870.git.jstancek@redhat.com>

On 05/17/2013 04:59 PM, Jan Stancek wrote:
> 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>

Acked-by: Wanlong Gao <gaowanlong@cn.fujitsu.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();
> 


------------------------------------------------------------------------------
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 10:00 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 ` [LTP] [PATCH 2/2] waitid02: split code into separate testcases Jan Stancek
2013-05-17  9:39   ` Wanlong Gao [this message]
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=5195FAC9.40301@cn.fujitsu.com \
    --to=gaowanlong@cn.fujitsu.com \
    --cc=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox