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