1 /*
2 * Copyright (c) 2022 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 #ifndef OMIT_JSON
17 #include <gtest/gtest.h>
18 #include <cmath>
19
20 #include "db_errno.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "log_print.h"
23 #include "relational_schema_object.h"
24 #include "schema_utils.h"
25 #include "schema_constant.h"
26 #include "schema_negotiate.h"
27
28 using namespace std;
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32
33 namespace {
34 const std::string NORMAL_SCHEMA = R""({
35 "SCHEMA_VERSION": "2.0",
36 "SCHEMA_TYPE": "RELATIVE",
37 "TABLES": [{
38 "NAME": "FIRST",
39 "DEFINE": {
40 "field_name1": {
41 "COLUMN_ID":1,
42 "TYPE": "STRING",
43 "NOT_NULL": true,
44 "DEFAULT": "abcd"
45 },
46 "field_name2": {
47 "COLUMN_ID":2,
48 "TYPE": "MYINT(21)",
49 "NOT_NULL": false,
50 "DEFAULT": "222"
51 },
52 "field_name3": {
53 "COLUMN_ID":3,
54 "TYPE": "INTGER",
55 "NOT_NULL": false,
56 "DEFAULT": "1"
57 }
58 },
59 "AUTOINCREMENT": true,
60 "UNIQUE": [["field_name1"], ["field_name2", "field_name3"]],
61 "PRIMARY_KEY": "field_name1",
62 "INDEX": {
63 "index_name1": ["field_name1", "field_name2"],
64 "index_name2": ["field_name3"]
65 }
66 }, {
67 "NAME": "SECOND",
68 "DEFINE": {
69 "key": {
70 "COLUMN_ID":1,
71 "TYPE": "BLOB",
72 "NOT_NULL": true
73 },
74 "value": {
75 "COLUMN_ID":2,
76 "TYPE": "BLOB",
77 "NOT_NULL": false
78 }
79 },
80 "PRIMARY_KEY": "field_name1"
81 }]
82 })"";
83
84 const std::string NORMAL_SCHEMA_V2_1 = R""({
85 "SCHEMA_VERSION": "2.1",
86 "SCHEMA_TYPE": "RELATIVE",
87 "TABLE_MODE": "SPLIT_BY_DEVICE",
88 "TABLES": [{
89 "NAME": "FIRST",
90 "DEFINE": {
91 "field_name1": {
92 "COLUMN_ID":1,
93 "TYPE": "STRING",
94 "NOT_NULL": true,
95 "DEFAULT": "abcd"
96 },
97 "field_name2": {
98 "COLUMN_ID":2,
99 "TYPE": "MYINT(21)",
100 "NOT_NULL": false,
101 "DEFAULT": "222"
102 },
103 "field_name3": {
104 "COLUMN_ID":3,
105 "TYPE": "INTGER",
106 "NOT_NULL": false,
107 "DEFAULT": "1"
108 }
109 },
110 "AUTOINCREMENT": true,
111 "UNIQUE": [["field_name1"], ["field_name2", "field_name3"]],
112 "PRIMARY_KEY": ["field_name1", "field_name3"],
113 "INDEX": {
114 "index_name1": ["field_name1", "field_name2"],
115 "index_name2": ["field_name3"]
116 }
117 }, {
118 "NAME": "SECOND",
119 "DEFINE": {
120 "key": {
121 "COLUMN_ID":1,
122 "TYPE": "BLOB",
123 "NOT_NULL": true
124 },
125 "value": {
126 "COLUMN_ID":2,
127 "TYPE": "BLOB",
128 "NOT_NULL": false
129 }
130 },
131 "PRIMARY_KEY": ["field_name1"]
132 }]
133 })"";
134
135 const std::string INVALID_SCHEMA = R""({
136 "SCHEMA_VERSION": "2.0",
137 "SCHEMA_TYPE": "RELATIVE",
138 "TABLES": [{
139 "NAME": "FIRST",
140 "DEFINE": {
141 "field_name1": {
142 "COLUMN_ID":1,
143 "TYPE": "STRING",
144 "NOT_NULL": true,
145 "DEFAULT": "abcd"
146 },"field_name2": {
147 "COLUMN_ID":2,
148 "TYPE": "MYINT(21)",
149 "NOT_NULL": false,
150 "DEFAULT": "222"
151 }
152 },
153 "PRIMARY_KEY": "field_name1"
154 }]
155 })"";
156
157 const std::string INVALID_JSON_STRING = R""({
158 "SCHEMA_VERSION": "2.0",
159 "SCHEMA_TYPE": "RELATIVE",
160 "TABLES": [{
161 "NAME": "FIRST",
162 "DEFINE": {
163 "field_name1": {)"";
164
165 const std::string SCHEMA_VERSION_STR_1 = R"("SCHEMA_VERSION": "1.0",)";
166 const std::string SCHEMA_VERSION_STR_2 = R"("SCHEMA_VERSION": "2.0",)";
167 const std::string SCHEMA_VERSION_STR_2_1 = R"("SCHEMA_VERSION": "2.1",)";
168 const std::string SCHEMA_VERSION_STR_INVALID = R"("SCHEMA_VERSION": "awd3",)";
169 const std::string SCHEMA_TYPE_STR_NONE = R"("SCHEMA_TYPE": "NONE",)";
170 const std::string SCHEMA_TYPE_STR_JSON = R"("SCHEMA_TYPE": "JSON",)";
171 const std::string SCHEMA_TYPE_STR_FLATBUFFER = R"("SCHEMA_TYPE": "FLATBUFFER",)";
172 const std::string SCHEMA_TYPE_STR_RELATIVE = R"("SCHEMA_TYPE": "RELATIVE",)";
173 const std::string SCHEMA_TYPE_STR_INVALID = R"("SCHEMA_TYPE": "adewaaSAD",)";
174 const std::string SCHEMA_TABLE_MODE_COLLABORATION = R"("TABLE_MODE": "COLLABORATION",)";
175 const std::string SCHEMA_TABLE_MODE_SPLIT_BY_DEVICE = R"("TABLE_MODE": "SPLIT_BY_DEVICE",)";
176 const std::string SCHEMA_TABLE_MODE_INVALID = R"("TABLE_MODE": "SPLIT_BY_USER",)";
177
178 const std::string SCHEMA_TABLE_STR = R""("TABLES": [{
179 "NAME": "FIRST",
180 "DEFINE": {
181 "field_name1": {
182 "COLUMN_ID":1,
183 "TYPE": "STRING",
184 "NOT_NULL": true,
185 "DEFAULT": "abcd"
186 },"field_name2": {
187 "COLUMN_ID":2,
188 "TYPE": "MYINT(21)",
189 "NOT_NULL": false,
190 "DEFAULT": "222"
191 }
192 },
193 "PRIMARY_KEY": "field_name1"
194 }])"";
195
196 const std::string TABLE_DEFINE_STR = R""({
197 "NAME": "FIRST",
198 "DEFINE": {
199 "field_name1": {
200 "COLUMN_ID":1,
201 "TYPE": "STRING",
202 "NOT_NULL": true,
203 "DEFAULT": "abcd"
204 },"field_name2": {
205 "COLUMN_ID":2,
206 "TYPE": "MYINT(21)",
207 "NOT_NULL": false,
208 "DEFAULT": "222"
209 }
210 },
211 "PRIMARY_KEY": "field_name1"
212 })"";
213
214 const std::string TABLE_DEFINE_STR_NAME = R""("NAME": "FIRST",)"";
215 const std::string TABLE_DEFINE_STR_NAME_INVALID = R"("NAME": 123,)";
216 const std::string TABLE_DEFINE_STR_NAME_INVALID_CHARACTER = R"("NAME": "t1; --",)";
217 const std::string TABLE_DEFINE_STR_FIELDS = R""("DEFINE": {
218 "field_name1": {
219 "COLUMN_ID":1,
220 "TYPE": "STRING",
221 "NOT_NULL": true,
222 "DEFAULT": "abcd"
223 },"field_name2": {
224 "COLUMN_ID":2,
225 "TYPE": "MYINT(21)",
226 "NOT_NULL": false,
227 "DEFAULT": "222"
228 }
229 },)"";
230 const std::string TABLE_DEFINE_STR_FIELDS_EMPTY = R""("DEFINE": {},)"";
231 const std::string TABLE_DEFINE_STR_FIELDS_NOTYPE = R""("DEFINE": {
232 "field_name1": {
233 "COLUMN_ID":1,
234 "NOT_NULL": true,
235 "DEFAULT": "abcd"
236 }},)"";
237 const std::string TABLE_DEFINE_STR_FIELDS_INVALID_CHARACTER = R""("DEFINE": {
238 "1 = 1; --": {
239 "COLUMN_ID":1,
240 "NOT_NULL": true,
241 "DEFAULT": "abcd"
242 }},)"";
243 const std::string TABLE_DEFINE_STR_KEY = R""("PRIMARY_KEY": "field_name1")"";
244 const std::string TABLE_DEFINE_BOOL_KEY_INVALID = R""("PRIMARY_KEY": false)"";
245 const std::string TABLE_DEFINE_BOOL_ARRAY_KEY_INVALID = R""("PRIMARY_KEY": [false, true, true])"";
246 }
247
248 class DistributedDBRelationalSchemaObjectTest : public testing::Test {
249 public:
SetUpTestCase(void)250 static void SetUpTestCase(void) {};
TearDownTestCase(void)251 static void TearDownTestCase(void) {};
252 void SetUp() override;
TearDown()253 void TearDown() override {};
254 };
255
SetUp()256 void DistributedDBRelationalSchemaObjectTest::SetUp()
257 {
258 DistributedDBToolsUnitTest::PrintTestCaseInfo();
259 }
260
261 /**
262 * @tc.name: RelationalSchemaParseTest001
263 * @tc.desc: Test relational schema parse from json string
264 * @tc.type: FUNC
265 * @tc.require: AR000GK58I
266 * @tc.author: lianhuix
267 */
268 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest001, TestSize.Level1)
269 {
270 const std::string schemaStr = NORMAL_SCHEMA;
271 RelationalSchemaObject schemaObj;
272 int errCode = schemaObj.ParseFromSchemaString(schemaStr);
273 EXPECT_EQ(errCode, E_OK);
274 EXPECT_EQ(schemaObj.GetTable("FIRST").GetUniqueDefine().size(), 2u);
275
276 RelationalSchemaObject schemaObj2;
277 schemaObj2.ParseFromSchemaString(schemaObj.ToSchemaString());
278 EXPECT_EQ(errCode, E_OK);
279 EXPECT_EQ(schemaObj2.GetTable("FIRST").GetUniqueDefine().size(), 2u);
280
281 RelationalSyncOpinion op = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, schemaObj2.ToSchemaString(),
282 static_cast<uint8_t>(SchemaType::RELATIVE));
283
284 EXPECT_EQ(op.size(), 2u);
285 EXPECT_EQ(op.at("FIRST").permitSync, true);
286 EXPECT_EQ(op.at("SECOND").permitSync, true);
287 }
288
289 /**
290 * @tc.name: RelationalSchemaParseTest002
291 * @tc.desc: Test relational schema parse from invalid json string
292 * @tc.type: FUNC
293 * @tc.require: AR000GK58I
294 * @tc.author: lianhuix
295 */
296 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest002, TestSize.Level1)
297 {
298 RelationalSchemaObject schemaObj;
299
300 std::string schemaStr01(SchemaConstant::SCHEMA_STRING_SIZE_LIMIT + 1, 's');
301 int errCode = schemaObj.ParseFromSchemaString(schemaStr01);
302 EXPECT_EQ(errCode, -E_INVALID_ARGS);
303
304 errCode = schemaObj.ParseFromSchemaString(INVALID_JSON_STRING);
305 EXPECT_EQ(errCode, -E_JSON_PARSE_FAIL);
306
307 std::string noVersion = "{" + SCHEMA_TYPE_STR_RELATIVE + SCHEMA_TABLE_STR + "}";
308 errCode = schemaObj.ParseFromSchemaString(noVersion);
309 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
310
311 std::string invalidVersion1 = "{" + SCHEMA_VERSION_STR_1 + SCHEMA_TYPE_STR_RELATIVE + SCHEMA_TABLE_STR + "}";
312 errCode = schemaObj.ParseFromSchemaString(invalidVersion1);
313 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
314
315 std::string invalidVersion2 = "{" + SCHEMA_VERSION_STR_INVALID + SCHEMA_TYPE_STR_RELATIVE + SCHEMA_TABLE_STR + "}";
316 errCode = schemaObj.ParseFromSchemaString(invalidVersion2);
317 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
318
319 std::string noType = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TABLE_STR + "}";
320 errCode = schemaObj.ParseFromSchemaString(noType);
321 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
322
323 std::string invalidType1 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_NONE + SCHEMA_TABLE_STR + "}";
324 errCode = schemaObj.ParseFromSchemaString(invalidType1);
325 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
326
327 std::string invalidType2 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_JSON + SCHEMA_TABLE_STR + "}";
328 errCode = schemaObj.ParseFromSchemaString(invalidType2);
329 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
330
331 std::string invalidType3 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_FLATBUFFER + SCHEMA_TABLE_STR + "}";
332 errCode = schemaObj.ParseFromSchemaString(invalidType3);
333 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
334
335 std::string invalidType4 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_INVALID + SCHEMA_TABLE_STR + "}";
336 errCode = schemaObj.ParseFromSchemaString(invalidType4);
337 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
338
339 std::string noTable = "{" + SCHEMA_VERSION_STR_2 +
340 SCHEMA_TYPE_STR_RELATIVE.substr(0, SCHEMA_TYPE_STR_RELATIVE.length() - 1) + "}";
341 errCode = schemaObj.ParseFromSchemaString(noTable);
342 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
343 }
344
345 namespace {
GenerateFromTableStr(const std::string & tableStr)346 std::string GenerateFromTableStr(const std::string &tableStr)
347 {
348 return R""({
349 "SCHEMA_VERSION": "2.0",
350 "SCHEMA_TYPE": "RELATIVE",
351 "TABLES": )"" + tableStr + "}";
352 }
353 }
354
355 /**
356 * @tc.name: RelationalSchemaParseTest003
357 * @tc.desc: Test relational schema parse from invalid json string
358 * @tc.type: FUNC
359 * @tc.require: AR000GK58I
360 * @tc.author: lianhuix
361 */
362 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest003, TestSize.Level1)
363 {
364 RelationalSchemaObject schemaObj;
365 int errCode = E_OK;
366
367 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr(TABLE_DEFINE_STR));
368 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
369
370 std::string invalidTableStr01 = "{" + TABLE_DEFINE_STR_FIELDS + TABLE_DEFINE_STR_KEY + "}";
371 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr01 + "]"));
372 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
373
374 std::string invalidTableStr02 = "{" + TABLE_DEFINE_STR_NAME_INVALID + TABLE_DEFINE_STR_FIELDS +
375 TABLE_DEFINE_STR_KEY + "}";
376 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr02 + "]"));
377 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
378
379 std::string invalidTableStr04 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS_NOTYPE +
380 TABLE_DEFINE_STR_KEY + "}";
381 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr04 + "]"));
382 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
383
384 std::string invalidTableStr05 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS +
385 TABLE_DEFINE_BOOL_KEY_INVALID + "}";
386 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr05 + "]"));
387 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
388
389 std::string invalidTableStr06 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS +
390 TABLE_DEFINE_BOOL_ARRAY_KEY_INVALID + "}";
391 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr06 + "]"));
392 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
393
394 std::string invalidTableStr07 = "{" + TABLE_DEFINE_STR_NAME_INVALID_CHARACTER + TABLE_DEFINE_STR_FIELDS +
395 TABLE_DEFINE_STR_KEY + "}";
396 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr07 + "]"));
397 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
398
399 std::string invalidTableStr08 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS_INVALID_CHARACTER +
400 TABLE_DEFINE_STR_KEY + "}";
401 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr08 + "]"));
402 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
403
404 errCode = schemaObj.ParseFromSchemaString("");
405 EXPECT_EQ(errCode, -E_INVALID_ARGS);
406 }
407
408 /**
409 * @tc.name: RelationalSchemaParseTest004
410 * @tc.desc:
411 * @tc.type: FUNC
412 * @tc.require:
413 * @tc.author: lianhuix
414 */
415 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest004, TestSize.Level1)
416 {
417 RelationalSchemaObject schemaObj;
418 int errCode = E_OK;
419
420 std::string schema = "{" + SCHEMA_VERSION_STR_2_1 + SCHEMA_TABLE_MODE_COLLABORATION + SCHEMA_TYPE_STR_RELATIVE +
421 SCHEMA_TABLE_STR + "}";
422 errCode = schemaObj.ParseFromSchemaString(schema);
423 EXPECT_EQ(errCode, E_OK);
424 }
425
426 /**
427 * @tc.name: RelationalSchemaParseTest005
428 * @tc.desc:
429 * @tc.type: FUNC
430 * @tc.require:
431 * @tc.author: lianhuix
432 */
433 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest005, TestSize.Level1)
434 {
435 RelationalSchemaObject schemaObj;
436 int errCode = E_OK;
437
438 std::string schema = "{" + SCHEMA_VERSION_STR_2_1 + SCHEMA_TABLE_MODE_SPLIT_BY_DEVICE + SCHEMA_TYPE_STR_RELATIVE +
439 SCHEMA_TABLE_STR + "}";
440 errCode = schemaObj.ParseFromSchemaString(schema);
441 EXPECT_EQ(errCode, E_OK);
442 }
443
444 /**
445 * @tc.name: RelationalSchemaParseTest006
446 * @tc.desc:
447 * @tc.type: FUNC
448 * @tc.require:
449 * @tc.author: lianhuix
450 */
451 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest006, TestSize.Level1)
452 {
453 RelationalSchemaObject schemaObj;
454 int errCode = E_OK;
455
456 std::string schema = "{" + SCHEMA_VERSION_STR_2_1 + SCHEMA_TABLE_MODE_INVALID + SCHEMA_TYPE_STR_RELATIVE +
457 SCHEMA_TABLE_STR + "}";
458 errCode = schemaObj.ParseFromSchemaString(schema);
459 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
460 }
461
462
463 /**
464 * @tc.name: RelationalSchemaCompareTest001
465 * @tc.desc: Test relational schema negotiate with same schema string
466 * @tc.type: FUNC
467 * @tc.require: AR000GK58I
468 * @tc.author: lianhuix
469 */
470 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest001, TestSize.Level1)
471 {
472 RelationalSchemaObject schemaObj;
473 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA);
474 EXPECT_EQ(errCode, E_OK);
475
476 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA,
477 static_cast<uint8_t>(SchemaType::RELATIVE));
478 EXPECT_EQ(opinion.at("FIRST").permitSync, true);
479 EXPECT_EQ(opinion.at("FIRST").checkOnReceive, false);
480 EXPECT_EQ(opinion.at("FIRST").requirePeerConvert, false);
481 }
482
483 /**
484 * @tc.name: RelationalSchemaCompareTest002
485 * @tc.desc: Test relational schema v2.1 negotiate with same schema string
486 * @tc.type: FUNC
487 * @tc.require: AR000H2PKN
488 * @tc.author: lianhuix
489 */
490 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest002, TestSize.Level1)
491 {
492 RelationalSchemaObject schemaObj;
493 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1);
494 EXPECT_EQ(errCode, E_OK);
495
496 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1,
497 static_cast<uint8_t>(SchemaType::RELATIVE));
498 EXPECT_EQ(opinion.at("FIRST").permitSync, true);
499 EXPECT_EQ(opinion.at("FIRST").checkOnReceive, false);
500 EXPECT_EQ(opinion.at("FIRST").requirePeerConvert, false);
501 }
502
503 /**
504 * @tc.name: RelationalSchemaCompareTest003
505 * @tc.desc: Test relational schema v2.1 negotiate with schema v2.0
506 * @tc.type: FUNC
507 * @tc.require: AR000H2PKN
508 * @tc.author: lianhuix
509 */
510 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest003, TestSize.Level1)
511 {
512 RelationalSchemaObject schemaObj;
513 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1);
514 EXPECT_EQ(errCode, E_OK);
515
516 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA,
517 static_cast<uint8_t>(SchemaType::RELATIVE));
518 EXPECT_TRUE(opinion.empty());
519 }
520
521 /**
522 * @tc.name: RelationalSchemaCompareTest004
523 * @tc.desc: Test relational schema v2.0 negotiate with schema v2.1
524 * @tc.type: FUNC
525 * @tc.require: AR000H2PKN
526 * @tc.author: lianhuix
527 */
528 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest004, TestSize.Level1)
529 {
530 RelationalSchemaObject schemaObj;
531 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA);
532 EXPECT_EQ(errCode, E_OK);
533
534 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1,
535 static_cast<uint8_t>(SchemaType::RELATIVE));
536 EXPECT_TRUE(opinion.empty());
537 }
538
539 /**
540 * @tc.name: RelationalSchemaCompareTest005
541 * @tc.desc: Test collaboration relational schema negotiate with other table mode
542 * @tc.type: FUNC
543 * @tc.require: AR000H2PKN
544 * @tc.author: lianhuix
545 */
546 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest005, TestSize.Level1)
547 {
548 RelationalSchemaObject schemaObj;
549 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1);
550 EXPECT_EQ(errCode, E_OK);
551 schemaObj.SetTableMode(DistributedTableMode::COLLABORATION);
552
553 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1,
554 static_cast<uint8_t>(SchemaType::RELATIVE));
555 EXPECT_TRUE(opinion.empty());
556 }
557
558 /**
559 * @tc.name: RelationalTableCompareTest001
560 * @tc.desc: Test relational schema negotiate with same schema string
561 * @tc.type: FUNC
562 * @tc.require: AR000GK58I
563 * @tc.author: lianhuix
564 */
565 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalTableCompareTest001, TestSize.Level1)
566 {
567 RelationalSchemaObject schemaObj;
568 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA);
569 EXPECT_EQ(errCode, E_OK);
570 TableInfo table1 = schemaObj.GetTable("FIRST");
571 TableInfo table2 = schemaObj.GetTable("FIRST");
572 EXPECT_EQ(table1.CompareWithTable(table2), -E_RELATIONAL_TABLE_EQUAL);
573
574 table2.AddIndexDefine("indexname", {"field_name2", "field_name1"});
575 EXPECT_EQ(table1.CompareWithTable(table2), -E_RELATIONAL_TABLE_COMPATIBLE);
576
577 TableInfo table3 = schemaObj.GetTable("SECOND");
578 EXPECT_EQ(table1.CompareWithTable(table3), -E_RELATIONAL_TABLE_INCOMPATIBLE);
579
580 TableInfo table4 = schemaObj.GetTable("FIRST");
581 table4.AddField(table3.GetFields().at("value"));
582 EXPECT_EQ(table1.CompareWithTable(table4), -E_RELATIONAL_TABLE_COMPATIBLE_UPGRADE);
583
584 TableInfo table5 = schemaObj.GetTable("FIRST");
585 table5.AddField(table3.GetFields().at("key"));
586 EXPECT_EQ(table1.CompareWithTable(table5), -E_RELATIONAL_TABLE_INCOMPATIBLE);
587
588 TableInfo table6 = schemaObj.GetTable("FIRST");
589 table6.SetUniqueDefine({{"field_name1", "field_name1"}});
590 EXPECT_EQ(table1.CompareWithTable(table6, SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1),
591 -E_RELATIONAL_TABLE_INCOMPATIBLE);
592
593 TableInfo table7 = schemaObj.GetTable("FIRST");
594 table7.SetAutoIncrement(false);
595 EXPECT_EQ(table1.CompareWithTable(table7, SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1),
596 -E_RELATIONAL_TABLE_INCOMPATIBLE);
597 }
598
599 /**
600 * @tc.name: RelationalSchemaOpinionTest001
601 * @tc.desc: Test relational schema sync opinion
602 * @tc.type: FUNC
603 * @tc.require: AR000GK58I
604 * @tc.author: lianhuix
605 */
606 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaOpinionTest001, TestSize.Level1)
607 {
608 RelationalSyncOpinion opinion;
609 opinion["table_1"] = SyncOpinion {true, false, false};
610 opinion["table_2"] = SyncOpinion {false, true, false};
611 opinion["table_3"] = SyncOpinion {false, false, true};
612
613 uint32_t len = SchemaNegotiate::CalculateParcelLen(opinion);
614 std::vector<uint8_t> buff(len, 0);
615 Parcel writeParcel(buff.data(), len);
616 int errCode = SchemaNegotiate::SerializeData(opinion, writeParcel);
617 EXPECT_EQ(errCode, E_OK);
618
619 Parcel readParcel(buff.data(), len);
620 RelationalSyncOpinion opinionRecv;
621 errCode = SchemaNegotiate::DeserializeData(readParcel, opinionRecv);
622 EXPECT_EQ(errCode, E_OK);
623
624 EXPECT_EQ(opinion.size(), opinionRecv.size());
625 for (const auto &it : opinion) {
626 SyncOpinion tableOpinionRecv = opinionRecv.at(it.first);
627 EXPECT_EQ(it.second.permitSync, tableOpinionRecv.permitSync);
628 EXPECT_EQ(it.second.requirePeerConvert, tableOpinionRecv.requirePeerConvert);
629 }
630 }
631
632 /**
633 * @tc.name: RelationalSchemaNegotiateTest001
634 * @tc.desc: Test relational schema negotiate
635 * @tc.type: FUNC
636 * @tc.require: AR000GK58I
637 * @tc.author: lianhuix
638 */
639 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaNegotiateTest001, TestSize.Level1)
640 {
641 RelationalSyncOpinion localOpinion;
642 localOpinion["table_1"] = SyncOpinion {true, false, false};
643 localOpinion["table_2"] = SyncOpinion {false, true, false};
644 localOpinion["table_3"] = SyncOpinion {false, false, true};
645
646 RelationalSyncOpinion remoteOpinion;
647 remoteOpinion["table_2"] = SyncOpinion {true, false, false};
648 remoteOpinion["table_3"] = SyncOpinion {false, true, false};
649 remoteOpinion["table_4"] = SyncOpinion {false, false, true};
650 RelationalSyncStrategy strategy = SchemaNegotiate::ConcludeSyncStrategy(localOpinion, remoteOpinion);
651
652 EXPECT_EQ(strategy.size(), 2u);
653 EXPECT_EQ(strategy.at("table_2").permitSync, true);
654 EXPECT_EQ(strategy.at("table_3").permitSync, false);
655 }
656
657 /**
658 * @tc.name: TableCompareTest001
659 * @tc.desc: Test table compare
660 * @tc.type: FUNC
661 * @tc.require: AR000GK58I
662 * @tc.author: lianhuix
663 */
664 HWTEST_F(DistributedDBRelationalSchemaObjectTest, TableCompareTest001, TestSize.Level1)
665 {
666 FieldInfo field1;
667 field1.SetFieldName("a");
668 FieldInfo field2;
669 field2.SetFieldName("b");
670 FieldInfo field3;
671 field3.SetFieldName("c");
672 FieldInfo field4;
673 field4.SetFieldName("d");
674
675 TableInfo table;
676 table.AddField(field2);
677 table.AddField(field3);
678
679 TableInfo inTable1;
680 inTable1.AddField(field1);
681 inTable1.AddField(field2);
682 inTable1.AddField(field3);
683 EXPECT_EQ(table.CompareWithTable(inTable1), -E_RELATIONAL_TABLE_COMPATIBLE_UPGRADE);
684
685 TableInfo inTable2;
686 inTable2.AddField(field1);
687 inTable2.AddField(field2);
688 inTable2.AddField(field4);
689 EXPECT_EQ(table.CompareWithTable(inTable2), -E_RELATIONAL_TABLE_INCOMPATIBLE);
690
691 TableInfo inTable3;
692 inTable3.AddField(field3);
693 inTable3.AddField(field2);
694 EXPECT_EQ(table.CompareWithTable(inTable3), -E_RELATIONAL_TABLE_EQUAL);
695 }
696 #endif