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