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 <[email protected]>

Acked-by: Wanlong Gao <[email protected]>

> ---
>  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
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to