From 581785a48f3139cb06ca33015b9534969e705749 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 13 Aug 2019 16:16:56 +0200 Subject: [PATCH] Extend fork test This patch extends the fork test with explicit checks for the cloned content of the heap and RW segment as well as the seek position of an open file descriptor. It adds the new libports/run/fork.run script that exercises the fork mechanism implemented by the libc. It is based on noux_fork.run, which tests the mechansim provided by noux. The test program has been moved from ports to libports. Issue #3478 --- repos/libports/run/fork.run | 37 ++++++ .../src/test/fork}/target.mk | 2 +- repos/libports/src/test/fork/test.cc | 121 ++++++++++++++++++ repos/ports/run/noux_fork.run | 8 +- repos/ports/src/test/noux_fork/test.cc | 73 ----------- 5 files changed, 163 insertions(+), 78 deletions(-) create mode 100644 repos/libports/run/fork.run rename repos/{ports/src/test/noux_fork => libports/src/test/fork}/target.mk (69%) create mode 100644 repos/libports/src/test/fork/test.cc delete mode 100644 repos/ports/src/test/noux_fork/test.cc diff --git a/repos/libports/run/fork.run b/repos/libports/run/fork.run new file mode 100644 index 000000000..03dc7c27f --- /dev/null +++ b/repos/libports/run/fork.run @@ -0,0 +1,37 @@ +build { core init test/fork } + +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + 0123456789 + + + + + +} + +build_boot_image { + core init ld.lib.so libc.lib.so vfs.lib.so libm.lib.so posix.lib.so test-fork +} + +append qemu_args " -nographic " + +run_genode_until "--- parent done ---.*\n" 20 +run_genode_until "child.*exited.*\n" 5 [output_spawn_id] diff --git a/repos/ports/src/test/noux_fork/target.mk b/repos/libports/src/test/fork/target.mk similarity index 69% rename from repos/ports/src/test/noux_fork/target.mk rename to repos/libports/src/test/fork/target.mk index 9d94b9841..cb2bda101 100644 --- a/repos/ports/src/test/noux_fork/target.mk +++ b/repos/libports/src/test/fork/target.mk @@ -1,4 +1,4 @@ -TARGET = test-noux_fork +TARGET = test-fork SRC_CC = test.cc LIBS = posix diff --git a/repos/libports/src/test/fork/test.cc b/repos/libports/src/test/fork/test.cc new file mode 100644 index 000000000..6f4ec4f28 --- /dev/null +++ b/repos/libports/src/test/fork/test.cc @@ -0,0 +1,121 @@ +/* + * \brief Simple fork test + * \author Norman Feske + * \date 2012-02-14 + */ + +#include +#include +#include +#include +#include +#include + +enum { MAX_COUNT = 100 }; + +int main(int, char **argv) +{ + printf("--- test-fork started ---\n"); + + enum { MSG_SIZE = 100 }; + static char message_in_rw_segment[MSG_SIZE]; + char const * const message_about_rw_segment = "message stored in rw segment"; + strncpy(message_in_rw_segment, message_about_rw_segment, MSG_SIZE); + + char * const message_on_heap = (char *)malloc(MSG_SIZE); + char const * const message_about_heap = "message stored on the heap"; + strncpy(message_on_heap, message_about_heap, MSG_SIZE - 1); + + enum { ARGV0_SIZE = 100 }; + static char parent_argv0[ARGV0_SIZE]; + strncpy(parent_argv0, argv[0], ARGV0_SIZE - 1); + + pid_t fork_ret = fork(); + if (fork_ret < 0) { + printf("Error: fork returned %d, errno=%d\n", fork_ret, errno); + return -1; + } + + printf("pid %d: fork returned %d\n", getpid(), fork_ret); + + /* child */ + if (fork_ret == 0) { + printf("pid %d: child says hello\n", getpid()); + + /* + * Validate that the child's heap and RW segment correspond to the + * the state of the parent. + */ + printf("RW segment: %s\n", message_in_rw_segment); + if (strcmp(message_in_rw_segment, message_about_rw_segment)) { + printf("Error: unexpected content of the child's RW segment\n"); + return -1; + } + + printf("argv0: %s\n", argv[0]); + if (!argv[0] || strcmp(argv[0], parent_argv0)) { + printf("Error: unexpected content of the child's args buffer\n"); + return -1; + } + + printf("heap: %s\n", message_on_heap); + if (strcmp(message_on_heap, message_about_heap)) { + printf("Error: unexpected content on the child's heap\n"); + return -1; + } + + { + char c = 0; + if (read(3, &c, 1) == 1) { + printf("read character '%c' from FD 3\n", c); + if (c != '5') { + printf("Error: read unexpected value from FD 3\n"); + return -1; + } + } + } + + pid_t fork_ret = fork(); + if (fork_ret < 0) { + printf("Error: fork returned %d, errno=%d\n", fork_ret, errno); + return -1; + } + + printf("pid %d: fork returned %d\n", getpid(), fork_ret); + + /* grand child */ + if (fork_ret == 0) { + printf("pid %d: grand child says hello\n", getpid()); + + for (int k = 0; k < MAX_COUNT; k++) { + printf("pid %d: grand child k = %d\n", getpid(), k); + } + + return 0; + }; + + for (int j = 0; j < MAX_COUNT; j++) { + printf("pid %d: child j = %d\n", getpid(), j); + } + + if (fork_ret != 0) { + printf("pid %d: child waits for grand-child exit\n", getpid()); + waitpid(fork_ret, nullptr, 0); + } + + return 0; + } + + printf("pid %d: parent received child pid %d, starts counting...\n", + getpid(), fork_ret); + + for (int i = 0; i < MAX_COUNT; ) { + printf("pid %d: parent i = %d\n", getpid(), i++); + } + + printf("pid %d: parent waits for child exit\n", getpid()); + waitpid(fork_ret, nullptr, 0); + + printf("--- parent done ---\n"); + return 0; +} diff --git a/repos/ports/run/noux_fork.run b/repos/ports/run/noux_fork.run index 39e846743..1c0f50e75 100644 --- a/repos/ports/run/noux_fork.run +++ b/repos/ports/run/noux_fork.run @@ -1,6 +1,6 @@ build { core init timer server/log_terminal noux lib/libc_noux - test/noux_fork + test/fork } create_boot_directory @@ -34,9 +34,9 @@ install_config { - + - + @@ -44,7 +44,7 @@ install_config { build_boot_image { core init timer log_terminal noux ld.lib.so libc.lib.so vfs.lib.so libm.lib.so - libc_noux.lib.so posix.lib.so test-noux_fork + libc_noux.lib.so posix.lib.so test-fork } append qemu_args " -nographic " diff --git a/repos/ports/src/test/noux_fork/test.cc b/repos/ports/src/test/noux_fork/test.cc deleted file mode 100644 index 5d35f0703..000000000 --- a/repos/ports/src/test/noux_fork/test.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* - * \brief Simple fork test - * \author Norman Feske - * \date 2012-02-14 - */ - -#include -#include -#include -#include - -enum { MAX_COUNT = 1000 }; - -int main(int, char **) -{ - printf("--- test-noux_fork started ---\n"); - - pid_t fork_ret = fork(); - if (fork_ret < 0) { - printf("Error: fork returned %d, errno=%d\n", fork_ret, errno); - return -1; - } - - printf("pid %d: fork returned %d\n", getpid(), fork_ret); - - /* child */ - if (fork_ret == 0) { - printf("pid %d: child says hello\n", getpid()); - - pid_t fork_ret = fork(); - if (fork_ret < 0) { - printf("Error: fork returned %d, errno=%d\n", fork_ret, errno); - return -1; - } - - printf("pid %d: fork returned %d\n", getpid(), fork_ret); - - /* grand child */ - if (fork_ret == 0) { - printf("pid %d: grand child says hello\n", getpid()); - - for (int k = 0; k < MAX_COUNT; k++) { - printf("pid %d: grand child k = %d\n", getpid(), k); - } - - return 0; - }; - - for (int j = 0; j < MAX_COUNT; j++) { - printf("pid %d: child j = %d\n", getpid(), j); - } - - if (fork_ret != 0) { - printf("pid %d: child waits for grand-child exit\n", getpid()); - waitpid(fork_ret, nullptr, 0); - } - - return 0; - } - - printf("pid %d: parent received child pid %d, starts counting...\n", - getpid(), fork_ret); - - for (int i = 0; i < MAX_COUNT; ) { - printf("pid %d: parent i = %d\n", getpid(), i++); - } - - printf("pid %d: parent waits for child exit\n", getpid()); - waitpid(fork_ret, nullptr, 0); - - printf("--- parent done ---\n"); - return 0; -}