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 
19 #include <fstream>
20 #include <string>
21 #include "sys/types.h"
22 #include <sys/stat.h>
23 #include <unistd.h>
24 
25 #include "logger.h"
26 #include "common.h"
27 #include "sqlite_utils.h"
28 #include "file_ex.h"
29 #include "rdb_common.h"
30 #include "rdb_errno.h"
31 #include "rdb_helper.h"
32 #include "rdb_open_callback.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(std::shared_ptr<RdbStore> &store, int num, int errCode = E_OK,
49         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 + "insert_test.db";
71 const std::string RdbDoubleWriteTest::SLAVE_DATABASE_NAME = RDB_TEST_PATH + "insert_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(std::shared_ptr<RdbStore> &store, int num, int errCode,
334     const std::string &tableName)
335 {
336     std::shared_ptr<ResultSet> resultSet =
337         store->QuerySql("SELECT * FROM " + tableName);
338     ASSERT_NE(resultSet, nullptr);
339     int countNum;
340     int ret = resultSet->GetRowCount(countNum);
341     EXPECT_EQ(ret, errCode);
342     EXPECT_EQ(num, countNum);
343 }
344 
345 /**
346  * @tc.name: RdbStore_DoubleWrite_003
347  * @tc.desc: test RdbStore execute
348  * @tc.type: FUNC
349  */
350 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_003, TestSize.Level1)
351 {
352     InitDb();
353 
354     int64_t id;
355     ValuesBucket values;
356     values.PutInt("id", 1);
357     values.PutString("name", std::string("zhangsan"));
358     values.PutInt("age", 25);
359     values.PutDouble("salary", CHECKCOLUMN);
360     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
361     int ret = store->Insert(id, "test", values);
362     EXPECT_EQ(ret, E_OK);
363     auto [ret2, outValue2] = store->Execute("UPDATE test SET age= 18 WHERE id = 1");
364     EXPECT_EQ(E_OK, ret2);
365 
366     RdbDoubleWriteTest::CheckResultSet(slaveStore);
367 }
368 
369 /**
370  * @tc.name: RdbStore_DoubleWrite_004
371  * @tc.desc: test RdbStore updata
372  * @tc.type: FUNC
373  */
374 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_004, TestSize.Level1)
375 {
376     InitDb();
377 
378     int64_t id;
379 
380     ValuesBucket values;
381     values.PutInt("id", 1);
382     values.PutString("name", std::string("zhangsan"));
383     values.PutInt("age", 25);
384     values.PutDouble("salary", 100.5);
385     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
386     int ret = store->Insert(id, "test", values);
387 
388     int changedRows;
389     values.Clear();
390     values.PutInt("age", 18);
391     ret = store->Update(changedRows, "test", values);
392     EXPECT_EQ(ret, E_OK);
393     EXPECT_EQ(1, changedRows);
394 
395     RdbDoubleWriteTest::CheckResultSet(slaveStore);
396 }
397 
398 /**
399  * @tc.name: RdbStore_DoubleWrite_005
400  * @tc.desc: test RdbStore delete
401  * @tc.type: FUNC
402  */
403 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_005, TestSize.Level1)
404 {
405     InitDb();
406 
407     ValuesBucket values;
408     int64_t id;
409     values.PutInt("id", 1);
410     values.PutString("name", std::string("zhangsan"));
411     values.PutInt("age", 18);
412     values.PutDouble("salary", 100.5);
413     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
414     int ret = store->Insert(id, "test", values);
415     EXPECT_EQ(ret, E_OK);
416     EXPECT_EQ(1, id);
417 
418     values.Clear();
419     values.PutInt("id", 2);
420     values.PutString("name", std::string("lisi"));
421     values.PutInt("age", 18);
422     values.PutDouble("salary", 100.5);
423     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
424     ret = store->Insert(id, "test", values);
425     EXPECT_EQ(ret, E_OK);
426     EXPECT_EQ(2, id);
427 
428     values.Clear();
429     values.PutInt("id", 3);
430     values.PutString("name", std::string("lisi"));
431     values.PutInt("age", 20L);
432     values.PutDouble("salary", 100.5f);
433     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
434     ret = store->Insert(id, "test", values);
435     EXPECT_EQ(ret, E_OK);
436     EXPECT_EQ(3, id);
437 
438     int deletedRows;
439     ret = store->Delete(deletedRows, "test", "id = 2");
440     ret = store->Delete(deletedRows, "test", "id = 3");
441     EXPECT_EQ(ret, E_OK);
442     EXPECT_EQ(1, deletedRows);
443 
444     RdbDoubleWriteTest::CheckNumber(slaveStore, 1);
445 }
446 
447 /**
448  * @tc.name: RdbStore_DoubleWrite_007
449  * @tc.desc: open SINGLE db, write, close, open MAIN_REPLICA db, check slave
450  * @tc.type: FUNC
451  */
452 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_007, TestSize.Level1)
453 {
454     int errCode = E_OK;
455     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
456     config.SetHaMode(HAMode::SINGLE);
457     DoubleWriteTestOpenCallback helper;
458     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
459     EXPECT_NE(store, nullptr);
460 
461     int64_t id = 10;
462     int count = 100;
463     Insert(id, count);
464 
465     store = nullptr;
466     config.SetHaMode(HAMode::MAIN_REPLICA);
467     RdbDoubleWriteTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
468     EXPECT_NE(RdbDoubleWriteTest::store, nullptr);
469 
470     WaitForBackupFinish(BACKUP_FINISHED);
471 
472     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
473     DoubleWriteTestOpenCallback slaveHelper;
474     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
475     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
476 
477     RdbDoubleWriteTest::CheckNumber(RdbDoubleWriteTest::slaveStore, count);
478 }
479 
480 /**
481  * @tc.name: RdbStore_DoubleWrite_008
482  * @tc.desc: open MAIN_REPLICA db, write, close, corrupt, reopen db allow rebuild, db returns to normal
483  * @tc.type: FUNC
484  */
485 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_008, TestSize.Level1)
486 {
487     InitDb();
488     int64_t id = 10;
489     int count = 100;
490     Insert(id, count);
491     LOG_INFO("RdbStore_DoubleWrite_008 insert finish");
492 
493     store = nullptr;
494 
495     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
496     ASSERT_TRUE(file.is_open() == true);
497     file.seekp(30, std::ios::beg);
498     ASSERT_TRUE(file.good() == true);
499     char bytes[2] = {0x6, 0x6};
500     file.write(bytes, 2);
501     ASSERT_TRUE(file.good() == true);
502     file.close();
503     LOG_INFO("RdbStore_DoubleWrite_008 corrupt db finish");
504 
505     int errCode = E_OK;
506     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
507     config.SetHaMode(HAMode::MAIN_REPLICA);
508     config.SetAllowRebuild(true);
509     DoubleWriteTestOpenCallback helper;
510     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
511     EXPECT_EQ(errCode, E_OK);
512     ASSERT_NE(store, nullptr);
513     RebuiltType rebuiltType;
514     store->GetRebuilt(rebuiltType);
515     EXPECT_EQ(rebuiltType, RebuiltType::REPAIRED);
516     LOG_INFO("RdbStore_DoubleWrite_008 reopen db finish");
517 
518     RdbDoubleWriteTest::CheckNumber(store, count);
519 }
520 
521 /**
522  * @tc.name: RdbStore_DoubleWrite_009
523  * @tc.desc: open MAIN_REPLICA db, write, slave db has 100 more data than main db, restore, check count
524  * @tc.type: FUNC
525  */
526 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_009, TestSize.Level1)
527 {
528     InitDb();
529     int64_t id = 10;
530     Insert(id, 100);
531     id = 200;
532     Insert(id, 100, true);
533     RdbDoubleWriteTest::CheckNumber(store, 100);
534     RdbDoubleWriteTest::CheckNumber(slaveStore, 200);
535     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
536     RdbDoubleWriteTest::CheckNumber(store, 200);
537 }
538 
539 /**
540  * @tc.name: RdbStore_DoubleWrite_010
541  * @tc.desc: open MAIN_REPLICA db, write, close all, corrupt slave, open MAIN_REPLICA db, slave returns to normal
542  * @tc.type: FUNC
543  */
544 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_010, TestSize.Level1)
545 {
546     InitDb();
547     int64_t id = 10;
548     int count = 100;
549     Insert(id, count);
550     LOG_INFO("RdbStore_DoubleWrite_010 insert finish");
551 
552     slaveStore = nullptr;
553     store = nullptr;
554 
555     std::fstream file(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
556     ASSERT_TRUE(file.is_open() == true);
557     file.seekp(30, std::ios::beg);
558     ASSERT_TRUE(file.good() == true);
559     char bytes[2] = {0x6, 0x6};
560     file.write(bytes, 2);
561     ASSERT_TRUE(file.good() == true);
562     file.close();
563     LOG_INFO("RdbStore_DoubleWrite_010 corrupt db finish");
564 
565     int errCode = E_OK;
566     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
567     config.SetHaMode(HAMode::MAIN_REPLICA);
568     DoubleWriteTestOpenCallback helper;
569     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
570     EXPECT_EQ(errCode, E_OK);
571     ASSERT_NE(store, nullptr);
572     LOG_INFO("RdbStore_DoubleWrite_010 reopen main db finish");
573 
574     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
575     DoubleWriteTestOpenCallback slaveHelper;
576     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
577     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
578     LOG_INFO("RdbStore_DoubleWrite_010 reopen slave db finish");
579     WaitForBackupFinish(BACKUP_FINISHED);
580     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
581 }
582 
583 /**
584  * @tc.name: RdbStore_DoubleWrite_011
585  * @tc.desc: open MAIN_REPLICA db, write, close slave, corrupt slave, backup, check slave
586  * @tc.type: FUNC
587  */
588 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_011, TestSize.Level1)
589 {
590     InitDb();
591     int64_t id = 10;
592     int count = 100;
593     Insert(id, count);
594     LOG_INFO("RdbStore_DoubleWrite_011 insert finish");
595 
596     slaveStore = nullptr;
597 
598     std::fstream file(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
599     ASSERT_TRUE(file.is_open() == true);
600     file.seekp(30, std::ios::beg);
601     ASSERT_TRUE(file.good() == true);
602     char bytes[2] = {0x6, 0x6};
603     file.write(bytes, 2);
604     ASSERT_TRUE(file.good() == true);
605     file.close();
606     LOG_INFO("RdbStore_DoubleWrite_011 corrupt db finish");
607 
608     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
609     LOG_INFO("RdbStore_DoubleWrite_011 backup db finish");
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_022
917  * @tc.desc: open SINGLE db, write, close, reopen MAIN_REPLICA db, wait for backup, insert, check count
918  * @tc.type: FUNC
919  */
920 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_022, TestSize.Level1)
921 {
922     int errCode = E_OK;
923     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
924     config.SetHaMode(HAMode::SINGLE);
925     DoubleWriteTestOpenCallback helper;
926     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
927     EXPECT_NE(store, nullptr);
928 
929     int64_t id = 10;
930     int strSize = 1024 * 100;
931     int count = 2000;
932     Insert(id, count, false, strSize);
933     LOG_INFO("RdbStore_DoubleWrite_022 insert finish");
934 
935     store = nullptr;
936     config.SetHaMode(HAMode::MAIN_REPLICA);
937     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
938     ASSERT_NE(store, nullptr);
939     LOG_INFO("RdbStore_DoubleWrite_022 reopen db finish");
940 
941     WaitForBackupFinish(BACKUP_FINISHED);
942 
943     id = 6666;
944     Insert(id, count);
945     LOG_INFO("RdbStore_DoubleWrite_022 insert db finish");
946 
947     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
948     DoubleWriteTestOpenCallback slaveHelper;
949     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
950     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
951     LOG_INFO("RdbStore_DoubleWrite_022 reopen slave db finish");
952 
953     RdbDoubleWriteTest::CheckNumber(store, count + count);
954     RdbDoubleWriteTest::CheckNumber(slaveStore, count + count);
955 }
956 
957 /**
958  * @tc.name: RdbStore_DoubleWrite_023
959  * @tc.desc: open MANUAL_TRIGGER db, write, backup async, interrupt, backup async, wait finish, check count
960  * @tc.type: FUNC
961  */
962 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_023, TestSize.Level1)
963 {
964     int errCode = E_OK;
965     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
966     config.SetHaMode(HAMode::MANUAL_TRIGGER);
967     DoubleWriteTestOpenCallback helper;
968     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
969     EXPECT_NE(store, nullptr);
970     ASSERT_TRUE(store->IsSlaveDiffFromMaster());
971     LOG_INFO("RdbStore_DoubleWrite_023 reopen finish");
972 
973     int64_t id = 10;
974     int strSize = 1024 * 100;
975     int count = 2000;
976     Insert(id, count, false, strSize);
977     LOG_INFO("RdbStore_DoubleWrite_023 insert finish");
978 
__anone67978660102() 979     std::thread thread([this]() {
980         LOG_INFO("RdbStore_DoubleWrite_023 t1 backup begin");
981         EXPECT_EQ(store->Backup(std::string(""), {}), E_BACKUP_INTERRUPT);
982         LOG_INFO("RdbStore_DoubleWrite_023 t1 backup end");
983     });
984     LOG_INFO("RdbStore_DoubleWrite_023 begin interrupt");
985     TryInterruptBackup();
986     LOG_INFO("RdbStore_DoubleWrite_023 interrupt end");
987     EXPECT_EQ(store->GetBackupStatus(), SlaveStatus::BACKUP_INTERRUPT);
988     thread.join();
989 
__anone67978660202() 990     std::thread thread1([this]() {
991         LOG_INFO("RdbStore_DoubleWrite_023 t2 backup begin");
992         EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
993         LOG_INFO("RdbStore_DoubleWrite_023 t2 backup end");
994     });
995     WaitForBackupFinish(BACKUP_FINISHED);
996     LOG_INFO("RdbStore_DoubleWrite_023 wait finish");
997     thread1.join();
998 
999     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1000     DoubleWriteTestOpenCallback slaveHelper;
1001     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1002     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1003     LOG_INFO("RdbStore_DoubleWrite_023 reopen slave db finish");
1004 
1005     RdbDoubleWriteTest::CheckNumber(store, count);
1006     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1007 }
1008 
1009 /**
1010  * @tc.name: RdbStore_DoubleWrite_024
1011  * @tc.desc: open SINGLE db, write, close, reopen MAIN_REPLICA db, wait for backup, insert, check count
1012  * @tc.type: FUNC
1013  */
1014 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_024, TestSize.Level1)
1015 {
1016     int errCode = E_OK;
1017     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1018     config.SetHaMode(HAMode::SINGLE);
1019     DoubleWriteTestOpenCallback helper;
1020     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1021     EXPECT_NE(store, nullptr);
1022 
1023     int64_t id = 10;
1024     int strSize = 1024 * 200;
1025     int count = 1000;
1026     Insert(id, count, false, strSize);
1027     LOG_INFO("RdbStore_DoubleWrite_024 insert finish");
1028 
1029     store = nullptr;
1030     LOG_INFO("RdbStore_DoubleWrite_024 close finish");
1031     config.SetHaMode(HAMode::MAIN_REPLICA);
1032     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1033     ASSERT_NE(store, nullptr);
1034     LOG_INFO("RdbStore_DoubleWrite_024 reopen db finish");
1035 
1036     usleep(200000); // 200000 us delay
1037     store = nullptr;
1038     LOG_INFO("RdbStore_DoubleWrite_024 close again");
1039 
1040     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1041     DoubleWriteTestOpenCallback slaveHelper;
1042     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1043     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1044     LOG_INFO("RdbStore_DoubleWrite_024 reopen slave");
1045     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1046 }
1047 
1048 /**
1049  * @tc.name: RdbStore_DoubleWrite_025
1050  * @tc.desc: open SINGLE db, write, close, reopen MAIN_REPLICA db, insert, wait for backup, check count
1051  * @tc.type: FUNC
1052  */
1053 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_025, TestSize.Level1)
1054 {
1055     int errCode = E_OK;
1056     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1057     config.SetHaMode(HAMode::SINGLE);
1058     DoubleWriteTestOpenCallback helper;
1059     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1060     EXPECT_NE(store, nullptr);
1061 
1062     int64_t id = 10;
1063     int strSize = 1024 * 200;
1064     int count = 1000;
1065     Insert(id, count, false, strSize);
1066     LOG_INFO("RdbStore_DoubleWrite_025 insert finish");
1067 
1068     store = nullptr;
1069     LOG_INFO("RdbStore_DoubleWrite_025 close finish");
1070     config.SetHaMode(HAMode::MAIN_REPLICA);
1071     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1072     ASSERT_NE(store, nullptr);
1073     LOG_INFO("RdbStore_DoubleWrite_025 reopen db finish");
1074 
1075     id = 6666;
1076     LOG_INFO("RdbStore_DoubleWrite_025 begin insert");
1077     Insert(id, count, false, strSize);
1078     LOG_INFO("RdbStore_DoubleWrite_025 insert end");
1079 
1080     WaitForBackupFinish(BACKUP_FINISHED, 1000); // 1000 is max retry time
1081     LOG_INFO("RdbStore_DoubleWrite_025 wait finish");
1082 
1083     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1084     DoubleWriteTestOpenCallback slaveHelper;
1085     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1086     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1087     LOG_INFO("RdbStore_DoubleWrite_025 reopen slave");
1088 
1089     RdbDoubleWriteTest::CheckNumber(store, count + count);
1090     std::shared_ptr<ResultSet> resultSet = slaveStore->QuerySql("SELECT * FROM test");
1091     ASSERT_NE(resultSet, nullptr);
1092     int countNum;
1093     EXPECT_EQ(resultSet->GetRowCount(countNum), errCode);
1094     EXPECT_GT(countNum, count);
1095     EXPECT_LE(countNum, count + count);
1096 }
1097 
1098 /**
1099  * @tc.name: RdbStore_DoubleWrite_026
1100  * @tc.desc: open MANUAL_TRIGGER db, write, restore, insert, check count
1101  * @tc.type: FUNC
1102  */
1103 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_026, TestSize.Level1)
1104 {
1105     int errCode = E_OK;
1106     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1107     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1108     DoubleWriteTestOpenCallback helper;
1109     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1110     EXPECT_EQ(errCode, E_OK);
1111     ASSERT_NE(store, nullptr);
1112 
1113     int64_t id = 10;
1114     int count = 100;
1115     Insert(id, count);
1116 
1117     EXPECT_EQ(store->Restore(std::string(""), {}), E_INVALID_FILE_PATH);
1118 
1119     id = 2000;
1120     Insert(id, count);
1121     RdbDoubleWriteTest::CheckNumber(store, count + count);
1122 }
1123 
1124 /**
1125  * @tc.name: RdbStore_DoubleWrite_027
1126  * @tc.desc: open MANUAL_TRIGGER db, write, close, corrupt db, reopen, insert, check count
1127  * @tc.type: FUNC
1128  */
1129 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_027, TestSize.Level1)
1130 {
1131     int errCode = E_OK;
1132     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1133     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1134     config.SetAllowRebuild(true);
1135     DoubleWriteTestOpenCallback helper;
1136 
1137     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1138     DoubleWriteTestOpenCallback slaveHelper;
1139     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1140     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1141 
1142     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1143     EXPECT_EQ(errCode, E_OK);
1144     ASSERT_NE(store, nullptr);
1145 
1146     int64_t id = 10;
1147     int count = 100;
1148     Insert(id, count);
1149     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1150 
1151     store = nullptr;
1152 
1153     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1154     ASSERT_TRUE(file.is_open() == true);
1155     file.seekp(30, std::ios::beg);
1156     ASSERT_TRUE(file.good() == true);
1157     char bytes[2] = {0x6, 0x6};
1158     file.write(bytes, 2);
1159     ASSERT_TRUE(file.good() == true);
1160     file.close();
1161 
1162     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1163     EXPECT_EQ(errCode, E_OK);
1164     ASSERT_NE(store, nullptr);
1165 
1166     id = 1000;
1167     Insert(id, count);
1168     RdbDoubleWriteTest::CheckNumber(store, count + count);
1169 }
1170 
1171 /**
1172  * @tc.name: RdbStore_DoubleWrite_029
1173  * @tc.desc: open db, write, corrupt slave db, backup, backup, check count
1174  * @tc.type: FUNC
1175  */
1176 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_029, TestSize.Level1)
1177 {
1178     InitDb();
1179     int64_t id = 10;
1180     int count = 100;
1181     Insert(id, count);
1182 
1183     std::fstream slaveFile(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::trunc);
1184     ASSERT_TRUE(slaveFile.is_open() == true);
1185     slaveFile << "0000";
1186     slaveFile.flush();
1187     slaveFile.close();
1188 
1189     std::fstream slaveWalFile(SLAVE_DATABASE_NAME + "-wal", std::ios::in | std::ios::out | std::ios::trunc);
1190     ASSERT_TRUE(slaveWalFile.is_open() == true);
1191     slaveWalFile << "0000";
1192     slaveWalFile.flush();
1193     slaveWalFile.close();
1194 
1195     EXPECT_NE(store->Backup(std::string(""), {}), E_OK);
1196     LOG_INFO("RdbStore_DoubleWrite_029 backup again");
1197     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
1198 
1199     RdbDoubleWriteTest::CheckNumber(store, count);
1200     RdbDoubleWriteTest::CheckNumber(slaveStore, -1, E_SQLITE_IOERR);
1201 
1202     int errCode = E_OK;
1203     slaveStore = nullptr;
1204     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1205     DoubleWriteTestOpenCallback slaveHelper;
1206     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1207     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1208 
1209     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1210 }
1211 
1212 /**
1213  * @tc.name: RdbStore_DoubleWrite_030
1214  * @tc.desc: open db, write, update slave, insert, check failure, restore, check count
1215  * @tc.type: FUNC
1216  */
1217 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_030, TestSize.Level1)
1218 {
1219     InitDb();
1220     int64_t id = 10;
1221     int count = 100;
1222     Insert(id, count);
1223 
1224     auto [ret2, outValue2] = slaveStore->Execute("UPDATE test SET id = 666 WHERE id = 22");
1225     EXPECT_EQ(E_OK, ret2);
1226 
1227     id = 666;
1228     Insert(id, 1);
1229 
1230     std::string failureFlagPath = RdbDoubleWriteTest::DATABASE_NAME + + "-slaveFailure";
1231     bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
1232     ASSERT_TRUE(isFlagFileExists);
1233 
1234     EXPECT_NE(store->Restore(std::string(""), {}), E_OK);
1235 
1236     RdbDoubleWriteTest::CheckNumber(store, count + 1);
1237     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1238 }