1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "MockCarWatchdogServiceForSystem.h"
18 #include "MockVhalClient.h"
19 #include "MockWatchdogServiceHelper.h"
20 #include "WatchdogProcessService.h"
21 #include "WatchdogServiceHelper.h"
22
23 #include <android/automotive/watchdog/internal/BnCarWatchdogServiceForSystem.h>
24 #include <android/binder_interface_utils.h>
25 #include <gmock/gmock.h>
26
27 namespace android {
28 namespace automotive {
29 namespace watchdog {
30
31 namespace aawi = ::android::automotive::watchdog::internal;
32 namespace afav = ::android::frameworks::automotive::vhal;
33 namespace aahav = ::aidl::android::hardware::automotive::vehicle;
34
35 using aahav::VehicleProperty;
36 using aawi::ProcessIdentifier;
37 using ::android::IBinder;
38 using ::android::sp;
39 using ::android::binder::Status;
40 using ::ndk::SharedRefBase;
41 using ::testing::_;
42 using ::testing::ByMove;
43 using ::testing::Return;
44
45 namespace {
46
47 class MockCarWatchdogClient : public ICarWatchdogClientDefault {
48 public:
MockCarWatchdogClient()49 MockCarWatchdogClient() { mBinder = sp<MockBinder>::make(); }
getBinder() const50 sp<MockBinder> getBinder() const { return mBinder; }
51
52 MOCK_METHOD(IBinder*, onAsBinder, (), (override));
53
54 private:
55 sp<MockBinder> mBinder;
56 };
57
58 class MockCarWatchdogMonitor : public aawi::ICarWatchdogMonitorDefault {
59 public:
MockCarWatchdogMonitor()60 MockCarWatchdogMonitor() { mBinder = sp<MockBinder>::make(); }
getBinder() const61 sp<MockBinder> getBinder() const { return mBinder; }
62
63 MOCK_METHOD(IBinder*, onAsBinder, (), (override));
64
65 private:
66 sp<MockBinder> mBinder;
67 };
68
constructProcessIdentifier(int32_t pid,int64_t startTimeMillis)69 ProcessIdentifier constructProcessIdentifier(int32_t pid, int64_t startTimeMillis) {
70 ProcessIdentifier processIdentifier;
71 processIdentifier.pid = pid;
72 processIdentifier.startTimeMillis = startTimeMillis;
73 return processIdentifier;
74 }
75
76 } // namespace
77
78 namespace internal {
79
80 class WatchdogProcessServicePeer final {
81 public:
WatchdogProcessServicePeer(const sp<WatchdogProcessService> & watchdogProcessService)82 explicit WatchdogProcessServicePeer(const sp<WatchdogProcessService>& watchdogProcessService) :
83 mWatchdogProcessService(watchdogProcessService) {
84 mWatchdogProcessService->mGetStartTimeForPidFunc = [](pid_t) -> uint64_t { return 12356; };
85 }
86
setVhalService(std::shared_ptr<afav::IVhalClient> service)87 void setVhalService(std::shared_ptr<afav::IVhalClient> service) {
88 mWatchdogProcessService->mVhalService = service;
89 }
90
setNotSupportedVhalProperties(const std::unordered_set<VehicleProperty> & properties)91 void setNotSupportedVhalProperties(const std::unordered_set<VehicleProperty>& properties) {
92 mWatchdogProcessService->mNotSupportedVhalProperties = properties;
93 }
94
95 private:
96 sp<WatchdogProcessService> mWatchdogProcessService;
97 };
98
99 } // namespace internal
100
101 class WatchdogProcessServiceTest : public ::testing::Test {
102 protected:
SetUp()103 void SetUp() override {
104 sp<Looper> looper(Looper::prepare(/*opts=*/0));
105 mWatchdogProcessService = sp<WatchdogProcessService>::make(looper);
106 mMockVehicle = SharedRefBase::make<MockVehicle>();
107 mMockVhalClient = std::make_shared<MockVhalClient>(mMockVehicle);
108 internal::WatchdogProcessServicePeer peer(mWatchdogProcessService);
109 peer.setVhalService(mMockVhalClient);
110 peer.setNotSupportedVhalProperties(
111 {VehicleProperty::WATCHDOG_ALIVE, VehicleProperty::WATCHDOG_TERMINATED_PROCESS});
112 mWatchdogProcessService->start();
113 }
114
TearDown()115 void TearDown() override {
116 mWatchdogProcessService->terminate();
117 mWatchdogProcessService.clear();
118 mMockVhalClient.reset();
119 mMockVehicle.reset();
120 }
121
122 sp<WatchdogProcessService> mWatchdogProcessService;
123 std::shared_ptr<MockVhalClient> mMockVhalClient;
124 std::shared_ptr<MockVehicle> mMockVehicle;
125 };
126
createMockCarWatchdogClient(status_t linkToDeathResult)127 sp<MockCarWatchdogClient> createMockCarWatchdogClient(status_t linkToDeathResult) {
128 sp<MockCarWatchdogClient> client = sp<MockCarWatchdogClient>::make();
129 sp<MockBinder> binder = client->getBinder();
130 EXPECT_CALL(*binder, linkToDeath(_, nullptr, 0)).WillRepeatedly(Return(linkToDeathResult));
131 EXPECT_CALL(*binder, unlinkToDeath(_, nullptr, 0, nullptr)).WillRepeatedly(Return(OK));
132 EXPECT_CALL(*client, onAsBinder()).WillRepeatedly(Return(binder.get()));
133 return client;
134 }
135
createMockCarWatchdogMonitor(status_t linkToDeathResult)136 sp<MockCarWatchdogMonitor> createMockCarWatchdogMonitor(status_t linkToDeathResult) {
137 sp<MockCarWatchdogMonitor> monitor = sp<MockCarWatchdogMonitor>::make();
138 sp<MockBinder> binder = monitor->getBinder();
139 EXPECT_CALL(*binder, linkToDeath(_, nullptr, 0)).WillRepeatedly(Return(linkToDeathResult));
140 EXPECT_CALL(*binder, unlinkToDeath(_, nullptr, 0, nullptr)).WillRepeatedly(Return(OK));
141 EXPECT_CALL(*monitor, onAsBinder()).WillRepeatedly(Return(binder.get()));
142 return monitor;
143 }
144
expectNormalCarWatchdogClient()145 sp<MockCarWatchdogClient> expectNormalCarWatchdogClient() {
146 return createMockCarWatchdogClient(OK);
147 }
148
expectCarWatchdogClientBinderDied()149 sp<MockCarWatchdogClient> expectCarWatchdogClientBinderDied() {
150 return createMockCarWatchdogClient(DEAD_OBJECT);
151 }
152
expectNormalCarWatchdogMonitor()153 sp<MockCarWatchdogMonitor> expectNormalCarWatchdogMonitor() {
154 return createMockCarWatchdogMonitor(OK);
155 }
156
expectCarWatchdogMonitorBinderDied()157 sp<MockCarWatchdogMonitor> expectCarWatchdogMonitorBinderDied() {
158 return createMockCarWatchdogMonitor(DEAD_OBJECT);
159 }
160
TEST_F(WatchdogProcessServiceTest,TestTerminate)161 TEST_F(WatchdogProcessServiceTest, TestTerminate) {
162 std::vector<int32_t> propIds = {static_cast<int32_t>(aahav::VehicleProperty::VHAL_HEARTBEAT)};
163 EXPECT_CALL(*mMockVhalClient, removeOnBinderDiedCallback(_)).Times(1);
164 EXPECT_CALL(*mMockVehicle, unsubscribe(_, propIds))
165 .WillOnce(Return(ByMove(std::move(ndk::ScopedAStatus::ok()))));
166 mWatchdogProcessService->terminate();
167 // TODO(b/217405065): Verify looper removes all MSG_VHAL_HEALTH_CHECK messages.
168 }
169
170 // TODO(b/217405065): Add test to verify the handleVhalDeath method.
171
TEST_F(WatchdogProcessServiceTest,TestRegisterClient)172 TEST_F(WatchdogProcessServiceTest, TestRegisterClient) {
173 sp<MockCarWatchdogClient> client = expectNormalCarWatchdogClient();
174 Status status =
175 mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
176 ASSERT_TRUE(status.isOk()) << status;
177 status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
178 ASSERT_TRUE(status.isOk()) << status;
179 }
180
TEST_F(WatchdogProcessServiceTest,TestUnregisterClient)181 TEST_F(WatchdogProcessServiceTest, TestUnregisterClient) {
182 sp<MockCarWatchdogClient> client = expectNormalCarWatchdogClient();
183 mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
184 Status status = mWatchdogProcessService->unregisterClient(client);
185 ASSERT_TRUE(status.isOk()) << status;
186 ASSERT_FALSE(mWatchdogProcessService->unregisterClient(client).isOk())
187 << "Unregistering an unregistered client should return an error";
188 }
189
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterClientWithDeadBinder)190 TEST_F(WatchdogProcessServiceTest, TestErrorOnRegisterClientWithDeadBinder) {
191 sp<MockCarWatchdogClient> client = expectCarWatchdogClientBinderDied();
192 ASSERT_FALSE(
193 mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL).isOk())
194 << "When linkToDeath fails, registerClient should return an error";
195 }
196
TEST_F(WatchdogProcessServiceTest,TestRegisterCarWatchdogService)197 TEST_F(WatchdogProcessServiceTest, TestRegisterCarWatchdogService) {
198 sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
199 ASSERT_RESULT_OK(mWatchdogProcessService->registerWatchdogServiceHelper(mockServiceHelper));
200
201 sp<MockCarWatchdogServiceForSystem> mockService = sp<MockCarWatchdogServiceForSystem>::make();
202 sp<IBinder> binder = mockService->getBinder();
203
204 Status status = mWatchdogProcessService->registerCarWatchdogService(binder);
205 ASSERT_TRUE(status.isOk()) << status;
206
207 status = mWatchdogProcessService->registerCarWatchdogService(binder);
208 ASSERT_TRUE(status.isOk()) << status;
209 }
210
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterCarWatchdogServiceWithUninitializedWatchdogServiceHelper)211 TEST_F(WatchdogProcessServiceTest,
212 TestErrorOnRegisterCarWatchdogServiceWithUninitializedWatchdogServiceHelper) {
213 sp<MockCarWatchdogServiceForSystem> mockService = sp<MockCarWatchdogServiceForSystem>::make();
214 sp<IBinder> binder = mockService->getBinder();
215
216 ASSERT_FALSE(mWatchdogProcessService->registerCarWatchdogService(binder).isOk())
217 << "Registering car watchdog service should fail when watchdog service helper is "
218 "uninitialized";
219 }
220
TEST_F(WatchdogProcessServiceTest,TestRegisterMonitor)221 TEST_F(WatchdogProcessServiceTest, TestRegisterMonitor) {
222 sp<aawi::ICarWatchdogMonitor> monitorOne = expectNormalCarWatchdogMonitor();
223 sp<aawi::ICarWatchdogMonitor> monitorTwo = expectNormalCarWatchdogMonitor();
224 Status status = mWatchdogProcessService->registerMonitor(monitorOne);
225 ASSERT_TRUE(status.isOk()) << status;
226 status = mWatchdogProcessService->registerMonitor(monitorOne);
227 ASSERT_TRUE(status.isOk()) << status;
228 status = mWatchdogProcessService->registerMonitor(monitorTwo);
229 ASSERT_TRUE(status.isOk()) << status;
230 }
231
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterMonitorWithDeadBinder)232 TEST_F(WatchdogProcessServiceTest, TestErrorOnRegisterMonitorWithDeadBinder) {
233 sp<MockCarWatchdogMonitor> monitor = expectCarWatchdogMonitorBinderDied();
234 ASSERT_FALSE(mWatchdogProcessService->registerMonitor(monitor).isOk())
235 << "When linkToDeath fails, registerMonitor should return an error";
236 }
237
TEST_F(WatchdogProcessServiceTest,TestUnregisterMonitor)238 TEST_F(WatchdogProcessServiceTest, TestUnregisterMonitor) {
239 sp<aawi::ICarWatchdogMonitor> monitor = expectNormalCarWatchdogMonitor();
240 mWatchdogProcessService->registerMonitor(monitor);
241 Status status = mWatchdogProcessService->unregisterMonitor(monitor);
242 ASSERT_TRUE(status.isOk()) << status;
243 ASSERT_FALSE(mWatchdogProcessService->unregisterMonitor(monitor).isOk())
244 << "Unregistering an unregistered monitor should return an error";
245 }
246
TEST_F(WatchdogProcessServiceTest,TestTellClientAlive)247 TEST_F(WatchdogProcessServiceTest, TestTellClientAlive) {
248 sp<ICarWatchdogClient> client = expectNormalCarWatchdogClient();
249 mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
250 ASSERT_FALSE(mWatchdogProcessService->tellClientAlive(client, 1234).isOk())
251 << "tellClientAlive not synced with checkIfAlive should return an error";
252 }
253
TEST_F(WatchdogProcessServiceTest,TestTellCarWatchdogServiceAlive)254 TEST_F(WatchdogProcessServiceTest, TestTellCarWatchdogServiceAlive) {
255 sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
256 ASSERT_RESULT_OK(mWatchdogProcessService->registerWatchdogServiceHelper(mockServiceHelper));
257
258 sp<MockCarWatchdogServiceForSystem> mockService = sp<MockCarWatchdogServiceForSystem>::make();
259
260 std::vector<ProcessIdentifier> processIdentifiers;
261 processIdentifiers.push_back(
262 constructProcessIdentifier(/* pid= */ 111, /* startTimeMillis= */ 0));
263 processIdentifiers.push_back(
264 constructProcessIdentifier(/* pid= */ 222, /* startTimeMillis= */ 0));
265 ASSERT_FALSE(mWatchdogProcessService
266 ->tellCarWatchdogServiceAlive(mockService, processIdentifiers, 1234)
267 .isOk())
268 << "tellCarWatchdogServiceAlive not synced with checkIfAlive should return an error";
269 }
270
TEST_F(WatchdogProcessServiceTest,TestTellDumpFinished)271 TEST_F(WatchdogProcessServiceTest, TestTellDumpFinished) {
272 sp<aawi::ICarWatchdogMonitor> monitor = expectNormalCarWatchdogMonitor();
273 ASSERT_FALSE(mWatchdogProcessService
274 ->tellDumpFinished(monitor,
275 constructProcessIdentifier(/* pid= */ 1234,
276 /* startTimeMillis= */ 0))
277 .isOk())
278 << "Unregistered monitor cannot call tellDumpFinished";
279 mWatchdogProcessService->registerMonitor(monitor);
280 Status status =
281 mWatchdogProcessService
282 ->tellDumpFinished(monitor,
283 constructProcessIdentifier(/* pid= */ 1234,
284 /* startTimeMillis= */ 0));
285 ASSERT_TRUE(status.isOk()) << status;
286 }
287
288 } // namespace watchdog
289 } // namespace automotive
290 } // namespace android
291