1 /*
2  * Copyright (c) 2021 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 #ifndef OMIT_MULTI_VER
16 #include <gtest/gtest.h>
17 
18 #include "db_errno.h"
19 #include "default_factory.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "ikvdb_factory.h"
22 
23 using namespace testing::ext;
24 using namespace DistributedDB;
25 using namespace DistributedDBUnitTest;
26 using namespace std;
27 
28 namespace {
29     IKvDBCommitStorage::Property g_prop;
30     IKvDBCommitStorage *g_commitStorage = nullptr;
31     bool g_createFactory = false;
32     Version g_defaultCommitVer1 = 1;
33     Version g_defaultCommitVer2 = 2;
34     Version g_defaultCommitVer3 = 3;
35     Version g_defaultCommitVer4 = 4;
36     Version g_defaultCommitVer5 = 5;
37     Version g_defaultCommitVer6 = 6;
38     Version g_defaultCommitVer7 = 7;
39     Version g_defaultCommitVer8 = 8;
40     Version g_defaultCommitVer9 = 9;
41     Version g_defaultCommitVer10 = 10;
42     Version g_defaultCommitVer11 = 11;
43     Version g_defaultCommitVer12 = 12;
44     string g_defaultCommitID0 = "";
45     string g_defaultCommitID1 = "commit_ID_1";
46     string g_defaultCommitID2 = "commit_ID_2";
47     string g_defaultCommitID3 = "commit_ID_3";
48     string g_defaultCommitID4 = "commit_ID_4";
49     string g_defaultCommitID5 = "commit_ID_5";
50     string g_defaultCommitID6 = "commit_ID_6";
51     string g_defaultCommitID7 = "commit_ID_7";
52     string g_defaultCommitID8 = "commit_ID_8";
53     string g_defaultCommitID9 = "commit_ID_9";
54     string g_defaultCommitID10 = "commit_ID_10";
55     string g_defaultCommitID11 = "commit_ID_11";
56     string g_defaultCommitID12 = "commit_ID_12";
57     string g_defaultCommitID13 = "commit_ID_13";
58     string g_defaultCommitID14 = "commit_ID_14";
59     DeviceID g_localDevice = "local";
60     DeviceID g_remoteDeviceA = "remote_device_A";
61     DeviceID g_remoteDeviceB = "remote_device_B";
62     DeviceID g_remoteDeviceC = "remote_device_C";
63     DeviceID g_remoteDeviceD = "remote_device_D";
64     const Timestamp TIME_STAMP1 = 100;
65     const Timestamp TIME_STAMP2 = 200;
66     const Timestamp TIME_STAMP3 = 300;
67     const Timestamp TIME_STAMP4 = 400;
68     const Timestamp TIME_STAMP5 = 500;
69     const Timestamp TIME_STAMP6 = 600;
70     const Timestamp TIME_STAMP7 = 700;
71     const Timestamp TIME_STAMP8 = 800;
72     const Timestamp TIME_STAMP9 = 900;
73     const Timestamp TIME_STAMP10 = 1000;
74     const Timestamp TIME_STAMP11 = 1100;
75     const Timestamp TIME_STAMP12 = 1200;
76 
77     struct CommitInfo {
78         Version version;
79         string commitID;
80         string leftCommitID;
81         string rightCommitID;
82         Timestamp timestamp;
83         bool localFlag;
84         DeviceID deviceInfo;
85     };
86 
TransCommitIDToStr(const CommitID & inputCommitID)87     string TransCommitIDToStr(const CommitID &inputCommitID)
88     {
89         string commitIDStr = "";
90         if (inputCommitID.size() != 0) {
91             commitIDStr.resize(inputCommitID.size());
92             commitIDStr.assign(inputCommitID.begin(), inputCommitID.end());
93         }
94         return commitIDStr;
95     }
96 
CompareCommitWithExpectation(const IKvDBCommit * commit,const CommitInfo & commitInfo)97     void CompareCommitWithExpectation(const IKvDBCommit *commit, const CommitInfo &commitInfo)
98     {
99         Version versionInfo = commit->GetCommitVersion();
100         ASSERT_EQ(versionInfo, commitInfo.version);
101         CommitID commitID = commit->GetCommitId();
102         string commitIDStr = TransCommitIDToStr(commitID);
103         ASSERT_STREQ(commitIDStr.c_str(), commitInfo.commitID.c_str());
104         CommitID leftCommitID = commit->GetLeftParentId();
105         string leftCommitIDStr = TransCommitIDToStr(leftCommitID);
106         ASSERT_STREQ(leftCommitIDStr.c_str(), commitInfo.leftCommitID.c_str());
107         CommitID rightCommitID = commit->GetRightParentId();
108         string rightCommitIDStr = TransCommitIDToStr(rightCommitID);
109         ASSERT_STREQ(rightCommitIDStr.c_str(), commitInfo.rightCommitID.c_str());
110         Timestamp timestamp = commit->GetTimestamp();
111         ASSERT_EQ(timestamp, commitInfo.timestamp);
112         bool localFlag = commit->GetLocalFlag();
113         ASSERT_EQ(localFlag, commitInfo.localFlag);
114         DeviceID deviceInfo = commit->GetDeviceInfo();
115         ASSERT_EQ(deviceInfo == commitInfo.deviceInfo, true);
116     }
117 
TestLatestCommitOfDevice(const std::map<DeviceID,IKvDBCommit * > & latestCommits,const DeviceID & deviceInfo,const CommitInfo & expectCommitInfo)118     void TestLatestCommitOfDevice(const std::map<DeviceID, IKvDBCommit*> &latestCommits,
119         const DeviceID &deviceInfo, const CommitInfo &expectCommitInfo)
120     {
121         auto latestCommit = latestCommits.find(deviceInfo);
122         ASSERT_EQ(latestCommit != latestCommits.end(), true);
123         CompareCommitWithExpectation(latestCommit->second, expectCommitInfo);
124     }
125 
TransStrToCommitID(const string & commitIDStr)126     CommitID TransStrToCommitID(const string &commitIDStr)
127     {
128         CommitID commitID;
129         commitID.resize(commitIDStr.size());
130         if (commitIDStr.size() != 0) {
131             commitID.assign(commitIDStr.begin(), commitIDStr.end());
132         }
133         return commitID;
134     }
135 
InsertCommitToCommitStorage(const CommitInfo & commitInfo,int expectedResult)136     void InsertCommitToCommitStorage(const CommitInfo &commitInfo, int expectedResult)
137     {
138         int result;
139         IKvDBCommit *commit = g_commitStorage->AllocCommit(result);
140         ASSERT_EQ(result, E_OK);
141         ASSERT_NE(commit, nullptr);
142         if (result != E_OK || commit == nullptr) {
143             return;
144         }
145         CommitID commitID = TransStrToCommitID(commitInfo.commitID);
146         CommitID leftCommitID = TransStrToCommitID(commitInfo.leftCommitID);
147         CommitID rightCommitID = TransStrToCommitID(commitInfo.rightCommitID);
148         commit->SetCommitVersion(commitInfo.version);
149         commit->SetLeftParentId(leftCommitID);
150         commit->SetRightParentId(rightCommitID);
151         commit->SetCommitId(commitID);
152         commit->SetTimestamp(commitInfo.timestamp);
153         commit->SetLocalFlag(commitInfo.localFlag);
154         commit->SetDeviceInfo(commitInfo.deviceInfo);
155         result = g_commitStorage->AddCommit(*commit, false);
156         ASSERT_EQ(result, expectedResult);
157         g_commitStorage->ReleaseCommit(commit);
158         commit = nullptr;
159     }
160 
DeleteCommit(const string & inputCommitID,int expectedResult)161     void DeleteCommit(const string &inputCommitID, int expectedResult)
162     {
163         CommitID commitID = TransStrToCommitID(inputCommitID);
164         int result = g_commitStorage->RemoveCommit(commitID);
165         ASSERT_EQ(result, expectedResult);
166     }
167 
TestCommit(const CommitInfo & commitInfo,int expectedResult)168     void TestCommit(const CommitInfo &commitInfo, int expectedResult)
169     {
170         int result;
171         CommitID inputCommitID = TransStrToCommitID(commitInfo.commitID);
172         IKvDBCommit *commit = g_commitStorage->GetCommit(inputCommitID, result);
173         ASSERT_EQ(result, expectedResult);
174         if (expectedResult == E_OK) {
175             ASSERT_NE(commit, nullptr);
176         } else {
177             ASSERT_EQ(commit, nullptr);
178         }
179         if (result != E_OK || commit == nullptr) {
180             return;
181         }
182         CompareCommitWithExpectation(commit, commitInfo);
183         g_commitStorage->ReleaseCommit(commit);
184         commit = nullptr;
185     }
186 
SetCommitStorageHeader(const string & inputHeader,int expectedResult)187     void SetCommitStorageHeader(const string &inputHeader, int expectedResult)
188     {
189         CommitID header = TransStrToCommitID(inputHeader);
190         int result = g_commitStorage->SetHeader(header);
191         ASSERT_EQ(result, expectedResult);
192     }
193 
TestCommitStorageHeader(const string & expectedHeader)194     void TestCommitStorageHeader(const string &expectedHeader)
195     {
196         int errCode = E_OK;
197         CommitID header = g_commitStorage->GetHeader(errCode);
198         string headerStr = TransCommitIDToStr(header);
199         ASSERT_STREQ(headerStr.c_str(), expectedHeader.c_str());
200     }
201 
202     /*
203     * commit tree is as below:
204     * L A B C D
205     * 1 2 4 8 d
206     * |/|/| |
207     * 3 / | 9
208     * |X| |/|
209     * 5 6 a e
210     * |/|/
211     * 7 b
212     * |/
213     * c
214     */
PrepareCommitTree()215     void PrepareCommitTree()
216     {
217         CommitInfo commitInfo1 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
218             TIME_STAMP1, true, g_localDevice};
219         CommitInfo commitInfo2 = {g_defaultCommitVer2, g_defaultCommitID2, g_defaultCommitID0, g_defaultCommitID0,
220             TIME_STAMP2, false, g_remoteDeviceA};
221         CommitInfo commitInfo3 = {g_defaultCommitVer3, g_defaultCommitID3, g_defaultCommitID1, g_defaultCommitID2,
222             TIME_STAMP3, true, g_localDevice};
223         CommitInfo commitInfo4 = {g_defaultCommitVer4, g_defaultCommitID4, g_defaultCommitID0, g_defaultCommitID0,
224             TIME_STAMP4, false, g_remoteDeviceB};
225         CommitInfo commitInfo5 = {g_defaultCommitVer5, g_defaultCommitID5, g_defaultCommitID3, g_defaultCommitID4,
226             TIME_STAMP5, true, g_localDevice};
227         CommitInfo commitInfo6 = {g_defaultCommitVer6, g_defaultCommitID6, g_defaultCommitID2, g_defaultCommitID3,
228             TIME_STAMP6, false, g_remoteDeviceA};
229         CommitInfo commitInfo7 = {g_defaultCommitVer7, g_defaultCommitID7, g_defaultCommitID5, g_defaultCommitID6,
230             TIME_STAMP7, true, g_localDevice};
231         CommitInfo commitInfo8 = {g_defaultCommitVer8, g_defaultCommitID8, g_defaultCommitID0, g_defaultCommitID0,
232             TIME_STAMP8, false, g_remoteDeviceC};
233         CommitInfo commitInfo9 = {g_defaultCommitVer9, g_defaultCommitID9, g_defaultCommitID8, g_defaultCommitID0,
234             TIME_STAMP9, false, g_remoteDeviceC};
235         CommitInfo commitInfo10 = {g_defaultCommitVer10, g_defaultCommitID10, g_defaultCommitID4, g_defaultCommitID9,
236             TIME_STAMP10, false, g_remoteDeviceB};
237         CommitInfo commitInfo11 = {g_defaultCommitVer11, g_defaultCommitID11, g_defaultCommitID6, g_defaultCommitID10,
238             TIME_STAMP11, false, g_remoteDeviceA};
239         CommitInfo commitInfo12 = {g_defaultCommitVer12, g_defaultCommitID12, g_defaultCommitID7, g_defaultCommitID11,
240             TIME_STAMP12, true, g_localDevice};
241         InsertCommitToCommitStorage(commitInfo1, E_OK);
242         InsertCommitToCommitStorage(commitInfo2, E_OK);
243         InsertCommitToCommitStorage(commitInfo3, E_OK);
244         InsertCommitToCommitStorage(commitInfo4, E_OK);
245         InsertCommitToCommitStorage(commitInfo5, E_OK);
246         InsertCommitToCommitStorage(commitInfo6, E_OK);
247         InsertCommitToCommitStorage(commitInfo7, E_OK);
248         InsertCommitToCommitStorage(commitInfo8, E_OK);
249         InsertCommitToCommitStorage(commitInfo9, E_OK);
250         InsertCommitToCommitStorage(commitInfo10, E_OK);
251         InsertCommitToCommitStorage(commitInfo11, E_OK);
252         InsertCommitToCommitStorage(commitInfo12, E_OK);
253         SetCommitStorageHeader(g_defaultCommitID12, E_OK);
254     }
255 }
256 
257 class DistributedDBStorageCommitStorageTest : public testing::Test {
258 public:
259     static void SetUpTestCase(void);
260     static void TearDownTestCase(void);
261     void SetUp();
262     void TearDown();
263 };
264 
SetUpTestCase(void)265 void DistributedDBStorageCommitStorageTest::SetUpTestCase(void)
266 {
267     DistributedDBToolsUnitTest::TestDirInit(g_prop.path);
268     g_prop.isNeedCreate = true;
269     if (IKvDBFactory::GetCurrent() == nullptr) {
270         IKvDBFactory *factory = new (std::nothrow) DefaultFactory();
271         ASSERT_NE(factory, nullptr);
272         if (factory == nullptr) {
273             LOGE("failed to new DefaultFactory!");
274             return;
275         }
276         IKvDBFactory::Register(factory);
277         g_createFactory = true;
278     }
279 }
280 
TearDownTestCase(void)281 void DistributedDBStorageCommitStorageTest::TearDownTestCase(void)
282 {
283     if (g_createFactory) {
284         if (IKvDBFactory::GetCurrent() != nullptr) {
285             delete IKvDBFactory::GetCurrent();
286             IKvDBFactory::Register(nullptr);
287         }
288     }
289     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_prop.path) != 0) {
290         LOGE("rm test db files error!");
291     }
292 }
293 
SetUp(void)294 void DistributedDBStorageCommitStorageTest::SetUp(void)
295 {
296     DistributedDBToolsUnitTest::PrintTestCaseInfo();
297     IKvDBFactory *factory = IKvDBFactory::GetCurrent();
298     ASSERT_NE(factory, nullptr);
299     if (factory == nullptr) {
300         LOGE("failed to get DefaultFactory!");
301         return;
302     }
303     int result;
304     g_commitStorage = factory->CreateMultiVerCommitStorage(result);
305     ASSERT_EQ(result, E_OK);
306     ASSERT_NE(g_commitStorage, nullptr);
307     if (g_commitStorage == nullptr) {
308         return;
309     }
310 
311     int errCode = g_commitStorage->Open(g_prop);
312     ASSERT_EQ(errCode, E_OK);
313     if (errCode != E_OK) {
314         delete g_commitStorage;
315         g_commitStorage = nullptr;
316         return;
317     }
318 }
319 
TearDown(void)320 void DistributedDBStorageCommitStorageTest::TearDown(void)
321 {
322     if (g_commitStorage != nullptr) {
323         (void)g_commitStorage->Remove(g_prop);
324         delete g_commitStorage;
325         g_commitStorage = nullptr;
326     }
327 }
328 
329 /**
330   * @tc.name: MultiVerCommitStorage001
331   * @tc.desc: Open a commit storage when it has been opened.
332   * @tc.type: FUNC
333   * @tc.require: AR000C6TRV AR000CQDTM
334   * @tc.author: liujialei
335   */
336 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage001, TestSize.Level1)
337 {
338     /**
339      * @tc.steps:step1/2. Open commit log database
340      * @tc.expected: step1/2. Return OK.
341      */
342     int result = g_commitStorage->Open(g_prop);
343     ASSERT_EQ(result, E_OK);
344     return;
345 }
346 
347 /**
348   * @tc.name: MultiVerCommitStorage002
349   * @tc.desc: Remove a commit storage database, then try to add, delete and query commit, set and get header.
350   * @tc.type: FUNC
351   * @tc.require: AR000C6TRV AR000CQDTM
352   * @tc.author: liujialei
353   */
354 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage002, TestSize.Level1)
355 {
356     /**
357      * @tc.steps:step1/2. Remove commit log database
358      * @tc.expected: step1/2. Return OK.
359      */
360     int result = g_commitStorage->Remove(g_prop);
361     ASSERT_EQ(result, E_OK);
362     if (result != E_OK) {
363         return;
364     }
365     CommitInfo commitInfo = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
366         TIME_STAMP1, true, g_localDevice};
367 
368     /**
369      * @tc.steps:step3/4. Insert recording commit log database
370      * @tc.expected: step3/4. Return E_INVALID_DB.
371      */
372     InsertCommitToCommitStorage(commitInfo, -E_INVALID_DB);
373 
374     /**
375      * @tc.steps:step5/6. Delete commit History to commit log database
376      * @tc.expected: step5/6. Return E_INVALID_DB.
377      */
378     DeleteCommit(g_defaultCommitID1, -E_INVALID_DB);
379 
380     /**
381      * @tc.steps:step7/8. Cheeck commit History to commit log database
382      * @tc.expected: step7/8. Return E_INVALID_DB.
383      */
384     TestCommit(commitInfo, -E_INVALID_DB);
385 
386     /**
387      * @tc.steps:step9/10. Cheeck change commit header
388      * @tc.expected: step7/10. Return E_INVALID_DB.
389      */
390     SetCommitStorageHeader(g_defaultCommitID1, -E_INVALID_DB);
391 
392     /**
393      * @tc.steps:step11/12. Cheeck query commit header
394      * @tc.expected: step11/12. Return failed.
395      */
396     TestCommitStorageHeader(g_defaultCommitID0);
397 }
398 
399 /**
400   * @tc.name: MultiVerCommitStorage003
401   * @tc.desc: Insert a commit to commit storage, and get it.
402   * @tc.type: FUNC
403   * @tc.require: AR000C6TRV AR000CQDTM
404   * @tc.author: liujialei
405   */
406 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage003, TestSize.Level1)
407 {
408     CommitInfo commitInfo = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
409         TIME_STAMP1, true, g_localDevice};
410 
411     /**
412      * @tc.steps:step1. Insert recording commit log database
413      * @tc.expected: step1. Return E_OK.
414      */
415     InsertCommitToCommitStorage(commitInfo, E_OK);
416 
417     /**
418      * @tc.steps:step2. Cheeck commit History to commit log database
419      * @tc.expected: step2. Return E_OK.
420      */
421     TestCommit(commitInfo, E_OK);
422     return;
423 }
424 
425 /**
426   * @tc.name: MultiVerCommitStorage004
427   * @tc.desc: Set header of commit storage, and get it.
428   * @tc.type: FUNC
429   * @tc.require: AR000C6TRV AR000CQDTM
430   * @tc.author: liujialei
431   */
432 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage004, TestSize.Level1)
433 {
434     CommitInfo commitInfo = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
435         TIME_STAMP1, true, g_localDevice};
436 
437     /**
438      * @tc.steps:step1. Insert recording commit log database
439      * @tc.expected: step1. Return E_OK.
440      */
441     InsertCommitToCommitStorage(commitInfo, E_OK);
442 
443     /**
444      * @tc.steps:step2. Cheeck change commit header
445      * @tc.expected: step2. Return E_OK.
446      */
447     SetCommitStorageHeader(g_defaultCommitID1, E_OK);
448 
449     /**
450      * @tc.steps:step3. Cheeck query commit header
451      * @tc.expected: step3. Return success.
452      */
453     TestCommitStorageHeader(g_defaultCommitID1);
454     return;
455 }
456 
457 /**
458   * @tc.name: MultiVerCommitStorage005
459   * @tc.desc: Delete the header commit, test if it can be get, and get the new header.
460   * @tc.type: FUNC
461   * @tc.require: AR000C6TRV AR000CQDTM
462   * @tc.author: liujialei
463   */
464 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage005, TestSize.Level1)
465 {
466     CommitInfo commitInfo1 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
467         TIME_STAMP1, true, g_localDevice};
468 
469     /**
470      * @tc.steps:step1. Insert recording commitInfo1 commit log database
471      * @tc.expected: step1. Return E_OK.
472      */
473     InsertCommitToCommitStorage(commitInfo1, E_OK);
474     CommitInfo commitInfo2 = {g_defaultCommitVer2, g_defaultCommitID2, g_defaultCommitID1, g_defaultCommitID0,
475         TIME_STAMP2, true, g_localDevice};
476 
477     /**
478      * @tc.steps:step2. Insert recording commitInfo2 commit log database
479      * @tc.expected: step2. Return E_OK.
480      */
481     InsertCommitToCommitStorage(commitInfo2, E_OK);
482 
483     /**
484      * @tc.steps:step3. Cheeck change commit header
485      * @tc.expected: step3. Return E_OK.
486      */
487     SetCommitStorageHeader(g_defaultCommitID2, E_OK);
488 
489     /**
490      * @tc.steps:step4. Delete commit History to commit log database
491      * @tc.expected: step4. Return E_INVALID_DB.
492      */
493     DeleteCommit(g_defaultCommitID2, E_OK);
494 
495     /**
496      * @tc.steps:step5. Cheeck query commit header
497      * @tc.expected: step5. Return success.
498      */
499     TestCommitStorageHeader(g_defaultCommitID1);
500 
501     /**
502      * @tc.steps:step6. Cheeck commit History to commit log database
503      * @tc.expected: step6. Return E_OK.
504      */
505     TestCommit(commitInfo1, E_OK);
506 
507     /**
508      * @tc.steps:step7. Cheeck commit History to commit log database
509      * @tc.expected: step7. Return E_OK.
510      */
511     TestCommit(commitInfo2, -E_NOT_FOUND);
512     return;
513 }
514 
515 /**
516   * @tc.name: MultiVerCommitStorage006
517   * @tc.desc: Add commit with empty commit ID, and it will not be added.
518   * @tc.type: FUNC
519   * @tc.require: AR000C6TRV AR000CQDTM
520   * @tc.author: liujialei
521   */
522 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage006, TestSize.Level1)
523 {
524     CommitInfo commitInfo = {g_defaultCommitVer1, g_defaultCommitID0, g_defaultCommitID0, g_defaultCommitID0,
525         TIME_STAMP1, true, g_localDevice};
526 
527     /**
528      * @tc.steps:step1/2. Insert commit ID is null to commit log database
529      * @tc.expected: step1/2. Return E_UNEXPECTED_DATA.
530      */
531     InsertCommitToCommitStorage(commitInfo, -E_UNEXPECTED_DATA);
532 }
533 
534 /**
535   * @tc.name: MultiVerCommitStorage008
536   * @tc.desc: Add commit with the same commit ID as its left parent, and it will not be added.
537   * @tc.type: FUNC
538   * @tc.require: AR000C6TRV AR000CQDTM
539   * @tc.author: liujialei
540   */
541 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage008, TestSize.Level1)
542 {
543     CommitInfo commitInfo1 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
544         TIME_STAMP1, true, g_localDevice};
545 
546     /**
547      * @tc.steps:step1. Insert a recording to commit log database
548      * @tc.expected: step1. Return E_OK.
549      */
550     InsertCommitToCommitStorage(commitInfo1, E_OK);
551     CommitInfo commitInfo2 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID1, g_defaultCommitID0,
552         TIME_STAMP2, true, g_localDevice};
553 
554     /**
555      * @tc.steps:step2. Add commit with the same commit ID as its right parent
556      * @tc.expected: step2. Return E_UNEXPECTED_DATA.
557      */
558     InsertCommitToCommitStorage(commitInfo2, -E_UNEXPECTED_DATA);
559 
560     /**
561      * @tc.steps:step3. Cheeck commit History to commit log database
562      * @tc.expected: step3. Return E_OK.
563      */
564     TestCommit(commitInfo1, E_OK);
565 }
566 
567 /**
568   * @tc.name: MultiVerCommitStorage009
569   * @tc.desc: Add commit with the same commit ID as its right parent, and it will not be added.
570   * @tc.type: FUNC
571   * @tc.require: AR000C6TRV AR000CQDTM
572   * @tc.author: liujialei
573   */
574 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage009, TestSize.Level1)
575 {
576     CommitInfo commitInfo1 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
577         TIME_STAMP1, true, g_localDevice};
578 
579     /**
580      * @tc.steps:step1. Insert a recording to commit log database
581      * @tc.expected: step1. Return E_OK.
582      */
583     InsertCommitToCommitStorage(commitInfo1, E_OK);
584     CommitInfo commitInfo2 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID1,
585         TIME_STAMP2, true, g_localDevice};
586 
587     /**
588      * @tc.steps:step2. Add commit with the same commit ID as its right parent
589      * @tc.expected: step2. Return E_UNEXPECTED_DATA.
590      */
591     InsertCommitToCommitStorage(commitInfo2, -E_UNEXPECTED_DATA);
592 
593     /**
594      * @tc.steps:step3. Cheeck commit History to commit log database
595      * @tc.expected: step3. Return E_OK.
596      */
597     TestCommit(commitInfo1, E_OK);
598 }
599 
600 /**
601   * @tc.name: MultiVerCommitStorage010
602   * @tc.desc: Add commit whose left parent and right parent is the same, and it will not be added.
603   * @tc.type: FUNC
604   * @tc.require: AR000C6TRV AR000CQDTM
605   * @tc.author: liujialei
606   */
607 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage010, TestSize.Level1)
608 {
609     CommitInfo commitInfo1 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
610         TIME_STAMP1, true, g_localDevice};
611 
612     /**
613      * @tc.steps:step1. Insert a recording to commit log database
614      * @tc.expected: step1. Return E_OK.
615      */
616     InsertCommitToCommitStorage(commitInfo1, E_OK);
617     CommitInfo commitInfo2 = {g_defaultCommitVer1, g_defaultCommitID2, g_defaultCommitID1, g_defaultCommitID1,
618         TIME_STAMP2, true, g_localDevice};
619 
620     /**
621      * @tc.steps:step2. Add commit whose left parent and right parent is the same
622      * @tc.expected: step2. Return E_UNEXPECTED_DATA.
623      */
624     InsertCommitToCommitStorage(commitInfo2, -E_UNEXPECTED_DATA);
625 
626     /**
627      * @tc.steps:step3. Cheeck commit History of commitInfo1 to commit log database
628      * @tc.expected: step3. Return E_OK.
629      */
630     TestCommit(commitInfo1, E_OK);
631 
632     /**
633      * @tc.steps:step3. Cheeck commit History of commitInfo2 to commit log database
634      * @tc.expected: step3. Return E_NOT_FOUND.
635      */
636     TestCommit(commitInfo2, -E_NOT_FOUND);
637 }
638 
639 /**
640   * @tc.name: MultiVerCommitStorage011
641   * @tc.desc: Add commit with a non exist left parent, and it will not be added.
642   * @tc.type: FUNC
643   * @tc.require: AR000C6TRV AR000CQDTM
644   * @tc.author: liujialei
645   */
646 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage011, TestSize.Level1)
647 {
648     CommitInfo commitInfo = {g_defaultCommitVer1, g_defaultCommitID2, g_defaultCommitID1, g_defaultCommitID0,
649         TIME_STAMP1, true, g_localDevice};
650 
651     /**
652      * @tc.steps:step1. Add commit with a non exist left parent
653      * @tc.expected: step1. Return E_NOT_FOUND.
654      */
655     InsertCommitToCommitStorage(commitInfo, -E_NOT_FOUND);
656 
657     /**
658      * @tc.steps:step2. Cheeck commit History to commit log database
659      * @tc.expected: step2. Return E_NOT_FOUND.
660      */
661     TestCommit(commitInfo, -E_NOT_FOUND);
662 }
663 
664 /**
665   * @tc.name: MultiVerCommitStorage012
666   * @tc.desc: Add commit with a non exist right parent, and it will not be added.
667   * @tc.type: FUNC
668   * @tc.require: AR000C6TRV AR000CQDTM
669   * @tc.author: liujialei
670   */
671 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage012, TestSize.Level1)
672 {
673     CommitInfo commitInfo = {g_defaultCommitVer1, g_defaultCommitID2, g_defaultCommitID0, g_defaultCommitID1,
674         TIME_STAMP1, true, g_localDevice};
675 
676     /**
677      * @tc.steps:step1. Add commit with a non exist right parent
678      * @tc.expected: step1. Return E_NOT_FOUND.
679      */
680     InsertCommitToCommitStorage(commitInfo, -E_NOT_FOUND);
681 
682     /**
683      * @tc.steps:step2. Cheeck commit History to commit log database
684      * @tc.expected: step2. Return E_NOT_FOUND.
685      */
686     TestCommit(commitInfo, -E_NOT_FOUND);
687 }
688 
689 /**
690   * @tc.name: MultiVerCommitStorage013
691   * @tc.desc: Delete a commit which is not header, and it will not be deleted.
692   * @tc.type: FUNC
693   * @tc.require: AR000C6TRV AR000CQDTM
694   * @tc.author: liujialei
695   */
696 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage013, TestSize.Level1)
697 {
698     CommitInfo commitInfo1 = {g_defaultCommitVer1, g_defaultCommitID1, g_defaultCommitID0, g_defaultCommitID0,
699         TIME_STAMP1, true, g_localDevice};
700 
701     /**
702      * @tc.steps:step1. Insert a recording to commit log database
703      */
704     InsertCommitToCommitStorage(commitInfo1, E_OK);
705     CommitInfo commitInfo2 = {g_defaultCommitVer2, g_defaultCommitID2, g_defaultCommitID1, g_defaultCommitID0,
706         TIME_STAMP2, true, g_localDevice};
707 
708     /**
709      * @tc.steps:step2. Insert a left parent to commit log database
710      */
711     InsertCommitToCommitStorage(commitInfo2, E_OK);
712 
713     /**
714      * @tc.steps:step3. Set g_defaultCommitID2 is parent to commit log database
715      */
716     SetCommitStorageHeader(g_defaultCommitID2, E_OK);
717 
718     /**
719      * @tc.steps:step4. Delete g_defaultCommitID1
720      * @tc.expected: step4. Return E_UNEXPECTED_DATA.
721      */
722     DeleteCommit(g_defaultCommitID1, -E_UNEXPECTED_DATA);
723 
724     /**
725      * @tc.steps:step5. Cheeck commit header is same as g_defaultCommitID2
726      */
727     TestCommitStorageHeader(g_defaultCommitID2);
728 
729     TestCommit(commitInfo1, E_OK);
730     TestCommit(commitInfo2, E_OK);
731     return;
732 }
733 
734 /**
735   * @tc.name: MultiVerCommitStorage014
736   * @tc.desc: Set unexist commit to header, and it will not success.
737   * @tc.type: FUNC
738   * @tc.require: AR000C6TRV AR000CQDTM
739   * @tc.author: liujialei
740   */
741 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage014, TestSize.Level1)
742 {
743     SetCommitStorageHeader(g_defaultCommitID2, -E_NOT_FOUND);
744     TestCommitStorageHeader(g_defaultCommitID0);
745 }
746 
747 /**
748   * @tc.name: MultiVerCommitStorage015
749   * @tc.desc: SDetermine whether commit exists
750   * @tc.type: FUNC
751   * @tc.require: AR000C6TRV AR000CQDTM
752   * @tc.author: liujialei
753   */
754 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage015, TestSize.Level1)
755 {
756     PrepareCommitTree();
757     int errCode = E_OK;
758     EXPECT_EQ(g_commitStorage->CommitExist(TransStrToCommitID(g_defaultCommitID7), errCode), true);
759     EXPECT_EQ(g_commitStorage->CommitExist(TransStrToCommitID(g_defaultCommitID13), errCode), false);
760 }
761 
762 /**
763   * @tc.name: MultiVerCommitStorage016
764   * @tc.desc: Get latest commit of each device from commit storage
765   * @tc.type: FUNC
766   * @tc.require: AR000C6TRV AR000CQDTM
767   * @tc.author: liujialei
768   */
769 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage016, TestSize.Level1)
770 {
771     PrepareCommitTree();
772     std::map<DeviceID, IKvDBCommit*> latestCommits;
773     int result = g_commitStorage->GetLatestCommits(latestCommits);
774     EXPECT_EQ(result, E_OK);
775     CommitInfo commitInfoLocal = {g_defaultCommitVer12, g_defaultCommitID12, g_defaultCommitID7,
776         g_defaultCommitID11, TIME_STAMP12, true, g_localDevice};
777     CommitInfo commitInfoA = {g_defaultCommitVer11, g_defaultCommitID11, g_defaultCommitID6,
778         g_defaultCommitID10, TIME_STAMP11, false, g_remoteDeviceA};
779     CommitInfo commitInfoB = {g_defaultCommitVer10, g_defaultCommitID10, g_defaultCommitID4,
780         g_defaultCommitID9, TIME_STAMP10, false, g_remoteDeviceB};
781     CommitInfo commitInfoC = {g_defaultCommitVer9, g_defaultCommitID9, g_defaultCommitID8,
782         g_defaultCommitID0, TIME_STAMP9, false, g_remoteDeviceC};
783     TestLatestCommitOfDevice(latestCommits, g_localDevice, commitInfoLocal);
784     TestLatestCommitOfDevice(latestCommits, g_remoteDeviceA, commitInfoA);
785     TestLatestCommitOfDevice(latestCommits, g_remoteDeviceB, commitInfoB);
786     TestLatestCommitOfDevice(latestCommits, g_remoteDeviceC, commitInfoC);
787     for (auto latestCommit : latestCommits) {
788         g_commitStorage->ReleaseCommit(latestCommit.second);
789     }
790 }
791 
792 /**
793   * @tc.name: MultiVerCommitStorage017
794   * @tc.desc: Get commit tree from commit storage by latest commits
795   * @tc.type: FUNC
796   * @tc.require: AR000C6TRV AR000CQDTM
797   * @tc.author: liujialei
798   */
799 HWTEST_F(DistributedDBStorageCommitStorageTest, MultiVerCommitStorage017, TestSize.Level1)
800 {
801     PrepareCommitTree();
802     map<DeviceID, CommitID> latestCommits;
803     latestCommits.insert(make_pair(g_localDevice, TransStrToCommitID(g_defaultCommitID3)));
804     latestCommits.insert(make_pair(g_remoteDeviceA, TransStrToCommitID(g_defaultCommitID2)));
805     latestCommits.insert(make_pair(g_remoteDeviceC, TransStrToCommitID(g_defaultCommitID14)));
806     latestCommits.insert(make_pair(g_remoteDeviceD, TransStrToCommitID(g_defaultCommitID13)));
807     list<IKvDBCommit *> commits;
808     int result = g_commitStorage->GetCommitTree(latestCommits, commits);
809     EXPECT_EQ(result, E_OK);
810     vector<IKvDBCommit *> commitsVector(commits.begin(), commits.end());
811     LOGD("Commits.size%zu", commits.size());
812     ASSERT_GT(commits.size(), 6UL);
813     CommitInfo commitInfo4 = {g_defaultCommitVer4, g_defaultCommitID4, g_defaultCommitID0, g_defaultCommitID0,
814         TIME_STAMP4, false, g_remoteDeviceB};
815     CommitInfo commitInfo5 = {g_defaultCommitVer5, g_defaultCommitID5, g_defaultCommitID3, g_defaultCommitID4,
816         TIME_STAMP5, true, g_localDevice};
817     CommitInfo commitInfo6 = {g_defaultCommitVer6, g_defaultCommitID6, g_defaultCommitID2, g_defaultCommitID3,
818         TIME_STAMP6, false, g_remoteDeviceA};
819     CommitInfo commitInfo7 = {g_defaultCommitVer7, g_defaultCommitID7, g_defaultCommitID5, g_defaultCommitID6,
820         TIME_STAMP7, true, g_localDevice};
821     CommitInfo commitInfo10 = {g_defaultCommitVer10, g_defaultCommitID10, g_defaultCommitID4, g_defaultCommitID9,
822         TIME_STAMP10, false, g_remoteDeviceB};
823     CommitInfo commitInfo11 = {g_defaultCommitVer11, g_defaultCommitID11, g_defaultCommitID6, g_defaultCommitID10,
824         TIME_STAMP11, false, g_remoteDeviceA};
825     CommitInfo commitInfo12 = {g_defaultCommitVer12, g_defaultCommitID12, g_defaultCommitID7, g_defaultCommitID11,
826         TIME_STAMP12, true, g_localDevice};
827     CompareCommitWithExpectation(commitsVector[0], commitInfo4);
828     CompareCommitWithExpectation(commitsVector[1], commitInfo5);
829     CompareCommitWithExpectation(commitsVector[2], commitInfo6);
830     CompareCommitWithExpectation(commitsVector[3], commitInfo7);
831     CompareCommitWithExpectation(commitsVector[4], commitInfo10);
832     CompareCommitWithExpectation(commitsVector[5], commitInfo11);
833     CompareCommitWithExpectation(commitsVector[6], commitInfo12);
834     for (auto commit : commits) {
835         g_commitStorage->ReleaseCommit(commit);
836         commit = nullptr;
837     }
838 }
839 #endif // OMIT_MULTI_VER
840