• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "cloud_sync_log_table_manager.h"
18 #include "distributeddb_tools_unit_test.h"
19 #include "rdb_data_generator.h"
20 #include "relational_store_client.h"
21 #include "sqlite_relational_utils.h"
22 #include "table_info.h"
23 
24 using namespace testing::ext;
25 using namespace DistributedDB;
26 using namespace DistributedDBUnitTest;
27 
28 namespace {
29     constexpr const char *DB_SUFFIX = ".db";
30     constexpr const char *STORE_ID = "Relational_Store_ID";
31     std::string g_dbDir;
32     std::string g_testDir;
33 }
34 
35 namespace {
36 class DistributedDBRDBKnowledgeClientTest : public testing::Test {
37 public:
38     static void SetUpTestCase(void);
39     static void TearDownTestCase(void);
40     void SetUp() override;
41     void TearDown() override;
42 protected:
43     static UtTableSchemaInfo GetTableSchema(const std::string &table);
44     static void SaveSchemaToMetaTable(sqlite3 *db, const std::string tableName, const TableInfo &tableInfo);
45     static void CreateDistributedTable(const std::vector<std::string> &tableNames,
46         DistributedDB::TableSyncType tableSyncType);
47     static constexpr const char *KNOWLEDGE_TABLE = "KNOWLEDGE_TABLE";
48     static constexpr const char *SYNC_TABLE = "SYNC_TABLE";
49 };
50 
51 
SetUpTestCase(void)52 void DistributedDBRDBKnowledgeClientTest::SetUpTestCase(void)
53 {
54     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
55     LOGD("Test dir is %s", g_testDir.c_str());
56     g_dbDir = g_testDir + "/";
57     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
58 }
59 
TearDownTestCase(void)60 void DistributedDBRDBKnowledgeClientTest::TearDownTestCase(void)
61 {
62 }
63 
SetUp()64 void DistributedDBRDBKnowledgeClientTest::SetUp()
65 {
66 }
67 
TearDown()68 void DistributedDBRDBKnowledgeClientTest::TearDown()
69 {
70     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
71 }
72 
GetTableSchema(const std::string & table)73 UtTableSchemaInfo DistributedDBRDBKnowledgeClientTest::GetTableSchema(const std::string &table)
74 {
75     UtTableSchemaInfo tableSchema;
76     tableSchema.name = table;
77     UtFieldInfo field;
78     field.field.colName = "id";
79     field.field.type = TYPE_INDEX<int64_t>;
80     field.field.primary = true;
81     tableSchema.fieldInfo.push_back(field);
82     field.field.primary = false;
83     field.field.colName = "int_field1";
84     tableSchema.fieldInfo.push_back(field);
85     field.field.colName = "int_field2";
86     tableSchema.fieldInfo.push_back(field);
87     field.field.colName = "int_field3";
88     tableSchema.fieldInfo.push_back(field);
89     return tableSchema;
90 }
91 
SaveSchemaToMetaTable(sqlite3 * db,const std::string tableName,const TableInfo & tableInfo)92 void DistributedDBRDBKnowledgeClientTest::SaveSchemaToMetaTable(sqlite3 *db, const std::string tableName,
93     const TableInfo &tableInfo)
94 {
95     RelationalSchemaObject schema;
96     schema.SetTableMode(DistributedDB::DistributedTableMode::SPLIT_BY_DEVICE);
97     schema.RemoveRelationalTable(tableName);
98     schema.AddRelationalTable(tableInfo);
99 
100     const Key schemaKey(DBConstant::RELATIONAL_SCHEMA_KEY,
101         DBConstant::RELATIONAL_SCHEMA_KEY + strlen(DBConstant::RELATIONAL_SCHEMA_KEY));
102     Value schemaVal;
103     auto schemaStr = schema.ToSchemaString();
104     EXPECT_FALSE(schemaStr.size() > SchemaConstant::SCHEMA_STRING_SIZE_LIMIT);
105     DBCommon::StringToVector(schemaStr, schemaVal);
106     EXPECT_EQ(SQLiteRelationalUtils::PutKvData(db, false, schemaKey, schemaVal), E_OK);
107 }
108 
CreateDistributedTable(const std::vector<std::string> & tableNames,DistributedDB::TableSyncType tableSyncType)109 void DistributedDBRDBKnowledgeClientTest::CreateDistributedTable(const std::vector<std::string> &tableNames,
110     DistributedDB::TableSyncType tableSyncType)
111 {
112     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
113     EXPECT_NE(db, nullptr);
114     for (const auto &tableName : tableNames) {
115         TableInfo tableInfo;
116         tableInfo.SetTableName(tableName);
117         tableInfo.SetTableSyncType(tableSyncType);
118         TrackerTable table111;
119         tableInfo.SetTrackerTable(table111);
120         DistributedTable distributedTable;
121         distributedTable.tableName = tableName;
122         tableInfo.SetDistributedTable(distributedTable);
123         std::unique_ptr<SqliteLogTableManager> tableManager = std::make_unique<CloudSyncLogTableManager>();
124         EXPECT_NE(tableManager, nullptr);
125         EXPECT_EQ(SQLiteUtils::AnalysisSchema(db, tableName, tableInfo), E_OK);
126         std::vector<FieldInfo> fieldInfos = tableInfo.GetFieldInfos();
127         EXPECT_EQ(SQLiteRelationalUtils::CreateRelationalMetaTable(db), E_OK);
128         EXPECT_EQ(SQLiteRelationalUtils::InitCursorToMeta(db, false, tableName), E_OK);
129         EXPECT_EQ(tableManager->CreateRelationalLogTable(db, tableInfo), E_OK);
130         EXPECT_EQ(tableManager->AddRelationalLogTableTrigger(db, tableInfo, ""), E_OK);
131         SQLiteRelationalUtils::SetLogTriggerStatus(db, true);
132         SaveSchemaToMetaTable(db, tableName, tableInfo);
133     }
134     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
135 }
136 
InsertDBData(const std::string & tableName,int count,sqlite3 * db)137 void InsertDBData(const std::string &tableName, int count, sqlite3 *db)
138 {
139     for (int i = 1; i <= count; i++) {
140         std::string sql = "INSERT INTO " + tableName + " VALUES(" + std::to_string(i) + ',' + std::to_string(i) + ',' +
141             std::to_string(i) + ',' + std::to_string(i) + ");";
142         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
143     }
144 }
145 
146 /**
147  * @tc.name: SetKnowledge001
148  * @tc.desc: Test set knowledge schema.
149  * @tc.type: FUNC
150  * @tc.require:
151  * @tc.author: zqq
152  */
153 HWTEST_F(DistributedDBRDBKnowledgeClientTest, SetKnowledge001, TestSize.Level0)
154 {
155     /**
156      * @tc.steps: step1. Set knowledge source schema and clean deleted data.
157      * @tc.expected: step1. Ok
158      */
159     UtTableSchemaInfo tableInfo = GetTableSchema(KNOWLEDGE_TABLE);
160     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
161     EXPECT_NE(db, nullptr);
162     RDBDataGenerator::InitTableWithSchemaInfo(tableInfo, *db);
163     KnowledgeSourceSchema schema;
164     schema.tableName = KNOWLEDGE_TABLE;
165     schema.extendColNames.insert("id");
166     schema.knowledgeColNames.insert("int_field1");
167     schema.knowledgeColNames.insert("int_field2");
168     EXPECT_EQ(SetKnowledgeSourceSchema(db, schema), OK);
169     EXPECT_EQ(CleanDeletedData(db, schema.tableName, 0u), OK);
170     /**
171      * @tc.steps: step2. Clean deleted data after insert one data.
172      * @tc.expected: step2. Ok
173      */
174     InsertDBData(schema.tableName, 1, db);
175     EXPECT_EQ(CleanDeletedData(db, schema.tableName, 0u), OK);
176     /**
177      * @tc.steps: step3. Clean deleted data after delete one data.
178      * @tc.expected: step3. Ok
179      */
180     std::string sql = std::string("DELETE FROM ").append(KNOWLEDGE_TABLE).append(" WHERE 1=1");
181     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
182     EXPECT_EQ(CleanDeletedData(db, schema.tableName, 10u), OK); // delete which cursor less than 10
183 
184     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
185 }
186 
187 /**
188  * @tc.name: SetKnowledge002
189  * @tc.desc: Test set knowledge schema with invalid args.
190  * @tc.type: FUNC
191  * @tc.require:
192  * @tc.author: zqq
193  */
194 HWTEST_F(DistributedDBRDBKnowledgeClientTest, SetKnowledge002, TestSize.Level0)
195 {
196     /**
197      * @tc.steps: step1. Set knowledge source schema and clean deleted data with null db.
198      * @tc.expected: step1. INVALID_ARGS
199      */
200     KnowledgeSourceSchema schema;
201     schema.tableName = KNOWLEDGE_TABLE;
202     schema.extendColNames.insert("id");
203     schema.knowledgeColNames.insert("int_field1");
204     schema.knowledgeColNames.insert("int_field2");
205     EXPECT_EQ(SetKnowledgeSourceSchema(nullptr, schema), INVALID_ARGS);
206     EXPECT_EQ(CleanDeletedData(nullptr, schema.tableName, 0u), INVALID_ARGS);
207     /**
208      * @tc.steps: step2. Set knowledge source schema and clean deleted data with null db.
209      * @tc.expected: step2. INVALID_ARGS
210      */
211     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
212     ASSERT_NE(db, nullptr);
213     schema.tableName = "UNKNOWN_TABLE";
214     EXPECT_EQ(SetKnowledgeSourceSchema(db, schema), INVALID_ARGS);
215     EXPECT_EQ(CleanDeletedData(db, schema.tableName, 0u), OK);
216 
217     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
218 }
219 
220 /**
221  * @tc.name: SetKnowledge003
222  * @tc.desc: Test set knowledge schema after create distributed table.
223  * @tc.type: FUNC
224  * @tc.require:
225  * @tc.author: zqq
226  */
227 HWTEST_F(DistributedDBRDBKnowledgeClientTest, SetKnowledge003, TestSize.Level0)
228 {
229     /**
230      * @tc.steps: step1. Create distributed table.
231      * @tc.expected: step1. Ok
232      */
233     UtTableSchemaInfo tableInfo1 = GetTableSchema(KNOWLEDGE_TABLE);
234     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
235     EXPECT_NE(db, nullptr);
236     RDBDataGenerator::InitTableWithSchemaInfo(tableInfo1, *db);
237     UtTableSchemaInfo tableInfo2 = GetTableSchema(SYNC_TABLE);
238     RDBDataGenerator::InitTableWithSchemaInfo(tableInfo2, *db);
239     CreateDistributedTable({SYNC_TABLE}, DistributedDB::CLOUD_COOPERATION);
240 
241     /**
242      * @tc.steps: step2. Set knowledge source schema.
243      * @tc.expected: step2. INVALID_ARGS
244      */
245     KnowledgeSourceSchema schema;
246     schema.tableName = KNOWLEDGE_TABLE;
247     schema.extendColNames.insert("id");
248     schema.knowledgeColNames.insert("int_field1");
249     schema.knowledgeColNames.insert("int_field2");
250     schema.tableName = SYNC_TABLE;
251     EXPECT_EQ(SetKnowledgeSourceSchema(db, schema), INVALID_ARGS);
252 
253     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
254 }
255 }
256