mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
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
This commit is contained in:
parent
65f75589e9
commit
581785a48f
37
repos/libports/run/fork.run
Normal file
37
repos/libports/run/fork.run
Normal file
@ -0,0 +1,37 @@
|
||||
build { core init test/fork }
|
||||
|
||||
create_boot_directory
|
||||
|
||||
install_config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="LOG"/>
|
||||
<service name="CPU"/>
|
||||
<service name="PD"/>
|
||||
</parent-provides>
|
||||
<start name="test-fork" caps="300">
|
||||
<resource name="RAM" quantum="1G"/>
|
||||
<config>
|
||||
<arg value="name_of_executeable"/>
|
||||
<libc stdin="/null" stdout="/log" stderr="/log">
|
||||
<fd id="3" path="/seek_test" readable="yes" seek="5"/>
|
||||
</libc>
|
||||
<vfs>
|
||||
<null/> <log/>
|
||||
<inline name="seek_test">0123456789</inline>
|
||||
</vfs>
|
||||
</config>
|
||||
<route> <any-service> <parent/> </any-service> </route>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
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]
|
@ -1,4 +1,4 @@
|
||||
TARGET = test-noux_fork
|
||||
TARGET = test-fork
|
||||
SRC_CC = test.cc
|
||||
LIBS = posix
|
||||
|
121
repos/libports/src/test/fork/test.cc
Normal file
121
repos/libports/src/test/fork/test.cc
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* \brief Simple fork test
|
||||
* \author Norman Feske
|
||||
* \date 2012-02-14
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
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;
|
||||
}
|
@ -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 {
|
||||
<config verbose="yes" stdin="/null" stdout="/log" stderr="/log">
|
||||
<fstab>
|
||||
<null/> <log/>
|
||||
<rom name="test-noux_fork" />
|
||||
<rom name="test-fork" />
|
||||
</fstab>
|
||||
<start name="test-noux_fork"> </start>
|
||||
<start name="test-fork"> </start>
|
||||
</config>
|
||||
</start>
|
||||
</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 "
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* \brief Simple fork test
|
||||
* \author Norman Feske
|
||||
* \date 2012-02-14
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user