1 /*
2  * Copyright (c) 2022 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 
16 #include "gtest/gtest.h"
17 
18 #include <ctime>
19 
20 #include "ipc_proxy.h"
21 #include "ipc_skeleton.h"
22 #include "rpc_errno.h"
23 #include "rpc_log.h"
24 #include "serializer.h"
25 
26 namespace {
27 constexpr int32_t PERFORMANCE_TEST_TIMES = 100;
28 SvcIdentity sidServer;
29 MessageOption g_option = {
30     .flags = TF_OP_SYNC
31 };
32 
33 uint32_t cbId1 = -1;
34 uint32_t cbId2 = -1;
35 uint32_t cbId3 = -1;
36 uint32_t cbId4 = -1;
37 uint32_t cbId5 = -1;
38 
RemoteRequest(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)39 int32_t RemoteRequest(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
40 {
41     int32_t result = ERR_NONE;
42     RPC_LOG_INFO("client OnRemoteRequest called....");
43     switch (code) {
44         case CLIENT_OP_ADD: {
45             int32_t a;
46             ReadInt32(data, &a);
47             int32_t b;
48             ReadInt32(data, &b);
49             WriteInt32(reply, a + b);
50             break;
51         }
52         case CLIENT_OP_SUB: {
53             int32_t a;
54             ReadInt32(data, &a);
55             int32_t b;
56             ReadInt32(data, &b);
57             WriteInt32(reply, a - b);
58             break;
59         }
60         case CLIENT_OP_PRINT: {
61             size_t len;
62             char *str = (char *)ReadString(data, &len);
63             RPC_LOG_INFO("client pop string %s....", str);
64             break;
65         }
66         default:
67             RPC_LOG_ERROR("unknown code %u", code);
68             break;
69     }
70     return result;
71 }
72 
ServerDead1()73 void ServerDead1()
74 {
75     RPC_LOG_INFO("#### server dead callback11 called ... ");
76 }
77 
ServerDead2()78 void ServerDead2()
79 {
80     RPC_LOG_INFO("#### server dead callback22 called ... ");
81 }
82 
ServerDead3()83 void ServerDead3()
84 {
85     RPC_LOG_INFO("#### server dead callback33 called ... ");
86 }
87 }
88 
89 using namespace testing::ext;
90 
91 namespace OHOS {
92 class IpcClientTest : public testing::Test {
93 public:
SetUpTestCase()94     static void SetUpTestCase()
95     {
96         pid_t pid = fork();
97         if (pid != 0) {
98             exit(0);
99         }
100         RPC_LOG_INFO("----------test case for ipc client start-------------\n");
101     }
TearDownTestCase()102     static void TearDownTestCase() {}
SetUp()103     void SetUp() {}
TearDown()104     void TearDown() {}
105 };
106 
107 HWTEST_F(IpcClientTest, IpcClientTest001, TestSize.Level1)
108 {
109     IpcIo data1;
110     uint8_t tmpData1[IPC_MAX_SIZE];
111     IpcIoInit(&data1, tmpData1, IPC_MAX_SIZE, 0);
112     WriteInt32(&data1, SERVER_SA_ID1);
113     SvcIdentity target = {
114         .handle = 0
115     };
116     IpcIo reply1;
117     uintptr_t ptr = 0;
118     int ret = SendRequest(target, GET_SYSTEM_ABILITY_TRANSACTION, &data1, &reply1, g_option, &ptr);
119     ReadRemoteObject(&reply1, &sidServer);
120     FreeBuffer((void *)ptr);
121     EXPECT_EQ(ret, ERR_NONE);
122 }
123 
124 HWTEST_F(IpcClientTest, IpcClientTest002, TestSize.Level1)
125 {
126     IpcIo data2;
127     uint8_t tmpData2[IPC_MAX_SIZE];
128     IpcIoInit(&data2, tmpData2, IPC_MAX_SIZE, 0);
129     WriteInt32(&data2, OP_A);
130     WriteInt32(&data2, OP_B);
131 
132     IpcIo reply2;
133     uintptr_t ptr2 = 0;
134     int ret = SendRequest(sidServer, SERVER_OP_ADD, &data2, &reply2, g_option, &ptr2);
135     int res = -1;
136     ReadInt32(&reply2, &res);
137     RPC_LOG_INFO(" 12 + 17 = %d", res);
138     FreeBuffer((void *)ptr2);
139     EXPECT_EQ(ret, ERR_NONE);
140     int tmpSum = OP_A + OP_B;
141     EXPECT_EQ(res, tmpSum);
142 }
143 
144 HWTEST_F(IpcClientTest, IpcServerTest002_01, TestSize.Level1)
145 {
146     RPC_LOG_INFO("====== call serverone OP_MULTI ======");
147     IpcIo data2;
148     uint8_t dataMulti[IPC_MAX_SIZE];
149     IpcIoInit(&data2, dataMulti, IPC_MAX_SIZE, 0);
150     WriteInt32(&data2, OP_A);
151     WriteInt32(&data2, OP_B);
152     IpcIo reply;
153     uintptr_t ptr = 0;
154     int ret = SendRequest(sidServer, SERVER_OP_MULTI, &data2, &reply, g_option, &ptr);
155     int res = -1;
156     ReadInt32(&reply, &res);
157     RPC_LOG_INFO(" 12 * 17 = %d", res);
158     FreeBuffer((void *)ptr);
159     EXPECT_EQ(ret, ERR_NONE);
160     int tmpMul = OP_A * OP_B;
161     EXPECT_EQ(res, tmpMul);
162 }
163 
164 static IpcObjectStub objectStub = {
165     .func = RemoteRequest,
166     .isRemote = false
167 };
168 
169 static SvcIdentity clientSvc = {
170     .handle = -1,
171     .token = 0,
172     .cookie = (uintptr_t)&objectStub
173 };
174 
175 HWTEST_F(IpcClientTest, IpcClientTest003, TestSize.Level1)
176 {
177     IpcIo anonymous;
178     uint8_t anonymousData[IPC_MAX_SIZE];
179     IpcIoInit(&anonymous, anonymousData, IPC_MAX_SIZE, 1);
180     WriteRemoteObject(&anonymous, &clientSvc);
181 
182     IpcIo anonymousreply;
183     uintptr_t anonymousptr = 0;
184     int ret = SendRequest(sidServer, SERVER_OP_ADD_SERVICE, &anonymous, &anonymousreply, g_option, &anonymousptr);
185     int res;
186     ReadInt32(&anonymousreply, &res);
187     RPC_LOG_INFO("add self to server = %d", res);
188     FreeBuffer((void *)anonymousptr);
189     EXPECT_EQ(ret, ERR_NONE);
190     EXPECT_EQ(res, ERR_NONE);
191 }
192 
193 HWTEST_F(IpcClientTest, IpcClientTest004, TestSize.Level0)
194 {
195     RPC_LOG_INFO("============= test case for add death callback ============");
196     int ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead1, nullptr, &cbId1);
197     EXPECT_EQ(ret, ERR_NONE);
198     ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead2, nullptr, &cbId2);
199     EXPECT_EQ(ret, ERR_NONE);
200     ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead3, nullptr, &cbId3);
201     EXPECT_EQ(ret, ERR_NONE);
202     ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead3, nullptr, &cbId4);
203     EXPECT_EQ(ret, ERR_NONE);
204     ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead3, nullptr, &cbId5); // failed
205     EXPECT_EQ(ret, ERR_INVALID_PARAM);
206 }
207 
208 HWTEST_F(IpcClientTest, IpcClientTest005, TestSize.Level0)
209 {
210     RPC_LOG_INFO("============= test case for remove death callback ============");
211     int ret = RemoveDeathRecipient(sidServer, cbId2);
212     EXPECT_EQ(ret, ERR_NONE);
213     ret = RemoveDeathRecipient(sidServer, cbId4);
214     EXPECT_EQ(ret, ERR_NONE);
215     ret = RemoveDeathRecipient(sidServer, cbId1);
216     EXPECT_EQ(ret, ERR_NONE);
217     ret = RemoveDeathRecipient(sidServer, cbId3);
218     EXPECT_EQ(ret, ERR_NONE);
219 }
220 
221 HWTEST_F(IpcClientTest, IpcClientTest006, TestSize.Level1)
222 {
223     ++sidServer.handle;
224     int ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead3, nullptr, &cbId5); // failed
225     EXPECT_EQ(ret, ERR_INVALID_PARAM);
226 
227     ret = RemoveDeathRecipient(sidServer, cbId3); // failed
228     EXPECT_EQ(ret, ERR_INVALID_PARAM);
229     --sidServer.handle;
230 }
231 
232 HWTEST_F(IpcClientTest, IpcClientTest007, TestSize.Level2)
233 {
234     IpcIo data2;
235     uint8_t tmpData2[IPC_MAX_SIZE];
236     IpcIoInit(&data2, tmpData2, IPC_MAX_SIZE, 0);
237     WriteInt32(&data2, OP_A);
238     WriteInt32(&data2, OP_B);
239 
240     IpcIo reply2;
241     uintptr_t ptr2 = 0;
242     int res;
243 
244     struct timespec start = {0, 0};
245     struct timespec end = {0, 0};
246 
247     clock_gettime(CLOCK_REALTIME, &start);
248     for (int i = 0; i < PERFORMANCE_TEST_TIMES; i++) {
249         SendRequest(sidServer, SERVER_OP_ADD, &data2, &reply2, g_option, &ptr2);
250         ReadInt32(&reply2, &res);
251         FreeBuffer((void *)ptr2);
252     }
253     clock_gettime(CLOCK_REALTIME, &end);
254 
255     float time = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; // ms
256     RPC_LOG_INFO("############ sync time with 100 times = %f ms", time);
257 }
258 
259 HWTEST_F(IpcClientTest, IpcClientTest008, TestSize.Level2)
260 {
261     IpcIo data2;
262     uint8_t tmpData2[IPC_MAX_SIZE];
263     IpcIoInit(&data2, tmpData2, IPC_MAX_SIZE, 0);
264     WriteInt32(&data2, OP_A);
265     WriteInt32(&data2, OP_B);
266 
267     struct timespec start = {0, 0};
268     struct timespec end = {0, 0};
269 
270     MessageOption option = {
271         .flags = TF_OP_ASYNC
272     };
273 
274     clock_gettime(CLOCK_REALTIME, &start);
275     for (int i = 0; i < PERFORMANCE_TEST_TIMES; i++) {
276         SendRequest(sidServer, SERVER_OP_ADD, &data2, nullptr, option, nullptr);
277     }
278     clock_gettime(CLOCK_REALTIME, &end);
279 
280     float time = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; // ms
281     RPC_LOG_INFO("########### async time with 100 times = %f ms", time);
282 }
283 
284 HWTEST_F(IpcClientTest, IpcClientTest009, TestSize.Level0)
285 {
286     int ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead1, nullptr, &cbId1);
287     EXPECT_EQ(ret, ERR_NONE);
288     ret = AddDeathRecipient(sidServer, (OnRemoteDead)ServerDead2, nullptr, &cbId2);
289     EXPECT_EQ(ret, ERR_NONE);
290     while (1) {}
291 }
292 }  // namespace OHOS