• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <cstring>
16 #include <iostream>
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <sys/mman.h>
20 
21 #include "message_parcel_warp.h"
22 using namespace testing;
23 using namespace testing::ext;
24 using namespace OHOS;
25 
26 namespace OHOS {
27 
28 constexpr size_t MIN_RAW_SIZE = 32 * 1024; // 32k
29 class MessageParcelWarpInterface {
30 public:
MessageParcelWarpInterface()31     MessageParcelWarpInterface() {};
~MessageParcelWarpInterface()32     virtual ~MessageParcelWarpInterface() {};
33 
34     virtual bool WriteInt64(int64_t value) = 0;
35     virtual int64_t ReadInt64() = 0;
36     virtual bool WriteFileDescriptor(int fd) = 0;
37     virtual int ReadFileDescriptor() = 0;
38     virtual bool WriteUnpadBuffer(const void *data, size_t size) = 0;
39     virtual uint8_t *ReadUnpadBuffer(size_t length) = 0;
40 };
41 
42 class MessageParcelWarpMock : public MessageParcelWarpInterface {
43 public:
44     MessageParcelWarpMock();
45     ~MessageParcelWarpMock() override;
46 
47     MOCK_METHOD1(WriteInt64, bool(int64_t value));
48     MOCK_METHOD0(ReadInt64, int64_t());
49     MOCK_METHOD1(WriteFileDescriptor, bool(int fd));
50     MOCK_METHOD0(ReadFileDescriptor, int());
51     MOCK_METHOD2(WriteUnpadBuffer, bool(const void *data, size_t size));
52     MOCK_METHOD1(ReadUnpadBuffer, uint8_t *(size_t length));
53 };
54 
55 static void *g_interface = nullptr;
56 
MessageParcelWarpMock()57 MessageParcelWarpMock::MessageParcelWarpMock()
58 {
59     g_interface = reinterpret_cast<void *>(this);
60 }
61 
~MessageParcelWarpMock()62 MessageParcelWarpMock::~MessageParcelWarpMock()
63 {
64     g_interface = nullptr;
65 }
66 
GetMessageParcelWarpInterface()67 static MessageParcelWarpInterface *GetMessageParcelWarpInterface()
68 {
69     return reinterpret_cast<MessageParcelWarpInterface *>(g_interface);
70 }
71 
72 extern "C" {
WriteInt64(int64_t value)73     bool Parcel::WriteInt64(int64_t value)
74     {
75         if (GetMessageParcelWarpInterface() == nullptr) {
76             return false;
77         }
78         return GetMessageParcelWarpInterface()->WriteInt64(value);
79     }
ReadInt64()80     int64_t Parcel::ReadInt64()
81     {
82         if (GetMessageParcelWarpInterface() == nullptr) {
83             return 0;
84         }
85         return GetMessageParcelWarpInterface()->ReadInt64();
86     }
WriteFileDescriptor(int fd)87     bool MessageParcel::WriteFileDescriptor(int fd)
88     {
89         if (GetMessageParcelWarpInterface() == nullptr) {
90             return false;
91         }
92         return GetMessageParcelWarpInterface()->WriteFileDescriptor(fd);
93     }
ReadFileDescriptor()94     int MessageParcel::ReadFileDescriptor()
95     {
96         if (GetMessageParcelWarpInterface() == nullptr) {
97             return 0;
98         }
99         return GetMessageParcelWarpInterface()->ReadFileDescriptor();
100     }
WriteUnpadBuffer(const void * data,size_t size)101     bool Parcel::WriteUnpadBuffer(const void *data, size_t size)
102     {
103         if (GetMessageParcelWarpInterface() == nullptr) {
104             return false;
105         }
106         return GetMessageParcelWarpInterface()->WriteUnpadBuffer(data, size);
107     }
ReadUnpadBuffer(size_t length)108     const uint8_t *Parcel::ReadUnpadBuffer(size_t length)
109     {
110         if (GetMessageParcelWarpInterface() == nullptr) {
111             return nullptr;
112         }
113         return GetMessageParcelWarpInterface()->ReadUnpadBuffer(length);
114     }
115 }
116 
117 namespace MiscServices {
118 class MessageParcelWarpTest : public testing::Test {
119 public:
120     static void SetUpTestCase(void);
121     static void TearDownTestCase(void);
122     void SetUp();
123     void TearDown();
124 };
125 
SetUpTestCase(void)126 void MessageParcelWarpTest::SetUpTestCase(void) { }
127 
TearDownTestCase(void)128 void MessageParcelWarpTest::TearDownTestCase(void) { }
129 
SetUp(void)130 void MessageParcelWarpTest::SetUp(void) { }
131 
TearDown(void)132 void MessageParcelWarpTest::TearDown(void) { }
133 
134 /**
135  * @tc.name: MemcpyDataTest001
136  * @tc.desc: Test MemcpyData
137  * @tc.type: FUNC
138  * @tc.require:
139  */
140 HWTEST_F(MessageParcelWarpTest, MemcpyDataTest001, TestSize.Level0)
141 {
142     MessageParcelWarp messageParcelWarp;
143     size_t size = 1024;
144     void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
145     const char data[] = "Test data";
146     size_t count = strlen(data) + 1;
147 
148     auto result = messageParcelWarp.MemcpyData(ptr, size, data, count);
149     EXPECT_TRUE(result);
150 
151     char* resultData = static_cast<char*>(ptr);
152     EXPECT_STREQ(resultData, data);
153     munmap(ptr, size);
154 }
155 
156 /**
157  * @tc.name: MemcpyDataTest002
158  * @tc.desc: Test MemcpyData
159  * @tc.type: FUNC
160  * @tc.require:
161  */
162 HWTEST_F(MessageParcelWarpTest, MemcpyDataTest002, TestSize.Level0)
163 {
164     MessageParcelWarp messageParcelWarp;
165     size_t size = 256 * 1024 * 1024 + 1;
166     void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
167     char* data = new char[size];
168     std::fill(data, data + size, 'A');
169 
170     auto result = messageParcelWarp.MemcpyData(ptr, size, data, size);
171     EXPECT_TRUE(result);
172 
173     char* resultData = static_cast<char*>(ptr);
174     EXPECT_STREQ(resultData, data);
175     munmap(ptr, size);
176 }
177 
178 /**
179  * @tc.name: WriteRawDataTest001
180  * @tc.desc: Test WriteRawData
181  * @tc.type: FUNC
182  * @tc.require:
183  */
184 HWTEST_F(MessageParcelWarpTest, WriteRawDataTest001, TestSize.Level0)
185 {
186     MessageParcelWarp messageParcelWarp;
187     MessageParcel parcel;
188     const char data[] = "Test data";
189     size_t size = strlen(data) + 1;
190 
191     NiceMock<MessageParcelWarpMock> mock;
192     EXPECT_CALL(mock, WriteInt64).WillOnce(testing::Return(false));
193 
194     auto result = messageParcelWarp.WriteRawData(parcel, data, size);
195     EXPECT_FALSE(result);
196 }
197 
198 /**
199  * @tc.name: WriteRawDataTest002
200  * @tc.desc: Test WriteRawData
201  * @tc.type: FUNC
202  * @tc.require:
203  */
204 HWTEST_F(MessageParcelWarpTest, WriteRawDataTest002, TestSize.Level0)
205 {
206     MessageParcelWarp messageParcelWarp;
207     MessageParcel parcel;
208     const char data[] = "Test data";
209     size_t size = strlen(data) + 1;
210 
211     NiceMock<MessageParcelWarpMock> mock;
212     EXPECT_CALL(mock, WriteInt64).WillOnce(testing::Return(true));
213     EXPECT_CALL(mock, WriteUnpadBuffer).WillOnce(testing::Return(true));
214 
215     auto result = messageParcelWarp.WriteRawData(parcel, data, size);
216     EXPECT_TRUE(result);
217 }
218 
219 /**
220  * @tc.name: WriteRawDataTest003
221  * @tc.desc: Test WriteRawData
222  * @tc.type: FUNC
223  * @tc.require:
224  */
225 HWTEST_F(MessageParcelWarpTest, WriteRawDataTest003, TestSize.Level0)
226 {
227     MessageParcelWarp messageParcelWarp;
228     MessageParcel parcel;
229     size_t size = MIN_RAW_SIZE + 1;
230     const char* data = new char[size];
231     std::fill(const_cast<char*>(data), const_cast<char*>(data) + size, 'A');
232 
233     NiceMock<MessageParcelWarpMock> mock;
234     EXPECT_CALL(mock, WriteInt64).WillOnce(testing::Return(true));
235     EXPECT_CALL(mock, WriteFileDescriptor).WillOnce(testing::Return(false));
236 
237     auto result = messageParcelWarp.WriteRawData(parcel, data, size);
238     EXPECT_FALSE(result);
239 }
240 
241 /**
242  * @tc.name: WriteRawDataTest004
243  * @tc.desc: Test WriteRawData
244  * @tc.type: FUNC
245  * @tc.require:
246  */
247 HWTEST_F(MessageParcelWarpTest, WriteRawDataTest004, TestSize.Level0)
248 {
249     MessageParcelWarp messageParcelWarp;
250     MessageParcel parcel;
251     size_t size = MIN_RAW_SIZE + 1;
252     const char* data = new char[size];
253     std::fill(const_cast<char*>(data), const_cast<char*>(data) + size, 'A');
254 
255     NiceMock<MessageParcelWarpMock> mock;
256     EXPECT_CALL(mock, WriteInt64).WillOnce(testing::Return(true));
257     EXPECT_CALL(mock, WriteFileDescriptor).WillOnce(testing::Return(true));
258 
259     auto result = messageParcelWarp.WriteRawData(parcel, data, size);
260     EXPECT_TRUE(result);
261 }
262 
263 /**
264  * @tc.name: ReadRawDataTest001
265  * @tc.desc: Test ReadRawData
266  * @tc.type: FUNC
267  * @tc.require:
268  */
269 HWTEST_F(MessageParcelWarpTest, ReadRawDataTest001, TestSize.Level0)
270 {
271     MessageParcelWarp messageParcelWarp;
272     MessageParcel parcel;
273     size_t size = MIN_RAW_SIZE - 1;
274 
275     NiceMock<MessageParcelWarpMock> mock;
276     EXPECT_CALL(mock, ReadInt64).WillOnce(testing::Return(1));
277     EXPECT_CALL(mock, ReadUnpadBuffer).WillRepeatedly(testing::Return(nullptr));
278 
279     auto result = messageParcelWarp.ReadRawData(parcel, size);
280     EXPECT_EQ(result, nullptr);
281 }
282 
283 /**
284  * @tc.name: ReadRawDataTest002
285  * @tc.desc: Test ReadRawData
286  * @tc.type: FUNC
287  * @tc.require:
288  */
289 HWTEST_F(MessageParcelWarpTest, ReadRawDataTest002, TestSize.Level0)
290 {
291     MessageParcelWarp messageParcelWarp;
292     messageParcelWarp.rawData_ = std::make_shared<char>('A');
293     messageParcelWarp.writeRawDataFd_ = 0;
294     MessageParcel parcel;
295     size_t size = MIN_RAW_SIZE + 1;
296 
297     NiceMock<MessageParcelWarpMock> mock;
298     EXPECT_CALL(mock, ReadInt64).WillOnce(testing::Return(size));
299     EXPECT_CALL(mock, ReadFileDescriptor).WillRepeatedly(testing::Return(1));
300 
301     auto result = messageParcelWarp.ReadRawData(parcel, size);
302     EXPECT_NE(result, messageParcelWarp.rawData_.get());
303 }
304 
305 /**
306  * @tc.name: ReadRawDataTest003
307  * @tc.desc: Test ReadRawData
308  * @tc.type: FUNC
309  * @tc.require:
310  */
311 HWTEST_F(MessageParcelWarpTest, ReadRawDataTest003, TestSize.Level0)
312 {
313     MessageParcelWarp messageParcelWarp;
314     messageParcelWarp.rawData_ = nullptr;
315     MessageParcel parcel;
316     size_t size = MIN_RAW_SIZE + 1;
317 
318     NiceMock<MessageParcelWarpMock> mock;
319     EXPECT_CALL(mock, ReadInt64).WillOnce(testing::Return(size));
320     EXPECT_CALL(mock, ReadFileDescriptor).WillRepeatedly(testing::Return(-1));
321 
322     auto result = messageParcelWarp.ReadRawData(parcel, size);
323     EXPECT_EQ(result, nullptr);
324 }
325 }
326 }