1 /*
2 * Copyright (c) 2021 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 "transfer.h"
17 #include <filesystem>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20
21 using namespace testing::ext;
22 using namespace testing;
23
24 namespace Hdc {
25
26 class HdcTransferTest : public Test {
27 public:
28 static void SetUpTestCase(void);
29 static void TearDownTestCase(void);
30 void SetUp();
31 void TearDown();
32
33 class MockHdcTransfer : public HdcTransferBase {
34 public:
MockHdcTransfer(HTaskInfo hTaskInfo)35 explicit MockHdcTransfer(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) {}
36 };
37
38 private:
BuildPTask()39 HTaskInfo BuildPTask()
40 {
41 HTaskInfo hTaskInfo = new(std::nothrow) TaskInformation();
42 if (hTaskInfo == nullptr) {
43 return nullptr;
44 }
45 uv_loop_t looptest;
46 uv_loop_init(&looptest);
47 LoopStatus ls(&looptest, "not support");
48 HdcSessionBase *unittest = new (std::nothrow) HdcSessionBase(false);
49 if (unittest == nullptr) {
50 delete hTaskInfo;
51 return nullptr;
52 }
53 hTaskInfo->ownerSessionClass = unittest;
54 hTaskInfo->channelId = 0;
55 hTaskInfo->sessionId = 0;
56 hTaskInfo->runLoop = &looptest;
57 hTaskInfo->runLoopStatus = &ls;
58 hTaskInfo->serverOrDaemon = false;
59 hTaskInfo->masterSlave = false;
60 hTaskInfo->closeRetryCount = 0;
61 hTaskInfo->channelTask = false;
62 hTaskInfo->isCleared = false;
63 hTaskInfo->taskType = TASK_FILE;
64 hTaskInfo->hasInitial = true;
65 HdcTransferBase *ptrTask = nullptr;
66 ptrTask = new (std::nothrow) HdcTransferBase(hTaskInfo);
67 if (ptrTask == nullptr) {
68 delete hTaskInfo;
69 delete unittest;
70 return nullptr;
71 }
72 hTaskInfo->taskClass = ptrTask;
73 return hTaskInfo;
74 }
75
76 HTaskInfo hTaskInfo;
77 MockHdcTransfer *mockHdcdTransfer;
78 };
79
SetUpTestCase()80 void HdcTransferTest::SetUpTestCase()
81 {
82 #ifdef UT_DEBUG
83 Hdc::Base::SetLogLevel(LOG_ALL);
84 #else
85 Hdc::Base::SetLogLevel(LOG_OFF);
86 #endif
87 }
TearDownTestCase()88 void HdcTransferTest::TearDownTestCase() {}
SetUp()89 void HdcTransferTest::SetUp()
90 {
91 hTaskInfo = BuildPTask();
92 mockHdcdTransfer = new (std::nothrow) MockHdcTransfer(hTaskInfo);
93 mockHdcdTransfer->commandBegin = CMD_FILE_BEGIN;
94 mockHdcdTransfer->commandBegin = CMD_FILE_DATA;
95 mockHdcdTransfer->isStableBuf = false;
96 }
TearDown()97 void HdcTransferTest::TearDown()
98 {
99 delete mockHdcdTransfer;
100 mockHdcdTransfer = nullptr;
101 }
102
103 HWTEST_F(HdcTransferTest, TestCommandDispatch, TestSize.Level0)
104 {
105 uint16_t command = CMD_FILE_DATA;
106 uint8_t payload[10];
107 int payloadSize = -1;
108 ASSERT_EQ(mockHdcdTransfer->CommandDispatch(command, payload, payloadSize), false);
109 }
110
111 HWTEST_F(HdcTransferTest, TestExtractRelativePath, TestSize.Level0)
112 {
113 string cwd = "D:\\";
114 string resolvedPath = "test\\path";
115 std::stringstream ss;
116 ss << "D:\\test\\path";
117 mockHdcdTransfer->ExtractRelativePath(cwd, resolvedPath);
118 ASSERT_EQ(resolvedPath, ss.str());
119 }
120
121 HWTEST_F(HdcTransferTest, TestAddFeatures, TestSize.Level0)
122 {
123 union HdcTransferBase::FeatureFlagsUnion f{};
124 mockHdcdTransfer->AddFeatures(f);
125 ASSERT_EQ(f.bits.reserveBits1, 1);
126 ASSERT_EQ(f.bits.hugeBuf, true);
127 }
128
129 HWTEST_F(HdcTransferTest, TestCheckFeatures, TestSize.Level0)
130 {
131 uint8_t payload[FEATURE_FLAG_MAX_SIZE] = {1};
132 // case 1: payloadSize < 0;
133 int payloadSize = 0;
134 HdcTransferBase::CtxFile context;
135 bool result = mockHdcdTransfer->CheckFeatures(&context, payload, payloadSize);
136 EXPECT_TRUE(result);
137 ASSERT_EQ(context.isStableBufSize, true);
138 ASSERT_EQ(context.isOtherSideSandboxSupported, false);
139 // case 1: payloadSize = FEATURE_FLAG_MAX_SIZE;
140 payloadSize = FEATURE_FLAG_MAX_SIZE;
141 result = mockHdcdTransfer->CheckFeatures(&context, payload, payloadSize);
142 EXPECT_TRUE(result);
143 ASSERT_EQ(context.isStableBufSize, false);
144 ASSERT_EQ(context.isOtherSideSandboxSupported, false);
145 // case 1: other payloadSize
146 payloadSize = FEATURE_FLAG_MAX_SIZE + 1;
147 result = mockHdcdTransfer->CheckFeatures(&context, payload, payloadSize);
148 EXPECT_FALSE(result);
149 }
150
151 HWTEST_F(HdcTransferTest, TestCheckSandboxOptionCompatibility, TestSize.Level0)
152 {
153 HdcTransferBase::CtxFile context;
154 bool result = mockHdcdTransfer->CheckSandboxOptionCompatibility(mockHdcdTransfer->cmdBundleName, &context);
155 EXPECT_TRUE(result);
156
157 context.isOtherSideSandboxSupported = false;
158 ASSERT_EQ(mockHdcdTransfer->CheckSandboxOptionCompatibility(mockHdcdTransfer->cmdBundleName, &context), true);
159 }
160
161 HWTEST_F(HdcTransferTest, TestResetCtx, TestSize.Level0)
162 {
163 HdcTransferBase::CtxFile context;
164 ASSERT_EQ(mockHdcdTransfer->ResetCtx(&context, true), true);
165 ASSERT_EQ(context.openFd, -1);
166 }
167
168 HWTEST_F(HdcTransferTest, TestSimpleFileIO, TestSize.Level0)
169 {
170 HdcTransferBase::CtxFile context;
171 int bufLen = MAX_SIZE_IOBUF_STABLE * mockHdcdTransfer->maxTransferBufFactor;
172 context.indexIO = rand();
173 context.isStableBufSize = true;
174 int result = mockHdcdTransfer->SimpleFileIO(&context, context.indexIO, nullptr, bufLen + 1);
175 ASSERT_EQ(result, -1);
176 result = mockHdcdTransfer->SimpleFileIO(&context, context.indexIO, nullptr, -1);
177 ASSERT_EQ(result, -1);
178
179 context.ioFinish = true;
180 result = mockHdcdTransfer->SimpleFileIO(&context, context.indexIO, nullptr, bufLen);
181 ASSERT_EQ(result, -1);
182
183 // case: memcpy error
184 context.ioFinish = false;
185 context.master = false;
186 result = mockHdcdTransfer->SimpleFileIO(&context, context.indexIO, nullptr, bufLen);
187 ASSERT_EQ(result, -1);
188 }
189
190 HWTEST_F(HdcTransferTest, TestInitTransferPayload, TestSize.Level0)
191 {
192 HdcTransferBase::TransferPayload payloadHead;
193 uint64_t index = rand();
194 uint8_t compressType = HdcTransferBase::COMPRESS_LZ4;
195 bool result = mockHdcdTransfer->InitTransferPayload(payloadHead, index,
196 compressType, MAX_SIZE_IOBUF_STABLE);
197
198 ASSERT_EQ(result, true);
199 ASSERT_EQ(payloadHead.compressType, compressType);
200 ASSERT_EQ(payloadHead.uncompressSize, MAX_SIZE_IOBUF_STABLE);
201 ASSERT_EQ(payloadHead.index, index);
202 }
203
204 HWTEST_F(HdcTransferTest, TestSendIOPayload, TestSize.Level0)
205 {
206 HdcTransferBase::CtxFile context;
207 uint64_t index = rand();
208 uint8_t *payload = new uint8_t[MAX_SIZE_IOBUF_STABLE];
209 memset_s(payload, MAX_SIZE_IOBUF_STABLE, 1, MAX_SIZE_IOBUF_STABLE);
210
211 bool result = mockHdcdTransfer->SendIOPayload(&context, index,
212 payload, -1);
213 ASSERT_EQ(result, false);
214 }
215
216 HWTEST_F(HdcTransferTest, TestProcressFileIOWrite, TestSize.Level0)
217 {
218 HdcTransferBase::CtxFile context;
219 uv_fs_t req;
220 req.result = 0;
221 context.indexIO = context.fileSize = rand();
222 bool result = mockHdcdTransfer->ProcressFileIOWrite(&req, &context,
223 (HdcTransferBase *)context.thisClass);
224 ASSERT_EQ(result, true);
225
226 req.result = -1;
227 context.indexIO = 1;
228 context.fileSize = 2;
229 result = mockHdcdTransfer->ProcressFileIOWrite(&req, &context,
230 (HdcTransferBase *)context.thisClass);
231 ASSERT_EQ(result, false);
232 }
233
234 HWTEST_F(HdcTransferTest, TestProcressFileIO, TestSize.Level0)
235 {
236 HdcTransferBase::CtxFile context;
237 uint64_t bytes = rand();
238 uv_fs_t req;
239 req.result = -1;
240
241 context.ioFinish = true;
242 bool result = mockHdcdTransfer->ProcressFileIO(&req, &context,
243 (HdcTransferBase *)context.thisClass, bytes);
244 ASSERT_EQ(result, true);
245
246 context.ioFinish = false;
247 context.master = true;
248 result = mockHdcdTransfer->ProcressFileIO(&req, &context,
249 (HdcTransferBase *)context.thisClass, bytes);
250 ASSERT_EQ(result, true);
251
252 req.result = 0;
253 req.fs_type = UV_FS_WRITE;
254 result = mockHdcdTransfer->ProcressFileIO(&req, &context,
255 (HdcTransferBase *)context.thisClass, bytes);
256 ASSERT_EQ(result, true);
257 }
258
259 HWTEST_F(HdcTransferTest, TestIODelayed, TestSize.Level0)
260 {
261 HdcTransferBase::CtxFile context;
262 uint64_t bytes = rand();
263 HdcTransferBase::CtxFileIO *ioContext = new (std::nothrow) HdcTransferBase::CtxFileIO();
264 uint8_t *buf = new uint8_t[bytes + HdcTransferBase::payloadPrefixReserve]();
265 uv_fs_t *req = &ioContext->fs;
266 ioContext->bytes = bytes;
267 ioContext->bufIO = buf + HdcTransferBase::payloadPrefixReserve;
268 ioContext->context = &context;
269 req->data = ioContext;
270 req->fs_type = UV_FS_WRITE;
271 bool result = mockHdcdTransfer->IODelayed(req);
272 ASSERT_EQ(result, false);
273 }
274
275 HWTEST_F(HdcTransferTest, TestIsValidBundlePath, TestSize.Level0)
276 {
277 std::filesystem::path testPath = "/mnt/debug/100/debug_hap/com.example.myapplication/data/local/tmp/";
278 if (!std::filesystem::exists(testPath))
279 {
280 std::filesystem::create_directories(testPath);
281 }
282 ASSERT_TRUE(std::filesystem::exists(testPath));
283 const string bundleName = "com.example.myapplication";
284 bool result = mockHdcdTransfer->IsValidBundlePath(bundleName);
285 ASSERT_EQ(result, true);
286 }
287
288 HWTEST_F(HdcTransferTest, TestMatchPackageExtendName, TestSize.Level0)
289 {
290 string resolvedPath = "D:\\test\\path\\libA_v10001.hsp";
291 bool result = mockHdcdTransfer->MatchPackageExtendName(resolvedPath, ".hsp");
292 ASSERT_EQ(result, true);
293
294 string invalidPath = "D:\\test\\path\\libA_v10001.hp";
295 result = mockHdcdTransfer->MatchPackageExtendName(invalidPath, ".hsp");
296 ASSERT_EQ(result, false);
297 }
298
299 HWTEST_F(HdcTransferTest, TestRecvIOPayload, TestSize.Level0)
300 {
301 HdcTransferBase::CtxFile context;
302 uint8_t *payload = new uint8_t[BUF_SIZE_TINY];
303 memset_s(payload, BUF_SIZE_TINY, 1, BUF_SIZE_TINY);
304
305 bool result = mockHdcdTransfer->RecvIOPayload(&context, payload, -1);
306 ASSERT_EQ(result, false);
307 }
308
309 }
310