Update test/* directory, it seem to be a bit bit-rotted

Added README; modified sigkill_rain.c to be more understandable,
made clone.c compile; added wait_must_be_interruptible.c test;
updated Makefile and .gitignore.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
Denys Vlasenko 2011-06-08 14:08:59 +02:00
parent b63256e69b
commit 8158e7716c
6 changed files with 120 additions and 7 deletions

4
test/.gitignore vendored
View File

@ -1,7 +1,9 @@
vfork
fork
sig
skodic
vfork
clone
leaderkill
childthread
sigkill_rain
wait_must_be_interruptible

View File

@ -2,11 +2,15 @@
# $Id$
#
all: vfork fork sig skodic clone leaderkill childthread
all: \
vfork fork sig skodic clone leaderkill childthread \
sigkill_rain wait_must_be_interruptible
leaderkill: LDFLAGS += -pthread
childthread: LDFLAGS += -pthread
clean distclean:
rm -f clone vfork fork sig leaderkill *.o core
rm -f *.o core \
vfork fork sig skodic clone leaderkill childthread \
sigkill_rain wait_must_be_interruptible

17
test/README Normal file
View File

@ -0,0 +1,17 @@
To run a test:
* Run make
* Run resulting executable(s) under strace
* Check strace output and/or program's output and exitcode
To add a new test:
* Add its .c source to this dir
* Add it to "all" and "clean" targets in Makefile
* Add it to .gitignore file
Please spend some time making your testcase understandable.
For example, it may print an explanation how it should be used
(which strace options to use, and what to look for in strace output).
If possible, make it so that your testcase detects error/bug
it is intended to test for, and prints error message and exits with 1
if the bug is detected, instead of relying on user to peruse strace output.

View File

@ -1,3 +1,6 @@
/* for CLONE_foo: */
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>

View File

@ -1,12 +1,10 @@
/* This test is not yet added to Makefile */
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
static const struct sockaddr sa;
@ -16,6 +14,12 @@ int main(int argc, char *argv[])
int pid;
sigset_t set;
printf(
"Please run me under 'strace -f -oLOG', and examine LOG file for incorrect\n"
"decoding of interrupted syscalls: grep for 'sendto', '??" /* anti-trigraph gap */ "?', 'unavailable'.\n"
"Pass number of iterations in argv[1] (default: 999).\n"
);
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, NULL);
@ -57,7 +61,7 @@ int main(int argc, char *argv[])
*/
switch (loops & 1) {
case 0:
break; /* intentional empty */
break; /* intentionally empty */
case 1:
sendto(-1, "Hello cruel world", 17, 0, &sa, sizeof(sa));
break;

View File

@ -0,0 +1,83 @@
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdio.h>
/* Expected order is:
* Child signals parent
* Parent got signal
* Child will exit now
*
* The bug we test for: under strace -f, last two lines are swapped
* because wait syscall is suspended by strace and thus can't be interrupted.
*/
static const char msg1[] = "Child signals parent\n";
static const char msg2[] = "Parent got signal\n";
static const char msg3[] = "Child will exit now\n";
static void handler(int s)
{
write(1, msg2, sizeof(msg2)-1);
}
static void test()
{
/* Note: in Linux, signal() installs handler with SA_RESTART flag,
* therefore wait will be restarted.
*/
signal(SIGALRM, handler);
if (fork() == 0) {
/* child */
sleep(1);
write(1, msg1, sizeof(msg1)-1);
kill(getppid(), SIGALRM);
sleep(1);
write(1, msg3, sizeof(msg3)-1);
_exit(0);
}
/* parent */
wait(NULL);
_exit(0);
}
int main()
{
char buf1[80];
char buf2[80];
char buf3[80];
int pipefd[2];
printf("Please run me under 'strace -f'\n");
pipe(pipefd);
if (fork() == 0) {
if (pipefd[1] != 1) {
dup2(pipefd[1], 1);
close(pipefd[1]);
}
test();
}
if (pipefd[0] != 0) {
dup2(pipefd[0], 0);
close(pipefd[0]);
}
fgets(buf1, 80, stdin); printf("%s", buf1);
fgets(buf2, 80, stdin); printf("%s", buf2);
fgets(buf3, 80, stdin); printf("%s", buf3);
if (strcmp(buf1, msg1) != 0
|| strcmp(buf2, msg2) != 0
|| strcmp(buf3, msg3) != 0
) {
printf("ERROR! Expected order:\n%s%s%s", msg1, msg2, msg3);
return 1;
}
printf("Good: wait seems to be correctly interrupted by signals\n");
return 0;
}