1*be431cd8SAndroid Build Coastguard Worker /*
2*be431cd8SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*be431cd8SAndroid Build Coastguard Worker *
4*be431cd8SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*be431cd8SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*be431cd8SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*be431cd8SAndroid Build Coastguard Worker *
8*be431cd8SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*be431cd8SAndroid Build Coastguard Worker *
10*be431cd8SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*be431cd8SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*be431cd8SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*be431cd8SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*be431cd8SAndroid Build Coastguard Worker * limitations under the License.
15*be431cd8SAndroid Build Coastguard Worker */
16*be431cd8SAndroid Build Coastguard Worker
17*be431cd8SAndroid Build Coastguard Worker #include <android-base/logging.h>
18*be431cd8SAndroid Build Coastguard Worker #include <asm-generic/mman.h>
19*be431cd8SAndroid Build Coastguard Worker #include <fmq/AidlMessageQueue.h>
20*be431cd8SAndroid Build Coastguard Worker #include <fmq/AidlMessageQueueCpp.h>
21*be431cd8SAndroid Build Coastguard Worker #include <fmq/ConvertMQDescriptors.h>
22*be431cd8SAndroid Build Coastguard Worker #include <fmq/EventFlag.h>
23*be431cd8SAndroid Build Coastguard Worker #include <fmq/MessageQueue.h>
24*be431cd8SAndroid Build Coastguard Worker #include <gtest/gtest-death-test.h>
25*be431cd8SAndroid Build Coastguard Worker #include <gtest/gtest.h>
26*be431cd8SAndroid Build Coastguard Worker #include <sys/resource.h>
27*be431cd8SAndroid Build Coastguard Worker #include <atomic>
28*be431cd8SAndroid Build Coastguard Worker #include <cstdlib>
29*be431cd8SAndroid Build Coastguard Worker #include <filesystem>
30*be431cd8SAndroid Build Coastguard Worker #include <sstream>
31*be431cd8SAndroid Build Coastguard Worker #include <thread>
32*be431cd8SAndroid Build Coastguard Worker
33*be431cd8SAndroid Build Coastguard Worker using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
34*be431cd8SAndroid Build Coastguard Worker using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
35*be431cd8SAndroid Build Coastguard Worker using cppSynchronizedReadWrite = android::hardware::common::fmq::SynchronizedReadWrite;
36*be431cd8SAndroid Build Coastguard Worker using cppUnSynchronizedWrite = android::hardware::common::fmq::UnsynchronizedWrite;
37*be431cd8SAndroid Build Coastguard Worker
38*be431cd8SAndroid Build Coastguard Worker using android::hardware::kSynchronizedReadWrite;
39*be431cd8SAndroid Build Coastguard Worker using android::hardware::kUnsynchronizedWrite;
40*be431cd8SAndroid Build Coastguard Worker
41*be431cd8SAndroid Build Coastguard Worker enum EventFlagBits : uint32_t {
42*be431cd8SAndroid Build Coastguard Worker kFmqNotFull = 1 << 0,
43*be431cd8SAndroid Build Coastguard Worker kFmqNotEmpty = 1 << 1,
44*be431cd8SAndroid Build Coastguard Worker };
45*be431cd8SAndroid Build Coastguard Worker
46*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<uint8_t, SynchronizedReadWrite> AidlMessageQueueSync;
47*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<uint8_t, UnsynchronizedWrite> AidlMessageQueueUnsync;
48*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<uint8_t, cppSynchronizedReadWrite> cppAidlMessageQueueSync;
49*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<uint8_t, cppUnSynchronizedWrite> cppAidlMessageQueueUnsync;
50*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite> MessageQueueSync;
51*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<uint8_t, kUnsynchronizedWrite> MessageQueueUnsync;
52*be431cd8SAndroid Build Coastguard Worker
53*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<uint16_t, SynchronizedReadWrite> AidlMessageQueueSync16;
54*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<uint16_t, cppSynchronizedReadWrite> cppAidlMessageQueueSync16;
55*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<uint16_t, kSynchronizedReadWrite> MessageQueueSync16;
56*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<uint16_t, UnsynchronizedWrite> AidlMessageQueueUnsync16;
57*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<uint16_t, cppUnSynchronizedWrite> cppAidlMessageQueueUnsync16;
58*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<uint16_t, kUnsynchronizedWrite> MessageQueueUnsync16;
59*be431cd8SAndroid Build Coastguard Worker
60*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite> MessageQueueSync8;
61*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MQDescriptor<uint8_t, kSynchronizedReadWrite> HidlMQDescSync8;
62*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<int8_t, SynchronizedReadWrite> AidlMessageQueueSync8;
63*be431cd8SAndroid Build Coastguard Worker typedef aidl::android::hardware::common::fmq::MQDescriptor<int8_t, SynchronizedReadWrite>
64*be431cd8SAndroid Build Coastguard Worker AidlMQDescSync8;
65*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<int8_t, cppSynchronizedReadWrite> cppAidlMessageQueueSync8;
66*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::common::fmq::MQDescriptor<int8_t, cppSynchronizedReadWrite>
67*be431cd8SAndroid Build Coastguard Worker cppAidlMQDescSync8;
68*be431cd8SAndroid Build Coastguard Worker
69*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<uint8_t, kUnsynchronizedWrite> MessageQueueUnsync8;
70*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MQDescriptor<uint8_t, kUnsynchronizedWrite> HidlMQDescUnsync8;
71*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<int8_t, UnsynchronizedWrite> AidlMessageQueueUnsync8;
72*be431cd8SAndroid Build Coastguard Worker typedef aidl::android::hardware::common::fmq::MQDescriptor<int8_t, UnsynchronizedWrite>
73*be431cd8SAndroid Build Coastguard Worker AidlMQDescUnsync8;
74*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<int8_t, cppUnSynchronizedWrite> cppAidlMessageQueueUnsync8;
75*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::common::fmq::MQDescriptor<int8_t, cppUnSynchronizedWrite>
76*be431cd8SAndroid Build Coastguard Worker cppAidlMQDescUnsync8;
77*be431cd8SAndroid Build Coastguard Worker
78*be431cd8SAndroid Build Coastguard Worker enum class SetupType {
79*be431cd8SAndroid Build Coastguard Worker SINGLE_FD,
80*be431cd8SAndroid Build Coastguard Worker DOUBLE_FD,
81*be431cd8SAndroid Build Coastguard Worker };
82*be431cd8SAndroid Build Coastguard Worker
83*be431cd8SAndroid Build Coastguard Worker template <typename T, SetupType setupType>
84*be431cd8SAndroid Build Coastguard Worker class TestParamTypes {
85*be431cd8SAndroid Build Coastguard Worker public:
86*be431cd8SAndroid Build Coastguard Worker typedef T MQType;
87*be431cd8SAndroid Build Coastguard Worker static constexpr SetupType Setup = setupType;
88*be431cd8SAndroid Build Coastguard Worker };
89*be431cd8SAndroid Build Coastguard Worker
90*be431cd8SAndroid Build Coastguard Worker // Run everything on both the AIDL and HIDL versions with one and two FDs
91*be431cd8SAndroid Build Coastguard Worker typedef ::testing::Types<TestParamTypes<AidlMessageQueueSync, SetupType::SINGLE_FD>,
92*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueSync, SetupType::SINGLE_FD>,
93*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueSync, SetupType::SINGLE_FD>,
94*be431cd8SAndroid Build Coastguard Worker TestParamTypes<AidlMessageQueueSync, SetupType::DOUBLE_FD>,
95*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueSync, SetupType::DOUBLE_FD>,
96*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueSync, SetupType::DOUBLE_FD>>
97*be431cd8SAndroid Build Coastguard Worker SyncTypes;
98*be431cd8SAndroid Build Coastguard Worker typedef ::testing::Types<TestParamTypes<AidlMessageQueueUnsync, SetupType::SINGLE_FD>,
99*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueUnsync, SetupType::SINGLE_FD>,
100*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueUnsync, SetupType::SINGLE_FD>,
101*be431cd8SAndroid Build Coastguard Worker TestParamTypes<AidlMessageQueueUnsync, SetupType::DOUBLE_FD>,
102*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueUnsync, SetupType::DOUBLE_FD>,
103*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueUnsync, SetupType::DOUBLE_FD>>
104*be431cd8SAndroid Build Coastguard Worker UnsyncTypes;
105*be431cd8SAndroid Build Coastguard Worker typedef ::testing::Types<TestParamTypes<AidlMessageQueueUnsync16, SetupType::SINGLE_FD>,
106*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueUnsync16, SetupType::SINGLE_FD>,
107*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueUnsync16, SetupType::SINGLE_FD>,
108*be431cd8SAndroid Build Coastguard Worker TestParamTypes<AidlMessageQueueUnsync16, SetupType::DOUBLE_FD>,
109*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueUnsync16, SetupType::DOUBLE_FD>,
110*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueUnsync16, SetupType::DOUBLE_FD>>
111*be431cd8SAndroid Build Coastguard Worker TwoByteUnsyncTypes;
112*be431cd8SAndroid Build Coastguard Worker typedef ::testing::Types<TestParamTypes<AidlMessageQueueSync16, SetupType::SINGLE_FD>,
113*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueSync16, SetupType::SINGLE_FD>,
114*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueSync16, SetupType::SINGLE_FD>,
115*be431cd8SAndroid Build Coastguard Worker TestParamTypes<AidlMessageQueueSync16, SetupType::DOUBLE_FD>,
116*be431cd8SAndroid Build Coastguard Worker TestParamTypes<cppAidlMessageQueueSync16, SetupType::DOUBLE_FD>,
117*be431cd8SAndroid Build Coastguard Worker TestParamTypes<MessageQueueSync16, SetupType::DOUBLE_FD>>
118*be431cd8SAndroid Build Coastguard Worker BadConfigTypes;
119*be431cd8SAndroid Build Coastguard Worker
120*be431cd8SAndroid Build Coastguard Worker template <typename T>
121*be431cd8SAndroid Build Coastguard Worker class TestBase : public ::testing::Test {
122*be431cd8SAndroid Build Coastguard Worker public:
123*be431cd8SAndroid Build Coastguard Worker static void ReaderThreadBlocking(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr);
124*be431cd8SAndroid Build Coastguard Worker static void ReaderThreadBlocking2(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr);
125*be431cd8SAndroid Build Coastguard Worker };
126*be431cd8SAndroid Build Coastguard Worker
127*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(SynchronizedReadWrites, SyncTypes);
128*be431cd8SAndroid Build Coastguard Worker
129*be431cd8SAndroid Build Coastguard Worker template <typename T>
130*be431cd8SAndroid Build Coastguard Worker class SynchronizedReadWrites : public TestBase<T> {
131*be431cd8SAndroid Build Coastguard Worker protected:
TearDown()132*be431cd8SAndroid Build Coastguard Worker virtual void TearDown() {
133*be431cd8SAndroid Build Coastguard Worker delete mQueue;
134*be431cd8SAndroid Build Coastguard Worker }
135*be431cd8SAndroid Build Coastguard Worker
SetUp()136*be431cd8SAndroid Build Coastguard Worker virtual void SetUp() {
137*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kNumElementsInQueue = 2048;
138*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kPayloadSizeBytes = 1;
139*be431cd8SAndroid Build Coastguard Worker if (T::Setup == SetupType::SINGLE_FD) {
140*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
141*be431cd8SAndroid Build Coastguard Worker } else {
142*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(::ashmem_create_region(
143*be431cd8SAndroid Build Coastguard Worker "SyncReadWrite", kNumElementsInQueue * kPayloadSizeBytes));
144*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow)
145*be431cd8SAndroid Build Coastguard Worker typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
146*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue * kPayloadSizeBytes);
147*be431cd8SAndroid Build Coastguard Worker }
148*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, mQueue);
149*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(mQueue->isValid());
150*be431cd8SAndroid Build Coastguard Worker mNumMessagesMax = mQueue->getQuantumCount();
151*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
152*be431cd8SAndroid Build Coastguard Worker }
153*be431cd8SAndroid Build Coastguard Worker
154*be431cd8SAndroid Build Coastguard Worker typename T::MQType* mQueue = nullptr;
155*be431cd8SAndroid Build Coastguard Worker size_t mNumMessagesMax = 0;
156*be431cd8SAndroid Build Coastguard Worker };
157*be431cd8SAndroid Build Coastguard Worker
158*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(UnsynchronizedReadWriteTest, UnsyncTypes);
159*be431cd8SAndroid Build Coastguard Worker
160*be431cd8SAndroid Build Coastguard Worker template <typename T>
161*be431cd8SAndroid Build Coastguard Worker class UnsynchronizedReadWriteTest : public TestBase<T> {
162*be431cd8SAndroid Build Coastguard Worker protected:
TearDown()163*be431cd8SAndroid Build Coastguard Worker virtual void TearDown() {
164*be431cd8SAndroid Build Coastguard Worker delete mQueue;
165*be431cd8SAndroid Build Coastguard Worker }
166*be431cd8SAndroid Build Coastguard Worker
SetUp()167*be431cd8SAndroid Build Coastguard Worker virtual void SetUp() {
168*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kNumElementsInQueue = 2048;
169*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kPayloadSizeBytes = 1;
170*be431cd8SAndroid Build Coastguard Worker if (T::Setup == SetupType::SINGLE_FD) {
171*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
172*be431cd8SAndroid Build Coastguard Worker } else {
173*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(
174*be431cd8SAndroid Build Coastguard Worker ::ashmem_create_region("UnsyncWrite", kNumElementsInQueue * kPayloadSizeBytes));
175*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow)
176*be431cd8SAndroid Build Coastguard Worker typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
177*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue * kPayloadSizeBytes);
178*be431cd8SAndroid Build Coastguard Worker }
179*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, mQueue);
180*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(mQueue->isValid());
181*be431cd8SAndroid Build Coastguard Worker mNumMessagesMax = mQueue->getQuantumCount();
182*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
183*be431cd8SAndroid Build Coastguard Worker }
184*be431cd8SAndroid Build Coastguard Worker
185*be431cd8SAndroid Build Coastguard Worker typename T::MQType* mQueue = nullptr;
186*be431cd8SAndroid Build Coastguard Worker size_t mNumMessagesMax = 0;
187*be431cd8SAndroid Build Coastguard Worker };
188*be431cd8SAndroid Build Coastguard Worker
189*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(BlockingReadWrites, SyncTypes);
190*be431cd8SAndroid Build Coastguard Worker
191*be431cd8SAndroid Build Coastguard Worker template <typename T>
192*be431cd8SAndroid Build Coastguard Worker class BlockingReadWrites : public TestBase<T> {
193*be431cd8SAndroid Build Coastguard Worker protected:
TearDown()194*be431cd8SAndroid Build Coastguard Worker virtual void TearDown() {
195*be431cd8SAndroid Build Coastguard Worker delete mQueue;
196*be431cd8SAndroid Build Coastguard Worker }
SetUp()197*be431cd8SAndroid Build Coastguard Worker virtual void SetUp() {
198*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kNumElementsInQueue = 2048;
199*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kPayloadSizeBytes = 1;
200*be431cd8SAndroid Build Coastguard Worker if (T::Setup == SetupType::SINGLE_FD) {
201*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
202*be431cd8SAndroid Build Coastguard Worker } else {
203*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(::ashmem_create_region(
204*be431cd8SAndroid Build Coastguard Worker "SyncBlockingReadWrite", kNumElementsInQueue * kPayloadSizeBytes));
205*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow)
206*be431cd8SAndroid Build Coastguard Worker typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
207*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue * kPayloadSizeBytes);
208*be431cd8SAndroid Build Coastguard Worker }
209*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, mQueue);
210*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(mQueue->isValid());
211*be431cd8SAndroid Build Coastguard Worker mNumMessagesMax = mQueue->getQuantumCount();
212*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
213*be431cd8SAndroid Build Coastguard Worker /*
214*be431cd8SAndroid Build Coastguard Worker * Initialize the EventFlag word to indicate Queue is not full.
215*be431cd8SAndroid Build Coastguard Worker */
216*be431cd8SAndroid Build Coastguard Worker std::atomic_init(&mFw, static_cast<uint32_t>(kFmqNotFull));
217*be431cd8SAndroid Build Coastguard Worker }
218*be431cd8SAndroid Build Coastguard Worker
219*be431cd8SAndroid Build Coastguard Worker typename T::MQType* mQueue;
220*be431cd8SAndroid Build Coastguard Worker std::atomic<uint32_t> mFw;
221*be431cd8SAndroid Build Coastguard Worker size_t mNumMessagesMax = 0;
222*be431cd8SAndroid Build Coastguard Worker };
223*be431cd8SAndroid Build Coastguard Worker
224*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(QueueSizeOdd, SyncTypes);
225*be431cd8SAndroid Build Coastguard Worker
226*be431cd8SAndroid Build Coastguard Worker template <typename T>
227*be431cd8SAndroid Build Coastguard Worker class QueueSizeOdd : public TestBase<T> {
228*be431cd8SAndroid Build Coastguard Worker protected:
TearDown()229*be431cd8SAndroid Build Coastguard Worker virtual void TearDown() { delete mQueue; }
SetUp()230*be431cd8SAndroid Build Coastguard Worker virtual void SetUp() {
231*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kNumElementsInQueue = 2049;
232*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kPayloadSizeBytes = 1;
233*be431cd8SAndroid Build Coastguard Worker if (T::Setup == SetupType::SINGLE_FD) {
234*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow)
235*be431cd8SAndroid Build Coastguard Worker typename T::MQType(kNumElementsInQueue, true /* configureEventFlagWord */);
236*be431cd8SAndroid Build Coastguard Worker } else {
237*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(
238*be431cd8SAndroid Build Coastguard Worker ::ashmem_create_region("SyncSizeOdd", kNumElementsInQueue * kPayloadSizeBytes));
239*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow) typename T::MQType(
240*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue, true /* configureEventFlagWord */, std::move(ringbufferFd),
241*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue * kPayloadSizeBytes);
242*be431cd8SAndroid Build Coastguard Worker }
243*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, mQueue);
244*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(mQueue->isValid());
245*be431cd8SAndroid Build Coastguard Worker mNumMessagesMax = mQueue->getQuantumCount();
246*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
247*be431cd8SAndroid Build Coastguard Worker auto evFlagWordPtr = mQueue->getEventFlagWord();
248*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, evFlagWordPtr);
249*be431cd8SAndroid Build Coastguard Worker /*
250*be431cd8SAndroid Build Coastguard Worker * Initialize the EventFlag word to indicate Queue is not full.
251*be431cd8SAndroid Build Coastguard Worker */
252*be431cd8SAndroid Build Coastguard Worker std::atomic_init(evFlagWordPtr, static_cast<uint32_t>(kFmqNotFull));
253*be431cd8SAndroid Build Coastguard Worker }
254*be431cd8SAndroid Build Coastguard Worker
255*be431cd8SAndroid Build Coastguard Worker typename T::MQType* mQueue;
256*be431cd8SAndroid Build Coastguard Worker size_t mNumMessagesMax = 0;
257*be431cd8SAndroid Build Coastguard Worker };
258*be431cd8SAndroid Build Coastguard Worker
259*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(BadQueueConfig, BadConfigTypes);
260*be431cd8SAndroid Build Coastguard Worker
261*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(UnsynchronizedOverflowHistoryTest, TwoByteUnsyncTypes);
262*be431cd8SAndroid Build Coastguard Worker
263*be431cd8SAndroid Build Coastguard Worker template <typename T>
264*be431cd8SAndroid Build Coastguard Worker class UnsynchronizedOverflowHistoryTest : public TestBase<T> {
265*be431cd8SAndroid Build Coastguard Worker protected:
TearDown()266*be431cd8SAndroid Build Coastguard Worker virtual void TearDown() { delete mQueue; }
267*be431cd8SAndroid Build Coastguard Worker
SetUp()268*be431cd8SAndroid Build Coastguard Worker virtual void SetUp() {
269*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kNumElementsInQueue = 2048;
270*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kPayloadSizeBytes = 2;
271*be431cd8SAndroid Build Coastguard Worker if (T::Setup == SetupType::SINGLE_FD) {
272*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
273*be431cd8SAndroid Build Coastguard Worker } else {
274*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(::ashmem_create_region(
275*be431cd8SAndroid Build Coastguard Worker "UnsyncHistory", kNumElementsInQueue * kPayloadSizeBytes));
276*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow)
277*be431cd8SAndroid Build Coastguard Worker typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
278*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue * kPayloadSizeBytes);
279*be431cd8SAndroid Build Coastguard Worker }
280*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, mQueue);
281*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(mQueue->isValid());
282*be431cd8SAndroid Build Coastguard Worker mNumMessagesMax = mQueue->getQuantumCount();
283*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
284*be431cd8SAndroid Build Coastguard Worker }
285*be431cd8SAndroid Build Coastguard Worker
286*be431cd8SAndroid Build Coastguard Worker typename T::MQType* mQueue = nullptr;
287*be431cd8SAndroid Build Coastguard Worker size_t mNumMessagesMax = 0;
288*be431cd8SAndroid Build Coastguard Worker };
289*be431cd8SAndroid Build Coastguard Worker
290*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(UnsynchronizedOverflowHistoryTestSingleElement, TwoByteUnsyncTypes);
291*be431cd8SAndroid Build Coastguard Worker
292*be431cd8SAndroid Build Coastguard Worker template <typename T>
293*be431cd8SAndroid Build Coastguard Worker class UnsynchronizedOverflowHistoryTestSingleElement : public TestBase<T> {
294*be431cd8SAndroid Build Coastguard Worker protected:
TearDown()295*be431cd8SAndroid Build Coastguard Worker virtual void TearDown() { delete mQueue; }
296*be431cd8SAndroid Build Coastguard Worker
SetUp()297*be431cd8SAndroid Build Coastguard Worker virtual void SetUp() {
298*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kNumElementsInQueue = 1;
299*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kPayloadSizeBytes = 2;
300*be431cd8SAndroid Build Coastguard Worker if (T::Setup == SetupType::SINGLE_FD) {
301*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
302*be431cd8SAndroid Build Coastguard Worker } else {
303*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(::ashmem_create_region(
304*be431cd8SAndroid Build Coastguard Worker "UnsyncHistory", kNumElementsInQueue * kPayloadSizeBytes));
305*be431cd8SAndroid Build Coastguard Worker mQueue = new (std::nothrow)
306*be431cd8SAndroid Build Coastguard Worker typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
307*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue * kPayloadSizeBytes);
308*be431cd8SAndroid Build Coastguard Worker }
309*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, mQueue);
310*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(mQueue->isValid());
311*be431cd8SAndroid Build Coastguard Worker mNumMessagesMax = mQueue->getQuantumCount();
312*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
313*be431cd8SAndroid Build Coastguard Worker }
314*be431cd8SAndroid Build Coastguard Worker
315*be431cd8SAndroid Build Coastguard Worker typename T::MQType* mQueue = nullptr;
316*be431cd8SAndroid Build Coastguard Worker size_t mNumMessagesMax = 0;
317*be431cd8SAndroid Build Coastguard Worker };
318*be431cd8SAndroid Build Coastguard Worker
319*be431cd8SAndroid Build Coastguard Worker template <typename T>
320*be431cd8SAndroid Build Coastguard Worker class BadQueueConfig : public TestBase<T> {};
321*be431cd8SAndroid Build Coastguard Worker
322*be431cd8SAndroid Build Coastguard Worker class AidlOnlyBadQueueConfig : public ::testing::Test {};
323*be431cd8SAndroid Build Coastguard Worker class HidlOnlyBadQueueConfig : public ::testing::Test {};
324*be431cd8SAndroid Build Coastguard Worker class Hidl2AidlOperation : public ::testing::Test {};
325*be431cd8SAndroid Build Coastguard Worker class DoubleFdFailures : public ::testing::Test {};
326*be431cd8SAndroid Build Coastguard Worker
327*be431cd8SAndroid Build Coastguard Worker /*
328*be431cd8SAndroid Build Coastguard Worker * Utility function to initialize data to be written to the FMQ
329*be431cd8SAndroid Build Coastguard Worker */
330*be431cd8SAndroid Build Coastguard Worker template <typename T>
initData(T * data,size_t count)331*be431cd8SAndroid Build Coastguard Worker inline void initData(T* data, size_t count) {
332*be431cd8SAndroid Build Coastguard Worker for (size_t i = 0; i < count; i++) {
333*be431cd8SAndroid Build Coastguard Worker data[i] = i & 0xFF;
334*be431cd8SAndroid Build Coastguard Worker }
335*be431cd8SAndroid Build Coastguard Worker }
336*be431cd8SAndroid Build Coastguard Worker
337*be431cd8SAndroid Build Coastguard Worker /*
338*be431cd8SAndroid Build Coastguard Worker * This thread will attempt to read and block. When wait returns
339*be431cd8SAndroid Build Coastguard Worker * it checks if the kFmqNotEmpty bit is actually set.
340*be431cd8SAndroid Build Coastguard Worker * If the read is succesful, it signals Wake to kFmqNotFull.
341*be431cd8SAndroid Build Coastguard Worker */
342*be431cd8SAndroid Build Coastguard Worker template <typename T>
ReaderThreadBlocking(typename T::MQType * fmq,std::atomic<uint32_t> * fwAddr)343*be431cd8SAndroid Build Coastguard Worker void TestBase<T>::ReaderThreadBlocking(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr) {
344*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 64;
345*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
346*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
347*be431cd8SAndroid Build Coastguard Worker android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
348*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
349*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
350*be431cd8SAndroid Build Coastguard Worker
351*be431cd8SAndroid Build Coastguard Worker while (true) {
352*be431cd8SAndroid Build Coastguard Worker uint32_t efState = 0;
353*be431cd8SAndroid Build Coastguard Worker android::status_t ret = efGroup->wait(kFmqNotEmpty,
354*be431cd8SAndroid Build Coastguard Worker &efState,
355*be431cd8SAndroid Build Coastguard Worker 5000000000 /* timeoutNanoSeconds */);
356*be431cd8SAndroid Build Coastguard Worker /*
357*be431cd8SAndroid Build Coastguard Worker * Wait should not time out here after 5s
358*be431cd8SAndroid Build Coastguard Worker */
359*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(android::TIMED_OUT, ret);
360*be431cd8SAndroid Build Coastguard Worker
361*be431cd8SAndroid Build Coastguard Worker if ((efState & kFmqNotEmpty) && fmq->read(data, dataLen)) {
362*be431cd8SAndroid Build Coastguard Worker efGroup->wake(kFmqNotFull);
363*be431cd8SAndroid Build Coastguard Worker break;
364*be431cd8SAndroid Build Coastguard Worker }
365*be431cd8SAndroid Build Coastguard Worker }
366*be431cd8SAndroid Build Coastguard Worker
367*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
368*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
369*be431cd8SAndroid Build Coastguard Worker }
370*be431cd8SAndroid Build Coastguard Worker
371*be431cd8SAndroid Build Coastguard Worker /*
372*be431cd8SAndroid Build Coastguard Worker * This thread will attempt to read and block using the readBlocking() API and
373*be431cd8SAndroid Build Coastguard Worker * passes in a pointer to an EventFlag object.
374*be431cd8SAndroid Build Coastguard Worker */
375*be431cd8SAndroid Build Coastguard Worker template <typename T>
ReaderThreadBlocking2(typename T::MQType * fmq,std::atomic<uint32_t> * fwAddr)376*be431cd8SAndroid Build Coastguard Worker void TestBase<T>::ReaderThreadBlocking2(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr) {
377*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 64;
378*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
379*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
380*be431cd8SAndroid Build Coastguard Worker android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
381*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
382*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
383*be431cd8SAndroid Build Coastguard Worker bool ret = fmq->readBlocking(data,
384*be431cd8SAndroid Build Coastguard Worker dataLen,
385*be431cd8SAndroid Build Coastguard Worker static_cast<uint32_t>(kFmqNotFull),
386*be431cd8SAndroid Build Coastguard Worker static_cast<uint32_t>(kFmqNotEmpty),
387*be431cd8SAndroid Build Coastguard Worker 5000000000 /* timeOutNanos */,
388*be431cd8SAndroid Build Coastguard Worker efGroup);
389*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(ret);
390*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
391*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
392*be431cd8SAndroid Build Coastguard Worker }
393*be431cd8SAndroid Build Coastguard Worker
TYPED_TEST(BadQueueConfig,QueueSizeTooLarge)394*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(BadQueueConfig, QueueSizeTooLarge) {
395*be431cd8SAndroid Build Coastguard Worker size_t numElementsInQueue = SIZE_MAX / sizeof(uint16_t) + 1;
396*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType fmq(numElementsInQueue);
397*be431cd8SAndroid Build Coastguard Worker /*
398*be431cd8SAndroid Build Coastguard Worker * Should fail due to size being too large to fit into size_t.
399*be431cd8SAndroid Build Coastguard Worker */
400*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(fmq.isValid());
401*be431cd8SAndroid Build Coastguard Worker }
402*be431cd8SAndroid Build Coastguard Worker
403*be431cd8SAndroid Build Coastguard Worker // {flags, fdIndex, offset, extent}
404*be431cd8SAndroid Build Coastguard Worker static const std::vector<android::hardware::GrantorDescriptor> kGrantors = {
405*be431cd8SAndroid Build Coastguard Worker {0, 0, 0, 4096},
406*be431cd8SAndroid Build Coastguard Worker {0, 0, 0, 4096},
407*be431cd8SAndroid Build Coastguard Worker {0, 0, 0, 4096},
408*be431cd8SAndroid Build Coastguard Worker };
409*be431cd8SAndroid Build Coastguard Worker
410*be431cd8SAndroid Build Coastguard Worker // Make sure this passes without invalid index/extent for the next two test
411*be431cd8SAndroid Build Coastguard Worker // cases
TEST_F(HidlOnlyBadQueueConfig,SanityCheck)412*be431cd8SAndroid Build Coastguard Worker TEST_F(HidlOnlyBadQueueConfig, SanityCheck) {
413*be431cd8SAndroid Build Coastguard Worker std::vector<android::hardware::GrantorDescriptor> grantors = kGrantors;
414*be431cd8SAndroid Build Coastguard Worker
415*be431cd8SAndroid Build Coastguard Worker native_handle_t* handle = native_handle_create(1, 0);
416*be431cd8SAndroid Build Coastguard Worker int ashmemFd = ashmem_create_region("QueueHidlOnlyBad", 4096);
417*be431cd8SAndroid Build Coastguard Worker ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
418*be431cd8SAndroid Build Coastguard Worker handle->data[0] = ashmemFd;
419*be431cd8SAndroid Build Coastguard Worker
420*be431cd8SAndroid Build Coastguard Worker android::hardware::MQDescriptor<uint16_t, kSynchronizedReadWrite> desc(grantors, handle,
421*be431cd8SAndroid Build Coastguard Worker sizeof(uint16_t));
422*be431cd8SAndroid Build Coastguard Worker android::hardware::MessageQueue<uint16_t, kSynchronizedReadWrite> fmq(desc);
423*be431cd8SAndroid Build Coastguard Worker EXPECT_TRUE(fmq.isValid());
424*be431cd8SAndroid Build Coastguard Worker
425*be431cd8SAndroid Build Coastguard Worker close(ashmemFd);
426*be431cd8SAndroid Build Coastguard Worker }
427*be431cd8SAndroid Build Coastguard Worker
TEST_F(HidlOnlyBadQueueConfig,BadFdIndex)428*be431cd8SAndroid Build Coastguard Worker TEST_F(HidlOnlyBadQueueConfig, BadFdIndex) {
429*be431cd8SAndroid Build Coastguard Worker std::vector<android::hardware::GrantorDescriptor> grantors = kGrantors;
430*be431cd8SAndroid Build Coastguard Worker grantors[0].fdIndex = 5;
431*be431cd8SAndroid Build Coastguard Worker
432*be431cd8SAndroid Build Coastguard Worker native_handle_t* handle = native_handle_create(1, 0);
433*be431cd8SAndroid Build Coastguard Worker int ashmemFd = ashmem_create_region("QueueHidlOnlyBad", 4096);
434*be431cd8SAndroid Build Coastguard Worker ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
435*be431cd8SAndroid Build Coastguard Worker handle->data[0] = ashmemFd;
436*be431cd8SAndroid Build Coastguard Worker
437*be431cd8SAndroid Build Coastguard Worker android::hardware::MQDescriptor<uint16_t, kSynchronizedReadWrite> desc(grantors, handle,
438*be431cd8SAndroid Build Coastguard Worker sizeof(uint16_t));
439*be431cd8SAndroid Build Coastguard Worker android::hardware::MessageQueue<uint16_t, kSynchronizedReadWrite> fmq(desc);
440*be431cd8SAndroid Build Coastguard Worker /*
441*be431cd8SAndroid Build Coastguard Worker * Should fail due fdIndex being out of range of the native_handle.
442*be431cd8SAndroid Build Coastguard Worker */
443*be431cd8SAndroid Build Coastguard Worker EXPECT_FALSE(fmq.isValid());
444*be431cd8SAndroid Build Coastguard Worker
445*be431cd8SAndroid Build Coastguard Worker close(ashmemFd);
446*be431cd8SAndroid Build Coastguard Worker }
447*be431cd8SAndroid Build Coastguard Worker
TEST_F(HidlOnlyBadQueueConfig,ExtentTooLarge)448*be431cd8SAndroid Build Coastguard Worker TEST_F(HidlOnlyBadQueueConfig, ExtentTooLarge) {
449*be431cd8SAndroid Build Coastguard Worker std::vector<android::hardware::GrantorDescriptor> grantors = kGrantors;
450*be431cd8SAndroid Build Coastguard Worker grantors[0].extent = 0xfffff041;
451*be431cd8SAndroid Build Coastguard Worker
452*be431cd8SAndroid Build Coastguard Worker native_handle_t* handle = native_handle_create(1, 0);
453*be431cd8SAndroid Build Coastguard Worker int ashmemFd = ashmem_create_region("QueueHidlOnlyBad", 4096);
454*be431cd8SAndroid Build Coastguard Worker ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
455*be431cd8SAndroid Build Coastguard Worker handle->data[0] = ashmemFd;
456*be431cd8SAndroid Build Coastguard Worker
457*be431cd8SAndroid Build Coastguard Worker android::hardware::MQDescriptor<uint16_t, kSynchronizedReadWrite> desc(grantors, handle,
458*be431cd8SAndroid Build Coastguard Worker sizeof(uint16_t));
459*be431cd8SAndroid Build Coastguard Worker android::hardware::MessageQueue<uint16_t, kSynchronizedReadWrite> fmq(desc);
460*be431cd8SAndroid Build Coastguard Worker /*
461*be431cd8SAndroid Build Coastguard Worker * Should fail due to extent being too large.
462*be431cd8SAndroid Build Coastguard Worker */
463*be431cd8SAndroid Build Coastguard Worker EXPECT_FALSE(fmq.isValid());
464*be431cd8SAndroid Build Coastguard Worker
465*be431cd8SAndroid Build Coastguard Worker close(ashmemFd);
466*be431cd8SAndroid Build Coastguard Worker }
467*be431cd8SAndroid Build Coastguard Worker
numFds()468*be431cd8SAndroid Build Coastguard Worker long numFds() {
469*be431cd8SAndroid Build Coastguard Worker return std::distance(std::filesystem::directory_iterator("/proc/self/fd"),
470*be431cd8SAndroid Build Coastguard Worker std::filesystem::directory_iterator{});
471*be431cd8SAndroid Build Coastguard Worker }
472*be431cd8SAndroid Build Coastguard Worker
TEST_F(AidlOnlyBadQueueConfig,LookForLeakedFds)473*be431cd8SAndroid Build Coastguard Worker TEST_F(AidlOnlyBadQueueConfig, LookForLeakedFds) {
474*be431cd8SAndroid Build Coastguard Worker // Write a log msg first to open the pmsg FD and socket to logd.
475*be431cd8SAndroid Build Coastguard Worker LOG(INFO) << "Nothin' to see here...";
476*be431cd8SAndroid Build Coastguard Worker // create/destroy a large number of queues that if we were leaking FDs
477*be431cd8SAndroid Build Coastguard Worker // we could detect it by looking at the number of FDs opened by the this
478*be431cd8SAndroid Build Coastguard Worker // test process.
479*be431cd8SAndroid Build Coastguard Worker constexpr uint32_t kNumQueues = 100;
480*be431cd8SAndroid Build Coastguard Worker const size_t kPageSize = getpagesize();
481*be431cd8SAndroid Build Coastguard Worker size_t numElementsInQueue = SIZE_MAX / sizeof(uint32_t) - kPageSize - 1;
482*be431cd8SAndroid Build Coastguard Worker long numFdsBefore = numFds();
483*be431cd8SAndroid Build Coastguard Worker for (int i = 0; i < kNumQueues; i++) {
484*be431cd8SAndroid Build Coastguard Worker android::AidlMessageQueue<uint32_t, SynchronizedReadWrite> fmq(numElementsInQueue);
485*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(fmq.isValid());
486*be431cd8SAndroid Build Coastguard Worker }
487*be431cd8SAndroid Build Coastguard Worker long numFdsAfter = numFds();
488*be431cd8SAndroid Build Coastguard Worker EXPECT_LT(numFdsAfter, kNumQueues);
489*be431cd8SAndroid Build Coastguard Worker EXPECT_EQ(numFdsAfter, numFdsBefore);
490*be431cd8SAndroid Build Coastguard Worker }
491*be431cd8SAndroid Build Coastguard Worker
TEST_F(Hidl2AidlOperation,ConvertDescriptorsSync)492*be431cd8SAndroid Build Coastguard Worker TEST_F(Hidl2AidlOperation, ConvertDescriptorsSync) {
493*be431cd8SAndroid Build Coastguard Worker size_t numElementsInQueue = 64;
494*be431cd8SAndroid Build Coastguard Worker
495*be431cd8SAndroid Build Coastguard Worker // Create HIDL side and get MQDescriptor
496*be431cd8SAndroid Build Coastguard Worker MessageQueueSync8 fmq(numElementsInQueue);
497*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(fmq.isValid());
498*be431cd8SAndroid Build Coastguard Worker const HidlMQDescSync8* hidlDesc = fmq.getDesc();
499*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, hidlDesc);
500*be431cd8SAndroid Build Coastguard Worker
501*be431cd8SAndroid Build Coastguard Worker // Create AIDL MQDescriptor to send to another process based off the HIDL MQDescriptor
502*be431cd8SAndroid Build Coastguard Worker AidlMQDescSync8 aidlDesc;
503*be431cd8SAndroid Build Coastguard Worker android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(*hidlDesc,
504*be431cd8SAndroid Build Coastguard Worker &aidlDesc);
505*be431cd8SAndroid Build Coastguard Worker
506*be431cd8SAndroid Build Coastguard Worker // Other process will create the other side of the queue using the AIDL MQDescriptor
507*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync8 aidlFmq(aidlDesc);
508*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(aidlFmq.isValid());
509*be431cd8SAndroid Build Coastguard Worker
510*be431cd8SAndroid Build Coastguard Worker // Make sure a write to the HIDL side, will show up for the AIDL side
511*be431cd8SAndroid Build Coastguard Worker constexpr size_t dataLen = 4;
512*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen] = {12, 11, 10, 9};
513*be431cd8SAndroid Build Coastguard Worker fmq.write(data, dataLen);
514*be431cd8SAndroid Build Coastguard Worker
515*be431cd8SAndroid Build Coastguard Worker int8_t readData[dataLen];
516*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(aidlFmq.read(readData, dataLen));
517*be431cd8SAndroid Build Coastguard Worker
518*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[0], readData[0]);
519*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[1], readData[1]);
520*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[2], readData[2]);
521*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[3], readData[3]);
522*be431cd8SAndroid Build Coastguard Worker }
523*be431cd8SAndroid Build Coastguard Worker
TEST_F(Hidl2AidlOperation,ConvertDescriptorsUnsync)524*be431cd8SAndroid Build Coastguard Worker TEST_F(Hidl2AidlOperation, ConvertDescriptorsUnsync) {
525*be431cd8SAndroid Build Coastguard Worker size_t numElementsInQueue = 64;
526*be431cd8SAndroid Build Coastguard Worker
527*be431cd8SAndroid Build Coastguard Worker // Create HIDL side and get MQDescriptor
528*be431cd8SAndroid Build Coastguard Worker MessageQueueUnsync8 fmq(numElementsInQueue);
529*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(fmq.isValid());
530*be431cd8SAndroid Build Coastguard Worker const HidlMQDescUnsync8* hidlDesc = fmq.getDesc();
531*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, hidlDesc);
532*be431cd8SAndroid Build Coastguard Worker
533*be431cd8SAndroid Build Coastguard Worker // Create AIDL MQDescriptor to send to another process based off the HIDL MQDescriptor
534*be431cd8SAndroid Build Coastguard Worker AidlMQDescUnsync8 aidlDesc;
535*be431cd8SAndroid Build Coastguard Worker android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, UnsynchronizedWrite>(*hidlDesc,
536*be431cd8SAndroid Build Coastguard Worker &aidlDesc);
537*be431cd8SAndroid Build Coastguard Worker
538*be431cd8SAndroid Build Coastguard Worker // Other process will create the other side of the queue using the AIDL MQDescriptor
539*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueUnsync8 aidlFmq(aidlDesc);
540*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(aidlFmq.isValid());
541*be431cd8SAndroid Build Coastguard Worker
542*be431cd8SAndroid Build Coastguard Worker // Can have multiple readers with unsync flavor
543*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueUnsync8 aidlFmq2(aidlDesc);
544*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(aidlFmq2.isValid());
545*be431cd8SAndroid Build Coastguard Worker
546*be431cd8SAndroid Build Coastguard Worker // Make sure a write to the HIDL side, will show up for the AIDL side
547*be431cd8SAndroid Build Coastguard Worker constexpr size_t dataLen = 4;
548*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen] = {12, 11, 10, 9};
549*be431cd8SAndroid Build Coastguard Worker fmq.write(data, dataLen);
550*be431cd8SAndroid Build Coastguard Worker
551*be431cd8SAndroid Build Coastguard Worker int8_t readData[dataLen];
552*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(aidlFmq.read(readData, dataLen));
553*be431cd8SAndroid Build Coastguard Worker int8_t readData2[dataLen];
554*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(aidlFmq2.read(readData2, dataLen));
555*be431cd8SAndroid Build Coastguard Worker
556*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[0], readData[0]);
557*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[1], readData[1]);
558*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[2], readData[2]);
559*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[3], readData[3]);
560*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[0], readData2[0]);
561*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[1], readData2[1]);
562*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[2], readData2[2]);
563*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data[3], readData2[3]);
564*be431cd8SAndroid Build Coastguard Worker }
565*be431cd8SAndroid Build Coastguard Worker
TEST_F(Hidl2AidlOperation,ConvertFdIndex1)566*be431cd8SAndroid Build Coastguard Worker TEST_F(Hidl2AidlOperation, ConvertFdIndex1) {
567*be431cd8SAndroid Build Coastguard Worker native_handle_t* mqHandle = native_handle_create(2 /* numFds */, 0 /* numInts */);
568*be431cd8SAndroid Build Coastguard Worker if (mqHandle == nullptr) {
569*be431cd8SAndroid Build Coastguard Worker return;
570*be431cd8SAndroid Build Coastguard Worker }
571*be431cd8SAndroid Build Coastguard Worker mqHandle->data[0] = 12;
572*be431cd8SAndroid Build Coastguard Worker mqHandle->data[1] = 5;
573*be431cd8SAndroid Build Coastguard Worker ::android::hardware::hidl_vec<android::hardware::GrantorDescriptor> grantors;
574*be431cd8SAndroid Build Coastguard Worker grantors.resize(3);
575*be431cd8SAndroid Build Coastguard Worker grantors[0] = {0, 1 /* fdIndex */, 16, 16};
576*be431cd8SAndroid Build Coastguard Worker grantors[1] = {0, 1 /* fdIndex */, 16, 16};
577*be431cd8SAndroid Build Coastguard Worker grantors[2] = {0, 1 /* fdIndex */, 16, 16};
578*be431cd8SAndroid Build Coastguard Worker
579*be431cd8SAndroid Build Coastguard Worker HidlMQDescUnsync8 hidlDesc(grantors, mqHandle, 10);
580*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(hidlDesc.isHandleValid());
581*be431cd8SAndroid Build Coastguard Worker
582*be431cd8SAndroid Build Coastguard Worker AidlMQDescUnsync8 aidlDesc;
583*be431cd8SAndroid Build Coastguard Worker bool ret = android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, UnsynchronizedWrite>(
584*be431cd8SAndroid Build Coastguard Worker hidlDesc, &aidlDesc);
585*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(ret);
586*be431cd8SAndroid Build Coastguard Worker }
587*be431cd8SAndroid Build Coastguard Worker
TEST_F(Hidl2AidlOperation,ConvertMultipleFds)588*be431cd8SAndroid Build Coastguard Worker TEST_F(Hidl2AidlOperation, ConvertMultipleFds) {
589*be431cd8SAndroid Build Coastguard Worker native_handle_t* mqHandle = native_handle_create(2 /* numFds */, 0 /* numInts */);
590*be431cd8SAndroid Build Coastguard Worker if (mqHandle == nullptr) {
591*be431cd8SAndroid Build Coastguard Worker return;
592*be431cd8SAndroid Build Coastguard Worker }
593*be431cd8SAndroid Build Coastguard Worker mqHandle->data[0] = ::ashmem_create_region("ConvertMultipleFds", 8);
594*be431cd8SAndroid Build Coastguard Worker mqHandle->data[1] = ::ashmem_create_region("ConvertMultipleFds2", 8);
595*be431cd8SAndroid Build Coastguard Worker ::android::hardware::hidl_vec<android::hardware::GrantorDescriptor> grantors;
596*be431cd8SAndroid Build Coastguard Worker grantors.resize(3);
597*be431cd8SAndroid Build Coastguard Worker grantors[0] = {0, 1 /* fdIndex */, 16, 16};
598*be431cd8SAndroid Build Coastguard Worker grantors[1] = {0, 1 /* fdIndex */, 16, 16};
599*be431cd8SAndroid Build Coastguard Worker grantors[2] = {0, 0 /* fdIndex */, 16, 16};
600*be431cd8SAndroid Build Coastguard Worker
601*be431cd8SAndroid Build Coastguard Worker HidlMQDescUnsync8 hidlDesc(grantors, mqHandle, 10);
602*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(hidlDesc.isHandleValid());
603*be431cd8SAndroid Build Coastguard Worker
604*be431cd8SAndroid Build Coastguard Worker AidlMQDescUnsync8 aidlDesc;
605*be431cd8SAndroid Build Coastguard Worker bool ret = android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, UnsynchronizedWrite>(
606*be431cd8SAndroid Build Coastguard Worker hidlDesc, &aidlDesc);
607*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(ret);
608*be431cd8SAndroid Build Coastguard Worker EXPECT_EQ(aidlDesc.handle.fds.size(), 2);
609*be431cd8SAndroid Build Coastguard Worker }
610*be431cd8SAndroid Build Coastguard Worker
611*be431cd8SAndroid Build Coastguard Worker // TODO(b/165674950) Since AIDL does not support unsigned integers, it can only support
612*be431cd8SAndroid Build Coastguard Worker // 1/2 the queue size of HIDL. Once support is added to AIDL, this restriction can be
613*be431cd8SAndroid Build Coastguard Worker // lifted. Until then, check against SSIZE_MAX instead of SIZE_MAX.
TEST_F(AidlOnlyBadQueueConfig,QueueSizeTooLargeForAidl)614*be431cd8SAndroid Build Coastguard Worker TEST_F(AidlOnlyBadQueueConfig, QueueSizeTooLargeForAidl) {
615*be431cd8SAndroid Build Coastguard Worker size_t numElementsInQueue = SSIZE_MAX / sizeof(uint16_t) + 1;
616*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq(numElementsInQueue);
617*be431cd8SAndroid Build Coastguard Worker /*
618*be431cd8SAndroid Build Coastguard Worker * Should fail due to size being too large to fit into size_t.
619*be431cd8SAndroid Build Coastguard Worker */
620*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(fmq.isValid());
621*be431cd8SAndroid Build Coastguard Worker }
622*be431cd8SAndroid Build Coastguard Worker
TEST_F(AidlOnlyBadQueueConfig,NegativeAidlDescriptor)623*be431cd8SAndroid Build Coastguard Worker TEST_F(AidlOnlyBadQueueConfig, NegativeAidlDescriptor) {
624*be431cd8SAndroid Build Coastguard Worker aidl::android::hardware::common::fmq::MQDescriptor<uint16_t, SynchronizedReadWrite> desc;
625*be431cd8SAndroid Build Coastguard Worker desc.quantum = -10;
626*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq(desc);
627*be431cd8SAndroid Build Coastguard Worker /*
628*be431cd8SAndroid Build Coastguard Worker * Should fail due to quantum being negative.
629*be431cd8SAndroid Build Coastguard Worker */
630*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(fmq.isValid());
631*be431cd8SAndroid Build Coastguard Worker }
632*be431cd8SAndroid Build Coastguard Worker
TEST_F(AidlOnlyBadQueueConfig,NegativeAidlDescriptorGrantor)633*be431cd8SAndroid Build Coastguard Worker TEST_F(AidlOnlyBadQueueConfig, NegativeAidlDescriptorGrantor) {
634*be431cd8SAndroid Build Coastguard Worker aidl::android::hardware::common::fmq::MQDescriptor<uint16_t, SynchronizedReadWrite> desc;
635*be431cd8SAndroid Build Coastguard Worker desc.quantum = 2;
636*be431cd8SAndroid Build Coastguard Worker desc.flags = 0;
637*be431cd8SAndroid Build Coastguard Worker desc.grantors.push_back(
638*be431cd8SAndroid Build Coastguard Worker aidl::android::hardware::common::fmq::GrantorDescriptor{.offset = 12, .extent = -10});
639*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq(desc);
640*be431cd8SAndroid Build Coastguard Worker /*
641*be431cd8SAndroid Build Coastguard Worker * Should fail due to grantor having negative extent.
642*be431cd8SAndroid Build Coastguard Worker */
643*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(fmq.isValid());
644*be431cd8SAndroid Build Coastguard Worker }
645*be431cd8SAndroid Build Coastguard Worker
646*be431cd8SAndroid Build Coastguard Worker /*
647*be431cd8SAndroid Build Coastguard Worker * Test creating a new queue from a modified MQDescriptor of another queue.
648*be431cd8SAndroid Build Coastguard Worker * If MQDescriptor.quantum doesn't match the size of the payload(T), the queue
649*be431cd8SAndroid Build Coastguard Worker * should be invalid.
650*be431cd8SAndroid Build Coastguard Worker */
TEST_F(AidlOnlyBadQueueConfig,MismatchedPayloadSize)651*be431cd8SAndroid Build Coastguard Worker TEST_F(AidlOnlyBadQueueConfig, MismatchedPayloadSize) {
652*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq = AidlMessageQueueSync16(64);
653*be431cd8SAndroid Build Coastguard Worker aidl::android::hardware::common::fmq::MQDescriptor<uint16_t, SynchronizedReadWrite> desc =
654*be431cd8SAndroid Build Coastguard Worker fmq.dupeDesc();
655*be431cd8SAndroid Build Coastguard Worker // This should work fine with the unmodified MQDescriptor
656*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq2 = AidlMessageQueueSync16(desc);
657*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(fmq2.isValid());
658*be431cd8SAndroid Build Coastguard Worker
659*be431cd8SAndroid Build Coastguard Worker // Simulate a difference in payload size between processes handling the queue
660*be431cd8SAndroid Build Coastguard Worker desc.quantum = 8;
661*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq3 = AidlMessageQueueSync16(desc);
662*be431cd8SAndroid Build Coastguard Worker
663*be431cd8SAndroid Build Coastguard Worker // Should fail due to the quantum not matching the sizeof(uint16_t)
664*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(fmq3.isValid());
665*be431cd8SAndroid Build Coastguard Worker }
666*be431cd8SAndroid Build Coastguard Worker
667*be431cd8SAndroid Build Coastguard Worker /*
668*be431cd8SAndroid Build Coastguard Worker * Test creating a new queue with an invalid fd. This should assert with message
669*be431cd8SAndroid Build Coastguard Worker * "mRing is null".
670*be431cd8SAndroid Build Coastguard Worker */
TEST_F(DoubleFdFailures,InvalidFd)671*be431cd8SAndroid Build Coastguard Worker TEST_F(DoubleFdFailures, InvalidFd) {
672*be431cd8SAndroid Build Coastguard Worker android::base::SetLogger(android::base::StdioLogger);
673*be431cd8SAndroid Build Coastguard Worker auto queue = AidlMessageQueueSync(64, false, android::base::unique_fd(3000), 64);
674*be431cd8SAndroid Build Coastguard Worker EXPECT_FALSE(queue.isValid());
675*be431cd8SAndroid Build Coastguard Worker }
676*be431cd8SAndroid Build Coastguard Worker
677*be431cd8SAndroid Build Coastguard Worker /*
678*be431cd8SAndroid Build Coastguard Worker * Test creating a new queue with a buffer fd and bufferSize smaller than the
679*be431cd8SAndroid Build Coastguard Worker * requested queue. This should fail to create a valid message queue.
680*be431cd8SAndroid Build Coastguard Worker */
TEST_F(DoubleFdFailures,InvalidFdSize)681*be431cd8SAndroid Build Coastguard Worker TEST_F(DoubleFdFailures, InvalidFdSize) {
682*be431cd8SAndroid Build Coastguard Worker constexpr size_t kNumElementsInQueue = 1024;
683*be431cd8SAndroid Build Coastguard Worker constexpr size_t kRequiredDataBufferSize = kNumElementsInQueue * sizeof(uint16_t);
684*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(
685*be431cd8SAndroid Build Coastguard Worker ::ashmem_create_region("SyncReadWrite", kRequiredDataBufferSize - 8));
686*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq = AidlMessageQueueSync16(
687*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue, false, std::move(ringbufferFd), kRequiredDataBufferSize - 8);
688*be431cd8SAndroid Build Coastguard Worker EXPECT_FALSE(fmq.isValid());
689*be431cd8SAndroid Build Coastguard Worker }
690*be431cd8SAndroid Build Coastguard Worker
691*be431cd8SAndroid Build Coastguard Worker /*
692*be431cd8SAndroid Build Coastguard Worker * Test creating a new queue with a buffer fd and bufferSize larger than the
693*be431cd8SAndroid Build Coastguard Worker * requested queue. The message queue should be valid.
694*be431cd8SAndroid Build Coastguard Worker */
TEST_F(DoubleFdFailures,LargerFdSize)695*be431cd8SAndroid Build Coastguard Worker TEST_F(DoubleFdFailures, LargerFdSize) {
696*be431cd8SAndroid Build Coastguard Worker constexpr size_t kNumElementsInQueue = 1024;
697*be431cd8SAndroid Build Coastguard Worker constexpr size_t kRequiredDataBufferSize = kNumElementsInQueue * sizeof(uint16_t);
698*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd ringbufferFd(
699*be431cd8SAndroid Build Coastguard Worker ::ashmem_create_region("SyncReadWrite", kRequiredDataBufferSize + 8));
700*be431cd8SAndroid Build Coastguard Worker AidlMessageQueueSync16 fmq = AidlMessageQueueSync16(
701*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue, false, std::move(ringbufferFd), kRequiredDataBufferSize + 8);
702*be431cd8SAndroid Build Coastguard Worker EXPECT_TRUE(fmq.isValid());
703*be431cd8SAndroid Build Coastguard Worker }
704*be431cd8SAndroid Build Coastguard Worker
705*be431cd8SAndroid Build Coastguard Worker /*
706*be431cd8SAndroid Build Coastguard Worker * Test that basic blocking works. This test uses the non-blocking read()/write()
707*be431cd8SAndroid Build Coastguard Worker * APIs.
708*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(BlockingReadWrites,SmallInputTest1)709*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(BlockingReadWrites, SmallInputTest1) {
710*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 64;
711*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen] = {0};
712*be431cd8SAndroid Build Coastguard Worker
713*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
714*be431cd8SAndroid Build Coastguard Worker android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
715*be431cd8SAndroid Build Coastguard Worker
716*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
717*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
718*be431cd8SAndroid Build Coastguard Worker
719*be431cd8SAndroid Build Coastguard Worker /*
720*be431cd8SAndroid Build Coastguard Worker * Start a thread that will try to read and block on kFmqNotEmpty.
721*be431cd8SAndroid Build Coastguard Worker */
722*be431cd8SAndroid Build Coastguard Worker std::thread Reader(BlockingReadWrites<TypeParam>::ReaderThreadBlocking, this->mQueue,
723*be431cd8SAndroid Build Coastguard Worker &this->mFw);
724*be431cd8SAndroid Build Coastguard Worker struct timespec waitTime = {0, 100 * 1000000};
725*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, nanosleep(&waitTime, NULL));
726*be431cd8SAndroid Build Coastguard Worker
727*be431cd8SAndroid Build Coastguard Worker /*
728*be431cd8SAndroid Build Coastguard Worker * After waiting for some time write into the FMQ
729*be431cd8SAndroid Build Coastguard Worker * and call Wake on kFmqNotEmpty.
730*be431cd8SAndroid Build Coastguard Worker */
731*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data, dataLen));
732*be431cd8SAndroid Build Coastguard Worker status = efGroup->wake(kFmqNotEmpty);
733*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
734*be431cd8SAndroid Build Coastguard Worker
735*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, nanosleep(&waitTime, NULL));
736*be431cd8SAndroid Build Coastguard Worker Reader.join();
737*be431cd8SAndroid Build Coastguard Worker
738*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
739*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
740*be431cd8SAndroid Build Coastguard Worker }
741*be431cd8SAndroid Build Coastguard Worker
742*be431cd8SAndroid Build Coastguard Worker /*
743*be431cd8SAndroid Build Coastguard Worker * Test that basic blocking works. This test uses the
744*be431cd8SAndroid Build Coastguard Worker * writeBlocking()/readBlocking() APIs.
745*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(BlockingReadWrites,SmallInputTest2)746*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(BlockingReadWrites, SmallInputTest2) {
747*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 64;
748*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen] = {0};
749*be431cd8SAndroid Build Coastguard Worker
750*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
751*be431cd8SAndroid Build Coastguard Worker android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
752*be431cd8SAndroid Build Coastguard Worker
753*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
754*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
755*be431cd8SAndroid Build Coastguard Worker
756*be431cd8SAndroid Build Coastguard Worker /*
757*be431cd8SAndroid Build Coastguard Worker * Start a thread that will try to read and block on kFmqNotEmpty. It will
758*be431cd8SAndroid Build Coastguard Worker * call wake() on kFmqNotFull when the read is successful.
759*be431cd8SAndroid Build Coastguard Worker */
760*be431cd8SAndroid Build Coastguard Worker std::thread Reader(BlockingReadWrites<TypeParam>::ReaderThreadBlocking2, this->mQueue,
761*be431cd8SAndroid Build Coastguard Worker &this->mFw);
762*be431cd8SAndroid Build Coastguard Worker bool ret = this->mQueue->writeBlocking(data, dataLen, static_cast<uint32_t>(kFmqNotFull),
763*be431cd8SAndroid Build Coastguard Worker static_cast<uint32_t>(kFmqNotEmpty),
764*be431cd8SAndroid Build Coastguard Worker 5000000000 /* timeOutNanos */, efGroup);
765*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(ret);
766*be431cd8SAndroid Build Coastguard Worker Reader.join();
767*be431cd8SAndroid Build Coastguard Worker
768*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
769*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
770*be431cd8SAndroid Build Coastguard Worker }
771*be431cd8SAndroid Build Coastguard Worker
772*be431cd8SAndroid Build Coastguard Worker /*
773*be431cd8SAndroid Build Coastguard Worker * Test that basic blocking times out as intended.
774*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(BlockingReadWrites,BlockingTimeOutTest)775*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(BlockingReadWrites, BlockingTimeOutTest) {
776*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
777*be431cd8SAndroid Build Coastguard Worker android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
778*be431cd8SAndroid Build Coastguard Worker
779*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
780*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
781*be431cd8SAndroid Build Coastguard Worker
782*be431cd8SAndroid Build Coastguard Worker /* Block on an EventFlag bit that no one will wake and time out in 1s */
783*be431cd8SAndroid Build Coastguard Worker uint32_t efState = 0;
784*be431cd8SAndroid Build Coastguard Worker android::status_t ret = efGroup->wait(kFmqNotEmpty,
785*be431cd8SAndroid Build Coastguard Worker &efState,
786*be431cd8SAndroid Build Coastguard Worker 1000000000 /* timeoutNanoSeconds */);
787*be431cd8SAndroid Build Coastguard Worker /*
788*be431cd8SAndroid Build Coastguard Worker * Wait should time out in a second.
789*be431cd8SAndroid Build Coastguard Worker */
790*be431cd8SAndroid Build Coastguard Worker EXPECT_EQ(android::TIMED_OUT, ret);
791*be431cd8SAndroid Build Coastguard Worker
792*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
793*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
794*be431cd8SAndroid Build Coastguard Worker }
795*be431cd8SAndroid Build Coastguard Worker
796*be431cd8SAndroid Build Coastguard Worker /*
797*be431cd8SAndroid Build Coastguard Worker * Test EventFlag wait on a waked flag with a short timeout.
798*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(BlockingReadWrites,ShortEventFlagWaitWithWakeTest)799*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(BlockingReadWrites, ShortEventFlagWaitWithWakeTest) {
800*be431cd8SAndroid Build Coastguard Worker std::atomic<uint32_t> eventFlagWord;
801*be431cd8SAndroid Build Coastguard Worker std::atomic_init(&eventFlagWord, static_cast<uint32_t>(kFmqNotFull));
802*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
803*be431cd8SAndroid Build Coastguard Worker android::status_t status =
804*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag::createEventFlag(&eventFlagWord, &efGroup);
805*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
806*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
807*be431cd8SAndroid Build Coastguard Worker
808*be431cd8SAndroid Build Coastguard Worker status = efGroup->wake(kFmqNotEmpty);
809*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
810*be431cd8SAndroid Build Coastguard Worker
811*be431cd8SAndroid Build Coastguard Worker uint32_t efState = 0;
812*be431cd8SAndroid Build Coastguard Worker android::status_t ret = efGroup->wait(kFmqNotEmpty, &efState, 1 /* ns */, true /* retry */);
813*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, ret);
814*be431cd8SAndroid Build Coastguard Worker
815*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
816*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
817*be431cd8SAndroid Build Coastguard Worker }
818*be431cd8SAndroid Build Coastguard Worker
819*be431cd8SAndroid Build Coastguard Worker /*
820*be431cd8SAndroid Build Coastguard Worker * Test on an EventFlag with no wakeup, short timeout.
821*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(BlockingReadWrites,ShortEventFlagWaitWithoutWakeTest)822*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(BlockingReadWrites, ShortEventFlagWaitWithoutWakeTest) {
823*be431cd8SAndroid Build Coastguard Worker std::atomic<uint32_t> eventFlagWord;
824*be431cd8SAndroid Build Coastguard Worker std::atomic_init(&eventFlagWord, static_cast<uint32_t>(kFmqNotFull));
825*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
826*be431cd8SAndroid Build Coastguard Worker android::status_t status =
827*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag::createEventFlag(&eventFlagWord, &efGroup);
828*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
829*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
830*be431cd8SAndroid Build Coastguard Worker
831*be431cd8SAndroid Build Coastguard Worker uint32_t efState = 0;
832*be431cd8SAndroid Build Coastguard Worker android::status_t ret = efGroup->wait(kFmqNotEmpty, &efState, 1 /* ns */, true /* retry */);
833*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::TIMED_OUT, ret);
834*be431cd8SAndroid Build Coastguard Worker
835*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
836*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
837*be431cd8SAndroid Build Coastguard Worker }
838*be431cd8SAndroid Build Coastguard Worker
839*be431cd8SAndroid Build Coastguard Worker /*
840*be431cd8SAndroid Build Coastguard Worker * Test FMQ write and read with event flag wait.
841*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(BlockingReadWrites,FmqWriteAndReadWithShortEventFlagWaitTest)842*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(BlockingReadWrites, FmqWriteAndReadWithShortEventFlagWaitTest) {
843*be431cd8SAndroid Build Coastguard Worker android::hardware::EventFlag* efGroup = nullptr;
844*be431cd8SAndroid Build Coastguard Worker android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
845*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
846*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(nullptr, efGroup);
847*be431cd8SAndroid Build Coastguard Worker
848*be431cd8SAndroid Build Coastguard Worker /*
849*be431cd8SAndroid Build Coastguard Worker * After waiting for some time write into the FMQ
850*be431cd8SAndroid Build Coastguard Worker * and call Wake on kFmqNotEmpty.
851*be431cd8SAndroid Build Coastguard Worker */
852*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 16;
853*be431cd8SAndroid Build Coastguard Worker uint8_t dataW[dataLen] = {0};
854*be431cd8SAndroid Build Coastguard Worker uint8_t dataR[dataLen] = {0};
855*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(dataW, dataLen));
856*be431cd8SAndroid Build Coastguard Worker status = efGroup->wake(kFmqNotEmpty);
857*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
858*be431cd8SAndroid Build Coastguard Worker
859*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->readBlocking(dataR, dataLen, static_cast<uint32_t>(kFmqNotEmpty),
860*be431cd8SAndroid Build Coastguard Worker static_cast<uint32_t>(kFmqNotFull), 1 /* timeOutNanos */,
861*be431cd8SAndroid Build Coastguard Worker efGroup));
862*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(dataW, dataR, dataLen));
863*be431cd8SAndroid Build Coastguard Worker
864*be431cd8SAndroid Build Coastguard Worker status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
865*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(android::NO_ERROR, status);
866*be431cd8SAndroid Build Coastguard Worker }
867*be431cd8SAndroid Build Coastguard Worker
868*be431cd8SAndroid Build Coastguard Worker /*
869*be431cd8SAndroid Build Coastguard Worker * Test that odd queue sizes do not cause unaligned error
870*be431cd8SAndroid Build Coastguard Worker * on access to EventFlag object.
871*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(QueueSizeOdd,EventFlagTest)872*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(QueueSizeOdd, EventFlagTest) {
873*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 64;
874*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen] = {0};
875*be431cd8SAndroid Build Coastguard Worker
876*be431cd8SAndroid Build Coastguard Worker bool ret = this->mQueue->writeBlocking(data, dataLen, static_cast<uint32_t>(kFmqNotFull),
877*be431cd8SAndroid Build Coastguard Worker static_cast<uint32_t>(kFmqNotEmpty),
878*be431cd8SAndroid Build Coastguard Worker 5000000000 /* timeOutNanos */);
879*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(ret);
880*be431cd8SAndroid Build Coastguard Worker }
881*be431cd8SAndroid Build Coastguard Worker
882*be431cd8SAndroid Build Coastguard Worker /*
883*be431cd8SAndroid Build Coastguard Worker * Verify that a few bytes of data can be successfully written and read.
884*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,SmallInputTest1)885*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, SmallInputTest1) {
886*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 16;
887*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
888*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
889*be431cd8SAndroid Build Coastguard Worker
890*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
891*be431cd8SAndroid Build Coastguard Worker
892*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data, dataLen));
893*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
894*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData, dataLen));
895*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(data, readData, dataLen));
896*be431cd8SAndroid Build Coastguard Worker }
897*be431cd8SAndroid Build Coastguard Worker
898*be431cd8SAndroid Build Coastguard Worker /*
899*be431cd8SAndroid Build Coastguard Worker * Verify that a few bytes of data can be successfully written and read using
900*be431cd8SAndroid Build Coastguard Worker * beginRead/beginWrite/CommitRead/CommitWrite
901*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,SmallInputTest2)902*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, SmallInputTest2) {
903*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 16;
904*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
905*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
906*be431cd8SAndroid Build Coastguard Worker
907*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
908*be431cd8SAndroid Build Coastguard Worker
909*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
910*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
911*be431cd8SAndroid Build Coastguard Worker
912*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(tx.copyTo(data, 0 /* startIdx */, dataLen));
913*be431cd8SAndroid Build Coastguard Worker
914*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
915*be431cd8SAndroid Build Coastguard Worker
916*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
917*be431cd8SAndroid Build Coastguard Worker
918*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
919*be431cd8SAndroid Build Coastguard Worker
920*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(tx.copyFrom(readData, 0 /* startIdx */, dataLen));
921*be431cd8SAndroid Build Coastguard Worker
922*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->commitRead(dataLen));
923*be431cd8SAndroid Build Coastguard Worker
924*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(data, readData, dataLen));
925*be431cd8SAndroid Build Coastguard Worker }
926*be431cd8SAndroid Build Coastguard Worker
927*be431cd8SAndroid Build Coastguard Worker /*
928*be431cd8SAndroid Build Coastguard Worker * Verify that a few bytes of data can be successfully written and read using
929*be431cd8SAndroid Build Coastguard Worker * beginRead/beginWrite/CommitRead/CommitWrite as well as getSlot().
930*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,SmallInputTest3)931*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, SmallInputTest3) {
932*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 16;
933*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
934*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
935*be431cd8SAndroid Build Coastguard Worker
936*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
937*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
938*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
939*be431cd8SAndroid Build Coastguard Worker
940*be431cd8SAndroid Build Coastguard Worker auto first = tx.getFirstRegion();
941*be431cd8SAndroid Build Coastguard Worker auto second = tx.getSecondRegion();
942*be431cd8SAndroid Build Coastguard Worker
943*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(first.getLength() + second.getLength(), dataLen);
944*be431cd8SAndroid Build Coastguard Worker for (size_t i = 0; i < dataLen; i++) {
945*be431cd8SAndroid Build Coastguard Worker uint8_t* ptr = tx.getSlot(i);
946*be431cd8SAndroid Build Coastguard Worker *ptr = data[i];
947*be431cd8SAndroid Build Coastguard Worker }
948*be431cd8SAndroid Build Coastguard Worker
949*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
950*be431cd8SAndroid Build Coastguard Worker
951*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
952*be431cd8SAndroid Build Coastguard Worker
953*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
954*be431cd8SAndroid Build Coastguard Worker
955*be431cd8SAndroid Build Coastguard Worker first = tx.getFirstRegion();
956*be431cd8SAndroid Build Coastguard Worker second = tx.getSecondRegion();
957*be431cd8SAndroid Build Coastguard Worker
958*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(first.getLength() + second.getLength(), dataLen);
959*be431cd8SAndroid Build Coastguard Worker
960*be431cd8SAndroid Build Coastguard Worker for (size_t i = 0; i < dataLen; i++) {
961*be431cd8SAndroid Build Coastguard Worker uint8_t* ptr = tx.getSlot(i);
962*be431cd8SAndroid Build Coastguard Worker readData[i] = *ptr;
963*be431cd8SAndroid Build Coastguard Worker }
964*be431cd8SAndroid Build Coastguard Worker
965*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->commitRead(dataLen));
966*be431cd8SAndroid Build Coastguard Worker
967*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(data, readData, dataLen));
968*be431cd8SAndroid Build Coastguard Worker }
969*be431cd8SAndroid Build Coastguard Worker
970*be431cd8SAndroid Build Coastguard Worker /*
971*be431cd8SAndroid Build Coastguard Worker * Verify that read() returns false when trying to read from an empty queue.
972*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,ReadWhenEmpty1)973*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, ReadWhenEmpty1) {
974*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
975*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 2;
976*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
977*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen];
978*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(readData, dataLen));
979*be431cd8SAndroid Build Coastguard Worker }
980*be431cd8SAndroid Build Coastguard Worker
981*be431cd8SAndroid Build Coastguard Worker /*
982*be431cd8SAndroid Build Coastguard Worker * Verify that beginRead() returns a MemTransaction object with null pointers when trying
983*be431cd8SAndroid Build Coastguard Worker * to read from an empty queue.
984*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,ReadWhenEmpty2)985*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, ReadWhenEmpty2) {
986*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
987*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 2;
988*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
989*be431cd8SAndroid Build Coastguard Worker
990*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
991*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->beginRead(dataLen, &tx));
992*be431cd8SAndroid Build Coastguard Worker
993*be431cd8SAndroid Build Coastguard Worker auto first = tx.getFirstRegion();
994*be431cd8SAndroid Build Coastguard Worker auto second = tx.getSecondRegion();
995*be431cd8SAndroid Build Coastguard Worker
996*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, first.getAddress());
997*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, second.getAddress());
998*be431cd8SAndroid Build Coastguard Worker }
999*be431cd8SAndroid Build Coastguard Worker
1000*be431cd8SAndroid Build Coastguard Worker /*
1001*be431cd8SAndroid Build Coastguard Worker * Write the queue until full. Verify that another write is unsuccessful.
1002*be431cd8SAndroid Build Coastguard Worker * Verify that availableToWrite() returns 0 as expected.
1003*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,WriteWhenFull1)1004*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, WriteWhenFull1) {
1005*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1006*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1007*be431cd8SAndroid Build Coastguard Worker
1008*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1009*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1010*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToWrite());
1011*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->write(&data[0], 1));
1012*be431cd8SAndroid Build Coastguard Worker
1013*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1014*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1015*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data, readData);
1016*be431cd8SAndroid Build Coastguard Worker }
1017*be431cd8SAndroid Build Coastguard Worker
1018*be431cd8SAndroid Build Coastguard Worker /*
1019*be431cd8SAndroid Build Coastguard Worker * Write the queue until full. Verify that beginWrite() returns
1020*be431cd8SAndroid Build Coastguard Worker * a MemTransaction object with null base pointers.
1021*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,WriteWhenFull2)1022*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, WriteWhenFull2) {
1023*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1024*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1025*be431cd8SAndroid Build Coastguard Worker
1026*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1027*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1028*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToWrite());
1029*be431cd8SAndroid Build Coastguard Worker
1030*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
1031*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->beginWrite(1, &tx));
1032*be431cd8SAndroid Build Coastguard Worker
1033*be431cd8SAndroid Build Coastguard Worker auto first = tx.getFirstRegion();
1034*be431cd8SAndroid Build Coastguard Worker auto second = tx.getSecondRegion();
1035*be431cd8SAndroid Build Coastguard Worker
1036*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, first.getAddress());
1037*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, second.getAddress());
1038*be431cd8SAndroid Build Coastguard Worker }
1039*be431cd8SAndroid Build Coastguard Worker
1040*be431cd8SAndroid Build Coastguard Worker /*
1041*be431cd8SAndroid Build Coastguard Worker * Write a chunk of data equal to the queue size.
1042*be431cd8SAndroid Build Coastguard Worker * Verify that the write is successful and the subsequent read
1043*be431cd8SAndroid Build Coastguard Worker * returns the expected data.
1044*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,LargeInputTest1)1045*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, LargeInputTest1) {
1046*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1047*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1048*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1049*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1050*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1051*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data, readData);
1052*be431cd8SAndroid Build Coastguard Worker }
1053*be431cd8SAndroid Build Coastguard Worker
1054*be431cd8SAndroid Build Coastguard Worker /*
1055*be431cd8SAndroid Build Coastguard Worker * Attempt to write a chunk of data larger than the queue size.
1056*be431cd8SAndroid Build Coastguard Worker * Verify that it fails. Verify that a subsequent read fails and
1057*be431cd8SAndroid Build Coastguard Worker * the queue is still empty.
1058*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,LargeInputTest2)1059*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, LargeInputTest2) {
1060*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1061*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 4096;
1062*be431cd8SAndroid Build Coastguard Worker ASSERT_GT(dataLen, this->mNumMessagesMax);
1063*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(dataLen);
1064*be431cd8SAndroid Build Coastguard Worker
1065*be431cd8SAndroid Build Coastguard Worker initData(&data[0], dataLen);
1066*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->write(&data[0], dataLen));
1067*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1068*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1069*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(data, readData);
1070*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1071*be431cd8SAndroid Build Coastguard Worker }
1072*be431cd8SAndroid Build Coastguard Worker
1073*be431cd8SAndroid Build Coastguard Worker /*
1074*be431cd8SAndroid Build Coastguard Worker * After the queue is full, try to write more data. Verify that
1075*be431cd8SAndroid Build Coastguard Worker * the attempt returns false. Verify that the attempt did not
1076*be431cd8SAndroid Build Coastguard Worker * affect the pre-existing data in the queue.
1077*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,LargeInputTest3)1078*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, LargeInputTest3) {
1079*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1080*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1081*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1082*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->write(&data[0], 1));
1083*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1084*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1085*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data, readData);
1086*be431cd8SAndroid Build Coastguard Worker }
1087*be431cd8SAndroid Build Coastguard Worker
1088*be431cd8SAndroid Build Coastguard Worker /*
1089*be431cd8SAndroid Build Coastguard Worker * Verify that beginWrite() returns a MemTransaction with
1090*be431cd8SAndroid Build Coastguard Worker * null base pointers when attempting to write data larger
1091*be431cd8SAndroid Build Coastguard Worker * than the queue size.
1092*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,LargeInputTest4)1093*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, LargeInputTest4) {
1094*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1095*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 4096;
1096*be431cd8SAndroid Build Coastguard Worker ASSERT_GT(dataLen, this->mNumMessagesMax);
1097*be431cd8SAndroid Build Coastguard Worker
1098*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
1099*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->beginWrite(dataLen, &tx));
1100*be431cd8SAndroid Build Coastguard Worker
1101*be431cd8SAndroid Build Coastguard Worker auto first = tx.getFirstRegion();
1102*be431cd8SAndroid Build Coastguard Worker auto second = tx.getSecondRegion();
1103*be431cd8SAndroid Build Coastguard Worker
1104*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, first.getAddress());
1105*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, second.getAddress());
1106*be431cd8SAndroid Build Coastguard Worker }
1107*be431cd8SAndroid Build Coastguard Worker
1108*be431cd8SAndroid Build Coastguard Worker /*
1109*be431cd8SAndroid Build Coastguard Worker * Verify that multiple reads one after the other return expected data.
1110*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,MultipleRead)1111*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, MultipleRead) {
1112*be431cd8SAndroid Build Coastguard Worker const size_t chunkSize = 100;
1113*be431cd8SAndroid Build Coastguard Worker const size_t chunkNum = 5;
1114*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = chunkSize * chunkNum;
1115*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
1116*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
1117*be431cd8SAndroid Build Coastguard Worker
1118*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
1119*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data, dataLen));
1120*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
1121*be431cd8SAndroid Build Coastguard Worker for (size_t i = 0; i < chunkNum; i++) {
1122*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
1123*be431cd8SAndroid Build Coastguard Worker }
1124*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(readData, data, dataLen));
1125*be431cd8SAndroid Build Coastguard Worker }
1126*be431cd8SAndroid Build Coastguard Worker
1127*be431cd8SAndroid Build Coastguard Worker /*
1128*be431cd8SAndroid Build Coastguard Worker * Verify that multiple writes one after the other happens correctly.
1129*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,MultipleWrite)1130*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, MultipleWrite) {
1131*be431cd8SAndroid Build Coastguard Worker const int chunkSize = 100;
1132*be431cd8SAndroid Build Coastguard Worker const int chunkNum = 5;
1133*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = chunkSize * chunkNum;
1134*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
1135*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
1136*be431cd8SAndroid Build Coastguard Worker
1137*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
1138*be431cd8SAndroid Build Coastguard Worker for (unsigned int i = 0; i < chunkNum; i++) {
1139*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
1140*be431cd8SAndroid Build Coastguard Worker }
1141*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
1142*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData, dataLen));
1143*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(readData, data, dataLen));
1144*be431cd8SAndroid Build Coastguard Worker }
1145*be431cd8SAndroid Build Coastguard Worker
1146*be431cd8SAndroid Build Coastguard Worker /*
1147*be431cd8SAndroid Build Coastguard Worker * Write enough messages into the FMQ to fill half of it
1148*be431cd8SAndroid Build Coastguard Worker * and read back the same.
1149*be431cd8SAndroid Build Coastguard Worker * Write this->mNumMessagesMax messages into the queue. This will cause a
1150*be431cd8SAndroid Build Coastguard Worker * wrap around. Read and verify the data.
1151*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,ReadWriteWrapAround1)1152*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, ReadWriteWrapAround1) {
1153*be431cd8SAndroid Build Coastguard Worker size_t numMessages = this->mNumMessagesMax - 1;
1154*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1155*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1156*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1157*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
1158*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], numMessages));
1159*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1160*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1161*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data, readData);
1162*be431cd8SAndroid Build Coastguard Worker }
1163*be431cd8SAndroid Build Coastguard Worker
1164*be431cd8SAndroid Build Coastguard Worker /*
1165*be431cd8SAndroid Build Coastguard Worker * Use beginRead/CommitRead/beginWrite/commitWrite APIs
1166*be431cd8SAndroid Build Coastguard Worker * to test wrap arounds are handled correctly.
1167*be431cd8SAndroid Build Coastguard Worker * Write enough messages into the FMQ to fill half of it
1168*be431cd8SAndroid Build Coastguard Worker * and read back the same.
1169*be431cd8SAndroid Build Coastguard Worker * Write mNumMessagesMax messages into the queue. This will cause a
1170*be431cd8SAndroid Build Coastguard Worker * wrap around. Read and verify the data.
1171*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(SynchronizedReadWrites,ReadWriteWrapAround2)1172*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWrites, ReadWriteWrapAround2) {
1173*be431cd8SAndroid Build Coastguard Worker size_t dataLen = this->mNumMessagesMax - 1;
1174*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1175*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1176*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1177*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], dataLen));
1178*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], dataLen));
1179*be431cd8SAndroid Build Coastguard Worker
1180*be431cd8SAndroid Build Coastguard Worker /*
1181*be431cd8SAndroid Build Coastguard Worker * The next write and read will have to deal with with wrap arounds.
1182*be431cd8SAndroid Build Coastguard Worker */
1183*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
1184*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginWrite(this->mNumMessagesMax, &tx));
1185*be431cd8SAndroid Build Coastguard Worker
1186*be431cd8SAndroid Build Coastguard Worker auto first = tx.getFirstRegion();
1187*be431cd8SAndroid Build Coastguard Worker auto second = tx.getSecondRegion();
1188*be431cd8SAndroid Build Coastguard Worker
1189*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(first.getLength() + second.getLength(), this->mNumMessagesMax);
1190*be431cd8SAndroid Build Coastguard Worker
1191*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */, this->mNumMessagesMax));
1192*be431cd8SAndroid Build Coastguard Worker
1193*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->commitWrite(this->mNumMessagesMax));
1194*be431cd8SAndroid Build Coastguard Worker
1195*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginRead(this->mNumMessagesMax, &tx));
1196*be431cd8SAndroid Build Coastguard Worker
1197*be431cd8SAndroid Build Coastguard Worker first = tx.getFirstRegion();
1198*be431cd8SAndroid Build Coastguard Worker second = tx.getSecondRegion();
1199*be431cd8SAndroid Build Coastguard Worker
1200*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(first.getLength() + second.getLength(), this->mNumMessagesMax);
1201*be431cd8SAndroid Build Coastguard Worker
1202*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(tx.copyFrom(&readData[0], 0 /* startIdx */, this->mNumMessagesMax));
1203*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->commitRead(this->mNumMessagesMax));
1204*be431cd8SAndroid Build Coastguard Worker
1205*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data, readData);
1206*be431cd8SAndroid Build Coastguard Worker }
1207*be431cd8SAndroid Build Coastguard Worker
1208*be431cd8SAndroid Build Coastguard Worker /*
1209*be431cd8SAndroid Build Coastguard Worker * Verify that a few bytes of data can be successfully written and read.
1210*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,SmallInputTest1)1211*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, SmallInputTest1) {
1212*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 16;
1213*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
1214*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
1215*be431cd8SAndroid Build Coastguard Worker
1216*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
1217*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data, dataLen));
1218*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
1219*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData, dataLen));
1220*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(data, readData, dataLen));
1221*be431cd8SAndroid Build Coastguard Worker }
1222*be431cd8SAndroid Build Coastguard Worker
1223*be431cd8SAndroid Build Coastguard Worker /*
1224*be431cd8SAndroid Build Coastguard Worker * Verify that read() returns false when trying to read from an empty queue.
1225*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,ReadWhenEmpty)1226*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, ReadWhenEmpty) {
1227*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1228*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 2;
1229*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(dataLen < this->mNumMessagesMax);
1230*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen];
1231*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(readData, dataLen));
1232*be431cd8SAndroid Build Coastguard Worker }
1233*be431cd8SAndroid Build Coastguard Worker
1234*be431cd8SAndroid Build Coastguard Worker /*
1235*be431cd8SAndroid Build Coastguard Worker * Write the queue when full. Verify that a subsequent writes is succesful.
1236*be431cd8SAndroid Build Coastguard Worker * Verify that availableToWrite() returns 0 as expected.
1237*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,WriteWhenFull1)1238*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, WriteWhenFull1) {
1239*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1240*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1241*be431cd8SAndroid Build Coastguard Worker
1242*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1243*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1244*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToWrite());
1245*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1246*be431cd8SAndroid Build Coastguard Worker
1247*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1248*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1249*be431cd8SAndroid Build Coastguard Worker }
1250*be431cd8SAndroid Build Coastguard Worker
1251*be431cd8SAndroid Build Coastguard Worker /*
1252*be431cd8SAndroid Build Coastguard Worker * Write the queue when full. Verify that a subsequent writes
1253*be431cd8SAndroid Build Coastguard Worker * using beginRead()/commitRead() is succesful.
1254*be431cd8SAndroid Build Coastguard Worker * Verify that the next read fails as expected for unsynchronized flavor.
1255*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,WriteWhenFull2)1256*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, WriteWhenFull2) {
1257*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1258*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1259*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1260*be431cd8SAndroid Build Coastguard Worker
1261*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
1262*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginWrite(1, &tx));
1263*be431cd8SAndroid Build Coastguard Worker
1264*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(tx.getFirstRegion().getLength(), 1U);
1265*be431cd8SAndroid Build Coastguard Worker
1266*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */));
1267*be431cd8SAndroid Build Coastguard Worker
1268*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->commitWrite(1));
1269*be431cd8SAndroid Build Coastguard Worker
1270*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1271*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1272*be431cd8SAndroid Build Coastguard Worker }
1273*be431cd8SAndroid Build Coastguard Worker
1274*be431cd8SAndroid Build Coastguard Worker /*
1275*be431cd8SAndroid Build Coastguard Worker * Write a chunk of data equal to the queue size.
1276*be431cd8SAndroid Build Coastguard Worker * Verify that the write is successful and the subsequent read
1277*be431cd8SAndroid Build Coastguard Worker * returns the expected data.
1278*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,LargeInputTest1)1279*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, LargeInputTest1) {
1280*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1281*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1282*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1283*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1284*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1285*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data, readData);
1286*be431cd8SAndroid Build Coastguard Worker }
1287*be431cd8SAndroid Build Coastguard Worker
1288*be431cd8SAndroid Build Coastguard Worker /*
1289*be431cd8SAndroid Build Coastguard Worker * Attempt to write a chunk of data larger than the queue size.
1290*be431cd8SAndroid Build Coastguard Worker * Verify that it fails. Verify that a subsequent read fails and
1291*be431cd8SAndroid Build Coastguard Worker * the queue is still empty.
1292*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,LargeInputTest2)1293*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, LargeInputTest2) {
1294*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1295*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = 4096;
1296*be431cd8SAndroid Build Coastguard Worker ASSERT_GT(dataLen, this->mNumMessagesMax);
1297*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(dataLen);
1298*be431cd8SAndroid Build Coastguard Worker initData(&data[0], dataLen);
1299*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->write(&data[0], dataLen));
1300*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1301*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1302*be431cd8SAndroid Build Coastguard Worker ASSERT_NE(data, readData);
1303*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0UL, this->mQueue->availableToRead());
1304*be431cd8SAndroid Build Coastguard Worker }
1305*be431cd8SAndroid Build Coastguard Worker
1306*be431cd8SAndroid Build Coastguard Worker /*
1307*be431cd8SAndroid Build Coastguard Worker * After the queue is full, try to write more data. Verify that
1308*be431cd8SAndroid Build Coastguard Worker * the attempt is succesful. Verify that the read fails
1309*be431cd8SAndroid Build Coastguard Worker * as expected.
1310*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,LargeInputTest3)1311*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, LargeInputTest3) {
1312*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1313*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1314*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1315*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1316*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1317*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1318*be431cd8SAndroid Build Coastguard Worker }
1319*be431cd8SAndroid Build Coastguard Worker
1320*be431cd8SAndroid Build Coastguard Worker /*
1321*be431cd8SAndroid Build Coastguard Worker * Verify that multiple reads one after the other return expected data.
1322*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,MultipleRead)1323*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, MultipleRead) {
1324*be431cd8SAndroid Build Coastguard Worker const size_t chunkSize = 100;
1325*be431cd8SAndroid Build Coastguard Worker const size_t chunkNum = 5;
1326*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = chunkSize * chunkNum;
1327*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
1328*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
1329*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
1330*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data, dataLen));
1331*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
1332*be431cd8SAndroid Build Coastguard Worker for (size_t i = 0; i < chunkNum; i++) {
1333*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
1334*be431cd8SAndroid Build Coastguard Worker }
1335*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(readData, data, dataLen));
1336*be431cd8SAndroid Build Coastguard Worker }
1337*be431cd8SAndroid Build Coastguard Worker
1338*be431cd8SAndroid Build Coastguard Worker /*
1339*be431cd8SAndroid Build Coastguard Worker * Verify that multiple writes one after the other happens correctly.
1340*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,MultipleWrite)1341*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, MultipleWrite) {
1342*be431cd8SAndroid Build Coastguard Worker const size_t chunkSize = 100;
1343*be431cd8SAndroid Build Coastguard Worker const size_t chunkNum = 5;
1344*be431cd8SAndroid Build Coastguard Worker const size_t dataLen = chunkSize * chunkNum;
1345*be431cd8SAndroid Build Coastguard Worker ASSERT_LE(dataLen, this->mNumMessagesMax);
1346*be431cd8SAndroid Build Coastguard Worker uint8_t data[dataLen];
1347*be431cd8SAndroid Build Coastguard Worker
1348*be431cd8SAndroid Build Coastguard Worker initData(data, dataLen);
1349*be431cd8SAndroid Build Coastguard Worker for (size_t i = 0; i < chunkNum; i++) {
1350*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
1351*be431cd8SAndroid Build Coastguard Worker }
1352*be431cd8SAndroid Build Coastguard Worker
1353*be431cd8SAndroid Build Coastguard Worker uint8_t readData[dataLen] = {};
1354*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData, dataLen));
1355*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(readData, data, dataLen));
1356*be431cd8SAndroid Build Coastguard Worker }
1357*be431cd8SAndroid Build Coastguard Worker
1358*be431cd8SAndroid Build Coastguard Worker /*
1359*be431cd8SAndroid Build Coastguard Worker * Write enough messages into the FMQ to fill half of it
1360*be431cd8SAndroid Build Coastguard Worker * and read back the same.
1361*be431cd8SAndroid Build Coastguard Worker * Write mNumMessagesMax messages into the queue. This will cause a
1362*be431cd8SAndroid Build Coastguard Worker * wrap around. Read and verify the data.
1363*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,ReadWriteWrapAround)1364*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, ReadWriteWrapAround) {
1365*be431cd8SAndroid Build Coastguard Worker size_t numMessages = this->mNumMessagesMax - 1;
1366*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1367*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax);
1368*be431cd8SAndroid Build Coastguard Worker
1369*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1370*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
1371*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], numMessages));
1372*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1373*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1374*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(data, readData);
1375*be431cd8SAndroid Build Coastguard Worker }
1376*be431cd8SAndroid Build Coastguard Worker
1377*be431cd8SAndroid Build Coastguard Worker /*
1378*be431cd8SAndroid Build Coastguard Worker * Attempt to read more than the maximum number of messages in the queue.
1379*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,ReadMoreThanNumMessagesMaxFails)1380*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, ReadMoreThanNumMessagesMaxFails) {
1381*be431cd8SAndroid Build Coastguard Worker // Fill the queue with data
1382*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(this->mNumMessagesMax);
1383*be431cd8SAndroid Build Coastguard Worker initData(data.data(), data.size());
1384*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
1385*be431cd8SAndroid Build Coastguard Worker
1386*be431cd8SAndroid Build Coastguard Worker // Attempt to read more than the maximum number of messages in the queue.
1387*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(this->mNumMessagesMax + 1);
1388*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(readData.data(), readData.size()));
1389*be431cd8SAndroid Build Coastguard Worker }
1390*be431cd8SAndroid Build Coastguard Worker
1391*be431cd8SAndroid Build Coastguard Worker /*
1392*be431cd8SAndroid Build Coastguard Worker * Write some data to the queue and attempt to read more than the available data.
1393*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedReadWriteTest,ReadMoreThanAvailableToReadFails)1394*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedReadWriteTest, ReadMoreThanAvailableToReadFails) {
1395*be431cd8SAndroid Build Coastguard Worker // Fill half of the queue with data.
1396*be431cd8SAndroid Build Coastguard Worker size_t dataLen = this->mNumMessagesMax / 2;
1397*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> data(dataLen);
1398*be431cd8SAndroid Build Coastguard Worker initData(data.data(), data.size());
1399*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
1400*be431cd8SAndroid Build Coastguard Worker
1401*be431cd8SAndroid Build Coastguard Worker // Attempt to read more than the available data.
1402*be431cd8SAndroid Build Coastguard Worker std::vector<uint8_t> readData(dataLen + 1);
1403*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(readData.data(), readData.size()));
1404*be431cd8SAndroid Build Coastguard Worker }
1405*be431cd8SAndroid Build Coastguard Worker
1406*be431cd8SAndroid Build Coastguard Worker /*
1407*be431cd8SAndroid Build Coastguard Worker * Ensure that the template specialization of MessageQueueBase to element types
1408*be431cd8SAndroid Build Coastguard Worker * other than MQErased exposes its static knowledge of element size.
1409*be431cd8SAndroid Build Coastguard Worker */
TEST(MessageQueueErasedTest,MQErasedCompiles)1410*be431cd8SAndroid Build Coastguard Worker TEST(MessageQueueErasedTest, MQErasedCompiles) {
1411*be431cd8SAndroid Build Coastguard Worker auto txn = AidlMessageQueueSync::MemRegion();
1412*be431cd8SAndroid Build Coastguard Worker txn.getLengthInBytes();
1413*be431cd8SAndroid Build Coastguard Worker }
1414*be431cd8SAndroid Build Coastguard Worker
1415*be431cd8SAndroid Build Coastguard Worker extern "C" uint8_t fmq_rust_test(void);
1416*be431cd8SAndroid Build Coastguard Worker
1417*be431cd8SAndroid Build Coastguard Worker /*
1418*be431cd8SAndroid Build Coastguard Worker * Test using the FMQ from Rust.
1419*be431cd8SAndroid Build Coastguard Worker */
TEST(RustInteropTest,Simple)1420*be431cd8SAndroid Build Coastguard Worker TEST(RustInteropTest, Simple) {
1421*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(fmq_rust_test(), 1);
1422*be431cd8SAndroid Build Coastguard Worker }
1423*be431cd8SAndroid Build Coastguard Worker
1424*be431cd8SAndroid Build Coastguard Worker /*
1425*be431cd8SAndroid Build Coastguard Worker * Verifies that after ring buffer overflow and first failed attempt to read
1426*be431cd8SAndroid Build Coastguard Worker * the whole ring buffer is available to read and old values was discarded.
1427*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedOverflowHistoryTest,ReadAfterOverflow)1428*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedOverflowHistoryTest, ReadAfterOverflow) {
1429*be431cd8SAndroid Build Coastguard Worker std::vector<uint16_t> data(this->mNumMessagesMax);
1430*be431cd8SAndroid Build Coastguard Worker
1431*be431cd8SAndroid Build Coastguard Worker // Fill the queue with monotonic pattern
1432*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1433*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1434*be431cd8SAndroid Build Coastguard Worker
1435*be431cd8SAndroid Build Coastguard Worker // Write more data (first element of the same data) to cause a wrap around
1436*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1437*be431cd8SAndroid Build Coastguard Worker
1438*be431cd8SAndroid Build Coastguard Worker // Attempt a read (this should fail due to how UnsynchronizedWrite works)
1439*be431cd8SAndroid Build Coastguard Worker uint16_t readDataPlaceholder;
1440*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(&readDataPlaceholder, 1));
1441*be431cd8SAndroid Build Coastguard Worker
1442*be431cd8SAndroid Build Coastguard Worker // Verify 1/2 of the ring buffer is available to read
1443*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(this->mQueue->availableToRead(), this->mQueue->getQuantumCount() / 2);
1444*be431cd8SAndroid Build Coastguard Worker
1445*be431cd8SAndroid Build Coastguard Worker // Next read should succeed as the queue read pointer have been reset in previous read.
1446*be431cd8SAndroid Build Coastguard Worker std::vector<uint16_t> readData(this->mQueue->availableToRead());
1447*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData.data(), readData.size()));
1448*be431cd8SAndroid Build Coastguard Worker
1449*be431cd8SAndroid Build Coastguard Worker // Verify that the tail of the data is preserved in history after partial wrap around
1450*be431cd8SAndroid Build Coastguard Worker // and followed by the new data.
1451*be431cd8SAndroid Build Coastguard Worker std::rotate(data.begin(), data.begin() + 1, data.end());
1452*be431cd8SAndroid Build Coastguard Worker
1453*be431cd8SAndroid Build Coastguard Worker // Compare in reverse to match tail of the data with readData
1454*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(std::equal(readData.rbegin(), readData.rend(), data.rbegin()));
1455*be431cd8SAndroid Build Coastguard Worker }
1456*be431cd8SAndroid Build Coastguard Worker
1457*be431cd8SAndroid Build Coastguard Worker /*
1458*be431cd8SAndroid Build Coastguard Worker * Verifies that after ring buffer overflow between beginRead() and failed commitRead()
1459*be431cd8SAndroid Build Coastguard Worker * the whole ring buffer is available to read and old values was discarded.
1460*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedOverflowHistoryTest,CommitReadAfterOverflow)1461*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedOverflowHistoryTest, CommitReadAfterOverflow) {
1462*be431cd8SAndroid Build Coastguard Worker std::vector<uint16_t> data(this->mNumMessagesMax);
1463*be431cd8SAndroid Build Coastguard Worker
1464*be431cd8SAndroid Build Coastguard Worker // Fill the queue with monotonic pattern
1465*be431cd8SAndroid Build Coastguard Worker initData(&data[0], this->mNumMessagesMax);
1466*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1467*be431cd8SAndroid Build Coastguard Worker
1468*be431cd8SAndroid Build Coastguard Worker typename TypeParam::MQType::MemTransaction tx;
1469*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->beginRead(this->mNumMessagesMax, &tx));
1470*be431cd8SAndroid Build Coastguard Worker
1471*be431cd8SAndroid Build Coastguard Worker // Write more data (first element of the same data) to cause a wrap around
1472*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1473*be431cd8SAndroid Build Coastguard Worker
1474*be431cd8SAndroid Build Coastguard Worker // Attempt to commit a read should fail due to ring buffer wrap around
1475*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->commitRead(this->mNumMessagesMax));
1476*be431cd8SAndroid Build Coastguard Worker
1477*be431cd8SAndroid Build Coastguard Worker // Verify 1/2 of the ring buffer is available to read
1478*be431cd8SAndroid Build Coastguard Worker ASSERT_EQ(this->mQueue->availableToRead(), this->mQueue->getQuantumCount() / 2);
1479*be431cd8SAndroid Build Coastguard Worker
1480*be431cd8SAndroid Build Coastguard Worker // Next read should succeed as the queue read pointer have been reset in previous commitRead.
1481*be431cd8SAndroid Build Coastguard Worker std::vector<uint16_t> readData(this->mQueue->availableToRead());
1482*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(readData.data(), readData.size()));
1483*be431cd8SAndroid Build Coastguard Worker
1484*be431cd8SAndroid Build Coastguard Worker // Verify that the tail of the data is preserved in history after partial wrap around
1485*be431cd8SAndroid Build Coastguard Worker // and followed by the new data.
1486*be431cd8SAndroid Build Coastguard Worker std::rotate(data.begin(), data.begin() + 1, data.end());
1487*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(std::equal(readData.rbegin(), readData.rend(), data.rbegin()));
1488*be431cd8SAndroid Build Coastguard Worker }
1489*be431cd8SAndroid Build Coastguard Worker
1490*be431cd8SAndroid Build Coastguard Worker /*
1491*be431cd8SAndroid Build Coastguard Worker * Verifies a queue of a single element will fail a read after a write overflow
1492*be431cd8SAndroid Build Coastguard Worker * and then recover.
1493*be431cd8SAndroid Build Coastguard Worker */
TYPED_TEST(UnsynchronizedOverflowHistoryTestSingleElement,ReadAfterOverflow)1494*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedOverflowHistoryTestSingleElement, ReadAfterOverflow) {
1495*be431cd8SAndroid Build Coastguard Worker constexpr uint16_t kValue = 4;
1496*be431cd8SAndroid Build Coastguard Worker std::vector<uint16_t> data = {kValue};
1497*be431cd8SAndroid Build Coastguard Worker
1498*be431cd8SAndroid Build Coastguard Worker // single write/read works normally
1499*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1500*be431cd8SAndroid Build Coastguard Worker uint16_t readDataPlaceholder;
1501*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readDataPlaceholder, 1));
1502*be431cd8SAndroid Build Coastguard Worker EXPECT_EQ(readDataPlaceholder, kValue);
1503*be431cd8SAndroid Build Coastguard Worker
1504*be431cd8SAndroid Build Coastguard Worker // Write more data (first element of the same data) to cause a wrap around
1505*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1506*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1507*be431cd8SAndroid Build Coastguard Worker
1508*be431cd8SAndroid Build Coastguard Worker // Attempt a read (this should fail due to how UnsynchronizedWrite works)
1509*be431cd8SAndroid Build Coastguard Worker ASSERT_FALSE(this->mQueue->read(&readDataPlaceholder, 1));
1510*be431cd8SAndroid Build Coastguard Worker
1511*be431cd8SAndroid Build Coastguard Worker // Subsequent write/reads should work again
1512*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1513*be431cd8SAndroid Build Coastguard Worker ASSERT_TRUE(this->mQueue->read(&readDataPlaceholder, 1));
1514*be431cd8SAndroid Build Coastguard Worker EXPECT_EQ(readDataPlaceholder, kValue);
1515*be431cd8SAndroid Build Coastguard Worker }
1516