• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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