From: Jeremy Kerr Date: Wed, 14 Aug 2013 07:05:56 +0000 (+0800) Subject: test/lib: add process tests X-Git-Tag: v1.0.0~511 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=d20e98b93afaf25faca4db2a3583c191bdabe439;hp=c7e26c27c7e029e6670dfebc8f27d9295e9fdeb7 test/lib: add process tests Signed-off-by: Jeremy Kerr --- diff --git a/test/lib/Makefile.am b/test/lib/Makefile.am index 16052c6..3b4d8cb 100644 --- a/test/lib/Makefile.am +++ b/test/lib/Makefile.am @@ -20,10 +20,16 @@ AM_CPPFLAGS = \ AM_CFLAGS = -O0 -ggdb -Wall -Wextra -Werror -list_test_SOURCES = list-test.c -list_test_LDADD = ../../lib/libpbcore.la +LDADD = ../../lib/libpbcore.la -check_PROGRAMS = list-test -TESTS = list-test +check_PROGRAMS = list-test \ + test-process-noargs \ + test-process-sync \ + test-process-sync-stdout \ + test-process-async \ + test-process-async-stdout \ + test-process-both + +TESTS = $(check_PROGRAMS) MAINTAINERCLEANFILES = Makefile.in diff --git a/test/lib/test-process-async-stdout.c b/test/lib/test-process-async-stdout.c new file mode 100644 index 0000000..fab9e39 --- /dev/null +++ b/test/lib/test-process-async-stdout.c @@ -0,0 +1,79 @@ + +#include +#include +#include + +#include +#include +#include + +static int do_child(void) +{ + printf("forty two\n"); + return 42; +} + +struct test { + bool exited; + int exit_status; + char *stdout_buf; + int stdout_len; +}; + +static void exit_cb(struct process *process) +{ + struct test *test = process->data; + + test->exited = true; + test->exit_status = process->exit_status; + + test->stdout_len = process->stdout_len; + test->stdout_buf = talloc_steal(test, process->stdout_buf); +} + +int main(int argc, char **argv) +{ + struct waitset *waitset; + struct process *process; + const char *child_argv[3]; + struct test *test; + + if (argc == 2 && !strcmp(argv[1], "child")) + return do_child(); + + test = talloc_zero(NULL, struct test); + + waitset = waitset_create(test); + + process_init(test, waitset); + + child_argv[0] = argv[0]; + child_argv[1] = "child"; + child_argv[2] = NULL; + + process = process_create(test); + process->path = child_argv[0]; + process->argv = child_argv; + process->keep_stdout = true; + process->exit_cb = exit_cb; + process->data = test; + + process_run_async(process); + + for (;;) { + waiter_poll(waitset); + + if (test->exited) + break; + } + + assert(WIFEXITED(test->exit_status)); + assert(WEXITSTATUS(test->exit_status) == 42); + assert(test->stdout_len == strlen("forty two\n")); + assert(test->stdout_buf); + assert(!memcmp(test->stdout_buf, "forty two\n", strlen("forty two\n"))); + + talloc_free(test); + + return EXIT_SUCCESS; +} diff --git a/test/lib/test-process-async.c b/test/lib/test-process-async.c new file mode 100644 index 0000000..61780ad --- /dev/null +++ b/test/lib/test-process-async.c @@ -0,0 +1,66 @@ + +#include +#include +#include + +#include +#include +#include + +static int do_child(void) +{ + return 42; +} + +static bool exited; +static int exit_status; + +static void exit_cb(struct process *process) +{ + exited = true; + exit_status = process->exit_status; +} + +int main(int argc, char **argv) +{ + struct waitset *waitset; + struct process *process; + const char *child_argv[3]; + void *ctx; + + if (argc == 2 && !strcmp(argv[1], "child")) + return do_child(); + + ctx = talloc_new(NULL); + + waitset = waitset_create(ctx); + + process_init(ctx, waitset); + + child_argv[0] = argv[0]; + child_argv[1] = "child"; + child_argv[2] = NULL; + + process = process_create(ctx); + process->path = child_argv[0]; + process->argv = child_argv; + process->exit_cb = exit_cb; + + exited = false; + + process_run_async(process); + + for (;;) { + waiter_poll(waitset); + + if (exited) + break; + } + + assert(WIFEXITED(exit_status)); + assert(WEXITSTATUS(exit_status) == 42); + + talloc_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/test/lib/test-process-both.c b/test/lib/test-process-both.c new file mode 100644 index 0000000..75e601c --- /dev/null +++ b/test/lib/test-process-both.c @@ -0,0 +1,122 @@ + +#include +#include +#include +#include +#include + +#include +#include +#include + +static const char *async_fifo = "/tmp/test-process-both.fifo"; + +static int do_sync_child(void) +{ + return 42; +} + +static int do_async_child(void) +{ + char c; + int fd; + + fd = open(async_fifo, O_RDONLY); + assert(fd >= 0); + + read(fd, &c, 1); + + assert(c == 1); + + return 43; +} + +struct test { + int async_fd; + struct process *sync_process; + struct process *async_process; + + bool async_exited; + int async_exit_status; + +}; + +static void async_exit_cb(struct process *process) +{ + struct test *test = process->data; + test->async_exited = true; + test->async_exit_status = process->exit_status; +} + +int main(int argc, char **argv) +{ + const char *sync_child_argv[3], *async_child_argv[3]; + struct waitset *waitset; + struct test *test; + char c; + int rc; + + if (argc == 2 && !strcmp(argv[1], "sync-child")) + return do_sync_child(); + + if (argc == 2 && !strcmp(argv[1], "async-child")) + return do_async_child(); + + test = talloc_zero(NULL, struct test); + + unlink(async_fifo); + rc = mkfifo(async_fifo, 0600); + assert(rc == 0); + + waitset = waitset_create(test); + + process_init(test, waitset); + + sync_child_argv[0] = argv[0]; + sync_child_argv[1] = "sync-child"; + sync_child_argv[2] = NULL; + + test->sync_process = process_create(test); + test->sync_process->path = sync_child_argv[0]; + test->sync_process->argv = sync_child_argv; + + async_child_argv[0] = argv[0]; + async_child_argv[1] = "async-child"; + async_child_argv[2] = NULL; + + test->async_process = process_create(test); + test->async_process->path = async_child_argv[0]; + test->async_process->argv = async_child_argv; + test->async_process->exit_cb = async_exit_cb; + test->async_process->data = test; + + process_run_async(test->async_process); + + process_run_sync(test->sync_process); + + assert(WIFEXITED(test->sync_process->exit_status)); + assert(WEXITSTATUS(test->sync_process->exit_status) == 42); + + /* now that the sync process has completed, let the async process + * exit */ + test->async_fd = open(async_fifo, O_WRONLY); + assert(test->async_fd >= 0); + c = 1; + write(test->async_fd, &c, 1); + + for (;;) { + waiter_poll(waitset); + + if (test->async_exited) + break; + } + + assert(WIFEXITED(test->async_exit_status)); + assert(WEXITSTATUS(test->async_exit_status) == 43); + + talloc_free(test); + + unlink(async_fifo); + + return EXIT_SUCCESS; +} diff --git a/test/lib/test-process-noargs.c b/test/lib/test-process-noargs.c new file mode 100644 index 0000000..02bdc58 --- /dev/null +++ b/test/lib/test-process-noargs.c @@ -0,0 +1,30 @@ + +#include +#include +#include + +#include +#include +#include + +int main(void) +{ + struct waitset *waitset; + int result; + void *ctx; + + ctx = talloc_new(NULL); + + waitset = waitset_create(ctx); + + process_init(ctx, waitset); + + result = process_run_simple(ctx, "true", NULL); + + assert(WIFEXITED(result)); + assert(WEXITSTATUS(result) == 0); + + talloc_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/test/lib/test-process-sync-stdout.c b/test/lib/test-process-sync-stdout.c new file mode 100644 index 0000000..96ccb75 --- /dev/null +++ b/test/lib/test-process-sync-stdout.c @@ -0,0 +1,53 @@ + +#include +#include +#include + +#include +#include +#include + +static int do_child(void) +{ + printf("forty two\n"); + return 42; +} + +int main(int argc, char **argv) +{ + struct waitset *waitset; + struct process *process; + const char *child_argv[3]; + void *ctx; + + if (argc == 2 && !strcmp(argv[1], "child")) + return do_child(); + + ctx = talloc_new(NULL); + + waitset = waitset_create(ctx); + + process_init(ctx, waitset); + + child_argv[0] = argv[0]; + child_argv[1] = "child"; + child_argv[2] = NULL; + + process = process_create(ctx); + process->path = child_argv[0]; + process->argv = child_argv; + process->keep_stdout = true; + + process_run_sync(process); + + assert(WIFEXITED(process->exit_status)); + assert(WEXITSTATUS(process->exit_status) == 42); + + assert(process->stdout_len == strlen("forty two\n")); + assert(!memcmp(process->stdout_buf, "forty two\n", + process->stdout_len)); + + talloc_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/test/lib/test-process-sync.c b/test/lib/test-process-sync.c new file mode 100644 index 0000000..b47bdc6 --- /dev/null +++ b/test/lib/test-process-sync.c @@ -0,0 +1,47 @@ + +#include +#include +#include + +#include +#include +#include + +static int do_child(void) +{ + return 42; +} + +int main(int argc, char **argv) +{ + struct waitset *waitset; + struct process *process; + const char *child_argv[3]; + void *ctx; + + if (argc == 2 && !strcmp(argv[1], "child")) + return do_child(); + + ctx = talloc_new(NULL); + + waitset = waitset_create(ctx); + + process_init(ctx, waitset); + + child_argv[0] = argv[0]; + child_argv[1] = "child"; + child_argv[2] = NULL; + + process = process_create(ctx); + process->path = child_argv[0]; + process->argv = child_argv; + + process_run_sync(process); + + assert(WIFEXITED(process->exit_status)); + assert(WEXITSTATUS(process->exit_status) == 42); + + talloc_free(ctx); + + return EXIT_SUCCESS; +}