• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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