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 }