1 /* 2 * Copyright (c) 2023 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 "cloud/cloud_db_types.h" 19 #include "db_common.h" 20 #include "db_constant.h" 21 #include "distributeddb_data_generate_unit_test.h" 22 #include "distributeddb_tools_unit_test.h" 23 #include "relational_store_manager.h" 24 25 using namespace testing::ext; 26 using namespace DistributedDB; 27 using namespace DistributedDBUnitTest; 28 using namespace std; 29 30 namespace { 31 constexpr const char *DB_SUFFIX = ".db"; 32 constexpr const char *STORE_ID = "Relational_Store_ID"; 33 std::string g_testDir; 34 std::string g_dbDir; 35 std::string g_storePath; 36 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID); 37 RelationalStoreDelegate *g_delegate = nullptr; 38 39 class DistributedDBCloudInterfacesReferenceTest : public testing::Test { 40 public: 41 static void SetUpTestCase(void); 42 static void TearDownTestCase(void); 43 void SetUp(); 44 void TearDown(); 45 }; 46 SetUpTestCase(void)47 void DistributedDBCloudInterfacesReferenceTest::SetUpTestCase(void) 48 { 49 DistributedDBToolsUnitTest::TestDirInit(g_testDir); 50 LOGD("Test dir is %s", g_testDir.c_str()); 51 g_dbDir = g_testDir + "/"; 52 g_storePath = g_dbDir + STORE_ID + DB_SUFFIX; 53 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); 54 } 55 TearDownTestCase(void)56 void DistributedDBCloudInterfacesReferenceTest::TearDownTestCase(void) 57 { 58 } 59 SetUp(void)60 void DistributedDBCloudInterfacesReferenceTest::SetUp(void) 61 { 62 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 63 ASSERT_NE(db, nullptr); 64 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); 65 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 66 67 DBStatus status = g_mgr.OpenStore(g_storePath, STORE_ID, {}, g_delegate); 68 EXPECT_EQ(status, OK); 69 ASSERT_NE(g_delegate, nullptr); 70 } 71 TearDown(void)72 void DistributedDBCloudInterfacesReferenceTest::TearDown(void) 73 { 74 EXPECT_EQ(g_mgr.CloseStore(g_delegate), OK); 75 g_delegate = nullptr; 76 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); 77 } 78 79 /** 80 * @tc.name: SetReferenceTest001 81 * @tc.desc: Test empty args for set reference interface 82 * @tc.type: FUNC 83 * @tc.require: 84 * @tc.author: zhangshjie 85 */ 86 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest001, TestSize.Level0) 87 { 88 /** 89 * @tc.steps:step1. call SetReference with empty TableReferenceProperty 90 * @tc.expected: step1. Return INVALID_ARGS. 91 */ 92 EXPECT_EQ(g_delegate->SetReference({}), OK); 93 TableReferenceProperty tableReferenceProperty; 94 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 95 std::string sourceTableName = "sourceTable"; 96 std::string targetTableName = "targetTable"; 97 tableReferenceProperty.sourceTableName = sourceTableName; 98 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 99 tableReferenceProperty.sourceTableName = ""; 100 tableReferenceProperty.targetTableName = targetTableName; 101 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 102 tableReferenceProperty.targetTableName = ""; 103 std::map<std::string, std::string> columns; 104 columns["col1"] = "col2"; 105 tableReferenceProperty.columns = columns; 106 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 107 108 tableReferenceProperty.sourceTableName = sourceTableName; 109 tableReferenceProperty.targetTableName = targetTableName; 110 tableReferenceProperty.columns = {}; 111 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 112 tableReferenceProperty.sourceTableName = ""; 113 tableReferenceProperty.targetTableName = targetTableName; 114 tableReferenceProperty.columns = columns; 115 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 116 tableReferenceProperty.sourceTableName = sourceTableName; 117 tableReferenceProperty.targetTableName = ""; 118 tableReferenceProperty.columns = columns; 119 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 120 } 121 122 /** 123 * @tc.name: SetReferenceTest002 124 * @tc.desc: Test set two reference for same two tables 125 * @tc.type: FUNC 126 * @tc.require: 127 * @tc.author: zhangshjie 128 */ 129 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest002, TestSize.Level0) 130 { 131 /** 132 * @tc.steps:step1. call SetReference with two TableReferenceProperty which sourceTableName and targetTableName 133 * are both same 134 * @tc.expected: step1. Return INVALID_ARGS. 135 */ 136 TableReferenceProperty tableReferenceProperty; 137 std::string sourceTableName = "sourceTable"; 138 std::string targetTableName = "targetTable"; 139 tableReferenceProperty.sourceTableName = sourceTableName; 140 tableReferenceProperty.targetTableName = targetTableName; 141 std::map<std::string, std::string> columns; 142 columns["col1"] = "col2"; 143 tableReferenceProperty.columns = columns; 144 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty, tableReferenceProperty}), INVALID_ARGS); 145 146 TableReferenceProperty tableReferenceProperty2; 147 tableReferenceProperty2.sourceTableName = "sourceTableName1"; 148 tableReferenceProperty2.targetTableName = targetTableName; 149 tableReferenceProperty2.columns = columns; 150 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty, tableReferenceProperty2, tableReferenceProperty}), 151 INVALID_ARGS); 152 } 153 154 /** 155 * @tc.name: SetReferenceTest003 156 * @tc.desc: Test simple circular dependency 157 * @tc.type: FUNC 158 * @tc.require: 159 * @tc.author: zhangshjie 160 */ 161 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest003, TestSize.Level0) 162 { 163 /** 164 * @tc.steps:step1. call SetReference with circular dependency(A->B->A) 165 * @tc.expected: step1. Return INVALID_ARGS. 166 */ 167 TableReferenceProperty referenceAB; 168 referenceAB.sourceTableName = "ta"; 169 referenceAB.targetTableName = "tb"; 170 std::map<std::string, std::string> columns; 171 columns["col1"] = "col2"; 172 referenceAB.columns = columns; 173 174 TableReferenceProperty referenceBA; 175 referenceBA.sourceTableName = "tb"; 176 referenceBA.targetTableName = "ta"; 177 referenceBA.columns = columns; 178 EXPECT_EQ(g_delegate->SetReference({referenceAB, referenceBA}), INVALID_ARGS); 179 180 /** 181 * @tc.steps:step2. call SetReference with circular dependency(A->B->C->A) 182 * @tc.expected: step1. Return INVALID_ARGS. 183 */ 184 TableReferenceProperty referenceBC; 185 referenceBC.sourceTableName = "tb"; 186 referenceBC.targetTableName = "tc"; 187 referenceBC.columns = columns; 188 189 TableReferenceProperty referenceCA; 190 referenceCA.sourceTableName = "tc"; 191 referenceCA.targetTableName = "ta"; 192 referenceCA.columns = columns; 193 194 EXPECT_EQ(g_delegate->SetReference({referenceAB, referenceBC, referenceCA}), INVALID_ARGS); 195 EXPECT_EQ(g_delegate->SetReference({referenceCA, referenceAB, referenceBC}), INVALID_ARGS); 196 } 197 198 /** 199 * @tc.name: SetReferenceTest004 200 * @tc.desc: Test complicated circular dependency 201 * @tc.type: FUNC 202 * @tc.require: 203 * @tc.author: zhangshjie 204 */ 205 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest004, TestSize.Level0) 206 { 207 /** 208 * @tc.steps:step1. call SetReference with complicated dependency 209 * @tc.expected: step1. Return INVALID_ARGS. 210 */ 211 TableReferenceProperty referenceAB; 212 referenceAB.sourceTableName = "ta"; 213 referenceAB.targetTableName = "tb"; 214 std::map<std::string, std::string> columns; 215 columns["col1"] = "col2"; 216 referenceAB.columns = columns; 217 218 TableReferenceProperty referenceDE; 219 referenceDE.sourceTableName = "td"; 220 referenceDE.targetTableName = "te"; 221 referenceDE.columns = columns; 222 223 TableReferenceProperty referenceAC; 224 referenceAC.sourceTableName = "ta"; 225 referenceAC.targetTableName = "tc"; 226 referenceAC.columns = columns; 227 228 TableReferenceProperty referenceEF; 229 referenceEF.sourceTableName = "te"; 230 referenceEF.targetTableName = "tf"; 231 referenceEF.columns = columns; 232 233 TableReferenceProperty referenceBD; 234 referenceBD.sourceTableName = "tb"; 235 referenceBD.targetTableName = "td"; 236 referenceBD.columns = columns; 237 238 TableReferenceProperty referenceFC; 239 referenceFC.sourceTableName = "tf"; 240 referenceFC.targetTableName = "tc"; 241 referenceFC.columns = columns; 242 243 EXPECT_EQ(g_delegate->SetReference({referenceAB, referenceDE, referenceAC, referenceEF, referenceBD, 244 referenceFC}), DISTRIBUTED_SCHEMA_NOT_FOUND); 245 246 TableReferenceProperty referenceFA; 247 referenceFA.sourceTableName = "tf"; 248 referenceFA.targetTableName = "ta"; 249 referenceFA.columns = columns; 250 EXPECT_EQ(g_delegate->SetReference( 251 {referenceAB, referenceDE, referenceAC, referenceEF, referenceBD, referenceFC, referenceFA}), INVALID_ARGS); 252 } 253 254 /** 255 * @tc.name: SetReferenceTest005 256 * @tc.desc: Test table name is case insensitive 257 * @tc.type: FUNC 258 * @tc.require: 259 * @tc.author: zhangshjie 260 */ 261 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest005, TestSize.Level0) 262 { 263 /** 264 * @tc.steps:step1. call SetReference with two TableReferenceProperty which sourceTableName and targetTableName 265 * are both same 266 * @tc.expected: step1. Return INVALID_ARGS. 267 */ 268 TableReferenceProperty tableReferenceProperty; 269 std::string sourceTableName = "sourceTable"; 270 std::string targetTableName = "targetTable"; 271 tableReferenceProperty.sourceTableName = sourceTableName; 272 tableReferenceProperty.targetTableName = targetTableName; 273 std::map<std::string, std::string> columns; 274 columns["col1"] = "col2"; 275 tableReferenceProperty.columns = columns; 276 277 TableReferenceProperty tableReferenceProperty2; 278 tableReferenceProperty2.sourceTableName = "SourCeTable"; 279 tableReferenceProperty2.targetTableName = "TARGETTABLE"; 280 tableReferenceProperty2.columns = columns; 281 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty, tableReferenceProperty2}), INVALID_ARGS); 282 } 283 284 /** 285 * @tc.name: SetReferenceTest006 286 * @tc.desc: Test reference table doesn't create distributed table 287 * @tc.type: FUNC 288 * @tc.require: 289 * @tc.author: zhangshjie 290 */ 291 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest006, TestSize.Level0) 292 { 293 /** 294 * @tc.steps:step1. set reference with table doesn't exists 295 * @tc.expected: step1. Return DISTRIBUTED_SCHEMA_NOT_FOUND. 296 */ 297 TableReferenceProperty tableReferenceProperty; 298 std::string sourceTableName = "sourceTable"; 299 std::string targetTableName = "targetTable"; 300 tableReferenceProperty.sourceTableName = sourceTableName; 301 tableReferenceProperty.targetTableName = targetTableName; 302 std::map<std::string, std::string> columns; 303 columns["col1"] = "col2"; 304 tableReferenceProperty.columns = columns; 305 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), DISTRIBUTED_SCHEMA_NOT_FOUND); 306 307 /** 308 * @tc.steps:step2. set reference with table doesn't create distributed table 309 * @tc.expected: step2. Return DISTRIBUTED_SCHEMA_NOT_FOUND. 310 */ 311 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 312 ASSERT_NE(db, nullptr); 313 std::string sql = "create table " + sourceTableName + "(id int);create table " + targetTableName + "(id int);"; 314 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 315 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), DISTRIBUTED_SCHEMA_NOT_FOUND); 316 317 /** 318 * @tc.steps:step3. set reference with one table doesn't create distributed table 319 * @tc.expected: step3. Return DISTRIBUTED_SCHEMA_NOT_FOUND. 320 */ 321 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName), OK); 322 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), DISTRIBUTED_SCHEMA_NOT_FOUND); 323 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 324 } 325 326 /** 327 * @tc.name: SetReferenceTest007 328 * @tc.desc: Test reference table doesn't create cloud sync distributed table 329 * @tc.type: FUNC 330 * @tc.require: 331 * @tc.author: zhangshjie 332 */ 333 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest007, TestSize.Level0) 334 { 335 /** 336 * @tc.steps:step1. prepare table and distributed table in device mode 337 * @tc.expected: step1. ok. 338 */ 339 std::string sourceTableName = "sourceTable"; 340 std::string targetTableName = "targetTable"; 341 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 342 ASSERT_NE(db, nullptr); 343 std::string sql = "create table " + sourceTableName + "(id int);create table " + targetTableName + "(id int);"; 344 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 345 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName), OK); 346 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName), OK); 347 348 /** 349 * @tc.steps:step2. set reference with column doesn't exists 350 * @tc.expected: step2. Return INVALID_ARGS. 351 */ 352 TableReferenceProperty tableReferenceProperty; 353 tableReferenceProperty.sourceTableName = sourceTableName; 354 tableReferenceProperty.targetTableName = targetTableName; 355 std::map<std::string, std::string> columns; 356 columns["id"] = "id"; 357 tableReferenceProperty.columns = columns; 358 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), DISTRIBUTED_SCHEMA_NOT_FOUND); 359 360 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 361 } 362 363 /** 364 * @tc.name: SetReferenceTest008 365 * @tc.desc: Test reference col doesn't exists table 366 * @tc.type: FUNC 367 * @tc.require: 368 * @tc.author: zhangshjie 369 */ 370 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest008, TestSize.Level0) 371 { 372 /** 373 * @tc.steps:step1. prepare table and distributed table 374 * @tc.expected: step1. ok. 375 */ 376 std::string sourceTableName = "sourceTable"; 377 std::string targetTableName = "targetTable"; 378 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 379 ASSERT_NE(db, nullptr); 380 std::string sql = "create table " + sourceTableName + "(id int);create table " + targetTableName + "(id int);"; 381 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 382 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName, DistributedDB::CLOUD_COOPERATION), OK); 383 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName, DistributedDB::CLOUD_COOPERATION), OK); 384 385 /** 386 * @tc.steps:step2. set reference with column doesn't exists 387 * @tc.expected: step2. Return INVALID_ARGS. 388 */ 389 TableReferenceProperty tableReferenceProperty; 390 tableReferenceProperty.sourceTableName = sourceTableName; 391 tableReferenceProperty.targetTableName = targetTableName; 392 std::map<std::string, std::string> columns; 393 columns["col1"] = "col2"; 394 tableReferenceProperty.columns = columns; 395 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), INVALID_ARGS); 396 397 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 398 } 399 CheckResult(sqlite3 * db)400 void CheckResult(sqlite3 *db) 401 { 402 int count = 0; 403 std::function<int (sqlite3_stmt *)> bindCallback = [] (sqlite3_stmt *bindStmt) { 404 Key key; 405 DBCommon::StringToVector("relational_schema", key); 406 int errCode = SQLiteUtils::BindBlobToStatement(bindStmt, 1, key, false); 407 return errCode; 408 }; 409 std::string sql = "select value from " + DBConstant::RELATIONAL_PREFIX + "metadata where key = ?;"; 410 int errCode = RelationalTestUtils::ExecSql(db, sql, bindCallback, [&count] (sqlite3_stmt *stmt) { 411 std::string schemaStr; 412 std::vector<uint8_t> value; 413 EXPECT_EQ(SQLiteUtils::GetColumnBlobValue(stmt, 0, value), E_OK); 414 DBCommon::VectorToString(value, schemaStr); 415 RelationalSchemaObject obj; 416 EXPECT_EQ(obj.ParseFromSchemaString(schemaStr), E_OK); 417 count++; 418 return E_OK; 419 }); 420 EXPECT_EQ(errCode, E_OK); 421 EXPECT_EQ(count, 1); 422 } 423 NormalSetReferenceTest(bool multipleTable)424 void NormalSetReferenceTest(bool multipleTable) 425 { 426 /** 427 * @tc.steps:step1. prepare table and distributed table 428 * @tc.expected: step1. ok. 429 */ 430 std::string sourceTableName = "sourceTable"; 431 std::string targetTableName = "targetTable"; 432 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 433 ASSERT_NE(db, nullptr); 434 std::string sql = "create table " + sourceTableName + "(id int);create table " + targetTableName + "(id int);"; 435 if (multipleTable) { 436 sql += "create table t3(key int, value int);create table t4(key int, value int);"; 437 } 438 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 439 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName, DistributedDB::CLOUD_COOPERATION), OK); 440 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName, DistributedDB::CLOUD_COOPERATION), OK); 441 if (multipleTable) { 442 EXPECT_EQ(g_delegate->CreateDistributedTable("t3", DistributedDB::CLOUD_COOPERATION), OK); 443 EXPECT_EQ(g_delegate->CreateDistributedTable("t4", DistributedDB::CLOUD_COOPERATION), OK); 444 } 445 446 /** 447 * @tc.steps:step2. set reference 448 * @tc.expected: step2. Return OK. 449 */ 450 TableReferenceProperty tableReferenceProperty; 451 tableReferenceProperty.sourceTableName = sourceTableName; 452 tableReferenceProperty.targetTableName = targetTableName; 453 std::map<std::string, std::string> columns; 454 columns["id"] = "id"; 455 tableReferenceProperty.columns = columns; 456 std::vector<TableReferenceProperty> vec; 457 vec.emplace_back(tableReferenceProperty); 458 if (multipleTable) { 459 TableReferenceProperty reference; 460 reference.sourceTableName = "t3"; 461 reference.targetTableName = "t4"; 462 reference.columns["key"] = "key"; 463 reference.columns["value"] = "value"; 464 vec.emplace_back(reference); 465 } 466 EXPECT_EQ(g_delegate->SetReference(vec), OK); 467 468 /** 469 * @tc.steps:step3. parse schema in db 470 * @tc.expected: step3. Return OK. 471 */ 472 CheckResult(db); 473 474 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 475 } 476 477 /** 478 * @tc.name: SetReferenceTest009 479 * @tc.desc: Test normal function for SetReference interface with one table 480 * @tc.type: FUNC 481 * @tc.require: 482 * @tc.author: zhangshjie 483 */ 484 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest009, TestSize.Level0) 485 { 486 NormalSetReferenceTest(false); 487 } 488 489 /** 490 * @tc.name: SetReferenceTest010 491 * @tc.desc: Test normal function for SetReference interface with two table 492 * @tc.type: FUNC 493 * @tc.require: 494 * @tc.author: zhangshjie 495 */ 496 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest010, TestSize.Level0) 497 { 498 NormalSetReferenceTest(true); 499 } 500 ReferenceChangeTest(bool isTableEmpty)501 void ReferenceChangeTest(bool isTableEmpty) 502 { 503 /** 504 * @tc.steps:step1. prepare table and distributed table 505 * @tc.expected: step1. ok. 506 */ 507 std::string sourceTableName = "sourceTable"; 508 std::string targetTableName = "targetTable"; 509 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 510 ASSERT_NE(db, nullptr); 511 std::string sql = "create table " + sourceTableName + "(id int, value text);create table " + 512 targetTableName + "(id int, value text);create table t3 (id int, value text);"; 513 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 514 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName, DistributedDB::CLOUD_COOPERATION), OK); 515 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName, DistributedDB::CLOUD_COOPERATION), OK); 516 EXPECT_EQ(g_delegate->CreateDistributedTable("t3", DistributedDB::CLOUD_COOPERATION), OK); 517 518 if (!isTableEmpty) { 519 sql = "insert into " + sourceTableName + " values(1, 'zhangsan');"; 520 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 521 } 522 523 /** 524 * @tc.steps:step2. set reference 525 * @tc.expected: step2. Return OK or PROPERTY_CHANGED. 526 */ 527 TableReferenceProperty tableReferenceProperty; 528 tableReferenceProperty.sourceTableName = sourceTableName; 529 tableReferenceProperty.targetTableName = targetTableName; 530 std::map<std::string, std::string> columns; 531 columns["id"] = "id"; 532 tableReferenceProperty.columns = columns; 533 if (isTableEmpty) { 534 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 535 } else { 536 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 537 } 538 539 /** 540 * @tc.steps:step3. set reference again with different table reference 541 * @tc.expected: step3. Return OK or PROPERTY_CHANGED. 542 */ 543 tableReferenceProperty.targetTableName = "t3"; 544 if (isTableEmpty) { 545 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 546 } else { 547 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 548 } 549 550 /** 551 * @tc.steps:step4. set reference again with different column reference 552 * @tc.expected: step4. Return OK or PROPERTY_CHANGED. 553 */ 554 columns["id"] = "value"; 555 tableReferenceProperty.columns = columns; 556 if (isTableEmpty) { 557 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 558 } else { 559 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 560 } 561 562 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 563 } 564 565 /** 566 * @tc.name: SetReferenceTest011 567 * @tc.desc: Test table reference change when table is empty 568 * @tc.type: FUNC 569 * @tc.require: 570 * @tc.author: zhangshjie 571 */ 572 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest011, TestSize.Level0) 573 { 574 ReferenceChangeTest(true); 575 } 576 577 /** 578 * @tc.name: SetReferenceTest012 579 * @tc.desc: Test table reference change when table is not empty 580 * @tc.type: FUNC 581 * @tc.require: 582 * @tc.author: zhangshjie 583 */ 584 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest012, TestSize.Level0) 585 { 586 ReferenceChangeTest(false); 587 } 588 589 /** 590 * @tc.name: SetReferenceTest013 591 * @tc.desc: Test table set reference is case insensitive 592 * @tc.type: FUNC 593 * @tc.require: 594 * @tc.author: zhangshjie 595 */ 596 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest013, TestSize.Level0) 597 { 598 /** 599 * @tc.steps:step1. prepare table and distributed table 600 * @tc.expected: step1. ok. 601 */ 602 std::string sourceTableName = "sourceTable"; 603 std::string targetTableName = "targetTable"; 604 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 605 ASSERT_NE(db, nullptr); 606 std::string sql = "create table " + sourceTableName + "(id int, value text);create table " + 607 targetTableName + "(id int, value text);"; 608 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 609 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName, DistributedDB::CLOUD_COOPERATION), OK); 610 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName, DistributedDB::CLOUD_COOPERATION), OK); 611 sql = "insert into " + sourceTableName + " values(1, 'zhangsan');"; 612 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 613 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 614 615 /** 616 * @tc.steps:step2. set reference 617 * @tc.expected: step2. Return PROPERTY_CHANGED. 618 */ 619 TableReferenceProperty tableReferenceProperty; 620 tableReferenceProperty.sourceTableName = sourceTableName; 621 tableReferenceProperty.targetTableName = targetTableName; 622 std::map<std::string, std::string> columns; 623 columns["id"] = "id"; 624 tableReferenceProperty.columns = columns; 625 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 626 627 /** 628 * @tc.steps:step3. set reference with same table name, but case different 629 * @tc.expected: step3. Return OK. 630 */ 631 tableReferenceProperty.sourceTableName = sourceTableName; 632 tableReferenceProperty.targetTableName = "Targettable"; 633 tableReferenceProperty.columns = columns; 634 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 635 636 /** 637 * @tc.steps:step4. set reference with same column name, but case different(value different) 638 * @tc.expected: step4. Return OK. 639 */ 640 tableReferenceProperty.sourceTableName = sourceTableName; 641 tableReferenceProperty.targetTableName = targetTableName; 642 columns["id"] = "ID"; 643 tableReferenceProperty.columns = columns; 644 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 645 646 /** 647 * @tc.steps:step5. set reference with same column name, but case different(key different) 648 * @tc.expected: step5. Return OK. 649 */ 650 std::map<std::string, std::string> columns2; 651 columns2["ID"] = "ID"; 652 tableReferenceProperty.columns = columns2; 653 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 654 655 /** 656 * @tc.steps:step6. set reference with column size not equal 657 * @tc.expected: step6. Return PROPERTY_CHANGED. 658 */ 659 columns2["ID"] = "ID"; 660 columns2["value"] = "value"; 661 tableReferenceProperty.columns = columns2; 662 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 663 } 664 665 /** 666 * @tc.name: SetReferenceTest014 667 * @tc.desc: Test table set reference with multi columns 668 * @tc.type: FUNC 669 * @tc.require: 670 * @tc.author: zhangshjie 671 */ 672 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest014, TestSize.Level0) 673 { 674 /** 675 * @tc.steps:step1. prepare table and distributed table 676 * @tc.expected: step1. ok. 677 */ 678 std::string sourceTableName = "sourceTable"; 679 std::string targetTableName = "targetTable"; 680 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 681 ASSERT_NE(db, nullptr); 682 std::string sql = "create table " + sourceTableName + "(id int, value text, name text);create table " + 683 targetTableName + "(id int, value text, name text);create table t3 (id int, value text);"; 684 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 685 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName, DistributedDB::CLOUD_COOPERATION), OK); 686 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName, DistributedDB::CLOUD_COOPERATION), OK); 687 EXPECT_EQ(g_delegate->CreateDistributedTable("t3", DistributedDB::CLOUD_COOPERATION), OK); 688 sql = "insert into " + sourceTableName + " values(1, 'zhangsan', 'test');insert into " + targetTableName + 689 " values(2, 'lisi', 'test2');insert into t3 values(3, 'wangwu');"; 690 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 691 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 692 693 /** 694 * @tc.steps:step2. set reference 695 * @tc.expected: step2. Return PROPERTY_CHANGED. 696 */ 697 TableReferenceProperty tableReferenceProperty; 698 tableReferenceProperty.sourceTableName = sourceTableName; 699 tableReferenceProperty.targetTableName = targetTableName; 700 std::map<std::string, std::string> columns; 701 columns["id"] = "id"; 702 columns["value"] = "value"; 703 tableReferenceProperty.columns = columns; 704 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 705 706 /** 707 * @tc.steps:step3. set reference with multi columns 708 * @tc.expected: step3. Return PROPERTY_CHANGED. 709 */ 710 std::map<std::string, std::string> columns2; 711 columns2["id"] = "id"; 712 columns2["name"] = "name"; 713 tableReferenceProperty.columns = columns2; 714 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 715 716 /** 717 * @tc.steps:step4. set reference with multi reference property 718 * @tc.expected: step4. Return PROPERTY_CHANGED. 719 */ 720 TableReferenceProperty tableReferenceProperty2; 721 tableReferenceProperty2.sourceTableName = sourceTableName; 722 tableReferenceProperty2.targetTableName = "t3"; 723 std::map<std::string, std::string> columns3; 724 columns3["id"] = "id"; 725 tableReferenceProperty2.columns = columns3; 726 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty, tableReferenceProperty2}), PROPERTY_CHANGED); 727 728 /** 729 * @tc.steps:step5. set reference with one reference property 730 * @tc.expected: step5. Return PROPERTY_CHANGED. 731 */ 732 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 733 } 734 SetCloudSchema(RelationalStoreDelegate * delegate)735 void SetCloudSchema(RelationalStoreDelegate *delegate) 736 { 737 TableSchema tableSchema; 738 Field field1 = { "id", TYPE_INDEX<int64_t>, true, false }; 739 Field field2 = { "value", TYPE_INDEX<std::string>, false, true }; 740 Field field3 = { "name", TYPE_INDEX<std::string>, false, true }; 741 742 tableSchema = { "sourceTable", "src_shared", { field1, field2, field3} }; 743 DataBaseSchema dbSchema; 744 dbSchema.tables.push_back(tableSchema); 745 tableSchema = { "targetTable", "dst_shared", { field1, field2, field3} }; 746 dbSchema.tables.push_back(tableSchema); 747 748 EXPECT_EQ(delegate->SetCloudDbSchema(dbSchema), OK); 749 } 750 751 /** 752 * @tc.name: SetReferenceTest015 753 * @tc.desc: Test reference change of shared table 754 * @tc.type: FUNC 755 * @tc.require: 756 * @tc.author: zhangshjie 757 */ 758 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest015, TestSize.Level0) 759 { 760 /** 761 * @tc.steps:step1. prepare table and distributed table 762 * @tc.expected: step1. ok. 763 */ 764 std::string sourceTableName = "sourceTable"; 765 std::string targetTableName = "targetTable"; 766 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 767 ASSERT_NE(db, nullptr); 768 std::string sql = "create table " + sourceTableName + "(id int, value text, name text);create table " + 769 targetTableName + "(id int, value text, name text);"; 770 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 771 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName, DistributedDB::CLOUD_COOPERATION), OK); 772 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName, DistributedDB::CLOUD_COOPERATION), OK); 773 TableReferenceProperty tableReferenceProperty; 774 tableReferenceProperty.sourceTableName = sourceTableName; 775 tableReferenceProperty.targetTableName = targetTableName; 776 std::map<std::string, std::string> columns; 777 columns["id"] = "id"; 778 columns["value"] = "value"; 779 tableReferenceProperty.columns = columns; 780 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 781 782 /** 783 * @tc.steps:step2. set cloud db schema, insert data into shared table 784 * @tc.expected: step2. ok. 785 */ 786 SetCloudSchema(g_delegate); 787 sql = "insert into src_shared values(1, 'zhangsan', 'test', 'aa', 'bb');"; 788 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 789 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 790 791 /** 792 * @tc.steps:step3. clear reference 793 * @tc.expected: step3. return PROPERTY_CHANGED. 794 */ 795 EXPECT_EQ(g_delegate->SetReference({}), PROPERTY_CHANGED); 796 } 797 798 /** 799 * @tc.name: SetReferenceTest016 800 * @tc.desc: Test set reference after some table was dropped 801 * @tc.type: FUNC 802 * @tc.require: 803 * @tc.author: zhangshjie 804 */ 805 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest016, TestSize.Level0) 806 { 807 /** 808 * @tc.steps:step1. prepare table and distributed table, then set reference t1->t2 809 * @tc.expected: step1. return ok. 810 */ 811 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 812 ASSERT_NE(db, nullptr); 813 std::string sql = "create table t1(id int, value text);create table t2(id int, value text);" \ 814 "create table t3(id int, value text);"; 815 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 816 EXPECT_EQ(g_delegate->CreateDistributedTable("t1", DistributedDB::CLOUD_COOPERATION), OK); 817 EXPECT_EQ(g_delegate->CreateDistributedTable("t2", DistributedDB::CLOUD_COOPERATION), OK); 818 EXPECT_EQ(g_delegate->CreateDistributedTable("t3", DistributedDB::CLOUD_COOPERATION), OK); 819 TableReferenceProperty tableReferenceProperty; 820 tableReferenceProperty.sourceTableName = "t1"; 821 tableReferenceProperty.targetTableName = "t2"; 822 std::map<std::string, std::string> columns; 823 columns["id"] = "id"; 824 columns["value"] = "value"; 825 tableReferenceProperty.columns = columns; 826 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 827 828 /** 829 * @tc.steps:step2. drop table t1, then reopen store 830 * @tc.expected: step2. return ok. 831 */ 832 sql = "drop table t1;"; 833 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 834 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 835 EXPECT_EQ(g_mgr.CloseStore(g_delegate), OK); 836 g_delegate = nullptr; 837 EXPECT_EQ(g_mgr.OpenStore(g_storePath, STORE_ID, {}, g_delegate), OK); 838 ASSERT_NE(g_delegate, nullptr); 839 840 /** 841 * @tc.steps:step3. set reference t2->t1 842 * @tc.expected: step3. return ok. 843 */ 844 tableReferenceProperty.sourceTableName = "t2"; 845 tableReferenceProperty.targetTableName = "t3"; 846 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), OK); 847 } 848 849 /** 850 * @tc.name: SetReferenceTest017 851 * @tc.desc: Test log table is case insensitive in set reference interface 852 * @tc.type: FUNC 853 * @tc.require: 854 * @tc.author: zhangshjie 855 */ 856 HWTEST_F(DistributedDBCloudInterfacesReferenceTest, SetReferenceTest017, TestSize.Level1) 857 { 858 /** 859 * @tc.steps:step1. prepare table and distributed table 860 * @tc.expected: step1. ok. 861 */ 862 std::string sourceTableName = "sourceTable"; 863 std::string targetTableName = "targetTable"; 864 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 865 ASSERT_NE(db, nullptr); 866 std::string sql = "create table " + sourceTableName + "(id int, value text);create table " + 867 targetTableName + "(id int, value text);"; 868 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 869 EXPECT_EQ(g_delegate->CreateDistributedTable(sourceTableName, DistributedDB::CLOUD_COOPERATION), OK); 870 EXPECT_EQ(g_delegate->CreateDistributedTable(targetTableName, DistributedDB::CLOUD_COOPERATION), OK); 871 sql = "insert into " + sourceTableName + " values(1, 'zhangsan');"; 872 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); 873 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 874 875 /** 876 * @tc.steps:step2. set reference with same table name, but case mismatch 877 * @tc.expected: step2. Return PROPERTY_CHANGED. 878 */ 879 TableReferenceProperty tableReferenceProperty; 880 tableReferenceProperty.sourceTableName = "SourceTable"; 881 tableReferenceProperty.targetTableName = targetTableName; 882 std::map<std::string, std::string> columns; 883 columns["id"] = "id"; 884 tableReferenceProperty.columns = columns; 885 EXPECT_EQ(g_delegate->SetReference({tableReferenceProperty}), PROPERTY_CHANGED); 886 } 887 } 888