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 "distributeddb_communicator_common.h"
17 #include <gtest/gtest.h>
18 #include "db_errno.h"
19 #include "log_print.h"
20 #include "message_transform.h"
21 #include "securec.h"
22 
23 using namespace std;
24 using namespace DistributedDB;
25 
SetUpEnv(EnvHandle & inEnv,const string & inName,const std::shared_ptr<DBStatusAdapter> & adapter)26 bool SetUpEnv(EnvHandle &inEnv, const string &inName, const std::shared_ptr<DBStatusAdapter> &adapter)
27 {
28     if (inEnv.adapterHandle != nullptr || inEnv.commAggrHandle != nullptr) {
29         LOGI("[UT][Common][SetUp] Already Setup for %s", inName.c_str());
30         return false;
31     }
32 
33     inEnv.adapterHandle = new (nothrow) AdapterStub(inName);
34     if (inEnv.adapterHandle == nullptr) {
35         LOGI("[UT][Common][SetUp] Create AdapterStub fail for %s", inName.c_str());
36         return false;
37     }
38 
39     inEnv.commAggrHandle = new (nothrow) CommunicatorAggregator();
40     if (inEnv.commAggrHandle == nullptr) {
41         LOGI("[UT][Common][SetUp] Create CommunicatorAggregator fail for %s", inName.c_str());
42         return false;
43     }
44 
45     int errCode = inEnv.commAggrHandle->Initialize(inEnv.adapterHandle, adapter);
46     if (errCode != E_OK) {
47         LOGI("[UT][Common][SetUp] Init CommunicatorAggregator fail for %s", inName.c_str());
48         return false;
49     }
50 
51     return true;
52 }
53 
SetUpEnv(EnvHandle & inEnv,const string & inName)54 bool SetUpEnv(EnvHandle &inEnv, const string &inName)
55 {
56     return SetUpEnv(inEnv, inName, nullptr);
57 }
58 
TearDownEnv(EnvHandle & inEnv)59 void TearDownEnv(EnvHandle &inEnv)
60 {
61     if (inEnv.commAggrHandle != nullptr) {
62         inEnv.commAggrHandle->Finalize();
63         inEnv.commAggrHandle->DecObjRef(inEnv.commAggrHandle);
64         inEnv.commAggrHandle = nullptr;
65     }
66 
67     if (inEnv.adapterHandle != nullptr) {
68         delete inEnv.adapterHandle;
69         inEnv.adapterHandle = nullptr;
70     }
71 }
72 
RegFuncForTinyMsg()73 static void RegFuncForTinyMsg()
74 {
75     TransformFunc funcForTinyMsg;
76     funcForTinyMsg.computeFunc = [](const Message *inMsg)->uint32_t{return TINY_SIZE;};
77     funcForTinyMsg.serializeFunc = [](uint8_t *buffer, uint32_t length, const Message *inMsg)->int{
78         const RegedTinyObject *outObj = inMsg->GetObject<RegedTinyObject>();
79         EXPECT_NE(outObj, nullptr);
80         return E_OK;
81     };
82     funcForTinyMsg.deserializeFunc = [](const uint8_t *buffer, uint32_t length, Message *inMsg)->int{
83         int errCode = inMsg->SetCopiedObject(RegedTinyObject());
84         EXPECT_EQ(errCode, E_OK);
85         return E_OK;
86     };
87 
88     MessageTransform::RegTransformFunction(REGED_TINY_MSG_ID, funcForTinyMsg);
89 }
90 
RegFuncForHugeMsg()91 static void RegFuncForHugeMsg()
92 {
93     TransformFunc funcForHugeMsg;
94     funcForHugeMsg.computeFunc = [](const Message *inMsg)->uint32_t{return HUGE_SIZE;};
95     funcForHugeMsg.serializeFunc = [](uint8_t *buffer, uint32_t length, const Message *inMsg)->int{
96         const RegedHugeObject *outObj = inMsg->GetObject<RegedHugeObject>();
97         EXPECT_NE(outObj, nullptr);
98         return E_OK;
99     };
100     funcForHugeMsg.deserializeFunc = [](const uint8_t *buffer, uint32_t length, Message *inMsg)->int{
101         int errCode = inMsg->SetCopiedObject(RegedHugeObject());
102         EXPECT_EQ(errCode, E_OK);
103         return E_OK;
104     };
105 
106     MessageTransform::RegTransformFunction(REGED_HUGE_MSG_ID, funcForHugeMsg);
107 }
108 
RegFuncForGiantMsg()109 static void RegFuncForGiantMsg()
110 {
111     TransformFunc funcForGiantMsg;
112     funcForGiantMsg.computeFunc = [](const Message *inMsg)->uint32_t{
113         const RegedGiantObject *outObj = inMsg->GetObject<RegedGiantObject>();
114         if (outObj == nullptr) {
115             return 0;
116         }
117         return outObj->rawData_.size();
118     };
119     funcForGiantMsg.serializeFunc = [](uint8_t *buffer, uint32_t length, const Message *inMsg)->int{
120         const RegedGiantObject *outObj = inMsg->GetObject<RegedGiantObject>();
121         if (outObj == nullptr) {
122             return -E_INVALID_ARGS;
123         }
124         if (outObj->rawData_.size() != length) {
125             return -E_LENGTH_ERROR;
126         }
127         errno_t errCode = memcpy_s(buffer, length, &(outObj->rawData_[0]), length);
128         if (errCode != EOK) {
129             return -E_SECUREC_ERROR;
130         }
131         return E_OK;
132     };
133     funcForGiantMsg.deserializeFunc = [](const uint8_t *buffer, uint32_t length, Message *inMsg)->int{
134         RegedGiantObject *obj = new (nothrow) RegedGiantObject();
135         if (obj == nullptr) {
136             return -E_OUT_OF_MEMORY;
137         }
138         obj->rawData_.resize(length);
139         errno_t retCode = memcpy_s(&(obj->rawData_[0]), length, buffer, length);
140         if (retCode != EOK) {
141             delete obj;
142             return -E_SECUREC_ERROR;
143         }
144         int errCode = inMsg->SetExternalObject(obj);
145         if (errCode != E_OK) {
146             delete obj;
147             return errCode;
148         }
149         return E_OK;
150     };
151 
152     MessageTransform::RegTransformFunction(REGED_GIANT_MSG_ID, funcForGiantMsg);
153 }
154 
RegFuncForOverSizeMsg()155 static void RegFuncForOverSizeMsg()
156 {
157     TransformFunc funcForOverSizeMsg;
158     funcForOverSizeMsg.computeFunc = [](const Message *inMsg)->uint32_t{return OVER_SIZE;};
159     funcForOverSizeMsg.serializeFunc = [](uint8_t *buffer, uint32_t length, const Message *inMsg)->int{
160         const RegedOverSizeObject *outObj = inMsg->GetObject<RegedOverSizeObject>();
161         EXPECT_NE(outObj, nullptr);
162         return E_OK;
163     };
164     funcForOverSizeMsg.deserializeFunc = [](const uint8_t *buffer, uint32_t length, Message *inMsg)->int{
165         int errCode = inMsg->SetCopiedObject(RegedOverSizeObject());
166         EXPECT_EQ(errCode, E_OK);
167         return E_OK;
168     };
169 
170     MessageTransform::RegTransformFunction(REGED_OVERSIZE_MSG_ID, funcForOverSizeMsg);
171 }
172 
DoRegTransformFunction()173 void DoRegTransformFunction()
174 {
175     RegFuncForTinyMsg();
176     RegFuncForHugeMsg();
177     RegFuncForGiantMsg();
178     RegFuncForOverSizeMsg();
179 }
180 
BuildRegedTinyMessage()181 Message *BuildRegedTinyMessage()
182 {
183     RegedTinyObject *obj = new (nothrow) RegedTinyObject();
184     if (obj == nullptr) {
185         return nullptr;
186     }
187 
188     Message *outMsg = new (nothrow) Message(REGED_TINY_MSG_ID);
189     if (outMsg == nullptr) {
190         delete obj;
191         obj = nullptr;
192         return nullptr;
193     }
194 
195     int errCode = outMsg->SetExternalObject(obj);
196     if (errCode != E_OK) {
197         delete obj;
198         obj = nullptr;
199         delete outMsg;
200         outMsg = nullptr;
201         return nullptr;
202     }
203     outMsg->SetMessageType(TYPE_REQUEST);
204     outMsg->SetSessionId(FIXED_SESSIONID);
205     outMsg->SetSequenceId(FIXED_SEQUENCEID);
206 
207     return outMsg;
208 }
209 
BuildRegedHugeMessage()210 Message *BuildRegedHugeMessage()
211 {
212     RegedHugeObject *obj = new (nothrow) RegedHugeObject();
213     if (obj == nullptr) {
214         return nullptr;
215     }
216 
217     Message *outMsg = new (nothrow) Message(REGED_HUGE_MSG_ID);
218     if (outMsg == nullptr) {
219         delete obj;
220         return nullptr;
221     }
222 
223     int errCode = outMsg->SetExternalObject(obj);
224     if (errCode != E_OK) {
225         delete obj;
226         obj = nullptr;
227         delete outMsg;
228         outMsg = nullptr;
229         return nullptr;
230     }
231     outMsg->SetMessageType(TYPE_RESPONSE);
232     outMsg->SetSessionId(FIXED_SESSIONID);
233     outMsg->SetSequenceId(FIXED_SEQUENCEID);
234 
235     return outMsg;
236 }
237 
238 // length should be a multiple of four
BuildRegedGiantMessage(uint32_t length)239 Message *BuildRegedGiantMessage(uint32_t length)
240 {
241     uint32_t count = length / sizeof(uint32_t);
242     if (count == 0) {
243         return nullptr;
244     }
245 
246     RegedGiantObject *obj = new (nothrow) RegedGiantObject();
247     if (obj == nullptr) {
248         return nullptr;
249     }
250 
251     Message *outMsg = new (nothrow) Message(REGED_GIANT_MSG_ID);
252     if (outMsg == nullptr) {
253         delete obj;
254         obj = nullptr;
255         return nullptr;
256     }
257 
258     obj->rawData_.resize(count * sizeof(uint32_t));
259     auto dataPtr = reinterpret_cast<uint32_t *>(&(obj->rawData_[0]));
260     uint32_t value = 0;
261     while (value < count) {
262         *dataPtr++ = value++;
263     }
264 
265     int errCode = outMsg->SetExternalObject(obj);
266     if (errCode != E_OK) {
267         delete obj;
268         obj = nullptr;
269         delete outMsg;
270         outMsg = nullptr;
271         return nullptr;
272     }
273     outMsg->SetMessageType(TYPE_NOTIFY);
274     outMsg->SetSessionId(FIXED_SESSIONID);
275     outMsg->SetSequenceId(FIXED_SEQUENCEID);
276 
277     return outMsg;
278 }
279 
BuildRegedOverSizeMessage()280 Message *BuildRegedOverSizeMessage()
281 {
282     RegedOverSizeObject *obj = new (nothrow) RegedOverSizeObject();
283     if (obj == nullptr) {
284         return nullptr;
285     }
286 
287     Message *outMsg = new (nothrow) Message(REGED_OVERSIZE_MSG_ID);
288     if (outMsg == nullptr) {
289         delete obj;
290         return nullptr;
291     }
292 
293     int errCode = outMsg->SetExternalObject(obj);
294     if (errCode != E_OK) {
295         delete obj;
296         obj = nullptr;
297         delete outMsg;
298         outMsg = nullptr;
299         return nullptr;
300     }
301     outMsg->SetMessageType(TYPE_NOTIFY);
302     outMsg->SetSessionId(FIXED_SESSIONID);
303     outMsg->SetSequenceId(FIXED_SEQUENCEID);
304 
305     return outMsg;
306 }
307 
BuildUnRegedTinyMessage()308 Message *BuildUnRegedTinyMessage()
309 {
310     UnRegedTinyObject *obj = new (nothrow) UnRegedTinyObject();
311     if (obj == nullptr) {
312         return nullptr;
313     }
314 
315     Message *outMsg = new (nothrow) Message(UNREGED_TINY_MSG_ID);
316     if (outMsg == nullptr) {
317         delete obj;
318         return nullptr;
319     }
320 
321     int errCode = outMsg->SetExternalObject(obj);
322     if (errCode != E_OK) {
323         delete obj;
324         obj = nullptr;
325         delete outMsg;
326         outMsg = nullptr;
327         return nullptr;
328     }
329     outMsg->SetMessageType(TYPE_NOTIFY);
330     outMsg->SetSessionId(FIXED_SESSIONID);
331     outMsg->SetSequenceId(FIXED_SEQUENCEID);
332 
333     return outMsg;
334 }
335 
CheckEqual(const RegedGiantObject & inLeft,const RegedGiantObject & inRight)336 bool RegedGiantObject::CheckEqual(const RegedGiantObject &inLeft, const RegedGiantObject &inRight)
337 {
338     if (inLeft.rawData_.size() != inRight.rawData_.size()) {
339         return false;
340     }
341     uint32_t index = 0;
342     for (const auto &left : inLeft.rawData_) {
343         uint8_t right = inRight.rawData_[index];
344         if (left != right) {
345             LOGE("[RegedGiantObject][CheckEqual] RawData unequal at index=%u", index);
346             return false;
347         }
348         index++;
349     }
350     return true;
351 }