xref: /aosp_15_r20/system/libfmq/tests/msgq_test_client.cpp (revision be431cd81a9a2349eaea34eb56fcf6d1608da596)
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 <gtest/gtest.h>
18*be431cd8SAndroid Build Coastguard Worker #ifndef GTEST_IS_THREADSAFE
19*be431cd8SAndroid Build Coastguard Worker #error "GTest did not detect pthread library."
20*be431cd8SAndroid Build Coastguard Worker #endif
21*be431cd8SAndroid Build Coastguard Worker 
22*be431cd8SAndroid Build Coastguard Worker #include <aidl/android/fmq/test/FixedParcelable.h>
23*be431cd8SAndroid Build Coastguard Worker #include <aidl/android/fmq/test/FixedUnion.h>
24*be431cd8SAndroid Build Coastguard Worker #include <aidl/android/fmq/test/ITestAidlMsgQ.h>
25*be431cd8SAndroid Build Coastguard Worker #include <android-base/logging.h>
26*be431cd8SAndroid Build Coastguard Worker #include <android/binder_manager.h>
27*be431cd8SAndroid Build Coastguard Worker #include <android/binder_process.h>
28*be431cd8SAndroid Build Coastguard Worker #include <android/fmq/test/FixedParcelable.h>
29*be431cd8SAndroid Build Coastguard Worker #include <android/fmq/test/FixedUnion.h>
30*be431cd8SAndroid Build Coastguard Worker #include <android/fmq/test/ITestAidlMsgQ.h>
31*be431cd8SAndroid Build Coastguard Worker #include <android/hardware/tests/msgq/1.0/ITestMsgQ.h>
32*be431cd8SAndroid Build Coastguard Worker #include <fmq/AidlMessageQueue.h>
33*be431cd8SAndroid Build Coastguard Worker #include <fmq/AidlMessageQueueCpp.h>
34*be431cd8SAndroid Build Coastguard Worker #include <fmq/EventFlag.h>
35*be431cd8SAndroid Build Coastguard Worker #include <fmq/MessageQueue.h>
36*be431cd8SAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
37*be431cd8SAndroid Build Coastguard Worker 
38*be431cd8SAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
39*be431cd8SAndroid Build Coastguard Worker 
40*be431cd8SAndroid Build Coastguard Worker // libutils:
41*be431cd8SAndroid Build Coastguard Worker using android::OK;
42*be431cd8SAndroid Build Coastguard Worker using android::sp;
43*be431cd8SAndroid Build Coastguard Worker using android::status_t;
44*be431cd8SAndroid Build Coastguard Worker 
45*be431cd8SAndroid Build Coastguard Worker // generated
46*be431cd8SAndroid Build Coastguard Worker using ::aidl::android::fmq::test::EventFlagBits;
47*be431cd8SAndroid Build Coastguard Worker using ::aidl::android::fmq::test::FixedParcelable;
48*be431cd8SAndroid Build Coastguard Worker using ::aidl::android::fmq::test::FixedUnion;
49*be431cd8SAndroid Build Coastguard Worker using ::aidl::android::fmq::test::ITestAidlMsgQ;
50*be431cd8SAndroid Build Coastguard Worker 
51*be431cd8SAndroid Build Coastguard Worker using cppEventFlagBits = ::android::fmq::test::EventFlagBits;
52*be431cd8SAndroid Build Coastguard Worker using cppFixedParcelable = android::fmq::test::FixedParcelable;
53*be431cd8SAndroid Build Coastguard Worker using cppFixedUnion = android::fmq::test::FixedUnion;
54*be431cd8SAndroid Build Coastguard Worker using cppITestAidlMsgQ = ::android::fmq::test::ITestAidlMsgQ;
55*be431cd8SAndroid Build Coastguard Worker 
56*be431cd8SAndroid Build Coastguard Worker using android::hardware::tests::msgq::V1_0::ITestMsgQ;
57*be431cd8SAndroid Build Coastguard Worker static_assert(static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL) ==
58*be431cd8SAndroid Build Coastguard Worker                       static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL),
59*be431cd8SAndroid Build Coastguard Worker               "The AIDL and HIDL test interfaces must use the same values!");
60*be431cd8SAndroid Build Coastguard Worker static_assert(static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY) ==
61*be431cd8SAndroid Build Coastguard Worker                       static_cast<uint32_t>(EventFlagBits::FMQ_NOT_EMPTY),
62*be431cd8SAndroid Build Coastguard Worker               "The AIDL and HIDL test interfaces must use the same values!");
63*be431cd8SAndroid Build Coastguard Worker 
64*be431cd8SAndroid Build Coastguard Worker // libhidl
65*be431cd8SAndroid Build Coastguard Worker using android::hardware::isHidlSupported;
66*be431cd8SAndroid Build Coastguard Worker using android::hardware::kSynchronizedReadWrite;
67*be431cd8SAndroid Build Coastguard Worker using android::hardware::kUnsynchronizedWrite;
68*be431cd8SAndroid Build Coastguard Worker using android::hardware::MessageQueue;
69*be431cd8SAndroid Build Coastguard Worker using android::hardware::MQDescriptorSync;
70*be431cd8SAndroid Build Coastguard Worker using android::hardware::MQDescriptorUnsync;
71*be431cd8SAndroid Build Coastguard Worker using android::hardware::details::waitForHwService;
72*be431cd8SAndroid Build Coastguard Worker 
73*be431cd8SAndroid Build Coastguard Worker using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
74*be431cd8SAndroid Build Coastguard Worker using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
75*be431cd8SAndroid Build Coastguard Worker using cppSynchronizedReadWrite = ::android::hardware::common::fmq::SynchronizedReadWrite;
76*be431cd8SAndroid Build Coastguard Worker using cppUnSynchronizedWrite = android::hardware::common::fmq::UnsynchronizedWrite;
77*be431cd8SAndroid Build Coastguard Worker using android::hardware::kSynchronizedReadWrite;
78*be431cd8SAndroid Build Coastguard Worker using android::hardware::kUnsynchronizedWrite;
79*be431cd8SAndroid Build Coastguard Worker 
80*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<int32_t, SynchronizedReadWrite> AidlMessageQueueSync;
81*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueue<int32_t, UnsynchronizedWrite> AidlMessageQueueUnsync;
82*be431cd8SAndroid Build Coastguard Worker 
83*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<int32_t, cppSynchronizedReadWrite> cppAidlMessageQueueSync;
84*be431cd8SAndroid Build Coastguard Worker typedef android::AidlMessageQueueCpp<int32_t, cppUnSynchronizedWrite> cppAidlMessageQueueUnsync;
85*be431cd8SAndroid Build Coastguard Worker 
86*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<int32_t, kSynchronizedReadWrite> MessageQueueSync;
87*be431cd8SAndroid Build Coastguard Worker typedef android::hardware::MessageQueue<int32_t, kUnsynchronizedWrite> MessageQueueUnsync;
88*be431cd8SAndroid Build Coastguard Worker static const size_t kPageSize = getpagesize();
89*be431cd8SAndroid Build Coastguard Worker static const size_t kNumElementsInSyncQueue = (kPageSize - 16) / sizeof(int32_t);
90*be431cd8SAndroid Build Coastguard Worker 
91*be431cd8SAndroid Build Coastguard Worker enum class SetupType {
92*be431cd8SAndroid Build Coastguard Worker     SINGLE_FD,
93*be431cd8SAndroid Build Coastguard Worker     DOUBLE_FD,
94*be431cd8SAndroid Build Coastguard Worker };
95*be431cd8SAndroid Build Coastguard Worker 
96*be431cd8SAndroid Build Coastguard Worker template <typename T, SetupType setupType>
97*be431cd8SAndroid Build Coastguard Worker class TestParamTypes {
98*be431cd8SAndroid Build Coastguard Worker   public:
99*be431cd8SAndroid Build Coastguard Worker     typedef T MQType;
100*be431cd8SAndroid Build Coastguard Worker     static constexpr bool UserFd = setupType == SetupType::DOUBLE_FD;
101*be431cd8SAndroid Build Coastguard Worker };
102*be431cd8SAndroid Build Coastguard Worker 
103*be431cd8SAndroid Build Coastguard Worker // Run everything on both the AIDL and HIDL versions with one and two FDs
104*be431cd8SAndroid Build Coastguard Worker typedef ::testing::Types<TestParamTypes<AidlMessageQueueSync, SetupType::SINGLE_FD>,
105*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<cppAidlMessageQueueSync, SetupType::SINGLE_FD>,
106*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<MessageQueueSync, SetupType::SINGLE_FD>,
107*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<AidlMessageQueueSync, SetupType::DOUBLE_FD>,
108*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<cppAidlMessageQueueSync, SetupType::DOUBLE_FD>,
109*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<MessageQueueSync, SetupType::DOUBLE_FD>>
110*be431cd8SAndroid Build Coastguard Worker         SyncTypes;
111*be431cd8SAndroid Build Coastguard Worker typedef ::testing::Types<TestParamTypes<AidlMessageQueueUnsync, SetupType::SINGLE_FD>,
112*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<cppAidlMessageQueueUnsync, SetupType::SINGLE_FD>,
113*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<MessageQueueUnsync, SetupType::SINGLE_FD>,
114*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<AidlMessageQueueUnsync, SetupType::DOUBLE_FD>,
115*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<cppAidlMessageQueueUnsync, SetupType::DOUBLE_FD>,
116*be431cd8SAndroid Build Coastguard Worker                          TestParamTypes<MessageQueueUnsync, SetupType::DOUBLE_FD>>
117*be431cd8SAndroid Build Coastguard Worker         UnsyncTypes;
118*be431cd8SAndroid Build Coastguard Worker 
119*be431cd8SAndroid Build Coastguard Worker template <typename T>
120*be431cd8SAndroid Build Coastguard Worker class ClientSyncTestBase : public ::testing::Test {};
121*be431cd8SAndroid Build Coastguard Worker 
122*be431cd8SAndroid Build Coastguard Worker // Specialize for AIDL
123*be431cd8SAndroid Build Coastguard Worker template <>
124*be431cd8SAndroid Build Coastguard Worker class ClientSyncTestBase<AidlMessageQueueSync> : public ::testing::Test {
125*be431cd8SAndroid Build Coastguard Worker   protected:
waitGetTestService()126*be431cd8SAndroid Build Coastguard Worker     static std::shared_ptr<ITestAidlMsgQ> waitGetTestService() {
127*be431cd8SAndroid Build Coastguard Worker         const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
128*be431cd8SAndroid Build Coastguard Worker         ndk::SpAIBinder binder(AServiceManager_getService(instance.c_str()));
129*be431cd8SAndroid Build Coastguard Worker         CHECK(nullptr != binder);
130*be431cd8SAndroid Build Coastguard Worker         auto ret = ITestAidlMsgQ::fromBinder(binder);
131*be431cd8SAndroid Build Coastguard Worker         CHECK(ret->isRemote() == true);
132*be431cd8SAndroid Build Coastguard Worker         return ret;
133*be431cd8SAndroid Build Coastguard Worker     }
configureFmqSyncReadWrite(AidlMessageQueueSync * mq)134*be431cd8SAndroid Build Coastguard Worker     bool configureFmqSyncReadWrite(AidlMessageQueueSync* mq) {
135*be431cd8SAndroid Build Coastguard Worker         bool result = false;
136*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->configureFmqSyncReadWrite(mq->dupeDesc(), &result);
137*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
138*be431cd8SAndroid Build Coastguard Worker     }
requestReadFmqSync(size_t dataLen)139*be431cd8SAndroid Build Coastguard Worker     bool requestReadFmqSync(size_t dataLen) {
140*be431cd8SAndroid Build Coastguard Worker         bool result = false;
141*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->requestReadFmqSync(dataLen, &result);
142*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
143*be431cd8SAndroid Build Coastguard Worker     }
requestWriteFmqSync(size_t dataLen)144*be431cd8SAndroid Build Coastguard Worker     bool requestWriteFmqSync(size_t dataLen) {
145*be431cd8SAndroid Build Coastguard Worker         bool result = false;
146*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->requestWriteFmqSync(dataLen, &result);
147*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
148*be431cd8SAndroid Build Coastguard Worker     }
149*be431cd8SAndroid Build Coastguard Worker 
150*be431cd8SAndroid Build Coastguard Worker     std::shared_ptr<ITestAidlMsgQ> mService;
151*be431cd8SAndroid Build Coastguard Worker };
152*be431cd8SAndroid Build Coastguard Worker 
153*be431cd8SAndroid Build Coastguard Worker // Specialize for AIDL cpp backend
154*be431cd8SAndroid Build Coastguard Worker template <>
155*be431cd8SAndroid Build Coastguard Worker class ClientSyncTestBase<cppAidlMessageQueueSync> : public ::testing::Test {
156*be431cd8SAndroid Build Coastguard Worker   protected:
waitGetTestService()157*be431cd8SAndroid Build Coastguard Worker     static sp<cppITestAidlMsgQ> waitGetTestService() {
158*be431cd8SAndroid Build Coastguard Worker         const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
159*be431cd8SAndroid Build Coastguard Worker         const android::String16 instanceString16(instance.c_str());
160*be431cd8SAndroid Build Coastguard Worker         sp<cppITestAidlMsgQ> binder;
161*be431cd8SAndroid Build Coastguard Worker         status_t err = getService(instanceString16, &binder);
162*be431cd8SAndroid Build Coastguard Worker         if (err != OK) {
163*be431cd8SAndroid Build Coastguard Worker             return nullptr;
164*be431cd8SAndroid Build Coastguard Worker         }
165*be431cd8SAndroid Build Coastguard Worker         CHECK(nullptr != binder);
166*be431cd8SAndroid Build Coastguard Worker         return binder;
167*be431cd8SAndroid Build Coastguard Worker     }
configureFmqSyncReadWrite(cppAidlMessageQueueSync * mq)168*be431cd8SAndroid Build Coastguard Worker     bool configureFmqSyncReadWrite(cppAidlMessageQueueSync* mq) {
169*be431cd8SAndroid Build Coastguard Worker         bool result = false;
170*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->configureFmqSyncReadWrite(mq->dupeDesc(), &result);
171*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
172*be431cd8SAndroid Build Coastguard Worker     }
requestReadFmqSync(size_t dataLen)173*be431cd8SAndroid Build Coastguard Worker     bool requestReadFmqSync(size_t dataLen) {
174*be431cd8SAndroid Build Coastguard Worker         bool result = false;
175*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->requestReadFmqSync(dataLen, &result);
176*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
177*be431cd8SAndroid Build Coastguard Worker     }
requestWriteFmqSync(size_t dataLen)178*be431cd8SAndroid Build Coastguard Worker     bool requestWriteFmqSync(size_t dataLen) {
179*be431cd8SAndroid Build Coastguard Worker         bool result = false;
180*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->requestWriteFmqSync(dataLen, &result);
181*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
182*be431cd8SAndroid Build Coastguard Worker     }
183*be431cd8SAndroid Build Coastguard Worker 
184*be431cd8SAndroid Build Coastguard Worker     sp<cppITestAidlMsgQ> mService;
185*be431cd8SAndroid Build Coastguard Worker };
186*be431cd8SAndroid Build Coastguard Worker 
187*be431cd8SAndroid Build Coastguard Worker // Specialize for HIDL
188*be431cd8SAndroid Build Coastguard Worker template <>
189*be431cd8SAndroid Build Coastguard Worker class ClientSyncTestBase<MessageQueueSync> : public ::testing::Test {
190*be431cd8SAndroid Build Coastguard Worker   protected:
waitGetTestService()191*be431cd8SAndroid Build Coastguard Worker     static sp<ITestMsgQ> waitGetTestService() {
192*be431cd8SAndroid Build Coastguard Worker         if (isHidlSupported()) {
193*be431cd8SAndroid Build Coastguard Worker             android::hardware::details::setTrebleTestingOverride(true);
194*be431cd8SAndroid Build Coastguard Worker             // waitForHwService is required because ITestMsgQ is not in manifest.xml.
195*be431cd8SAndroid Build Coastguard Worker             // "Real" HALs shouldn't be doing this.
196*be431cd8SAndroid Build Coastguard Worker             waitForHwService(ITestMsgQ::descriptor, "default");
197*be431cd8SAndroid Build Coastguard Worker             sp<ITestMsgQ> service = ITestMsgQ::getService();
198*be431cd8SAndroid Build Coastguard Worker             CHECK(nullptr != service);
199*be431cd8SAndroid Build Coastguard Worker             CHECK(service->isRemote() == true);
200*be431cd8SAndroid Build Coastguard Worker             return service;
201*be431cd8SAndroid Build Coastguard Worker         } else {
202*be431cd8SAndroid Build Coastguard Worker             return nullptr;
203*be431cd8SAndroid Build Coastguard Worker         }
204*be431cd8SAndroid Build Coastguard Worker     }
configureFmqSyncReadWrite(MessageQueueSync * mq)205*be431cd8SAndroid Build Coastguard Worker     bool configureFmqSyncReadWrite(MessageQueueSync* mq) {
206*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->configureFmqSyncReadWrite(*mq->getDesc());
207*be431cd8SAndroid Build Coastguard Worker         return ret && ret.isOk();
208*be431cd8SAndroid Build Coastguard Worker     }
requestReadFmqSync(size_t dataLen)209*be431cd8SAndroid Build Coastguard Worker     bool requestReadFmqSync(size_t dataLen) {
210*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->requestReadFmqSync(dataLen);
211*be431cd8SAndroid Build Coastguard Worker         return ret && ret.isOk();
212*be431cd8SAndroid Build Coastguard Worker     }
requestWriteFmqSync(size_t dataLen)213*be431cd8SAndroid Build Coastguard Worker     bool requestWriteFmqSync(size_t dataLen) {
214*be431cd8SAndroid Build Coastguard Worker         auto ret = mService->requestWriteFmqSync(dataLen);
215*be431cd8SAndroid Build Coastguard Worker         return ret && ret.isOk();
216*be431cd8SAndroid Build Coastguard Worker     }
217*be431cd8SAndroid Build Coastguard Worker 
218*be431cd8SAndroid Build Coastguard Worker     sp<ITestMsgQ> mService;
219*be431cd8SAndroid Build Coastguard Worker };
220*be431cd8SAndroid Build Coastguard Worker 
221*be431cd8SAndroid Build Coastguard Worker template <typename T>
222*be431cd8SAndroid Build Coastguard Worker class ClientUnsyncTestBase : public ::testing::Test {};
223*be431cd8SAndroid Build Coastguard Worker 
224*be431cd8SAndroid Build Coastguard Worker // Specialize for AIDL
225*be431cd8SAndroid Build Coastguard Worker template <>
226*be431cd8SAndroid Build Coastguard Worker class ClientUnsyncTestBase<AidlMessageQueueUnsync> : public ::testing::Test {
227*be431cd8SAndroid Build Coastguard Worker   protected:
waitGetTestService()228*be431cd8SAndroid Build Coastguard Worker     static std::shared_ptr<ITestAidlMsgQ> waitGetTestService() {
229*be431cd8SAndroid Build Coastguard Worker         const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
230*be431cd8SAndroid Build Coastguard Worker         ndk::SpAIBinder binder(AServiceManager_getService(instance.c_str()));
231*be431cd8SAndroid Build Coastguard Worker         CHECK(nullptr != binder);
232*be431cd8SAndroid Build Coastguard Worker         auto ret = ITestAidlMsgQ::fromBinder(binder);
233*be431cd8SAndroid Build Coastguard Worker         CHECK(ret->isRemote() == true);
234*be431cd8SAndroid Build Coastguard Worker         return ret;
235*be431cd8SAndroid Build Coastguard Worker     }
getFmqUnsyncWrite(bool configureFmq,bool userFd,std::shared_ptr<ITestAidlMsgQ> service,AidlMessageQueueUnsync ** queue)236*be431cd8SAndroid Build Coastguard Worker     bool getFmqUnsyncWrite(bool configureFmq, bool userFd, std::shared_ptr<ITestAidlMsgQ> service,
237*be431cd8SAndroid Build Coastguard Worker                            AidlMessageQueueUnsync** queue) {
238*be431cd8SAndroid Build Coastguard Worker         bool result = false;
239*be431cd8SAndroid Build Coastguard Worker         aidl::android::hardware::common::fmq::MQDescriptor<int32_t, UnsynchronizedWrite> desc;
240*be431cd8SAndroid Build Coastguard Worker         auto ret = service->getFmqUnsyncWrite(configureFmq, userFd, &desc, &result);
241*be431cd8SAndroid Build Coastguard Worker         *queue = new (std::nothrow) AidlMessageQueueUnsync(desc, false);
242*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
243*be431cd8SAndroid Build Coastguard Worker     }
244*be431cd8SAndroid Build Coastguard Worker 
getQueue(AidlMessageQueueUnsync ** fmq,bool setupQueue,bool userFd)245*be431cd8SAndroid Build Coastguard Worker     std::shared_ptr<ITestAidlMsgQ> getQueue(AidlMessageQueueUnsync** fmq, bool setupQueue,
246*be431cd8SAndroid Build Coastguard Worker                                             bool userFd) {
247*be431cd8SAndroid Build Coastguard Worker         std::shared_ptr<ITestAidlMsgQ> service = waitGetTestService();
248*be431cd8SAndroid Build Coastguard Worker         if (service == nullptr) return nullptr;
249*be431cd8SAndroid Build Coastguard Worker         getFmqUnsyncWrite(setupQueue, userFd, service, fmq);
250*be431cd8SAndroid Build Coastguard Worker         return service;
251*be431cd8SAndroid Build Coastguard Worker     }
252*be431cd8SAndroid Build Coastguard Worker 
requestReadFmqUnsync(size_t dataLen,std::shared_ptr<ITestAidlMsgQ> service)253*be431cd8SAndroid Build Coastguard Worker     bool requestReadFmqUnsync(size_t dataLen, std::shared_ptr<ITestAidlMsgQ> service) {
254*be431cd8SAndroid Build Coastguard Worker         bool result = false;
255*be431cd8SAndroid Build Coastguard Worker         auto ret = service->requestReadFmqUnsync(dataLen, &result);
256*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
257*be431cd8SAndroid Build Coastguard Worker     }
requestWriteFmqUnsync(size_t dataLen,std::shared_ptr<ITestAidlMsgQ> service)258*be431cd8SAndroid Build Coastguard Worker     bool requestWriteFmqUnsync(size_t dataLen, std::shared_ptr<ITestAidlMsgQ> service) {
259*be431cd8SAndroid Build Coastguard Worker         bool result = false;
260*be431cd8SAndroid Build Coastguard Worker         auto ret = service->requestWriteFmqUnsync(dataLen, &result);
261*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
262*be431cd8SAndroid Build Coastguard Worker     }
newQueue()263*be431cd8SAndroid Build Coastguard Worker     AidlMessageQueueUnsync* newQueue() {
264*be431cd8SAndroid Build Coastguard Worker         if (mQueue->isValid())
265*be431cd8SAndroid Build Coastguard Worker             return new (std::nothrow) AidlMessageQueueUnsync(mQueue->dupeDesc(), false);
266*be431cd8SAndroid Build Coastguard Worker         else
267*be431cd8SAndroid Build Coastguard Worker             return nullptr;
268*be431cd8SAndroid Build Coastguard Worker     }
269*be431cd8SAndroid Build Coastguard Worker 
270*be431cd8SAndroid Build Coastguard Worker     std::shared_ptr<ITestAidlMsgQ> mService;
271*be431cd8SAndroid Build Coastguard Worker     AidlMessageQueueUnsync* mQueue = nullptr;
272*be431cd8SAndroid Build Coastguard Worker };
273*be431cd8SAndroid Build Coastguard Worker 
274*be431cd8SAndroid Build Coastguard Worker // Specialize for AIDL cpp backend
275*be431cd8SAndroid Build Coastguard Worker template <>
276*be431cd8SAndroid Build Coastguard Worker class ClientUnsyncTestBase<cppAidlMessageQueueUnsync> : public ::testing::Test {
277*be431cd8SAndroid Build Coastguard Worker   protected:
waitGetTestService()278*be431cd8SAndroid Build Coastguard Worker     static sp<cppITestAidlMsgQ> waitGetTestService() {
279*be431cd8SAndroid Build Coastguard Worker         const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
280*be431cd8SAndroid Build Coastguard Worker         const android::String16 instanceString16(instance.c_str());
281*be431cd8SAndroid Build Coastguard Worker         sp<cppITestAidlMsgQ> binder;
282*be431cd8SAndroid Build Coastguard Worker         status_t err = getService(instanceString16, &binder);
283*be431cd8SAndroid Build Coastguard Worker         if (err != OK) {
284*be431cd8SAndroid Build Coastguard Worker             return nullptr;
285*be431cd8SAndroid Build Coastguard Worker         }
286*be431cd8SAndroid Build Coastguard Worker         CHECK(nullptr != binder);
287*be431cd8SAndroid Build Coastguard Worker         return binder;
288*be431cd8SAndroid Build Coastguard Worker     }
getFmqUnsyncWrite(bool configureFmq,bool userFd,sp<cppITestAidlMsgQ> service,cppAidlMessageQueueUnsync ** queue)289*be431cd8SAndroid Build Coastguard Worker     bool getFmqUnsyncWrite(bool configureFmq, bool userFd, sp<cppITestAidlMsgQ> service,
290*be431cd8SAndroid Build Coastguard Worker                            cppAidlMessageQueueUnsync** queue) {
291*be431cd8SAndroid Build Coastguard Worker         bool result = false;
292*be431cd8SAndroid Build Coastguard Worker         android::hardware::common::fmq::MQDescriptor<int32_t, cppUnSynchronizedWrite> desc;
293*be431cd8SAndroid Build Coastguard Worker         auto ret = service->getFmqUnsyncWrite(configureFmq, userFd, &desc, &result);
294*be431cd8SAndroid Build Coastguard Worker         *queue = new (std::nothrow) cppAidlMessageQueueUnsync(desc, false);
295*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
296*be431cd8SAndroid Build Coastguard Worker     }
297*be431cd8SAndroid Build Coastguard Worker 
getQueue(cppAidlMessageQueueUnsync ** fmq,bool setupQueue,bool userFd)298*be431cd8SAndroid Build Coastguard Worker     sp<cppITestAidlMsgQ> getQueue(cppAidlMessageQueueUnsync** fmq, bool setupQueue, bool userFd) {
299*be431cd8SAndroid Build Coastguard Worker         sp<cppITestAidlMsgQ> service = waitGetTestService();
300*be431cd8SAndroid Build Coastguard Worker         if (service == nullptr) return nullptr;
301*be431cd8SAndroid Build Coastguard Worker         getFmqUnsyncWrite(setupQueue, userFd, service, fmq);
302*be431cd8SAndroid Build Coastguard Worker         return service;
303*be431cd8SAndroid Build Coastguard Worker     }
304*be431cd8SAndroid Build Coastguard Worker 
requestReadFmqUnsync(size_t dataLen,sp<cppITestAidlMsgQ> service)305*be431cd8SAndroid Build Coastguard Worker     bool requestReadFmqUnsync(size_t dataLen, sp<cppITestAidlMsgQ> service) {
306*be431cd8SAndroid Build Coastguard Worker         bool result = false;
307*be431cd8SAndroid Build Coastguard Worker         auto ret = service->requestReadFmqUnsync(dataLen, &result);
308*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
309*be431cd8SAndroid Build Coastguard Worker     }
requestWriteFmqUnsync(size_t dataLen,sp<cppITestAidlMsgQ> service)310*be431cd8SAndroid Build Coastguard Worker     bool requestWriteFmqUnsync(size_t dataLen, sp<cppITestAidlMsgQ> service) {
311*be431cd8SAndroid Build Coastguard Worker         bool result = false;
312*be431cd8SAndroid Build Coastguard Worker         auto ret = service->requestWriteFmqUnsync(dataLen, &result);
313*be431cd8SAndroid Build Coastguard Worker         return result && ret.isOk();
314*be431cd8SAndroid Build Coastguard Worker     }
newQueue()315*be431cd8SAndroid Build Coastguard Worker     cppAidlMessageQueueUnsync* newQueue() {
316*be431cd8SAndroid Build Coastguard Worker         if (mQueue->isValid())
317*be431cd8SAndroid Build Coastguard Worker             return new (std::nothrow) cppAidlMessageQueueUnsync(mQueue->dupeDesc(), false);
318*be431cd8SAndroid Build Coastguard Worker         else
319*be431cd8SAndroid Build Coastguard Worker             return nullptr;
320*be431cd8SAndroid Build Coastguard Worker     }
321*be431cd8SAndroid Build Coastguard Worker 
322*be431cd8SAndroid Build Coastguard Worker     sp<cppITestAidlMsgQ> mService;
323*be431cd8SAndroid Build Coastguard Worker     cppAidlMessageQueueUnsync* mQueue = nullptr;
324*be431cd8SAndroid Build Coastguard Worker };
325*be431cd8SAndroid Build Coastguard Worker 
326*be431cd8SAndroid Build Coastguard Worker // Specialize for HIDL
327*be431cd8SAndroid Build Coastguard Worker template <>
328*be431cd8SAndroid Build Coastguard Worker class ClientUnsyncTestBase<MessageQueueUnsync> : public ::testing::Test {
329*be431cd8SAndroid Build Coastguard Worker   protected:
waitGetTestService()330*be431cd8SAndroid Build Coastguard Worker     static sp<ITestMsgQ> waitGetTestService() {
331*be431cd8SAndroid Build Coastguard Worker         if (isHidlSupported()) {
332*be431cd8SAndroid Build Coastguard Worker             android::hardware::details::setTrebleTestingOverride(true);
333*be431cd8SAndroid Build Coastguard Worker             // waitForHwService is required because ITestMsgQ is not in manifest.xml.
334*be431cd8SAndroid Build Coastguard Worker             // "Real" HALs shouldn't be doing this.
335*be431cd8SAndroid Build Coastguard Worker             waitForHwService(ITestMsgQ::descriptor, "default");
336*be431cd8SAndroid Build Coastguard Worker             sp<ITestMsgQ> service = ITestMsgQ::getService();
337*be431cd8SAndroid Build Coastguard Worker             CHECK(nullptr != service);
338*be431cd8SAndroid Build Coastguard Worker             CHECK(service->isRemote() == true);
339*be431cd8SAndroid Build Coastguard Worker             return service;
340*be431cd8SAndroid Build Coastguard Worker         } else {
341*be431cd8SAndroid Build Coastguard Worker             return nullptr;
342*be431cd8SAndroid Build Coastguard Worker         }
343*be431cd8SAndroid Build Coastguard Worker     }
getFmqUnsyncWrite(bool configureFmq,bool userFd,sp<ITestMsgQ> service,MessageQueueUnsync ** queue)344*be431cd8SAndroid Build Coastguard Worker     bool getFmqUnsyncWrite(bool configureFmq, bool userFd, sp<ITestMsgQ> service,
345*be431cd8SAndroid Build Coastguard Worker                            MessageQueueUnsync** queue) {
346*be431cd8SAndroid Build Coastguard Worker         if (!service) {
347*be431cd8SAndroid Build Coastguard Worker             return false;
348*be431cd8SAndroid Build Coastguard Worker         }
349*be431cd8SAndroid Build Coastguard Worker         service->getFmqUnsyncWrite(configureFmq, userFd,
350*be431cd8SAndroid Build Coastguard Worker                                    [queue](bool ret, const MQDescriptorUnsync<int32_t>& in) {
351*be431cd8SAndroid Build Coastguard Worker                                        ASSERT_TRUE(ret);
352*be431cd8SAndroid Build Coastguard Worker                                        *queue = new (std::nothrow) MessageQueueUnsync(in, false);
353*be431cd8SAndroid Build Coastguard Worker                                    });
354*be431cd8SAndroid Build Coastguard Worker         return true;
355*be431cd8SAndroid Build Coastguard Worker     }
356*be431cd8SAndroid Build Coastguard Worker 
getQueue(MessageQueueUnsync ** fmq,bool setupQueue,bool userFd)357*be431cd8SAndroid Build Coastguard Worker     sp<ITestMsgQ> getQueue(MessageQueueUnsync** fmq, bool setupQueue, bool userFd) {
358*be431cd8SAndroid Build Coastguard Worker         sp<ITestMsgQ> service = waitGetTestService();
359*be431cd8SAndroid Build Coastguard Worker         if (service == nullptr) return nullptr;
360*be431cd8SAndroid Build Coastguard Worker         getFmqUnsyncWrite(setupQueue, userFd, service, fmq);
361*be431cd8SAndroid Build Coastguard Worker         return service;
362*be431cd8SAndroid Build Coastguard Worker     }
363*be431cd8SAndroid Build Coastguard Worker 
requestReadFmqUnsync(size_t dataLen,sp<ITestMsgQ> service)364*be431cd8SAndroid Build Coastguard Worker     bool requestReadFmqUnsync(size_t dataLen, sp<ITestMsgQ> service) {
365*be431cd8SAndroid Build Coastguard Worker         auto ret = service->requestReadFmqUnsync(dataLen);
366*be431cd8SAndroid Build Coastguard Worker         return ret && ret.isOk();
367*be431cd8SAndroid Build Coastguard Worker     }
requestWriteFmqUnsync(size_t dataLen,sp<ITestMsgQ> service)368*be431cd8SAndroid Build Coastguard Worker     bool requestWriteFmqUnsync(size_t dataLen, sp<ITestMsgQ> service) {
369*be431cd8SAndroid Build Coastguard Worker         auto ret = service->requestWriteFmqUnsync(dataLen);
370*be431cd8SAndroid Build Coastguard Worker         return ret && ret.isOk();
371*be431cd8SAndroid Build Coastguard Worker     }
372*be431cd8SAndroid Build Coastguard Worker 
newQueue()373*be431cd8SAndroid Build Coastguard Worker     MessageQueueUnsync* newQueue() {
374*be431cd8SAndroid Build Coastguard Worker         return new (std::nothrow) MessageQueueUnsync(*mQueue->getDesc(), false);
375*be431cd8SAndroid Build Coastguard Worker     }
376*be431cd8SAndroid Build Coastguard Worker 
377*be431cd8SAndroid Build Coastguard Worker     sp<ITestMsgQ> mService;
378*be431cd8SAndroid Build Coastguard Worker     MessageQueueUnsync* mQueue = nullptr;
379*be431cd8SAndroid Build Coastguard Worker };
380*be431cd8SAndroid Build Coastguard Worker 
381*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(UnsynchronizedWriteClientMultiProcess, UnsyncTypes);
382*be431cd8SAndroid Build Coastguard Worker template <typename T>
383*be431cd8SAndroid Build Coastguard Worker class UnsynchronizedWriteClientMultiProcess : public ClientUnsyncTestBase<typename T::MQType> {};
384*be431cd8SAndroid Build Coastguard Worker 
385*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(SynchronizedReadWriteClient, SyncTypes);
386*be431cd8SAndroid Build Coastguard Worker template <typename T>
387*be431cd8SAndroid Build Coastguard Worker class SynchronizedReadWriteClient : public ClientSyncTestBase<typename T::MQType> {
388*be431cd8SAndroid Build Coastguard Worker   protected:
TearDown()389*be431cd8SAndroid Build Coastguard Worker     virtual void TearDown() {
390*be431cd8SAndroid Build Coastguard Worker         delete mQueue;
391*be431cd8SAndroid Build Coastguard Worker     }
392*be431cd8SAndroid Build Coastguard Worker 
SetUp()393*be431cd8SAndroid Build Coastguard Worker     virtual void SetUp() {
394*be431cd8SAndroid Build Coastguard Worker         this->mService = this->waitGetTestService();
395*be431cd8SAndroid Build Coastguard Worker         if (this->mService == nullptr) GTEST_SKIP() << "HIDL is not supported";
396*be431cd8SAndroid Build Coastguard Worker         static constexpr size_t kSyncElementSizeBytes = sizeof(int32_t);
397*be431cd8SAndroid Build Coastguard Worker         android::base::unique_fd ringbufferFd;
398*be431cd8SAndroid Build Coastguard Worker         if (T::UserFd) {
399*be431cd8SAndroid Build Coastguard Worker             ringbufferFd.reset(::ashmem_create_region(
400*be431cd8SAndroid Build Coastguard Worker                     "SyncReadWrite", kNumElementsInSyncQueue * kSyncElementSizeBytes));
401*be431cd8SAndroid Build Coastguard Worker         }
402*be431cd8SAndroid Build Coastguard Worker         // create a queue on the client side
403*be431cd8SAndroid Build Coastguard Worker         mQueue = new (std::nothrow) typename T::MQType(
404*be431cd8SAndroid Build Coastguard Worker                 kNumElementsInSyncQueue, true /* configure event flag word */,
405*be431cd8SAndroid Build Coastguard Worker                 std::move(ringbufferFd), kNumElementsInSyncQueue * kSyncElementSizeBytes);
406*be431cd8SAndroid Build Coastguard Worker         ASSERT_NE(nullptr, mQueue);
407*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(mQueue->isValid());
408*be431cd8SAndroid Build Coastguard Worker         ASSERT_EQ(mQueue->getQuantumCount(), kNumElementsInSyncQueue);
409*be431cd8SAndroid Build Coastguard Worker 
410*be431cd8SAndroid Build Coastguard Worker         // tell server to set up the queue on its end
411*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(this->configureFmqSyncReadWrite(mQueue));
412*be431cd8SAndroid Build Coastguard Worker     }
413*be431cd8SAndroid Build Coastguard Worker 
414*be431cd8SAndroid Build Coastguard Worker     typename T::MQType* mQueue = nullptr;
415*be431cd8SAndroid Build Coastguard Worker };
416*be431cd8SAndroid Build Coastguard Worker 
417*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(UnsynchronizedWriteClient, UnsyncTypes);
418*be431cd8SAndroid Build Coastguard Worker template <typename T>
419*be431cd8SAndroid Build Coastguard Worker class UnsynchronizedWriteClient : public ClientUnsyncTestBase<typename T::MQType> {
420*be431cd8SAndroid Build Coastguard Worker   protected:
TearDown()421*be431cd8SAndroid Build Coastguard Worker     virtual void TearDown() { delete this->mQueue; }
422*be431cd8SAndroid Build Coastguard Worker 
SetUp()423*be431cd8SAndroid Build Coastguard Worker     virtual void SetUp() {
424*be431cd8SAndroid Build Coastguard Worker         this->mService = this->waitGetTestService();
425*be431cd8SAndroid Build Coastguard Worker         if (this->mService == nullptr) GTEST_SKIP() << "HIDL is not supported";
426*be431cd8SAndroid Build Coastguard Worker         this->getFmqUnsyncWrite(true, false, this->mService, &this->mQueue);
427*be431cd8SAndroid Build Coastguard Worker         ASSERT_NE(nullptr, this->mQueue);
428*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(this->mQueue->isValid());
429*be431cd8SAndroid Build Coastguard Worker         mNumMessagesMax = this->mQueue->getQuantumCount();
430*be431cd8SAndroid Build Coastguard Worker     }
431*be431cd8SAndroid Build Coastguard Worker 
432*be431cd8SAndroid Build Coastguard Worker     size_t mNumMessagesMax = 0;
433*be431cd8SAndroid Build Coastguard Worker };
434*be431cd8SAndroid Build Coastguard Worker 
435*be431cd8SAndroid Build Coastguard Worker /*
436*be431cd8SAndroid Build Coastguard Worker  * Utility function to verify data read from the fast message queue.
437*be431cd8SAndroid Build Coastguard Worker  */
verifyData(int32_t * data,size_t count)438*be431cd8SAndroid Build Coastguard Worker bool verifyData(int32_t* data, size_t count) {
439*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < count; i++) {
440*be431cd8SAndroid Build Coastguard Worker         if (data[i] != i) return false;
441*be431cd8SAndroid Build Coastguard Worker     }
442*be431cd8SAndroid Build Coastguard Worker     return true;
443*be431cd8SAndroid Build Coastguard Worker }
444*be431cd8SAndroid Build Coastguard Worker 
445*be431cd8SAndroid Build Coastguard Worker /*
446*be431cd8SAndroid Build Coastguard Worker  * Utility function to initialize data to be written to the FMQ
447*be431cd8SAndroid Build Coastguard Worker  */
initData(int32_t * data,size_t count)448*be431cd8SAndroid Build Coastguard Worker inline void initData(int32_t* data, size_t count) {
449*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < count; i++) {
450*be431cd8SAndroid Build Coastguard Worker         data[i] = i;
451*be431cd8SAndroid Build Coastguard Worker     }
452*be431cd8SAndroid Build Coastguard Worker }
453*be431cd8SAndroid Build Coastguard Worker 
454*be431cd8SAndroid Build Coastguard Worker /*
455*be431cd8SAndroid Build Coastguard Worker  * Verify that for an unsynchronized flavor of FMQ, multiple readers
456*be431cd8SAndroid Build Coastguard Worker  * can recover from a write overflow condition.
457*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClientMultiProcess,MultipleReadersAfterOverflow)458*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClientMultiProcess, MultipleReadersAfterOverflow) {
459*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
460*be431cd8SAndroid Build Coastguard Worker 
461*be431cd8SAndroid Build Coastguard Worker     pid_t pid;
462*be431cd8SAndroid Build Coastguard Worker     /* creating first reader process */
463*be431cd8SAndroid Build Coastguard Worker     if ((pid = fork()) == 0) {
464*be431cd8SAndroid Build Coastguard Worker         typename TypeParam::MQType* queue = nullptr;
465*be431cd8SAndroid Build Coastguard Worker         auto service =
466*be431cd8SAndroid Build Coastguard Worker                 this->getQueue(&queue, true /* setupQueue */, TypeParam::UserFd /* userFd */);
467*be431cd8SAndroid Build Coastguard Worker         ASSERT_NE(service, nullptr);
468*be431cd8SAndroid Build Coastguard Worker         ASSERT_NE(queue, nullptr);
469*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(queue->isValid());
470*be431cd8SAndroid Build Coastguard Worker 
471*be431cd8SAndroid Build Coastguard Worker         size_t numMessagesMax = queue->getQuantumCount();
472*be431cd8SAndroid Build Coastguard Worker 
473*be431cd8SAndroid Build Coastguard Worker         // The following two writes will cause a write overflow.
474*be431cd8SAndroid Build Coastguard Worker         auto ret = this->requestWriteFmqUnsync(numMessagesMax, service);
475*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
476*be431cd8SAndroid Build Coastguard Worker 
477*be431cd8SAndroid Build Coastguard Worker         ret = this->requestWriteFmqUnsync(1, service);
478*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
479*be431cd8SAndroid Build Coastguard Worker 
480*be431cd8SAndroid Build Coastguard Worker         // The following read should fail due to the overflow.
481*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> readData(numMessagesMax);
482*be431cd8SAndroid Build Coastguard Worker         ASSERT_FALSE(queue->read(&readData[0], numMessagesMax));
483*be431cd8SAndroid Build Coastguard Worker 
484*be431cd8SAndroid Build Coastguard Worker         /*
485*be431cd8SAndroid Build Coastguard Worker          * Request another write to verify that the reader can recover from the
486*be431cd8SAndroid Build Coastguard Worker          * overflow condition.
487*be431cd8SAndroid Build Coastguard Worker          */
488*be431cd8SAndroid Build Coastguard Worker         ASSERT_LT(dataLen, numMessagesMax);
489*be431cd8SAndroid Build Coastguard Worker         ret = this->requestWriteFmqUnsync(dataLen, service);
490*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
491*be431cd8SAndroid Build Coastguard Worker 
492*be431cd8SAndroid Build Coastguard Worker         // Verify that the read is successful.
493*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(queue->read(&readData[0], dataLen));
494*be431cd8SAndroid Build Coastguard Worker 
495*be431cd8SAndroid Build Coastguard Worker         delete queue;
496*be431cd8SAndroid Build Coastguard Worker         exit(0);
497*be431cd8SAndroid Build Coastguard Worker     }
498*be431cd8SAndroid Build Coastguard Worker 
499*be431cd8SAndroid Build Coastguard Worker     ASSERT_GT(pid, 0 /* parent should see PID greater than 0 for a good fork */);
500*be431cd8SAndroid Build Coastguard Worker 
501*be431cd8SAndroid Build Coastguard Worker     int status;
502*be431cd8SAndroid Build Coastguard Worker     // wait for the first reader process to exit.
503*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(pid, waitpid(pid, &status, 0 /* options */));
504*be431cd8SAndroid Build Coastguard Worker 
505*be431cd8SAndroid Build Coastguard Worker     // creating second reader process.
506*be431cd8SAndroid Build Coastguard Worker     if ((pid = fork()) == 0) {
507*be431cd8SAndroid Build Coastguard Worker         typename TypeParam::MQType* queue = nullptr;
508*be431cd8SAndroid Build Coastguard Worker         auto service = this->getQueue(&queue, false /* setupQueue */, false /* userFd */);
509*be431cd8SAndroid Build Coastguard Worker         ASSERT_NE(service, nullptr);
510*be431cd8SAndroid Build Coastguard Worker         ASSERT_NE(queue, nullptr);
511*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(queue->isValid());
512*be431cd8SAndroid Build Coastguard Worker 
513*be431cd8SAndroid Build Coastguard Worker         // This read should fail due to the write overflow.
514*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> readData(dataLen);
515*be431cd8SAndroid Build Coastguard Worker         ASSERT_FALSE(queue->read(&readData[0], dataLen));
516*be431cd8SAndroid Build Coastguard Worker 
517*be431cd8SAndroid Build Coastguard Worker         /*
518*be431cd8SAndroid Build Coastguard Worker          * Request another write to verify that the process that recover from
519*be431cd8SAndroid Build Coastguard Worker          * the overflow condition.
520*be431cd8SAndroid Build Coastguard Worker          */
521*be431cd8SAndroid Build Coastguard Worker         auto ret = this->requestWriteFmqUnsync(dataLen, service);
522*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
523*be431cd8SAndroid Build Coastguard Worker 
524*be431cd8SAndroid Build Coastguard Worker         // verify that the read is successful.
525*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(queue->read(&readData[0], dataLen));
526*be431cd8SAndroid Build Coastguard Worker 
527*be431cd8SAndroid Build Coastguard Worker         delete queue;
528*be431cd8SAndroid Build Coastguard Worker         exit(0);
529*be431cd8SAndroid Build Coastguard Worker     }
530*be431cd8SAndroid Build Coastguard Worker 
531*be431cd8SAndroid Build Coastguard Worker     ASSERT_GT(pid, 0 /* parent should see PID greater than 0 for a good fork */);
532*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(pid, waitpid(pid, &status, 0 /* options */));
533*be431cd8SAndroid Build Coastguard Worker }
534*be431cd8SAndroid Build Coastguard Worker 
535*be431cd8SAndroid Build Coastguard Worker /*
536*be431cd8SAndroid Build Coastguard Worker  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
537*be431cd8SAndroid Build Coastguard Worker  * using the EventFlag object owned by FMQ.
538*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWrite1)539*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite1) {
540*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 64;
541*be431cd8SAndroid Build Coastguard Worker     bool ret = false;
542*be431cd8SAndroid Build Coastguard Worker     /*
543*be431cd8SAndroid Build Coastguard Worker      * Request service to perform a blocking read. This call is oneway and will
544*be431cd8SAndroid Build Coastguard Worker      * return immediately.
545*be431cd8SAndroid Build Coastguard Worker      */
546*be431cd8SAndroid Build Coastguard Worker     this->mService->requestBlockingRead(dataLen);
547*be431cd8SAndroid Build Coastguard Worker     {
548*be431cd8SAndroid Build Coastguard Worker         std::array<int32_t, dataLen> data = {0};
549*be431cd8SAndroid Build Coastguard Worker         ret = this->mQueue->writeBlocking(
550*be431cd8SAndroid Build Coastguard Worker                 data.data(), data.size(),
551*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
552*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
553*be431cd8SAndroid Build Coastguard Worker                 5000000000 /* timeOutNanos */);
554*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
555*be431cd8SAndroid Build Coastguard Worker     }
556*be431cd8SAndroid Build Coastguard Worker     {
557*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
558*be431cd8SAndroid Build Coastguard Worker         ret = this->mQueue->writeBlocking(
559*be431cd8SAndroid Build Coastguard Worker                 data.data(), data.size(),
560*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
561*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
562*be431cd8SAndroid Build Coastguard Worker                 5000000000 /* timeOutNanos */);
563*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
564*be431cd8SAndroid Build Coastguard Worker     }
565*be431cd8SAndroid Build Coastguard Worker }
566*be431cd8SAndroid Build Coastguard Worker 
567*be431cd8SAndroid Build Coastguard Worker /*
568*be431cd8SAndroid Build Coastguard Worker  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
569*be431cd8SAndroid Build Coastguard Worker  * using the EventFlag object owned by FMQ and using the default EventFlag
570*be431cd8SAndroid Build Coastguard Worker  * notification bit mask.
571*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWrite2)572*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite2) {
573*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 64;
574*be431cd8SAndroid Build Coastguard Worker     bool ret = false;
575*be431cd8SAndroid Build Coastguard Worker 
576*be431cd8SAndroid Build Coastguard Worker     /*
577*be431cd8SAndroid Build Coastguard Worker      * Request service to perform a blocking read using default EventFlag
578*be431cd8SAndroid Build Coastguard Worker      * notification bit mask. This call is oneway and will
579*be431cd8SAndroid Build Coastguard Worker      * return immediately.
580*be431cd8SAndroid Build Coastguard Worker      */
581*be431cd8SAndroid Build Coastguard Worker     this->mService->requestBlockingReadDefaultEventFlagBits(dataLen);
582*be431cd8SAndroid Build Coastguard Worker 
583*be431cd8SAndroid Build Coastguard Worker     /* Cause a context switch to allow service to block */
584*be431cd8SAndroid Build Coastguard Worker     sched_yield();
585*be431cd8SAndroid Build Coastguard Worker     {
586*be431cd8SAndroid Build Coastguard Worker         std::array<int32_t, dataLen> data = {0};
587*be431cd8SAndroid Build Coastguard Worker         ret = this->mQueue->writeBlocking(data.data(), data.size());
588*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
589*be431cd8SAndroid Build Coastguard Worker     }
590*be431cd8SAndroid Build Coastguard Worker 
591*be431cd8SAndroid Build Coastguard Worker     /*
592*be431cd8SAndroid Build Coastguard Worker      * If the blocking read was successful, another write of size
593*be431cd8SAndroid Build Coastguard Worker      * kNumElementsInSyncQueue will succeed.
594*be431cd8SAndroid Build Coastguard Worker      */
595*be431cd8SAndroid Build Coastguard Worker     {
596*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
597*be431cd8SAndroid Build Coastguard Worker         ret = this->mQueue->writeBlocking(data.data(), data.size(), 5000000000 /* timeOutNanos */);
598*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
599*be431cd8SAndroid Build Coastguard Worker     }
600*be431cd8SAndroid Build Coastguard Worker }
601*be431cd8SAndroid Build Coastguard Worker 
602*be431cd8SAndroid Build Coastguard Worker /*
603*be431cd8SAndroid Build Coastguard Worker  * Test that repeated blocking reads and writes work using readBlocking()/writeBlocking() APIs
604*be431cd8SAndroid Build Coastguard Worker  * using the EventFlag object owned by FMQ.
605*be431cd8SAndroid Build Coastguard Worker  * Each write operation writes the same amount of data as a single read
606*be431cd8SAndroid Build Coastguard Worker  * operation.
607*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteRepeat1)608*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat1) {
609*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 64;
610*be431cd8SAndroid Build Coastguard Worker     bool ret = false;
611*be431cd8SAndroid Build Coastguard Worker 
612*be431cd8SAndroid Build Coastguard Worker     /*
613*be431cd8SAndroid Build Coastguard Worker      * Request service to perform a blocking read of 64 elements. This call is
614*be431cd8SAndroid Build Coastguard Worker      * oneway and will return immediately.
615*be431cd8SAndroid Build Coastguard Worker      */
616*be431cd8SAndroid Build Coastguard Worker     const size_t writeCount = kNumElementsInSyncQueue;
617*be431cd8SAndroid Build Coastguard Worker     this->mService->requestBlockingReadRepeat(dataLen, writeCount);
618*be431cd8SAndroid Build Coastguard Worker     /*
619*be431cd8SAndroid Build Coastguard Worker      * Write 64 elements into the queue for the service to consume
620*be431cd8SAndroid Build Coastguard Worker      */
621*be431cd8SAndroid Build Coastguard Worker     {
622*be431cd8SAndroid Build Coastguard Worker         std::array<int32_t, dataLen> data = {0};
623*be431cd8SAndroid Build Coastguard Worker         for (size_t i = 0; i < writeCount; i++) {
624*be431cd8SAndroid Build Coastguard Worker             ret = this->mQueue->writeBlocking(
625*be431cd8SAndroid Build Coastguard Worker                     data.data(), data.size(),
626*be431cd8SAndroid Build Coastguard Worker                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
627*be431cd8SAndroid Build Coastguard Worker                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
628*be431cd8SAndroid Build Coastguard Worker                     5000000000 /* timeOutNanos */);
629*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(ret);
630*be431cd8SAndroid Build Coastguard Worker         }
631*be431cd8SAndroid Build Coastguard Worker     }
632*be431cd8SAndroid Build Coastguard Worker     /*
633*be431cd8SAndroid Build Coastguard Worker      * The queue should be totally empty now, so filling it up entirely with one
634*be431cd8SAndroid Build Coastguard Worker      * blocking write should be successful.
635*be431cd8SAndroid Build Coastguard Worker      */
636*be431cd8SAndroid Build Coastguard Worker     {
637*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
638*be431cd8SAndroid Build Coastguard Worker         ret = this->mQueue->writeBlocking(
639*be431cd8SAndroid Build Coastguard Worker                 data.data(), data.size(),
640*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
641*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
642*be431cd8SAndroid Build Coastguard Worker                 5000000000 /* timeOutNanos */);
643*be431cd8SAndroid Build Coastguard Worker 
644*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
645*be431cd8SAndroid Build Coastguard Worker     }
646*be431cd8SAndroid Build Coastguard Worker }
647*be431cd8SAndroid Build Coastguard Worker 
648*be431cd8SAndroid Build Coastguard Worker /*
649*be431cd8SAndroid Build Coastguard Worker  * Test that repeated blocking reads and writes work using readBlocking()/writeBlocking() APIs
650*be431cd8SAndroid Build Coastguard Worker  * using the EventFlag object owned by FMQ. Each read operation reads twice the
651*be431cd8SAndroid Build Coastguard Worker  * amount of data as a single write.
652*be431cd8SAndroid Build Coastguard Worker  *
653*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteRepeat2)654*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat2) {
655*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 64;
656*be431cd8SAndroid Build Coastguard Worker     bool ret = false;
657*be431cd8SAndroid Build Coastguard Worker     /*
658*be431cd8SAndroid Build Coastguard Worker      * Request service to perform a repeated blocking read. This call is oneway
659*be431cd8SAndroid Build Coastguard Worker      * and will return immediately. It will read 64 * 2 elements with each
660*be431cd8SAndroid Build Coastguard Worker      * blocking read, for a total of writeCount / 2 calls.
661*be431cd8SAndroid Build Coastguard Worker      */
662*be431cd8SAndroid Build Coastguard Worker     const size_t writeCount = kNumElementsInSyncQueue;
663*be431cd8SAndroid Build Coastguard Worker     this->mService->requestBlockingReadRepeat(dataLen * 2, writeCount / 2);
664*be431cd8SAndroid Build Coastguard Worker     /*
665*be431cd8SAndroid Build Coastguard Worker      * Write 64 elements into the queue writeCount times
666*be431cd8SAndroid Build Coastguard Worker      */
667*be431cd8SAndroid Build Coastguard Worker     {
668*be431cd8SAndroid Build Coastguard Worker         std::array<int32_t, dataLen> data = {0};
669*be431cd8SAndroid Build Coastguard Worker         for (size_t i = 0; i < writeCount; i++) {
670*be431cd8SAndroid Build Coastguard Worker             ret = this->mQueue->writeBlocking(
671*be431cd8SAndroid Build Coastguard Worker                     data.data(), data.size(),
672*be431cd8SAndroid Build Coastguard Worker                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
673*be431cd8SAndroid Build Coastguard Worker                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
674*be431cd8SAndroid Build Coastguard Worker                     5000000000 /* timeOutNanos */);
675*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(ret);
676*be431cd8SAndroid Build Coastguard Worker         }
677*be431cd8SAndroid Build Coastguard Worker     }
678*be431cd8SAndroid Build Coastguard Worker     /*
679*be431cd8SAndroid Build Coastguard Worker      * The queue should be totally empty now, so filling it up entirely with one
680*be431cd8SAndroid Build Coastguard Worker      * blocking write should be successful.
681*be431cd8SAndroid Build Coastguard Worker      */
682*be431cd8SAndroid Build Coastguard Worker     {
683*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
684*be431cd8SAndroid Build Coastguard Worker         ret = this->mQueue->writeBlocking(
685*be431cd8SAndroid Build Coastguard Worker                 data.data(), data.size(),
686*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
687*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
688*be431cd8SAndroid Build Coastguard Worker                 5000000000 /* timeOutNanos */);
689*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
690*be431cd8SAndroid Build Coastguard Worker     }
691*be431cd8SAndroid Build Coastguard Worker }
692*be431cd8SAndroid Build Coastguard Worker 
693*be431cd8SAndroid Build Coastguard Worker /*
694*be431cd8SAndroid Build Coastguard Worker  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
695*be431cd8SAndroid Build Coastguard Worker  * using the EventFlag object owned by FMQ. Each write operation writes twice
696*be431cd8SAndroid Build Coastguard Worker  * the amount of data as a single read.
697*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteRepeat3)698*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat3) {
699*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 64;
700*be431cd8SAndroid Build Coastguard Worker     bool ret = false;
701*be431cd8SAndroid Build Coastguard Worker 
702*be431cd8SAndroid Build Coastguard Worker     /*
703*be431cd8SAndroid Build Coastguard Worker      * Request service to perform a repeated blocking read. This call is oneway
704*be431cd8SAndroid Build Coastguard Worker      * and will return immediately. It will read 64 / 2 elements with each
705*be431cd8SAndroid Build Coastguard Worker      * blocking read, for a total of writeCount * 2 calls.
706*be431cd8SAndroid Build Coastguard Worker      */
707*be431cd8SAndroid Build Coastguard Worker     size_t writeCount = 1024;
708*be431cd8SAndroid Build Coastguard Worker     this->mService->requestBlockingReadRepeat(dataLen / 2, writeCount * 2);
709*be431cd8SAndroid Build Coastguard Worker     /*
710*be431cd8SAndroid Build Coastguard Worker      * Write 64 elements into the queue writeCount times
711*be431cd8SAndroid Build Coastguard Worker      */
712*be431cd8SAndroid Build Coastguard Worker     {
713*be431cd8SAndroid Build Coastguard Worker         std::array<int32_t, dataLen> data = {0};
714*be431cd8SAndroid Build Coastguard Worker         for (size_t i = 0; i < writeCount; i++) {
715*be431cd8SAndroid Build Coastguard Worker             ret = this->mQueue->writeBlocking(
716*be431cd8SAndroid Build Coastguard Worker                     data.data(), data.size(),
717*be431cd8SAndroid Build Coastguard Worker                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
718*be431cd8SAndroid Build Coastguard Worker                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
719*be431cd8SAndroid Build Coastguard Worker                     5000000000 /* timeOutNanos */);
720*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(ret);
721*be431cd8SAndroid Build Coastguard Worker         }
722*be431cd8SAndroid Build Coastguard Worker     }
723*be431cd8SAndroid Build Coastguard Worker     /*
724*be431cd8SAndroid Build Coastguard Worker      * The queue should be totally empty now, so filling it up entirely with one
725*be431cd8SAndroid Build Coastguard Worker      * blocking write should be successful.
726*be431cd8SAndroid Build Coastguard Worker      */
727*be431cd8SAndroid Build Coastguard Worker     {
728*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
729*be431cd8SAndroid Build Coastguard Worker         ret = this->mQueue->writeBlocking(
730*be431cd8SAndroid Build Coastguard Worker                 data.data(), data.size(),
731*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
732*be431cd8SAndroid Build Coastguard Worker                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
733*be431cd8SAndroid Build Coastguard Worker                 5000000000 /* timeOutNanos */);
734*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
735*be431cd8SAndroid Build Coastguard Worker     }
736*be431cd8SAndroid Build Coastguard Worker }
737*be431cd8SAndroid Build Coastguard Worker 
738*be431cd8SAndroid Build Coastguard Worker /*
739*be431cd8SAndroid Build Coastguard Worker  * Test that writeBlocking()/readBlocking() APIs do not block on
740*be431cd8SAndroid Build Coastguard Worker  * attempts to write/read 0 messages and return true.
741*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteZeroMessages)742*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteZeroMessages) {
743*be431cd8SAndroid Build Coastguard Worker     int32_t data = 0;
744*be431cd8SAndroid Build Coastguard Worker 
745*be431cd8SAndroid Build Coastguard Worker     /*
746*be431cd8SAndroid Build Coastguard Worker      * Trigger a blocking write for zero messages with no timeout.
747*be431cd8SAndroid Build Coastguard Worker      */
748*be431cd8SAndroid Build Coastguard Worker     bool ret = this->mQueue->writeBlocking(
749*be431cd8SAndroid Build Coastguard Worker             &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
750*be431cd8SAndroid Build Coastguard Worker             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
751*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
752*be431cd8SAndroid Build Coastguard Worker 
753*be431cd8SAndroid Build Coastguard Worker     /*
754*be431cd8SAndroid Build Coastguard Worker      * Trigger a blocking read for zero messages with no timeout.
755*be431cd8SAndroid Build Coastguard Worker      */
756*be431cd8SAndroid Build Coastguard Worker     ret = this->mQueue->readBlocking(
757*be431cd8SAndroid Build Coastguard Worker             &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
758*be431cd8SAndroid Build Coastguard Worker             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
759*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
760*be431cd8SAndroid Build Coastguard Worker }
761*be431cd8SAndroid Build Coastguard Worker 
762*be431cd8SAndroid Build Coastguard Worker /*
763*be431cd8SAndroid Build Coastguard Worker  * Request mService to write a small number of messages
764*be431cd8SAndroid Build Coastguard Worker  * to the FMQ. Read and verify data.
765*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputReaderTest1)766*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest1) {
767*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
768*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
769*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqSync(dataLen);
770*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
771*be431cd8SAndroid Build Coastguard Worker     int32_t readData[dataLen] = {};
772*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->read(readData, dataLen));
773*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(verifyData(readData, dataLen));
774*be431cd8SAndroid Build Coastguard Worker }
775*be431cd8SAndroid Build Coastguard Worker 
776*be431cd8SAndroid Build Coastguard Worker /*
777*be431cd8SAndroid Build Coastguard Worker  * Request mService to write a message to the queue followed by a beginRead().
778*be431cd8SAndroid Build Coastguard Worker  * Get a pointer to the memory region for the that first message. Set the write
779*be431cd8SAndroid Build Coastguard Worker  * counter to the last byte in the ring buffer. Request another write from
780*be431cd8SAndroid Build Coastguard Worker  * mService. The write should fail because the write address is misaligned.
781*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,MisalignedWriteCounter)782*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, MisalignedWriteCounter) {
783*be431cd8SAndroid Build Coastguard Worker     if (TypeParam::UserFd) {
784*be431cd8SAndroid Build Coastguard Worker         // When using the second FD for the ring buffer, we can't get to the read/write
785*be431cd8SAndroid Build Coastguard Worker         // counters from a pointer to the ring buffer, so no sense in testing.
786*be431cd8SAndroid Build Coastguard Worker         GTEST_SKIP();
787*be431cd8SAndroid Build Coastguard Worker     }
788*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 1;
789*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
790*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqSync(dataLen);
791*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
792*be431cd8SAndroid Build Coastguard Worker     // begin read and get a MemTransaction object for the first object in the queue
793*be431cd8SAndroid Build Coastguard Worker     typename TypeParam::MQType::MemTransaction tx;
794*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
795*be431cd8SAndroid Build Coastguard Worker     // get a pointer to the beginning of the ring buffer
796*be431cd8SAndroid Build Coastguard Worker     const auto& region = tx.getFirstRegion();
797*be431cd8SAndroid Build Coastguard Worker     int32_t* firstStart = region.getAddress();
798*be431cd8SAndroid Build Coastguard Worker 
799*be431cd8SAndroid Build Coastguard Worker     // because this is the first location in the ring buffer, we can get
800*be431cd8SAndroid Build Coastguard Worker     // access to the read and write pointer stored in the fd. 8 bytes back for the
801*be431cd8SAndroid Build Coastguard Worker     // write counter and 16 bytes back for the read counter
802*be431cd8SAndroid Build Coastguard Worker     uint64_t* writeCntr = (uint64_t*)((uint8_t*)firstStart - 8);
803*be431cd8SAndroid Build Coastguard Worker 
804*be431cd8SAndroid Build Coastguard Worker     // set it to point to the very last byte in the ring buffer
805*be431cd8SAndroid Build Coastguard Worker     *(writeCntr) = this->mQueue->getQuantumCount() * this->mQueue->getQuantumSize() - 1;
806*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(*writeCntr % sizeof(int32_t) != 0);
807*be431cd8SAndroid Build Coastguard Worker 
808*be431cd8SAndroid Build Coastguard Worker     // this is not actually necessary, but it's the expected the pattern.
809*be431cd8SAndroid Build Coastguard Worker     this->mQueue->commitRead(dataLen);
810*be431cd8SAndroid Build Coastguard Worker 
811*be431cd8SAndroid Build Coastguard Worker     // This next write will be misaligned and will overlap outside of the ring buffer.
812*be431cd8SAndroid Build Coastguard Worker     // The write should fail.
813*be431cd8SAndroid Build Coastguard Worker     ret = this->requestWriteFmqSync(dataLen);
814*be431cd8SAndroid Build Coastguard Worker     EXPECT_FALSE(ret);
815*be431cd8SAndroid Build Coastguard Worker }
816*be431cd8SAndroid Build Coastguard Worker 
817*be431cd8SAndroid Build Coastguard Worker /*
818*be431cd8SAndroid Build Coastguard Worker  * Request mService to write a small number of messages
819*be431cd8SAndroid Build Coastguard Worker  * to the FMQ. Read and verify each message using
820*be431cd8SAndroid Build Coastguard Worker  * beginRead/Commit read APIs.
821*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputReaderTest2)822*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest2) {
823*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
824*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
825*be431cd8SAndroid Build Coastguard Worker     auto ret = this->requestWriteFmqSync(dataLen);
826*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
827*be431cd8SAndroid Build Coastguard Worker 
828*be431cd8SAndroid Build Coastguard Worker     typename TypeParam::MQType::MemTransaction tx;
829*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
830*be431cd8SAndroid Build Coastguard Worker 
831*be431cd8SAndroid Build Coastguard Worker     auto first = tx.getFirstRegion();
832*be431cd8SAndroid Build Coastguard Worker     auto second = tx.getSecondRegion();
833*be431cd8SAndroid Build Coastguard Worker     size_t firstRegionLength = first.getLength();
834*be431cd8SAndroid Build Coastguard Worker 
835*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < dataLen; i++) {
836*be431cd8SAndroid Build Coastguard Worker         if (i < firstRegionLength) {
837*be431cd8SAndroid Build Coastguard Worker             ASSERT_EQ(i, *(first.getAddress() + i));
838*be431cd8SAndroid Build Coastguard Worker         } else {
839*be431cd8SAndroid Build Coastguard Worker             ASSERT_EQ(i, *(second.getAddress() + i - firstRegionLength));
840*be431cd8SAndroid Build Coastguard Worker         }
841*be431cd8SAndroid Build Coastguard Worker     }
842*be431cd8SAndroid Build Coastguard Worker 
843*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->commitRead(dataLen));
844*be431cd8SAndroid Build Coastguard Worker }
845*be431cd8SAndroid Build Coastguard Worker 
846*be431cd8SAndroid Build Coastguard Worker /*
847*be431cd8SAndroid Build Coastguard Worker  * Write a small number of messages to FMQ. Request
848*be431cd8SAndroid Build Coastguard Worker  * mService to read and verify that the write was successful.
849*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputWriterTest1)850*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest1) {
851*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
852*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
853*be431cd8SAndroid Build Coastguard Worker     size_t originalCount = this->mQueue->availableToWrite();
854*be431cd8SAndroid Build Coastguard Worker     int32_t data[dataLen];
855*be431cd8SAndroid Build Coastguard Worker     initData(data, dataLen);
856*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->write(data, dataLen));
857*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestReadFmqSync(dataLen);
858*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
859*be431cd8SAndroid Build Coastguard Worker     size_t availableCount = this->mQueue->availableToWrite();
860*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(originalCount, availableCount);
861*be431cd8SAndroid Build Coastguard Worker }
862*be431cd8SAndroid Build Coastguard Worker 
863*be431cd8SAndroid Build Coastguard Worker /*
864*be431cd8SAndroid Build Coastguard Worker  * Write a message to the queue, get a pointer to the memory region for that
865*be431cd8SAndroid Build Coastguard Worker  * first message. Set the write counter to the last byte in the ring buffer.
866*be431cd8SAndroid Build Coastguard Worker  * Try another write, it should fail because the write address is misaligned.
867*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,MisalignedWriteCounterClientSide)868*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, MisalignedWriteCounterClientSide) {
869*be431cd8SAndroid Build Coastguard Worker     if (TypeParam::UserFd) {
870*be431cd8SAndroid Build Coastguard Worker         // When using the second FD for the ring buffer, we can't get to the read/write
871*be431cd8SAndroid Build Coastguard Worker         // counters from a pointer to the ring buffer, so no sense in testing.
872*be431cd8SAndroid Build Coastguard Worker         GTEST_SKIP();
873*be431cd8SAndroid Build Coastguard Worker     }
874*be431cd8SAndroid Build Coastguard Worker 
875*be431cd8SAndroid Build Coastguard Worker     bool errorCallbackTriggered = false;
876*be431cd8SAndroid Build Coastguard Worker     auto errorHandler = [&errorCallbackTriggered](TypeParam::MQType::Error error, std::string&&) {
877*be431cd8SAndroid Build Coastguard Worker         if (error == TypeParam::MQType::Error::POINTER_CORRUPTION) {
878*be431cd8SAndroid Build Coastguard Worker             errorCallbackTriggered = true;
879*be431cd8SAndroid Build Coastguard Worker         }
880*be431cd8SAndroid Build Coastguard Worker     };
881*be431cd8SAndroid Build Coastguard Worker     this->mQueue->setErrorHandler(errorHandler);
882*be431cd8SAndroid Build Coastguard Worker     EXPECT_FALSE(errorCallbackTriggered);
883*be431cd8SAndroid Build Coastguard Worker 
884*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 1;
885*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
886*be431cd8SAndroid Build Coastguard Worker     int32_t data[dataLen];
887*be431cd8SAndroid Build Coastguard Worker     initData(data, dataLen);
888*be431cd8SAndroid Build Coastguard Worker     // begin write and get a MemTransaction object for the first object in the queue
889*be431cd8SAndroid Build Coastguard Worker     typename TypeParam::MQType::MemTransaction tx;
890*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
891*be431cd8SAndroid Build Coastguard Worker     EXPECT_FALSE(errorCallbackTriggered);
892*be431cd8SAndroid Build Coastguard Worker 
893*be431cd8SAndroid Build Coastguard Worker     // get a pointer to the beginning of the ring buffer
894*be431cd8SAndroid Build Coastguard Worker     const auto& region = tx.getFirstRegion();
895*be431cd8SAndroid Build Coastguard Worker     int32_t* firstStart = region.getAddress();
896*be431cd8SAndroid Build Coastguard Worker 
897*be431cd8SAndroid Build Coastguard Worker     // because this is the first location in the ring buffer, we can get
898*be431cd8SAndroid Build Coastguard Worker     // access to the read and write pointer stored in the fd. 8 bytes back for the
899*be431cd8SAndroid Build Coastguard Worker     // write counter and 16 bytes back for the read counter
900*be431cd8SAndroid Build Coastguard Worker     uint64_t* writeCntr = (uint64_t*)((uint8_t*)firstStart - 8);
901*be431cd8SAndroid Build Coastguard Worker 
902*be431cd8SAndroid Build Coastguard Worker     // set it to point to the very last byte in the ring buffer
903*be431cd8SAndroid Build Coastguard Worker     *(writeCntr) = this->mQueue->getQuantumCount() * this->mQueue->getQuantumSize() - 1;
904*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(*writeCntr % sizeof(int32_t) != 0);
905*be431cd8SAndroid Build Coastguard Worker     EXPECT_FALSE(errorCallbackTriggered);
906*be431cd8SAndroid Build Coastguard Worker 
907*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
908*be431cd8SAndroid Build Coastguard Worker     EXPECT_FALSE(errorCallbackTriggered);
909*be431cd8SAndroid Build Coastguard Worker 
910*be431cd8SAndroid Build Coastguard Worker     // This next write will be misaligned and will overlap outside of the ring buffer.
911*be431cd8SAndroid Build Coastguard Worker     // The write should fail.
912*be431cd8SAndroid Build Coastguard Worker     EXPECT_FALSE(this->mQueue->write(data, dataLen));
913*be431cd8SAndroid Build Coastguard Worker     EXPECT_TRUE(errorCallbackTriggered);
914*be431cd8SAndroid Build Coastguard Worker 
915*be431cd8SAndroid Build Coastguard Worker     errorCallbackTriggered = false;
916*be431cd8SAndroid Build Coastguard Worker     EXPECT_EQ(0, this->mQueue->availableToWrite());
917*be431cd8SAndroid Build Coastguard Worker     EXPECT_TRUE(errorCallbackTriggered);
918*be431cd8SAndroid Build Coastguard Worker 
919*be431cd8SAndroid Build Coastguard Worker     // Check that it is possible to reset the error handler.
920*be431cd8SAndroid Build Coastguard Worker     errorCallbackTriggered = false;
921*be431cd8SAndroid Build Coastguard Worker     this->mQueue->setErrorHandler(nullptr);
922*be431cd8SAndroid Build Coastguard Worker     EXPECT_EQ(0, this->mQueue->availableToWrite());
923*be431cd8SAndroid Build Coastguard Worker     EXPECT_FALSE(errorCallbackTriggered);
924*be431cd8SAndroid Build Coastguard Worker }
925*be431cd8SAndroid Build Coastguard Worker 
926*be431cd8SAndroid Build Coastguard Worker /*
927*be431cd8SAndroid Build Coastguard Worker  * Write a small number of messages to FMQ using the beginWrite()/CommitWrite()
928*be431cd8SAndroid Build Coastguard Worker  * APIs. Request mService to read and verify that the write was successful.
929*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputWriterTest2)930*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest2) {
931*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
932*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
933*be431cd8SAndroid Build Coastguard Worker     size_t originalCount = this->mQueue->availableToWrite();
934*be431cd8SAndroid Build Coastguard Worker     int32_t data[dataLen];
935*be431cd8SAndroid Build Coastguard Worker     initData(data, dataLen);
936*be431cd8SAndroid Build Coastguard Worker 
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     size_t firstRegionLength = first.getLength();
944*be431cd8SAndroid Build Coastguard Worker     int32_t* firstBaseAddress = first.getAddress();
945*be431cd8SAndroid Build Coastguard Worker     int32_t* secondBaseAddress = second.getAddress();
946*be431cd8SAndroid Build Coastguard Worker 
947*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < dataLen; i++) {
948*be431cd8SAndroid Build Coastguard Worker         if (i < firstRegionLength) {
949*be431cd8SAndroid Build Coastguard Worker             *(firstBaseAddress + i) = i;
950*be431cd8SAndroid Build Coastguard Worker         } else {
951*be431cd8SAndroid Build Coastguard Worker             *(secondBaseAddress + i - firstRegionLength) = i;
952*be431cd8SAndroid Build Coastguard Worker         }
953*be431cd8SAndroid Build Coastguard Worker     }
954*be431cd8SAndroid Build Coastguard Worker 
955*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
956*be431cd8SAndroid Build Coastguard Worker 
957*be431cd8SAndroid Build Coastguard Worker     auto ret = this->requestReadFmqSync(dataLen);
958*be431cd8SAndroid Build Coastguard Worker     // ASSERT_TRUE(ret.isOk());
959*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
960*be431cd8SAndroid Build Coastguard Worker     size_t availableCount = this->mQueue->availableToWrite();
961*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(originalCount, availableCount);
962*be431cd8SAndroid Build Coastguard Worker }
963*be431cd8SAndroid Build Coastguard Worker 
964*be431cd8SAndroid Build Coastguard Worker /*
965*be431cd8SAndroid Build Coastguard Worker  * Verify that the FMQ is empty and read fails when it is empty.
966*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,ReadWhenEmpty)967*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, ReadWhenEmpty) {
968*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToRead());
969*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = 2;
970*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(numMessages, kNumElementsInSyncQueue);
971*be431cd8SAndroid Build Coastguard Worker     int32_t readData[numMessages];
972*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(this->mQueue->read(readData, numMessages));
973*be431cd8SAndroid Build Coastguard Worker }
974*be431cd8SAndroid Build Coastguard Worker 
975*be431cd8SAndroid Build Coastguard Worker /*
976*be431cd8SAndroid Build Coastguard Worker  * Verify FMQ is empty.
977*be431cd8SAndroid Build Coastguard Worker  * Write enough messages to fill it.
978*be431cd8SAndroid Build Coastguard Worker  * Verify availableToWrite() method returns is zero.
979*be431cd8SAndroid Build Coastguard Worker  * Try writing another message and verify that
980*be431cd8SAndroid Build Coastguard Worker  * the attempted write was unsuccessful. Request mService
981*be431cd8SAndroid Build Coastguard Worker  * to read and verify the messages in the FMQ.
982*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,WriteWhenFull)983*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, WriteWhenFull) {
984*be431cd8SAndroid Build Coastguard Worker     std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
985*be431cd8SAndroid Build Coastguard Worker     initData(data.data(), data.size());
986*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
987*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
988*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(this->mQueue->write(&data[0], 1));
989*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestReadFmqSync(data.size());
990*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
991*be431cd8SAndroid Build Coastguard Worker }
992*be431cd8SAndroid Build Coastguard Worker 
993*be431cd8SAndroid Build Coastguard Worker /*
994*be431cd8SAndroid Build Coastguard Worker  * Verify FMQ is empty.
995*be431cd8SAndroid Build Coastguard Worker  * Request mService to write data equal to queue size.
996*be431cd8SAndroid Build Coastguard Worker  * Read and verify data in mQueue.
997*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,LargeInputTest1)998*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest1) {
999*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqSync(kNumElementsInSyncQueue);
1000*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1001*be431cd8SAndroid Build Coastguard Worker     std::vector<int32_t> readData(kNumElementsInSyncQueue);
1002*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->read(&readData[0], kNumElementsInSyncQueue));
1003*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(verifyData(&readData[0], kNumElementsInSyncQueue));
1004*be431cd8SAndroid Build Coastguard Worker }
1005*be431cd8SAndroid Build Coastguard Worker 
1006*be431cd8SAndroid Build Coastguard Worker /*
1007*be431cd8SAndroid Build Coastguard Worker  * Request mService to write more than maximum number of messages to the FMQ.
1008*be431cd8SAndroid Build Coastguard Worker  * Verify that the write fails. Verify that availableToRead() method
1009*be431cd8SAndroid Build Coastguard Worker  * still returns 0 and verify that attempt to read fails.
1010*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,LargeInputTest2)1011*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest2) {
1012*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToRead());
1013*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = 2048;
1014*be431cd8SAndroid Build Coastguard Worker     ASSERT_GT(numMessages, kNumElementsInSyncQueue);
1015*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqSync(numMessages);
1016*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(ret);
1017*be431cd8SAndroid Build Coastguard Worker     int32_t readData;
1018*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToRead());
1019*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(this->mQueue->read(&readData, 1));
1020*be431cd8SAndroid Build Coastguard Worker }
1021*be431cd8SAndroid Build Coastguard Worker 
1022*be431cd8SAndroid Build Coastguard Worker /*
1023*be431cd8SAndroid Build Coastguard Worker  * Write until FMQ is full.
1024*be431cd8SAndroid Build Coastguard Worker  * Verify that the number of messages available to write
1025*be431cd8SAndroid Build Coastguard Worker  * is equal to mNumMessagesMax.
1026*be431cd8SAndroid Build Coastguard Worker  * Verify that another write attempt fails.
1027*be431cd8SAndroid Build Coastguard Worker  * Request mService to read. Verify read count.
1028*be431cd8SAndroid Build Coastguard Worker  */
1029*be431cd8SAndroid Build Coastguard Worker 
TYPED_TEST(SynchronizedReadWriteClient,LargeInputTest3)1030*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest3) {
1031*be431cd8SAndroid Build Coastguard Worker     std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
1032*be431cd8SAndroid Build Coastguard Worker     initData(data.data(), data.size());
1033*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
1034*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
1035*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(this->mQueue->write(data.data(), 1));
1036*be431cd8SAndroid Build Coastguard Worker 
1037*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestReadFmqSync(data.size());
1038*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1039*be431cd8SAndroid Build Coastguard Worker }
1040*be431cd8SAndroid Build Coastguard Worker 
1041*be431cd8SAndroid Build Coastguard Worker /*
1042*be431cd8SAndroid Build Coastguard Worker  * Confirm that the FMQ is empty. Request mService to write to FMQ.
1043*be431cd8SAndroid Build Coastguard Worker  * Do multiple reads to empty FMQ and verify data.
1044*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,MultipleRead)1045*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, MultipleRead) {
1046*be431cd8SAndroid Build Coastguard Worker     const size_t chunkSize = 100;
1047*be431cd8SAndroid Build Coastguard Worker     const size_t chunkNum = 5;
1048*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = chunkSize * chunkNum;
1049*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(numMessages, kNumElementsInSyncQueue);
1050*be431cd8SAndroid Build Coastguard Worker     size_t availableToRead = this->mQueue->availableToRead();
1051*be431cd8SAndroid Build Coastguard Worker     size_t expectedCount = 0;
1052*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(expectedCount, availableToRead);
1053*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqSync(numMessages);
1054*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1055*be431cd8SAndroid Build Coastguard Worker     int32_t readData[numMessages] = {};
1056*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < chunkNum; i++) {
1057*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
1058*be431cd8SAndroid Build Coastguard Worker     }
1059*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(verifyData(readData, numMessages));
1060*be431cd8SAndroid Build Coastguard Worker }
1061*be431cd8SAndroid Build Coastguard Worker 
1062*be431cd8SAndroid Build Coastguard Worker /*
1063*be431cd8SAndroid Build Coastguard Worker  * Write to FMQ in bursts.
1064*be431cd8SAndroid Build Coastguard Worker  * Request mService to read data. Verify the read was successful.
1065*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,MultipleWrite)1066*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, MultipleWrite) {
1067*be431cd8SAndroid Build Coastguard Worker     const size_t chunkSize = 100;
1068*be431cd8SAndroid Build Coastguard Worker     const size_t chunkNum = 5;
1069*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = chunkSize * chunkNum;
1070*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(numMessages, kNumElementsInSyncQueue);
1071*be431cd8SAndroid Build Coastguard Worker     int32_t data[numMessages];
1072*be431cd8SAndroid Build Coastguard Worker     initData(&data[0], numMessages);
1073*be431cd8SAndroid Build Coastguard Worker 
1074*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < chunkNum; i++) {
1075*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
1076*be431cd8SAndroid Build Coastguard Worker     }
1077*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestReadFmqSync(numMessages);
1078*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1079*be431cd8SAndroid Build Coastguard Worker }
1080*be431cd8SAndroid Build Coastguard Worker 
1081*be431cd8SAndroid Build Coastguard Worker /*
1082*be431cd8SAndroid Build Coastguard Worker  * Write enough messages into the FMQ to fill half of it.
1083*be431cd8SAndroid Build Coastguard Worker  * Request mService to read back the same.
1084*be431cd8SAndroid Build Coastguard Worker  * Write mNumMessagesMax messages into the queue. This should cause a
1085*be431cd8SAndroid Build Coastguard Worker  * wrap around. Request mService to read and verify the data.
1086*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,ReadWriteWrapAround)1087*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, ReadWriteWrapAround) {
1088*be431cd8SAndroid Build Coastguard Worker     size_t numMessages = kNumElementsInSyncQueue / 2;
1089*be431cd8SAndroid Build Coastguard Worker     std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
1090*be431cd8SAndroid Build Coastguard Worker     initData(data.data(), data.size());
1091*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
1092*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestReadFmqSync(numMessages);
1093*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1094*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
1095*be431cd8SAndroid Build Coastguard Worker     ret = this->requestReadFmqSync(data.size());
1096*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1097*be431cd8SAndroid Build Coastguard Worker }
1098*be431cd8SAndroid Build Coastguard Worker 
1099*be431cd8SAndroid Build Coastguard Worker /*
1100*be431cd8SAndroid Build Coastguard Worker  * Use beginWrite/commitWrite/getSlot APIs to test wrap arounds are handled
1101*be431cd8SAndroid Build Coastguard Worker  * correctly.
1102*be431cd8SAndroid Build Coastguard Worker  * Write enough messages into the FMQ to fill half of it
1103*be431cd8SAndroid Build Coastguard Worker  * and read back the same.
1104*be431cd8SAndroid Build Coastguard Worker  * Write mNumMessagesMax messages into the queue. This will cause a
1105*be431cd8SAndroid Build Coastguard Worker  * wrap around. Read and verify the data.
1106*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(SynchronizedReadWriteClient,ReadWriteWrapAround2)1107*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(SynchronizedReadWriteClient, ReadWriteWrapAround2) {
1108*be431cd8SAndroid Build Coastguard Worker     size_t numMessages = kNumElementsInSyncQueue / 2;
1109*be431cd8SAndroid Build Coastguard Worker     std::vector<int32_t> data(kNumElementsInSyncQueue, 0);
1110*be431cd8SAndroid Build Coastguard Worker     initData(data.data(), data.size());
1111*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
1112*be431cd8SAndroid Build Coastguard Worker     auto ret = this->requestReadFmqSync(numMessages);
1113*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1114*be431cd8SAndroid Build Coastguard Worker 
1115*be431cd8SAndroid Build Coastguard Worker     /*
1116*be431cd8SAndroid Build Coastguard Worker      * The next write and read will have to deal with with wrap arounds.
1117*be431cd8SAndroid Build Coastguard Worker      */
1118*be431cd8SAndroid Build Coastguard Worker     typename TypeParam::MQType::MemTransaction tx;
1119*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->beginWrite(data.size(), &tx));
1120*be431cd8SAndroid Build Coastguard Worker 
1121*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(tx.getFirstRegion().getLength() + tx.getSecondRegion().getLength(), data.size());
1122*be431cd8SAndroid Build Coastguard Worker 
1123*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < data.size(); i++) {
1124*be431cd8SAndroid Build Coastguard Worker         int32_t* ptr = tx.getSlot(i);
1125*be431cd8SAndroid Build Coastguard Worker         *ptr = data[i];
1126*be431cd8SAndroid Build Coastguard Worker     }
1127*be431cd8SAndroid Build Coastguard Worker 
1128*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->commitWrite(data.size()));
1129*be431cd8SAndroid Build Coastguard Worker 
1130*be431cd8SAndroid Build Coastguard Worker     ret = this->requestReadFmqSync(data.size());
1131*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1132*be431cd8SAndroid Build Coastguard Worker }
1133*be431cd8SAndroid Build Coastguard Worker 
1134*be431cd8SAndroid Build Coastguard Worker /*
1135*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to write a small number of messages
1136*be431cd8SAndroid Build Coastguard Worker  * to the FMQ. Read and verify data.
1137*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,SmallInputReaderTest1)1138*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, SmallInputReaderTest1) {
1139*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
1140*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, this->mNumMessagesMax);
1141*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
1142*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1143*be431cd8SAndroid Build Coastguard Worker     int32_t readData[dataLen] = {};
1144*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->read(readData, dataLen));
1145*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(verifyData(readData, dataLen));
1146*be431cd8SAndroid Build Coastguard Worker }
1147*be431cd8SAndroid Build Coastguard Worker 
1148*be431cd8SAndroid Build Coastguard Worker /*
1149*be431cd8SAndroid Build Coastguard Worker  * Write a small number of messages to FMQ. Request
1150*be431cd8SAndroid Build Coastguard Worker  * this->mService to read and verify that the write was successful.
1151*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,SmallInputWriterTest1)1152*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, SmallInputWriterTest1) {
1153*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
1154*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, this->mNumMessagesMax);
1155*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(dataLen, this->mService));
1156*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestReadFmqUnsync(dataLen, this->mService));
1157*be431cd8SAndroid Build Coastguard Worker }
1158*be431cd8SAndroid Build Coastguard Worker 
1159*be431cd8SAndroid Build Coastguard Worker /*
1160*be431cd8SAndroid Build Coastguard Worker  * Verify that the FMQ is empty and read fails when it is empty.
1161*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,ReadWhenEmpty)1162*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, ReadWhenEmpty) {
1163*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToRead());
1164*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = 2;
1165*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(numMessages, this->mNumMessagesMax);
1166*be431cd8SAndroid Build Coastguard Worker     int32_t readData[numMessages];
1167*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(this->mQueue->read(readData, numMessages));
1168*be431cd8SAndroid Build Coastguard Worker }
1169*be431cd8SAndroid Build Coastguard Worker 
1170*be431cd8SAndroid Build Coastguard Worker /*
1171*be431cd8SAndroid Build Coastguard Worker  * Verify FMQ is empty.
1172*be431cd8SAndroid Build Coastguard Worker  * Write enough messages to fill it.
1173*be431cd8SAndroid Build Coastguard Worker  * Verify availableToWrite() method returns is zero.
1174*be431cd8SAndroid Build Coastguard Worker  * Try writing another message and verify that
1175*be431cd8SAndroid Build Coastguard Worker  * the attempted write was successful. Request this->mService
1176*be431cd8SAndroid Build Coastguard Worker  * to read the messages in the FMQ and verify that it is unsuccessful.
1177*be431cd8SAndroid Build Coastguard Worker  */
1178*be431cd8SAndroid Build Coastguard Worker 
TYPED_TEST(UnsynchronizedWriteClient,WriteWhenFull)1179*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, WriteWhenFull) {
1180*be431cd8SAndroid Build Coastguard Worker     std::vector<int32_t> data(this->mNumMessagesMax);
1181*be431cd8SAndroid Build Coastguard Worker     initData(&data[0], this->mNumMessagesMax);
1182*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService));
1183*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
1184*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(1, this->mService));
1185*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
1186*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(ret);
1187*be431cd8SAndroid Build Coastguard Worker }
1188*be431cd8SAndroid Build Coastguard Worker 
1189*be431cd8SAndroid Build Coastguard Worker /*
1190*be431cd8SAndroid Build Coastguard Worker  * Verify FMQ is empty.
1191*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to write data equal to queue size.
1192*be431cd8SAndroid Build Coastguard Worker  * Read and verify data in this->mQueue.
1193*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,LargeInputTest1)1194*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest1) {
1195*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
1196*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1197*be431cd8SAndroid Build Coastguard Worker     std::vector<int32_t> data(this->mNumMessagesMax);
1198*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->read(&data[0], this->mNumMessagesMax));
1199*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(verifyData(&data[0], this->mNumMessagesMax));
1200*be431cd8SAndroid Build Coastguard Worker }
1201*be431cd8SAndroid Build Coastguard Worker 
1202*be431cd8SAndroid Build Coastguard Worker /*
1203*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to write more than maximum number of messages to the FMQ.
1204*be431cd8SAndroid Build Coastguard Worker  * Verify that the write fails. Verify that availableToRead() method
1205*be431cd8SAndroid Build Coastguard Worker  * still returns 0 and verify that attempt to read fails.
1206*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,LargeInputTest2)1207*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest2) {
1208*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToRead());
1209*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = this->mNumMessagesMax + 1;
1210*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
1211*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(ret);
1212*be431cd8SAndroid Build Coastguard Worker     int32_t readData;
1213*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToRead());
1214*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(this->mQueue->read(&readData, 1));
1215*be431cd8SAndroid Build Coastguard Worker }
1216*be431cd8SAndroid Build Coastguard Worker 
1217*be431cd8SAndroid Build Coastguard Worker /*
1218*be431cd8SAndroid Build Coastguard Worker  * Write until FMQ is full.
1219*be431cd8SAndroid Build Coastguard Worker  * Verify that another write attempt is successful.
1220*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to read. Verify that read is unsuccessful
1221*be431cd8SAndroid Build Coastguard Worker  * because of the write overflow.
1222*be431cd8SAndroid Build Coastguard Worker  * Perform another write and verify that the read is successful
1223*be431cd8SAndroid Build Coastguard Worker  * to check if the reader process can recover from the error condition.
1224*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,LargeInputTest3)1225*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest3) {
1226*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService));
1227*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
1228*be431cd8SAndroid Build Coastguard Worker 
1229*be431cd8SAndroid Build Coastguard Worker     int32_t readData;
1230*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(1, this->mService));
1231*be431cd8SAndroid Build Coastguard Worker 
1232*be431cd8SAndroid Build Coastguard Worker     ASSERT_FALSE(this->mQueue->read(&readData, 1));
1233*be431cd8SAndroid Build Coastguard Worker 
1234*be431cd8SAndroid Build Coastguard Worker     // Half of the buffer gets cleared on overflow so single item write will not
1235*be431cd8SAndroid Build Coastguard Worker     // cause another overflow.
1236*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(1, this->mService));
1237*be431cd8SAndroid Build Coastguard Worker 
1238*be431cd8SAndroid Build Coastguard Worker     // Half of the buffer plus a newly written element will be available.
1239*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->read(&readData, 1));
1240*be431cd8SAndroid Build Coastguard Worker }
1241*be431cd8SAndroid Build Coastguard Worker 
1242*be431cd8SAndroid Build Coastguard Worker /*
1243*be431cd8SAndroid Build Coastguard Worker  * Confirm that the FMQ is empty. Request this->mService to write to FMQ.
1244*be431cd8SAndroid Build Coastguard Worker  * Do multiple reads to empty FMQ and verify data.
1245*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,MultipleRead)1246*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, MultipleRead) {
1247*be431cd8SAndroid Build Coastguard Worker     const size_t chunkSize = 100;
1248*be431cd8SAndroid Build Coastguard Worker     const size_t chunkNum = 5;
1249*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = chunkSize * chunkNum;
1250*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(numMessages, this->mNumMessagesMax);
1251*be431cd8SAndroid Build Coastguard Worker     size_t availableToRead = this->mQueue->availableToRead();
1252*be431cd8SAndroid Build Coastguard Worker     size_t expectedCount = 0;
1253*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(expectedCount, availableToRead);
1254*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
1255*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1256*be431cd8SAndroid Build Coastguard Worker     int32_t readData[numMessages] = {};
1257*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < chunkNum; i++) {
1258*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
1259*be431cd8SAndroid Build Coastguard Worker     }
1260*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(verifyData(readData, numMessages));
1261*be431cd8SAndroid Build Coastguard Worker }
1262*be431cd8SAndroid Build Coastguard Worker 
1263*be431cd8SAndroid Build Coastguard Worker /*
1264*be431cd8SAndroid Build Coastguard Worker  * Write to FMQ in bursts.
1265*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to read data, verify that it was successful.
1266*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,MultipleWrite)1267*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, MultipleWrite) {
1268*be431cd8SAndroid Build Coastguard Worker     const size_t chunkSize = 100;
1269*be431cd8SAndroid Build Coastguard Worker     const size_t chunkNum = 5;
1270*be431cd8SAndroid Build Coastguard Worker     const size_t numMessages = chunkSize * chunkNum;
1271*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(numMessages, this->mNumMessagesMax);
1272*be431cd8SAndroid Build Coastguard Worker     for (size_t i = 0; i < chunkNum; i++) {
1273*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(this->requestWriteFmqUnsync(chunkSize, this->mService));
1274*be431cd8SAndroid Build Coastguard Worker     }
1275*be431cd8SAndroid Build Coastguard Worker     ASSERT_EQ(numMessages, this->mQueue->availableToRead());
1276*be431cd8SAndroid Build Coastguard Worker     int32_t readData[numMessages] = {};
1277*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->mQueue->read(readData, numMessages));
1278*be431cd8SAndroid Build Coastguard Worker     // verify that data is filled by the service - the messages will contiain
1279*be431cd8SAndroid Build Coastguard Worker     // 'chunkSize' because that's the value we passed to the service each write.
1280*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(verifyData(readData, chunkSize));
1281*be431cd8SAndroid Build Coastguard Worker }
1282*be431cd8SAndroid Build Coastguard Worker 
1283*be431cd8SAndroid Build Coastguard Worker /*
1284*be431cd8SAndroid Build Coastguard Worker  * Write enough messages into the FMQ to fill half of it.
1285*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to read back the same.
1286*be431cd8SAndroid Build Coastguard Worker  * Write this->mNumMessagesMax messages into the queue. This should cause a
1287*be431cd8SAndroid Build Coastguard Worker  * wrap around. Request this->mService to read and verify the data.
1288*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,ReadWriteWrapAround)1289*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, ReadWriteWrapAround) {
1290*be431cd8SAndroid Build Coastguard Worker     size_t numMessages = this->mNumMessagesMax / 2;
1291*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(numMessages, this->mService));
1292*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestReadFmqUnsync(numMessages, this->mService));
1293*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService));
1294*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService));
1295*be431cd8SAndroid Build Coastguard Worker }
1296*be431cd8SAndroid Build Coastguard Worker 
1297*be431cd8SAndroid Build Coastguard Worker /*
1298*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to write a small number of messages
1299*be431cd8SAndroid Build Coastguard Worker  * to the FMQ. Read and verify data from two threads configured
1300*be431cd8SAndroid Build Coastguard Worker  * as readers to the FMQ.
1301*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,SmallInputMultipleReaderTest)1302*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, SmallInputMultipleReaderTest) {
1303*be431cd8SAndroid Build Coastguard Worker     typename TypeParam::MQType* mQueue2 = this->newQueue();
1304*be431cd8SAndroid Build Coastguard Worker 
1305*be431cd8SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, mQueue2);
1306*be431cd8SAndroid Build Coastguard Worker 
1307*be431cd8SAndroid Build Coastguard Worker     const size_t dataLen = 16;
1308*be431cd8SAndroid Build Coastguard Worker     ASSERT_LE(dataLen, this->mNumMessagesMax);
1309*be431cd8SAndroid Build Coastguard Worker 
1310*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
1311*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1312*be431cd8SAndroid Build Coastguard Worker 
1313*be431cd8SAndroid Build Coastguard Worker     pid_t pid;
1314*be431cd8SAndroid Build Coastguard Worker     if ((pid = fork()) == 0) {
1315*be431cd8SAndroid Build Coastguard Worker         /* child process */
1316*be431cd8SAndroid Build Coastguard Worker         int32_t readData[dataLen] = {};
1317*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(mQueue2->read(readData, dataLen));
1318*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(verifyData(readData, dataLen));
1319*be431cd8SAndroid Build Coastguard Worker         exit(0);
1320*be431cd8SAndroid Build Coastguard Worker     } else {
1321*be431cd8SAndroid Build Coastguard Worker         ASSERT_GT(pid,
1322*be431cd8SAndroid Build Coastguard Worker                   0 /* parent should see PID greater than 0 for a good fork */);
1323*be431cd8SAndroid Build Coastguard Worker         int32_t readData[dataLen] = {};
1324*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(this->mQueue->read(readData, dataLen));
1325*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(verifyData(readData, dataLen));
1326*be431cd8SAndroid Build Coastguard Worker     }
1327*be431cd8SAndroid Build Coastguard Worker }
1328*be431cd8SAndroid Build Coastguard Worker 
1329*be431cd8SAndroid Build Coastguard Worker /*
1330*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to write into the FMQ until it is full.
1331*be431cd8SAndroid Build Coastguard Worker  * Request this->mService to do another write and verify it is successful.
1332*be431cd8SAndroid Build Coastguard Worker  * Use two reader processes to read and verify that both fail.
1333*be431cd8SAndroid Build Coastguard Worker  */
TYPED_TEST(UnsynchronizedWriteClient,OverflowNotificationTest)1334*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(UnsynchronizedWriteClient, OverflowNotificationTest) {
1335*be431cd8SAndroid Build Coastguard Worker     typename TypeParam::MQType* mQueue2 = this->newQueue();
1336*be431cd8SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, mQueue2);
1337*be431cd8SAndroid Build Coastguard Worker 
1338*be431cd8SAndroid Build Coastguard Worker     bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
1339*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1340*be431cd8SAndroid Build Coastguard Worker     ret = this->requestWriteFmqUnsync(1, this->mService);
1341*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(ret);
1342*be431cd8SAndroid Build Coastguard Worker 
1343*be431cd8SAndroid Build Coastguard Worker     pid_t pid;
1344*be431cd8SAndroid Build Coastguard Worker     if ((pid = fork()) == 0) {
1345*be431cd8SAndroid Build Coastguard Worker         /* child process */
1346*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> readData(this->mNumMessagesMax);
1347*be431cd8SAndroid Build Coastguard Worker         ASSERT_FALSE(mQueue2->read(&readData[0], this->mNumMessagesMax));
1348*be431cd8SAndroid Build Coastguard Worker         exit(0);
1349*be431cd8SAndroid Build Coastguard Worker     } else {
1350*be431cd8SAndroid Build Coastguard Worker         ASSERT_GT(pid, 0/* parent should see PID greater than 0 for a good fork */);
1351*be431cd8SAndroid Build Coastguard Worker         std::vector<int32_t> readData(this->mNumMessagesMax);
1352*be431cd8SAndroid Build Coastguard Worker         ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1353*be431cd8SAndroid Build Coastguard Worker     }
1354*be431cd8SAndroid Build Coastguard Worker }
1355*be431cd8SAndroid Build Coastguard Worker 
1356*be431cd8SAndroid Build Coastguard Worker /*
1357*be431cd8SAndroid Build Coastguard Worker  * Make sure a valid queue can be created with different supported types.
1358*be431cd8SAndroid Build Coastguard Worker  * All fundamental or native types should work. An AIDL parcelable that is
1359*be431cd8SAndroid Build Coastguard Worker  * annotated with @FixedSize is supported. A parcelable without it, will cause
1360*be431cd8SAndroid Build Coastguard Worker  * a compilation error.
1361*be431cd8SAndroid Build Coastguard Worker  */
1362*be431cd8SAndroid Build Coastguard Worker typedef ::testing::Types<FixedParcelable, FixedUnion, EventFlagBits, bool, int8_t, char, char16_t,
1363*be431cd8SAndroid Build Coastguard Worker                          int32_t, int64_t, float, double>
1364*be431cd8SAndroid Build Coastguard Worker         AidlTypeCheckTypes;
1365*be431cd8SAndroid Build Coastguard Worker 
1366*be431cd8SAndroid Build Coastguard Worker template <typename T>
1367*be431cd8SAndroid Build Coastguard Worker class AidlTypeChecks : public ::testing::Test {};
1368*be431cd8SAndroid Build Coastguard Worker 
1369*be431cd8SAndroid Build Coastguard Worker TYPED_TEST_CASE(AidlTypeChecks, AidlTypeCheckTypes);
1370*be431cd8SAndroid Build Coastguard Worker 
TYPED_TEST(AidlTypeChecks,FixedSizeParcelableTest)1371*be431cd8SAndroid Build Coastguard Worker TYPED_TEST(AidlTypeChecks, FixedSizeParcelableTest) {
1372*be431cd8SAndroid Build Coastguard Worker     android::AidlMessageQueue<TypeParam, UnsynchronizedWrite> queue =
1373*be431cd8SAndroid Build Coastguard Worker             android::AidlMessageQueue<TypeParam, UnsynchronizedWrite>(64);
1374*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(queue.isValid());
1375*be431cd8SAndroid Build Coastguard Worker     // Make sure we can do a simple write/read of any value.
1376*be431cd8SAndroid Build Coastguard Worker     TypeParam writeData[1];
1377*be431cd8SAndroid Build Coastguard Worker     TypeParam readData[1];
1378*be431cd8SAndroid Build Coastguard Worker     EXPECT_TRUE(queue.write(writeData, 1));
1379*be431cd8SAndroid Build Coastguard Worker     EXPECT_TRUE(queue.read(readData, 1));
1380*be431cd8SAndroid Build Coastguard Worker }
1381