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 }