summaryrefslogtreecommitdiff
path: root/test/testshm.c
diff options
context:
space:
mode:
authorrbb <rbb@13f79535-47bb-0310-9956-ffa450edef68>2004-03-13 21:41:04 +0000
committerrbb <rbb@13f79535-47bb-0310-9956-ffa450edef68>2004-03-13 21:41:04 +0000
commit9d4c3822349307e9574ba0682193f891752f3ae0 (patch)
tree477481cb124661b725e042f404c76e710643ba9b /test/testshm.c
parentd270493de58ffc9aabca2524990a953a3a327d89 (diff)
downloadlibapr-9d4c3822349307e9574ba0682193f891752f3ae0.tar.gz
Port testshm and all of it's component parts (testshmconsumer and
testshmproducer) so that they are a part of the unified test suite. They are also now all portable programs, which means that we are actually using APR as a part of the tests. Also, just generally improve the tests. Now, we not only check that msgavail flag is set, we also check that the actuall message is transferred correctly. Finally, we ensure that the receiver received the same number of messages that the sender sent. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64982 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testshm.c')
-rw-r--r--test/testshm.c349
1 files changed, 141 insertions, 208 deletions
diff --git a/test/testshm.c b/test/testshm.c
index 236f68c01..9d82dc2a6 100644
--- a/test/testshm.c
+++ b/test/testshm.c
@@ -13,281 +13,214 @@
* limitations under the License.
*/
+#include "test_apr.h"
#include "apr_shm.h"
#include "apr_errno.h"
#include "apr_general.h"
#include "apr_lib.h"
#include "apr_strings.h"
+#include "apr_thread_proc.h"
#include "apr_time.h"
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#if APR_HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include "testshm.h"
#if APR_HAS_SHARED_MEMORY
-typedef struct mbox {
- char msg[1024];
- int msgavail;
-} mbox;
-mbox *boxes;
-
-#define N_BOXES 10
-#define N_MESSAGES 100
-#define SHARED_SIZE (apr_size_t)(N_BOXES * sizeof(mbox))
-#define SHARED_FILENAME "/tmp/apr.testshm.shm"
-
-static void msgwait(int sleep_sec, int first_box, int last_box)
+static int msgwait(int sleep_sec, int first_box, int last_box)
{
int i;
+ int recvd = 0;
apr_time_t start = apr_time_now();
apr_interval_time_t sleep_duration = apr_time_from_sec(sleep_sec);
while (apr_time_now() - start < sleep_duration) {
for (i = first_box; i < last_box; i++) {
- if (boxes[i].msgavail) {
- fprintf(stdout, "received a message in box %d, message was: %s\n",
- i, boxes[i].msg);
+ if (boxes[i].msgavail && !strcmp(boxes[i].msg, MSG)) {
+ recvd++;
boxes[i].msgavail = 0; /* reset back to 0 */
+ /* reset the msg field. 1024 is a magic number and it should
+ * be a macro, but I am being lazy.
+ */
+ memset(boxes[i].msg, 0, 1024);
}
}
apr_sleep(apr_time_make(0, 10000)); /* 10ms */
}
- fprintf(stdout, "done waiting on mailboxes...\n");
+ return recvd;
}
static void msgput(int boxnum, char *msg)
{
- fprintf(stdout, "Sending message to box %d\n", boxnum);
- apr_cpystrn(boxes[boxnum].msg, msg, strlen(msg));
+ apr_cpystrn(boxes[boxnum].msg, msg, strlen(msg) + 1);
boxes[boxnum].msgavail = 1;
}
-static apr_status_t test_anon(apr_pool_t *parpool)
+static void test_anon_create(CuTest *tc)
{
apr_status_t rv;
- apr_pool_t *pool;
- apr_shm_t *shm;
- apr_size_t retsize;
- pid_t pid;
- int cnt, i, exit_int;
+ apr_shm_t *shm = NULL;
- rv = apr_pool_create(&pool, parpool);
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "Error creating child pool\n");
- return rv;
- }
+ rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
+ apr_assert_success(tc, "Error allocating shared memory block", rv);
+ CuAssertPtrNotNull(tc, shm);
- printf("Creating anonymous shared memory block (%"
- APR_SIZE_T_FMT " bytes)........", SHARED_SIZE);
- rv = apr_shm_create(&shm, SHARED_SIZE, NULL, pool);
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "Error allocating shared memory block\n");
- return rv;
- }
- fprintf(stdout, "OK\n");
+ rv = apr_shm_destroy(shm);
+ apr_assert_success(tc, "Error destroying shared memory block", rv);
+}
- printf("Checking size...%" APR_SIZE_T_FMT " bytes...",
- retsize = apr_shm_size_get(shm));
- if (retsize != SHARED_SIZE) {
- fprintf(stderr, "Error allocating shared memory block\n");
- return rv;
- }
- fprintf(stdout, "OK\n");
+static void test_check_size(CuTest *tc)
+{
+ apr_status_t rv;
+ apr_shm_t *shm = NULL;
+ apr_size_t retsize;
- printf("Allocating shared mbox memory for %d boxes ..............",
- N_BOXES);
- boxes = apr_shm_baseaddr_get(shm);
- if (boxes == NULL) {
- fprintf(stderr, "Error creating message boxes.\n");
- return rv;
- }
- fprintf(stdout, "OK\n");
+ rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
+ apr_assert_success(tc, "Error allocating shared memory block", rv);
+ CuAssertPtrNotNull(tc, shm);
- printf("Shared Process Test (child/parent)\n");
- pid = fork();
- if (pid == 0) { /* child */
- msgwait(5, 0, N_BOXES);
- exit(0);
- }
- else if (pid > 0) { /* parent */
- i = N_BOXES;
- cnt = N_MESSAGES;
- while (--cnt > 0) {
- if ((i-=3) < 0) {
- i += N_BOXES; /* start over at the top */
- }
- msgput(i, "Sending a message\n");
- apr_sleep(apr_time_make(0, 10000));
- }
- }
- else {
- printf("Error creating a child process\n");
- return errno;
- }
- /* wait for the child */
- printf("Waiting for child to exit.\n");
- if (waitpid(pid, &exit_int, 0) < 0) {
- return errno;
- }
+ retsize = apr_shm_size_get(shm);
+ CuAssertIntEquals(tc, SHARED_SIZE, retsize);
- printf("Destroying shared memory segment...");
rv = apr_shm_destroy(shm);
- if (rv != APR_SUCCESS) {
- printf("FAILED\n");
- return rv;
- }
- printf("OK\n");
+ apr_assert_success(tc, "Error destroying shared memory block", rv);
+}
- apr_pool_destroy(pool);
+static void test_shm_allocate(CuTest *tc)
+{
+ apr_status_t rv;
+ apr_shm_t *shm = NULL;
+ apr_size_t retsize;
+
+ rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
+ apr_assert_success(tc, "Error allocating shared memory block", rv);
+ CuAssertPtrNotNull(tc, shm);
+
+ boxes = apr_shm_baseaddr_get(shm);
+ CuAssertPtrNotNull(tc, boxes);
- return APR_SUCCESS;
+ rv = apr_shm_destroy(shm);
+ apr_assert_success(tc, "Error destroying shared memory block", rv);
}
-static apr_status_t test_named(apr_pool_t *parpool)
+static void test_anon(CuTest *tc)
{
+ apr_proc_t proc;
apr_status_t rv;
- apr_pool_t *pool;
apr_shm_t *shm;
apr_size_t retsize;
- pid_t pidproducer, pidconsumer;
- int exit_int;
+ pid_t pid;
+ int cnt, i, exit_int;
+ int recvd;
- rv = apr_pool_create(&pool, parpool);
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "Error creating child pool\n");
- return rv;
- }
+ rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
+ apr_assert_success(tc, "Error allocating shared memory block", rv);
+ CuAssertPtrNotNull(tc, shm);
- printf("Creating named shared memory block (%"
- APR_SIZE_T_FMT " bytes)........", SHARED_SIZE);
- rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, pool);
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "Error allocating shared memory block\n");
- return rv;
- }
- fprintf(stdout, "OK\n");
+ retsize = apr_shm_size_get(shm);
+ CuAssertIntEquals(tc, SHARED_SIZE, retsize);
- printf("Checking size...%" APR_SIZE_T_FMT " bytes...",
- retsize = apr_shm_size_get(shm));
- if (retsize != SHARED_SIZE) {
- fprintf(stderr, "Error allocating shared memory block\n");
- return rv;
- }
- fprintf(stdout, "OK\n");
-
- printf("Allocating shared mbox memory for %d boxes ..............",
- N_BOXES);
boxes = apr_shm_baseaddr_get(shm);
- if (boxes == NULL) {
- fprintf(stderr, "Error creating message boxes.\n");
- return rv;
- }
- fprintf(stdout, "OK\n");
-
- printf("fork()ing and exec()ing children:\n");
- pidproducer = fork();
- if (pidproducer == 0) { /* child */
- /* FIXME: exec a producer */
- printf("starting consumer.....\n");
- if (execlp("testshmconsumer", "testshmconsumer", (char*)0) < 0) {
- return errno;
- }
- return 0; /* not reached - avoid warnings */
+ CuAssertPtrNotNull(tc, boxes);
+
+ rv = apr_proc_fork(&proc, p);
+ if (rv == APR_INCHILD) { /* child */
+ int num = msgwait(5, 0, N_BOXES);
+ /* exit with the number of messages received so that the parent
+ * can check that all messages were received.
+ */
+ exit(num);
}
- else if (pidproducer > 0) { /* parent */
- /* fork another child */
- pidconsumer = fork();
- if (pidconsumer == 0) { /* child */
- /* FIXME: exec a producer */
- printf("starting producer.....\n");
- if (execlp("testshmproducer", "testshmproducer", (char*)0) < 0) {
- return errno;
+ else if (rv == APR_INPARENT) { /* parent */
+ i = N_BOXES;
+ cnt = 0;
+ while (cnt++ < N_MESSAGES) {
+ if ((i-=3) < 0) {
+ i += N_BOXES; /* start over at the top */
}
- }
- else if (pidconsumer < 0) { /* parent */
- printf("Error creating a child process\n");
- return errno;
+ msgput(i, MSG);
+ apr_sleep(apr_time_make(0, 10000));
}
}
else {
- printf("Error creating a child process\n");
- return errno;
+ CuFail(tc, "apr_proc_fork failed");
}
/* wait for the child */
- printf("Waiting for producer to exit.\n");
- if (waitpid(pidconsumer, &exit_int, 0) < 0) {
- return errno;
- }
- if (!WIFEXITED(exit_int)) {
- printf("Producer was unsuccessful.\n");
- return APR_EGENERAL;
- }
- printf("Waiting for consumer to exit.\n");
- if (waitpid(pidproducer, &exit_int, 0) < 0) {
- return errno;
- }
- if (!WIFEXITED(exit_int)) {
- printf("Consumer was unsuccessful.\n");
- return APR_EGENERAL;
- }
+ rv = apr_proc_wait(&proc, &recvd, NULL, APR_WAIT);
+ CuAssertIntEquals(tc, N_MESSAGES, recvd);
- printf("Destroying shared memory segment...");
rv = apr_shm_destroy(shm);
- if (rv != APR_SUCCESS) {
- printf("FAILED\n");
- return rv;
- }
- printf("OK\n");
-
- apr_pool_destroy(pool);
-
- return APR_SUCCESS;
+ apr_assert_success(tc, "Error destroying shared memory block", rv);
}
-int main(void)
+static void test_named(CuTest *tc)
{
apr_status_t rv;
- apr_pool_t *pool;
- char errmsg[200];
+ apr_shm_t *shm = NULL;
+ apr_size_t retsize;
+ apr_proc_t pidproducer, pidconsumer;
+ apr_procattr_t *attr1 = NULL, *attr2 = NULL;
+ int sent, received;
+ apr_exit_why_e why;
+ const char *args[4];
- apr_initialize();
+ rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
+ apr_assert_success(tc, "Error allocating shared memory block", rv);
+ CuAssertPtrNotNull(tc, shm);
+
+ retsize = apr_shm_size_get(shm);
+ CuAssertIntEquals(tc, SHARED_SIZE, retsize);
+
+ boxes = apr_shm_baseaddr_get(shm);
+ CuAssertPtrNotNull(tc, boxes);
+
+ rv = apr_procattr_create(&attr1, p);
+ CuAssertPtrNotNull(tc, attr1);
+ apr_assert_success(tc, "Couldn't create attr1", rv);
+ args[0] = apr_pstrdup(p, "testshmproducer");
+ args[1] = NULL;
+ rv = apr_proc_create(&pidproducer, "./testshmproducer", args, NULL,
+ attr1, p);
+ apr_assert_success(tc, "Couldn't launch producer", rv);
+
+ rv = apr_procattr_create(&attr2, p);
+ CuAssertPtrNotNull(tc, attr2);
+ apr_assert_success(tc, "Couldn't create attr2", rv);
+ args[0] = apr_pstrdup(p, "testshmconsumer");
+ rv = apr_proc_create(&pidconsumer, "./testshmconsumer", args, NULL,
+ attr2, p);
+ apr_assert_success(tc, "Couldn't launch consumer", rv);
+
+ rv = apr_proc_wait(&pidconsumer, &received, &why, APR_WAIT);
+ CuAssertIntEquals(tc, APR_CHILD_DONE, rv);
+ CuAssertIntEquals(tc, APR_PROC_EXIT, why);
+
+ rv = apr_proc_wait(&pidproducer, &sent, &why, APR_WAIT);
+ CuAssertIntEquals(tc, APR_CHILD_DONE, rv);
+ CuAssertIntEquals(tc, APR_PROC_EXIT, why);
+
+ /* Cleanup before testing that producer and consumer worked correctly.
+ * This way, if they didn't succeed, we can just run this test again
+ * without having to cleanup manually.
+ */
+ apr_assert_success(tc, "Error destroying shared memory",
+ apr_shm_destroy(shm));
- printf("APR Shared Memory Test\n");
- printf("======================\n\n");
+ CuAssertIntEquals(tc, sent, received);
- printf("Initializing the pool............................");
- if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
- printf("could not initialize pool\n");
- exit(-1);
- }
- printf("OK\n");
+}
+#endif
- rv = test_anon(pool);
- if (rv != APR_SUCCESS) {
- if (rv == APR_ENOTIMPL) {
- printf("Anonymous shared memory unavailable on this platform.\n");
- }
- else {
- printf("Anonymous shared memory test FAILED: [%d] %s\n",
- rv, apr_strerror(rv, errmsg, sizeof(errmsg)));
- exit(-2);
- }
- }
- printf("Anonymous shared memory test passed!\n");
+CuSuite *testshm(void)
+{
+ CuSuite *suite = CuSuiteNew("Shared Memory");
- if ((rv = test_named(pool)) != APR_SUCCESS) {
- printf("Name-based shared memory test FAILED: [%d] %s \n",
- rv, apr_strerror(rv, errmsg, sizeof(errmsg)));
- exit(-3);
- }
- printf("Named shared memory test passed!\n");
+#if APR_HAS_SHARED_MEMORY
+ SUITE_ADD_TEST(suite, test_anon_create);
+ SUITE_ADD_TEST(suite, test_check_size);
+ SUITE_ADD_TEST(suite, test_shm_allocate);
+ SUITE_ADD_TEST(suite, test_anon);
+ SUITE_ADD_TEST(suite, test_named);
+#endif
- return 0;
+ return suite;
}
-#else /* APR_HAS_SHARED_MEMORY */
-#error shmem is not supported on this platform
-#endif /* APR_HAS_SHARED_MEMORY */