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