• 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 "MockIoOveruseMonitor.h"
18 #include "MockResourceOveruseListener.h"
19 #include "MockWatchdogPerfService.h"
20 #include "MockWatchdogProcessService.h"
21 #include "MockWatchdogServiceHelper.h"
22 #include "WatchdogBinderMediator.h"
23 
24 #include <android-base/stringprintf.h>
25 #include <binder/IBinder.h>
26 #include <gmock/gmock.h>
27 #include <gtest/gtest.h>
28 #include <utils/String16.h>
29 
30 #include <errno.h>
31 
32 namespace android {
33 namespace automotive {
34 namespace watchdog {
35 
36 using ::android::sp;
37 using ::android::String16;
38 using ::android::base::Result;
39 using ::android::base::StringAppendF;
40 using ::android::binder::Status;
41 using ::testing::_;
42 using ::testing::DoAll;
43 using ::testing::Return;
44 using ::testing::SaveArg;
45 using ::testing::SetArgPointee;
46 using ::testing::UnorderedElementsAreArray;
47 
48 namespace {
49 
50 const std::function<android::base::Result<void>(const char*, const android::sp<android::IBinder>&)>
51         kAddServiceFunctionStub =
__anon6dfd99110202(const char*, const android::sp<android::IBinder>&) 52                 [](const char*, const android::sp<android::IBinder>&) -> Result<void> {
53     return Result<void>{};
54 };
55 
56 class MockICarWatchdogClient : public ICarWatchdogClient {
57 public:
58     MOCK_METHOD(Status, checkIfAlive, (int32_t sessionId, TimeoutLength timeout), (override));
59     MOCK_METHOD(Status, prepareProcessTermination, (), (override));
60     MOCK_METHOD(IBinder*, onAsBinder, (), (override));
61     MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
62     MOCK_METHOD(std::string, getInterfaceHash, (), (override));
63 };
64 
toString(const std::vector<ResourceOveruseStats> & resourceOveruseStats)65 std::string toString(const std::vector<ResourceOveruseStats>& resourceOveruseStats) {
66     std::string buffer;
67     for (const auto& stats : resourceOveruseStats) {
68         StringAppendF(&buffer, "%s\n", stats.toString().c_str());
69     }
70     return buffer;
71 }
72 
73 }  // namespace
74 
75 namespace internal {
76 
77 class WatchdogBinderMediatorPeer {
78 public:
WatchdogBinderMediatorPeer(const sp<WatchdogBinderMediator> & mediator)79     explicit WatchdogBinderMediatorPeer(const sp<WatchdogBinderMediator>& mediator) :
80           mMediator(mediator) {}
~WatchdogBinderMediatorPeer()81     ~WatchdogBinderMediatorPeer() { mMediator.clear(); }
82 
init(const sp<IIoOveruseMonitor> & ioOveruseMonitor)83     Result<void> init(const sp<IIoOveruseMonitor>& ioOveruseMonitor) {
84         mMediator->mIoOveruseMonitor = ioOveruseMonitor;
85         return mMediator->init();
86     }
87 
88 private:
89     sp<WatchdogBinderMediator> mMediator;
90 };
91 
92 }  // namespace internal
93 
94 class WatchdogBinderMediatorTest : public ::testing::Test {
95 protected:
SetUp()96     virtual void SetUp() {
97         mMockWatchdogProcessService = sp<MockWatchdogProcessService>::make();
98         mMockWatchdogPerfService = sp<MockWatchdogPerfService>::make();
99         mWatchdogBinderMediator =
100                 sp<WatchdogBinderMediator>::make(mMockWatchdogProcessService,
101                                                  mMockWatchdogPerfService,
102                                                  sp<MockWatchdogServiceHelper>::make(),
103                                                  kAddServiceFunctionStub);
104         internal::WatchdogBinderMediatorPeer mediatorPeer(mWatchdogBinderMediator);
105         mMockIoOveruseMonitor = sp<MockIoOveruseMonitor>::make();
106         ASSERT_RESULT_OK(mediatorPeer.init(mMockIoOveruseMonitor));
107     }
TearDown()108     virtual void TearDown() {
109         mMockWatchdogProcessService.clear();
110         mMockWatchdogPerfService.clear();
111         mMockIoOveruseMonitor.clear();
112         mWatchdogBinderMediator.clear();
113     }
114 
115     sp<MockWatchdogProcessService> mMockWatchdogProcessService;
116     sp<MockWatchdogPerfService> mMockWatchdogPerfService;
117     sp<MockIoOveruseMonitor> mMockIoOveruseMonitor;
118     sp<WatchdogBinderMediator> mWatchdogBinderMediator;
119 };
120 
TEST_F(WatchdogBinderMediatorTest,TestInit)121 TEST_F(WatchdogBinderMediatorTest, TestInit) {
122     sp<WatchdogBinderMediator> mediator =
123             sp<WatchdogBinderMediator>::make(sp<MockWatchdogProcessService>::make(),
124                                              sp<MockWatchdogPerfService>::make(),
125                                              sp<MockWatchdogServiceHelper>::make(),
126                                              kAddServiceFunctionStub);
127 
128     ASSERT_RESULT_OK(mediator->init());
129 
130     ASSERT_NE(mediator->mWatchdogProcessService, nullptr);
131     ASSERT_NE(mediator->mWatchdogPerfService, nullptr);
132     ASSERT_NE(mediator->mIoOveruseMonitor, nullptr);
133     ASSERT_NE(mediator->mWatchdogInternalHandler, nullptr);
134 }
135 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnInitWithNullServiceInstances)136 TEST_F(WatchdogBinderMediatorTest, TestErrorOnInitWithNullServiceInstances) {
137     auto mockWatchdogProcessService = sp<MockWatchdogProcessService>::make();
138     auto mockWatchdogPerfservice = sp<MockWatchdogPerfService>::make();
139     auto mockWatchdogServiceHelper = sp<MockWatchdogServiceHelper>::make();
140     sp<WatchdogBinderMediator> mediator =
141             sp<WatchdogBinderMediator>::make(nullptr, mockWatchdogPerfservice,
142                                              mockWatchdogServiceHelper, kAddServiceFunctionStub);
143 
144     EXPECT_FALSE(mediator->init().ok()) << "No error returned on nullptr watchdog process service";
145     mediator.clear();
146 
147     mediator = sp<WatchdogBinderMediator>::make(mockWatchdogProcessService, nullptr,
148                                                 mockWatchdogServiceHelper, kAddServiceFunctionStub);
149 
150     EXPECT_FALSE(mediator->init().ok()) << "No error returned on nullptr watchdog perf service";
151     mediator.clear();
152 
153     mediator = sp<WatchdogBinderMediator>::make(mockWatchdogProcessService, mockWatchdogPerfservice,
154                                                 nullptr, kAddServiceFunctionStub);
155 
156     EXPECT_FALSE(mediator->init().ok()) << "No error returned on nullptr watchdog service helper";
157     mediator.clear();
158 
159     mediator = sp<WatchdogBinderMediator>::make(nullptr, nullptr, nullptr, kAddServiceFunctionStub);
160 
161     EXPECT_FALSE(mediator->init().ok()) << "No error returned on null services";
162     mediator.clear();
163 }
164 
TEST_F(WatchdogBinderMediatorTest,TestTerminate)165 TEST_F(WatchdogBinderMediatorTest, TestTerminate) {
166     EXPECT_NE(mWatchdogBinderMediator->mWatchdogProcessService, nullptr);
167     EXPECT_NE(mWatchdogBinderMediator->mWatchdogPerfService, nullptr);
168     EXPECT_NE(mWatchdogBinderMediator->mIoOveruseMonitor, nullptr);
169     EXPECT_NE(mWatchdogBinderMediator->mWatchdogInternalHandler, nullptr);
170 
171     mWatchdogBinderMediator->terminate();
172 
173     EXPECT_EQ(mWatchdogBinderMediator->mWatchdogProcessService, nullptr);
174     EXPECT_EQ(mWatchdogBinderMediator->mWatchdogPerfService, nullptr);
175     EXPECT_EQ(mWatchdogBinderMediator->mIoOveruseMonitor, nullptr);
176     EXPECT_EQ(mWatchdogBinderMediator->mWatchdogInternalHandler, nullptr);
177 }
178 
TEST_F(WatchdogBinderMediatorTest,TestDumpWithEmptyArgs)179 TEST_F(WatchdogBinderMediatorTest, TestDumpWithEmptyArgs) {
180     EXPECT_CALL(*mMockWatchdogProcessService, dump(-1, _)).WillOnce(Return(Result<void>()));
181     EXPECT_CALL(*mMockWatchdogPerfService, onDump(-1)).WillOnce(Return(Result<void>()));
182     mWatchdogBinderMediator->dump(-1, Vector<String16>());
183 }
184 
TEST_F(WatchdogBinderMediatorTest,TestDumpWithStartCustomPerfCollection)185 TEST_F(WatchdogBinderMediatorTest, TestDumpWithStartCustomPerfCollection) {
186     EXPECT_CALL(*mMockWatchdogPerfService, onCustomCollection(-1, _))
187             .WillOnce(Return(Result<void>()));
188 
189     Vector<String16> args;
190     args.push_back(String16(kStartCustomCollectionFlag));
191     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
192 }
193 
TEST_F(WatchdogBinderMediatorTest,TestDumpWithStopCustomPerfCollection)194 TEST_F(WatchdogBinderMediatorTest, TestDumpWithStopCustomPerfCollection) {
195     EXPECT_CALL(*mMockWatchdogPerfService, onCustomCollection(-1, _))
196             .WillOnce(Return(Result<void>()));
197 
198     Vector<String16> args;
199     args.push_back(String16(kEndCustomCollectionFlag));
200     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
201 }
202 
TEST_F(WatchdogBinderMediatorTest,TestDumpWithResetResourceOveruseStats)203 TEST_F(WatchdogBinderMediatorTest, TestDumpWithResetResourceOveruseStats) {
204     std::vector<std::string> actualPackages;
205     EXPECT_CALL(*mMockIoOveruseMonitor, resetIoOveruseStats(_))
206             .WillOnce(DoAll(SaveArg<0>(&actualPackages), Return(Result<void>())));
207 
208     Vector<String16> args;
209     args.push_back(String16(kResetResourceOveruseStatsFlag));
210     args.push_back(String16("packageA,packageB"));
211     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
212     ASSERT_EQ(actualPackages, std::vector<std::string>({"packageA", "packageB"}));
213 }
214 
TEST_F(WatchdogBinderMediatorTest,TestFailsDumpWithInvalidResetResourceOveruseStatsArg)215 TEST_F(WatchdogBinderMediatorTest, TestFailsDumpWithInvalidResetResourceOveruseStatsArg) {
216     EXPECT_CALL(*mMockIoOveruseMonitor, resetIoOveruseStats(_)).Times(0);
217 
218     Vector<String16> args;
219     args.push_back(String16(kResetResourceOveruseStatsFlag));
220     args.push_back(String16(""));
221     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), BAD_VALUE);
222 }
223 
TEST_F(WatchdogBinderMediatorTest,TestDumpWithInvalidDumpArgs)224 TEST_F(WatchdogBinderMediatorTest, TestDumpWithInvalidDumpArgs) {
225     Vector<String16> args;
226     args.push_back(String16("--invalid_option"));
227     int nullFd = open("/dev/null", O_RDONLY);
228     EXPECT_CALL(*mMockWatchdogProcessService, dump(nullFd, _)).WillOnce(Return(Result<void>()));
229     EXPECT_CALL(*mMockWatchdogPerfService, onDump(nullFd)).WillOnce(Return(Result<void>()));
230 
231     EXPECT_EQ(mWatchdogBinderMediator->dump(nullFd, args), OK) << "Error returned on invalid args";
232     close(nullFd);
233 }
234 
TEST_F(WatchdogBinderMediatorTest,TestRegisterClient)235 TEST_F(WatchdogBinderMediatorTest, TestRegisterClient) {
236     sp<ICarWatchdogClient> client = sp<MockICarWatchdogClient>::make();
237     TimeoutLength timeout = TimeoutLength::TIMEOUT_MODERATE;
238     EXPECT_CALL(*mMockWatchdogProcessService, registerClient(client, timeout))
239             .WillOnce(Return(Status::ok()));
240     Status status = mWatchdogBinderMediator->registerClient(client, timeout);
241     ASSERT_TRUE(status.isOk()) << status;
242 }
243 
TEST_F(WatchdogBinderMediatorTest,TestUnregisterClient)244 TEST_F(WatchdogBinderMediatorTest, TestUnregisterClient) {
245     sp<ICarWatchdogClient> client = sp<MockICarWatchdogClient>::make();
246     EXPECT_CALL(*mMockWatchdogProcessService, unregisterClient(client))
247             .WillOnce(Return(Status::ok()));
248     Status status = mWatchdogBinderMediator->unregisterClient(client);
249     ASSERT_TRUE(status.isOk()) << status;
250 }
251 
TEST_F(WatchdogBinderMediatorTest,TestTellClientAlive)252 TEST_F(WatchdogBinderMediatorTest, TestTellClientAlive) {
253     sp<ICarWatchdogClient> client = sp<MockICarWatchdogClient>::make();
254     EXPECT_CALL(*mMockWatchdogProcessService, tellClientAlive(client, 456))
255             .WillOnce(Return(Status::ok()));
256     Status status = mWatchdogBinderMediator->tellClientAlive(client, 456);
257     ASSERT_TRUE(status.isOk()) << status;
258 }
259 
TEST_F(WatchdogBinderMediatorTest,TestAddResourceOveruseListener)260 TEST_F(WatchdogBinderMediatorTest, TestAddResourceOveruseListener) {
261     sp<IResourceOveruseListener> listener = sp<MockResourceOveruseListener>::make();
262     EXPECT_CALL(*mMockIoOveruseMonitor, addIoOveruseListener(listener))
263             .WillOnce(Return(Result<void>{}));
264 
265     Status status =
266             mWatchdogBinderMediator->addResourceOveruseListener({ResourceType::IO}, listener);
267     ASSERT_TRUE(status.isOk()) << status;
268 }
269 
TEST_F(WatchdogBinderMediatorTest,TestErrorsAddResourceOveruseListenerOnInvalidArgs)270 TEST_F(WatchdogBinderMediatorTest, TestErrorsAddResourceOveruseListenerOnInvalidArgs) {
271     sp<IResourceOveruseListener> listener = sp<MockResourceOveruseListener>::make();
272     EXPECT_CALL(*mMockIoOveruseMonitor, addIoOveruseListener(listener)).Times(0);
273 
274     ASSERT_FALSE(mWatchdogBinderMediator->addResourceOveruseListener({}, listener).isOk())
275             << "Should fail on empty resource types";
276 
277     ASSERT_FALSE(
278             mWatchdogBinderMediator->addResourceOveruseListener({ResourceType::IO}, nullptr).isOk())
279             << "Should fail on null listener";
280 }
281 
TEST_F(WatchdogBinderMediatorTest,TestRemoveResourceOveruseListener)282 TEST_F(WatchdogBinderMediatorTest, TestRemoveResourceOveruseListener) {
283     sp<IResourceOveruseListener> listener = sp<MockResourceOveruseListener>::make();
284     EXPECT_CALL(*mMockIoOveruseMonitor, removeIoOveruseListener(listener))
285             .WillOnce(Return(Result<void>{}));
286 
287     Status status = mWatchdogBinderMediator->removeResourceOveruseListener(listener);
288     ASSERT_TRUE(status.isOk()) << status;
289 }
290 
TEST_F(WatchdogBinderMediatorTest,TestGetResourceOveruseStats)291 TEST_F(WatchdogBinderMediatorTest, TestGetResourceOveruseStats) {
292     IoOveruseStats ioOveruseStats;
293     ioOveruseStats.killableOnOveruse = true;
294     ioOveruseStats.startTime = 99898;
295     ioOveruseStats.durationInSeconds = 12345;
296     ioOveruseStats.totalOveruses = 3;
297     std::vector<ResourceOveruseStats> expected;
298     ResourceOveruseStats stats;
299     stats.set<ResourceOveruseStats::ioOveruseStats>(ioOveruseStats);
300     expected.emplace_back(std::move(stats));
301 
302     EXPECT_CALL(*mMockIoOveruseMonitor, getIoOveruseStats(_))
303             .WillOnce(DoAll(SetArgPointee<0>(ioOveruseStats), Return(Result<void>{})));
304 
305     std::vector<ResourceOveruseStats> actual;
306     Status status = mWatchdogBinderMediator->getResourceOveruseStats({ResourceType::IO}, &actual);
307     ASSERT_TRUE(status.isOk()) << status;
308     EXPECT_THAT(actual, UnorderedElementsAreArray(expected))
309             << "Expected: " << toString(expected) << "\nActual: " << toString(actual);
310 }
311 
TEST_F(WatchdogBinderMediatorTest,TestErrorsGetResourceOveruseStatsOnInvalidArgs)312 TEST_F(WatchdogBinderMediatorTest, TestErrorsGetResourceOveruseStatsOnInvalidArgs) {
313     sp<IResourceOveruseListener> listener = sp<MockResourceOveruseListener>::make();
314     EXPECT_CALL(*mMockIoOveruseMonitor, getIoOveruseStats(_)).Times(0);
315 
316     std::vector<ResourceOveruseStats> actual;
317     ASSERT_FALSE(mWatchdogBinderMediator->getResourceOveruseStats({}, &actual).isOk())
318             << "Should fail on empty resource types";
319 
320     ASSERT_FALSE(
321             mWatchdogBinderMediator->getResourceOveruseStats({ResourceType::IO}, nullptr).isOk())
322             << "Should fail on null listener";
323 }
324 
TEST_F(WatchdogBinderMediatorTest,TestRegisterMediator)325 TEST_F(WatchdogBinderMediatorTest, TestRegisterMediator) {
326     Status status = mWatchdogBinderMediator->registerMediator(nullptr);
327     ASSERT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
328 }
329 
TEST_F(WatchdogBinderMediatorTest,TestUnregisterMediator)330 TEST_F(WatchdogBinderMediatorTest, TestUnregisterMediator) {
331     Status status = mWatchdogBinderMediator->unregisterMediator(nullptr);
332     ASSERT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
333 }
334 
TEST_F(WatchdogBinderMediatorTest,TestRegisterMonitor)335 TEST_F(WatchdogBinderMediatorTest, TestRegisterMonitor) {
336     Status status = mWatchdogBinderMediator->registerMonitor(nullptr);
337     ASSERT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
338 }
339 
TEST_F(WatchdogBinderMediatorTest,TestUnregisterMonitor)340 TEST_F(WatchdogBinderMediatorTest, TestUnregisterMonitor) {
341     Status status = mWatchdogBinderMediator->unregisterMonitor(nullptr);
342     ASSERT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
343 }
344 
TEST_F(WatchdogBinderMediatorTest,TestTellMediatorAlive)345 TEST_F(WatchdogBinderMediatorTest, TestTellMediatorAlive) {
346     Status status = mWatchdogBinderMediator->tellMediatorAlive(nullptr, {}, 0);
347     ASSERT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
348 }
349 
TEST_F(WatchdogBinderMediatorTest,TestTellDumpFinished)350 TEST_F(WatchdogBinderMediatorTest, TestTellDumpFinished) {
351     Status status = mWatchdogBinderMediator->tellDumpFinished(nullptr, 0);
352     ASSERT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
353 }
354 
TEST_F(WatchdogBinderMediatorTest,TestNotifySystemStateChange)355 TEST_F(WatchdogBinderMediatorTest, TestNotifySystemStateChange) {
356     Status status = mWatchdogBinderMediator->notifySystemStateChange(StateType::POWER_CYCLE, 0, 0);
357     ASSERT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
358 }
359 
360 }  // namespace watchdog
361 }  // namespace automotive
362 }  // namespace android
363