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 "rdb_general_ut.h"
17 #include "sqlite_relational_utils.h"
18
19 using namespace testing::ext;
20 using namespace DistributedDB;
21 using namespace DistributedDBUnitTest;
22
23 namespace {
24 class DistributedDBBasicRDBTest : public RDBGeneralUt {
25 public:
26 void SetUp() override;
27 void TearDown() override;
28
29 protected:
30 static constexpr const char *DEVICE_SYNC_TABLE = "DEVICE_SYNC_TABLE";
31 static constexpr const char *CLOUD_SYNC_TABLE = "CLOUD_SYNC_TABLE";
32 };
33
SetUp()34 void DistributedDBBasicRDBTest::SetUp()
35 {
36 RDBGeneralUt::SetUp();
37 }
38
TearDown()39 void DistributedDBBasicRDBTest::TearDown()
40 {
41 RDBGeneralUt::TearDown();
42 }
43
44 /**
45 * @tc.name: InitDelegateExample001
46 * @tc.desc: Test InitDelegate interface of RDBGeneralUt.
47 * @tc.type: FUNC
48 * @tc.require:
49 * @tc.author: suyue
50 */
51 HWTEST_F(DistributedDBBasicRDBTest, InitDelegateExample001, TestSize.Level0)
52 {
53 /**
54 * @tc.steps: step1. Call InitDelegate interface with default data.
55 * @tc.expected: step1. Ok
56 */
57 StoreInfo info1 = {USER_ID, APP_ID, STORE_ID_1};
58 EXPECT_EQ(BasicUnitTest::InitDelegate(info1, "dev1"), E_OK);
59 DataBaseSchema actualSchemaInfo = RDBGeneralUt::GetSchema(info1);
60 ASSERT_EQ(actualSchemaInfo.tables.size(), 2u);
61 EXPECT_EQ(actualSchemaInfo.tables[0].name, g_defaultTable1);
62 EXPECT_EQ(RDBGeneralUt::CloseDelegate(info1), E_OK);
63
64 /**
65 * @tc.steps: step2. Call twice InitDelegate interface with the set data.
66 * @tc.expected: step2. Ok
67 */
68 const std::vector<UtFieldInfo> filedInfo = {
69 {{"id", TYPE_INDEX<int64_t>, true, false}, true}, {{"name", TYPE_INDEX<std::string>, false, true}, false},
70 };
71 UtDateBaseSchemaInfo schemaInfo = {
72 .tablesInfo = {{.name = DEVICE_SYNC_TABLE, .fieldInfo = filedInfo}}
73 };
74 RDBGeneralUt::SetSchemaInfo(info1, schemaInfo);
75 RelationalStoreDelegate::Option option;
76 option.tableMode = DistributedTableMode::COLLABORATION;
77 SetOption(option);
78 EXPECT_EQ(BasicUnitTest::InitDelegate(info1, "dev1"), E_OK);
79
80 StoreInfo info2 = {USER_ID, APP_ID, STORE_ID_2};
81 schemaInfo = {
82 .tablesInfo = {
83 {.name = DEVICE_SYNC_TABLE, .fieldInfo = filedInfo},
84 {.name = CLOUD_SYNC_TABLE, .fieldInfo = filedInfo},
85 }
86 };
87 RDBGeneralUt::SetSchemaInfo(info2, schemaInfo);
88 EXPECT_EQ(BasicUnitTest::InitDelegate(info2, "dev2"), E_OK);
89 actualSchemaInfo = RDBGeneralUt::GetSchema(info2);
90 ASSERT_EQ(actualSchemaInfo.tables.size(), schemaInfo.tablesInfo.size());
91 EXPECT_EQ(actualSchemaInfo.tables[1].name, CLOUD_SYNC_TABLE);
92 TableSchema actualTableInfo = RDBGeneralUt::GetTableSchema(info2, CLOUD_SYNC_TABLE);
93 EXPECT_EQ(actualTableInfo.fields.size(), filedInfo.size());
94 }
95
96 /**
97 * @tc.name: RdbSyncExample001
98 * @tc.desc: Test insert data and sync from dev1 to dev2.
99 * @tc.type: FUNC
100 * @tc.require:
101 * @tc.author: suyue
102 */
103 HWTEST_F(DistributedDBBasicRDBTest, RdbSyncExample001, TestSize.Level0)
104 {
105 /**
106 * @tc.steps: step1. dev1 insert data.
107 * @tc.expected: step1. Ok
108 */
109 RelationalStoreDelegate::Option option;
110 option.tableMode = DistributedTableMode::COLLABORATION;
111 SetOption(option);
112 auto info1 = GetStoreInfo1();
113 ASSERT_EQ(BasicUnitTest::InitDelegate(info1, "dev1"), E_OK);
114 auto info2 = GetStoreInfo2();
115 ASSERT_EQ(BasicUnitTest::InitDelegate(info2, "dev2"), E_OK);
116 InsertLocalDBData(0, 2, info1);
117 EXPECT_EQ(RDBGeneralUt::CountTableData(info1, g_defaultTable1), 2);
118 EXPECT_EQ(RDBGeneralUt::CountTableData(info2, g_defaultTable1), 0);
119
120 /**
121 * @tc.steps: step2. create distributed tables and sync to dev1.
122 * @tc.expected: step2. Ok
123 */
124 ASSERT_EQ(SetDistributedTables(info1, {g_defaultTable1}), E_OK);
125 ASSERT_EQ(SetDistributedTables(info2, {g_defaultTable1}), E_OK);
126 BlockPush(info1, info2, g_defaultTable1);
127 EXPECT_EQ(RDBGeneralUt::CountTableData(info1, g_defaultTable1), 2);
128 EXPECT_EQ(RDBGeneralUt::CountTableData(info2, g_defaultTable1), 2);
129
130 /**
131 * @tc.steps: step3. update name and sync to dev1.
132 * @tc.expected: step3. Ok
133 */
134 std::string sql = "UPDATE " + g_defaultTable1 + " SET name='update'";
135 EXPECT_EQ(ExecuteSQL(sql, info1), E_OK);
136 ASSERT_NO_FATAL_FAILURE(BlockPush(info1, info2, g_defaultTable1));
137 EXPECT_EQ(RDBGeneralUt::CountTableData(info2, g_defaultTable1, "name='update'"), 2);
138 }
139
140 #ifdef USE_DISTRIBUTEDDB_CLOUD
141 /**
142 * @tc.name: RdbCloudSyncExample001
143 * @tc.desc: Test cloud sync.
144 * @tc.type: FUNC
145 * @tc.require:
146 * @tc.author: suyue
147 */
148 HWTEST_F(DistributedDBBasicRDBTest, RdbCloudSyncExample001, TestSize.Level0)
149 {
150 /**
151 * @tc.steps: step1. sync dev1 data to cloud.
152 * @tc.expected: step1. Ok
153 */
154 RelationalStoreDelegate::Option option;
155 option.tableMode = DistributedTableMode::COLLABORATION;
156 SetOption(option);
157 auto info1 = GetStoreInfo1();
158 ASSERT_EQ(BasicUnitTest::InitDelegate(info1, "dev1"), E_OK);
159 InsertLocalDBData(0, 2, info1);
160 EXPECT_EQ(RDBGeneralUt::CountTableData(info1, g_defaultTable1), 2);
161
162 ASSERT_EQ(SetDistributedTables(info1, {g_defaultTable1}, TableSyncType::CLOUD_COOPERATION), E_OK);
163 RDBGeneralUt::SetCloudDbConfig(info1);
164 Query query = Query::Select().FromTable({g_defaultTable1});
165 RDBGeneralUt::CloudBlockSync(info1, query);
166 EXPECT_EQ(RDBGeneralUt::GetCloudDataCount(g_defaultTable1), 2);
167 }
168
169 /**
170 * @tc.name: RdbCloudSyncExample002
171 * @tc.desc: Test cloud insert data and cloud sync.
172 * @tc.type: FUNC
173 * @tc.require:
174 * @tc.author: suyue
175 */
176 HWTEST_F(DistributedDBBasicRDBTest, RdbCloudSyncExample002, TestSize.Level0)
177 {
178 /**
179 * @tc.steps: step1. cloud insert data.
180 * @tc.expected: step1. Ok
181 */
182 RelationalStoreDelegate::Option option;
183 option.tableMode = DistributedTableMode::COLLABORATION;
184 SetOption(option);
185 auto info1 = GetStoreInfo1();
186 ASSERT_EQ(BasicUnitTest::InitDelegate(info1, "dev1"), E_OK);
187 ASSERT_EQ(SetDistributedTables(info1, {g_defaultTable1}, TableSyncType::CLOUD_COOPERATION), E_OK);
188 RDBGeneralUt::SetCloudDbConfig(info1);
189 std::shared_ptr<VirtualCloudDb> virtualCloudDb = RDBGeneralUt::GetVirtualCloudDb();
190 ASSERT_NE(virtualCloudDb, nullptr);
191 EXPECT_EQ(RDBDataGenerator::InsertCloudDBData(0, 20, 0, RDBGeneralUt::GetSchema(info1), virtualCloudDb), OK);
192 EXPECT_EQ(RDBGeneralUt::GetCloudDataCount(g_defaultTable1), 20);
193 EXPECT_EQ(RDBGeneralUt::CountTableData(info1, g_defaultTable1), 0);
194
195 /**
196 * @tc.steps: step2. cloud sync data to dev1.
197 * @tc.expected: step2. Ok
198 */
199 Query query = Query::Select().FromTable({g_defaultTable1});
200 RDBGeneralUt::CloudBlockSync(info1, query);
201 EXPECT_EQ(RDBGeneralUt::CountTableData(info1, g_defaultTable1), 20);
202 }
203 #endif // USE_DISTRIBUTEDDB_CLOUD
204
205 /**
206 * @tc.name: RdbUtilsTest001
207 * @tc.desc: Test rdb utils execute actions.
208 * @tc.type: FUNC
209 * @tc.author: zqq
210 */
211 HWTEST_F(DistributedDBBasicRDBTest, RdbUtilsTest001, TestSize.Level0)
212 {
213 std::vector<std::function<int()>> actions;
214 /**
215 * @tc.steps: step1. execute null actions no effect ret.
216 * @tc.expected: step1. E_OK
217 */
218 actions.emplace_back(nullptr);
219 EXPECT_EQ(SQLiteRelationalUtils::ExecuteListAction(actions), E_OK);
220 /**
221 * @tc.steps: step2. execute abort when action return error.
222 * @tc.expected: step2. -E_INVALID_ARGS
223 */
224 actions.clear();
__anonbd0e6c290202() 225 actions.emplace_back([]() {
226 return -E_INVALID_ARGS;
227 });
__anonbd0e6c290302() 228 actions.emplace_back([]() {
229 return -E_NOT_SUPPORT;
230 });
231 EXPECT_EQ(SQLiteRelationalUtils::ExecuteListAction(actions), -E_INVALID_ARGS);
232 }
233 }