• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gtest/gtest.h>
18 #ifndef GTEST_IS_THREADSAFE
19 #error "GTest did not detect pthread library."
20 #endif
21 
22 #include <android/hardware/tests/msgq/1.0/ITestMsgQ.h>
23 #include <fmq/EventFlag.h>
24 #include <fmq/MessageQueue.h>
25 #include <hidl/ServiceManagement.h>
26 
27 // libutils:
28 using android::OK;
29 using android::sp;
30 using android::status_t;
31 
32 // generated
33 using android::hardware::tests::msgq::V1_0::ITestMsgQ;
34 
35 // libhidl
36 using android::hardware::kSynchronizedReadWrite;
37 using android::hardware::kUnsynchronizedWrite;
38 using android::hardware::MessageQueue;
39 using android::hardware::MQDescriptorSync;
40 using android::hardware::MQDescriptorUnsync;
41 using android::hardware::details::waitForHwService;
42 
43 typedef MessageQueue<uint16_t, kSynchronizedReadWrite> MessageQueueSync;
44 typedef MessageQueue<uint16_t, kUnsynchronizedWrite> MessageQueueUnsync;
45 
waitGetTestService()46 static sp<ITestMsgQ> waitGetTestService() {
47     // waitForHwService is required because ITestMsgQ is not in manifest.xml.
48     // "Real" HALs shouldn't be doing this.
49     waitForHwService(ITestMsgQ::descriptor, "default");
50     return ITestMsgQ::getService();
51 }
52 
53 class UnsynchronizedWriteClientMultiProcess : public ::testing::Test {
54    protected:
getQueue(MessageQueueUnsync ** fmq,sp<ITestMsgQ> * service,bool setupQueue)55     void getQueue(MessageQueueUnsync** fmq, sp<ITestMsgQ>* service, bool setupQueue) {
56         *service = waitGetTestService();
57         *fmq = nullptr;
58         if (*service == nullptr) return;
59         if (!(*service)->isRemote()) return;
60         (*service)->getFmqUnsyncWrite(setupQueue,
61                                       [fmq](bool ret, const MQDescriptorUnsync<uint16_t>& in) {
62                                           ASSERT_TRUE(ret);
63                                           *fmq = new (std::nothrow) MessageQueueUnsync(in);
64                                       });
65     }
66 };
67 
68 class SynchronizedReadWriteClient : public ::testing::Test {
69 protected:
TearDown()70     virtual void TearDown() {
71         delete mQueue;
72     }
73 
SetUp()74     virtual void SetUp() {
75         static constexpr size_t kNumElementsInQueue = 1024;
76         mService = waitGetTestService();
77         ASSERT_NE(mService, nullptr);
78         ASSERT_TRUE(mService->isRemote());
79         // create a queue on the client side
80         mQueue = new (std::nothrow)
81             MessageQueueSync(kNumElementsInQueue, true /* configure event flag word */);
82         ASSERT_NE(nullptr, mQueue);
83         ASSERT_TRUE(mQueue->isValid());
84         mNumMessagesMax = mQueue->getQuantumCount();
85 
86         // tell server to set up the queue on its end
87         ASSERT_TRUE(mService->configureFmqSyncReadWrite(*mQueue->getDesc()));
88     }
89 
90     sp<ITestMsgQ> mService;
91     MessageQueueSync* mQueue = nullptr;
92     size_t mNumMessagesMax = 0;
93 };
94 
95 class UnsynchronizedWriteClient : public ::testing::Test {
96 protected:
TearDown()97     virtual void TearDown() {
98         delete mQueue;
99     }
100 
SetUp()101     virtual void SetUp() {
102         mService = waitGetTestService();
103         ASSERT_NE(mService, nullptr);
104         ASSERT_TRUE(mService->isRemote());
105         mService->getFmqUnsyncWrite(true /* configureFmq */,
106                                     [this](bool ret, const MQDescriptorUnsync<uint16_t>& in) {
107                                         ASSERT_TRUE(ret);
108                                         mQueue = new (std::nothrow) MessageQueueUnsync(in);
109                                     });
110         ASSERT_NE(nullptr, mQueue);
111         ASSERT_TRUE(mQueue->isValid());
112         mNumMessagesMax = mQueue->getQuantumCount();
113     }
114 
115     sp<ITestMsgQ> mService;
116     MessageQueueUnsync*  mQueue = nullptr;
117     size_t mNumMessagesMax = 0;
118 };
119 
120 /*
121  * Utility function to verify data read from the fast message queue.
122  */
verifyData(uint16_t * data,size_t count)123 bool verifyData(uint16_t* data, size_t count) {
124     for (size_t i = 0; i < count; i++) {
125         if (data[i] != i) return false;
126     }
127     return true;
128 }
129 
130 /*
131  * Utility function to initialize data to be written to the FMQ
132  */
initData(uint16_t * data,size_t count)133 inline void initData(uint16_t* data, size_t count) {
134     for (size_t i = 0; i < count; i++) {
135         data[i] = i;
136     }
137 }
138 
139 /*
140  * Verify that for an unsynchronized flavor of FMQ, multiple readers
141  * can recover from a write overflow condition.
142  */
TEST_F(UnsynchronizedWriteClientMultiProcess,MultipleReadersAfterOverflow)143 TEST_F(UnsynchronizedWriteClientMultiProcess, MultipleReadersAfterOverflow) {
144     const size_t dataLen = 16;
145 
146     pid_t pid;
147     /* creating first reader process */
148     if ((pid = fork()) == 0) {
149         sp<ITestMsgQ> testService;
150         MessageQueueUnsync*  queue = nullptr;
151         getQueue(&queue, &testService, true /* setupQueue */);
152         ASSERT_NE(testService, nullptr);
153         ASSERT_TRUE(testService->isRemote());
154         ASSERT_NE(queue, nullptr);
155         ASSERT_TRUE(queue->isValid());
156 
157         size_t numMessagesMax = queue->getQuantumCount();
158 
159         // The following two writes will cause a write overflow.
160         auto ret = testService->requestWriteFmqUnsync(numMessagesMax);
161         ASSERT_TRUE(ret.isOk());
162         ASSERT_TRUE(ret);
163 
164         ret = testService->requestWriteFmqUnsync(1);
165         ASSERT_TRUE(ret.isOk());
166         ASSERT_TRUE(ret);
167 
168         // The following read should fail due to the overflow.
169         std::vector<uint16_t> readData(numMessagesMax);
170         ASSERT_FALSE(queue->read(&readData[0], numMessagesMax));
171 
172         /*
173          * Request another write to verify that the reader can recover from the
174          * overflow condition.
175          */
176         ASSERT_LT(dataLen, numMessagesMax);
177         ret = testService->requestWriteFmqUnsync(dataLen);
178         ASSERT_TRUE(ret.isOk());
179         ASSERT_TRUE(ret);
180 
181         // Verify that the read is successful.
182         ASSERT_TRUE(queue->read(&readData[0], dataLen));
183         ASSERT_TRUE(verifyData(&readData[0], dataLen));
184 
185         delete queue;
186         exit(0);
187     }
188 
189     ASSERT_GT(pid, 0 /* parent should see PID greater than 0 for a good fork */);
190 
191     int status;
192     // wait for the first reader process to exit.
193     ASSERT_EQ(pid, waitpid(pid, &status, 0 /* options */));
194 
195     // creating second reader process.
196     if ((pid = fork()) == 0) {
197         sp<ITestMsgQ> testService;
198         MessageQueueUnsync* queue = nullptr;
199 
200         getQueue(&queue, &testService, false /* setupQueue */);
201         ASSERT_NE(testService, nullptr);
202         ASSERT_TRUE(testService->isRemote());
203         ASSERT_NE(queue, nullptr);
204         ASSERT_TRUE(queue->isValid());
205 
206         // This read should fail due to the write overflow.
207         std::vector<uint16_t> readData(dataLen);
208         ASSERT_FALSE(queue->read(&readData[0], dataLen));
209 
210         /*
211          * Request another write to verify that the process that recover from
212          * the overflow condition.
213          */
214         auto ret = testService->requestWriteFmqUnsync(dataLen);
215         ASSERT_TRUE(ret.isOk());
216         ASSERT_TRUE(ret);
217 
218         // verify that the read is successful.
219         ASSERT_TRUE(queue->read(&readData[0], dataLen));
220         ASSERT_TRUE(verifyData(&readData[0], dataLen));
221 
222         delete queue;
223         exit(0);
224     }
225 
226     ASSERT_GT(pid, 0 /* parent should see PID greater than 0 for a good fork */);
227     ASSERT_EQ(pid, waitpid(pid, &status, 0 /* options */));
228 }
229 
230 /*
231  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
232  * using the EventFlag object owned by FMQ.
233  */
TEST_F(SynchronizedReadWriteClient,BlockingReadWrite1)234 TEST_F(SynchronizedReadWriteClient, BlockingReadWrite1) {
235     const size_t dataLen = 64;
236     uint16_t data[dataLen] = {0};
237 
238     /*
239      * Request service to perform a blocking read. This call is oneway and will
240      * return immediately.
241      */
242     mService->requestBlockingRead(dataLen);
243     bool ret = mQueue->writeBlocking(data,
244                                      dataLen,
245                                      static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
246                                      static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
247                                      5000000000 /* timeOutNanos */);
248     ASSERT_TRUE(ret);
249     ret = mQueue->writeBlocking(data, mNumMessagesMax,
250                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
251                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
252                                 5000000000 /* timeOutNanos */);
253     ASSERT_TRUE(ret);
254 }
255 
256 /*
257  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
258  * using the EventFlag object owned by FMQ and using the default EventFlag
259  * notification bit mask.
260  */
TEST_F(SynchronizedReadWriteClient,BlockingReadWrite2)261 TEST_F(SynchronizedReadWriteClient, BlockingReadWrite2) {
262     const size_t dataLen = 64;
263     std::vector<uint16_t> data(mNumMessagesMax);
264 
265     /*
266      * Request service to perform a blocking read using default EventFlag
267      * notification bit mask. This call is oneway and will
268      * return immediately.
269      */
270     mService->requestBlockingReadDefaultEventFlagBits(dataLen);
271 
272     /* Cause a context switch to allow service to block */
273     sched_yield();
274 
275     bool ret = mQueue->writeBlocking(&data[0],
276                                      dataLen);
277     ASSERT_TRUE(ret);
278 
279     /*
280      * If the blocking read was successful, another write of size
281      * mNumMessagesMax will succeed.
282      */
283     ret = mQueue->writeBlocking(&data[0], mNumMessagesMax, 5000000000 /* timeOutNanos */);
284     ASSERT_TRUE(ret);
285 }
286 
287 /*
288  * Test that repeated blocking reads and writes work using readBlocking()/writeBlocking() APIs
289  * using the EventFlag object owned by FMQ.
290  * Each write operation writes the same amount of data as a single read
291  * operation.
292  */
TEST_F(SynchronizedReadWriteClient,BlockingReadWriteRepeat1)293 TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat1) {
294     const size_t dataLen = 64;
295     uint16_t data[dataLen] = {0};
296     bool ret = false;
297 
298     /*
299      * Request service to perform a blocking read. This call is oneway and will
300      * return immediately.
301      */
302     const size_t writeCount = 1024;
303     mService->requestBlockingReadRepeat(dataLen, writeCount);
304 
305     for (size_t i = 0; i < writeCount; i++) {
306         ret = mQueue->writeBlocking(data, dataLen,
307                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
308                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
309                                     5000000000 /* timeOutNanos */);
310         ASSERT_TRUE(ret);
311     }
312 
313     ret = mQueue->writeBlocking(data, mNumMessagesMax,
314                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
315                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
316                                 5000000000 /* timeOutNanos */);
317 
318     ASSERT_TRUE(ret);
319 }
320 
321 /*
322  * Test that repeated blocking reads and writes work using readBlocking()/writeBlocking() APIs
323  * using the EventFlag object owned by FMQ. Each read operation reads twice the
324  * amount of data as a single write.
325  *
326  */
TEST_F(SynchronizedReadWriteClient,BlockingReadWriteRepeat2)327 TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat2) {
328     const size_t dataLen = 64;
329     uint16_t data[dataLen] = {0};
330     bool ret = false;
331 
332     /*
333      * Request service to perform a blocking read. This call is oneway and will
334      * return immediately.
335      */
336     const size_t writeCount = 1024;
337     mService->requestBlockingReadRepeat(dataLen*2, writeCount/2);
338 
339     for (size_t i = 0; i < writeCount; i++) {
340         ret = mQueue->writeBlocking(data, dataLen,
341                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
342                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
343                                     5000000000 /* timeOutNanos */);
344         ASSERT_TRUE(ret);
345     }
346 
347     ret = mQueue->writeBlocking(data, mNumMessagesMax,
348                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
349                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
350                                 5000000000 /* timeOutNanos */);
351     ASSERT_TRUE(ret);
352 }
353 
354 /*
355  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
356  * using the EventFlag object owned by FMQ. Each write operation writes twice
357  * the amount of data as a single read.
358  */
TEST_F(SynchronizedReadWriteClient,BlockingReadWriteRepeat3)359 TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat3) {
360     const size_t dataLen = 64;
361     uint16_t data[dataLen] = {0};
362     bool ret = false;
363 
364     /*
365      * Request service to perform a blocking read. This call is oneway and will
366      * return immediately.
367      */
368     size_t writeCount = 1024;
369     mService->requestBlockingReadRepeat(dataLen/2, writeCount*2);
370 
371     for (size_t i = 0; i < writeCount; i++) {
372         ret = mQueue->writeBlocking(data, dataLen,
373                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
374                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
375                                     5000000000 /* timeOutNanos */);
376         ASSERT_TRUE(ret);
377     }
378     ret = mQueue->writeBlocking(data, mNumMessagesMax,
379                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
380                                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
381                                 5000000000 /* timeOutNanos */);
382     ASSERT_TRUE(ret);
383 }
384 
385 /*
386  * Test that writeBlocking()/readBlocking() APIs do not block on
387  * attempts to write/read 0 messages and return true.
388  */
TEST_F(SynchronizedReadWriteClient,BlockingReadWriteZeroMessages)389 TEST_F(SynchronizedReadWriteClient, BlockingReadWriteZeroMessages) {
390     uint16_t data = 0;
391 
392     /*
393      * Trigger a blocking write for zero messages with no timeout.
394      */
395     bool ret = mQueue->writeBlocking(
396             &data,
397             0,
398             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
399             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
400     ASSERT_TRUE(ret);
401 
402     /*
403      * Trigger a blocking read for zero messages with no timeout.
404      */
405     ret = mQueue->readBlocking(&data,
406                                0,
407                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
408                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
409     ASSERT_TRUE(ret);
410 }
411 
412 /*
413  * Request mService to write a small number of messages
414  * to the FMQ. Read and verify data.
415  */
TEST_F(SynchronizedReadWriteClient,SmallInputReaderTest1)416 TEST_F(SynchronizedReadWriteClient, SmallInputReaderTest1) {
417     const size_t dataLen = 16;
418     ASSERT_LE(dataLen, mNumMessagesMax);
419     bool ret = mService->requestWriteFmqSync(dataLen);
420     ASSERT_TRUE(ret);
421     uint16_t readData[dataLen] = {};
422     ASSERT_TRUE(mQueue->read(readData, dataLen));
423     ASSERT_TRUE(verifyData(readData, dataLen));
424 }
425 
426 /*
427  * Request mService to write a small number of messages
428  * to the FMQ. Read and verify each message using
429  * beginRead/Commit read APIs.
430  */
TEST_F(SynchronizedReadWriteClient,SmallInputReaderTest2)431 TEST_F(SynchronizedReadWriteClient, SmallInputReaderTest2) {
432     const size_t dataLen = 16;
433     ASSERT_LE(dataLen, mNumMessagesMax);
434     auto ret = mService->requestWriteFmqSync(dataLen);
435 
436     ASSERT_TRUE(ret.isOk());
437     ASSERT_TRUE(ret);
438 
439     MessageQueueSync::MemTransaction tx;
440     ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
441 
442     auto first = tx.getFirstRegion();
443     auto second = tx.getSecondRegion();
444     size_t firstRegionLength = first.getLength();
445 
446     for (size_t i = 0; i < dataLen; i++) {
447         if (i < firstRegionLength) {
448             ASSERT_EQ(i, *(first.getAddress() + i));
449         } else {
450             ASSERT_EQ(i, *(second.getAddress() + i - firstRegionLength));
451         }
452     }
453 
454     ASSERT_TRUE(mQueue->commitRead(dataLen));
455 }
456 
457 /*
458  * Write a small number of messages to FMQ. Request
459  * mService to read and verify that the write was succesful.
460  */
TEST_F(SynchronizedReadWriteClient,SmallInputWriterTest1)461 TEST_F(SynchronizedReadWriteClient, SmallInputWriterTest1) {
462     const size_t dataLen = 16;
463     ASSERT_LE(dataLen, mNumMessagesMax);
464     size_t originalCount = mQueue->availableToWrite();
465     uint16_t data[dataLen];
466     initData(data, dataLen);
467     ASSERT_TRUE(mQueue->write(data, dataLen));
468     bool ret = mService->requestReadFmqSync(dataLen);
469     ASSERT_TRUE(ret);
470     size_t availableCount = mQueue->availableToWrite();
471     ASSERT_EQ(originalCount, availableCount);
472 }
473 
474 /*
475  * Write a small number of messages to FMQ using the beginWrite()/CommitWrite()
476  * APIs. Request mService to read and verify that the write was succesful.
477  */
TEST_F(SynchronizedReadWriteClient,SmallInputWriterTest2)478 TEST_F(SynchronizedReadWriteClient, SmallInputWriterTest2) {
479     const size_t dataLen = 16;
480     ASSERT_LE(dataLen, mNumMessagesMax);
481     size_t originalCount = mQueue->availableToWrite();
482     uint16_t data[dataLen];
483     initData(data, dataLen);
484 
485     MessageQueueSync::MemTransaction tx;
486     ASSERT_TRUE(mQueue->beginWrite(dataLen, &tx));
487 
488     auto first = tx.getFirstRegion();
489     auto second = tx.getSecondRegion();
490 
491     size_t firstRegionLength = first.getLength();
492     uint16_t* firstBaseAddress = first.getAddress();
493     uint16_t* secondBaseAddress = second.getAddress();
494 
495     for (size_t i = 0; i < dataLen; i++) {
496         if (i < firstRegionLength) {
497             *(firstBaseAddress + i) = i;
498         } else {
499             *(secondBaseAddress + i - firstRegionLength) = i;
500         }
501     }
502 
503     ASSERT_TRUE(mQueue->commitWrite(dataLen));
504 
505     auto ret = mService->requestReadFmqSync(dataLen);
506     ASSERT_TRUE(ret.isOk());
507     ASSERT_TRUE(ret);
508     size_t availableCount = mQueue->availableToWrite();
509     ASSERT_EQ(originalCount, availableCount);
510 }
511 
512 /*
513  * Verify that the FMQ is empty and read fails when it is empty.
514  */
TEST_F(SynchronizedReadWriteClient,ReadWhenEmpty)515 TEST_F(SynchronizedReadWriteClient, ReadWhenEmpty) {
516     ASSERT_EQ(0UL, mQueue->availableToRead());
517     const size_t numMessages = 2;
518     ASSERT_LE(numMessages, mNumMessagesMax);
519     uint16_t readData[numMessages];
520     ASSERT_FALSE(mQueue->read(readData, numMessages));
521 }
522 
523 /*
524  * Verify FMQ is empty.
525  * Write enough messages to fill it.
526  * Verify availableToWrite() method returns is zero.
527  * Try writing another message and verify that
528  * the attempted write was unsuccesful. Request mService
529  * to read and verify the messages in the FMQ.
530  */
531 
TEST_F(SynchronizedReadWriteClient,WriteWhenFull)532 TEST_F(SynchronizedReadWriteClient, WriteWhenFull) {
533     std::vector<uint16_t> data(mNumMessagesMax);
534     initData(&data[0], mNumMessagesMax);
535     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
536     ASSERT_EQ(0UL, mQueue->availableToWrite());
537     ASSERT_FALSE(mQueue->write(&data[0], 1));
538     bool ret = mService->requestReadFmqSync(mNumMessagesMax);
539     ASSERT_TRUE(ret);
540 }
541 
542 /*
543  * Verify FMQ is empty.
544  * Request mService to write data equal to queue size.
545  * Read and verify data in mQueue.
546  */
TEST_F(SynchronizedReadWriteClient,LargeInputTest1)547 TEST_F(SynchronizedReadWriteClient, LargeInputTest1) {
548     bool ret = mService->requestWriteFmqSync(mNumMessagesMax);
549     ASSERT_TRUE(ret);
550     std::vector<uint16_t> readData(mNumMessagesMax);
551     ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
552     ASSERT_TRUE(verifyData(&readData[0], mNumMessagesMax));
553 }
554 
555 /*
556  * Request mService to write more than maximum number of messages to the FMQ.
557  * Verify that the write fails. Verify that availableToRead() method
558  * still returns 0 and verify that attempt to read fails.
559  */
TEST_F(SynchronizedReadWriteClient,LargeInputTest2)560 TEST_F(SynchronizedReadWriteClient, LargeInputTest2) {
561     ASSERT_EQ(0UL, mQueue->availableToRead());
562     const size_t numMessages = 2048;
563     ASSERT_GT(numMessages, mNumMessagesMax);
564     bool ret = mService->requestWriteFmqSync(numMessages);
565     ASSERT_FALSE(ret);
566     uint16_t readData;
567     ASSERT_EQ(0UL, mQueue->availableToRead());
568     ASSERT_FALSE(mQueue->read(&readData, 1));
569 }
570 
571 /*
572  * Write until FMQ is full.
573  * Verify that the number of messages available to write
574  * is equal to mNumMessagesMax.
575  * Verify that another write attempt fails.
576  * Request mService to read. Verify read count.
577  */
578 
TEST_F(SynchronizedReadWriteClient,LargeInputTest3)579 TEST_F(SynchronizedReadWriteClient, LargeInputTest3) {
580     std::vector<uint16_t> data(mNumMessagesMax);
581     initData(&data[0], mNumMessagesMax);
582     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
583     ASSERT_EQ(0UL, mQueue->availableToWrite());
584     ASSERT_FALSE(mQueue->write(&data[0], 1));
585 
586     bool ret = mService->requestReadFmqSync(mNumMessagesMax);
587     ASSERT_TRUE(ret);
588 }
589 
590 /*
591  * Confirm that the FMQ is empty. Request mService to write to FMQ.
592  * Do multiple reads to empty FMQ and verify data.
593  */
TEST_F(SynchronizedReadWriteClient,MultipleRead)594 TEST_F(SynchronizedReadWriteClient, MultipleRead) {
595     const size_t chunkSize = 100;
596     const size_t chunkNum = 5;
597     const size_t numMessages = chunkSize * chunkNum;
598     ASSERT_LE(numMessages, mNumMessagesMax);
599     size_t availableToRead = mQueue->availableToRead();
600     size_t expectedCount = 0;
601     ASSERT_EQ(expectedCount, availableToRead);
602     bool ret = mService->requestWriteFmqSync(numMessages);
603     ASSERT_TRUE(ret);
604     uint16_t readData[numMessages] = {};
605     for (size_t i = 0; i < chunkNum; i++) {
606         ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
607     }
608     ASSERT_TRUE(verifyData(readData, numMessages));
609 }
610 
611 /*
612  * Write to FMQ in bursts.
613  * Request mService to read data. Verify the read was successful.
614  */
TEST_F(SynchronizedReadWriteClient,MultipleWrite)615 TEST_F(SynchronizedReadWriteClient, MultipleWrite) {
616     const size_t chunkSize = 100;
617     const size_t chunkNum = 5;
618     const size_t numMessages = chunkSize * chunkNum;
619     ASSERT_LE(numMessages, mNumMessagesMax);
620     uint16_t data[numMessages];
621     initData(&data[0], numMessages);
622 
623     for (size_t i = 0; i < chunkNum; i++) {
624         ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
625     }
626     bool ret = mService->requestReadFmqSync(numMessages);
627     ASSERT_TRUE(ret);
628 }
629 
630 /*
631  * Write enough messages into the FMQ to fill half of it.
632  * Request mService to read back the same.
633  * Write mNumMessagesMax messages into the queue. This should cause a
634  * wrap around. Request mService to read and verify the data.
635  */
TEST_F(SynchronizedReadWriteClient,ReadWriteWrapAround)636 TEST_F(SynchronizedReadWriteClient, ReadWriteWrapAround) {
637     size_t numMessages = mNumMessagesMax / 2;
638     std::vector<uint16_t> data(mNumMessagesMax);
639     initData(&data[0], mNumMessagesMax);
640     ASSERT_TRUE(mQueue->write(&data[0], numMessages));
641     bool ret = mService->requestReadFmqSync(numMessages);
642     ASSERT_TRUE(ret);
643     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
644     ret = mService->requestReadFmqSync(mNumMessagesMax);
645     ASSERT_TRUE(ret);
646 }
647 
648 /*
649  * Use beginWrite/commitWrite/getSlot APIs to test wrap arounds are handled
650  * correctly.
651  * Write enough messages into the FMQ to fill half of it
652  * and read back the same.
653  * Write mNumMessagesMax messages into the queue. This will cause a
654  * wrap around. Read and verify the data.
655  */
TEST_F(SynchronizedReadWriteClient,ReadWriteWrapAround2)656 TEST_F(SynchronizedReadWriteClient, ReadWriteWrapAround2) {
657     size_t numMessages = mNumMessagesMax / 2;
658     std::vector<uint16_t> data(mNumMessagesMax);
659     initData(&data[0], mNumMessagesMax);
660     ASSERT_TRUE(mQueue->write(&data[0], numMessages));
661     auto ret = mService->requestReadFmqSync(numMessages);
662 
663     ASSERT_TRUE(ret.isOk());
664     ASSERT_TRUE(ret);
665 
666     /*
667      * The next write and read will have to deal with with wrap arounds.
668      */
669     MessageQueueSync::MemTransaction tx;
670     ASSERT_TRUE(mQueue->beginWrite(mNumMessagesMax, &tx));
671 
672     ASSERT_EQ(tx.getFirstRegion().getLength() + tx.getSecondRegion().getLength(),  mNumMessagesMax);
673 
674     for (size_t i = 0; i < mNumMessagesMax; i++) {
675         uint16_t* ptr = tx.getSlot(i);
676         *ptr = data[i];
677     }
678 
679     ASSERT_TRUE(mQueue->commitWrite(mNumMessagesMax));
680 
681     ret = mService->requestReadFmqSync(mNumMessagesMax);
682 
683     ASSERT_TRUE(ret.isOk());
684     ASSERT_TRUE(ret);
685 }
686 
687 /*
688  * Request mService to write a small number of messages
689  * to the FMQ. Read and verify data.
690  */
TEST_F(UnsynchronizedWriteClient,SmallInputReaderTest1)691 TEST_F(UnsynchronizedWriteClient, SmallInputReaderTest1) {
692     const size_t dataLen = 16;
693     ASSERT_LE(dataLen, mNumMessagesMax);
694     bool ret = mService->requestWriteFmqUnsync(dataLen);
695     ASSERT_TRUE(ret);
696     uint16_t readData[dataLen] = {};
697     ASSERT_TRUE(mQueue->read(readData, dataLen));
698     ASSERT_TRUE(verifyData(readData, dataLen));
699 }
700 
701 /*
702  * Write a small number of messages to FMQ. Request
703  * mService to read and verify that the write was succesful.
704  */
TEST_F(UnsynchronizedWriteClient,SmallInputWriterTest1)705 TEST_F(UnsynchronizedWriteClient, SmallInputWriterTest1) {
706     const size_t dataLen = 16;
707     ASSERT_LE(dataLen, mNumMessagesMax);
708     uint16_t data[dataLen];
709     initData(data, dataLen);
710     ASSERT_TRUE(mQueue->write(data, dataLen));
711     bool ret = mService->requestReadFmqUnsync(dataLen);
712     ASSERT_TRUE(ret);
713 }
714 
715 /*
716  * Verify that the FMQ is empty and read fails when it is empty.
717  */
TEST_F(UnsynchronizedWriteClient,ReadWhenEmpty)718 TEST_F(UnsynchronizedWriteClient, ReadWhenEmpty) {
719     ASSERT_EQ(0UL, mQueue->availableToRead());
720     const size_t numMessages = 2;
721     ASSERT_LE(numMessages, mNumMessagesMax);
722     uint16_t readData[numMessages];
723     ASSERT_FALSE(mQueue->read(readData, numMessages));
724 }
725 
726 /*
727  * Verify FMQ is empty.
728  * Write enough messages to fill it.
729  * Verify availableToWrite() method returns is zero.
730  * Try writing another message and verify that
731  * the attempted write was successful. Request mService
732  * to read the messages in the FMQ and verify that it is unsuccesful.
733  */
734 
TEST_F(UnsynchronizedWriteClient,WriteWhenFull)735 TEST_F(UnsynchronizedWriteClient, WriteWhenFull) {
736     std::vector<uint16_t> data(mNumMessagesMax);
737     initData(&data[0], mNumMessagesMax);
738     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
739     ASSERT_EQ(0UL, mQueue->availableToWrite());
740     ASSERT_TRUE(mQueue->write(&data[0], 1));
741     bool ret = mService->requestReadFmqUnsync(mNumMessagesMax);
742     ASSERT_FALSE(ret);
743 }
744 
745 /*
746  * Verify FMQ is empty.
747  * Request mService to write data equal to queue size.
748  * Read and verify data in mQueue.
749  */
TEST_F(UnsynchronizedWriteClient,LargeInputTest1)750 TEST_F(UnsynchronizedWriteClient, LargeInputTest1) {
751     bool ret = mService->requestWriteFmqUnsync(mNumMessagesMax);
752     ASSERT_TRUE(ret);
753     std::vector<uint16_t> data(mNumMessagesMax);
754     ASSERT_TRUE(mQueue->read(&data[0], mNumMessagesMax));
755     ASSERT_TRUE(verifyData(&data[0], mNumMessagesMax));
756 }
757 
758 /*
759  * Request mService to write more than maximum number of messages to the FMQ.
760  * Verify that the write fails. Verify that availableToRead() method
761  * still returns 0 and verify that attempt to read fails.
762  */
TEST_F(UnsynchronizedWriteClient,LargeInputTest2)763 TEST_F(UnsynchronizedWriteClient, LargeInputTest2) {
764     ASSERT_EQ(0UL, mQueue->availableToRead());
765     const size_t numMessages = mNumMessagesMax + 1;
766     bool ret = mService->requestWriteFmqUnsync(numMessages);
767     ASSERT_FALSE(ret);
768     uint16_t readData;
769     ASSERT_EQ(0UL, mQueue->availableToRead());
770     ASSERT_FALSE(mQueue->read(&readData, 1));
771 }
772 
773 /*
774  * Write until FMQ is full.
775  * Verify that the number of messages available to write
776  * is equal to mNumMessagesMax.
777  * Verify that another write attempt is succesful.
778  * Request mService to read. Verify that read is unsuccessful.
779  * Perform another write and verify that the read is succesful
780  * to check if the reader process can recover from the error condition.
781  */
TEST_F(UnsynchronizedWriteClient,LargeInputTest3)782 TEST_F(UnsynchronizedWriteClient, LargeInputTest3) {
783     std::vector<uint16_t> data(mNumMessagesMax);
784     initData(&data[0], mNumMessagesMax);
785     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
786     ASSERT_EQ(0UL, mQueue->availableToWrite());
787     ASSERT_TRUE(mQueue->write(&data[0], 1));
788 
789     bool ret = mService->requestReadFmqUnsync(mNumMessagesMax);
790     ASSERT_FALSE(ret);
791     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
792 
793     ret = mService->requestReadFmqUnsync(mNumMessagesMax);
794     ASSERT_TRUE(ret);
795 }
796 
797 /*
798  * Confirm that the FMQ is empty. Request mService to write to FMQ.
799  * Do multiple reads to empty FMQ and verify data.
800  */
TEST_F(UnsynchronizedWriteClient,MultipleRead)801 TEST_F(UnsynchronizedWriteClient, MultipleRead) {
802     const size_t chunkSize = 100;
803     const size_t chunkNum = 5;
804     const size_t numMessages = chunkSize * chunkNum;
805     ASSERT_LE(numMessages, mNumMessagesMax);
806     size_t availableToRead = mQueue->availableToRead();
807     size_t expectedCount = 0;
808     ASSERT_EQ(expectedCount, availableToRead);
809     bool ret = mService->requestWriteFmqUnsync(numMessages);
810     ASSERT_TRUE(ret);
811     uint16_t readData[numMessages] = {};
812     for (size_t i = 0; i < chunkNum; i++) {
813         ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
814     }
815     ASSERT_TRUE(verifyData(readData, numMessages));
816 }
817 
818 /*
819  * Write to FMQ in bursts.
820  * Request mService to read data, verify that it was successful.
821  */
TEST_F(UnsynchronizedWriteClient,MultipleWrite)822 TEST_F(UnsynchronizedWriteClient, MultipleWrite) {
823     const size_t chunkSize = 100;
824     const size_t chunkNum = 5;
825     const size_t numMessages = chunkSize * chunkNum;
826     ASSERT_LE(numMessages, mNumMessagesMax);
827     uint16_t data[numMessages];
828     initData(data, numMessages);
829     for (size_t i = 0; i < chunkNum; i++) {
830         ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
831     }
832     bool ret = mService->requestReadFmqUnsync(numMessages);
833     ASSERT_TRUE(ret);
834 }
835 
836 /*
837  * Write enough messages into the FMQ to fill half of it.
838  * Request mService to read back the same.
839  * Write mNumMessagesMax messages into the queue. This should cause a
840  * wrap around. Request mService to read and verify the data.
841  */
TEST_F(UnsynchronizedWriteClient,ReadWriteWrapAround)842 TEST_F(UnsynchronizedWriteClient, ReadWriteWrapAround) {
843     size_t numMessages = mNumMessagesMax / 2;
844     std::vector<uint16_t> data(mNumMessagesMax);
845     initData(&data[0], mNumMessagesMax);
846     ASSERT_TRUE(mQueue->write(&data[0], numMessages));
847     bool ret = mService->requestReadFmqUnsync(numMessages);
848     ASSERT_TRUE(ret);
849     ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
850     ret = mService->requestReadFmqUnsync(mNumMessagesMax);
851     ASSERT_TRUE(ret);
852 }
853 
854 /*
855  * Request mService to write a small number of messages
856  * to the FMQ. Read and verify data from two threads configured
857  * as readers to the FMQ.
858  */
TEST_F(UnsynchronizedWriteClient,SmallInputMultipleReaderTest)859 TEST_F(UnsynchronizedWriteClient, SmallInputMultipleReaderTest) {
860     auto desc = mQueue->getDesc();
861     std::unique_ptr<MessageQueue<uint16_t, kUnsynchronizedWrite>> mQueue2(
862             new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite>(*desc));
863     ASSERT_NE(nullptr, mQueue2.get());
864 
865     const size_t dataLen = 16;
866     ASSERT_LE(dataLen, mNumMessagesMax);
867 
868     bool ret = mService->requestWriteFmqUnsync(dataLen);
869     ASSERT_TRUE(ret);
870 
871     pid_t pid;
872     if ((pid = fork()) == 0) {
873         /* child process */
874         uint16_t readData[dataLen] = {};
875         ASSERT_TRUE(mQueue2->read(readData, dataLen));
876         ASSERT_TRUE(verifyData(readData, dataLen));
877         exit(0);
878     } else {
879         ASSERT_GT(pid,
880                   0 /* parent should see PID greater than 0 for a good fork */);
881         uint16_t readData[dataLen] = {};
882         ASSERT_TRUE(mQueue->read(readData, dataLen));
883         ASSERT_TRUE(verifyData(readData, dataLen));
884     }
885 }
886 
887 /*
888  * Request mService to write into the FMQ until it is full.
889  * Request mService to do another write and verify it is successful.
890  * Use two reader processes to read and verify that both fail.
891  */
TEST_F(UnsynchronizedWriteClient,OverflowNotificationTest)892 TEST_F(UnsynchronizedWriteClient, OverflowNotificationTest) {
893     auto desc = mQueue->getDesc();
894     std::unique_ptr<MessageQueue<uint16_t, kUnsynchronizedWrite>> mQueue2(
895             new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite>(*desc));
896     ASSERT_NE(nullptr, mQueue2.get());
897 
898     bool ret = mService->requestWriteFmqUnsync(mNumMessagesMax);
899     ASSERT_TRUE(ret);
900     ret = mService->requestWriteFmqUnsync(1);
901     ASSERT_TRUE(ret);
902 
903     pid_t pid;
904     if ((pid = fork()) == 0) {
905         /* child process */
906         std::vector<uint16_t> readData(mNumMessagesMax);
907         ASSERT_FALSE(mQueue2->read(&readData[0], mNumMessagesMax));
908         exit(0);
909     } else {
910         ASSERT_GT(pid, 0/* parent should see PID greater than 0 for a good fork */);
911         std::vector<uint16_t> readData(mNumMessagesMax);
912         ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
913     }
914 }
915