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
next prev parent 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