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_tools_unit_test.h"
17
18 #include <gtest/gtest.h>
19
20 #include "db_errno.h"
21 #include "log_print.h"
22 #include "schema_utils.h"
23
24 using namespace testing::ext;
25 using namespace DistributedDB;
26 using namespace DistributedDBUnitTest;
27 using namespace std;
28
29 class DistributedDBSchemalTest : public testing::Test {
30 public:
31 static void SetUpTestCase(void);
32 static void TearDownTestCase(void);
33 void SetUp();
34 void TearDown();
35 };
36
SetUpTestCase(void)37 void DistributedDBSchemalTest::SetUpTestCase(void)
38 {
39 }
40
TearDownTestCase(void)41 void DistributedDBSchemalTest::TearDownTestCase(void)
42 {
43 }
44
SetUp(void)45 void DistributedDBSchemalTest::SetUp(void)
46 {
47 DistributedDBToolsUnitTest::PrintTestCaseInfo();
48 }
49
TearDown(void)50 void DistributedDBSchemalTest::TearDown(void)
51 {
52 }
53
54 namespace {
55 map<string, SchemaAttribute> g_schemaAttrDefTestDataDir;
56
CheckSchemaAttribute(const SchemaAttribute & res,const SchemaAttribute & check)57 void CheckSchemaAttribute(const SchemaAttribute &res, const SchemaAttribute &check)
58 {
59 EXPECT_EQ(res.type, check.type);
60 EXPECT_EQ(res.isIndexable, check.isIndexable);
61 EXPECT_EQ(res.hasNotNullConstraint, check.hasNotNullConstraint);
62 EXPECT_EQ(res.hasDefaultValue, check.hasDefaultValue);
63 EXPECT_EQ(res.defaultValue.stringValue, check.defaultValue.stringValue);
64 EXPECT_EQ(memcmp(&res.defaultValue, &check.defaultValue, 8), 0); // only check this unit 8 byte
65 }
66
PreNumDataForParseAndCheckSchemaAttribute003()67 void PreNumDataForParseAndCheckSchemaAttribute003()
68 {
69 SchemaAttribute attributeRes;
70 attributeRes.type = FieldType::LEAF_FIELD_INTEGER;
71 attributeRes.defaultValue.integerValue = 0;
72 attributeRes.hasDefaultValue = true;
73 g_schemaAttrDefTestDataDir["INTEGER, DEFAULT 0"] = attributeRes;
74
75 SchemaAttribute attributeRes1;
76 attributeRes1.type = FieldType::LEAF_FIELD_INTEGER;
77 attributeRes1.hasDefaultValue = true;
78 attributeRes1.hasNotNullConstraint = true;
79 attributeRes1.defaultValue.integerValue = INT32_MAX;
80 g_schemaAttrDefTestDataDir["INTEGER, NOT NULL, DEFAULT " + std::to_string(INT32_MAX)] = attributeRes1;
81
82 SchemaAttribute attributeRes2;
83 attributeRes2.type = FieldType::LEAF_FIELD_INTEGER;
84 attributeRes2.hasDefaultValue = true;
85 attributeRes2.defaultValue.integerValue = 0;
86 g_schemaAttrDefTestDataDir["INTEGER, DEFAULT +0"] = attributeRes2;
87
88 SchemaAttribute attributeRes3;
89 attributeRes3.type = FieldType::LEAF_FIELD_LONG;
90 attributeRes3.hasDefaultValue = true;
91 attributeRes3.defaultValue.longValue = 0;
92 g_schemaAttrDefTestDataDir["LONG, DEFAULT -0"] = attributeRes3;
93
94 SchemaAttribute attributeRes4;
95 attributeRes4.type = FieldType::LEAF_FIELD_LONG;
96 attributeRes4.hasNotNullConstraint = true;
97 attributeRes4.hasDefaultValue = true;
98 attributeRes4.defaultValue.longValue = LONG_MAX;
99 g_schemaAttrDefTestDataDir["LONG, NOT NULL,DEFAULT " + std::to_string(LONG_MAX)] = attributeRes4;
100 }
101
PreStringDataForParseAndCheckSchemaAttribute003()102 void PreStringDataForParseAndCheckSchemaAttribute003()
103 {
104 SchemaAttribute attributeRes5;
105 attributeRes5.type = FieldType::LEAF_FIELD_STRING;
106 attributeRes5.hasDefaultValue = true;
107 attributeRes5.defaultValue.stringValue = "11ada%$%";
108 g_schemaAttrDefTestDataDir["STRING , DEFAULT '11ada%$%'"] = attributeRes5;
109
110 SchemaAttribute attributeRes6;
111 attributeRes6.type = FieldType::LEAF_FIELD_STRING;
112 attributeRes6.hasNotNullConstraint = true;
113 attributeRes6.hasDefaultValue = true;
114 attributeRes6.defaultValue.stringValue = "asdasd_\n\t";
115 g_schemaAttrDefTestDataDir["STRING, NOT NULL , DEFAULT 'asdasd_\n\t'"] = attributeRes6;
116 }
117
PreDoubleDataForParseAndCheckSchemaAttribute003()118 void PreDoubleDataForParseAndCheckSchemaAttribute003()
119 {
120 SchemaAttribute attributeRes7;
121 attributeRes7.type = FieldType::LEAF_FIELD_DOUBLE;
122 attributeRes7.hasDefaultValue = true;
123 attributeRes7.defaultValue.doubleValue = 0;
124 g_schemaAttrDefTestDataDir["DOUBLE,DEFAULT 0.0"] = attributeRes7;
125
126 SchemaAttribute attributeRes8;
127 attributeRes8.type = FieldType::LEAF_FIELD_DOUBLE;
128 attributeRes8.hasDefaultValue = true;
129 attributeRes8.defaultValue.doubleValue = 0;
130 g_schemaAttrDefTestDataDir["DOUBLE,DEFAULT 0."] = attributeRes8;
131
132 SchemaAttribute attributeRes9;
133 attributeRes9.type = FieldType::LEAF_FIELD_DOUBLE;
134 attributeRes9.hasDefaultValue = true;
135 attributeRes9.defaultValue.doubleValue = 0.1; // 0.1 as test data
136 g_schemaAttrDefTestDataDir["DOUBLE,DEFAULT 0.1"] = attributeRes9;
137
138 SchemaAttribute attributeRes10;
139 attributeRes10.type = FieldType::LEAF_FIELD_DOUBLE;
140 attributeRes10.hasNotNullConstraint = true;
141 attributeRes10.hasDefaultValue = true;
142 attributeRes10.defaultValue.doubleValue = -0.123456; // -0.123456 as test data
143 g_schemaAttrDefTestDataDir["DOUBLE, NOT NULL,DEFAULT -0.123456"] = attributeRes10;
144
145 SchemaAttribute attributeRes11;
146 attributeRes11.type = FieldType::LEAF_FIELD_DOUBLE;
147 attributeRes11.hasNotNullConstraint = false;
148 attributeRes11.hasDefaultValue = true;
149 attributeRes11.defaultValue.doubleValue = 0;
150 g_schemaAttrDefTestDataDir["DOUBLE,DEFAULT +0.0"] = attributeRes11;
151
152 // double -0 Has been manually verified
153 SchemaAttribute attributeRes13;
154 attributeRes13.type = FieldType::LEAF_FIELD_DOUBLE;
155 attributeRes13.hasNotNullConstraint = true;
156 attributeRes13.hasDefaultValue = true;
157 attributeRes13.defaultValue.doubleValue = DBL_MAX;
158 g_schemaAttrDefTestDataDir["DOUBLE, NOT NULL,DEFAULT " + std::to_string(DBL_MAX)] = attributeRes13;
159 }
160
PreBoolDataForParseAndCheckSchemaAttribute003()161 void PreBoolDataForParseAndCheckSchemaAttribute003()
162 {
163 SchemaAttribute attributeRes14;
164 attributeRes14.type = FieldType::LEAF_FIELD_BOOL;
165 attributeRes14.hasNotNullConstraint = false;
166 attributeRes14.hasDefaultValue = true;
167 attributeRes14.defaultValue.boolValue = false;
168 g_schemaAttrDefTestDataDir["BOOL,DEFAULT false"] = attributeRes14;
169
170 SchemaAttribute attributeRes15;
171 attributeRes15.type = FieldType::LEAF_FIELD_BOOL;
172 attributeRes15.hasNotNullConstraint = true;
173 attributeRes15.hasDefaultValue = true;
174 attributeRes15.defaultValue.boolValue = true;
175 g_schemaAttrDefTestDataDir["BOOL, NOT NULL,DEFAULT true"] = attributeRes15;
176 }
177 } // namespace
178
179 /**
180 * @tc.name: ParseAndCheckSchemaAttribute001
181 * @tc.desc: Ability to recognize and parse the correct schema attribute format
182 * @tc.type: FUNC
183 * @tc.require: AR000DR9K3
184 * @tc.author: sunpeng
185 */
186 HWTEST_F(DistributedDBSchemalTest, ParseAndCheckSchemaAttribute001, TestSize.Level1)
187 {
188 /**
189 * @tc.steps: step1. Preset shcema attribute strings that are correctly written according to the definition.
190 */
191 SchemaAttribute attributeRes;
192 attributeRes.type = FieldType::LEAF_FIELD_INTEGER;
193 g_schemaAttrDefTestDataDir["INTEGER"] = attributeRes;
194
195 SchemaAttribute attributeRes1;
196 attributeRes1.type = FieldType::LEAF_FIELD_BOOL;
197 attributeRes1.hasNotNullConstraint = true;
198 g_schemaAttrDefTestDataDir["BOOL, NOT NULL"] = attributeRes1;
199
200 SchemaAttribute attributeRes2;
201 attributeRes2.type = FieldType::LEAF_FIELD_STRING;
202 attributeRes2.hasDefaultValue = true;
203 attributeRes2.defaultValue.stringValue = "dasdads";
204 g_schemaAttrDefTestDataDir["STRING,DEFAULT 'dasdads'"] = attributeRes2;
205
206 SchemaAttribute attributeRes3;
207 attributeRes3.type = FieldType::LEAF_FIELD_DOUBLE;
208 attributeRes3.hasDefaultValue = true;
209 attributeRes3.hasNotNullConstraint = true;
210 attributeRes3.defaultValue.doubleValue = -1.0;
211 g_schemaAttrDefTestDataDir["\tDOUBLE \t,\t\t\tNOT NULL , DEFAULT -1.0"] = attributeRes3;
212
213 SchemaAttribute attributeRes4;
214 attributeRes4.type = FieldType::LEAF_FIELD_LONG;
215 attributeRes4.hasNotNullConstraint = false;
216 attributeRes4.hasDefaultValue = false;
217 g_schemaAttrDefTestDataDir["LONG,DEFAULT null"] = attributeRes4;
218
219 /**
220 * @tc.steps: step2. Call interface
221 * @tc.expected: step2. Returns E_OK and parses correctly.
222 */
223 for (auto &iter : g_schemaAttrDefTestDataDir) {
224 SchemaAttribute attributeOut;
225 LOGD("Attr : %s", iter.first.c_str());
226 EXPECT_EQ(SchemaUtils::ParseAndCheckSchemaAttribute(iter.first, attributeOut), E_OK);
227 CheckSchemaAttribute(iter.second, attributeOut);
228 }
229 }
230
231 /**
232 * @tc.name: ParseAndCheckSchemaAttribute002
233 * @tc.desc: Can identify the wrong schema attribute format and report an error.
234 * @tc.type: FUNC
235 * @tc.require: AR000DR9K3
236 * @tc.author: sunpeng
237 */
238 HWTEST_F(DistributedDBSchemalTest, ParseAndCheckSchemaAttribute002, TestSize.Level1)
239 {
240 /**
241 * @tc.steps: step1. Preset shcema attributes based on definition error.
242 */
243 std::vector<std::string> preData = {
244 "",
245 " ",
246 "$INTEGER",
247 "INTEGER NOT_NULL DEFAULT 1",
248 "STRING \n DEFAULT 'a'",
249 "BOOL,NOT NULL",
250 "LONG,NOT\tNULL",
251 "BOOL,NOT null",
252 "bool,not null",
253 "BOOL,NOT NULL,default false",
254 "INTEGER,",
255 "BOOL, NOT NULL,",
256 "BOOL, NOT NULL,DEFAULT ",
257 "BOOL, DEFAULT false, NOT NULL",
258 "DEFAULT 1, LONG, NOT NULL",
259 "DEFAULT 1",
260 "NOT NULL, DEFAULT x",
261 ", NOT NULL DEFAULT 1",
262 "LONG, NOT NULL, DEFAULT null"
263 };
264 string overflowDol = to_string(DBL_MAX);
265 overflowDol = '1' + overflowDol;
266 preData.push_back("DOUBLE, NOT NULL, DEFAULT " + overflowDol);
267 preData.push_back("DOUBLE, NOT NULL, DEFAULT -" + overflowDol);
268
269 preData.push_back("INTEGER, NOT NULL, DEFAULT 2147483648"); // int max + 1;
270 preData.push_back("INTEGER, NOT NULL, DEFAULT -2147483649");
271 preData.push_back("LONG, NOT NULL, DEFAULT 9223372036854775808"); // long max + 1;
272 preData.push_back("LONG, NOT NULL, DEFAULT -9223372036854775809");
273
274 /**
275 * @tc.steps: step2. Call interface ParseAndCheckSchemaAttribute.
276 * @tc.expected: step2. Returns -E_SCHEMA_PARSE_FAIL.
277 */
278 for (auto &iter : preData) {
279 SchemaAttribute attributeOut;
280 LOGD("Attr : %s", iter.c_str());
281 EXPECT_EQ(SchemaUtils::ParseAndCheckSchemaAttribute(iter, attributeOut), -E_SCHEMA_PARSE_FAIL);
282 }
283 }
284
285 /**
286 * @tc.name: ParseAndCheckSchemaAttribute003
287 * @tc.desc: Can correctly interpret the meaning of each keyword of the schema attribute
288 * @tc.type: FUNC
289 * @tc.require: AR000DR9K3
290 * @tc.author: sunpeng
291 */
292 HWTEST_F(DistributedDBSchemalTest, ParseAndCheckSchemaAttribute003, TestSize.Level1)
293 {
294 /**
295 * @tc.steps: step1. Preset shcema attributes based on defining correct format and content.
296 */
297 g_schemaAttrDefTestDataDir.clear();
298 PreNumDataForParseAndCheckSchemaAttribute003();
299 PreDoubleDataForParseAndCheckSchemaAttribute003();
300 PreStringDataForParseAndCheckSchemaAttribute003();
301 PreBoolDataForParseAndCheckSchemaAttribute003();
302
303 /**
304 * @tc.steps: step2. Call interface ParseAndCheckSchemaAttribute.
305 * @tc.expected: step2. Returns E_OK and parses correctly.
306 */
307 for (auto &iter : g_schemaAttrDefTestDataDir) {
308 SchemaAttribute attributeOut;
309 EXPECT_EQ(SchemaUtils::ParseAndCheckSchemaAttribute(iter.first, attributeOut), E_OK);
310 CheckSchemaAttribute(iter.second, attributeOut);
311 }
312 }
313
314 /**
315 * @tc.name: ParseAndCheckSchemaAttribute004
316 * @tc.desc: Can correctly identify the meaning of the schema attribute field that is incorrectly parsed
317 * @tc.type: FUNC
318 * @tc.require: AR000DR9K3
319 * @tc.author: sunpeng
320 */
321 HWTEST_F(DistributedDBSchemalTest, ParseAndCheckSchemaAttribute004, TestSize.Level1)
322 {
323 /**
324 * @tc.steps: step1. Preset shcema attributes based on defining incorrect format and content.
325 */
326 std::vector<std::string> preData = {
327 "LONG,NOT NULL, DEFAULT '123'",
328 "STRING,DEFAULT true",
329 "INTEGER,NOT NULL,DEFAULT MAX+1",
330 "LONG,DEFAULT 0.0",
331 "INTEGER,NOT NULL,DEFAULT - 123",
332 "INTEGER,DEFAULT 12 3",
333 "LONG,NOT NULL,DEFAULT 0xFF",
334 "INTEGER,00",
335 "DOUBLE,DEFAULT 123a",
336 "DOUBLE,NOT NULL,DEFAULT 0..0",
337 "DOUBLE,DEFAULT 2e2",
338 "DOUBLE,NOT NULL,DEFAULT 1+1",
339 "DOUBLE,NOT NULL,DEFAULT .0",
340 "DOUBLE,DEFAULT MAX+1",
341 "STRING,DEFAULT 123",
342 "STRING,NOT NULL,DEFAULT 'ABC",
343 "BOOL,DEFAULT TRUE",
344 "INT",
345 "long",
346 "String",
347 "STRING DEFAULT 'a'a",
348 };
349
350 /**
351 * @tc.steps: step2. Call interface ParseAndCheckSchemaAttribute.
352 * @tc.expected: step2. Returns -E_SCHEMA_PARSE_FAIL.
353 */
354 string overSize(4 * 1024 + 1, 'a');
355 preData.push_back("STRING, DEFAULT '" + overSize + "'");
356 LOGD("%s", preData[0].c_str());
357 for (auto &iter : preData) {
358 SchemaAttribute attributeOut;
359 EXPECT_EQ(SchemaUtils::ParseAndCheckSchemaAttribute(iter, attributeOut), -E_SCHEMA_PARSE_FAIL);
360 }
361 }
362
363 /**
364 * @tc.name: CheckFieldName001
365 * @tc.desc: Correctly identify field names
366 * @tc.type: FUNC
367 * @tc.require: AR000DR9K3
368 * @tc.author: sunpeng
369 */
370 HWTEST_F(DistributedDBSchemalTest, CheckFieldName001, TestSize.Level1)
371 {
372 /**
373 * @tc.steps: step1. Enter the preset correct string array into CheckFieldName and check.
374 * @tc.expected: step1. Returns E_OK.
375 */
376 std::vector<std::string> preData = {
377 "_abc",
378 "_123abc",
379 "a_123_",
380 };
381 string overSize(64, 'a');
382 preData.push_back(overSize);
383 for (auto &iter : preData) {
384 EXPECT_EQ(SchemaUtils::CheckFieldName(iter), E_OK);
385 }
386 }
387
388 /**
389 * @tc.name: CheckFieldName002
390 * @tc.desc: Identify illegal field name
391 * @tc.type: FUNC
392 * @tc.require: AR000DR9K3
393 * @tc.author: sunpeng
394 */
395 HWTEST_F(DistributedDBSchemalTest, CheckFieldName002, TestSize.Level1)
396 {
397 /**
398 * @tc.steps: step1. Enter the preset incorrect string array into CheckFieldName and check.
399 * @tc.expected: step1. Returns -E_SCHEMA_PARSE_FAIL.
400 */
401 std::vector<std::string> preData = {
402 "123abc",
403 "$.LONG",
404 "",
405 " abc",
406 "\tabc"
407 };
408 string overSize(65, 'a');
409 preData.push_back(overSize);
410 for (auto &iter : preData) {
411 EXPECT_EQ(SchemaUtils::CheckFieldName(iter), -E_SCHEMA_PARSE_FAIL);
412 }
413 }
414
415 /**
416 * @tc.name: ParseAndCheckFieldPath001
417 * @tc.desc: Correctly identify and parse shema index fields
418 * @tc.type: FUNC
419 * @tc.require: AR000DR9K3
420 * @tc.author: sunpeng
421 */
422 HWTEST_F(DistributedDBSchemalTest, ParseAndCheckFieldPath001, TestSize.Level1)
423 {
424 /**
425 * @tc.steps: step1. Enter the array of preset correct strings into ParseAndCheckFieldPath and check result.
426 * @tc.expected: step1. Returns E_OK and Parse correctly.
427 */
428 vector<pair<string, vector<string> > > testPreData {
429 // test
430 // ans
431 {"$.abc.def.fg",
432 {"abc", "def", "fg"}},
433
434 {"$.abc._def.fg",
435 {"abc", "_def", "fg"}},
436
437 {"$._.__.___",
438 {"_", "__", "___"}},
439
440 {"$._.__1234.abc455545",
441 {"_", "__1234", "abc455545"}},
442
443 {" $.abc._def.fg",
444 {"abc", "_def", "fg"}},
445
446 {" $.a.a.a.a",
447 {"a", "a", "a", "a"}},
448
449 {"$.abc._def.fg ",
450 {"abc", "_def", "fg"}},
451
452 {" $.abc._def.fg ",
453 {"abc", "_def", "fg"}},
454
455 {"\t$.abc.def.fg ",
456 {"abc", "def", "fg"}},
457
458 {" $.abc.def.fg\r\t",
459 {"abc", "def", "fg"}},
460
461 {"\r$.abc.def.fg\t\r",
462 {"abc", "def", "fg"}},
463 };
464
465 for (auto &iter : testPreData) {
466 FieldPath ans;
467 EXPECT_EQ(SchemaUtils::ParseAndCheckFieldPath(iter.first, ans), E_OK);
468 EXPECT_EQ(ans, iter.second);
469 }
470 }
471
472 /**
473 * @tc.name: ParseAndCheckFieldPath002
474 * @tc.desc: Correctly identify illegal shema index fields
475 * @tc.type: FUNC
476 * @tc.require: AR000DR9K3
477 * @tc.author: sunpeng
478 */
479 HWTEST_F(DistributedDBSchemalTest, ParseAndCheckFieldPath002, TestSize.Level1)
480 {
481 /**
482 * @tc.steps: step1. Enter the array of preset illegal strings into ParseAndCheckFieldPath and check result.
483 * @tc.expected: step1. Returns -E_SCHEMA_PARSE_FAIL.
484 */
485 vector<string> testPreData {
486 "",
487 "\t",
488 "\r",
489 "\r\t",
490 " ",
491 "$",
492 "$.",
493 " . ",
494 "$$",
495 "$.$",
496 "$.a.b.c.d.e",
497 "$..abc",
498 "$.abc..def.fg",
499 "$abc.def.fg.",
500 "$.123",
501 "$.abc123%",
502 "$.abc.\0.fg",
503 "$.abc.fg.\0",
504 "\"$.abc.def.fg\"",
505 "$.\"abc\".def.fg",
506 "$.\"abc\n.def.fg",
507 };
508
509 for (auto &iter : testPreData) {
510 FieldPath ans;
511 EXPECT_EQ(SchemaUtils::ParseAndCheckFieldPath(iter, ans), -E_SCHEMA_PARSE_FAIL);
512 }
513 }
514
515 /**
516 * @tc.name: ParseTrackerSchemaAndName
517 * @tc.desc: Correctly identify illegal shema index fields
518 * @tc.type: FUNC
519 * @tc.require: DTS2024073106613
520 * @tc.author: suyue
521 */
522 HWTEST_F(DistributedDBSchemalTest, ParseTrackerSchemaAndName, TestSize.Level1)
523 {
524 /**
525 * @tc.steps: step1. Trans TrackerSchema to Lower.
526 * @tc.expected: step1. Trans success.
527 */
528 const TrackerSchema srcSchema = {"Test", "Col", {"Col1", "Col2"}};
529 TrackerSchema destSchema;
530 SchemaUtils::TransTrackerSchemaToLower(srcSchema, destSchema);
531 TrackerSchema expectedSchema = {"test", "col", {"col1", "col2"}};
532 EXPECT_TRUE(destSchema.tableName.compare(0, expectedSchema.tableName.length(), expectedSchema.tableName) == 0);
533 EXPECT_TRUE(
534 destSchema.extendColName.compare(0, expectedSchema.extendColName.length(), expectedSchema.extendColName) == 0);
535
536 /**
537 * @tc.steps: step2. Strip space from name.
538 * @tc.expected: step2. Success.
539 */
540 const std::string inputName1 = "test1";
541 std::string expectedName1 = "test1";
542 std::string outputName1 = SchemaUtils::StripNameSpace(inputName1);
543 EXPECT_TRUE(outputName1.compare(0, expectedName1.length(), expectedName1) == 0);
544
545 const std::string inputName2 = "test1.test2";
546 std::string expectedName2 = "test2";
547 std::string outputName2 = SchemaUtils::StripNameSpace(inputName2);
548 EXPECT_TRUE(outputName2.compare(0, expectedName2.length(), expectedName2) == 0);
549 }