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 "gtest/gtest.h" 17 18#include <cstddef> 19#include <string> 20 21#include "utils/aie_guard.h" 22#include "utils/aie_macros.h" 23#include "utils/encdec/include/data_decoder.h" 24#include "utils/encdec/include/data_encoder.h" 25#include "utils/encdec/include/encdec_facade.h" 26#include "utils/log/aie_log.h" 27 28using namespace OHOS::AI; 29using namespace testing::ext; 30namespace { 31constexpr size_t ARRAY_LEN = 10; 32constexpr int g_int = 12; 33constexpr char g_char = 'd'; 34constexpr float g_float = 0.99f; 35constexpr long long g_long = 123456789L; 36const std::string g_string = "random string"; 37const std::string g_emptyString = ""; 38 39typedef struct { 40 char foo; 41 int bar; 42} StructWithPadding; // definition of struct with padding(blank memory) between members 43 44typedef struct { 45 int foo; 46 StructWithPadding bar; 47} NestedStruct; 48 49typedef struct { 50 size_t objectsNum; 51 StructWithPadding* objects; 52} StructWithPointer; 53 54typedef struct { 55 size_t foo; 56 int barArray[ARRAY_LEN]; 57} StructWithArray; 58 59template<typename Type> 60bool CompareData(const Type &input, const Type &output) 61{ 62 return input == output; 63} 64 65bool CompareData(const StructWithPadding &input, const StructWithPadding &output) 66{ 67 return (input.foo == output.foo) && (input.bar == output.bar); 68} 69 70bool CompareData(const NestedStruct &input, const NestedStruct &output) 71{ 72 return (input.foo == output.foo) && CompareData(input.bar, output.bar); 73} 74 75bool CompareData(const StructWithPointer &input, const StructWithPointer &output) 76{ 77 if (input.objectsNum != output.objectsNum) { 78 return false; 79 } 80 for (unsigned int i = 0; i < input.objectsNum; ++i) { 81 if (!CompareData(input.objects[i], output.objects[i])) { 82 return false; 83 } 84 } 85 return true; 86} 87 88bool CompareData(const StructWithArray &input, const StructWithArray &output) 89{ 90 if (input.foo != output.foo) { 91 return false; 92 } 93 for (unsigned int i = 0; i < ARRAY_LEN; ++i) { 94 if (!CompareData(input.barArray[i], output.barArray[i])) { 95 return false; 96 } 97 } 98 return true; 99} 100 101StructWithPadding GenStructWithPadding(const int myNum, const char myChar) 102{ 103 StructWithPadding structWithPadding = { 104 .foo = myChar, 105 .bar = myNum 106 }; 107 return structWithPadding; 108} 109 110NestedStruct GenNestedStruct() 111{ 112 NestedStruct nestedStruct = { 113 .foo = g_int, 114 .bar = GenStructWithPadding(g_int, g_char) 115 }; 116 return nestedStruct; 117} 118 119StructWithPointer GenStructWithPointer(const size_t objectsNum) 120{ 121 StructWithPointer structWithPointer { 122 .objectsNum = objectsNum 123 }; 124 if (objectsNum > 0) { 125 AIE_NEW(structWithPointer.objects, StructWithPadding[objectsNum]); 126 for (size_t i = 0; i < objectsNum; ++i) { 127 structWithPointer.objects[i] = GenStructWithPadding(g_int, g_char); 128 } 129 } 130 return structWithPointer; 131} 132 133void ReleaseStructWithPointer(StructWithPointer &structWithPointer) 134{ 135 AIE_DELETE_ARRAY(structWithPointer.objects); 136} 137 138StructWithArray GenStructWithArray(const size_t num) 139{ 140 StructWithArray structWithArray { 141 .foo = num 142 }; 143 for (size_t i = 0; i < num && i < ARRAY_LEN; ++i) { 144 structWithArray.barArray[i] = g_int; 145 } 146 return structWithArray; 147} 148 149void PolluteData(DataInfo &dataInfo) 150{ 151 *(reinterpret_cast<size_t*>(dataInfo.data + dataInfo.length - sizeof(size_t))) = 0U; 152} 153 154void BasicTypesCheck(bool normalMode = true) 155{ 156 DataInfo dataInfo {}; 157 int retCode = EncdecFacade::ProcessEncode(dataInfo, g_int, g_char, g_float, g_long, g_string, g_emptyString); 158 MallocPointerGuard<unsigned char> dataInfoGuard(dataInfo.data); 159 ASSERT_EQ(retCode, RETCODE_SUCCESS); 160 if (!normalMode) { 161 PolluteData(dataInfo); 162 } 163 int outInt {}; 164 char outChar {}; 165 float outFloat {}; 166 long long outLong {}; 167 std::string outString {}; 168 std::string outEmptyString {}; 169 170 retCode = EncdecFacade::ProcessDecode(dataInfo, outInt, outChar, outFloat, outLong, outString, 171 outEmptyString); 172 if (normalMode) { 173 ASSERT_EQ(retCode, RETCODE_SUCCESS); 174 ASSERT_TRUE(CompareData(g_int, outInt)); 175 ASSERT_TRUE(CompareData(g_char, outChar)); 176 ASSERT_TRUE(CompareData(g_float, outFloat)); 177 ASSERT_TRUE(CompareData(g_long, outLong)); 178 ASSERT_TRUE(CompareData(g_string, outString)); 179 ASSERT_TRUE(CompareData(g_emptyString, outEmptyString)); 180 } else { 181 ASSERT_NE(retCode, RETCODE_SUCCESS); 182 } 183} 184 185void StructCheck(bool normalMode = true) 186{ 187 DataInfo dataInfo {}; 188 StructWithPadding structWithPadding = GenStructWithPadding(g_int, g_char); 189 NestedStruct nestedStruct = GenNestedStruct(); 190 StructWithArray structWithArray = GenStructWithArray(ARRAY_LEN); 191 192 int retCode = EncdecFacade::ProcessEncode(dataInfo, structWithPadding, nestedStruct, structWithArray); 193 MallocPointerGuard<unsigned char> dataInfoGuard(dataInfo.data); 194 ASSERT_EQ(retCode, RETCODE_SUCCESS); 195 if (!normalMode) { 196 PolluteData(dataInfo); 197 } 198 StructWithPadding outStructWithPadding {}; 199 NestedStruct outNestedStruct {}; 200 StructWithArray outStructWithArray {}; 201 202 retCode = EncdecFacade::ProcessDecode(dataInfo, outStructWithPadding, outNestedStruct, outStructWithArray); 203 if (normalMode) { 204 ASSERT_EQ(retCode, RETCODE_SUCCESS); 205 ASSERT_TRUE(CompareData(structWithPadding, outStructWithPadding)); 206 ASSERT_TRUE(CompareData(nestedStruct, outNestedStruct)); 207 ASSERT_TRUE(CompareData(structWithArray, outStructWithArray)); 208 } else { 209 ASSERT_NE(retCode, RETCODE_SUCCESS); 210 } 211} 212 213void StructWithPointerCheck(bool normalMode = true) 214{ 215 for (size_t classNum = 0; classNum <= ARRAY_LEN; ++classNum) { 216 HILOGD ("[Test]Normal test StructWithPointer, classNum = %d.************", classNum); 217 StructWithPointer structWithPointer = GenStructWithPointer(classNum); 218 DataInfo dataInfo {}; 219 int retCode = EncdecFacade::ProcessEncode(dataInfo, structWithPointer); 220 MallocPointerGuard<unsigned char> dataInfoGuard(dataInfo.data); 221 ASSERT_EQ(retCode, RETCODE_SUCCESS); 222 if (!normalMode) { 223 PolluteData(dataInfo); 224 } 225 StructWithPointer res {}; 226 retCode = EncdecFacade::ProcessDecode(dataInfo, res); 227 if (normalMode) { 228 ASSERT_EQ(retCode, RETCODE_SUCCESS); 229 ASSERT_TRUE(CompareData(structWithPointer, res)); 230 ReleaseStructWithPointer(res); 231 } else { 232 ASSERT_NE(retCode, RETCODE_SUCCESS); 233 } 234 ReleaseStructWithPointer(structWithPointer); 235 } 236} 237} 238 239namespace OHOS { 240namespace AI { 241template<> 242int DataEncoder::EncodeOneParameter(const StructWithPointer &val) 243{ 244 if (RecursiveEncode(val.objectsNum) != RETCODE_SUCCESS) { 245 HILOGE("[EncdecTest]Serialize memory error."); 246 return RETCODE_FAILURE; 247 } 248 for (size_t i = 0; i < val.objectsNum; ++i) { 249 if (RecursiveEncode(val.objects[i]) != RETCODE_SUCCESS) { 250 HILOGE("[EncdecTest]Serialize memory error."); 251 return RETCODE_FAILURE; 252 } 253 } 254 return RETCODE_SUCCESS; 255} 256 257template<> 258int DataDecoder::DecodeOneParameter(StructWithPointer &val) 259{ 260 if (RecursiveDecode(val.objectsNum) != RETCODE_SUCCESS) { 261 HILOGE("[EncdecTest]Unserialize failed."); 262 return RETCODE_FAILURE; 263 } 264 if (val.objectsNum > 0) { 265 AIE_NEW(val.objects, StructWithPadding[val.objectsNum]); 266 for (size_t i = 0; i < val.objectsNum; ++i) { 267 if (RecursiveDecode(val.objects[i]) != RETCODE_SUCCESS) { 268 AIE_DELETE_ARRAY(val.objects); 269 return RETCODE_FAILURE; 270 } 271 } 272 } 273 return RETCODE_SUCCESS; 274} 275} // namespace AI 276} // namespace OHOS 277 278class EncdecTest : public testing::Test { 279public: 280 // SetUpTestCase:The preset action of the test suite is executed before the first TestCase 281 static void SetUpTestCase() {}; 282 283 // TearDownTestCase:The test suite cleanup action is executed after the last TestCase 284 static void TearDownTestCase() {}; 285 286 // SetUp:Execute before each test case 287 void SetUp() override {}; 288 289 // TearDown:Execute after each test case 290 void TearDown() override {}; 291}; 292 293/** 294 * @tc.name: EncdecNormalCheck001 295 * @tc.desc: Test encode decode function for non-pointer type in normal mode. 296 * @tc.type: FUNC 297 * @tc.require: AR000F77MR 298 */ 299HWTEST_F(EncdecTest, EncdecNormalCheck001, TestSize.Level0) 300{ 301 HILOGD ("**********[Test]Normal test start, all the result should return 0************"); 302 BasicTypesCheck(); 303 HILOGD ("**********[Test]Normal test end************"); 304} 305 306/** 307 * @tc.name: EncdecNormalCheck002 308 * @tc.desc: Test encode decode function for struct without pointer. 309 * @tc.type: FUNC 310 * @tc.require: AR000F77MR 311 */ 312HWTEST_F(EncdecTest, EncdecNormalCheck002, TestSize.Level0) 313{ 314 HILOGD ("**********[Test]Normal test start, all the result should return 0************"); 315 StructCheck(); 316 HILOGD ("**********[Test]Normal test end************"); 317} 318 319/** 320 * @tc.name: EncdecNormalCheck003 321 * @tc.desc: Test encode decode function for types which include pointers in normal mode. 322 * @tc.type: FUNC 323 * @tc.require: AR000F77MR 324 */ 325HWTEST_F(EncdecTest, EncdecNormalCheck003, TestSize.Level0) 326{ 327 HILOGD ("**********[Test]Normal test start, all the result should return 0************"); 328 StructWithPointerCheck(); 329 HILOGD ("**********[Test]Normal test end************"); 330} 331 332/** 333 * @tc.name: EncdecAbnormalCheck001 334 * @tc.desc: Test encode decode function for non-pointer type in abnormal mode. 335 * @tc.type: FUNC 336 * @tc.require: AR000F77MR 337 */ 338HWTEST_F(EncdecTest, EncdecAbnormalCheck001, TestSize.Level1) 339{ 340 HILOGD ("**********[Test]abnormal test start************"); 341 BasicTypesCheck(false); 342 HILOGD ("**********[Test]abnormal test end************"); 343} 344 345/** 346 * @tc.name: EncdecAbnormalCheck002 347 * @tc.desc: Test encode decode function for types which include pointers in abnormal mode. 348 * @tc.type: FUNC 349 * @tc.require: AR000F77MR 350 */ 351HWTEST_F(EncdecTest, EncdecAbnormalCheck002, TestSize.Level1) 352{ 353 HILOGD ("**********[Test]abnormal test start************"); 354 StructCheck(false); 355 HILOGD ("**********[Test]abnormal test end************"); 356} 357 358/** 359 * @tc.name: EncdecAbnormalCheck003 360 * @tc.desc: Test encode decode function for types which include pointers in normal mode. 361 * @tc.type: FUNC 362 * @tc.require: AR000F77MR 363 */ 364HWTEST_F(EncdecTest, EncdecAbnormalCheck003, TestSize.Level1) 365{ 366 HILOGD ("**********[Test]Normal test start, all the result should return 0************"); 367 StructWithPointerCheck(false); 368 HILOGD ("**********[Test]Normal test end************"); 369} 370