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 #include "rdb_general_ut.h"
16 #include "sqlite_relational_utils.h"
17
18 using namespace testing::ext;
19 using namespace DistributedDB;
20 using namespace DistributedDBUnitTest;
21
22 namespace {
23 class DistributedDBRDBUpgradeTest : public RDBGeneralUt {
24 public:
25 void SetUp() override;
26 void TearDown() override;
27 protected:
28 void InitUpgradeDelegate();
29 void InitNoJsonTrackerSchema();
30 static constexpr const char *DEVICE_SYNC_TABLE = "DEVICE_SYNC_TABLE";
31 };
32
SetUp()33 void DistributedDBRDBUpgradeTest::SetUp()
34 {
35 RDBGeneralUt::SetUp();
36 }
37
TearDown()38 void DistributedDBRDBUpgradeTest::TearDown()
39 {
40 RDBGeneralUt::TearDown();
41 }
42
InitUpgradeDelegate()43 void DistributedDBRDBUpgradeTest::InitUpgradeDelegate()
44 {
45 RelationalStoreDelegate::Option option;
46 option.tableMode = DistributedTableMode::COLLABORATION;
47 SetOption(option);
48 auto info1 = GetStoreInfo1();
49 const std::vector<UtFieldInfo> filedInfo = {
50 {{"id", TYPE_INDEX<int64_t>, true, false}, true}, {{"name1", TYPE_INDEX<std::string>, false, true}, false},
51 {{"name2", TYPE_INDEX<std::string>, false, true}, false}
52 };
53 UtDateBaseSchemaInfo schemaInfo = {
54 .tablesInfo = {{.name = DEVICE_SYNC_TABLE, .fieldInfo = filedInfo}}
55 };
56 RDBGeneralUt::SetSchemaInfo(info1, schemaInfo);
57 ASSERT_EQ(BasicUnitTest::InitDelegate(info1, "dev1"), E_OK);
58 }
59
InitNoJsonTrackerSchema()60 void DistributedDBRDBUpgradeTest::InitNoJsonTrackerSchema()
61 {
62 std::string keyStr = "relational_tracker_schema";
63 Key key(keyStr.begin(), keyStr.end());
64 std::string schemaStr = R"({"SCHEMA_TYPE":"TRACKER","TABLES":[
65 {"NAME": "DEVICE_SYNC_TABLE", "EXTEND_NAME": "id",
66 "TRACKER_NAMES": ["id", "name1", "name2"], "TRACKER_ACTION": false}]})";
67 Value value(schemaStr.begin(), schemaStr.end());
68 ASSERT_EQ(PutMetaData(GetStoreInfo1(), key, value), E_OK);
69 }
70
71 /**
72 * @tc.name: UpgradeTracker001
73 * @tc.desc: Test rdb upgrade extend field from no json to json.
74 * @tc.type: FUNC
75 * @tc.author: zqq
76 */
77 HWTEST_F(DistributedDBRDBUpgradeTest, UpgradeTracker001, TestSize.Level0)
78 {
79 /**
80 * @tc.steps: step1. Init delegate and set tracker schema.
81 * @tc.expected: step1. Ok
82 */
83 ASSERT_NO_FATAL_FAILURE(InitUpgradeDelegate());
84 auto info1 = GetStoreInfo1();
85 EXPECT_EQ(SetTrackerTables(info1, {DEVICE_SYNC_TABLE}), E_OK);
86 /**
87 * @tc.steps: step2. Insert local data and log, low version schema.
88 * @tc.expected: step2. Ok
89 */
90 InsertLocalDBData(0, 1, info1);
91 std::string sql = "UPDATE " + DBCommon::GetLogTableName(DEVICE_SYNC_TABLE) + " SET extend_field=1";
92 EXPECT_EQ(ExecuteSQL(sql, info1), E_OK);
93 ASSERT_NO_FATAL_FAILURE(InitNoJsonTrackerSchema());
94 EXPECT_EQ(CloseDelegate(info1), E_OK);
95 ASSERT_NO_FATAL_FAILURE(InitUpgradeDelegate());
96 /**
97 * @tc.steps: step3. Set tracker table and create distributed table.
98 * @tc.expected: step3. Ok
99 */
100 auto store = GetDelegate(info1);
101 ASSERT_NE(store, nullptr);
102 EXPECT_EQ(CreateDistributedTable(info1, DEVICE_SYNC_TABLE), E_OK);
103 EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE),
104 " json_valid(extend_field) = 0"), 0);
105 EXPECT_EQ(SetTrackerTables(info1, {DEVICE_SYNC_TABLE}), E_OK);
106 /**
107 * @tc.steps: step4. Check log extend field.
108 * @tc.expected: step4. Ok
109 */
110 EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE),
111 " json_type(extend_field) = 'object'"), 1);
112 EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE),
113 " json_valid(extend_field) = 0"), 0);
114 }
115
116 /**
117 * @tc.name: UpgradeTracker002
118 * @tc.desc: Test rdb upgrade extend field is no json format.
119 * @tc.type: FUNC
120 * @tc.author: zqq
121 */
122 HWTEST_F(DistributedDBRDBUpgradeTest, UpgradeTracker002, TestSize.Level0)
123 {
124 /**
125 * @tc.steps: step1. Init delegate and set tracker schema.
126 * @tc.expected: step1. Ok
127 */
128 ASSERT_NO_FATAL_FAILURE(InitUpgradeDelegate());
129 auto info1 = GetStoreInfo1();
130 EXPECT_EQ(SetTrackerTables(info1, {DEVICE_SYNC_TABLE}), E_OK);
131 /**
132 * @tc.steps: step2. Insert local data and log update extend_field to empty str.
133 * @tc.expected: step2. Ok
134 */
135 InsertLocalDBData(0, 1, info1);
136 std::string sql = "UPDATE " + DBCommon::GetLogTableName(DEVICE_SYNC_TABLE) + " SET extend_field=''";
137 EXPECT_EQ(ExecuteSQL(sql, info1), E_OK);
138 EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE),
139 " json_valid(extend_field) = 0"), 1);
140 /**
141 * @tc.steps: step3. Set tracker again and check log.
142 * @tc.expected: step3. Ok
143 */
144 EXPECT_EQ(SetTrackerTables(info1, {DEVICE_SYNC_TABLE}), E_OK);
145 EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE),
146 " json_valid(extend_field) = 0"), 0);
147 }
148 }