From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1530D6E5CF for ; Fri, 14 Feb 2020 11:57:33 +0000 (UTC) Date: Fri, 14 Feb 2020 13:57:29 +0200 From: Petri Latvala Message-ID: <20200214115729.GW25209@platvala-desk.ger.corp.intel.com> References: <20200212132123.108506-1-arkadiusz.hiler@intel.com> <20200212132123.108506-2-arkadiusz.hiler@intel.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20200212132123.108506-2-arkadiusz.hiler@intel.com> Subject: Re: [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: igt-dev-bounces@lists.freedesktop.org Sender: "igt-dev" To: Arkadiusz Hiler Cc: igt-dev@lists.freedesktop.org List-ID: On Wed, Feb 12, 2020 at 03:21:15PM +0200, Arkadiusz Hiler wrote: > Because of excessive 'copy and paste' we ended up with multiple copies > of almost the same fork helper. This patch extracts the do_fork helper > out and switches all the tests over to it. > > Additionally, preemptively I have extracted the more fancy fork helper > that captures stderr/out + related functions out of igt_describe tests. > > Signed-off-by: Arkadiusz Hiler Reviewed-by: Petri Latvala > --- > lib/tests/igt_assert.c | 35 +++---- > lib/tests/igt_conflicting_args.c | 25 ++--- > lib/tests/igt_describe.c | 135 ++++++--------------------- > lib/tests/igt_dynamic_subtests.c | 18 ---- > lib/tests/igt_fork.c | 71 ++++++-------- > lib/tests/igt_invalid_subtest_name.c | 18 ---- > lib/tests/igt_no_exit.c | 18 ---- > lib/tests/igt_segfault.c | 59 +++++------- > lib/tests/igt_simulation.c | 101 +++++++++----------- > lib/tests/igt_tests_common.h | 91 ++++++++++++++++++ > 10 files changed, 232 insertions(+), 339 deletions(-) > > diff --git a/lib/tests/igt_assert.c b/lib/tests/igt_assert.c > index 1caf5d88..c94ac698 100644 > --- a/lib/tests/igt_assert.c > +++ b/lib/tests/igt_assert.c > @@ -38,8 +38,6 @@ > > #include "igt_tests_common.h" > > -char test[] = "test"; > -char *argv_run[] = { test }; > void (*test_to_run)(void) = NULL; > > /* > @@ -55,26 +53,17 @@ void (*test_to_run)(void) = NULL; > exec_total++; \ > } > > -static int do_fork(void) > +static void fake_test(void) > { > - int pid, status; > - int argc; > - > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - argc = ARRAY_SIZE(argv_run); > - igt_simple_init(argc, argv_run); > - test_to_run(); > - igt_exit(); > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > - > - return status; > - } > + char test[] = "test"; > + char *argv_run[] = { test }; > + int argc = ARRAY_SIZE(argv_run); > + > + igt_simple_init(argc, argv_run); > + > + test_to_run(); > + > + igt_exit(); > } > > static void test_cmpint_negative(void) > @@ -150,7 +139,7 @@ igt_main > * we inherit the state from the parent, so ... > */ > test_to_run = test_cmpint_negative; > - ret = do_fork(); > + ret = do_fork(fake_test); > igt_subtest("igt_cmpint_negative") > internal_assert_wexited(ret, IGT_EXIT_FAILURE); > > @@ -158,7 +147,7 @@ igt_main > test_fd(); > > test_to_run = test_fd_negative; > - ret = do_fork(); > + ret = do_fork(fake_test); > igt_subtest("igt_assert_fd_negative") > internal_assert_wexited(ret, IGT_EXIT_FAILURE); > } > diff --git a/lib/tests/igt_conflicting_args.c b/lib/tests/igt_conflicting_args.c > index f600abd4..b644fd4b 100644 > --- a/lib/tests/igt_conflicting_args.c > +++ b/lib/tests/igt_conflicting_args.c > @@ -43,25 +43,12 @@ static int opt_handler(int option, int option_index, void *input) > return 0; > } > > -static int do_fork(void) > +static void fake_test(void) > { > char test_name[] = "test"; > - > char *argv[] = { test_name }; > int argc = ARRAY_SIZE(argv); > > - pid_t pid = fork(); > - internal_assert(pid != -1); > - > - if (pid) { > - int status; > - while (waitpid(pid, &status, 0) == -1 && errno == EINTR) > - ; > - > - return status; > - } > - > - > igt_subtest_init_parse_opts(&argc, argv, short_options, long_options, > "", opt_handler, NULL); > igt_subtest("dummy") {} > @@ -73,27 +60,27 @@ int main(int argc, char **argv) > /* no conflict */ > long_options[0] = (struct option) { "iterations", required_argument, NULL, 'i'}; > short_options = ""; > - internal_assert_wexited(do_fork(), 0); > + internal_assert_wexited(do_fork(fake_test), 0); > > /* conflict on short option */ > long_options[0] = (struct option) { "iterations", required_argument, NULL, 'i'}; > short_options = "h"; > - internal_assert_wsignaled(do_fork(), SIGABRT); > + internal_assert_wsignaled(do_fork(fake_test), SIGABRT); > > /* conflict on long option name */ > long_options[0] = (struct option) { "help", required_argument, NULL, 'i'}; > short_options = ""; > - internal_assert_wsignaled(do_fork(), SIGABRT); > + internal_assert_wsignaled(do_fork(fake_test), SIGABRT); > > /* conflict on long option 'val' representation vs short option */ > long_options[0] = (struct option) { "iterations", required_argument, NULL, 'h'}; > short_options = ""; > - internal_assert_wsignaled(do_fork(), SIGABRT); > + internal_assert_wsignaled(do_fork(fake_test), SIGABRT); > > /* conflict on long option 'val' representations */ > long_options[0] = (struct option) { "iterations", required_argument, NULL, 500}; > short_options = ""; > - internal_assert_wsignaled(do_fork(), SIGABRT); > + internal_assert_wsignaled(do_fork(fake_test), SIGABRT); > > return 0; > } > diff --git a/lib/tests/igt_describe.c b/lib/tests/igt_describe.c > index 6f3a4319..7b4fa9af 100644 > --- a/lib/tests/igt_describe.c > +++ b/lib/tests/igt_describe.c > @@ -28,9 +28,15 @@ > #include "drmtest.h" > #include "igt_tests_common.h" > > +char prog[] = "igt_describe"; > +char fake_arg[100]; > +char *fake_argv[] = {prog, fake_arg}; > +int fake_argc = ARRAY_SIZE(fake_argv); > + > IGT_TEST_DESCRIPTION("the top level description"); > -static void fake_main(int argc, char **argv) { > - igt_subtest_init(argc, argv); > +static void fake_main(void) > +{ > + igt_subtest_init(fake_argc, fake_argv); > > igt_describe("Basic A"); > igt_subtest("A") > @@ -101,33 +107,33 @@ static void fake_main(int argc, char **argv) { > static const char DESCRIBE_ALL_OUTPUT[] = \ > "the top level description\n" > "\n" > - "SUB A ../lib/tests/igt_describe.c:36:\n" > + "SUB A ../lib/tests/igt_describe.c:42:\n" > " Basic A\n" > "\n" > - "SUB B ../lib/tests/igt_describe.c:45:\n" > + "SUB B ../lib/tests/igt_describe.c:51:\n" > " Group with B, C & D\n" > "\n" > " Basic B\n" > "\n" > - "SUB C ../lib/tests/igt_describe.c:54:\n" > + "SUB C ../lib/tests/igt_describe.c:60:\n" > " Group with B, C & D\n" > "\n" > " Group with C & D\n" > "\n" > " Basic C\n" > "\n" > - "SUB D ../lib/tests/igt_describe.c:58:\n" > + "SUB D ../lib/tests/igt_describe.c:64:\n" > " Group with B, C & D\n" > "\n" > " Group with C & D\n" > "\n" > - "SUB E ../lib/tests/igt_describe.c:66:\n" > + "SUB E ../lib/tests/igt_describe.c:72:\n" > " NO DOCUMENTATION!\n" > "\n" > - "SUB F ../lib/tests/igt_describe.c:71:\n" > + "SUB F ../lib/tests/igt_describe.c:77:\n" > " NO DOCUMENTATION!\n" > "\n" > - "SUB G ../lib/tests/igt_describe.c:80:\n" > + "SUB G ../lib/tests/igt_describe.c:86:\n" > " this description should be so long that it wraps itself nicely in the terminal this\n" > " description should be so long that it wraps itself nicely in the terminal this description\n" > " should be so long that it wraps itself nicely in the terminal this description should be so\n" > @@ -135,17 +141,17 @@ static const char DESCRIBE_ALL_OUTPUT[] = \ > " wraps itself nicely in the terminal this description should be so long that it wraps itself\n" > " nicely in the terminal\n" > "\n" > - "SUB F ../lib/tests/igt_describe.c:87:\n" > + "SUB F ../lib/tests/igt_describe.c:93:\n" > " verylongwordthatshoudlbeprintedeventhoughitspastthewrppinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n" > " verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n" > "\n" > - "SUB G ../lib/tests/igt_describe.c:91:\n" > + "SUB G ../lib/tests/igt_describe.c:97:\n" > " Subtest with dynamic subsubtests\n\n"; > > static const char JUST_C_OUTPUT[] = \ > "the top level description\n" > "\n" > - "SUB C ../lib/tests/igt_describe.c:54:\n" > + "SUB C ../lib/tests/igt_describe.c:60:\n" > " Group with B, C & D\n" > "\n" > " Group with C & D\n" > @@ -153,95 +159,22 @@ static const char JUST_C_OUTPUT[] = \ > " Basic C\n" > "\n"; > > -static void assert_pipe_empty(int fd) > -{ > - char buf[5]; > - internal_assert(0 == read(fd, buf, sizeof(buf))); > -} > - > -static void read_whole_pipe(int fd, char *buf, size_t buflen) > -{ > - ssize_t readlen; > - off_t offset; > - > - offset = 0; > - while ((readlen = read(fd, buf+offset, buflen-offset))) { > - if (readlen == -1) { > - if (errno == EINTR) { > - continue; > - } else { > - printf("read failed with %s\n", strerror(errno)); > - exit(1); > - } > - } > - internal_assert(readlen != -1); > - offset += readlen; > - } > -} > - > -static pid_t do_fork(int argc, char **argv, int *out, int *err) > -{ > - int outfd[2], errfd[2]; > - pid_t pid; > - > - internal_assert(pipe(outfd) != -1); > - internal_assert(pipe(errfd) != -1); > - > - pid = fork(); > - internal_assert(pid != -1); > - > - if (pid == 0) { > - while (dup2(outfd[1], STDOUT_FILENO) == -1 && errno == EINTR) {} > - while (dup2(errfd[1], STDERR_FILENO) == -1 && errno == EINTR) {} > - > - close(outfd[0]); > - close(outfd[1]); > - close(errfd[0]); > - close(errfd[1]); > - > - fake_main(argc, argv); > - > - exit(-1); > - } else { > - /* close the writing ends */ > - close(outfd[1]); > - close(errfd[1]); > - > - *out = outfd[0]; > - *err = errfd[0]; > - > - return pid; > - } > -} > - > -static int _wait(pid_t pid, int *status) { > - int ret; > - > - do { > - ret = waitpid(pid, status, 0); > - } while (ret == -1 && errno == EINTR); > - > - return ret; > -} > - > int main(int argc, char **argv) > { > - char prog[] = "igt_describe"; > int status; > int outfd, errfd; > + pid_t pid; > > /* describe all subtest */ { > static char out[4096]; > - char arg[] = "--describe"; > - char *fake_argv[] = {prog, arg}; > - int fake_argc = ARRAY_SIZE(fake_argv); > + strncpy(fake_arg, "--describe", sizeof(fake_arg)); > > - pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd); > + pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd); > > read_whole_pipe(outfd, out, sizeof(out)); > assert_pipe_empty(errfd); > > - internal_assert(_wait(pid, &status) != -1); > + internal_assert(safe_wait(pid, &status) != -1); > internal_assert(WIFEXITED(status)); > internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS); > internal_assert(0 == strcmp(DESCRIBE_ALL_OUTPUT, out)); > @@ -252,16 +185,14 @@ int main(int argc, char **argv) > > /* describe C using a pattern */ { > static char out[4096]; > - char arg[] = "--describe=C"; > - char *fake_argv[] = {prog, arg}; > - int fake_argc = ARRAY_SIZE(fake_argv); > + strncpy(fake_arg, "--describe=C", sizeof(fake_arg)); > > - pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd); > + pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd); > > read_whole_pipe(outfd, out, sizeof(out)); > assert_pipe_empty(errfd); > > - internal_assert(_wait(pid, &status) != -1); > + internal_assert(safe_wait(pid, &status) != -1); > internal_assert(WIFEXITED(status)); > internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS); > internal_assert(0 == strcmp(JUST_C_OUTPUT, out)); > @@ -272,15 +203,13 @@ int main(int argc, char **argv) > > /* fail describing with a bad pattern */ { > static char err[4096]; > - char arg[] = "--describe=Z"; > - char *fake_argv[] = {prog, arg}; > - int fake_argc = ARRAY_SIZE(fake_argv); > + strncpy(fake_arg, "--describe=Z", sizeof(fake_arg)); > > - pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd); > + pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd); > > read_whole_pipe(errfd, err, sizeof(err)); > > - internal_assert(_wait(pid, &status) != -1); > + internal_assert(safe_wait(pid, &status) != -1); > internal_assert(WIFEXITED(status)); > internal_assert(WEXITSTATUS(status) == IGT_EXIT_INVALID); > internal_assert(strstr(err, "Unknown subtest: Z")); > @@ -291,15 +220,13 @@ int main(int argc, char **argv) > > /* trying to igt_describe a dynamic subsubtest should assert */ { > static char err[4096]; > - char arg[] = "--run-subtest=G"; > - char *fake_argv[] = {prog, arg}; > - int fake_argc = ARRAY_SIZE(fake_argv); > + strncpy(fake_arg, "--run-subtest=G", sizeof(fake_arg)); > > - pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd); > + pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd); > > read_whole_pipe(errfd, err, sizeof(err)); > > - internal_assert(_wait(pid, &status) != -1); > + internal_assert(safe_wait(pid, &status) != -1); > internal_assert_wsignaled(status, SIGABRT); > > close(outfd); > diff --git a/lib/tests/igt_dynamic_subtests.c b/lib/tests/igt_dynamic_subtests.c > index 606104c5..bd1e1675 100644 > --- a/lib/tests/igt_dynamic_subtests.c > +++ b/lib/tests/igt_dynamic_subtests.c > @@ -29,24 +29,6 @@ > > #include "igt_tests_common.h" > > -static int do_fork(void (*test_to_run)(void)) > -{ > - int pid, status; > - > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - test_to_run(); > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > - > - return status; > - } > -} > - > static void dynamic_subtest_in_normal_subtest(void) > { > char prog[] = "igt_no_exit"; > diff --git a/lib/tests/igt_fork.c b/lib/tests/igt_fork.c > index e30584fd..4fd0e0c8 100644 > --- a/lib/tests/igt_fork.c > +++ b/lib/tests/igt_fork.c > @@ -35,37 +35,52 @@ > #include "igt_tests_common.h" > > char test[] = "test"; > -char *argv_run[] = { test }; > +char *fake_argv[] = { test }; > +int fake_argc = ARRAY_SIZE(fake_argv); > > static void igt_fork_vs_skip(void) > { > + igt_simple_init(fake_argc, fake_argv); > + > igt_fork(i, 1) { > igt_skip("skipping"); > } > > igt_waitchildren(); > + > + igt_exit(); > } > > static void igt_fork_vs_assert(void) > { > + igt_simple_init(fake_argc, fake_argv); > + > igt_fork(i, 1) { > igt_assert(0); > } > > igt_waitchildren(); > + > + igt_exit(); > } > > static void igt_fork_leak(void) > { > + igt_simple_init(fake_argc, fake_argv); > + > igt_fork(i, 1) { > sleep(10); > } > + > + igt_exit(); > } > > static void plain_fork_leak(void) > { > int pid; > > + igt_simple_init(fake_argc, fake_argv); > + > switch (pid = fork()) { > case -1: > internal_assert(0); > @@ -74,59 +89,21 @@ static void plain_fork_leak(void) > default: > exit(0); > } > + > + igt_exit(); > } > > static void igt_fork_timeout_leak(void) > { > + igt_simple_init(fake_argc, fake_argv); > + > igt_fork(i, 1) { > sleep(10); > } > > igt_waitchildren_timeout(1, "library test"); > -} > - > -static int do_fork(void (*test_to_run)(void)) > -{ > - int pid, status; > - int argc; > - > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - argc = ARRAY_SIZE(argv_run); > - igt_simple_init(argc, argv_run); > - test_to_run(); > - igt_exit(); > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > - > - return status; > - } > -} > - > -static int do_subtest(void (*test_to_run)(void)) > -{ > - int pid, status; > - int argc; > - > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - argc = ARRAY_SIZE(argv_run); > - igt_subtest_init(argc, argv_run); > - test_to_run(); > - igt_exit(); > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > > - return status; > - } > + igt_exit(); > } > > static void subtest_leak(void) > @@ -135,6 +112,8 @@ static void subtest_leak(void) > mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); > const int num_children = 4096 / sizeof(*children); > > + igt_subtest_init(fake_argc, fake_argv); > + > igt_subtest("fork-leak") { > igt_fork(child, num_children) > children[child] = getpid(); > @@ -148,6 +127,8 @@ static void subtest_leak(void) > assert(kill(children[i], 0) == -1 && errno == ESRCH); > > munmap(children, 4096); > + > + igt_exit(); > } > > int main(int argc, char **argv) > @@ -174,6 +155,6 @@ int main(int argc, char **argv) > ret = do_fork(plain_fork_leak); > internal_assert_wsignaled(ret, SIGABRT); > > - ret = do_subtest(subtest_leak); > + ret = do_fork(subtest_leak); > internal_assert_wexited(ret, IGT_EXIT_FAILURE); /* not asserted! */ > } > diff --git a/lib/tests/igt_invalid_subtest_name.c b/lib/tests/igt_invalid_subtest_name.c > index 92e767ab..32c4bcbc 100644 > --- a/lib/tests/igt_invalid_subtest_name.c > +++ b/lib/tests/igt_invalid_subtest_name.c > @@ -60,24 +60,6 @@ static void nonexisting_subtest(void) > igt_exit(); > } > > -static int do_fork(void (*test_to_run)(void)) > -{ > - int pid, status; > - > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - test_to_run(); > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > - > - return status; > - } > -} > - > int main(int argc, char **argv) > { > int ret; > diff --git a/lib/tests/igt_no_exit.c b/lib/tests/igt_no_exit.c > index 82f00b52..d303eba7 100644 > --- a/lib/tests/igt_no_exit.c > +++ b/lib/tests/igt_no_exit.c > @@ -56,24 +56,6 @@ static void no_exit(void) > ; > } > > -static int do_fork(void (*test_to_run)(void)) > -{ > - int pid, status; > - > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - test_to_run(); > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > - > - return status; > - } > -} > - > int main(int argc, char **argv) > { > int ret; > diff --git a/lib/tests/igt_segfault.c b/lib/tests/igt_segfault.c > index 0d872f67..38c040a6 100644 > --- a/lib/tests/igt_segfault.c > +++ b/lib/tests/igt_segfault.c > @@ -48,51 +48,38 @@ > bool simple; > bool runa; > bool runc; > -char test[] = "test"; > -char *argv_run[] = { test }; > > static void crashme(void) > { > raise(SIGSEGV); > } > > -static int do_fork(void) > +static void fake_test(void) > { > - int pid, status; > - int argc; > - > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - argc = ARRAY_SIZE(argv_run); > - if (simple) { > - igt_simple_init(argc, argv_run); > - crashme(); > + char prog[] = "test"; > + char *fake_argv[] = { prog }; > + int fake_argc = ARRAY_SIZE(fake_argv); > > - igt_exit(); > - } else { > - igt_subtest_init(argc, argv_run); > > - if(runa) > - igt_subtest("A") > - ; > + if (simple) { > + igt_simple_init(fake_argc, fake_argv); > + crashme(); > > - igt_subtest("B") > - crashme(); > + igt_exit(); > + } else { > + igt_subtest_init(fake_argc, fake_argv); > + if(runa) > + igt_subtest("A") > + ; > > - if(runc) > - igt_subtest("C") > - ; > + igt_subtest("B") > + crashme(); > > - igt_exit(); > - } > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > + if(runc) > + igt_subtest("C") > + ; > > - return status; > + igt_exit(); > } > } > > @@ -104,20 +91,20 @@ int main(int argc, char **argv) > runc=false; > igt_info("Simple test.\n"); > fflush(stdout); > - internal_assert_wsignaled(do_fork(), SIGSEGV); > + internal_assert_wsignaled(do_fork(fake_test), SIGSEGV); > > /* Test crash in a single subtest is reported */ > simple = false; > igt_info("Single subtest.\n"); > fflush(stdout); > - internal_assert_wexited(do_fork(), SIGSEGV + 128); > + internal_assert_wexited(do_fork(fake_test), SIGSEGV + 128); > > /* Test crash in a subtest following a pass is reported */ > simple = false; > runa=true; > igt_info("Passing then crashing subtest.\n"); > fflush(stdout); > - internal_assert_wexited(do_fork(), SIGSEGV + 128); > + internal_assert_wexited(do_fork(fake_test), SIGSEGV + 128); > > /* Test crash in a subtest preceeding a pass is reported */ > simple = false; > @@ -125,7 +112,7 @@ int main(int argc, char **argv) > runc=true; > igt_info("Crashing then passing subtest.\n"); > fflush(stdout); > - internal_assert_wexited(do_fork(), SIGSEGV + 128); > + internal_assert_wexited(do_fork(fake_test), SIGSEGV + 128); > > return 0; > } > diff --git a/lib/tests/igt_simulation.c b/lib/tests/igt_simulation.c > index 3f3cd88f..a0ea7000 100644 > --- a/lib/tests/igt_simulation.c > +++ b/lib/tests/igt_simulation.c > @@ -40,59 +40,44 @@ bool list_subtests; > bool in_fixture; > bool in_subtest; > > -char test[] = "test"; > -char list[] = "--list-subtests"; > -char *argv_list[] = { test, list }; > -char *argv_run[] = { test }; > - > -static int do_fork(void) > +static void fake_test(void) > { > - int pid, status; > + char test[] = "test"; > + char list[] = "--list-subtests"; > + char *argv_list[] = { test, list }; > + char *argv_run[] = { test }; > int argc; > > - switch (pid = fork()) { > - case -1: > - internal_assert(0); > - case 0: > - if (simple) { > - argc = 1; > - igt_simple_init(argc, argv_run); > + if (simple) { > + argc = 1; > + igt_simple_init(argc, argv_run); > > - igt_skip_on_simulation(); > + igt_skip_on_simulation(); > > - igt_exit(); > + igt_exit(); > + } else { > + if (list_subtests) { > + argc = 2; > + igt_subtest_init(argc, argv_list); > } else { > - if (list_subtests) { > - argc = 2; > - igt_subtest_init(argc, argv_list); > - } else { > - argc = 1; > - igt_subtest_init(argc, argv_run); > - } > - > - if (in_fixture) { > - igt_fixture > - igt_skip_on_simulation(); > - } if (in_subtest) { > - igt_subtest("sim") > - igt_skip_on_simulation(); > - } else > - igt_skip_on_simulation(); > - > - if (!in_subtest) > - igt_subtest("foo") > - ; > - > - igt_exit(); > + argc = 1; > + igt_subtest_init(argc, argv_run); > } > - default: > - while (waitpid(pid, &status, 0) == -1 && > - errno == EINTR) > - ; > > - internal_assert(WIFEXITED(status)); > + if (in_fixture) { > + igt_fixture > + igt_skip_on_simulation(); > + } if (in_subtest) { > + igt_subtest("sim") > + igt_skip_on_simulation(); > + } else > + igt_skip_on_simulation(); > + > + if (!in_subtest) > + igt_subtest("foo") > + ; > > - return status; > + igt_exit(); > } > } > > @@ -101,10 +86,10 @@ int main(int argc, char **argv) > /* simple tests */ > simple = true; > internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP); > > internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > /* subtests, list mode */ > simple = false; > @@ -112,28 +97,28 @@ int main(int argc, char **argv) > > in_fixture = false; > internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > in_fixture = true; > internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > > internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > > in_fixture = false; > in_subtest = true; > internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > > internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > > /* subtest, run mode */ > @@ -142,29 +127,29 @@ int main(int argc, char **argv) > > in_fixture = false; > internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP); > > internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > > in_fixture = true; > internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP); > > > internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > > in_fixture = false; > in_subtest = true; > internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP); > > > internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0); > - internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS); > + internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS); > > > return 0; > diff --git a/lib/tests/igt_tests_common.h b/lib/tests/igt_tests_common.h > index e66ee37c..b3da3b34 100644 > --- a/lib/tests/igt_tests_common.h > +++ b/lib/tests/igt_tests_common.h > @@ -26,6 +26,8 @@ > #define IGT_LIB_TESTS_COMMON_H > > #include > +#include > +#include > > /* > * We need to hide assert from the cocci igt test refactor spatch. > @@ -46,4 +48,93 @@ static inline void internal_assert_wsignaled(int wstatus, int signal) > internal_assert(WIFSIGNALED(wstatus) && > WTERMSIG(wstatus) == signal); > } > + > +static inline int do_fork(void (*test_to_run)(void)) > +{ > + int pid, status; > + > + switch (pid = fork()) { > + case -1: > + internal_assert(0); > + case 0: > + test_to_run(); > + default: > + while (waitpid(pid, &status, 0) == -1 && > + errno == EINTR) > + ; > + > + return status; > + } > +} > + > +static inline pid_t do_fork_bg_with_pipes(void (*test_to_run)(void), int *out, int *err) > +{ > + int outfd[2], errfd[2]; > + pid_t pid; > + > + internal_assert(pipe(outfd) != -1); > + internal_assert(pipe(errfd) != -1); > + > + pid = fork(); > + internal_assert(pid != -1); > + > + if (pid == 0) { > + while (dup2(outfd[1], STDOUT_FILENO) == -1 && errno == EINTR) {} > + while (dup2(errfd[1], STDERR_FILENO) == -1 && errno == EINTR) {} > + > + close(outfd[0]); > + close(outfd[1]); > + close(errfd[0]); > + close(errfd[1]); > + > + test_to_run(); > + > + exit(-1); > + } else { > + /* close the writing ends */ > + close(outfd[1]); > + close(errfd[1]); > + > + *out = outfd[0]; > + *err = errfd[0]; > + > + return pid; > + } > +} > + > +static inline int safe_wait(pid_t pid, int *status) { > + int ret; > + > + do { > + ret = waitpid(pid, status, 0); > + } while (ret == -1 && errno == EINTR); > + > + return ret; > +} > + > +static inline void assert_pipe_empty(int fd) > +{ > + char buf[5]; > + internal_assert(0 == read(fd, buf, sizeof(buf))); > +} > + > +static inline void read_whole_pipe(int fd, char *buf, size_t buflen) > +{ > + ssize_t readlen; > + off_t offset; > + > + offset = 0; > + while ((readlen = read(fd, buf+offset, buflen-offset))) { > + if (readlen == -1) { > + if (errno == EINTR) { > + continue; > + } else { > + printf("read failed with %s\n", strerror(errno)); > + exit(1); > + } > + } > + internal_assert(readlen != -1); > + offset += readlen; > + } > +} > #endif > -- > 2.24.1 > _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev