Make test40 behave
Make test40 behave better. It should create its own subdirectory to conduct its tests and should not write to /tmp. Also, the master-slave terminal pair it tries to open might be in use; it should try to obtain another pair. These changes allow the test to be run multiple times simultaneously from different paths (to test select() more intensively).
This commit is contained in:
parent
196de8bc40
commit
827daf1fca
@ -23,7 +23,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define FILE1 "/tmp/selecttest01-1"
|
#define FILE1 "selecttestb-1"
|
||||||
#define FILES 2
|
#define FILES 2
|
||||||
#define TIME 3
|
#define TIME 3
|
||||||
|
|
||||||
|
|||||||
92
test/t40c.c
92
test/t40c.c
@ -37,28 +37,48 @@ void e(int n, char *s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_child(void) {
|
void open_terminal(int *child_fd, int *parent_fd) {
|
||||||
int fd, retval;
|
int fd1, fd2, i;
|
||||||
struct timeval tv;
|
char opentermw[5+OPEN_MAX+1];
|
||||||
|
char opentermr[5+OPEN_MAX+1];
|
||||||
|
char *term[] = {"f","e","d","c","b","a","9","8","7","6","5","4","3","2","1"};
|
||||||
|
|
||||||
/* Opening master terminal for writing */
|
if (!child_fd || !parent_fd) exit(EXIT_FAILURE);
|
||||||
if((fd = open(TERMINALW, O_WRONLY)) == -1) {
|
|
||||||
printf("Error opening %s for writing, signalling parent to quit\n",
|
for (i = 0; i < 16; i++) {
|
||||||
TERMINALW);
|
snprintf(opentermw, 5+OPEN_MAX, "/dev/ttyp%s", term[i]);
|
||||||
perror(NULL);
|
snprintf(opentermr, 5+OPEN_MAX, "/dev/ptyp%s", term[i]);
|
||||||
printf("Please make sure that %s is not in use while running this test\n",
|
|
||||||
TERMINALW);
|
/* Open master terminal for writing */
|
||||||
exit(-1);
|
if((fd1 = open(opentermw, O_WRONLY)) == -1) continue;
|
||||||
|
|
||||||
|
/* Open slave terminal for reading */
|
||||||
|
if((fd2 = open(opentermr, O_RDONLY)) == -1) {
|
||||||
|
close(fd1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*child_fd = fd1;
|
||||||
|
*parent_fd = fd2;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we get here we failed to find a terminal pair */
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_child(int terminal) {
|
||||||
|
int retval;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
/* Going to sleep for two seconds to allow the parent proc to get ready */
|
/* Going to sleep for two seconds to allow the parent proc to get ready */
|
||||||
tv.tv_sec = 2;
|
tv.tv_sec = 2;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
select(0, NULL, NULL, NULL, &tv);
|
select(0, NULL, NULL, NULL, &tv);
|
||||||
|
|
||||||
/* Try to write. Doesn't matter how many bytes we actually send. */
|
/* Try to write. Doesn't matter how many bytes we actually send. */
|
||||||
retval = write(fd, SENDSTRING, strlen(SENDSTRING));
|
retval = write(terminal, SENDSTRING, strlen(SENDSTRING));
|
||||||
close(fd);
|
close(terminal);
|
||||||
|
|
||||||
/* Wait for another second to allow the parent to process incoming data */
|
/* Wait for another second to allow the parent to process incoming data */
|
||||||
tv.tv_usec = 1000000;
|
tv.tv_usec = 1000000;
|
||||||
@ -66,65 +86,55 @@ int do_child(void) {
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_parent(int child) {
|
int do_parent(int child, int terminal) {
|
||||||
int fd;
|
|
||||||
fd_set fds_read, fds_write, fds_error;
|
fd_set fds_read, fds_write, fds_error;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Open slave terminal for reading */
|
|
||||||
if((fd = open(TERMINALR, O_RDONLY)) == -1) {
|
|
||||||
printf("Error opening %s for reading\n", TERMINALR);
|
|
||||||
perror(NULL);
|
|
||||||
printf("Please make sure that %s is not in use while running this test.\n",
|
|
||||||
TERMINALR);
|
|
||||||
waitpid(child, &retval, 0);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear bit masks */
|
/* Clear bit masks */
|
||||||
FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error);
|
FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error);
|
||||||
/* Set read bits */
|
/* Set read bits */
|
||||||
FD_SET(fd, &fds_read);
|
FD_SET(terminal, &fds_read);
|
||||||
FD_SET(fd, &fds_write);
|
FD_SET(terminal, &fds_write);
|
||||||
|
|
||||||
/* Test if we can read or write from/to fd. As fd is opened read only we
|
/* Test if we can read or write from/to fd. As fd is opened read only we
|
||||||
* cannot actually write, so the select should return immediately with fd
|
* cannot actually write, so the select should return immediately with fd
|
||||||
* set in fds_write, but not in fds_read. Note that the child waits two
|
* set in fds_write, but not in fds_read. Note that the child waits two
|
||||||
* seconds before sending data. This gives us the opportunity run this
|
* seconds before sending data. This gives us the opportunity run this
|
||||||
* sub-test as reading from fd is blocking at this point. */
|
* sub-test as reading from fd is blocking at this point. */
|
||||||
retval = select(fd+1, &fds_read, &fds_write, &fds_error, NULL);
|
retval = select(terminal+1, &fds_read, &fds_write, &fds_error, NULL);
|
||||||
|
|
||||||
if(retval != 1) e(1, "incorrect amount of ready file descriptors");
|
if(retval != 1) e(1, "incorrect amount of ready file descriptors");
|
||||||
|
|
||||||
|
|
||||||
if(FD_ISSET(fd, &fds_read)) e(2, "read should NOT be set");
|
if(FD_ISSET(terminal, &fds_read)) e(2, "read should NOT be set");
|
||||||
if(!FD_ISSET(fd, &fds_write)) e(3, "write should be set");
|
if(!FD_ISSET(terminal, &fds_write)) e(3, "write should be set");
|
||||||
if(FD_ISSET(fd, &fds_error)) e(4, "error should NOT be set");
|
if(FD_ISSET(terminal, &fds_error)) e(4, "error should NOT be set");
|
||||||
|
|
||||||
/* Block until ready; until child wrote stuff */
|
/* Block until ready; until child wrote stuff */
|
||||||
FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error);
|
FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error);
|
||||||
FD_SET(fd, &fds_read);
|
FD_SET(terminal, &fds_read);
|
||||||
retval = select(fd+1, &fds_read, NULL, &fds_error, NULL);
|
retval = select(terminal+1, &fds_read, NULL, &fds_error, NULL);
|
||||||
|
|
||||||
if(retval != 1) e(5, "incorrect amount of ready file descriptors");
|
if(retval != 1) e(5, "incorrect amount of ready file descriptors");
|
||||||
if(!FD_ISSET(fd, &fds_read)) e(6, "read should be set");
|
if(!FD_ISSET(terminal, &fds_read)) e(6, "read should be set");
|
||||||
if(FD_ISSET(fd, &fds_error)) e(7, "error should not be set");
|
if(FD_ISSET(terminal, &fds_error)) e(7, "error should not be set");
|
||||||
|
|
||||||
|
|
||||||
FD_ZERO(&fds_read); FD_ZERO(&fds_error);
|
FD_ZERO(&fds_read); FD_ZERO(&fds_error);
|
||||||
FD_SET(fd,&fds_write);
|
FD_SET(terminal, &fds_write);
|
||||||
retval = select(fd+1, NULL, &fds_write, NULL, NULL);
|
retval = select(terminal+1, NULL, &fds_write, NULL, NULL);
|
||||||
/* As it is impossible to write to a read only fd, this select should return
|
/* As it is impossible to write to a read only fd, this select should return
|
||||||
* immediately with fd set in fds_write. */
|
* immediately with fd set in fds_write. */
|
||||||
if(retval != 1) e(8, "incorrect amount or ready file descriptors");
|
if(retval != 1) e(8, "incorrect amount or ready file descriptors");
|
||||||
|
|
||||||
close(fd);
|
close(terminal);
|
||||||
waitpid(child, &retval, 0);
|
waitpid(child, &retval, 0);
|
||||||
exit(errct);
|
exit(errct);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int forkres;
|
int forkres;
|
||||||
|
int master, slave;
|
||||||
|
|
||||||
/* Get subtest number */
|
/* Get subtest number */
|
||||||
if(argc != 2) {
|
if(argc != 2) {
|
||||||
@ -135,9 +145,11 @@ int main(int argc, char **argv) {
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open_terminal(&master, &slave);
|
||||||
|
|
||||||
forkres = fork();
|
forkres = fork();
|
||||||
if(forkres == 0) do_child();
|
if(forkres == 0) do_child(master);
|
||||||
else if(forkres > 0) do_parent(forkres);
|
else if(forkres > 0) do_parent(forkres, slave);
|
||||||
else { /* Fork failed */
|
else { /* Fork failed */
|
||||||
perror("Unable to fork");
|
perror("Unable to fork");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
@ -36,8 +36,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#define NAMEDPIPE1 "/tmp/selecttest03-1"
|
#define NAMEDPIPE1 "selecttestd-1"
|
||||||
#define NAMEDPIPE2 "/tmp/selecttest03-2"
|
#define NAMEDPIPE2 "selecttestd-2"
|
||||||
#define SENDSTRING "minixrocks"
|
#define SENDSTRING "minixrocks"
|
||||||
#define DO_HANDLEDATA 1
|
#define DO_HANDLEDATA 1
|
||||||
#define DO_PAUSE 3
|
#define DO_PAUSE 3
|
||||||
|
|||||||
@ -11,19 +11,26 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define MAX_ERROR 5
|
||||||
|
#include "common.c"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
char *tests[] = {"t40a", "t40b", "t40c", "t40d", "t40e", "t40f"};
|
char *tests[] = {"t40a", "t40b", "t40c", "t40d", "t40e", "t40f"};
|
||||||
|
char copy_command[8+PATH_MAX+1];
|
||||||
int no_tests, i, forkres, status = 0, errorct = 0;
|
int no_tests, i, forkres, status = 0, errorct = 0;
|
||||||
|
|
||||||
no_tests = sizeof(tests) / sizeof(char *);
|
no_tests = sizeof(tests) / sizeof(char *);
|
||||||
|
|
||||||
printf("Test 40 ");
|
start(40);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
for(i = 0; i < no_tests; i++) {
|
for(i = 0; i < no_tests; i++) {
|
||||||
char subtest[2];
|
char subtest[2];
|
||||||
sprintf(subtest, "%d", i+1);
|
snprintf(subtest, 2, "%d", i+1);
|
||||||
|
|
||||||
|
/* Copy subtest */
|
||||||
|
snprintf(copy_command, 8 + PATH_MAX, "cp ../%s .", tests[i]);
|
||||||
|
system(copy_command);
|
||||||
|
|
||||||
forkres = fork();
|
forkres = fork();
|
||||||
if(forkres == 0) { /* Child */
|
if(forkres == 0) { /* Child */
|
||||||
execl(tests[i], tests[i], subtest, (char *) 0);
|
execl(tests[i], tests[i], subtest, (char *) 0);
|
||||||
@ -40,13 +47,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(errorct == 0) {
|
quit();
|
||||||
printf("ok\n");
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
printf("%d error(s)\n", errorct);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (-1); /* Impossible */
|
return (-1); /* Impossible */
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user