Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <asm-generic/mman.h>
     18 #include <gtest/gtest.h>
     19 #include <atomic>
     20 #include <cstdlib>
     21 #include <sstream>
     22 #include <thread>
     23 #include <fmq/MessageQueue.h>
     24 #include <fmq/EventFlag.h>
     25 
     26 enum EventFlagBits : uint32_t {
     27     kFmqNotEmpty = 1 << 0,
     28     kFmqNotFull = 1 << 1,
     29 };
     30 
     31 typedef android::hardware::MessageQueue<uint8_t, android::hardware::kSynchronizedReadWrite>
     32           MessageQueueSync;
     33 typedef android::hardware::MessageQueue<uint8_t, android::hardware::kUnsynchronizedWrite>
     34             MessageQueueUnsync;
     35 
     36 class SynchronizedReadWrites : public ::testing::Test {
     37 protected:
     38     virtual void TearDown() {
     39         delete mQueue;
     40     }
     41 
     42     virtual void SetUp() {
     43         static constexpr size_t kNumElementsInQueue = 2048;
     44         mQueue = new (std::nothrow) MessageQueueSync(kNumElementsInQueue);
     45         ASSERT_NE(nullptr, mQueue);
     46         ASSERT_TRUE(mQueue->isValid());
     47         mNumMessagesMax = mQueue->getQuantumCount();
     48         ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
     49     }
     50 
     51     MessageQueueSync* mQueue = nullptr;
     52     size_t mNumMessagesMax = 0;
     53 };
     54 
     55 class UnsynchronizedWrite : public ::testing::Test {
     56 protected:
     57     virtual void TearDown() {
     58         delete mQueue;
     59     }
     60 
     61     virtual void SetUp() {
     62         static constexpr size_t kNumElementsInQueue = 2048;
     63         mQueue = new (std::nothrow) MessageQueueUnsync(kNumElementsInQueue);
     64         ASSERT_NE(nullptr, mQueue);
     65         ASSERT_TRUE(mQueue->isValid());
     66         mNumMessagesMax = mQueue->getQuantumCount();
     67         ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
     68     }
     69 
     70     MessageQueueUnsync* mQueue = nullptr;
     71     size_t mNumMessagesMax = 0;
     72 };
     73 
     74 class BlockingReadWrites : public ::testing::Test {
     75 protected:
     76     virtual void TearDown() {
     77         delete mQueue;
     78     }
     79     virtual void SetUp() {
     80         static constexpr size_t kNumElementsInQueue = 2048;
     81         mQueue = new (std::nothrow) MessageQueueSync(kNumElementsInQueue);
     82         ASSERT_NE(nullptr, mQueue);
     83         ASSERT_TRUE(mQueue->isValid());
     84         mNumMessagesMax = mQueue->getQuantumCount();
     85         ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
     86         /*
     87          * Initialize the EventFlag word to indicate Queue is not full.
     88          */
     89         std::atomic_init(&mFw, static_cast<uint32_t>(kFmqNotFull));
     90     }
     91 
     92     MessageQueueSync* mQueue;
     93     std::atomic<uint32_t> mFw;
     94     size_t mNumMessagesMax = 0;
     95 };
     96 
     97 class QueueSizeOdd : public ::testing::Test {
     98 protected:
     99   virtual void TearDown() {
    100       delete mQueue;
    101   }
    102   virtual void SetUp() {
    103       static constexpr size_t kNumElementsInQueue = 2049;
    104       mQueue = new (std::nothrow) MessageQueueSync(kNumElementsInQueue,
    105                                                    true /* configureEventFlagWord */);
    106       ASSERT_NE(nullptr, mQueue);
    107       ASSERT_TRUE(mQueue->isValid());
    108       mNumMessagesMax = mQueue->getQuantumCount();
    109       ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
    110       auto evFlagWordPtr = mQueue->getEventFlagWord();
    111       ASSERT_NE(nullptr, evFlagWordPtr);
    112       /*
    113        * Initialize the EventFlag word to indicate Queue is not full.
    114        */
    115       std::atomic_init(evFlagWordPtr, static_cast<uint32_t>(kFmqNotFull));
    116   }
    117 
    118   MessageQueueSync* mQueue;
    119   size_t mNumMessagesMax = 0;
    120 };
    121 
    122 class BadQueueConfig: public ::testing::Test {
    123 };
    124 
    125 /*
    126  * Utility function to initialize data to be written to the FMQ
    127  */
    128 inline void initData(uint8_t* data, size_t count) {
    129     for (size_t i = 0; i < count; i++) {
    130         data[i] = i & 0xFF;
    131     }
    132 }
    133 
    134 /*
    135  * This thread will attempt to read and block. When wait returns
    136  * it checks if the kFmqNotEmpty bit is actually set.
    137  * If the read is succesful, it signals Wake to kFmqNotFull.
    138  */
    139 void ReaderThreadBlocking(
    140         android::hardware::MessageQueue<uint8_t,
    141         android::hardware::kSynchronizedReadWrite>* fmq,
    142         std::atomic<uint32_t>* fwAddr) {
    143     const size_t dataLen = 64;
    144     uint8_t data[dataLen];
    145     android::hardware::EventFlag* efGroup = nullptr;
    146     android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
    147     ASSERT_EQ(android::NO_ERROR, status);
    148     ASSERT_NE(nullptr, efGroup);
    149 
    150     while (true) {
    151         uint32_t efState = 0;
    152         android::status_t ret = efGroup->wait(kFmqNotEmpty,
    153                                               &efState,
    154                                               5000000000 /* timeoutNanoSeconds */);
    155         /*
    156          * Wait should not time out here after 5s
    157          */
    158         ASSERT_NE(android::TIMED_OUT, ret);
    159 
    160         if ((efState & kFmqNotEmpty) && fmq->read(data, dataLen)) {
    161             efGroup->wake(kFmqNotFull);
    162             break;
    163         }
    164     }
    165 
    166     status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
    167     ASSERT_EQ(android::NO_ERROR, status);
    168 }
    169 
    170 /*
    171  * This thread will attempt to read and block using the readBlocking() API and
    172  * passes in a pointer to an EventFlag object.
    173  */
    174 void ReaderThreadBlocking2(
    175         android::hardware::MessageQueue<uint8_t,
    176         android::hardware::kSynchronizedReadWrite>* fmq,
    177         std::atomic<uint32_t>* fwAddr) {
    178     const size_t dataLen = 64;
    179     uint8_t data[dataLen];
    180     android::hardware::EventFlag* efGroup = nullptr;
    181     android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
    182     ASSERT_EQ(android::NO_ERROR, status);
    183     ASSERT_NE(nullptr, efGroup);
    184     bool ret = fmq->readBlocking(data,
    185                                  dataLen,
    186                                  static_cast<uint32_t>(kFmqNotFull),
    187                                  static_cast<uint32_t>(kFmqNotEmpty),
    188                                  5000000000 /* timeOutNanos */,
    189                                  efGroup);
    190     ASSERT_TRUE(ret);
    191     status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
    192     ASSERT_EQ(android::NO_ERROR, status);
    193 }
    194 
    195 
    196 TEST_F(BadQueueConfig, QueueSizeTooLarge) {
    197     typedef android::hardware::MessageQueue<uint16_t, android::hardware::kSynchronizedReadWrite>
    198             MessageQueueSync16;
    199     size_t numElementsInQueue = SIZE_MAX / sizeof(uint16_t) + 1;
    200     MessageQueueSync16 * fmq = new (std::nothrow) MessageQueueSync16(numElementsInQueue);
    201     ASSERT_NE(nullptr, fmq);
    202     /*
    203      * Should fail due to size being too large to fit into size_t.
    204      */
    205     ASSERT_FALSE(fmq->isValid());
    206 }
    207 
    208 /*
    209  * Test that basic blocking works. This test uses the non-blocking read()/write()
    210  * APIs.
    211  */
    212 TEST_F(BlockingReadWrites, SmallInputTest1) {
    213     const size_t dataLen = 64;
    214     uint8_t data[dataLen] = {0};
    215 
    216     android::hardware::EventFlag* efGroup = nullptr;
    217     android::status_t status = android::hardware::EventFlag::createEventFlag(&mFw, &efGroup);
    218 
    219     ASSERT_EQ(android::NO_ERROR, status);
    220     ASSERT_NE(nullptr, efGroup);
    221 
    222     /*
    223      * Start a thread that will try to read and block on kFmqNotEmpty.
    224      */
    225     std::thread Reader(ReaderThreadBlocking, mQueue, &mFw);
    226     struct timespec waitTime = {0, 100 * 1000000};
    227     ASSERT_EQ(0, nanosleep(&waitTime, NULL));
    228 
    229     /*
    230      * After waiting for some time write into the FMQ
    231      * and call Wake on kFmqNotEmpty.
    232      */
    233     ASSERT_TRUE(mQueue->write(data, dataLen));
    234     status = efGroup->wake(kFmqNotEmpty);
    235     ASSERT_EQ(android::NO_ERROR, status);
    236 
    237     ASSERT_EQ(0, nanosleep(&waitTime, NULL));
    238     Reader.join();
    239 
    240     status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
    241     ASSERT_EQ(android::NO_ERROR, status);
    242 }
    243 
    244 /*
    245  * Test that basic blocking works. This test uses the
    246  * writeBlocking()/readBlocking() APIs.
    247  */
    248 TEST_F(BlockingReadWrites, SmallInputTest2) {
    249     const size_t dataLen = 64;
    250     uint8_t data[dataLen] = {0};
    251 
    252     android::hardware::EventFlag* efGroup = nullptr;
    253     android::status_t status = android::hardware::EventFlag::createEventFlag(&mFw, &efGroup);
    254 
    255     ASSERT_EQ(android::NO_ERROR, status);
    256     ASSERT_NE(nullptr, efGroup);
    257 
    258     /*
    259      * Start a thread that will try to read and block on kFmqNotEmpty. It will
    260      * call wake() on kFmqNotFull when the read is successful.
    261      */
    262     std::thread Reader(ReaderThreadBlocking2, mQueue, &mFw);
    263     bool ret = mQueue->writeBlocking(data,
    264                                      dataLen,
    265                                      static_cast<uint32_t>(kFmqNotFull),
    266                                      static_cast<uint32_t>(kFmqNotEmpty),
    267                                      5000000000 /* timeOutNanos */,
    268                                      efGroup);
    269     ASSERT_TRUE(ret);
    270     Reader.join();
    271 
    272     status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
    273     ASSERT_EQ(android::NO_ERROR, status);
    274 }
    275 
    276 /*
    277  * Test that basic blocking times out as intended.
    278  */
    279 TEST_F(BlockingReadWrites, BlockingTimeOutTest) {
    280     android::hardware::EventFlag* efGroup = nullptr;
    281     android::status_t status = android::hardware::EventFlag::createEventFlag(&mFw, &efGroup);
    282 
    283     ASSERT_EQ(android::NO_ERROR, status);
    284     ASSERT_NE(nullptr, efGroup);
    285 
    286     /* Block on an EventFlag bit that no one will wake and time out in 1s */
    287     uint32_t efState = 0;
    288     android::status_t ret = efGroup->wait(kFmqNotEmpty,
    289                                           &efState,
    290                                           1000000000 /* timeoutNanoSeconds */);
    291     /*
    292      * Wait should time out in a second.
    293      */
    294     EXPECT_EQ(android::TIMED_OUT, ret);
    295 
    296     status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
    297     ASSERT_EQ(android::NO_ERROR, status);
    298 }
    299 
    300 /*
    301  * Test that odd queue sizes do not cause unaligned error
    302  * on access to EventFlag object.
    303  */
    304 TEST_F(QueueSizeOdd, EventFlagTest) {
    305     const size_t dataLen = 64;
    306     uint8_t data[dataLen] = {0};
    307 
    308     bool ret = mQueue->writeBlocking(data,
    309                                      dataLen,
    310                                      static_cast<uint32_t>(kFmqNotFull),
    311                                      static_cast<uint32_t>(kFmqNotEmpty),
    312                                      5000000000 /* timeOutNanos */);
    313     ASSERT_TRUE(ret);
    314 }
    315 
    316 /*
    317  * Verify that a few bytes of data can be successfully written and read.
    318  */
    319 TEST_F(SynchronizedReadWrites, SmallInputTest1) {
    320     const size_t dataLen = 16;
    321     ASSERT_LE(dataLen, mNumMessagesMax);
    322     uint8_t data[dataLen];
    323 
    324     initData(data, dataLen);
    325 
    326     ASSERT_TRUE(mQueue->write(data, dataLen));
    327     uint8_t readData[dataLen] = {};
    328     ASSERT_TRUE(mQueue->read(readData, dataLen));
    329     ASSERT_EQ(0, memcmp(data, readData, dataLen));
    330 }
    331 
    332 /*
    333  * Verify that a few bytes of data can be successfully written and read using
    334  * beginRead/beginWrite/CommitRead/CommitWrite
    335  */
    336 TEST_F(SynchronizedReadWrites, SmallInputTest2) {
    337     const size_t dataLen = 16;
    338     ASSERT_LE(dataLen, mNumMessagesMax);
    339     uint8_t data[dataLen];
    340 
    341     initData(data, dataLen);
    342 
    343     MessageQueueSync::MemTransaction tx;
    344     ASSERT_TRUE(mQueue->beginWrite(dataLen, &tx));
    345 
    346     ASSERT_TRUE(tx.copyTo(data, 0 /* startIdx */, dataLen));
    347 
    348     ASSERT_TRUE(mQueue->commitWrite(dataLen));
    349 
    350     uint8_t readData[dataLen] = {};
    351 
    352     ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
    353 
    354     ASSERT_TRUE(tx.copyFrom(readData, 0 /* startIdx */, dataLen));
    355 
    356     ASSERT_TRUE(mQueue->commitRead(dataLen));
    357 
    358     ASSERT_EQ(0, memcmp(data, readData, dataLen));
    359 }
    360 
    361 /*
    362  * Verify that a few bytes of data can be successfully written and read using
    363  * beginRead/beginWrite/CommitRead/CommitWrite as well as getSlot().
    364  */
    365 TEST_F(SynchronizedReadWrites, SmallInputTest3) {
    366     const size_t dataLen = 16;
    367     ASSERT_LE(dataLen, mNumMessagesMax);
    368     uint8_t data[dataLen];
    369 
    370     initData(data, dataLen);
    371     MessageQueueSync::MemTransaction tx;
    372     ASSERT_TRUE(mQueue->beginWrite(dataLen, &tx));
    373 
    374     auto first = tx.getFirstRegion();
    375     auto second = tx.getSecondRegion();
    376 
    377     ASSERT_EQ(first.getLength() + second.getLength(),  dataLen);
    378     for (size_t i = 0; i < dataLen; i++) {
    379         uint8_t* ptr = tx.getSlot(i);
    380         *ptr = data[i];
    381     }
    382 
    383     ASSERT_TRUE(mQueue->commitWrite(dataLen));
    384 
    385     uint8_t readData[dataLen] = {};
    386 
    387     ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
    388 
    389     first = tx.getFirstRegion();
    390     second = tx.getSecondRegion();
    391 
    392     ASSERT_EQ(first.getLength() + second.getLength(),  dataLen);
    393 
    394     for (size_t i = 0; i < dataLen; i++) {
    395         uint8_t* ptr = tx.getSlot(i);
    396         readData[i] = *ptr;
    397     }
    398 
    399     ASSERT_TRUE(mQueue->commitRead(dataLen));
    400 
    401     ASSERT_EQ(0, memcmp(data, readData, dataLen));
    402 }
    403 
    404 /*
    405  * Verify that read() returns false when trying to read from an empty queue.
    406  */
    407 TEST_F(SynchronizedReadWrites, ReadWhenEmpty1) {
    408     ASSERT_EQ(0UL, mQueue->availableToRead());
    409     const size_t dataLen = 2;
    410     ASSERT_LE(dataLen, mNumMessagesMax);
    411     uint8_t readData[dataLen];
    412     ASSERT_FALSE(mQueue->read(readData, dataLen));
    413 }
    414 
    415 /*
    416  * Verify that beginRead() returns a MemTransaction object with null pointers when trying
    417  * to read from an empty queue.
    418  */
    419 TEST_F(SynchronizedReadWrites, ReadWhenEmpty2) {
    420     ASSERT_EQ(0UL, mQueue->availableToRead());
    421     const size_t dataLen = 2;
    422     ASSERT_LE(dataLen, mNumMessagesMax);
    423 
    424     MessageQueueSync::MemTransaction tx;
    425     ASSERT_FALSE(mQueue->beginRead(dataLen, &tx));
    426 
    427     auto first = tx.getFirstRegion();
    428     auto second = tx.getSecondRegion();
    429 
    430     ASSERT_EQ(nullptr, first.getAddress());
    431     ASSERT_EQ(nullptr, second.getAddress());
    432 }
    433 
    434 /*
    435  * Write the queue until full. Verify that another write is unsuccessful.
    436  * Verify that availableToWrite() returns 0 as expected.
    437  */
    438 TEST_F(SynchronizedReadWrites, WriteWhenFull1) {
    439     ASSERT_EQ(0UL, mQueue->availableToRead());
    440     std::vector<uint8_t> data(mNumMessagesMax);
    441 
    442     initData(&data[0], mNumMessagesMax);
    443     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    444     ASSERT_EQ(0UL, mQueue->availableToWrite());
    445     ASSERT_FALSE(mQueue->write(&data[0], 1));
    446 
    447     std::vector<uint8_t> readData(mNumMessagesMax);
    448     ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
    449     ASSERT_EQ(data, readData);
    450 }
    451 
    452 /*
    453  * Write the queue until full. Verify that beginWrite() returns
    454  * a MemTransaction object with null base pointers.
    455  */
    456 TEST_F(SynchronizedReadWrites, WriteWhenFull2) {
    457     ASSERT_EQ(0UL, mQueue->availableToRead());
    458     std::vector<uint8_t> data(mNumMessagesMax);
    459 
    460     initData(&data[0], mNumMessagesMax);
    461     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    462     ASSERT_EQ(0UL, mQueue->availableToWrite());
    463 
    464     MessageQueueSync::MemTransaction tx;
    465     ASSERT_FALSE(mQueue->beginWrite(1, &tx));
    466 
    467     auto first = tx.getFirstRegion();
    468     auto second = tx.getSecondRegion();
    469 
    470     ASSERT_EQ(nullptr, first.getAddress());
    471     ASSERT_EQ(nullptr, second.getAddress());
    472 }
    473 
    474 /*
    475  * Write a chunk of data equal to the queue size.
    476  * Verify that the write is successful and the subsequent read
    477  * returns the expected data.
    478  */
    479 TEST_F(SynchronizedReadWrites, LargeInputTest1) {
    480     std::vector<uint8_t> data(mNumMessagesMax);
    481     initData(&data[0], mNumMessagesMax);
    482     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    483     std::vector<uint8_t> readData(mNumMessagesMax);
    484     ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
    485     ASSERT_EQ(data, readData);
    486 }
    487 
    488 /*
    489  * Attempt to write a chunk of data larger than the queue size.
    490  * Verify that it fails. Verify that a subsequent read fails and
    491  * the queue is still empty.
    492  */
    493 TEST_F(SynchronizedReadWrites, LargeInputTest2) {
    494     ASSERT_EQ(0UL, mQueue->availableToRead());
    495     const size_t dataLen = 4096;
    496     ASSERT_GT(dataLen, mNumMessagesMax);
    497     std::vector<uint8_t> data(dataLen);
    498 
    499     initData(&data[0], dataLen);
    500     ASSERT_FALSE(mQueue->write(&data[0], dataLen));
    501     std::vector<uint8_t> readData(mNumMessagesMax);
    502     ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
    503     ASSERT_NE(data, readData);
    504     ASSERT_EQ(0UL, mQueue->availableToRead());
    505 }
    506 
    507 /*
    508  * After the queue is full, try to write more data. Verify that
    509  * the attempt returns false. Verify that the attempt did not
    510  * affect the pre-existing data in the queue.
    511  */
    512 TEST_F(SynchronizedReadWrites, LargeInputTest3) {
    513     std::vector<uint8_t> data(mNumMessagesMax);
    514     initData(&data[0], mNumMessagesMax);
    515     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    516     ASSERT_FALSE(mQueue->write(&data[0], 1));
    517     std::vector<uint8_t> readData(mNumMessagesMax);
    518     ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
    519     ASSERT_EQ(data, readData);
    520 }
    521 
    522 /*
    523  * Verify that beginWrite() returns a MemTransaction with
    524  * null base pointers when attempting to write data larger
    525  * than the queue size.
    526  */
    527 TEST_F(SynchronizedReadWrites, LargeInputTest4) {
    528     ASSERT_EQ(0UL, mQueue->availableToRead());
    529     const size_t dataLen = 4096;
    530     ASSERT_GT(dataLen, mNumMessagesMax);
    531 
    532     MessageQueueSync::MemTransaction tx;
    533     ASSERT_FALSE(mQueue->beginWrite(dataLen, &tx));
    534 
    535     auto first = tx.getFirstRegion();
    536     auto second = tx.getSecondRegion();
    537 
    538     ASSERT_EQ(nullptr, first.getAddress());
    539     ASSERT_EQ(nullptr, second.getAddress());
    540 }
    541 
    542 /*
    543  * Verify that multiple reads one after the other return expected data.
    544  */
    545 TEST_F(SynchronizedReadWrites, MultipleRead) {
    546     const size_t chunkSize = 100;
    547     const size_t chunkNum = 5;
    548     const size_t dataLen = chunkSize * chunkNum;
    549     ASSERT_LE(dataLen, mNumMessagesMax);
    550     uint8_t data[dataLen];
    551 
    552     initData(data, dataLen);
    553     ASSERT_TRUE(mQueue->write(data, dataLen));
    554     uint8_t readData[dataLen] = {};
    555     for (size_t i = 0; i < chunkNum; i++) {
    556         ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
    557     }
    558     ASSERT_EQ(0, memcmp(readData, data, dataLen));
    559 }
    560 
    561 /*
    562  * Verify that multiple writes one after the other happens correctly.
    563  */
    564 TEST_F(SynchronizedReadWrites, MultipleWrite) {
    565     const int chunkSize = 100;
    566     const int chunkNum = 5;
    567     const size_t dataLen = chunkSize * chunkNum;
    568     ASSERT_LE(dataLen, mNumMessagesMax);
    569     uint8_t data[dataLen];
    570 
    571     initData(data, dataLen);
    572     for (unsigned int i = 0; i < chunkNum; i++) {
    573         ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
    574     }
    575     uint8_t readData[dataLen] = {};
    576     ASSERT_TRUE(mQueue->read(readData, dataLen));
    577     ASSERT_EQ(0, memcmp(readData, data, dataLen));
    578 }
    579 
    580 /*
    581  * Write enough messages into the FMQ to fill half of it
    582  * and read back the same.
    583  * Write mNumMessagesMax messages into the queue. This will cause a
    584  * wrap around. Read and verify the data.
    585  */
    586 TEST_F(SynchronizedReadWrites, ReadWriteWrapAround1) {
    587     size_t numMessages = mNumMessagesMax - 1;
    588     std::vector<uint8_t> data(mNumMessagesMax);
    589     std::vector<uint8_t> readData(mNumMessagesMax);
    590     initData(&data[0], mNumMessagesMax);
    591     ASSERT_TRUE(mQueue->write(&data[0], numMessages));
    592     ASSERT_TRUE(mQueue->read(&readData[0], numMessages));
    593     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    594     ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
    595     ASSERT_EQ(data, readData);
    596 }
    597 
    598 /*
    599  * Use beginRead/CommitRead/beginWrite/commitWrite APIs
    600  * to test wrap arounds are handled correctly.
    601  * Write enough messages into the FMQ to fill half of it
    602  * and read back the same.
    603  * Write mNumMessagesMax messages into the queue. This will cause a
    604  * wrap around. Read and verify the data.
    605  */
    606 TEST_F(SynchronizedReadWrites, ReadWriteWrapAround2) {
    607     size_t dataLen = mNumMessagesMax - 1;
    608     std::vector<uint8_t> data(mNumMessagesMax);
    609     std::vector<uint8_t> readData(mNumMessagesMax);
    610     initData(&data[0], mNumMessagesMax);
    611     ASSERT_TRUE(mQueue->write(&data[0], dataLen));
    612     ASSERT_TRUE(mQueue->read(&readData[0], dataLen));
    613 
    614     /*
    615      * The next write and read will have to deal with with wrap arounds.
    616      */
    617     MessageQueueSync::MemTransaction tx;
    618     ASSERT_TRUE(mQueue->beginWrite(mNumMessagesMax, &tx));
    619 
    620     auto first = tx.getFirstRegion();
    621     auto second = tx.getSecondRegion();
    622 
    623     ASSERT_EQ(first.getLength() + second.getLength(), mNumMessagesMax);
    624 
    625     ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */,  mNumMessagesMax));
    626 
    627     ASSERT_TRUE(mQueue->commitWrite(mNumMessagesMax));
    628 
    629     ASSERT_TRUE(mQueue->beginRead(mNumMessagesMax, &tx));
    630 
    631     first = tx.getFirstRegion();
    632     second = tx.getSecondRegion();
    633 
    634     ASSERT_EQ(first.getLength() + second.getLength(), mNumMessagesMax);
    635 
    636     ASSERT_TRUE(tx.copyFrom(&readData[0], 0 /* startIdx */, mNumMessagesMax));
    637     ASSERT_TRUE(mQueue->commitRead(mNumMessagesMax));
    638 
    639     ASSERT_EQ(data, readData);
    640 }
    641 
    642 /*
    643  * Verify that a few bytes of data can be successfully written and read.
    644  */
    645 TEST_F(UnsynchronizedWrite, SmallInputTest1) {
    646     const size_t dataLen = 16;
    647     ASSERT_LE(dataLen, mNumMessagesMax);
    648     uint8_t data[dataLen];
    649 
    650     initData(data, dataLen);
    651     ASSERT_TRUE(mQueue->write(data, dataLen));
    652     uint8_t readData[dataLen] = {};
    653     ASSERT_TRUE(mQueue->read(readData, dataLen));
    654     ASSERT_EQ(0, memcmp(data, readData, dataLen));
    655 }
    656 
    657 /*
    658  * Verify that read() returns false when trying to read from an empty queue.
    659  */
    660 TEST_F(UnsynchronizedWrite, ReadWhenEmpty) {
    661     ASSERT_EQ(0UL, mQueue->availableToRead());
    662     const size_t dataLen = 2;
    663     ASSERT_TRUE(dataLen < mNumMessagesMax);
    664     uint8_t readData[dataLen];
    665     ASSERT_FALSE(mQueue->read(readData, dataLen));
    666 }
    667 
    668 /*
    669  * Write the queue when full. Verify that a subsequent writes is succesful.
    670  * Verify that availableToWrite() returns 0 as expected.
    671  */
    672 TEST_F(UnsynchronizedWrite, WriteWhenFull1) {
    673     ASSERT_EQ(0UL, mQueue->availableToRead());
    674     std::vector<uint8_t> data(mNumMessagesMax);
    675 
    676     initData(&data[0], mNumMessagesMax);
    677     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    678     ASSERT_EQ(0UL, mQueue->availableToWrite());
    679     ASSERT_TRUE(mQueue->write(&data[0], 1));
    680 
    681     std::vector<uint8_t> readData(mNumMessagesMax);
    682     ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
    683 }
    684 
    685 /*
    686  * Write the queue when full. Verify that a subsequent writes
    687  * using beginRead()/commitRead() is succesful.
    688  * Verify that the next read fails as expected for unsynchronized flavor.
    689  */
    690 TEST_F(UnsynchronizedWrite, WriteWhenFull2) {
    691     ASSERT_EQ(0UL, mQueue->availableToRead());
    692     std::vector<uint8_t> data(mNumMessagesMax);
    693     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    694 
    695     MessageQueueUnsync::MemTransaction tx;
    696     ASSERT_TRUE(mQueue->beginWrite(1, &tx));
    697 
    698     ASSERT_EQ(tx.getFirstRegion().getLength(), 1U);
    699 
    700     ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */));
    701 
    702     ASSERT_TRUE(mQueue->commitWrite(1));
    703 
    704     std::vector<uint8_t> readData(mNumMessagesMax);
    705     ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
    706 }
    707 
    708 /*
    709  * Write a chunk of data equal to the queue size.
    710  * Verify that the write is successful and the subsequent read
    711  * returns the expected data.
    712  */
    713 TEST_F(UnsynchronizedWrite, LargeInputTest1) {
    714     std::vector<uint8_t> data(mNumMessagesMax);
    715     initData(&data[0], mNumMessagesMax);
    716     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    717     std::vector<uint8_t> readData(mNumMessagesMax);
    718     ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
    719     ASSERT_EQ(data, readData);
    720 }
    721 
    722 /*
    723  * Attempt to write a chunk of data larger than the queue size.
    724  * Verify that it fails. Verify that a subsequent read fails and
    725  * the queue is still empty.
    726  */
    727 TEST_F(UnsynchronizedWrite, LargeInputTest2) {
    728     ASSERT_EQ(0UL, mQueue->availableToRead());
    729     const size_t dataLen = 4096;
    730     ASSERT_GT(dataLen, mNumMessagesMax);
    731     std::vector<uint8_t> data(dataLen);
    732     initData(&data[0], dataLen);
    733     ASSERT_FALSE(mQueue->write(&data[0], dataLen));
    734     std::vector<uint8_t> readData(mNumMessagesMax);
    735     ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
    736     ASSERT_NE(data, readData);
    737     ASSERT_EQ(0UL, mQueue->availableToRead());
    738 }
    739 
    740 /*
    741  * After the queue is full, try to write more data. Verify that
    742  * the attempt is succesful. Verify that the read fails
    743  * as expected.
    744  */
    745 TEST_F(UnsynchronizedWrite, LargeInputTest3) {
    746     std::vector<uint8_t> data(mNumMessagesMax);
    747     initData(&data[0], mNumMessagesMax);
    748     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    749     ASSERT_TRUE(mQueue->write(&data[0], 1));
    750     std::vector<uint8_t> readData(mNumMessagesMax);
    751     ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
    752 }
    753 
    754 /*
    755  * Verify that multiple reads one after the other return expected data.
    756  */
    757 TEST_F(UnsynchronizedWrite, MultipleRead) {
    758     const size_t chunkSize = 100;
    759     const size_t chunkNum = 5;
    760     const size_t dataLen = chunkSize * chunkNum;
    761     ASSERT_LE(dataLen, mNumMessagesMax);
    762     uint8_t data[dataLen];
    763     initData(data, dataLen);
    764     ASSERT_TRUE(mQueue->write(data, dataLen));
    765     uint8_t readData[dataLen] = {};
    766     for (size_t i = 0; i < chunkNum; i++) {
    767         ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
    768     }
    769     ASSERT_EQ(0, memcmp(readData, data, dataLen));
    770 }
    771 
    772 /*
    773  * Verify that multiple writes one after the other happens correctly.
    774  */
    775 TEST_F(UnsynchronizedWrite, MultipleWrite) {
    776     const size_t chunkSize = 100;
    777     const size_t chunkNum = 5;
    778     const size_t dataLen = chunkSize * chunkNum;
    779     ASSERT_LE(dataLen, mNumMessagesMax);
    780     uint8_t data[dataLen];
    781 
    782     initData(data, dataLen);
    783     for (size_t i = 0; i < chunkNum; i++) {
    784         ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
    785     }
    786 
    787     uint8_t readData[dataLen] = {};
    788     ASSERT_TRUE(mQueue->read(readData, dataLen));
    789     ASSERT_EQ(0, memcmp(readData, data, dataLen));
    790 }
    791 
    792 /*
    793  * Write enough messages into the FMQ to fill half of it
    794  * and read back the same.
    795  * Write mNumMessagesMax messages into the queue. This will cause a
    796  * wrap around. Read and verify the data.
    797  */
    798 TEST_F(UnsynchronizedWrite, ReadWriteWrapAround) {
    799     size_t numMessages = mNumMessagesMax - 1;
    800     std::vector<uint8_t> data(mNumMessagesMax);
    801     std::vector<uint8_t> readData(mNumMessagesMax);
    802 
    803     initData(&data[0], mNumMessagesMax);
    804     ASSERT_TRUE(mQueue->write(&data[0], numMessages));
    805     ASSERT_TRUE(mQueue->read(&readData[0], numMessages));
    806     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
    807     ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
    808     ASSERT_EQ(data, readData);
    809 }
    810