Home | History | Annotate | Download | only in tests
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <hardware/sensors.h>
      4 #include <pthread.h>
      5 #include <cutils/atomic.h>
      6 
      7 #include "SensorEventQueue.cpp"
      8 
      9 // Unit tests for the SensorEventQueue.
     10 
     11 // Run it like this:
     12 //
     13 // make sensorstests -j32 && \
     14 // out/host/linux-x86/obj/EXECUTABLES/sensorstests_intermediates/sensorstests
     15 
     16 bool checkWritableBufferSize(SensorEventQueue* queue, int requested, int expected) {
     17     sensors_event_t* buffer;
     18     int actual = queue->getWritableRegion(requested, &buffer);
     19     if (actual != expected) {
     20         printf("Expected buffer size was %d; actual was %d\n", expected, actual);
     21         return false;
     22     }
     23     return true;
     24 }
     25 
     26 bool checkSize(SensorEventQueue* queue, int expected) {
     27     int actual = queue->getSize();
     28     if (actual != expected) {
     29         printf("Expected queue size was %d; actual was %d\n", expected, actual);
     30         return false;
     31     }
     32     return true;
     33 }
     34 
     35 bool checkInt(char* msg, int expected, int actual) {
     36     if (actual != expected) {
     37         printf("%s; expected %d; actual was %d\n", msg, expected, actual);
     38         return false;
     39     }
     40     return true;
     41 }
     42 
     43 bool testSimpleWriteSizeCounts() {
     44     printf("testSimpleWriteSizeCounts\n");
     45     SensorEventQueue* queue = new SensorEventQueue(10);
     46     if (!checkSize(queue, 0)) return false;
     47     if (!checkWritableBufferSize(queue, 11, 10)) return false;
     48     if (!checkWritableBufferSize(queue, 10, 10)) return false;
     49     if (!checkWritableBufferSize(queue, 9, 9)) return false;
     50 
     51     queue->markAsWritten(7);
     52     if (!checkSize(queue, 7)) return false;
     53     if (!checkWritableBufferSize(queue, 4, 3)) return false;
     54     if (!checkWritableBufferSize(queue, 3, 3)) return false;
     55     if (!checkWritableBufferSize(queue, 2, 2)) return false;
     56 
     57     queue->markAsWritten(3);
     58     if (!checkSize(queue, 10)) return false;
     59     if (!checkWritableBufferSize(queue, 1, 0)) return false;
     60 
     61     printf("passed\n");
     62     return true;
     63 }
     64 
     65 bool testWrappingWriteSizeCounts() {
     66     printf("testWrappingWriteSizeCounts\n");
     67     SensorEventQueue* queue = new SensorEventQueue(10);
     68     queue->markAsWritten(9);
     69     if (!checkSize(queue, 9)) return false;
     70 
     71     // dequeue from the front
     72     queue->dequeue();
     73     queue->dequeue();
     74     if (!checkSize(queue, 7)) return false;
     75     if (!checkWritableBufferSize(queue, 100, 1)) return false;
     76 
     77     // Write all the way to the end.
     78     queue->markAsWritten(1);
     79     if (!checkSize(queue, 8)) return false;
     80     // Now the two free spots in the front are available.
     81     if (!checkWritableBufferSize(queue, 100, 2)) return false;
     82 
     83     // Fill the queue again
     84     queue->markAsWritten(2);
     85     if (!checkSize(queue, 10)) return false;
     86 
     87     printf("passed\n");
     88     return true;
     89 }
     90 
     91 
     92 
     93 struct TaskContext {
     94   bool success;
     95   SensorEventQueue* queue;
     96 };
     97 
     98 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
     99 static pthread_cond_t dataAvailableCond = PTHREAD_COND_INITIALIZER;
    100 
    101 int FULL_QUEUE_CAPACITY = 5;
    102 int FULL_QUEUE_EVENT_COUNT = 31;
    103 
    104 void *fullQueueWriterTask(void* ptr) {
    105     TaskContext* ctx = (TaskContext*)ptr;
    106     SensorEventQueue* queue = ctx->queue;
    107     ctx->success = true;
    108     int totalWaits = 0;
    109     int totalWrites = 0;
    110     sensors_event_t* buffer;
    111 
    112     while (totalWrites < FULL_QUEUE_EVENT_COUNT) {
    113         pthread_mutex_lock(&mutex);
    114         if (queue->waitForSpace(&mutex)) {
    115             totalWaits++;
    116             printf(".");
    117         }
    118         int writableSize = queue->getWritableRegion(FULL_QUEUE_CAPACITY, &buffer);
    119         queue->markAsWritten(writableSize);
    120         totalWrites += writableSize;
    121         for (int i = 0; i < writableSize; i++) {
    122             printf("w");
    123         }
    124         pthread_cond_broadcast(&dataAvailableCond);
    125         pthread_mutex_unlock(&mutex);
    126     }
    127     printf("\n");
    128 
    129     ctx->success =
    130             checkInt("totalWrites", FULL_QUEUE_EVENT_COUNT, totalWrites) &&
    131             checkInt("totalWaits", FULL_QUEUE_EVENT_COUNT - FULL_QUEUE_CAPACITY, totalWaits);
    132     return NULL;
    133 }
    134 
    135 bool fullQueueReaderShouldRead(int queueSize, int totalReads) {
    136     if (queueSize == 0) {
    137         return false;
    138     }
    139     int totalWrites = totalReads + queueSize;
    140     return queueSize == FULL_QUEUE_CAPACITY || totalWrites == FULL_QUEUE_EVENT_COUNT;
    141 }
    142 
    143 void* fullQueueReaderTask(void* ptr) {
    144     TaskContext* ctx = (TaskContext*)ptr;
    145     SensorEventQueue* queue = ctx->queue;
    146     int totalReads = 0;
    147     while (totalReads < FULL_QUEUE_EVENT_COUNT) {
    148         pthread_mutex_lock(&mutex);
    149         // Only read if there are events,
    150         // and either the queue is full, or if we're reading the last few events.
    151         while (!fullQueueReaderShouldRead(queue->getSize(), totalReads)) {
    152             pthread_cond_wait(&dataAvailableCond, &mutex);
    153         }
    154         queue->dequeue();
    155         totalReads++;
    156         printf("r");
    157         pthread_mutex_unlock(&mutex);
    158     }
    159     printf("\n");
    160     ctx->success = ctx->success && checkInt("totalreads", FULL_QUEUE_EVENT_COUNT, totalReads);
    161     return NULL;
    162 }
    163 
    164 // Test internal queue-full waiting and broadcasting.
    165 bool testFullQueueIo() {
    166     printf("testFullQueueIo\n");
    167     SensorEventQueue* queue = new SensorEventQueue(FULL_QUEUE_CAPACITY);
    168 
    169     TaskContext readerCtx;
    170     readerCtx.success = true;
    171     readerCtx.queue = queue;
    172 
    173     TaskContext writerCtx;
    174     writerCtx.success = true;
    175     writerCtx.queue = queue;
    176 
    177     pthread_t writer, reader;
    178     pthread_create(&reader, NULL, fullQueueReaderTask, &readerCtx);
    179     pthread_create(&writer, NULL, fullQueueWriterTask, &writerCtx);
    180 
    181     pthread_join(writer, NULL);
    182     pthread_join(reader, NULL);
    183 
    184     if (!readerCtx.success || !writerCtx.success) return false;
    185     printf("passed\n");
    186     return true;
    187 }
    188 
    189 
    190 int main(int argc, char **argv) {
    191     if (testSimpleWriteSizeCounts() &&
    192             testWrappingWriteSizeCounts() &&
    193             testFullQueueIo()) {
    194         printf("ALL PASSED\n");
    195     } else {
    196         printf("SOMETHING FAILED\n");
    197     }
    198     return EXIT_SUCCESS;
    199 }
    200