1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <cstdlib>
16 #include <string>
17 #include "gtest/gtest.h"
18 #include "message_parcel.h"
19 #include "iservice_registry.h"
20 #include "if_system_ability_manager.h"
21 #include "system_ability_definition.h"
22 #include "listen_ability_proxy.h"
23 #include "test_sa_proxy_cache_proxy.h"
24 #include "test_log.h"
25
26 using namespace testing::ext;
27
28 namespace OHOS {
29 namespace {
30 int g_mockReturn;
31 }
32
33 class SaProxyCacheTest : public testing::Test {
34 public:
35 static void SetUpTestCase();
36 static void TearDownTestCase();
37 void SetUp();
38 void TearDown();
39 };
40
SetUpTestCase()41 void SaProxyCacheTest::SetUpTestCase()
42 {}
43
TearDownTestCase()44 void SaProxyCacheTest::TearDownTestCase()
45 {}
46
SetUp()47 void SaProxyCacheTest::SetUp()
48 {}
49
TearDown()50 void SaProxyCacheTest::TearDown()
51 {}
52
CheckCallGetDoubleFuncIpcTimes(sptr<ITestSaProxyCache> & proxy,int32_t input,int32_t expectIpcTimes)53 bool CheckCallGetDoubleFuncIpcTimes(sptr<ITestSaProxyCache>& proxy, int32_t input, int32_t expectIpcTimes)
54 {
55 constexpr double pi = 3.14;
56 double retDouble;
57
58 auto ret = proxy->GetDoubleFunc(input, retDouble);
59 if (ret != ERR_OK) {
60 EXPECT_EQ(ret, ERR_OK);
61 return false;
62 }
63 EXPECT_DOUBLE_EQ(retDouble, input * pi);
64 int times = proxy->TestGetIpcSendRequestTimes();
65 if (times != expectIpcTimes) {
66 EXPECT_EQ(times, expectIpcTimes);
67 return false;
68 }
69
70 return true;
71 }
72
73 /**
74 * @tc.name: SaProxyCacheTest001
75 * @tc.desc: test proxy cache
76 * @tc.type: FUNC
77 * @tc.require:
78 */
79 HWTEST_F(SaProxyCacheTest, SaProxyCacheTest001, TestSize.Level2)
80 {
81 sptr<ISystemAbilityManager> systemAbilityManager =
82 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
83 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(DISTRIBUTED_SCHED_TEST_TT_ID);
84 sptr<ITestSaProxyCache> proxy = iface_cast<ITestSaProxyCache>(remoteObject);
85 EXPECT_NE(proxy, nullptr);
86 bool ret;
87
88 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 3, 1), true);
89
90 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 4, 2), true);
91
92 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 10, 3), true);
93
94 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 10, 3), true);
95
96 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 20, 4), true);
97
98 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 20, 4), true);
99
100 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 100, 5), true);
101
102 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 1000, 6), true);
103
104 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 2000, 7), true);
105
106 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 3000, 8), true);
107
108 // test cache hit
109 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 4, 8), true);
110
111 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 1000, 8), true);
112
113 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 3000, 8), true);
114
115 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 3000, 8), true);
116
117 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 2000, 8), true);
118
119 // exceed cache map size, eliminate cache (3, 9.42)
120 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 10000, 9), true);
121
122 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 3, 10), true);
123
124 std::string input("AABB");
125 std::string output;
126 ret = proxy->GetStringFunc(input, output);
127 EXPECT_EQ(ret, ERR_OK);
128 EXPECT_EQ(output, "AABBBBAA");
129 EXPECT_EQ(proxy->TestGetIpcSendRequestTimes(), 11);
130
131 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 10, 12), true);
132
133 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 10, 12), true);
134
135 // timeout
136 sleep(5);
137 EXPECT_EQ(CheckCallGetDoubleFuncIpcTimes(proxy, 10, 13), true);
138
139 output.clear();
140 EXPECT_EQ(proxy->GetStringFunc(input, output), ERR_OK);
141 EXPECT_EQ(output, "AABBBBAA");
142 EXPECT_EQ(proxy->TestGetIpcSendRequestTimes(), 14);
143 }
144
145 class MockIRemoteObject : public IRemoteObject {
146 public:
MockIRemoteObject()147 MockIRemoteObject() : IRemoteObject(u"mock_i_remote_object") {}
148
~MockIRemoteObject()149 ~MockIRemoteObject() {}
150
GetObjectRefCount()151 int32_t GetObjectRefCount() override
152 {
153 return 0;
154 }
155
SendRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)156 int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override
157 {
158 DTEST_LOG << "mockmockmock" << std::endl;
159 reply.WriteInt32(ERR_PERMISSION_DENIED);
160 return g_mockReturn;
161 }
162
IsProxyObject() const163 bool IsProxyObject() const override
164 {
165 return true;
166 }
167
CheckObjectLegality() const168 bool CheckObjectLegality() const override
169 {
170 return true;
171 }
172
AddDeathRecipient(const sptr<DeathRecipient> & recipient)173 bool AddDeathRecipient(const sptr<DeathRecipient> &recipient) override
174 {
175 return true;
176 }
177
RemoveDeathRecipient(const sptr<DeathRecipient> & recipient)178 bool RemoveDeathRecipient(const sptr<DeathRecipient> &recipient) override
179 {
180 return true;
181 }
182
Marshalling(Parcel & parcel) const183 bool Marshalling(Parcel &parcel) const override
184 {
185 return true;
186 }
187
AsInterface()188 sptr<IRemoteBroker> AsInterface() override
189 {
190 return nullptr;
191 }
192
Dump(int fd,const std::vector<std::u16string> & args)193 int Dump(int fd, const std::vector<std::u16string> &args) override
194 {
195 return 0;
196 }
197
GetObjectDescriptor() const198 std::u16string GetObjectDescriptor() const
199 {
200 std::u16string descriptor = std::u16string();
201 return descriptor;
202 }
203 };
204
205 /**
206 * @tc.name: SaProxyCacheTest002
207 * @tc.desc: test abnormal barnch
208 * @tc.type: FUNC
209 * @tc.require:
210 */
211 HWTEST_F(SaProxyCacheTest, SaProxyCacheTest002, TestSize.Level2)
212 {
213 {
214 g_mockReturn = ERR_TIMED_OUT;
215 sptr<MockIRemoteObject> iRemoteObject = sptr<MockIRemoteObject>(new (std::nothrow) MockIRemoteObject());
216 EXPECT_TRUE(iRemoteObject != nullptr);
217 TestSaProxyCacheProxy p(iRemoteObject);
218 std::string input("hello_test");
219 std::string output;
220 auto ret = p.GetStringFunc(input, output);
221 EXPECT_EQ(ret, ERR_TIMED_OUT);
222 EXPECT_EQ(p.TestGetIpcSendRequestTimes(), 1);
223
224 output.clear();
225 ret = p.GetStringFunc(input, output);
226 EXPECT_EQ(p.TestGetIpcSendRequestTimes(), 2);
227 }
228
229 {
230 g_mockReturn = ERR_OK;
231 sptr<MockIRemoteObject> iRemoteObject = sptr<MockIRemoteObject>(new (std::nothrow) MockIRemoteObject());
232 EXPECT_TRUE(iRemoteObject != nullptr);
233 TestSaProxyCacheProxy p(iRemoteObject);
234
235 double retDouble;
236 auto ret = p.GetDoubleFunc(100, retDouble);
237 EXPECT_EQ(ret, ERR_PERMISSION_DENIED);
238 EXPECT_EQ(p.TestGetIpcSendRequestTimes(), 1);
239
240 ret = p.GetDoubleFunc(100, retDouble);
241 EXPECT_EQ(p.TestGetIpcSendRequestTimes(), 2);
242 }
243 }
244
245 /**
246 * @tc.name: SaProxyCacheTest003
247 * @tc.desc: test proxy object and cache are destroyed together
248 * @tc.type: FUNC
249 * @tc.require:
250 */
251 HWTEST_F(SaProxyCacheTest, SaProxyCacheTest003, TestSize.Level2)
252 {
253 std::vector<bool> input;
254 std::vector<int8_t> output;
255 std::vector<int8_t> expect;
256 input.push_back(true);
257 input.push_back(false);
258 input.push_back(true);
259 for (auto i:input) {
260 expect.push_back(i == true ? 1 : -1);
261 }
262 {
263 sptr<ISystemAbilityManager> systemAbilityManager =
264 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
265 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(DISTRIBUTED_SCHED_TEST_TT_ID);
266 sptr<ITestSaProxyCache> proxy = iface_cast<ITestSaProxyCache>(remoteObject);
267 EXPECT_NE(proxy, nullptr);
268
269 int ret = proxy->GetVectorFunc(input, output);
270 EXPECT_EQ(ret, ERR_OK);
271 EXPECT_EQ((output == expect), 1);
272 EXPECT_EQ(proxy->TestGetIpcSendRequestTimes(), 1);
273
274 output.clear();
275 ret = proxy->GetVectorFunc(input, output);
276 EXPECT_EQ(ret, ERR_OK);
277 EXPECT_EQ((output == expect), 1);
278 EXPECT_EQ(proxy->TestGetIpcSendRequestTimes(), 1);
279 }
280
281 sptr<ISystemAbilityManager> systemAbilityManager =
282 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
283 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(DISTRIBUTED_SCHED_TEST_TT_ID);
284 sptr<ITestSaProxyCache> proxy = iface_cast<ITestSaProxyCache>(remoteObject);
285 EXPECT_NE(proxy, nullptr);
286
287 output.clear();
288 auto ret = proxy->GetVectorFunc(input, output);
289 EXPECT_EQ(ret, ERR_OK);
290 EXPECT_EQ((output == expect), 1);
291 EXPECT_EQ(proxy->TestGetIpcSendRequestTimes(), 1);
292 }
293
294 /**
295 * @tc.name: SaProxyCacheTest004
296 * @tc.desc: test clear cache when sa stub exits
297 * @tc.type: FUNC
298 * @tc.require:
299 */
300 HWTEST_F(SaProxyCacheTest, SaProxyCacheTest004, TestSize.Level2)
301 {
302 sptr<ISystemAbilityManager> systemAbilityManager =
303 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
304 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(DISTRIBUTED_SCHED_TEST_TT_ID);
305 sptr<ITestSaProxyCache> proxy = iface_cast<ITestSaProxyCache>(remoteObject);
306 EXPECT_NE(proxy, nullptr);
307
308 sptr<IRemoteObject> remoteObject1 = systemAbilityManager->GetSystemAbility(1494);
309 sptr<IListenAbility> listenProxy = iface_cast<IListenAbility>(remoteObject1);
310 EXPECT_NE(listenProxy, nullptr);
311
312 int pid;
313 double retDouble, retDouble2;
314 auto ret = proxy->GetSaPid(pid);
315 EXPECT_EQ(ret, ERR_OK);
316
317 std::string cmd = "kill -9 ";
318 cmd += std::to_string(pid);
319
320 CheckCallGetDoubleFuncIpcTimes(proxy, 3, 1);
321
322 CheckCallGetDoubleFuncIpcTimes(proxy, 3, 1);
323
324 std::string input("AABB");
325 std::string output;
326 ret = proxy->GetStringFunc(input, output);
327 EXPECT_EQ(ret, ERR_OK);
328 EXPECT_EQ(output, "AABBBBAA");
329 EXPECT_EQ(proxy->TestGetIpcSendRequestTimes(), 2);
330
331 EXPECT_EQ(listenProxy->AddVolume(100), 101);
332 EXPECT_EQ(listenProxy->TestSaCallSa(100, retDouble2), ERR_OK);
333
334 system(cmd.c_str());
335 DTEST_LOG << cmd << std::endl;
336
337 int trytime = 3;
338 ret = ERR_OK;
339 while ((ret == ERR_OK) && (trytime != 0)) {
340 ret = proxy->GetDoubleFunc(3, retDouble);
341 usleep(500000);
342 trytime--;
343 }
344 EXPECT_NE(ret, ERR_OK);
345 EXPECT_GT(proxy->TestGetIpcSendRequestTimes(), 2);
346
347 int currIpcSendRequestTimes = proxy->TestGetIpcSendRequestTimes();
348 ret = proxy->GetStringFunc(input, output);
349 EXPECT_NE(ret, ERR_OK);
350 EXPECT_GT(proxy->TestGetIpcSendRequestTimes(), currIpcSendRequestTimes);
351
352 ret = listenProxy->TestSaCallSa(100, retDouble2);
353 EXPECT_NE(ret, ERR_OK);
354
355 int32_t times;
356 ret = listenProxy->TestGetIpcSendRequestTimes(times);
357 EXPECT_EQ(ret, ERR_OK);
358 EXPECT_GT(times, 1);
359
360 EXPECT_EQ(listenProxy->AddVolume(100), 101);
361 EXPECT_EQ(listenProxy->TestClearSa1493Proxy_(), ERR_OK);
362 }
363 }