src/vfer_test_accept_queue.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2005, 2006, Internet2
00003  * Legal conditions are in file LICENSE
00004  * (MD5 = c434f2e53b8089d8b4d0172c7ce07360).
00005  */
00006 /**
00007  * @file   vfer_test_accept_queue.c
00008  * @author Ivan Beschastnikh
00009  * @brief  Test: Accept Queue [accept_queue] tester.
00010  *
00011  * This test tests accept_queue.c and accept_queue.h. It creates
00012  * accept queues, enqueues and dequeues messages from the queue,
00013  * making sure that everything is consistent and exhibits correct
00014  * behaviour. This is done for server.c which is the only user of
00015  * the accept_queue.
00016  *
00017  * -     02/02/06        ivan            Updated to be more concise and use new testing suite
00018  * -     08/02/05        ivan            Upgraded to work with new accept_queue
00019  * -     07/30/05        ivan            Added to doxygen doc sys 
00020  */
00021 
00022 #include "vfer_tests.h"
00023 #include "vfer_accept_queue.h"
00024 
00025 accept_queue* ac;
00026 packet* request;
00027 int enqueuer_err;
00028 
00029 /**
00030  * Thread to dequeue items from the queue
00031  * @param ptr not used
00032  */
00033 
00034 void DeQueuerT(void* ptr) {
00035         queued_conn* qc;
00036         int num;                /* number of packets that queue holds at maximum */
00037         int count;              /* number of items dequeued so far */
00038         int num_failed;
00039 
00040         num_failed = 0;
00041         num = (int)ptr;
00042         count = 0;
00043         while (count != num && num_failed < 3) {
00044                 qc = Accept_Queue_Dequeue(ac);
00045                 if (qc == NULL) {
00046                         sleep(1); /* wait for enqueue to happen in EnQueuerT */
00047                         num_failed++;
00048                         continue;
00049                 }
00050                 TEST_CHECK((qc->fd == count), "DeQueuerT: testing data integrity (fd)");
00051                 count++;
00052         }
00053         TEST_CHECK((count == num), "DeQueuerT couldn't dequeues appropriate number of elements from queue");
00054         return;
00055 } /* DeQueuerT() */
00056 
00057 /**
00058  * Thread to enquue items into the queue
00059  * @param ptr not used
00060  */
00061 void EnQueuerT(void* ptr) {
00062         int i;
00063         int num;
00064         struct sockaddr sa;
00065         
00066         num = (int) ptr;
00067         enqueuer_err = 0;
00068         for (i = 0; i < num; i++) {
00069                 /* note: we are enqueuing an element with fd = i */
00070                 if (Accept_Queue_Enqueue (ac, i, sa, request) != 0) {
00071                         /* we can't use TEST_CHECK b/c it is not
00072                          * thread safe so we rely on a global var that
00073                          * is checked after both threads exit */
00074                         enqueuer_err = 1;
00075                 }
00076         }
00077 } /* EnQueuerT() */
00078 
00079 
00080 /**
00081  * Main process. Ignores arguments, runs small initial test and then
00082  * starts threads to enqueue and dequeue items from a queue.
00083  */
00084 int main(int argc, char** argv) {
00085         int i, j;
00086         queued_conn* qc;
00087         pthread_t tid1, tid2;
00088         struct sockaddr sa;
00089         int mem0, mem1;         /* for memory leak checking */
00090         
00091         TEST_INIT("TEST_AQ", "test_accept_queue.c", stdout, stdout);
00092 
00093         /* tests to make sure functions return errors on incorrect args */
00094         TEST_CHECK((Accept_Queue_Create(-10) == NULL), "aq create with negative backlog");
00095         TEST_CHECK((Accept_Queue_Create(0) == NULL), "aq create with zero backlog");
00096 
00097         /* test create\delete and test for memory leak in either call */
00098         for (i = 1; i < 102; i+=20) {
00099                 mem0 = (int)(ReqMem); /* save req mem to check for aq create and delete memory leaks */
00100                 TEST_CHECK(((ac = Accept_Queue_Create(i)) != NULL), "aq create with okay backlog");
00101                 Accept_Queue_Delete (ac);
00102                 mem1 = (int)(ReqMem);
00103                 TEST_CHECK((mem0 == mem1), "memory leak in creating\\deleting aq");
00104         }
00105 
00106         /* test create, enqueue up to backlog, dequeue, and delete and memory leak in any of these */
00107         for (i = 50; i <= 100; i+=50) {
00108 
00109                 mem0 = (int)(ReqMem);
00110                 TEST_CHECK(((ac = Accept_Queue_Create(i)) != NULL), "aq create with okay backlog");
00111                 
00112                 /* enqueue maximum number of entries */
00113                 for (j = 0; j < i; j++) {
00114                         ALLOC(request, packet*, packet, 1);
00115                         ALLOC(request->iov, struct iovec*, struct iovec, 1);
00116                         request->iovlen = 0;
00117                         TEST_CHECK((Accept_Queue_Enqueue (ac, i, sa, request) == 0) , "aq enqueue");
00118                 }
00119 
00120                 for (j = 0; j < i; j++) {
00121                         TEST_CHECK(((qc = Accept_Queue_Dequeue(ac)) != NULL), "aq dequeue");
00122                         RELEASE_PACK(qc->request);
00123                         RELEASE(qc, sizeof(queued_conn));
00124                 }
00125                 
00126                 Accept_Queue_Delete (ac);
00127                 mem1 = (int)(ReqMem);
00128                 TEST_CHECK((mem0 == mem1), "memory leak in creating\\deleting aq");
00129         }
00130 
00131         
00132         /* now we test how the queue works by being queued by one thread and dequeued by another */
00133 
00134         /* create the queue and allocate the packet for the threads to use */
00135         TEST_CHECK((Accept_Queue_Create(30) != NULL), "aq create with 30 items");
00136         ALLOC(request, packet*, packet, 1);
00137         ALLOC(request->iov, struct iovec*, struct iovec, 1);
00138         request->iovlen = 0;
00139         
00140         pthread_create(&tid1, NULL, (void (*)) DeQueuerT, (void*)(30));
00141         pthread_create(&tid2, NULL, (void (*)) EnQueuerT, (void*)(30));
00142         TEST_CHECK((enqueuer_err == 0), "enqueuing thread failed to enqueue at some point");
00143         
00144         /* collect the threads */
00145         pthread_join(tid1, NULL);
00146         pthread_join(tid2, NULL);
00147         TEST_SUMMARY();
00148         
00149         return 0;
00150 } /* main() */

Generated on Tue Aug 8 16:07:19 2006 for VFER by  doxygen 1.4.7