• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #define LOG_TAG "RdbDoubleWriteTest"
17 #include <gtest/gtest.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20 
21 #include <fstream>
22 #include <string>
23 
24 #include "common.h"
25 #include "file_ex.h"
26 #include "logger.h"
27 #include "rdb_common.h"
28 #include "rdb_errno.h"
29 #include "rdb_helper.h"
30 #include "rdb_open_callback.h"
31 #include "sqlite_utils.h"
32 #include "sys/types.h"
33 
34 using namespace testing::ext;
35 using namespace OHOS::NativeRdb;
36 using namespace OHOS::Rdb;
37 
38 class RdbDoubleWriteTest : public testing::Test {
39 public:
40     static void SetUpTestCase(void);
41     static void TearDownTestCase(void);
42     void SetUp();
43     void TearDown();
44     void CheckResultSet(std::shared_ptr<RdbStore> &store);
45     void CheckAge(std::shared_ptr<ResultSet> &resultSet);
46     void CheckSalary(std::shared_ptr<ResultSet> &resultSet);
47     void CheckBlob(std::shared_ptr<ResultSet> &resultSet);
48     void CheckNumber(
49         std::shared_ptr<RdbStore> &store, int num, int errCode = E_OK, const std::string &tableName = "test");
50     void Insert(int64_t start, int count, bool isSlave = false, int dataSize = 0);
51     void WaitForBackupFinish(int32_t expectStatus, int maxTimes = 400);
52     void TryInterruptBackup();
53     void InitDb();
54 
55     static const std::string DATABASE_NAME;
56     static const std::string SLAVE_DATABASE_NAME;
57     static std::shared_ptr<RdbStore> store;
58     static std::shared_ptr<RdbStore> slaveStore;
59     static std::shared_ptr<RdbStore> store3;
60 
61     enum SlaveStatus : uint32_t {
62         UNDEFINED,
63         DB_NOT_EXITS,
64         BACKING_UP,
65         BACKUP_INTERRUPT,
66         BACKUP_FINISHED,
67     };
68 };
69 
70 const std::string RdbDoubleWriteTest::DATABASE_NAME = RDB_TEST_PATH + "dual_write_test.db";
71 const std::string RdbDoubleWriteTest::SLAVE_DATABASE_NAME = RDB_TEST_PATH + "dual_write_test_slave.db";
72 std::shared_ptr<RdbStore> RdbDoubleWriteTest::store = nullptr;
73 std::shared_ptr<RdbStore> RdbDoubleWriteTest::slaveStore = nullptr;
74 std::shared_ptr<RdbStore> RdbDoubleWriteTest::store3 = nullptr;
75 const int BLOB_SIZE = 3;
76 const uint8_t EXPECTED_BLOB_DATA[]{ 1, 2, 3 };
77 const int CHECKAGE = 18;
78 const double CHECKCOLUMN = 100.5;
79 
80 class DoubleWriteTestOpenCallback : public RdbOpenCallback {
81 public:
82     int OnCreate(RdbStore &store) override;
83     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
84     static const std::string CREATE_TABLE_TEST;
85 };
86 
87 const std::string DoubleWriteTestOpenCallback::CREATE_TABLE_TEST =
88     std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
89                                                                   "name TEXT NOT NULL, age INTEGER, salary "
90                                                                   "REAL, blobType BLOB)");
91 
OnCreate(RdbStore & store)92 int DoubleWriteTestOpenCallback::OnCreate(RdbStore &store)
93 {
94     return store.ExecuteSql(CREATE_TABLE_TEST);
95 }
96 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)97 int DoubleWriteTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
98 {
99     return E_OK;
100 }
101 
SetUpTestCase(void)102 void RdbDoubleWriteTest::SetUpTestCase(void)
103 {
104 }
105 
TearDownTestCase(void)106 void RdbDoubleWriteTest::TearDownTestCase(void)
107 {
108 }
109 
SetUp(void)110 void RdbDoubleWriteTest::SetUp(void)
111 {
112 }
113 
TearDown(void)114 void RdbDoubleWriteTest::TearDown(void)
115 {
116     store = nullptr;
117     slaveStore = nullptr;
118     RdbHelper::DeleteRdbStore(RdbDoubleWriteTest::DATABASE_NAME);
119 }
120 
InitDb()121 void RdbDoubleWriteTest::InitDb()
122 {
123     int errCode = E_OK;
124     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
125     config.SetHaMode(HAMode::MAIN_REPLICA);
126     DoubleWriteTestOpenCallback helper;
127     RdbDoubleWriteTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
128     EXPECT_NE(RdbDoubleWriteTest::store, nullptr);
129 
130     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
131     DoubleWriteTestOpenCallback slaveHelper;
132     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
133     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
134     store->ExecuteSql("DELETE FROM test");
135     slaveStore->ExecuteSql("DELETE FROM test");
136 }
137 
138 /**
139  * @tc.name: RdbStore_DoubleWrite_001
140  * @tc.desc: test RdbStore doubleWrite
141  * @tc.type: FUNC
142  */
143 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_001, TestSize.Level1)
144 {
145     InitDb();
146     int64_t id;
147     ValuesBucket values;
148 
149     values.PutInt("id", 1);
150     values.PutString("name", std::string("zhangsan"));
151     values.PutInt("age", 18);
152     values.PutDouble("salary", 100.5);
153     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
154     int ret = store->Insert(id, "test", values);
155     EXPECT_EQ(ret, E_OK);
156     EXPECT_EQ(1, id);
157 
158     values.Clear();
159     values.PutInt("id", 2);
160     values.PutString("name", std::string("lisi"));
161     values.PutInt("age", 18);
162     values.PutDouble("salary", 100.5);
163     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
164     ret = store->Insert(id, "test", values);
165     EXPECT_EQ(ret, E_OK);
166     EXPECT_EQ(2, id);
167 
168     values.Clear();
169     values.PutInt("id", 3);
170     values.PutString("name", std::string("lisi"));
171     values.PutInt("age", 20L);
172     values.PutDouble("salary", 100.5f);
173     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
174     ret = store->Insert(id, "test", values);
175     EXPECT_EQ(ret, E_OK);
176     EXPECT_EQ(3, id);
177 
178     RdbDoubleWriteTest::CheckResultSet(slaveStore);
179 }
180 
Insert(int64_t start,int count,bool isSlave,int dataSize)181 void RdbDoubleWriteTest::Insert(int64_t start, int count, bool isSlave, int dataSize)
182 {
183     ValuesBucket values;
184     int64_t id = start;
185     int ret = E_OK;
186     for (int i = 0; i < count; i++) {
187         values.Clear();
188         values.PutInt("id", id);
189         if (dataSize > 0) {
190             values.PutString("name", std::string(dataSize, 'a'));
191         } else {
192             values.PutString("name", std::string("zhangsan"));
193         }
194         values.PutInt("age", CHECKAGE);
195         values.PutDouble("salary", CHECKCOLUMN);
196         values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
197         if (isSlave) {
198             ret = slaveStore->Insert(id, "test", values);
199         } else {
200             ret = store->Insert(id, "test", values);
201         }
202         EXPECT_EQ(ret, E_OK);
203         id++;
204     }
205 }
206 
WaitForBackupFinish(int32_t expectStatus,int maxTimes)207 void RdbDoubleWriteTest::WaitForBackupFinish(int32_t expectStatus, int maxTimes)
208 {
209     int32_t curStatus = store->GetBackupStatus();
210     int tryTimes = 0;
211     while (curStatus != expectStatus && (++tryTimes <= maxTimes)) {
212         usleep(50000); // 50000 delay
213         curStatus = store->GetBackupStatus();
214     }
215     LOG_INFO("----------cur backup Status:%{public}d---------", curStatus);
216     ASSERT_EQ(curStatus, expectStatus);
217 }
218 
TryInterruptBackup()219 void RdbDoubleWriteTest::TryInterruptBackup()
220 {
221     int err = store->InterruptBackup();
222     int tryTimes = 0;
223     while (err != E_OK && (++tryTimes <= 1000)) { // 1000 is try time
224         usleep(10000);                            // 10000 delay
225         err = store->InterruptBackup();
226     }
227     EXPECT_EQ(err, E_OK);
228     LOG_INFO("----------interrupt backup---------");
229 }
230 
CheckResultSet(std::shared_ptr<RdbStore> & store)231 void RdbDoubleWriteTest::CheckResultSet(std::shared_ptr<RdbStore> &store)
232 {
233     std::shared_ptr<ResultSet> resultSet =
234         store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector<std::string>{ "zhangsan" });
235     EXPECT_NE(resultSet, nullptr);
236 
237     int columnIndex;
238     int intVal;
239     std::string strVal;
240     ColumnType columnType;
241     int position;
242     int ret = resultSet->GetRowIndex(position);
243     EXPECT_EQ(ret, E_OK);
244     EXPECT_EQ(position, -1);
245 
246     ret = resultSet->GetColumnType(0, columnType);
247     EXPECT_EQ(ret, E_ROW_OUT_RANGE);
248 
249     ret = resultSet->GoToFirstRow();
250     EXPECT_EQ(ret, E_OK);
251 
252     ret = resultSet->GetColumnIndex("id", columnIndex);
253     EXPECT_EQ(ret, E_OK);
254     EXPECT_EQ(columnIndex, 0);
255     ret = resultSet->GetColumnType(columnIndex, columnType);
256     EXPECT_EQ(ret, E_OK);
257     EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
258     ret = resultSet->GetInt(columnIndex, intVal);
259     EXPECT_EQ(ret, E_OK);
260     EXPECT_EQ(1, intVal);
261 
262     ret = resultSet->GetColumnIndex("name", columnIndex);
263     EXPECT_EQ(ret, E_OK);
264     ret = resultSet->GetColumnType(columnIndex, columnType);
265     EXPECT_EQ(ret, E_OK);
266     EXPECT_EQ(columnType, ColumnType::TYPE_STRING);
267     ret = resultSet->GetString(columnIndex, strVal);
268     EXPECT_EQ(ret, E_OK);
269     EXPECT_EQ("zhangsan", strVal);
270 
271     RdbDoubleWriteTest::CheckAge(resultSet);
272     RdbDoubleWriteTest::CheckSalary(resultSet);
273     RdbDoubleWriteTest::CheckBlob(resultSet);
274 
275     ret = resultSet->GoToNextRow();
276     EXPECT_EQ(ret, E_ROW_OUT_RANGE);
277 
278     ret = resultSet->GetColumnType(columnIndex, columnType);
279     EXPECT_EQ(ret, E_ROW_OUT_RANGE);
280 
281     ret = resultSet->Close();
282     EXPECT_EQ(ret, E_OK);
283 }
284 
CheckAge(std::shared_ptr<ResultSet> & resultSet)285 void RdbDoubleWriteTest::CheckAge(std::shared_ptr<ResultSet> &resultSet)
286 {
287     int columnIndex;
288     int intVal;
289     ColumnType columnType;
290     int ret = resultSet->GetColumnIndex("age", columnIndex);
291     EXPECT_EQ(ret, E_OK);
292     ret = resultSet->GetColumnType(columnIndex, columnType);
293     EXPECT_EQ(ret, E_OK);
294     EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
295     ret = resultSet->GetInt(columnIndex, intVal);
296     EXPECT_EQ(ret, E_OK);
297     EXPECT_EQ(CHECKAGE, intVal);
298 }
299 
CheckSalary(std::shared_ptr<ResultSet> & resultSet)300 void RdbDoubleWriteTest::CheckSalary(std::shared_ptr<ResultSet> &resultSet)
301 {
302     int columnIndex;
303     double dVal;
304     ColumnType columnType;
305     int ret = resultSet->GetColumnIndex("salary", columnIndex);
306     EXPECT_EQ(ret, E_OK);
307     ret = resultSet->GetColumnType(columnIndex, columnType);
308     EXPECT_EQ(ret, E_OK);
309     EXPECT_EQ(columnType, ColumnType::TYPE_FLOAT);
310     ret = resultSet->GetDouble(columnIndex, dVal);
311     EXPECT_EQ(ret, E_OK);
312     EXPECT_EQ(CHECKCOLUMN, dVal);
313 }
314 
CheckBlob(std::shared_ptr<ResultSet> & resultSet)315 void RdbDoubleWriteTest::CheckBlob(std::shared_ptr<ResultSet> &resultSet)
316 {
317     int columnIndex;
318     std::vector<uint8_t> blob;
319     ColumnType columnType;
320     int ret = resultSet->GetColumnIndex("blobType", columnIndex);
321     EXPECT_EQ(ret, E_OK);
322     ret = resultSet->GetColumnType(columnIndex, columnType);
323     EXPECT_EQ(ret, E_OK);
324     EXPECT_EQ(columnType, ColumnType::TYPE_BLOB);
325     ret = resultSet->GetBlob(columnIndex, blob);
326     EXPECT_EQ(ret, E_OK);
327     EXPECT_EQ(BLOB_SIZE, static_cast<int>(blob.size()));
328     for (int i = 0; i < BLOB_SIZE; i++) {
329         EXPECT_EQ(EXPECTED_BLOB_DATA[i], blob[i]);
330     }
331 }
332 
CheckNumber(std::shared_ptr<RdbStore> & store,int num,int errCode,const std::string & tableName)333 void RdbDoubleWriteTest::CheckNumber(
334     std::shared_ptr<RdbStore> &store, int num, int errCode, const std::string &tableName)
335 {
336     std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM " + tableName);
337     ASSERT_NE(resultSet, nullptr);
338     int countNum;
339     int ret = resultSet->GetRowCount(countNum);
340     EXPECT_EQ(ret, errCode);
341     EXPECT_EQ(num, countNum);
342 }
343 
344 /**
345  * @tc.name: RdbStore_DoubleWrite_003
346  * @tc.desc: test RdbStore execute
347  * @tc.type: FUNC
348  */
349 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_003, TestSize.Level1)
350 {
351     InitDb();
352 
353     int64_t id;
354     ValuesBucket values;
355     values.PutInt("id", 1);
356     values.PutString("name", std::string("zhangsan"));
357     values.PutInt("age", 25);
358     values.PutDouble("salary", CHECKCOLUMN);
359     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
360     int ret = store->Insert(id, "test", values);
361     EXPECT_EQ(ret, E_OK);
362     auto [ret2, outValue2] = store->Execute("UPDATE test SET age= 18 WHERE id = 1");
363     EXPECT_EQ(E_OK, ret2);
364 
365     RdbDoubleWriteTest::CheckResultSet(slaveStore);
366 }
367 
368 /**
369  * @tc.name: RdbStore_DoubleWrite_004
370  * @tc.desc: test RdbStore updata
371  * @tc.type: FUNC
372  */
373 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_004, TestSize.Level1)
374 {
375     InitDb();
376 
377     int64_t id;
378 
379     ValuesBucket values;
380     values.PutInt("id", 1);
381     values.PutString("name", std::string("zhangsan"));
382     values.PutInt("age", 25);
383     values.PutDouble("salary", 100.5);
384     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
385     int ret = store->Insert(id, "test", values);
386 
387     int changedRows;
388     values.Clear();
389     values.PutInt("age", 18);
390     ret = store->Update(changedRows, "test", values);
391     EXPECT_EQ(ret, E_OK);
392     EXPECT_EQ(1, changedRows);
393 
394     RdbDoubleWriteTest::CheckResultSet(slaveStore);
395 }
396 
397 /**
398  * @tc.name: RdbStore_DoubleWrite_005
399  * @tc.desc: test RdbStore delete
400  * @tc.type: FUNC
401  */
402 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_005, TestSize.Level1)
403 {
404     InitDb();
405 
406     ValuesBucket values;
407     int64_t id;
408     values.PutInt("id", 1);
409     values.PutString("name", std::string("zhangsan"));
410     values.PutInt("age", 18);
411     values.PutDouble("salary", 100.5);
412     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
413     int ret = store->Insert(id, "test", values);
414     EXPECT_EQ(ret, E_OK);
415     EXPECT_EQ(1, id);
416 
417     values.Clear();
418     values.PutInt("id", 2);
419     values.PutString("name", std::string("lisi"));
420     values.PutInt("age", 18);
421     values.PutDouble("salary", 100.5);
422     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
423     ret = store->Insert(id, "test", values);
424     EXPECT_EQ(ret, E_OK);
425     EXPECT_EQ(2, id);
426 
427     values.Clear();
428     values.PutInt("id", 3);
429     values.PutString("name", std::string("lisi"));
430     values.PutInt("age", 20L);
431     values.PutDouble("salary", 100.5f);
432     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
433     ret = store->Insert(id, "test", values);
434     EXPECT_EQ(ret, E_OK);
435     EXPECT_EQ(3, id);
436 
437     int deletedRows;
438     ret = store->Delete(deletedRows, "test", "id = 2");
439     ret = store->Delete(deletedRows, "test", "id = 3");
440     EXPECT_EQ(ret, E_OK);
441     EXPECT_EQ(1, deletedRows);
442 
443     RdbDoubleWriteTest::CheckNumber(slaveStore, 1);
444 }
445 
446 /**
447  * @tc.name: RdbStore_DoubleWrite_007
448  * @tc.desc: open SINGLE db, write, close, open MAIN_REPLICA db, check slave
449  * @tc.type: FUNC
450  */
451 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_007, TestSize.Level1)
452 {
453     int errCode = E_OK;
454     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
455     config.SetHaMode(HAMode::SINGLE);
456     DoubleWriteTestOpenCallback helper;
457     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
458     EXPECT_NE(store, nullptr);
459 
460     int64_t id = 10;
461     int count = 100;
462     Insert(id, count);
463 
464     store = nullptr;
465     config.SetHaMode(HAMode::MAIN_REPLICA);
466     RdbDoubleWriteTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
467     EXPECT_NE(RdbDoubleWriteTest::store, nullptr);
468 
469     WaitForBackupFinish(BACKUP_FINISHED);
470 
471     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
472     DoubleWriteTestOpenCallback slaveHelper;
473     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
474     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
475 
476     RdbDoubleWriteTest::CheckNumber(RdbDoubleWriteTest::slaveStore, count);
477 }
478 
479 /**
480  * @tc.name: RdbStore_DoubleWrite_008
481  * @tc.desc: open MAIN_REPLICA db, write, close, corrupt, reopen db allow rebuild, db returns to normal
482  * @tc.type: FUNC
483  */
484 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_008, TestSize.Level1)
485 {
486     InitDb();
487     int64_t id = 10;
488     int count = 100;
489     Insert(id, count);
490     LOG_INFO("RdbStore_DoubleWrite_008 insert finish");
491 
492     store = nullptr;
493 
494     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
495     ASSERT_TRUE(file.is_open() == true);
496     file.seekp(30, std::ios::beg);
497     ASSERT_TRUE(file.good() == true);
498     char bytes[2] = { 0x6, 0x6 };
499     file.write(bytes, 2);
500     ASSERT_TRUE(file.good() == true);
501     file.close();
502     LOG_INFO("RdbStore_DoubleWrite_008 corrupt db finish");
503 
504     int errCode = E_OK;
505     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
506     config.SetHaMode(HAMode::MAIN_REPLICA);
507     config.SetAllowRebuild(true);
508     DoubleWriteTestOpenCallback helper;
509     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
510     EXPECT_EQ(errCode, E_OK);
511     ASSERT_NE(store, nullptr);
512     RebuiltType rebuiltType;
513     store->GetRebuilt(rebuiltType);
514     EXPECT_EQ(rebuiltType, RebuiltType::REPAIRED);
515     LOG_INFO("RdbStore_DoubleWrite_008 reopen db finish");
516 
517     RdbDoubleWriteTest::CheckNumber(store, count);
518 }
519 
520 /**
521  * @tc.name: RdbStore_DoubleWrite_009
522  * @tc.desc: open MAIN_REPLICA db, write, slave db has 100 more data than main db, restore, check count
523  * @tc.type: FUNC
524  */
525 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_009, TestSize.Level1)
526 {
527     InitDb();
528     int64_t id = 10;
529     Insert(id, 100);
530     id = 200;
531     Insert(id, 100, true);
532     RdbDoubleWriteTest::CheckNumber(store, 100);
533     RdbDoubleWriteTest::CheckNumber(slaveStore, 200);
534     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
535     RdbDoubleWriteTest::CheckNumber(store, 200);
536 }
537 
538 /**
539  * @tc.name: RdbStore_DoubleWrite_010
540  * @tc.desc: open MAIN_REPLICA db, write, close all, corrupt slave, open MAIN_REPLICA db, slave returns to normal
541  * @tc.type: FUNC
542  */
543 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_010, TestSize.Level1)
544 {
545     InitDb();
546     int64_t id = 10;
547     int count = 100;
548     Insert(id, count);
549     LOG_INFO("RdbStore_DoubleWrite_010 insert finish");
550 
551     slaveStore = nullptr;
552     store = nullptr;
553 
554     std::fstream file(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
555     ASSERT_TRUE(file.is_open() == true);
556     file.seekp(30, std::ios::beg);
557     ASSERT_TRUE(file.good() == true);
558     char bytes[2] = { 0x6, 0x6 };
559     file.write(bytes, 2);
560     ASSERT_TRUE(file.good() == true);
561     file.close();
562     LOG_INFO("RdbStore_DoubleWrite_010 corrupt db finish");
563 
564     int errCode = E_OK;
565     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
566     config.SetHaMode(HAMode::MAIN_REPLICA);
567     DoubleWriteTestOpenCallback helper;
568     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
569     EXPECT_EQ(errCode, E_OK);
570     ASSERT_NE(store, nullptr);
571     LOG_INFO("RdbStore_DoubleWrite_010 reopen main db finish");
572 
573     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
574     DoubleWriteTestOpenCallback slaveHelper;
575     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
576     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
577     LOG_INFO("RdbStore_DoubleWrite_010 reopen slave db finish");
578     WaitForBackupFinish(BACKUP_FINISHED);
579     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
580 }
581 
582 /**
583  * @tc.name: RdbStore_DoubleWrite_011
584  * @tc.desc: open MAIN_REPLICA db, write, close slave, corrupt slave, backup, check slave
585  * @tc.type: FUNC
586  */
587 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_011, TestSize.Level1)
588 {
589     InitDb();
590     int64_t id = 10;
591     int count = 100;
592     Insert(id, count);
593     LOG_INFO("RdbStore_DoubleWrite_011 insert finish");
594 
595     slaveStore = nullptr;
596 
597     std::fstream file(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
598     ASSERT_TRUE(file.is_open() == true);
599     file.seekp(30, std::ios::beg);
600     ASSERT_TRUE(file.good() == true);
601     char bytes[2] = { 0x6, 0x6 };
602     file.write(bytes, 2);
603     ASSERT_TRUE(file.good() == true);
604     file.close();
605     LOG_INFO("RdbStore_DoubleWrite_011 corrupt db finish");
606 
607     EXPECT_NE(store->Backup(std::string(""), {}), E_OK);
608     LOG_INFO("RdbStore_DoubleWrite_011 backup db finish");
609     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
610 
611     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
612     DoubleWriteTestOpenCallback slaveHelper;
613     int errCode;
614     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
615     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
616     LOG_INFO("RdbStore_DoubleWrite_011 reopen slave db finish");
617 
618     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
619 }
620 
621 /**
622  * @tc.name: RdbStore_DoubleWrite_012
623  * @tc.desc: test RdbStore transaction
624  * @tc.type: FUNC
625  */
626 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_012, TestSize.Level1)
627 {
628     InitDb();
629 
630     int err = store->BeginTransaction();
631     EXPECT_EQ(err, E_OK);
632     int64_t id;
633     ValuesBucket values;
634     values.PutInt("id", 1);
635     values.PutString("name", std::string("zhangsan"));
636     values.PutInt("age", 25);
637     values.PutDouble("salary", CHECKCOLUMN);
638     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
639     int ret = store->Insert(id, "test", values);
640     EXPECT_EQ(ret, E_OK);
641     auto [ret2, outValue2] = store->Execute("UPDATE test SET age= 18 WHERE id = 1");
642     EXPECT_EQ(E_OK, ret2);
643     err = store->Commit();
644     EXPECT_EQ(err, E_OK);
645 
646     RdbDoubleWriteTest::CheckResultSet(slaveStore);
647 }
648 
649 /**
650  * @tc.name: RdbStore_DoubleWrite_013
651  * @tc.desc: open MANUAL_TRIGGER db, open slave, write, slave is empty, backup, check slave, write, check slave
652  * @tc.type: FUNC
653  */
654 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_013, TestSize.Level1)
655 {
656     int errCode = E_OK;
657     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
658     config.SetHaMode(HAMode::MANUAL_TRIGGER);
659     DoubleWriteTestOpenCallback helper;
660     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
661     EXPECT_EQ(errCode, E_OK);
662     ASSERT_NE(store, nullptr);
663     LOG_INFO("RdbStore_DoubleWrite_013 reopen main db finish");
664 
665     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
666     DoubleWriteTestOpenCallback slaveHelper;
667     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
668     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
669     LOG_INFO("RdbStore_DoubleWrite_013 reopen slave db finish");
670 
671     int64_t id = 10;
672     int count = 100;
673     Insert(id, count);
674     LOG_INFO("RdbStore_DoubleWrite_013 insert finish");
675 
676     RdbDoubleWriteTest::CheckNumber(slaveStore, 0);
677 
678     errCode = store->Backup(std::string(""), {});
679     EXPECT_EQ(errCode, E_OK);
680     LOG_INFO("RdbStore_DoubleWrite_013 backup finish");
681 
682     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
683 
684     id = 1000;
685     Insert(id, count);
686     LOG_INFO("RdbStore_DoubleWrite_013 insert finish");
687     RdbDoubleWriteTest::CheckNumber(slaveStore, 200); // 200 is all count
688 }
689 
690 /**
691  * @tc.name: RdbStore_DoubleWrite_014
692  * @tc.desc: open MANUAL_TRIGGER db, write, backup, open slave, check slave, write, check slave
693  * @tc.type: FUNC
694  */
695 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_014, TestSize.Level1)
696 {
697     int errCode = E_OK;
698     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
699     config.SetHaMode(HAMode::MANUAL_TRIGGER);
700     DoubleWriteTestOpenCallback helper;
701     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
702     EXPECT_EQ(errCode, E_OK);
703     ASSERT_NE(store, nullptr);
704     LOG_INFO("RdbStore_DoubleWrite_014 reopen main db finish");
705 
706     int64_t id = 10;
707     int count = 100;
708     Insert(id, count);
709     LOG_INFO("RdbStore_DoubleWrite_014 insert finish");
710 
711     errCode = store->Backup(std::string(""), {});
712     EXPECT_EQ(errCode, E_OK);
713     LOG_INFO("RdbStore_DoubleWrite_014 backup finish");
714 
715     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
716     DoubleWriteTestOpenCallback slaveHelper;
717     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
718     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
719     LOG_INFO("RdbStore_DoubleWrite_014 reopen slave db finish");
720 
721     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
722 
723     id = 1000;
724     Insert(id, count);
725     LOG_INFO("RdbStore_DoubleWrite_014 insert finish");
726     RdbDoubleWriteTest::CheckNumber(slaveStore, 200); // 200 is all count
727 }
728 
729 /**
730  * @tc.name: RdbStore_DoubleWrite_015
731  * @tc.desc: open MAIN_REPLICA db, write, close, corrupt, slave create table, open MAIN_REPLICA db. check count
732  * @tc.type: FUNC
733  */
734 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_015, TestSize.Level1)
735 {
736     InitDb();
737     int64_t id = 10;
738     int count = 100;
739     ValuesBucket values;
740     for (int i = 0; i < count; i++) {
741         id++;
742         values.Clear();
743         values.PutInt("id", id);
744         values.PutString("name", std::string("zhangsan"));
745         values.PutInt("age", 18);
746         values.PutDouble("salary", 100.5);
747         values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
748         int ret = store->Insert(id, "test", values);
749         EXPECT_EQ(ret, E_OK);
750     }
751     LOG_INFO("RdbStore_DoubleWrite_015 insert finish");
752 
753     store = nullptr;
754 
755     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
756     ASSERT_TRUE(file.is_open() == true);
757     file.seekp(30, std::ios::beg);
758     ASSERT_TRUE(file.good() == true);
759     char bytes[2] = { 0x6, 0x6 };
760     file.write(bytes, 2);
761     ASSERT_TRUE(file.good() == true);
762     file.close();
763     LOG_INFO("RdbStore_DoubleWrite_015 corrupt db finish");
764 
765     int errCode = slaveStore->ExecuteSql("CREATE TABLE IF NOT EXISTS xx (id INTEGER PRIMARY KEY AUTOINCREMENT,"
766                                          "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
767     EXPECT_EQ(errCode, E_OK);
768     EXPECT_EQ(slaveStore->Insert(id, "xx", values), E_OK);
769 
770     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
771     config.SetHaMode(HAMode::MAIN_REPLICA);
772     config.SetAllowRebuild(true);
773     DoubleWriteTestOpenCallback helper;
774     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
775     EXPECT_EQ(errCode, E_OK);
776     ASSERT_NE(store, nullptr);
777     LOG_INFO("RdbStore_DoubleWrite_015 reopen db finish");
778 
779     RdbDoubleWriteTest::CheckNumber(store, 1, E_OK, std::string("xx"));
780     RdbDoubleWriteTest::CheckNumber(store, count);
781     RdbDoubleWriteTest::CheckNumber(slaveStore, 1, E_OK, std::string("xx"));
782     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
783 }
784 
785 /**
786  * @tc.name: RdbStore_DoubleWrite_016
787  * @tc.desc: open MAIN_REPLICA db, write, close, delete db file, reopen, check count
788  * @tc.type: FUNC
789  */
790 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_016, TestSize.Level1)
791 {
792     InitDb();
793     int64_t id = 10;
794     int count = 100;
795     Insert(id, count);
796     LOG_INFO("RdbStore_DoubleWrite_016 insert finish");
797 
798     store = nullptr;
799     LOG_INFO("RdbStore_DoubleWrite_016 close finish");
800 
801     SqliteUtils::DeleteFile(DATABASE_NAME);
802     SqliteUtils::DeleteFile(DATABASE_NAME + "-shm");
803     SqliteUtils::DeleteFile(DATABASE_NAME + "-wal");
804     LOG_INFO("RdbStore_DoubleWrite_016 delete db file finish");
805 
806     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
807     config.SetHaMode(HAMode::MAIN_REPLICA);
808     DoubleWriteTestOpenCallback helper;
809     int errCode;
810     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
811     EXPECT_EQ(errCode, E_OK);
812     ASSERT_NE(store, nullptr);
813     LOG_INFO("RdbStore_DoubleWrite_016 reopen db finish");
814 
815     WaitForBackupFinish(BACKUP_FINISHED);
816 
817     RdbDoubleWriteTest::CheckNumber(store, count);
818     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
819 }
820 
821 /**
822  * @tc.name: RdbStore_DoubleWrite_018
823  * @tc.desc: open MAIN_REPLICA db, update slave, insert, M succ && S failed,
824  *           check failureFlag, backup, check failureFlag
825  * @tc.type: FUNC
826  */
827 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_018, TestSize.Level1)
828 {
829     InitDb();
830 
831     int64_t id;
832     ValuesBucket values;
833     values.PutInt("id", 1);
834     values.PutString("name", std::string("zhangsan"));
835     values.PutInt("age", 25);
836     values.PutDouble("salary", CHECKCOLUMN);
837     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
838     int ret = store->Insert(id, "test", values);
839     EXPECT_EQ(ret, E_OK);
840 
841     auto [ret2, outValue2] = slaveStore->Execute("UPDATE test SET id = 3 WHERE id = 1");
842     EXPECT_EQ(E_OK, ret2);
843 
844     int64_t id2;
845     ValuesBucket values2;
846     values2.PutInt("id", 3);
847     values2.PutString("name", std::string("zhangsan"));
848     values2.PutInt("age", 25);
849     values2.PutDouble("salary", CHECKCOLUMN);
850     values2.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
851     int ret3 = store->Insert(id2, "test", values2);
852     EXPECT_EQ(E_OK, ret3);
853     std::string failureFlagPath = RdbDoubleWriteTest::DATABASE_NAME + +"-slaveFailure";
854     bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
855     ASSERT_TRUE(isFlagFileExists);
856     ASSERT_TRUE(store->IsSlaveDiffFromMaster());
857 
858     int errCode;
859     errCode = store->Backup(std::string(""), {});
860     EXPECT_EQ(errCode, E_OK);
861     isFlagFileExists = OHOS::FileExists(failureFlagPath);
862     ASSERT_FALSE(isFlagFileExists);
863 }
864 
865 /**
866  * @tc.name: RdbStore_DoubleWrite_019
867  * @tc.desc: open MAIN_REPLICA db, update slave, insert, M succ && S failed,
868  *           check failureFlag, reopen, check failureFlag
869  * @tc.type: FUNC
870  */
871 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_019, TestSize.Level1)
872 {
873     InitDb();
874 
875     int64_t id;
876     ValuesBucket values;
877     values.PutInt("id", 1);
878     values.PutString("name", std::string("zhangsan"));
879     values.PutInt("age", 25);
880     values.PutDouble("salary", CHECKCOLUMN);
881     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
882     int ret = store->Insert(id, "test", values);
883     EXPECT_EQ(ret, E_OK);
884 
885     auto [ret2, outValue2] = slaveStore->Execute("UPDATE test SET id = 3 WHERE id = 1");
886     EXPECT_EQ(E_OK, ret2);
887 
888     int64_t id2;
889     ValuesBucket values2;
890     values2.PutInt("id", 3);
891     values2.PutString("name", std::string("zhangsan"));
892     values2.PutInt("age", 25);
893     values2.PutDouble("salary", CHECKCOLUMN);
894     values2.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
895     int ret3 = store->Insert(id2, "test", values2);
896     EXPECT_EQ(E_OK, ret3);
897     std::string failureFlagPath = RdbDoubleWriteTest::DATABASE_NAME + +"-slaveFailure";
898     bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
899     ASSERT_TRUE(isFlagFileExists);
900     ASSERT_TRUE(store->IsSlaveDiffFromMaster());
901 
902     store = nullptr;
903     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
904     config.SetHaMode(HAMode::MAIN_REPLICA);
905     config.SetAllowRebuild(true);
906     DoubleWriteTestOpenCallback helper;
907     int errCode;
908     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
909     WaitForBackupFinish(BACKUP_FINISHED);
910     store = nullptr;
911     isFlagFileExists = OHOS::FileExists(failureFlagPath);
912     ASSERT_FALSE(isFlagFileExists);
913 }
914 
915 /**
916  * @tc.name: RdbStore_DoubleWrite_026
917  * @tc.desc: open MANUAL_TRIGGER db, write, restore, insert, check count
918  * @tc.type: FUNC
919  */
920 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_026, TestSize.Level1)
921 {
922     int errCode = E_OK;
923     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
924     config.SetHaMode(HAMode::MANUAL_TRIGGER);
925     DoubleWriteTestOpenCallback helper;
926     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
927     EXPECT_EQ(errCode, E_OK);
928     ASSERT_NE(store, nullptr);
929 
930     int64_t id = 10;
931     int count = 100;
932     Insert(id, count);
933 
934     EXPECT_EQ(store->Restore(std::string(""), {}), E_INVALID_FILE_PATH);
935 
936     id = 2000;
937     Insert(id, count);
938     RdbDoubleWriteTest::CheckNumber(store, count + count);
939 }
940 
941 /**
942  * @tc.name: RdbStore_DoubleWrite_027
943  * @tc.desc: open MANUAL_TRIGGER db, write, close, corrupt db, reopen, insert, check count
944  * @tc.type: FUNC
945  */
946 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_027, TestSize.Level1)
947 {
948     int errCode = E_OK;
949     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
950     config.SetHaMode(HAMode::MANUAL_TRIGGER);
951     config.SetAllowRebuild(true);
952     DoubleWriteTestOpenCallback helper;
953 
954     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
955     EXPECT_EQ(errCode, E_OK);
956     ASSERT_NE(store, nullptr);
957 
958     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
959     DoubleWriteTestOpenCallback slaveHelper;
960     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
961     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
962 
963     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
964 
965     int64_t id = 10;
966     int count = 100;
967     Insert(id, count);
968     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
969 
970     store = nullptr;
971 
972     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
973     ASSERT_TRUE(file.is_open() == true);
974     file.seekp(30, std::ios::beg);
975     ASSERT_TRUE(file.good() == true);
976     char bytes[2] = { 0x6, 0x6 };
977     file.write(bytes, 2);
978     ASSERT_TRUE(file.good() == true);
979     file.close();
980 
981     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
982     EXPECT_EQ(errCode, E_OK);
983     ASSERT_NE(store, nullptr);
984 
985     id = 1000;
986     Insert(id, count);
987     RdbDoubleWriteTest::CheckNumber(store, count + count);
988 }
989 
990 /**
991  * @tc.name: RdbStore_DoubleWrite_029
992  * @tc.desc: open db, write, corrupt slave db, backup, backup, check count
993  * @tc.type: FUNC
994  */
995 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_029, TestSize.Level1)
996 {
997     InitDb();
998     int64_t id = 10;
999     int count = 100;
1000     Insert(id, count);
1001 
1002     std::fstream slaveFile(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::trunc);
1003     ASSERT_TRUE(slaveFile.is_open() == true);
1004     slaveFile << "0000";
1005     slaveFile.flush();
1006     slaveFile.close();
1007 
1008     std::fstream slaveWalFile(SLAVE_DATABASE_NAME + "-wal", std::ios::in | std::ios::out | std::ios::trunc);
1009     ASSERT_TRUE(slaveWalFile.is_open() == true);
1010     slaveWalFile << "0000";
1011     slaveWalFile.flush();
1012     slaveWalFile.close();
1013 
1014     EXPECT_NE(store->Backup(std::string(""), {}), E_OK);
1015     LOG_INFO("RdbStore_DoubleWrite_029 backup again");
1016     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
1017 
1018     RdbDoubleWriteTest::CheckNumber(store, count);
1019     RdbDoubleWriteTest::CheckNumber(slaveStore, -1, E_SQLITE_CORRUPT);
1020 
1021     int errCode = E_OK;
1022     slaveStore = nullptr;
1023     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1024     DoubleWriteTestOpenCallback slaveHelper;
1025     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1026     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1027 
1028     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1029 }
1030 
1031 /**
1032  * @tc.name: RdbStore_DoubleWrite_030
1033  * @tc.desc: open db, write, update slave, insert, check failure, restore, check count
1034  * @tc.type: FUNC
1035  */
1036 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_030, TestSize.Level1)
1037 {
1038     InitDb();
1039     int64_t id = 10;
1040     int count = 100;
1041     Insert(id, count);
1042 
1043     auto [ret2, outValue2] = slaveStore->Execute("UPDATE test SET id = 666 WHERE id = 22");
1044     EXPECT_EQ(E_OK, ret2);
1045 
1046     id = 666;
1047     Insert(id, 1);
1048 
1049     std::string failureFlagPath = RdbDoubleWriteTest::DATABASE_NAME + +"-slaveFailure";
1050     bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
1051     ASSERT_TRUE(isFlagFileExists);
1052 
1053     EXPECT_NE(store->Restore(std::string(""), {}), E_OK);
1054 
1055     RdbDoubleWriteTest::CheckNumber(store, count + 1);
1056     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1057 }
1058 
1059 /**
1060  * @tc.name: RdbStore_DoubleWrite_031
1061  * @tc.desc: open db, delete main.db, deleteRdbStore, check slave db
1062  * @tc.type: FUNC
1063  */
1064 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_031, TestSize.Level1)
1065 {
1066     InitDb();
1067     remove(RdbDoubleWriteTest::DATABASE_NAME.c_str());
1068     RdbHelper::DeleteRdbStore(RdbDoubleWriteTest::DATABASE_NAME);
1069     EXPECT_NE(access(RdbDoubleWriteTest::SLAVE_DATABASE_NAME.c_str(), F_OK), 0);
1070 }
1071 
1072 /**
1073  * @tc.name: RdbStore_DoubleWrite_032
1074  * @tc.desc: open db, delete main.db, deleteRdbStore, check slave db
1075  * @tc.type: FUNC
1076  */
1077 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_032, TestSize.Level1)
1078 {
1079     InitDb();
1080     remove(RdbDoubleWriteTest::DATABASE_NAME.c_str());
1081     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1082     RdbHelper::DeleteRdbStore(config);
1083     EXPECT_NE(access(RdbDoubleWriteTest::SLAVE_DATABASE_NAME.c_str(), F_OK), 0);
1084 }
1085 
1086 /**
1087  * @tc.name: RdbStore_DoubleWrite_033
1088  * @tc.desc: open db, write, close, corrupt, open SINGLE db, check
1089  * @tc.type: FUNC
1090  */
1091 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_033, TestSize.Level1)
1092 {
1093     InitDb();
1094     int64_t id = 10;
1095     int count = 100;
1096     Insert(id, count);
1097 
1098     store = nullptr;
1099     slaveStore = nullptr;
1100 
1101     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1102     ASSERT_TRUE(file.is_open() == true);
1103     file.seekp(30, std::ios::beg);
1104     ASSERT_TRUE(file.good() == true);
1105     char bytes[2] = { 0x6, 0x6 };
1106     file.write(bytes, 2);
1107     ASSERT_TRUE(file.good() == true);
1108     file.close();
1109 
1110     int errCode = E_OK;
1111     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1112     config.SetHaMode(HAMode::SINGLE);
1113     DoubleWriteTestOpenCallback helper;
1114     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1115     EXPECT_EQ(errCode, E_OK);
1116     ASSERT_NE(store, nullptr);
1117 
1118     RebuiltType rebuiltType;
1119     store->GetRebuilt(rebuiltType);
1120     EXPECT_EQ(rebuiltType, RebuiltType::REPAIRED);
1121 
1122     RdbDoubleWriteTest::CheckNumber(store, count);
1123 }
1124 
1125 /**
1126  * @tc.name: RdbStore_DoubleWrite_034
1127  * @tc.desc: open MANUAL_TRIGGER db, write, backup, insert, check count, restore, check count
1128  * @tc.type: FUNC
1129  */
1130 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_034, TestSize.Level1)
1131 {
1132     int errCode = E_OK;
1133     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1134     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1135     config.SetAllowRebuild(true);
1136     DoubleWriteTestOpenCallback helper;
1137 
1138     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1139     EXPECT_EQ(errCode, E_OK);
1140     ASSERT_NE(store, nullptr);
1141 
1142     int64_t id = 10;
1143     int count = 100;
1144     Insert(id, count);
1145 
1146     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1147     DoubleWriteTestOpenCallback slaveHelper;
1148     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1149     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1150     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
1151     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1152 
1153     id = 1000;
1154     Insert(id, count, true);
1155     RdbDoubleWriteTest::CheckNumber(store, count);
1156     RdbDoubleWriteTest::CheckNumber(slaveStore, count + count);
1157     slaveStore = nullptr;
1158 
1159     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
1160     RdbDoubleWriteTest::CheckNumber(store, count + count);
1161 
1162     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1163     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1164     RdbDoubleWriteTest::CheckNumber(slaveStore, 0L);
1165 }