• 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 #include <gtest/gtest.h>
17 #include <queue>
18 #include <random>
19 
20 #include "db_common.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "log_print.h"
24 #include "platform_specific.h"
25 #include "relational_store_manager.h"
26 #include "relational_store_sqlite_ext.h"
27 #include "relational_virtual_device.h"
28 #include "runtime_config.h"
29 #include "virtual_relational_ver_sync_db_interface.h"
30 
31 using namespace testing::ext;
32 using namespace DistributedDB;
33 using namespace DistributedDBUnitTest;
34 using namespace std;
35 
36 namespace {
37 constexpr const char* DB_SUFFIX = ".db";
38 constexpr const char* STORE_ID = "Relational_Store_ID";
39 std::string g_testDir;
40 std::string g_dbDir;
41 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
42 
43 const std::string DEVICE_A = "real_device";
44 const std::string DEVICE_B = "deviceB";
45 VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
46 RelationalVirtualDevice *g_deviceB = nullptr;
47 
48 const std::string NORMAL_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS sync_data(" \
49     "key         BLOB NOT NULL UNIQUE," \
50     "value       BLOB," \
51     "timestamp   INT  NOT NULL," \
52     "flag        INT  NOT NULL," \
53     "device      BLOB," \
54     "ori_device  BLOB," \
55     "hash_key    BLOB PRIMARY KEY NOT NULL," \
56     "w_timestamp INT," \
57     "UNIQUE(device, ori_device));" \
58     "CREATE INDEX key_index ON sync_data(key, flag);";
59 
60 const std::string NORMAL_CREATE_NO_UNIQUE = "CREATE TABLE IF NOT EXISTS sync_data(" \
61     "key         BLOB NOT NULL," \
62     "value       BLOB," \
63     "timestamp   INT  NOT NULL," \
64     "flag        INT  NOT NULL," \
65     "device      BLOB," \
66     "ori_device  BLOB," \
67     "hash_key    BLOB PRIMARY KEY NOT NULL," \
68     "w_timestamp INT);" \
69     "CREATE INDEX key_index ON sync_data(key, flag);";
70 
71 const std::string SIMPLE_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS t1(a INT, b TEXT)";
72 
73 const std::string CREATE_TABLE_SQL_NO_PRIMARY_KEY = "CREATE TABLE IF NOT EXISTS sync_data(" \
74     "key         BLOB NOT NULL UNIQUE," \
75     "value       BLOB," \
76     "timestamp   INT  NOT NULL," \
77     "flag        INT  NOT NULL," \
78     "device      BLOB," \
79     "ori_device  BLOB," \
80     "hash_key    BLOB NOT NULL," \
81     "w_timestamp INT," \
82     "UNIQUE(device, ori_device));" \
83     "CREATE INDEX key_index ON sync_data (key, flag);";
84 
85 const std::string CREATE_TABLE_SQL_NO_PRIMARY_KEY_NO_UNIQUE = "CREATE TABLE IF NOT EXISTS sync_data(" \
86     "key         BLOB NOT NULL," \
87     "value       BLOB," \
88     "timestamp   INT  NOT NULL," \
89     "flag        INT  NOT NULL," \
90     "device      BLOB," \
91     "ori_device  BLOB," \
92     "hash_key    BLOB NOT NULL," \
93     "w_timestamp INT);" \
94     "CREATE INDEX key_index ON sync_data (key, flag);";
95 
96 const std::string UNSUPPORTED_FIELD_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test('$.ID' INT, val BLOB);";
97 
98 const std::string COMPOSITE_PRIMARY_KEY_TABLE_SQL = R"(CREATE TABLE workers (
99         worker_id INTEGER,
100         last_name VARCHAR NOT NULL,
101         first_name VARCHAR,
102         join_date DATE,
103         PRIMARY KEY (last_name, first_name)
104     );)";
105 
106 const std::string INSERT_SYNC_DATA_SQL = "INSERT OR REPLACE INTO sync_data (key, timestamp, flag, hash_key) "
107     "VALUES('KEY', 123456789, 1, 'HASH_KEY');";
108 
109 const std::string INVALID_TABLE_FIELD_SQL = "create table if not exists t1 ('1 = 1; --' int primary key, b blob)";
110 
111 
PrepareVirtualDeviceEnv(const std::string & tableName,const std::string & dbPath,const std::vector<RelationalVirtualDevice * > & remoteDeviceVec)112 void PrepareVirtualDeviceEnv(const std::string &tableName, const std::string &dbPath,
113     const std::vector<RelationalVirtualDevice *> &remoteDeviceVec)
114 {
115     sqlite3 *db = RelationalTestUtils::CreateDataBase(dbPath);
116     ASSERT_NE(db, nullptr);
117     TableInfo tableInfo;
118     SQLiteUtils::AnalysisSchema(db, tableName, tableInfo);
119     for (const auto &dev : remoteDeviceVec) {
120         std::vector<FieldInfo> fieldInfoList = tableInfo.GetFieldInfos();
121         dev->SetLocalFieldInfo(fieldInfoList);
122         dev->SetTableInfo(tableInfo);
123     }
124     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
125 }
126 
127 class DistributedDBInterfacesRelationalTest : public testing::Test {
128 public:
129     static void SetUpTestCase(void);
130     static void TearDownTestCase(void);
131     void SetUp();
132     void TearDown();
133 };
134 
SetUpTestCase(void)135 void DistributedDBInterfacesRelationalTest::SetUpTestCase(void)
136 {
137     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
138     LOGD("Test dir is %s", g_testDir.c_str());
139     g_dbDir = g_testDir + "/";
140     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
141 
142     g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
143     ASSERT_TRUE(g_communicatorAggregator != nullptr);
144     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
145 }
146 
TearDownTestCase(void)147 void DistributedDBInterfacesRelationalTest::TearDownTestCase(void)
148 {
149 }
150 
SetUp(void)151 void DistributedDBInterfacesRelationalTest::SetUp(void)
152 {
153     DistributedDBToolsUnitTest::PrintTestCaseInfo();
154 
155     g_deviceB = new (std::nothrow) RelationalVirtualDevice(DEVICE_B);
156     ASSERT_TRUE(g_deviceB != nullptr);
157     auto *syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
158     ASSERT_TRUE(syncInterfaceB != nullptr);
159     ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
160     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
161         const std::string &deviceId, uint8_t flag) -> bool {
162         return true;
163     };
164     EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
165 }
166 
TearDown(void)167 void DistributedDBInterfacesRelationalTest::TearDown(void)
168 {
169     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
170     if (g_deviceB != nullptr) {
171         delete g_deviceB;
172         g_deviceB = nullptr;
173     }
174     PermissionCheckCallbackV2 nullCallback;
175     EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(nullCallback), OK);
176     if (g_communicatorAggregator != nullptr) {
177         g_communicatorAggregator->RegOnDispatch(nullptr);
178     }
179 }
180 
NoramlCreateDistributedTableTest(TableSyncType tableSyncType)181 void NoramlCreateDistributedTableTest(TableSyncType tableSyncType)
182 {
183     /**
184      * @tc.steps:step1. Prepare db file
185      * @tc.expected: step1. Return OK.
186      */
187     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
188     ASSERT_NE(db, nullptr);
189     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
190     if (tableSyncType == DistributedDB::DEVICE_COOPERATION) {
191         EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
192     } else {
193         EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK);
194     }
195 
196     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A");
197     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
198 
199     /**
200      * @tc.steps:step2. open relational store, create distributed table, close store
201      * @tc.expected: step2. Return OK.
202      */
203     RelationalStoreDelegate *delegate = nullptr;
204     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
205     EXPECT_EQ(status, OK);
206     ASSERT_NE(delegate, nullptr);
207 
208     status = delegate->CreateDistributedTable("sync_data", tableSyncType);
209     EXPECT_EQ(status, OK);
210 
211     // test create same table again
212     status = delegate->CreateDistributedTable("sync_data", tableSyncType);
213     EXPECT_EQ(status, OK);
214 
215     status = g_mgr.CloseStore(delegate);
216     EXPECT_EQ(status, OK);
217 
218     /**
219      * @tc.steps:step3. drop sync_data table
220      * @tc.expected: step3. Return OK.
221      */
222     db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
223     ASSERT_NE(db, nullptr);
224     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "drop table sync_data;"), SQLITE_OK);
225     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
226 
227     /**
228      * @tc.steps:step4. open again, check auxiliary should be delete
229      * @tc.expected: step4. Return OK.
230      */
231     delegate = nullptr;
232     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
233     EXPECT_EQ(status, OK);
234     ASSERT_NE(delegate, nullptr);
235     status = g_mgr.CloseStore(delegate);
236     EXPECT_EQ(status, OK);
237 }
238 
239 /**
240   * @tc.name: RelationalStoreTest001
241   * @tc.desc: Test open store and create distributed db with DEVICE_COOPERATION type
242   * @tc.type: FUNC
243   * @tc.require: AR000GK58F
244   * @tc.author: lianhuix
245   */
246 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest001, TestSize.Level1)
247 {
248     NoramlCreateDistributedTableTest(DistributedDB::DEVICE_COOPERATION);
249 }
250 
251 /**
252   * @tc.name: RelationalStoreTest001
253   * @tc.desc: Test open store and create distributed db with CLOUD_COOPERATION type
254   * @tc.type: FUNC
255   * @tc.require: AR000GK58F
256   * @tc.author: lianhuix
257   */
258 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest001_1, TestSize.Level1)
259 {
260     NoramlCreateDistributedTableTest(DistributedDB::CLOUD_COOPERATION);
261 }
262 
263 /**
264   * @tc.name: RelationalStoreTest002
265   * @tc.desc: Test open store with invalid path or store ID
266   * @tc.type: FUNC
267   * @tc.require: AR000GK58F
268   * @tc.author: lianhuix
269   */
270 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest002, TestSize.Level1)
271 {
272     /**
273      * @tc.steps:step1. Prepare db file
274      * @tc.expected: step1. Return OK.
275      */
276     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
277     ASSERT_NE(db, nullptr);
278     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
279     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
280     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
281 
282     /**
283      * @tc.steps:step2. Test open store with invalid path or store ID
284      * @tc.expected: step2. open store failed.
285      */
286     RelationalStoreDelegate *delegate = nullptr;
287 
288     // test open store with path not exist
289     DBStatus status = g_mgr.OpenStore(g_dbDir + "tmp/" + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
290     EXPECT_NE(status, OK);
291     ASSERT_EQ(delegate, nullptr);
292 
293     // test open store with empty store_id
294     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, {}, {}, delegate);
295     EXPECT_NE(status, OK);
296     ASSERT_EQ(delegate, nullptr);
297 
298     // test open store with path has invalid character
299     status = g_mgr.OpenStore(g_dbDir + "t&m$p/" + STORE_ID + DB_SUFFIX, {}, {}, delegate);
300     EXPECT_NE(status, OK);
301     ASSERT_EQ(delegate, nullptr);
302 
303     // test open store with store_id has invalid character
304     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, "Relation@al_S$tore_ID", {}, delegate);
305     EXPECT_NE(status, OK);
306     ASSERT_EQ(delegate, nullptr);
307 
308     // test open store with store_id length over MAX_STORE_ID_LENGTH
309     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX,
310         std::string(DBConstant::MAX_STORE_ID_LENGTH + 1, 'a'), {}, delegate);
311     EXPECT_NE(status, OK);
312     ASSERT_EQ(delegate, nullptr);
313 }
314 
315 /**
316   * @tc.name: RelationalStoreTest003
317   * @tc.desc: Test open store with journal_mode is not WAL
318   * @tc.type: FUNC
319   * @tc.require: AR000GK58F
320   * @tc.author: lianhuix
321   */
322 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest003, TestSize.Level1)
323 {
324     /**
325      * @tc.steps:step1. Prepare db file with string is not WAL
326      * @tc.expected: step1. Return OK.
327      */
328     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
329     ASSERT_NE(db, nullptr);
330     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=PERSIST;"), SQLITE_OK);
331     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
332     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
333 
334     /**
335      * @tc.steps:step2. Test open store
336      * @tc.expected: step2. Open store failed.
337      */
338     RelationalStoreDelegate *delegate = nullptr;
339 
340     // test open store with journal mode is not WAL
341     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
342     EXPECT_NE(status, OK);
343     ASSERT_EQ(delegate, nullptr);
344 }
345 
CreateDistributedTableOverLimitTest(TableSyncType tableSyncTpe)346 void CreateDistributedTableOverLimitTest(TableSyncType tableSyncTpe)
347 {
348     /**
349      * @tc.steps:step1. Prepare db file with multiple tables
350      * @tc.expected: step1. Return OK.
351      */
352     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
353     ASSERT_NE(db, nullptr);
354     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
355     const int tableCount = DBConstant::MAX_DISTRIBUTED_TABLE_COUNT + 10; // 10: additional size for test abnormal scene
356     for (int i=0; i<tableCount; i++) {
357         std::string sql = "CREATE TABLE TEST_" + std::to_string(i) + "(id INT PRIMARY KEY, value TEXT);";
358         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK);
359     }
360     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
361 
362     RelationalStoreDelegate *delegate = nullptr;
363 
364     /**
365      * @tc.steps:step2. Open store and create multiple distributed table
366      * @tc.expected: step2. The tables in limited quantity were created successfully, the others failed.
367      */
368     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
369     EXPECT_EQ(status, OK);
370     ASSERT_NE(delegate, nullptr);
371 
372     for (int i=0; i<tableCount; i++) {
373         if (i < DBConstant::MAX_DISTRIBUTED_TABLE_COUNT) {
374             EXPECT_EQ(delegate->CreateDistributedTable("TEST_" + std::to_string(i), tableSyncTpe), OK);
375         } else {
376             EXPECT_NE(delegate->CreateDistributedTable("TEST_" + std::to_string(i), tableSyncTpe), OK);
377         }
378     }
379 
380     /**
381      * @tc.steps:step3. Close store
382      * @tc.expected: step3. Return OK.
383      */
384     status = g_mgr.CloseStore(delegate);
385     EXPECT_EQ(status, OK);
386 }
387 
388 /**
389   * @tc.name: RelationalStoreTest004
390   * @tc.desc: Test create distributed table with over limit for DEVICE_COOPERATION type
391   * @tc.type: FUNC
392   * @tc.require: AR000GK58F
393   * @tc.author: lianhuix
394   */
395 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest004, TestSize.Level1)
396 {
397     CreateDistributedTableOverLimitTest(DistributedDB::DEVICE_COOPERATION);
398 }
399 
400 /**
401   * @tc.name: RelationalStoreTest004
402   * @tc.desc: Test create distributed table with over limit for CLOUD_COOPERATION type
403   * @tc.type: FUNC
404   * @tc.require:
405   * @tc.author: zhangshijie
406   */
407 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest004_1, TestSize.Level1)
408 {
409     CreateDistributedTableOverLimitTest(DistributedDB::CLOUD_COOPERATION);
410 }
411 
CreateDistributedTableInvalidArgsTest(TableSyncType tableSyncType)412 void CreateDistributedTableInvalidArgsTest(TableSyncType tableSyncType)
413 {
414     /**
415      * @tc.steps:step1. Prepare db file
416      * @tc.expected: step1. Return OK.
417      */
418     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
419     ASSERT_NE(db, nullptr);
420     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
421     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
422 
423     /**
424      * @tc.steps:step2. Open store
425      * @tc.expected: step2. return OK
426      */
427     RelationalStoreDelegate *delegate = nullptr;
428     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
429     EXPECT_EQ(status, OK);
430     ASSERT_NE(delegate, nullptr);
431 
432     /**
433      * @tc.steps:step3. Create distributed table with invalid table name
434      * @tc.expected: step3. Create distributed table failed.
435      */
436     EXPECT_NE(delegate->CreateDistributedTable(DBConstant::SYSTEM_TABLE_PREFIX + "_tmp", tableSyncType), OK);
437 
438     EXPECT_EQ(delegate->CreateDistributedTable("Handle-J@^.", tableSyncType), INVALID_ARGS);
439     EXPECT_EQ(delegate->CreateDistributedTable("sync_data",
440         static_cast<TableSyncType>(DistributedDB::DEVICE_COOPERATION - 1)), INVALID_ARGS);
441     EXPECT_EQ(delegate->CreateDistributedTable("sync_data",
442         static_cast<TableSyncType>(DistributedDB::CLOUD_COOPERATION + 1)), INVALID_ARGS);
443 
444     EXPECT_EQ(RelationalTestUtils::ExecSql(db, INVALID_TABLE_FIELD_SQL), SQLITE_OK);
445     EXPECT_EQ(delegate->CreateDistributedTable("t1", tableSyncType), NOT_SUPPORT);
446 
447     /**
448      * @tc.steps:step4. Create distributed table temp table or not exist table
449      * @tc.expected: step4. Create distributed table failed.
450      */
451     EXPECT_EQ(delegate->CreateDistributedTable("child", tableSyncType), NOT_FOUND);
452     std::string tempTableSql = "CREATE TEMP TABLE child(x, y, z)";
453     EXPECT_EQ(RelationalTestUtils::ExecSql(db, tempTableSql), SQLITE_OK);
454     EXPECT_EQ(delegate->CreateDistributedTable("child", tableSyncType), NOT_FOUND);
455 
456     /**
457      * @tc.steps:step5. Close store
458      * @tc.expected: step5. Return OK.
459      */
460     status = g_mgr.CloseStore(delegate);
461     EXPECT_EQ(status, OK);
462     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
463 }
464 
465 /**
466   * @tc.name: RelationalStoreTest005
467   * @tc.desc: Test create distributed table with invalid table name or invalid table sync type
468   * @tc.type: FUNC
469   * @tc.require: AR000GK58F
470   * @tc.author: lianhuix
471   */
472 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest005, TestSize.Level1)
473 {
474     CreateDistributedTableInvalidArgsTest(DistributedDB::DEVICE_COOPERATION);
475 }
476 
477 /**
478   * @tc.name: RelationalStoreTest005
479   * @tc.desc: Test create distributed table with invalid table name or invalid table sync type
480   * @tc.type: FUNC
481   * @tc.require:
482   * @tc.author:
483   */
484 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest005_1, TestSize.Level1)
485 {
486     CreateDistributedTableInvalidArgsTest(DistributedDB::CLOUD_COOPERATION);
487 }
488 
CreateDistributedTableNonPrimaryKeyTest(TableSyncType tableSyncType)489 void CreateDistributedTableNonPrimaryKeyTest(TableSyncType tableSyncType)
490 {
491     /**
492      * @tc.steps:step1. Prepare db file
493      * @tc.expected: step1. Return OK.
494      */
495     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
496     ASSERT_NE(db, nullptr);
497     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
498     if (tableSyncType == DistributedDB::DEVICE_COOPERATION) {
499         EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_TABLE_SQL_NO_PRIMARY_KEY), SQLITE_OK);
500     } else {
501         EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_TABLE_SQL_NO_PRIMARY_KEY_NO_UNIQUE), SQLITE_OK);
502     }
503     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
504 
505     /**
506      * @tc.steps:step2. Open store
507      * @tc.expected: step2. return OK
508      */
509     RelationalStoreDelegate *delegate = nullptr;
510     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
511     EXPECT_EQ(status, OK);
512     ASSERT_NE(delegate, nullptr);
513 
514     /**
515      * @tc.steps:step3. Create distributed table with valid table name
516      * @tc.expected: step3. Create distributed table success.
517      */
518     EXPECT_EQ(delegate->CreateDistributedTable("sync_data", tableSyncType), OK);
519 
520     /**
521      * @tc.steps:step4. Close store
522      * @tc.expected: step4. Return OK.
523      */
524     status = g_mgr.CloseStore(delegate);
525     EXPECT_EQ(status, OK);
526     delegate = nullptr;
527 
528     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
529     EXPECT_EQ(status, OK);
530     ASSERT_NE(delegate, nullptr);
531 
532     status = g_mgr.CloseStore(delegate);
533     EXPECT_EQ(status, OK);
534 }
535 
536 /**
537   * @tc.name: RelationalStoreTest006
538   * @tc.desc: Test create distributed table with non primary key schema
539   * @tc.type: FUNC
540   * @tc.require: AR000GK58F
541   * @tc.author: lianhuix
542   */
543 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest006, TestSize.Level1)
544 {
545     CreateDistributedTableNonPrimaryKeyTest(DistributedDB::DEVICE_COOPERATION);
546 }
547 
548 /**
549   * @tc.name: RelationalStoreTest006
550   * @tc.desc: Test create distributed table with non primary key schema
551   * @tc.type: FUNC
552   * @tc.require:
553   * @tc.author:
554   */
555 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest006_1, TestSize.Level1)
556 {
557     CreateDistributedTableNonPrimaryKeyTest(DistributedDB::CLOUD_COOPERATION);
558 }
559 
CreateDistributedTableInvalidFieldTest(TableSyncType tableSyncType)560 void CreateDistributedTableInvalidFieldTest(TableSyncType tableSyncType)
561 {
562     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
563     ASSERT_NE(db, nullptr);
564     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
565     EXPECT_EQ(RelationalTestUtils::ExecSql(db, UNSUPPORTED_FIELD_TABLE_SQL), SQLITE_OK);
566     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
567 
568     RelationalStoreDelegate *delegate = nullptr;
569     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
570     EXPECT_EQ(status, OK);
571     ASSERT_NE(delegate, nullptr);
572 
573     EXPECT_EQ(delegate->CreateDistributedTable("test", tableSyncType), NOT_SUPPORT);
574     status = g_mgr.CloseStore(delegate);
575     EXPECT_EQ(status, OK);
576 }
577 
578 /**
579   * @tc.name: RelationalStoreTest007
580   * @tc.desc: Test create distributed table with table has invalid field name
581   * @tc.type: FUNC
582   * @tc.require: AR000GK58F
583   * @tc.author: lianhuix
584   */
585 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest007, TestSize.Level1)
586 {
587     CreateDistributedTableInvalidFieldTest(DistributedDB::DEVICE_COOPERATION);
588 }
589 
590 /**
591   * @tc.name: RelationalStoreTest007
592   * @tc.desc: Test create distributed table with table has invalid field name
593   * @tc.type: FUNC
594   * @tc.require:
595   * @tc.author: zhangshijie
596   */
597 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest007_1, TestSize.Level1)
598 {
599     CreateDistributedTableInvalidFieldTest(DistributedDB::CLOUD_COOPERATION);
600 }
601 
CreateDistributedTableCompositePKTest(TableSyncType tableSyncType,int expectCode)602 void CreateDistributedTableCompositePKTest(TableSyncType tableSyncType, int expectCode)
603 {
604     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
605     ASSERT_NE(db, nullptr);
606     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
607     EXPECT_EQ(RelationalTestUtils::ExecSql(db, COMPOSITE_PRIMARY_KEY_TABLE_SQL), SQLITE_OK);
608     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
609 
610     RelationalStoreDelegate *delegate = nullptr;
611     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
612     EXPECT_EQ(status, OK);
613     ASSERT_NE(delegate, nullptr);
614 
615     EXPECT_EQ(delegate->CreateDistributedTable("workers", tableSyncType), expectCode);
616     status = g_mgr.CloseStore(delegate);
617     EXPECT_EQ(status, OK);
618 }
619 
620 /**
621   * @tc.name: RelationalStoreTest008
622   * @tc.desc: Test create distributed table with table has composite primary keys for DEVICE_COOPERATION
623   * @tc.type: FUNC
624   * @tc.require: AR000GK58F
625   * @tc.author: lianhuix
626   */
627 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest008, TestSize.Level1)
628 {
629     CreateDistributedTableCompositePKTest(DistributedDB::DEVICE_COOPERATION, NOT_SUPPORT);
630 }
631 
632 /**
633   * @tc.name: RelationalStoreTest008
634   * @tc.desc: Test create distributed table with table has composite primary keys for CLOUD_COOPERATION
635   * @tc.type: FUNC
636   * @tc.require:
637   * @tc.author:
638   */
639 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest008_1, TestSize.Level1)
640 {
641     CreateDistributedTableCompositePKTest(DistributedDB::CLOUD_COOPERATION, OK);
642 }
643 
CreateDistributedTableWithHistoryDataTest(TableSyncType tableSyncType)644 void CreateDistributedTableWithHistoryDataTest(TableSyncType tableSyncType)
645 {
646     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
647     ASSERT_NE(db, nullptr);
648     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
649     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
650     EXPECT_EQ(RelationalTestUtils::ExecSql(db, INSERT_SYNC_DATA_SQL), SQLITE_OK);
651     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
652 
653     RelationalStoreDelegate *delegate = nullptr;
654     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
655     EXPECT_EQ(status, OK);
656     ASSERT_NE(delegate, nullptr);
657 
658     EXPECT_EQ(delegate->CreateDistributedTable("sync_data"), NOT_SUPPORT);
659     status = g_mgr.CloseStore(delegate);
660     EXPECT_EQ(status, OK);
661 }
662 
663 /**
664   * @tc.name: RelationalStoreTest009
665   * @tc.desc: Test create distributed table with table has history data for DEVICE_COOPERATION
666   * @tc.type: FUNC
667   * @tc.require: AR000GK58F
668   * @tc.author: lianhuix
669   */
670 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest009, TestSize.Level1)
671 {
672     CreateDistributedTableWithHistoryDataTest(DistributedDB::DEVICE_COOPERATION);
673 }
674 
675 /**
676   * @tc.name: RelationalStoreTest009
677   * @tc.desc: Test create distributed table with table has history data for CLOUD_COOPERATION
678   * @tc.type: FUNC
679   * @tc.require:
680   * @tc.author:
681   */
682 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest009_1, TestSize.Level1)
683 {
684     CreateDistributedTableWithHistoryDataTest(DistributedDB::CLOUD_COOPERATION);
685 }
686 
TableModifyTest(const std::string & modifySql,TableSyncType tableSyncType,DBStatus expect)687 void TableModifyTest(const std::string &modifySql, TableSyncType tableSyncType, DBStatus expect)
688 {
689     /**
690      * @tc.steps:step1. Prepare db file
691      * @tc.expected: step1. Return OK.
692      */
693     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
694     ASSERT_NE(db, nullptr);
695     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
696     if (tableSyncType == DistributedDB::DEVICE_COOPERATION) {
697         EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
698     } else {
699         EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK);
700     }
701 
702     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A");
703     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_B");
704     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_C");
705 
706     /**
707      * @tc.steps:step2. Open store
708      * @tc.expected: step2. return OK
709      */
710     RelationalStoreDelegate *delegate = nullptr;
711     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
712     EXPECT_EQ(status, OK);
713     ASSERT_NE(delegate, nullptr);
714 
715     /**
716      * @tc.steps:step3. Create distributed table
717      * @tc.expected: step3. Create distributed table OK.
718      */
719     EXPECT_EQ(delegate->CreateDistributedTable("sync_data", tableSyncType), OK);
720 
721     /**
722      * @tc.steps:step4. Upgrade table with modifySql
723      * @tc.expected: step4. return OK
724      */
725     EXPECT_EQ(RelationalTestUtils::ExecSql(db, modifySql), SQLITE_OK);
726 
727     /**
728      * @tc.steps:step5. Create distributed table again
729      * @tc.expected: step5. Create distributed table return expect.
730      */
731     EXPECT_EQ(delegate->CreateDistributedTable("sync_data", tableSyncType), expect);
732 
733     /**
734      * @tc.steps:step6. Close store
735      * @tc.expected: step6 Return OK.
736      */
737     status = g_mgr.CloseStore(delegate);
738     EXPECT_EQ(status, OK);
739     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
740 }
741 
742 /**
743   * @tc.name: RelationalTableModifyTest001
744   * @tc.desc: Test modify distributed table with compatible upgrade
745   * @tc.type: FUNC
746   * @tc.require: AR000GK58F
747   * @tc.author: lianhuix
748   */
749 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest001, TestSize.Level1)
750 {
751     TableModifyTest("ALTER TABLE sync_data ADD COLUMN add_field INTEGER NOT NULL DEFAULT 123;",
752         DistributedDB::DEVICE_COOPERATION, OK);
753 }
754 
755 /**
756   * @tc.name: RelationalTableModifyTest002
757   * @tc.desc: Test modify distributed table with incompatible upgrade
758   * @tc.type: FUNC
759   * @tc.require: AR000GK58F
760   * @tc.author: lianhuix
761   */
762 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest002, TestSize.Level1)
763 {
764     TableModifyTest("ALTER TABLE sync_data ADD COLUMN add_field INTEGER NOT NULL;",
765         DistributedDB::DEVICE_COOPERATION, SCHEMA_MISMATCH);
766 }
767 
768 /**
769   * @tc.name: RelationalTableModifyTest003
770   * @tc.desc: Test modify distributed table with incompatible upgrade
771   * @tc.type: FUNC
772   * @tc.require: AR000GK58F
773   * @tc.author: lianhuix
774   */
775 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest003, TestSize.Level1)
776 {
777     TableModifyTest("ALTER TABLE sync_data DROP COLUMN w_timestamp;",
778         DistributedDB::DEVICE_COOPERATION, SCHEMA_MISMATCH);
779 }
780 
781 /**
782   * @tc.name: RelationalTableModifyTest001
783   * @tc.desc: Test modify distributed table with compatible upgrade
784   * @tc.type: FUNC
785   * @tc.require:
786   * @tc.author: zhangshijie
787   */
788 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest001_1, TestSize.Level1)
789 {
790     TableModifyTest("ALTER TABLE sync_data ADD COLUMN add_field INTEGER NOT NULL DEFAULT 123;",
791         DistributedDB::CLOUD_COOPERATION, OK);
792 }
793 
794 /**
795   * @tc.name: RelationalTableModifyTest002
796   * @tc.desc: Test modify distributed table with incompatible upgrade
797   * @tc.type: FUNC
798   * @tc.require:
799   * @tc.author: zhangshijie
800   */
801 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest002_1, TestSize.Level1)
802 {
803     TableModifyTest("ALTER TABLE sync_data ADD COLUMN add_field INTEGER NOT NULL;",
804         DistributedDB::CLOUD_COOPERATION, SCHEMA_MISMATCH);
805 }
806 
807 /**
808   * @tc.name: RelationalTableModifyTest003
809   * @tc.desc: Test modify distributed table with incompatible upgrade
810   * @tc.type: FUNC
811   * @tc.require:
812   * @tc.author: zhangshijie
813   */
814 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest003_1, TestSize.Level1)
815 {
816     TableModifyTest("ALTER TABLE sync_data DROP COLUMN w_timestamp;",
817         DistributedDB::CLOUD_COOPERATION, SCHEMA_MISMATCH);
818 }
819 
UpgradeDistributedTableTest(TableSyncType tableSyncType)820 void UpgradeDistributedTableTest(TableSyncType tableSyncType)
821 {
822     /**
823      * @tc.steps:step1. Prepare db file
824      * @tc.expected: step1. Return OK.
825      */
826     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
827     ASSERT_NE(db, nullptr);
828     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
829     if (tableSyncType == DistributedDB::DEVICE_COOPERATION) {
830         EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
831     } else {
832         EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK);
833     }
834 
835     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A");
836     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_B");
837     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_C");
838 
839     /**
840      * @tc.steps:step2. Open store
841      * @tc.expected: step2. return OK
842      */
843     RelationalStoreDelegate *delegate = nullptr;
844     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
845     EXPECT_EQ(status, OK);
846     ASSERT_NE(delegate, nullptr);
847 
848     /**
849      * @tc.steps:step3. Create distributed table
850      * @tc.expected: step3. Create distributed table OK.
851      */
852     EXPECT_EQ(delegate->CreateDistributedTable("sync_data", tableSyncType), OK);
853 
854     /**
855      * @tc.steps:step4. Upgrade table
856      * @tc.expected: step4. return OK
857      */
858     std::string modifySql = "ALTER TABLE sync_data ADD COLUMN add_field INTEGER;";
859     EXPECT_EQ(RelationalTestUtils::ExecSql(db, modifySql), SQLITE_OK);
860     std::string indexSql = "CREATE INDEX add_index ON sync_data (add_field);";
861     EXPECT_EQ(RelationalTestUtils::ExecSql(db, indexSql), SQLITE_OK);
862     std::string deleteIndexSql = "DROP INDEX IF EXISTS key_index";
863     EXPECT_EQ(RelationalTestUtils::ExecSql(db, deleteIndexSql), SQLITE_OK);
864     EXPECT_EQ(RelationalTestUtils::ExecSql(db, INSERT_SYNC_DATA_SQL), SQLITE_OK);
865 
866     /**
867      * @tc.steps:step5. Create distributed table again
868      * @tc.expected: step5. Create distributed table return expect.
869      */
870     EXPECT_EQ(delegate->CreateDistributedTable("sync_data", tableSyncType), OK);
871 
872     /**
873      * @tc.steps:step6. Close store
874      * @tc.expected: step6 Return OK.
875      */
876     status = g_mgr.CloseStore(delegate);
877     EXPECT_EQ(status, OK);
878     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
879 }
880 
881 /**
882   * @tc.name: RelationalTableModifyTest004
883   * @tc.desc: Test upgrade distributed table with device table exists
884   * @tc.type: FUNC
885   * @tc.require: AR000GK58F
886   * @tc.author: lianhuix
887   */
888 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest004, TestSize.Level1)
889 {
890     UpgradeDistributedTableTest(DistributedDB::DEVICE_COOPERATION);
891 }
892 
893 /**
894   * @tc.name: RelationalTableModifyTest004
895   * @tc.desc: Test upgrade distributed table with device table exists
896   * @tc.type: FUNC
897   * @tc.require:
898   * @tc.author: zhangshijie
899   */
900 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest004_1, TestSize.Level1)
901 {
902     UpgradeDistributedTableTest(DistributedDB::CLOUD_COOPERATION);
903 }
904 
905 /**
906   * @tc.name: RelationalTableModifyTest005
907   * @tc.desc: Test modify distributed table with compatible upgrade
908   * @tc.type: FUNC
909   * @tc.require: AR000GK58F
910   * @tc.author: lianhuix
911   */
912 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest005, TestSize.Level1)
913 {
914     TableModifyTest("ALTER TABLE sync_data ADD COLUMN add_field STRING NOT NULL DEFAULT 'asdf';",
915         DistributedDB::DEVICE_COOPERATION, OK);
916 }
917 
918 /**
919   * @tc.name: RelationalTableModifyTest005
920   * @tc.desc: Test modify distributed table with compatible upgrade
921   * @tc.type: FUNC
922   * @tc.require:
923   * @tc.author: zhangshijie
924   */
925 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest005_1, TestSize.Level1)
926 {
927     TableModifyTest("ALTER TABLE sync_data ADD COLUMN add_field STRING NOT NULL DEFAULT 'asdf';",
928         DistributedDB::CLOUD_COOPERATION, OK);
929 }
930 
CheckTable(TableSyncType tableSyncType,RelationalStoreDelegate * delegate,sqlite3 * db)931 void CheckTable(TableSyncType tableSyncType, RelationalStoreDelegate *delegate, sqlite3 *db)
932 {
933     /**
934      * @tc.steps:step4. Create distributed table with a table with "UNIQUE"
935      * @tc.expected: step4. return OK or NOT_SUPPORT.
936      */
937     std::string tableName4 = "t4";
938     std::string createSql = "create table " + tableName4 + "(id int UNIQUE);";
939     createSql += "create table t4_1(id int primary key, value text UNIQUE, name int);";
940     createSql += "create table t4_2(id int primary key, value text UNIQUE , name int);";
941     createSql += "create table t4_3(id int primary key, value text UNIQUE );";
942     createSql += "create table t4_4(id int primary key, value text UNIQUE , name int);";
943     createSql += "create table t4_5(id int unique);";
944     createSql += "create table t4_6(id int primary key, value text UniqUe, name int);";
945     createSql += "create table t4_7(id int primary key, uniquekey text , name int);";
946     createSql += "create table t4_8(id int , name text, UNIQUE(id, name));";
947     createSql += "create table t4_9(id int , name text,UNIQUE(id, name));";
948     EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK);
949     DBStatus expectCode;
950     if (tableSyncType == DEVICE_COOPERATION) {
951         expectCode = OK;
952     } else {
953         expectCode = NOT_SUPPORT;
954     }
955     EXPECT_EQ(delegate->CreateDistributedTable(tableName4, tableSyncType), expectCode);
956     EXPECT_EQ(delegate->CreateDistributedTable("t4_1", tableSyncType), expectCode);
957     EXPECT_EQ(delegate->CreateDistributedTable("t4_2", tableSyncType), expectCode);
958     EXPECT_EQ(delegate->CreateDistributedTable("t4_3", tableSyncType), expectCode);
959     EXPECT_EQ(delegate->CreateDistributedTable("t4_4", tableSyncType), expectCode);
960     EXPECT_EQ(delegate->CreateDistributedTable("t4_5", tableSyncType), expectCode);
961     EXPECT_EQ(delegate->CreateDistributedTable("t4_6", tableSyncType), expectCode);
962     EXPECT_EQ(delegate->CreateDistributedTable("t4_7", tableSyncType), OK);
963     EXPECT_EQ(delegate->CreateDistributedTable("t4_8", tableSyncType), expectCode);
964     EXPECT_EQ(delegate->CreateDistributedTable("t4_9", tableSyncType), expectCode);
965 }
966 
TableConstraintsCheck(TableSyncType tableSyncType,RelationalStoreDelegate * delegate,sqlite3 * db)967 void TableConstraintsCheck(TableSyncType tableSyncType, RelationalStoreDelegate *delegate, sqlite3 *db)
968 {
969     /**
970      * @tc.steps:step1. Create distributed table with a table with "CHECK" key word
971      * @tc.expected: step1. return NOT_SUPPORT or OK.
972      */
973     std::string tableName1 = "t1";
974     std::string createSql = "create table " + tableName1 + "(id int CHECK(id > 5));";
975     EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK);
976     int expectCode = OK;
977     if (tableSyncType == DistributedDB::CLOUD_COOPERATION) {
978         expectCode = NOT_SUPPORT;
979     }
980     EXPECT_EQ(delegate->CreateDistributedTable(tableName1, tableSyncType), expectCode);
981 
982     /**
983      * @tc.steps:step2. Create distributed table with a table with foreign key
984      * @tc.expected: step2. return OK.
985      */
986     std::string tableName2 = "t2";
987     createSql = "create table " + tableName2 + "(name text, t1_id int, FOREIGN KEY (t1_id) REFERENCES " + tableName1 +
988                 " (id));";
989     EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK);
990     EXPECT_EQ(delegate->CreateDistributedTable(tableName2, tableSyncType), OK);
991 
992     CheckTable(tableSyncType, delegate, db);
993 
994     /**
995      * @tc.steps:step3. Create distributed table with a table with "WITHOUT ROWID"
996      * @tc.expected: step3. return NOT_SUPPORT.
997      */
998     std::string tableName3 = "t3";
999     createSql = "create table " + tableName3 + "(id int primary key) WITHOUT ROWID;";
1000     EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK);
1001     EXPECT_EQ(delegate->CreateDistributedTable(tableName3, tableSyncType), NOT_SUPPORT);
1002 
1003     /**
1004      * @tc.steps:step5. Create distributed table with a table with primary key which is real
1005      * @tc.expected: step5. return OK or NOT_SUPPORT.
1006      */
1007     std::string tableName5 = "t5";
1008     createSql = "create table " + tableName5 + "(id REAL primary key);";
1009     EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK);
1010     if (tableSyncType == DEVICE_COOPERATION) {
1011         expectCode = OK;
1012     } else {
1013         expectCode = NOT_SUPPORT;
1014     }
1015     EXPECT_EQ(delegate->CreateDistributedTable(tableName5, tableSyncType), expectCode);
1016 
1017     /**
1018      * @tc.steps:step6. Create distributed table with a table with primary key which is ASSET
1019      * @tc.expected: step6. return OK or NOT_SUPPORT.
1020      */
1021     std::string tableName6 = "t6";
1022     createSql = "create table " + tableName6 + "(id ASSET primary key);";
1023     EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK);
1024     if (tableSyncType == DEVICE_COOPERATION) {
1025         expectCode = OK;
1026     } else {
1027         expectCode = NOT_SUPPORT;
1028     }
1029     EXPECT_EQ(delegate->CreateDistributedTable(tableName6, tableSyncType), expectCode);
1030 
1031     /**
1032      * @tc.steps:step7. Create distributed table with a table with primary key which is ASSETS
1033      * @tc.expected: step7. return OK or NOT_SUPPORT.
1034      */
1035     std::string tableName7 = "t7";
1036     createSql = "create table " + tableName7 + "(id assets primary key);";
1037     EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK);
1038     if (tableSyncType == DEVICE_COOPERATION) {
1039         expectCode = OK;
1040     } else {
1041         expectCode = NOT_SUPPORT;
1042     }
1043     EXPECT_EQ(delegate->CreateDistributedTable(tableName7, tableSyncType), expectCode);
1044 }
1045 
TableConstraintsTest(TableSyncType tableSyncType)1046 void TableConstraintsTest(TableSyncType tableSyncType)
1047 {
1048     /**
1049      * @tc.steps:step1. Prepare db file
1050      * @tc.expected: step1. Return OK.
1051      */
1052     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1053     ASSERT_NE(db, nullptr);
1054     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1055 
1056     /**
1057      * @tc.steps:step2. Open store
1058      * @tc.expected: step2. return OK
1059      */
1060     RelationalStoreDelegate *delegate = nullptr;
1061     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1062     EXPECT_EQ(status, OK);
1063     ASSERT_NE(delegate, nullptr);
1064 
1065     /**
1066      * @tc.steps:step3. check constraints
1067      */
1068     TableConstraintsCheck(tableSyncType, delegate, db);
1069 
1070     /**
1071      * @tc.steps:step4. Close store
1072      * @tc.expected: step4 Return OK.
1073      */
1074     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1075     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1076 }
1077 
1078 /**
1079   * @tc.name: TableConstraintsTest001
1080   * @tc.desc: Test table constraints when create distributed table with DistributedDB::DEVICE_COOPERATION
1081   * @tc.type: FUNC
1082   * @tc.require:
1083   * @tc.author: zhangshijie
1084   */
1085 HWTEST_F(DistributedDBInterfacesRelationalTest, TableConstraintsTest001, TestSize.Level1)
1086 {
1087     TableConstraintsTest(DistributedDB::DEVICE_COOPERATION);
1088 }
1089 
1090 /**
1091   * @tc.name: TableConstraintsTest002
1092   * @tc.desc: Test table constraints when create distributed table with DistributedDB::CLOUD_COOPERATION
1093   * @tc.type: FUNC
1094   * @tc.require:
1095   * @tc.author: zhangshijie
1096   */
1097 HWTEST_F(DistributedDBInterfacesRelationalTest, TableConstraintsTest002, TestSize.Level1)
1098 {
1099     TableConstraintsTest(DistributedDB::CLOUD_COOPERATION);
1100 }
1101 
1102 /**
1103   * @tc.name: RelationalRemoveDeviceDataTest001
1104   * @tc.desc: Test remove device data
1105   * @tc.type: FUNC
1106   * @tc.require: AR000GK58F
1107   * @tc.author: lianhuix
1108   */
1109 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest001, TestSize.Level1)
1110 {
1111     /**
1112      * @tc.steps:step1. Prepare db file
1113      * @tc.expected: step1. Return OK.
1114      */
1115     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1116     ASSERT_NE(db, nullptr);
1117     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1118     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
1119     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A");
1120     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_B");
1121     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_C");
1122 
1123     /**
1124      * @tc.steps:step2. Open store
1125      * @tc.expected: step2. return OK
1126      */
1127     RelationalStoreDelegate *delegate = nullptr;
1128     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1129     EXPECT_EQ(status, OK);
1130     ASSERT_NE(delegate, nullptr);
1131 
1132     /**
1133      * @tc.steps:step3. Remove device data
1134      * @tc.expected: step3. ok
1135      */
1136     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A"), DISTRIBUTED_SCHEMA_NOT_FOUND);
1137     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_D"), DISTRIBUTED_SCHEMA_NOT_FOUND);
1138     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "sync_data"), DISTRIBUTED_SCHEMA_NOT_FOUND);
1139     EXPECT_EQ(delegate->CreateDistributedTable("sync_data"), OK);
1140     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A"), OK);
1141     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_B"), OK);
1142     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_C", "sync_data"), OK);
1143     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_D"), OK);
1144     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "sync_data_A"), DISTRIBUTED_SCHEMA_NOT_FOUND);
1145 
1146     /**
1147      * @tc.steps:step4. Remove device data with invalid args
1148      * @tc.expected: step4. invalid
1149      */
1150     EXPECT_EQ(delegate->RemoveDeviceData(""), INVALID_ARGS);
1151     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "Handle-J@^."), INVALID_ARGS);
1152 
1153     /**
1154      * @tc.steps:step5. Close store
1155      * @tc.expected: step5 Return OK.
1156      */
1157     status = g_mgr.CloseStore(delegate);
1158     EXPECT_EQ(status, OK);
1159     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1160 }
1161 
1162 struct TableT1 {
1163     int a;
1164     std::string b;
1165     int rowid;
1166     int flag;
1167     int timestamp;
1168 
operator ()__anonb7c9854c0111::TableT11169     VirtualRowData operator() () const
1170     {
1171         VirtualRowData rowData;
1172         DataValue dA;
1173         dA = static_cast<int64_t>(a);
1174         rowData.objectData.PutDataValue("a", dA);
1175         DataValue dB;
1176         dB.SetText(b);
1177         rowData.objectData.PutDataValue("b", dB);
1178         rowData.logInfo.dataKey = rowid;
1179         rowData.logInfo.device = DEVICE_B;
1180         rowData.logInfo.originDev = DEVICE_B;
1181         rowData.logInfo.timestamp = timestamp;
1182         rowData.logInfo.wTimestamp = timestamp;
1183         rowData.logInfo.flag = flag;
1184         Key key;
1185         DBCommon::StringToVector(std::to_string(rowid), key);
1186         std::vector<uint8_t> hashKey;
1187         DBCommon::CalcValueHash(key, hashKey);
1188         rowData.logInfo.hashKey = hashKey;
1189         return rowData;
1190     }
1191 };
1192 
AddDeviceSchema(RelationalVirtualDevice * device,sqlite3 * db,const std::string & name)1193 void AddDeviceSchema(RelationalVirtualDevice *device, sqlite3 *db, const std::string &name)
1194 {
1195     TableInfo table;
1196     SQLiteUtils::AnalysisSchema(db, name, table);
1197     device->SetLocalFieldInfo(table.GetFieldInfos());
1198     device->SetTableInfo(table);
1199 }
1200 
AddErrorTrigger(sqlite3 * db,const std::string & name)1201 void AddErrorTrigger(sqlite3 *db, const std::string &name)
1202 {
1203     ASSERT_NE(db, nullptr);
1204     ASSERT_NE(name, "");
1205     std::string sql = "CREATE TRIGGER IF NOT EXISTS "
1206         "naturalbase_rdb_aux_" + name + "_log_ON_DELETE BEFORE DELETE \n"
1207         "ON naturalbase_rdb_aux_" + name + "_log \n"
1208         "BEGIN \n"
1209         "\t INSERT INTO naturalbase_rdb_aux_" + name + "_log VALUES(no_exist_func(), '', '', '', '', '', ''); \n"
1210         "END;";
1211     char *errMsg = nullptr;
1212     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errMsg), SQLITE_OK);
1213     if (errMsg != nullptr) {
1214         LOGE("sql error %s", errMsg);
1215         LOGE("sql %s", sql.c_str());
1216     }
1217 }
1218 
1219 /**
1220   * @tc.name: RelationalRemoveDeviceDataTest002
1221   * @tc.desc: Test remove device data and syn
1222   * @tc.type: FUNC
1223   * @tc.require: AR000GK58F
1224   * @tc.author: lianhuix
1225   */
1226 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest002, TestSize.Level1)
1227 {
1228     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1229     ASSERT_NE(db, nullptr);
1230     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1231     EXPECT_EQ(RelationalTestUtils::ExecSql(db, SIMPLE_CREATE_TABLE_SQL), SQLITE_OK);
1232     AddDeviceSchema(g_deviceB, db, "t1");
1233 
1234     RelationalStoreDelegate *delegate = nullptr;
1235     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1236     EXPECT_EQ(status, OK);
1237     ASSERT_NE(delegate, nullptr);
1238 
1239     EXPECT_EQ(delegate->CreateDistributedTable("t1"), OK);
1240 
1241     g_deviceB->PutDeviceData("t1", std::vector<TableT1>{
1242         {1, "111", 1, 2, 1}, // test data
1243         {2, "222", 2, 2, 2}, // test data
1244         {3, "333", 3, 2, 3}, // test data
1245         {4, "444", 4, 2, 4} // test data
1246     });
1247     std::vector<std::string> devices = {DEVICE_B};
1248     Query query = Query::Select("t1").NotEqualTo("a", 0);
1249     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonb7c9854c0302(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1250         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1251             EXPECT_EQ(devicesMap.size(), devices.size());
1252             EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
1253         }, true);
1254     EXPECT_EQ(status, OK);
1255 
1256     EXPECT_EQ(delegate->RemoveDeviceData(DEVICE_B), OK);
1257 
1258     int logCnt = -1;
1259     std::string checkLogSql = "SELECT count(*) FROM naturalbase_rdb_aux_t1_log";
__anonb7c9854c0402(sqlite3_stmt *stmt) 1260     RelationalTestUtils::ExecSql(db, checkLogSql, nullptr, [&logCnt](sqlite3_stmt *stmt) {
1261         logCnt = sqlite3_column_int(stmt, 0);
1262         return E_OK;
1263     });
1264     EXPECT_EQ(logCnt, 0);
1265 
1266     int dataCnt = -1;
1267     std::string deviceTable = g_mgr.GetDistributedTableName(DEVICE_B, "t1");
1268     std::string checkDataSql = "SELECT count(*) FROM " + deviceTable;
__anonb7c9854c0502(sqlite3_stmt *stmt) 1269     RelationalTestUtils::ExecSql(db, checkDataSql, nullptr, [&dataCnt](sqlite3_stmt *stmt) {
1270         dataCnt = sqlite3_column_int(stmt, 0);
1271         return E_OK;
1272     });
1273     EXPECT_EQ(logCnt, 0);
1274 
1275     status = g_mgr.CloseStore(delegate);
1276     EXPECT_EQ(status, OK);
1277     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1278 }
1279 
TestRemoveDeviceDataWithCallback(bool removeAll)1280 void TestRemoveDeviceDataWithCallback(bool removeAll)
1281 {
1282     /**
1283      * @tc.steps:step1. Prepare db and data
1284      * @tc.expected: step1. Return OK.
1285      */
1286     RuntimeConfig::SetTranslateToDeviceIdCallback([](const std::string &oriDevId, const StoreInfo &info) {
1287         return oriDevId + "_" + info.appId;
1288     });
1289     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1290     ASSERT_NE(db, nullptr);
1291     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1292     EXPECT_EQ(RelationalTestUtils::ExecSql(db, SIMPLE_CREATE_TABLE_SQL), SQLITE_OK);
1293     AddDeviceSchema(g_deviceB, db, "t1");
1294     RelationalStoreDelegate *delegate = nullptr;
1295     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1296     EXPECT_EQ(status, OK);
1297     ASSERT_NE(delegate, nullptr);
1298     EXPECT_EQ(delegate->CreateDistributedTable("t1"), OK);
1299     g_deviceB->PutDeviceData("t1", std::vector<TableT1> {
1300         {1, "111", 1, 0, 1} // test data
1301     });
1302     std::vector<std::string> devices = {DEVICE_B};
1303     Query query = Query::Select("t1").EqualTo("a", 1);
1304     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
1305         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1306             ASSERT_EQ(devicesMap.size(), devices.size());
1307             EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
1308         }, true);
1309     EXPECT_EQ(status, OK);
1310     /**
1311      * @tc.steps:step2. remove device data and check table
1312      * @tc.expected: step2. dev table not exist and log not exist device b.
1313      */
1314     std::this_thread::sleep_for(std::chrono::seconds(1));
1315     if (removeAll) {
1316         EXPECT_EQ(delegate->RemoveDeviceData(), OK);
1317     } else {
1318         EXPECT_EQ(delegate->RemoveDeviceData(DEVICE_B + "_" + APP_ID), OK);
1319     }
1320     int logCnt = -1;
1321     std::string checkLogSql = "SELECT count(*) FROM naturalbase_rdb_aux_t1_log";
1322     RelationalTestUtils::ExecSql(db, checkLogSql, nullptr, [&logCnt](sqlite3_stmt *stmt) {
1323         logCnt = sqlite3_column_int(stmt, 0);
1324         return E_OK;
1325     });
1326     EXPECT_EQ(logCnt, 0);
1327     std::string deviceTable = RelationalStoreManager::GetDistributedTableName(DEVICE_B + "_" + APP_ID, "t1");
1328     std::string checkDataSql = "SELECT count(*) FROM " + deviceTable;
1329     EXPECT_NE(RelationalTestUtils::ExecSql(db, checkDataSql, nullptr, nullptr), SQLITE_OK);
1330     /**
1331      * @tc.steps:step3. close db
1332      * @tc.expected: step3. Return OK.
1333      */
1334     status = g_mgr.CloseStore(delegate);
1335     EXPECT_EQ(status, OK);
1336     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1337     RuntimeConfig::SetTranslateToDeviceIdCallback(nullptr);
1338 }
1339 
1340 /**
1341   * @tc.name: RelationalRemoveDeviceDataTest003
1342   * @tc.desc: Test remove all device data and sync again
1343   * @tc.type: FUNC
1344   * @tc.require: AR000GK58F
1345   * @tc.author: zhangqiquan
1346   */
1347 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest003, TestSize.Level1)
1348 {
1349     TestRemoveDeviceDataWithCallback(true);
1350 }
1351 
1352 /**
1353   * @tc.name: RelationalRemoveDeviceDataTest004
1354   * @tc.desc: Test remove one device data and sync again
1355   * @tc.type: FUNC
1356   * @tc.require: AR000GK58F
1357   * @tc.author: zhangqiquan
1358   */
1359 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest004, TestSize.Level1)
1360 {
1361     TestRemoveDeviceDataWithCallback(false);
1362 }
1363 
1364 /**
1365   * @tc.name: RelationalRemoveDeviceDataTest005
1366   * @tc.desc: Test remove device data with invalid param
1367   * @tc.type: FUNC
1368   * @tc.require: AR000GK58F
1369   * @tc.author: zhangqiquan
1370   */
1371 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest005, TestSize.Level1)
1372 {
1373     /**
1374      * @tc.steps:step1. Prepare db file
1375      * @tc.expected: step1. Return OK.
1376      */
1377     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1378     ASSERT_NE(db, nullptr);
1379     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1380     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
1381     RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A");
1382     AddDeviceSchema(g_deviceB, db, "sync_data");
1383     /**
1384      * @tc.steps:step2. Open store
1385      * @tc.expected: step2. return OK
1386      */
1387     RelationalStoreDelegate *delegate = nullptr;
1388     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1389     EXPECT_EQ(status, OK);
1390     ASSERT_NE(delegate, nullptr);
1391     int count = 0;
__anonb7c9854c0902(const std::string &oriDevId, const StoreInfo &info) 1392     RuntimeConfig::SetTranslateToDeviceIdCallback([&count](const std::string &oriDevId, const StoreInfo &info) {
1393         count++;
1394         return oriDevId + "_" + info.appId;
1395     });
1396     /**
1397      * @tc.steps:step3. Remove not exist device data
1398      * @tc.expected: step3. ok
1399      */
1400     EXPECT_EQ(delegate->CreateDistributedTable("sync_data"), OK);
1401     EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_C", "sync_data"), OK);
1402     EXPECT_EQ(count, 0);
1403     /**
1404      * @tc.steps:step4. Close store
1405      * @tc.expected: step4 Return OK.
1406      */
1407     status = g_mgr.CloseStore(delegate);
1408     EXPECT_EQ(status, OK);
1409     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1410     RuntimeConfig::SetTranslateToDeviceIdCallback(nullptr);
1411 }
1412 
1413 /**
1414   * @tc.name: RelationalRemoveDeviceDataTest006
1415   * @tc.desc: Test remove device data with busy
1416   * @tc.type: FUNC
1417   * @tc.require: AR000GK58F
1418   * @tc.author: zhangqiquan
1419   */
1420 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest006, TestSize.Level1)
1421 {
1422     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1423     ASSERT_NE(db, nullptr);
1424     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1425     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "CREATE TABLE IF NOT EXISTS t2(a INT, b TEXT)"), SQLITE_OK);
1426     AddDeviceSchema(g_deviceB, db, "t2");
1427 
1428     RelationalStoreDelegate *delegate = nullptr;
1429     auto observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1430     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID,
1431         { .observer = observer }, delegate);
1432     EXPECT_EQ(status, OK);
1433     ASSERT_NE(delegate, nullptr);
1434 
1435     EXPECT_EQ(delegate->CreateDistributedTable("t2"), OK);
1436 
1437     g_deviceB->PutDeviceData("t2", std::vector<TableT1>{
1438         {1, "111", 1, 2, 1}, // test data
1439     });
1440     std::vector<std::string> devices = {DEVICE_B};
1441     Query query = Query::Select("t2");
1442     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, true);
1443     EXPECT_EQ(status, OK);
1444 
1445     auto beforeCallCount = observer->GetCallCount();
1446     AddErrorTrigger(db, "t2");
1447     EXPECT_EQ(delegate->RemoveDeviceData(DEVICE_B), DB_ERROR);
1448 
1449     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, true);
1450     EXPECT_EQ(status, OK);
1451     auto afterCallCount = observer->GetCallCount();
1452     EXPECT_NE(beforeCallCount, afterCallCount);
1453 
1454     status = g_mgr.CloseStore(delegate);
1455     EXPECT_EQ(status, OK);
1456     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1457     delete observer;
1458 }
1459 
1460 /**
1461   * @tc.name: RelationalOpenStorePathCheckTest001
1462   * @tc.desc: Test open store with same label but different path.
1463   * @tc.type: FUNC
1464   * @tc.require: AR000GK58F
1465   * @tc.author: lianhuix
1466   */
1467 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalOpenStorePathCheckTest001, TestSize.Level1)
1468 {
1469     std::string dir1 = g_dbDir + "dbDir1";
1470     EXPECT_EQ(OS::MakeDBDirectory(dir1), E_OK);
1471     sqlite3 *db1 = RelationalTestUtils::CreateDataBase(dir1 + STORE_ID + DB_SUFFIX);
1472     ASSERT_NE(db1, nullptr);
1473     EXPECT_EQ(RelationalTestUtils::ExecSql(db1, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1474     EXPECT_EQ(RelationalTestUtils::ExecSql(db1, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
1475     EXPECT_EQ(sqlite3_close_v2(db1), SQLITE_OK);
1476 
1477     std::string dir2 = g_dbDir + "dbDir2";
1478     EXPECT_EQ(OS::MakeDBDirectory(dir2), E_OK);
1479     sqlite3 *db2 = RelationalTestUtils::CreateDataBase(dir2 + STORE_ID + DB_SUFFIX);
1480     ASSERT_NE(db2, nullptr);
1481     EXPECT_EQ(RelationalTestUtils::ExecSql(db2, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1482     EXPECT_EQ(RelationalTestUtils::ExecSql(db2, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
1483     EXPECT_EQ(sqlite3_close_v2(db2), SQLITE_OK);
1484 
1485     DBStatus status = OK;
1486     RelationalStoreDelegate *delegate1 = nullptr;
1487     status = g_mgr.OpenStore(dir1 + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate1);
1488     EXPECT_EQ(status, OK);
1489     ASSERT_NE(delegate1, nullptr);
1490 
1491     RelationalStoreDelegate *delegate2 = nullptr;
1492     status = g_mgr.OpenStore(dir2 + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate2);
1493     EXPECT_EQ(status, INVALID_ARGS);
1494     ASSERT_EQ(delegate2, nullptr);
1495 
1496     status = g_mgr.CloseStore(delegate1);
1497     EXPECT_EQ(status, OK);
1498 
1499     status = g_mgr.CloseStore(delegate2);
1500     EXPECT_EQ(status, INVALID_ARGS);
1501 }
1502 
1503 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalOpenStorePressureTest001, TestSize.Level1)
1504 {
1505     /**
1506      * @tc.steps:step1. Prepare db file
1507      * @tc.expected: step1. Return OK.
1508      */
1509     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1510     ASSERT_NE(db, nullptr);
1511     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1512     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
1513     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1514 
1515     DBStatus status = OK;
1516     for (int i = 0; i < 1000; i++) {
1517         RelationalStoreDelegate *delegate = nullptr;
1518         status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1519         EXPECT_EQ(status, OK);
1520         ASSERT_NE(delegate, nullptr);
1521 
1522         status = g_mgr.CloseStore(delegate);
1523         EXPECT_EQ(status, OK);
1524         delegate = nullptr;
1525     }
1526 }
1527 
1528 HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalOpenStorePressureTest002, TestSize.Level1)
1529 {
1530     /**
1531      * @tc.steps:step1. Prepare db file
1532      * @tc.expected: step1. Return OK.
1533      */
1534     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1535     ASSERT_NE(db, nullptr);
1536     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1537     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
1538     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1539 
1540     std::queue<RelationalStoreDelegate *> delegateQueue;
1541     std::mutex queueLock;
1542     std::random_device rd;
1543     default_random_engine e(rd());
1544     uniform_int_distribution<unsigned> u(0, 9);
1545 
__anonb7c9854c0a02() 1546     std::thread openStoreThread([&, this]() {
1547         for (int i = 0; i < 1000; i++) {
1548             LOGD("++++> open store delegate: %d", i);
1549             RelationalStoreDelegate *delegate = nullptr;
1550             DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1551             EXPECT_EQ(status, OK);
1552             ASSERT_NE(delegate, nullptr);
1553             {
1554                 std::lock_guard<std::mutex> lock(queueLock);
1555                 delegateQueue.push(delegate);
1556             }
1557             LOGD("++++< open store delegate: %d", i);
1558         }
1559     });
1560 
1561     int cnt = 0;
1562     while (cnt < 1000) {
1563         RelationalStoreDelegate *delegate = nullptr;
1564         {
1565             std::lock_guard<std::mutex> lock(queueLock);
1566             if (delegateQueue.empty()) {
1567                 std::this_thread::sleep_for(std::chrono::microseconds(100));
1568                 continue;
1569             }
1570             delegate = delegateQueue.front();
1571             delegateQueue.pop();
1572         }
1573         LOGD("++++> close store delegate: %d", cnt);
1574         DBStatus status = g_mgr.CloseStore(delegate);
1575         LOGD("++++< close store delegate: %d", cnt);
1576         EXPECT_EQ(status, OK);
1577         delegate = nullptr;
1578         cnt++;
1579         std::this_thread::sleep_for(std::chrono::microseconds(100 * u(e)));
1580     }
1581     openStoreThread.join();
1582 }
1583 
1584 namespace {
ProcessSync(RelationalStoreDelegate * delegate)1585     void ProcessSync(RelationalStoreDelegate *delegate)
1586     {
1587         std::vector<std::string> devices = {DEVICE_B};
1588         Query query = Query::Select("create").EqualTo("create", 1);
1589         DBStatus status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
1590             [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1591                 EXPECT_EQ(devicesMap.size(), devices.size());
1592                 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
1593             }, true);
1594         EXPECT_EQ(status, OK);
1595 
1596         std::vector<VirtualRowData> data;
1597         g_deviceB->GetAllSyncData("create", data);
1598         EXPECT_EQ(data.size(), 1u);
1599 
1600         VirtualRowData virtualRowData;
1601         DataValue d1;
1602         d1 = static_cast<int64_t>(2); // 2: test data
1603         virtualRowData.objectData.PutDataValue("create", d1);
1604         DataValue d2;
1605         d2.SetText("hello");
1606         virtualRowData.objectData.PutDataValue("ddd", d2);
1607         DataValue d3;
1608         d3.SetText("hello");
1609         virtualRowData.objectData.PutDataValue("eee", d3);
1610         virtualRowData.logInfo.timestamp = 1;
1611         g_deviceB->PutData("create", {virtualRowData});
1612         status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
1613             [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1614                 EXPECT_EQ(devicesMap.size(), devices.size());
1615                 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
1616             }, true);
1617         EXPECT_EQ(status, OK);
1618     }
1619 }
1620 
1621 /**
1622   * @tc.name: SqliteKeyWord001
1623   * @tc.desc: Test relational table with sqlite key world.
1624   * @tc.type: FUNC
1625   * @tc.require:
1626   * @tc.author: lianhuix
1627   */
1628 HWTEST_F(DistributedDBInterfacesRelationalTest, SqliteKeyWordTest001, TestSize.Level1)
1629 {
1630     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1631     ASSERT_NE(db, nullptr);
1632     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1633 
1634     std::string tableSql = "CREATE TABLE IF NOT EXISTS 'create' ('create' INTEGER PRIMARY KEY, b 'CREATE', " \
1635     "c TEXT DEFAULT 'DEFAULT', UNIQUE(b, c))";
1636     EXPECT_EQ(RelationalTestUtils::ExecSql(db, tableSql), SQLITE_OK);
1637     std::string indexSql = "CREATE INDEX IF NOT EXISTS 'index' on 'create' (b)";
1638     EXPECT_EQ(RelationalTestUtils::ExecSql(db, indexSql), SQLITE_OK);
1639 
1640     PrepareVirtualDeviceEnv("create", g_dbDir + STORE_ID + DB_SUFFIX, {g_deviceB});
1641 
1642     DBStatus status = OK;
1643     RelationalStoreDelegate *delegate = nullptr;
1644     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1645     EXPECT_EQ(status, OK);
1646     ASSERT_NE(delegate, nullptr);
1647 
1648     status = delegate->CreateDistributedTable("create");
1649     EXPECT_EQ(status, OK);
1650 
1651     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "INSERT INTO 'create' values(1, 'bbb', 'ccc')"), SQLITE_OK);
1652 
1653     std::string insertSql = "INSERT INTO 'create' values(1001, 'create', 'text')";
1654     EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
1655 
1656     std::string updateSql = "UPDATE 'create' SET 'create' = 1002 WHERE b = 'create'";
1657     EXPECT_EQ(RelationalTestUtils::ExecSql(db, updateSql), SQLITE_OK);
1658 
1659     std::string deleteSql = "DELETE FROM 'create' WHERE 'create' = 1002";
1660     EXPECT_EQ(RelationalTestUtils::ExecSql(db, deleteSql), SQLITE_OK);
1661 
1662     ProcessSync(delegate);
1663 
1664     std::string alterSql = "ALTER TABLE 'create' ADD COLUMN 'table' 'insert' DEFAULT NULL";
1665     EXPECT_EQ(RelationalTestUtils::ExecSql(db, alterSql), SQLITE_OK);
1666     status = delegate->CreateDistributedTable("create");
1667     EXPECT_EQ(status, OK);
1668 
1669     status = delegate->RemoveDeviceData("DEVICES_B", "create");
1670     EXPECT_EQ(status, OK);
1671 
1672     status = g_mgr.CloseStore(delegate);
1673     EXPECT_EQ(status, OK);
1674     delegate = nullptr;
1675     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1676 }
1677 
1678 /**
1679   * @tc.name: GetDistributedTableName001
1680   * @tc.desc: Test get distributed table name
1681   * @tc.type: FUNC
1682   * @tc.require: AR000GK58F
1683   * @tc.author: zhangqiquan
1684   */
1685 HWTEST_F(DistributedDBInterfacesRelationalTest, GetDistributedTableName001, TestSize.Level1)
1686 {
1687     const std::string deviceName = "DEVICES_A";
1688     const std::string tableName = "TABLE";
1689     const std::string hashDev = DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceName));
1690 
1691     std::string devTableName = RelationalStoreManager::GetDistributedTableName(deviceName, tableName);
1692     EXPECT_EQ(devTableName, DBConstant::RELATIONAL_PREFIX + tableName + "_" + hashDev);
__anonb7c9854c0e02(const std::string &oriDevId, const StoreInfo &info) 1693     RuntimeConfig::SetTranslateToDeviceIdCallback([](const std::string &oriDevId, const StoreInfo &info) {
1694         EXPECT_EQ(info.appId, "");
1695         return oriDevId;
1696     });
1697     devTableName = RelationalStoreManager::GetDistributedTableName(deviceName, tableName);
1698     EXPECT_EQ(devTableName, DBConstant::RELATIONAL_PREFIX + tableName + "_" + deviceName);
1699     devTableName = RelationalStoreManager::GetDistributedTableName("", tableName);
1700     EXPECT_EQ(devTableName, DBConstant::RELATIONAL_PREFIX + tableName + "_");
1701     RuntimeConfig::SetTranslateToDeviceIdCallback(nullptr);
1702 }
1703 
1704 /**
1705   * @tc.name: CloudRelationalStoreTest001
1706   * @tc.desc: Test create distributed table in cloud table sync type
1707   * @tc.type: FUNC
1708   * @tc.require:
1709   * @tc.author: zhangshjie
1710   */
1711 HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest001, TestSize.Level0) {
1712     /**
1713      * @tc.steps:step1. Prepare db file
1714      * @tc.expected: step1. Return OK.
1715      */
1716     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1717     ASSERT_NE(db, nullptr);
1718     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1719     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK);
1720     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1721 
1722     /**
1723      * @tc.steps:step2. open relational store, create distributed table with CLOUD_COOPERATION
1724      * @tc.expected: step2. Return OK.
1725      */
1726     RelationalStoreDelegate *delegate = nullptr;
1727     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1728     EXPECT_EQ(status, OK);
1729     ASSERT_NE(delegate, nullptr);
1730 
1731     status = delegate->CreateDistributedTable("sync_data", DistributedDB::CLOUD_COOPERATION);
1732     EXPECT_EQ(status, OK);
1733 
1734     /**
1735      * @tc.steps:step3. open relational store, create distributed table with CLOUD_COOPERATION again
1736      * @tc.expected: step3. Return OK.
1737      */
1738     status = delegate->CreateDistributedTable("sync_data", DistributedDB::CLOUD_COOPERATION);
1739     EXPECT_EQ(status, OK);
1740 
1741     status = g_mgr.CloseStore(delegate);
1742     EXPECT_EQ(status, OK);
1743 }
1744 
1745 /**
1746   * @tc.name: CloudRelationalStoreTest002
1747   * @tc.desc: Test create distributed table in diff table sync type for the same table
1748   * @tc.type: FUNC
1749   * @tc.require:
1750   * @tc.author: zhangshjie
1751   */
1752 HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest002, TestSize.Level0) {
1753     /**
1754      * @tc.steps:step1. Prepare db file
1755      * @tc.expected: step1. Return OK.
1756      */
1757     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1758     ASSERT_NE(db, nullptr);
1759     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1760     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK);
1761     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1762 
1763     /**
1764      * @tc.steps:step2. open relational store, create distributed table with DEVICE_COOPERATION
1765      * @tc.expected: step2. Return OK.
1766      */
1767     RelationalStoreDelegate *delegate = nullptr;
1768     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1769     EXPECT_EQ(status, OK);
1770     ASSERT_NE(delegate, nullptr);
1771 
1772     status = delegate->CreateDistributedTable("sync_data", DistributedDB::DEVICE_COOPERATION);
1773     EXPECT_EQ(status, OK);
1774 
1775     /**
1776      * @tc.steps:step3. create distributed table with CLOUD_COOPERATION again
1777      * @tc.expected: step3. Return TYPE_MISMATCH.
1778      */
1779     status = delegate->CreateDistributedTable("sync_data", DistributedDB::CLOUD_COOPERATION);
1780     EXPECT_EQ(status, TYPE_MISMATCH);
1781 
1782     status = g_mgr.CloseStore(delegate);
1783     EXPECT_EQ(status, OK);
1784     delegate = nullptr;
1785 
1786     /**
1787      * @tc.steps:step4. drop table sync_data and create again
1788      * @tc.expected: step4. Return OK.
1789      */
1790     db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1791     ASSERT_NE(db, nullptr);
1792     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1793     const std::string dropSql = "drop table sync_data;";
1794     EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropSql), SQLITE_OK);
1795     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1796 
1797     /**
1798      * @tc.steps:step5. open relational store, create distributed table with CLOUD_COOPERATION
1799      * @tc.expected: step5. Return OK.
1800      */
1801     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1802     EXPECT_EQ(status, OK);
1803     ASSERT_NE(delegate, nullptr);
1804 
1805     db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1806     ASSERT_NE(db, nullptr);
1807     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1808     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK);
1809     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1810 
1811     EXPECT_EQ(delegate->CreateDistributedTable("sync_data", DistributedDB::CLOUD_COOPERATION), OK);
1812 
1813     /**
1814      * @tc.steps:step6. create distributed table with DEVICE_COOPERATION again
1815      * @tc.expected: step6. Return TYPE_MISMATCH.
1816      */
1817     status = delegate->CreateDistributedTable("sync_data", DistributedDB::DEVICE_COOPERATION);
1818     EXPECT_EQ(status, TYPE_MISMATCH);
1819 
1820     status = g_mgr.CloseStore(delegate);
1821     EXPECT_EQ(status, OK);
1822     delegate = nullptr;
1823 }
1824 }
1825