1 /*
2 * Copyright (c) 2024 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 <gtest/gtest.h>
16
17 #include "db_constant.h"
18 #include "db_common.h"
19 #include "distributeddb_tools_unit_test.h"
20 #include "meta_data.h"
21 #include "virtual_single_ver_sync_db_Interface.h"
22
23 using namespace testing::ext;
24 using namespace testing;
25 using namespace DistributedDB;
26 using namespace DistributedDBUnitTest;
27
28 namespace {
29 constexpr const char *DEVICE_A = "deviceA";
30 constexpr const char *DEVICE_B = "deviceB";
31 class DistributedDBMetaDataTest : public testing::Test {
32 public:
33 static void SetUpTestCase();
34 static void TearDownTestCase();
35 void SetUp();
36 void TearDown();
37 void GetMetaDataValue(const std::string &hashDeviceId, MetaDataValue &metaDataValue);
38 void PutMetaDataValue(const std::string &hashDeviceId, MetaDataValue &metaDataValue);
39 protected:
40 std::shared_ptr<Metadata> metadata_ = nullptr;
41 VirtualSingleVerSyncDBInterface *storage_ = nullptr;
42 };
43
SetUpTestCase()44 void DistributedDBMetaDataTest::SetUpTestCase()
45 {
46 }
47
TearDownTestCase()48 void DistributedDBMetaDataTest::TearDownTestCase()
49 {
50 }
51
SetUp()52 void DistributedDBMetaDataTest::SetUp()
53 {
54 DistributedDBToolsUnitTest::PrintTestCaseInfo();
55 metadata_ = std::make_shared<Metadata>();
56 ASSERT_NE(metadata_, nullptr);
57 storage_ = new(std::nothrow) VirtualSingleVerSyncDBInterface();
58 ASSERT_NE(storage_, nullptr);
59 metadata_->Initialize(storage_);
60 }
61
TearDown()62 void DistributedDBMetaDataTest::TearDown()
63 {
64 metadata_ = nullptr;
65 if (storage_ != nullptr) {
66 delete storage_;
67 storage_ = nullptr;
68 }
69 }
70
GetMetaDataValue(const std::string & hashDeviceId,MetaDataValue & metaDataValue)71 void DistributedDBMetaDataTest::GetMetaDataValue(const std::string &hashDeviceId, MetaDataValue &metaDataValue)
72 {
73 Key key;
74 DBCommon::StringToVector(hashDeviceId, key);
75 Value value;
76 int errCode = storage_->GetMetaData(key, value);
77 if (errCode == -E_NOT_FOUND) {
78 return;
79 }
80 EXPECT_EQ(errCode, E_OK);
81 EXPECT_EQ(memcpy_s(&metaDataValue, sizeof(MetaDataValue), value.data(), value.size()), EOK);
82 }
83
PutMetaDataValue(const std::string & hashDeviceId,MetaDataValue & metaDataValue)84 void DistributedDBMetaDataTest::PutMetaDataValue(const std::string &hashDeviceId, MetaDataValue &metaDataValue)
85 {
86 Key key;
87 DBCommon::StringToVector(hashDeviceId, key);
88 Value value;
89 value.resize(sizeof(MetaDataValue));
90 EXPECT_EQ(memcpy_s(value.data(), value.size(), &metaDataValue, sizeof(MetaDataValue)), EOK);
91 EXPECT_EQ(storage_->PutMetaData(key, value, false), E_OK);
92 }
93
94 /**
95 * @tc.name: MetadataTest001
96 * @tc.desc: Test metadata set and get ability sync mark.
97 * @tc.type: FUNC
98 * @tc.require:
99 * @tc.author: zhangqiquan
100 */
101 HWTEST_F(DistributedDBMetaDataTest, MetadataTest001, TestSize.Level0)
102 {
103 /**
104 * @tc.steps: step1. Check ability sync finish before set mark.
105 * @tc.expected: step1. Default all ability sync finish is false.
106 */
107 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_A));
108 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_B));
109 /**
110 * @tc.steps: step2. Set A ability sync finish.
111 * @tc.expected: step2. A is finish B is not finish.
112 */
113 EXPECT_EQ(metadata_->SetAbilitySyncFinishMark(DEVICE_A, true), E_OK);
114 EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_A));
115 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_B));
116 /**
117 * @tc.steps: step3. Set B ability sync finish.
118 * @tc.expected: step3. A and B is finish.
119 */
120 EXPECT_EQ(metadata_->SetAbilitySyncFinishMark(DEVICE_B, true), E_OK);
121 EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_A));
122 EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_B));
123 /**
124 * @tc.steps: step4. Set A ability sync not finish.
125 * @tc.expected: step4. A is not finish B is finish.
126 */
127 EXPECT_EQ(metadata_->SetAbilitySyncFinishMark(DEVICE_A, false), E_OK);
128 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_A));
129 EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_B));
130 /**
131 * @tc.steps: step5. Clear all time sync finish.
132 * @tc.expected: step5. A and B is finish.
133 */
134 EXPECT_EQ(metadata_->ClearAllTimeSyncFinishMark(), E_OK);
135 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_A));
136 EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_B));
137 /**
138 * @tc.steps: step6. Clear all ability sync finish.
139 * @tc.expected: step6. A and B is not finish.
140 */
141 EXPECT_EQ(metadata_->ClearAllAbilitySyncFinishMark(), E_OK);
142 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_A));
143 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_B));
144 }
145
146 /**
147 * @tc.name: MetadataTest002
148 * @tc.desc: Test metadata set and get time sync mark.
149 * @tc.type: FUNC
150 * @tc.require:
151 * @tc.author: zhangqiquan
152 */
153 HWTEST_F(DistributedDBMetaDataTest, MetadataTest002, TestSize.Level0)
154 {
155 /**
156 * @tc.steps: step1. Check time sync finish before set mark.
157 * @tc.expected: step1. Default all time sync finish is false.
158 */
159 EXPECT_FALSE(metadata_->IsTimeSyncFinish(DEVICE_A));
160 EXPECT_FALSE(metadata_->IsTimeSyncFinish(DEVICE_B));
161 /**
162 * @tc.steps: step2. Set A time sync finish.
163 * @tc.expected: step2. A is finish B is not finish.
164 */
165 EXPECT_EQ(metadata_->SetTimeSyncFinishMark(DEVICE_A, true), E_OK);
166 EXPECT_TRUE(metadata_->IsTimeSyncFinish(DEVICE_A));
167 EXPECT_FALSE(metadata_->IsTimeSyncFinish(DEVICE_B));
168 /**
169 * @tc.steps: step3. Set B time sync finish.
170 * @tc.expected: step3. A and B is finish.
171 */
172 EXPECT_EQ(metadata_->SetTimeSyncFinishMark(DEVICE_B, true), E_OK);
173 EXPECT_TRUE(metadata_->IsTimeSyncFinish(DEVICE_A));
174 EXPECT_TRUE(metadata_->IsTimeSyncFinish(DEVICE_B));
175 /**
176 * @tc.steps: step4. Set A time sync not finish.
177 * @tc.expected: step4. A is not finish B is finish.
178 */
179 EXPECT_EQ(metadata_->SetTimeSyncFinishMark(DEVICE_A, false), E_OK);
180 EXPECT_FALSE(metadata_->IsTimeSyncFinish(DEVICE_A));
181 EXPECT_TRUE(metadata_->IsTimeSyncFinish(DEVICE_B));
182 /**
183 * @tc.steps: step5. Clear all time sync finish.
184 * @tc.expected: step5. A and B is not finish.
185 */
186 EXPECT_EQ(metadata_->ClearAllTimeSyncFinishMark(), E_OK);
187 EXPECT_FALSE(metadata_->IsTimeSyncFinish(DEVICE_A));
188 EXPECT_FALSE(metadata_->IsTimeSyncFinish(DEVICE_B));
189 }
190
191 /**
192 * @tc.name: MetadataTest003
193 * @tc.desc: Test metadata set remote schema version.
194 * @tc.type: FUNC
195 * @tc.require:
196 * @tc.author: zhangqiquan
197 */
198 HWTEST_F(DistributedDBMetaDataTest, MetadataTest003, TestSize.Level0)
199 {
200 /**
201 * @tc.steps: step1. Check remote schema version before set version.
202 * @tc.expected: step1. Default all version is zero.
203 */
204 EXPECT_EQ(metadata_->GetRemoteSchemaVersion(DEVICE_A), 0u);
205 EXPECT_EQ(metadata_->GetRemoteSchemaVersion(DEVICE_B), 0u);
206 /**
207 * @tc.steps: step2. Set A schema version.
208 * @tc.expected: step2. A is finish B is not finish.
209 */
210 EXPECT_EQ(metadata_->SetRemoteSchemaVersion(DEVICE_A, SOFTWARE_VERSION_CURRENT), E_OK);
211 EXPECT_EQ(metadata_->GetRemoteSchemaVersion(DEVICE_A), SOFTWARE_VERSION_CURRENT);
212 EXPECT_EQ(metadata_->GetRemoteSchemaVersion(DEVICE_B), 0u);
213 /**
214 * @tc.steps: step3. Clear all ability sync finish.
215 * @tc.expected: step3. A and B version is zero.
216 */
217 EXPECT_EQ(metadata_->ClearAllAbilitySyncFinishMark(), E_OK);
218 EXPECT_EQ(metadata_->GetRemoteSchemaVersion(DEVICE_A), 0u);
219 EXPECT_EQ(metadata_->GetRemoteSchemaVersion(DEVICE_B), 0u);
220 }
221
222 /**
223 * @tc.name: MetadataTest004
224 * @tc.desc: Test metadata set remote system time off set.
225 * @tc.type: FUNC
226 * @tc.require:
227 * @tc.author: zhangqiquan
228 */
229 HWTEST_F(DistributedDBMetaDataTest, MetadataTest004, TestSize.Level0)
230 {
231 /**
232 * @tc.steps: step1. Check remote schema version before set version.
233 * @tc.expected: step1. Default all version is zero.
234 */
235 EXPECT_EQ(metadata_->GetSystemTimeOffset(DEVICE_A), 0u);
236 EXPECT_EQ(metadata_->GetSystemTimeOffset(DEVICE_B), 0u);
237 /**
238 * @tc.steps: step2. Set A schema version.
239 * @tc.expected: step2. A is finish B is not finish.
240 */
241 const int64_t offset = 100u;
242 EXPECT_EQ(metadata_->SetSystemTimeOffset(DEVICE_A, offset), E_OK);
243 EXPECT_EQ(metadata_->GetSystemTimeOffset(DEVICE_A), offset);
244 EXPECT_EQ(metadata_->GetSystemTimeOffset(DEVICE_B), 0u);
245 /**
246 * @tc.steps: step3. Clear all time sync finish.
247 * @tc.expected: step3. A and B system time offset is zero.
248 */
249 EXPECT_EQ(metadata_->ClearAllTimeSyncFinishMark(), E_OK);
250 EXPECT_EQ(metadata_->GetSystemTimeOffset(DEVICE_A), 0u);
251 EXPECT_EQ(metadata_->GetSystemTimeOffset(DEVICE_B), 0u);
252 }
253
254 /**
255 * @tc.name: MetadataTest005
256 * @tc.desc: Test metadata set local schema version.
257 * @tc.type: FUNC
258 * @tc.require:
259 * @tc.author: zhangqiquan
260 */
261 HWTEST_F(DistributedDBMetaDataTest, MetadataTest005, TestSize.Level0)
262 {
263 /**
264 * @tc.steps: step1. Check local schema version before set version.
265 * @tc.expected: step1. Default all version is zero.
266 */
267 auto res = metadata_->GetLocalSchemaVersion();
268 EXPECT_EQ(res.first, E_OK);
269 EXPECT_NE(res.second, 0u);
270 /**
271 * @tc.steps: step2. Set local schema version.
272 * @tc.expected: step2. set success.
273 */
274 EXPECT_EQ(metadata_->SetLocalSchemaVersion(SOFTWARE_VERSION_CURRENT), E_OK);
275 res = metadata_->GetLocalSchemaVersion();
276 EXPECT_EQ(res.first, E_OK);
277 EXPECT_EQ(res.second, SOFTWARE_VERSION_CURRENT);
278 }
279
280 /**
281 * @tc.name: MetadataTest006
282 * @tc.desc: Test metadata remove device data with reload.
283 * @tc.type: FUNC
284 * @tc.require:
285 * @tc.author: zhangqiquan
286 */
287 HWTEST_F(DistributedDBMetaDataTest, MetadataTest006, TestSize.Level0)
288 {
289 /**
290 * @tc.steps: step1. Set storage ability sync finish.
291 * @tc.expected: step1. A is finish.
292 */
293 std::string hashDeviceId = DBConstant::DEVICEID_PREFIX_KEY + DBCommon::TransferHashString(DEVICE_A);
294 MetaDataValue metaDataValue;
295 GetMetaDataValue(hashDeviceId, metaDataValue);
296 EXPECT_EQ(metaDataValue.syncMark & static_cast<uint64_t>(SyncMark::SYNC_MARK_ABILITY_SYNC), 0u);
297 metaDataValue.syncMark = static_cast<uint64_t>(SyncMark::SYNC_MARK_ABILITY_SYNC);
298 PutMetaDataValue(hashDeviceId, metaDataValue);
299 /**
300 * @tc.steps: step2. Check ability sync finish by meta.
301 * @tc.expected: step2. A is not finish because of cached.
302 */
303 EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_A));
304 /**
305 * @tc.steps: step3. Erase water mark and check again.
306 * @tc.expected: step3. A is finish because reload cache.
307 */
308 EXPECT_EQ(metadata_->EraseDeviceWaterMark(DEVICE_A, true), E_OK);
309 EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_A));
310 }
311
312 /**
313 * @tc.name: MetadataTest007
314 * @tc.desc: Test metadata init with time change if need.
315 * @tc.type: FUNC
316 * @tc.require:
317 * @tc.author: zhangqiquan
318 */
319 HWTEST_F(DistributedDBMetaDataTest, MetadataTest007, TestSize.Level0)
320 {
321 /**
322 * @tc.steps: step1. Check time sync finish by meta.
323 * @tc.expected: step1. B is change because of time change.
324 */
325 RuntimeContext::GetInstance()->SetTimeChanged(true);
326 EXPECT_TRUE(metadata_->IsTimeChange(DEVICE_B));
327 RuntimeContext::GetInstance()->SetTimeChanged(false);
328 RuntimeContext::GetInstance()->StopTimeTickMonitorIfNeed();
329 }
330 }