--- sio_test.c 2003/01/20 19:13:39 1.8
+++ sio_test.c 2003/01/30 13:44:20 1.9
@@ -33,11 +33,15 @@
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
#include "ts.h"
#include "al.h"
#include "sio.h"
@@ -69,13 +73,17 @@
block \
if (rc != rc0) \
ts_test_fail(TS_CTX, "%s -> %d[%s] (expected %d[%s])\n", \
- rc, sio_error(rc), rc0, sio_error(rc0))
+ name, rc, sio_error(rc), rc0, sio_error(rc0))
#define EVAL0(name,block) EVAL(name,rc,SIO_OK,block)
+sio_rc_t readloop(sio_t *, char *, size_t, size_t *);
+int test_sio_pipe_read(ts_test_t *, int, int);
+int test_sio_pipe_write(ts_test_t *, int, int);
+
sio_rc_t readloop(sio_t *sio, char *buf, size_t len, size_t *actualp)
{
- sio_rc_t rc;
+ sio_rc_t rc = SIO_OK;
size_t actual, total = 0;
while (len > 0) {
@@ -322,21 +330,530 @@
});
}
+int test_sio_pipe_read(ts_test_t *_t, int fd, int wcount)
+{
+ int error = 0, result = -1;
+ sio_rc_t rc;
+ sio_t *sio;
+ sio_stage_t *sios_buffer, *sios_fd;
+ size_t bufsize = 987; /* output buffer size */
+ size_t buflen = 64; /* fd input buffer size */
+ int i;
+ char S[] = "Hello world\n";
+ char buf[sizeof(S)];
+ size_t actual, len = strlen(S);
+
+ EVAL0("sio_create", {
+ rc = sio_create(&sio);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_create_stage(&sios_fd)", {
+ rc = sio_create_stage(sio, &sio_module_fd, &sios_fd);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_create_stage(&sios_buffer)", {
+ rc = sio_create_stage(sio, &sio_module_buffer, &sios_buffer);
+ });
+ if (rc != SIO_OK) return -1;
+
+ EVAL0("sio_configure_stage(sios_fd, buflen)", {
+ rc = sio_configure_stage(sio, sios_fd, "buflen", &buflen);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_configure_stage(sios_buffer)", {
+ rc = sio_configure_stage(sio, sios_buffer, "outputsize", &buflen);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_configure_stage(sios_buffer, inputsize)", {
+ rc = sio_configure_stage(sio, sios_buffer, "inputsize", &bufsize);
+ });
+ if (rc != SIO_OK) return -1;
+
+ EVAL0("sio_configure_stage(sios_fd, fd)", {
+ rc = sio_configure_stage(sio, sios_fd, "fd", &fd);
+ });
+ if (rc != SIO_OK) goto badread;
+
+ EVAL0("sio_attach(sios_fd)", {
+ rc = sio_attach(sio, sios_fd, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) goto badread;
+ EVAL0("sio_attach(sios_buffer)", {
+ rc = sio_attach(sio, sios_buffer, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) goto badread2;
+
+ for (i=0; i<wcount; ++i) {
+ EVAL0("sio_read", {
+ rc = readloop(sio, buf, len, &actual);
+ });
+ if (rc != SIO_OK) error = 1;
+ if (rc != SIO_OK) break;
+ if (actual != len) {
+ ts_test_fail(TS_CTX, "sio_read result %d (expected %d)\n",
+ (int)actual, (int)len);
+ break;
+ }
+ buf[actual] = '\0';
+ if (strcmp(buf, S)) {
+ ts_test_fail(TS_CTX, "sio_read data mismatch at loop %d\n",
+ i);
+ break;
+ }
+ }
+
+ EVAL0("sio_detach(sios_buffer)", {
+ rc = sio_detach(sio, sios_buffer);
+ });
+ if (rc != SIO_OK) error = 1;
+
+ result = error;
+
+ badread2:
+
+ EVAL0("sio_detach(sios_fd)", {
+ rc = sio_detach(sio, sios_fd);
+ });
+ if (rc != SIO_OK) result = -1;
+
+ badread:
+
+ EVAL0("sio_destroy_stage", {
+ rc = sio_destroy_stage(sio, sios_buffer);
+ });
+ if (rc != SIO_OK) result = -1;
+ EVAL0("sio_destroy_stage(sios_fd)", {
+ rc = sio_destroy_stage(sio, sios_fd);
+ });
+ if (rc != SIO_OK) result = -1;
+ EVAL0("sio_destroy", {
+ rc = sio_destroy(sio);
+ });
+ if (rc != SIO_OK) result = -1;
+
+ return result;
+}
+
+int test_sio_pipe_write(ts_test_t *_t, int fd, int wcount)
+{
+ int error = 0, result = -1;
+ sio_rc_t rc;
+ sio_t *sio;
+ sio_stage_t *sios_buffer, *sios_fd;
+ size_t bufsize = 1003; /* output buffer size */
+ size_t buflen = 47; /* fd input buffer size */
+ int i;
+ char S[] = "Hello world\n";
+ size_t actual, len = strlen(S);
+
+ EVAL0("sio_create", {
+ rc = sio_create(&sio);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_create_stage(&sios_fd)", {
+ rc = sio_create_stage(sio, &sio_module_fd, &sios_fd);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_create_stage(&sios_buffer)", {
+ rc = sio_create_stage(sio, &sio_module_buffer, &sios_buffer);
+ });
+ if (rc != SIO_OK) return -1;
+
+ EVAL0("sio_configure_stage(sios_fd, buflen)", {
+ rc = sio_configure_stage(sio, sios_fd, "buflen", &buflen);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_configure_stage(sios_buffer)", {
+ rc = sio_configure_stage(sio, sios_buffer, "outputsize", &buflen);
+ });
+ if (rc != SIO_OK) return -1;
+ EVAL0("sio_configure_stage(sios_buffer, inputsize)", {
+ rc = sio_configure_stage(sio, sios_buffer, "inputsize", &bufsize);
+ });
+ if (rc != SIO_OK) return -1;
+
+ /*
+ * WRITE phase
+ */
+
+ EVAL0("sio_configure_stage(sios_fd, fd)", {
+ rc = sio_configure_stage(sio, sios_fd, "fd", &fd);
+ });
+ if (rc != SIO_OK) goto badwrite;
+ EVAL0("sio_attach(sios_fd)", {
+ rc = sio_attach(sio, sios_fd, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) goto badwrite;
+ EVAL0("sio_attach(sios_buffer)", {
+ rc = sio_attach(sio, sios_buffer, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) goto badwrite2;
+
+ for (i=0; i<wcount; ++i) {
+ EVAL0("sio_write", {
+ rc = sio_write(sio, S, len, &actual);
+ });
+ if (rc != SIO_OK) error = 1;
+ if (rc != SIO_OK) break;
+ if (actual != len) {
+ ts_test_fail(TS_CTX, "sio_write result %d (expected %d)\n",
+ (int)actual, (int)len);
+ break;
+ }
+ }
+
+ EVAL0("sio_push", {
+ rc = sio_push(sio);
+ });
+ if (rc != SIO_OK) error = 1;
+
+ EVAL0("sio_detach(sios_buffer)", {
+ rc = sio_detach(sio, sios_buffer);
+ });
+ if (rc != SIO_OK) error = 1;
+
+ result = error;
+
+ badwrite2:
+ EVAL0("sio_detach(sios_fd)", {
+ rc = sio_detach(sio, sios_fd);
+ });
+ if (rc != SIO_OK) result = -1;
+
+ badwrite:
+
+ /*
+ * common cleanup
+ */
+
+ EVAL0("sio_destroy_stage", {
+ rc = sio_destroy_stage(sio, sios_buffer);
+ });
+ if (rc != SIO_OK) result = -1;
+ EVAL0("sio_destroy_stage(sios_fd)", {
+ rc = sio_destroy_stage(sio, sios_fd);
+ });
+ if (rc != SIO_OK) result = -1;
+ EVAL0("sio_destroy", {
+ rc = sio_destroy(sio);
+ });
+ if (rc != SIO_OK) result = -1;
+
+ return result;
+}
+
TS_TEST(test_sio_pipe)
{
+ pid_t child;
+ int pd[2];
+ int wcount = 147;
+ int status;
+
+ fflush(stdout);
+ fflush(stderr);
+
+ if (pipe(pd) == -1) {
+ ts_test_fail(TS_CTX, "cannot create pipe (%s)\n",
+ strerror(errno));
+ }
+
+ child = fork();
+ if (child == -1) {
+ ts_test_fail(TS_CTX, "cannot fork (%s)\n",
+ strerror(errno));
+ }
+
+ if (child == 0) {
+ int result;
+ close(pd[1]);
+ result = test_sio_pipe_write(NULL, pd[0], wcount);
+ close(pd[0]);
+ exit(result ? 1 : 0);
+ } else {
+ close(pd[0]);
+ test_sio_pipe_read(_t, pd[1], wcount);
+ close(pd[1]);
+ waitpid(child, &status, 0);
+ if (status != 0) {
+ ts_test_fail(TS_CTX, "child returned status %08lx\n",
+ status);
+ }
+ }
}
TS_TEST(test_sio_sio)
{
+ sio_rc_t rc;
+ sio_t *A_sio;
+ sio_stage_t *A_sios_sillymux;
+ sio_stage_t *A_sios_fd;
+ sio_t *B_sio;
+ sio_stage_t *B_sios_sio;
+ sio_t *C_sio;
+ sio_stage_t *C_sios_sio;
+ size_t buflen = 53;
+ int i,wcount = 100;
+ char SO[] = "Hello world\n";
+ size_t lenodd = strlen(SO);
+ char SE[] = "Goodbye cruel world\n";
+ size_t leneven = strlen(SE);
+ size_t actual;
+ al_label_t ODD = (al_label_t)1;
+ al_label_t EVEN = (al_label_t)2;
+ char tempfile[] = "./sio_test_tmpfile.XXXXXX";
+ int fd;
+ int neven, nodd;
+ int ceven, codd;
+
+ mktemp(tempfile);
+ fd = open(tempfile, O_CREAT|O_EXCL|O_RDWR, 0600);
+ if (fd < 0) {
+ ts_test_fail(TS_CTX, "cannot create temporary file \"%s\" (%s)\n",
+ tempfile, strerror(errno));
+ return;
+ }
+
+ for (i=0; i<wcount; ++i) {
+ if (write(fd, SO, lenodd) != lenodd ||
+ write(fd, SE, leneven) != leneven) {
+ ts_test_fail(TS_CTX, "cannot write temporary file \"%s\" (%s)\n",
+ tempfile, strerror(errno));
+ goto close_and_cleanup;
+ }
+ }
+
+ if (lseek(fd, (off_t)0, SEEK_SET) == -1) {
+ ts_test_fail(TS_CTX, "cannot rewind temporary file \"%s\" (%s)\n",
+ tempfile, strerror(errno));
+ goto close_and_cleanup;
+ }
+
+ /*
+ * create MUX stream
+ */
+ EVAL0("sio_create(&A_sio)", {
+ rc = sio_create(&A_sio);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_create_stage(&A_sios_fd)", {
+ rc = sio_create_stage(A_sio, &sio_module_fd, &A_sios_fd);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(A_sios_fd, fd)", {
+ rc = sio_configure_stage(A_sio, A_sios_fd, "fd", &fd);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(A_sios_fd, buflen)", {
+ rc = sio_configure_stage(A_sio, A_sios_fd, "buflen", &buflen);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_create_stage(&A_sios_sillymux)", {
+ rc = sio_create_stage(A_sio, &sio_module_sillymux, &A_sios_sillymux);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(A_sios_sillymux, oddlabel)", {
+ rc = sio_configure_stage(A_sio, A_sios_sillymux, "oddlabel", ODD);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(A_sios_sillymux, evenlabel)", {
+ rc = sio_configure_stage(A_sio, A_sios_sillymux, "evenlabel", EVEN);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_attach(A_sios_fd)", {
+ rc = sio_attach(A_sio, A_sios_fd, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_attach(A_sios_sillymux)", {
+ rc = sio_attach(A_sio, A_sios_sillymux, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) return;
+
+ /*
+ * create ODD stream
+ */
+ EVAL0("sio_create(&B_sio)", {
+ rc = sio_create(&B_sio);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_create_stage(&B_sios_sio)", {
+ rc = sio_create_stage(B_sio, &sio_module_sio, &B_sios_sio);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(B_sios_sio, upstream)", {
+ rc = sio_configure_stage(B_sio, B_sios_sio, "upstream", A_sio);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(B_sios_sio, mydatalabel)", {
+ rc = sio_configure_stage(B_sio, B_sios_sio, "mydatalabel", ODD);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_attach(B_sios_sio)", {
+ rc = sio_attach(B_sio, B_sios_sio, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) return;
+
+ /*
+ * create EVEN stream
+ */
+ EVAL0("sio_create(&C_sio)", {
+ rc = sio_create(&C_sio);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_create_stage(&C_sios_sio)", {
+ rc = sio_create_stage(C_sio, &sio_module_sio, &C_sios_sio);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(C_sios_sio, upstream)", {
+ rc = sio_configure_stage(C_sio, C_sios_sio, "upstream", A_sio);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_configure_stage(C_sios_sio, mydatalabel)", {
+ rc = sio_configure_stage(C_sio, C_sios_sio, "mydatalabel", EVEN);
+ });
+ if (rc != SIO_OK) return;
+ EVAL0("sio_attach(C_sios_sio)", {
+ rc = sio_attach(C_sio, C_sios_sio, SIO_MODE_READWRITE);
+ });
+ if (rc != SIO_OK) return;
+
+ /*
+ * read from both streams
+ */
+ nodd = neven = 0;
+ codd = ceven = 0;
+ while (nodd < wcount || neven < wcount) {
+ char buf[17], *p;
+ int nstreams = 2;
+
+ EVAL0("sio_read(B_sio)", {
+ rc = readloop(B_sio, buf, sizeof(buf), &actual);
+ if (rc == SIO_ERR_EOF) {
+ --nstreams;
+ rc = SIO_OK;
+ }
+ });
+ if (rc != SIO_OK)
+ break;
+ p = buf;
+ while (actual > 0) {
+ int n = lenodd - codd;
+ if (n > actual) n = actual;
+ if (memcmp(p, SO + codd, n) != 0) {
+ ts_test_fail(TS_CTX, "data mismatch on odd stream\n");
+ break;
+ }
+ actual -= n;
+ p += n;
+ codd += n;
+ if (codd >= lenodd) {
+ codd = 0;
+ ++nodd;
+ }
+ }
+ if (actual > 0)
+ break;
+
+ EVAL0("sio_read(C_sio)", {
+ rc = readloop(C_sio, buf, sizeof(buf), &actual);
+ if (rc == SIO_ERR_EOF) {
+ --nstreams;
+ rc = SIO_OK;
+ }
+ });
+ if (rc != SIO_OK)
+ break;
+ p = buf;
+ while (actual > 0) {
+ int n = leneven - ceven;
+ if (n > actual) n = actual;
+ if (memcmp(p, SE + ceven, n) != 0) {
+ ts_test_fail(TS_CTX, "data mismatch on even stream\n");
+ break;
+ }
+ actual -= n;
+ p += n;
+ ceven += n;
+ if (ceven >= leneven) {
+ ceven = 0;
+ ++neven;
+ }
+ }
+ if (actual > 0)
+ break;
+
+ if (nstreams == 0) {
+ if (neven != wcount ||
+ ceven != 0 ||
+ nodd != wcount ||
+ codd != 0) {
+ ts_test_fail(TS_CTX, "data missing from streams\n");
+ }
+ break;
+ }
+ }
+
+ /*
+ * destroy EVEN stream
+ */
+ EVAL0("sio_detach(C_sios_sio)", {
+ rc = sio_detach(C_sio, C_sios_sio);
+ });
+ EVAL0("sio_destroy_stage(C_sios_sio)", {
+ rc = sio_destroy_stage(C_sio, C_sios_sio);
+ });
+ EVAL0("sio_destroy(C_sio)", {
+ rc = sio_destroy(C_sio);
+ });
+
+ /*
+ * destroy ODD stream
+ */
+ EVAL0("sio_detach(B_sios_sio)", {
+ rc = sio_detach(B_sio, B_sios_sio);
+ });
+ EVAL0("sio_destroy_stage(B_sios_sio)", {
+ rc = sio_destroy_stage(B_sio, B_sios_sio);
+ });
+ EVAL0("sio_destroy(B_sio)", {
+ rc = sio_destroy(B_sio);
+ });
+
+ /*
+ * destroy MUX stream
+ */
+ EVAL0("sio_detach(A_sios_sillymux)", {
+ rc = sio_detach(A_sio, A_sios_sillymux);
+ });
+ EVAL0("sio_detach(A_sios_fd)", {
+ rc = sio_detach(A_sio, A_sios_fd);
+ });
+ EVAL0("sio_destroy_stage(A_sios_sillymux)", {
+ rc = sio_destroy_stage(A_sio, A_sios_sillymux);
+ });
+ EVAL0("sio_destroy_stage(A_sios_fd)", {
+ rc = sio_destroy_stage(A_sio, A_sios_fd);
+ });
+ EVAL0("sio_destroy(A_sio)", {
+ rc = sio_destroy(A_sio);
+ });
+
+close_and_cleanup:
+ close(fd);
+ if (unlink(tempfile) < 0) {
+ ts_test_fail(TS_CTX, "cannot unlink temporary file \"%s\" (%s)\n",
+ tempfile, strerror(errno));
+ }
}
TS_TEST(test_sio_hello)
{
}
+#if ENABLE_ZLIB
TS_TEST(test_sio_zlib)
{
}
+#endif
#if ENABLE_SA
TS_TEST(test_sio_sa)
|