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