• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #define LOG_TAG "RdbDoubleWriteTest"
17 #include <gtest/gtest.h>
18 #include <sys/stat.h>
19 #include <sqlite3sym.h>
20 #include <unistd.h>
21 
22 #include <fstream>
23 #include <string>
24 
25 #include "common.h"
26 #include "file_ex.h"
27 #include "grd_api_manager.h"
28 #include "logger.h"
29 #include "rdb_common.h"
30 #include "rdb_errno.h"
31 #include "rdb_helper.h"
32 #include "rdb_open_callback.h"
33 #include "rdb_security_manager.h"
34 #ifndef CROSS_PLATFORM
35 #include "relational/relational_store_sqlite_ext.h"
36 #endif
37 #include "sqlite_connection.h"
38 #include "sqlite_utils.h"
39 #include "sys/types.h"
40 
41 using namespace testing::ext;
42 using namespace OHOS::NativeRdb;
43 using namespace OHOS::Rdb;
44 
45 class RdbDoubleWriteTest : public testing::Test {
46 public:
47     static void SetUpTestCase(void);
48     static void TearDownTestCase(void);
49     void SetUp();
50     void TearDown();
51     void CheckResultSet(std::shared_ptr<RdbStore> &store);
52     void CheckAge(std::shared_ptr<ResultSet> &resultSet);
53     void CheckSalary(std::shared_ptr<ResultSet> &resultSet);
54     void CheckBlob(std::shared_ptr<ResultSet> &resultSet);
55     void CheckNumber(
56         std::shared_ptr<RdbStore> &store, int num, int errCode = E_OK, const std::string &tableName = "test");
57     void Insert(int64_t start, int count, bool isSlave = false, int dataSize = 0);
58     void WaitForBackupFinish(int32_t expectStatus, int maxTimes = 400);
59     void WaitForAsyncRepairFinish(int maxTimes = 400);
60     void TryInterruptBackup();
61     void InitDb(HAMode mode = HAMode::MAIN_REPLICA, bool isOpenSlave = true);
62 
63     static const std::string DATABASE_NAME;
64     static const std::string SLAVE_DATABASE_NAME;
65     static std::shared_ptr<RdbStore> store;
66     static std::shared_ptr<RdbStore> slaveStore;
67     static std::shared_ptr<RdbStore> store3;
68     static const struct sqlite3_api_routines_extra *originalExtraApi;
69     static struct sqlite3_api_routines_extra mockExtraApi;
70 #ifndef CROSS_PLATFORM
71     static const struct sqlite3_api_routines_relational *originalKvApi;
72     static struct sqlite3_api_routines_relational mockKvApi;
73 #endif
74 
75     enum SlaveStatus : uint32_t {
76         UNDEFINED,
77         BACKING_UP,
78         BACKUP_INTERRUPT,
79         BACKUP_FINISHED,
80         DB_CLOSING,
81     };
82 };
83 
84 const std::string RdbDoubleWriteTest::DATABASE_NAME = RDB_TEST_PATH + "dual_write_test.db";
85 const std::string RdbDoubleWriteTest::SLAVE_DATABASE_NAME = RDB_TEST_PATH + "dual_write_test_slave.db";
86 std::shared_ptr<RdbStore> RdbDoubleWriteTest::store = nullptr;
87 std::shared_ptr<RdbStore> RdbDoubleWriteTest::slaveStore = nullptr;
88 std::shared_ptr<RdbStore> RdbDoubleWriteTest::store3 = nullptr;
89 const struct sqlite3_api_routines_extra *RdbDoubleWriteTest::originalExtraApi = sqlite3_export_extra_symbols;
90 struct sqlite3_api_routines_extra RdbDoubleWriteTest::mockExtraApi = *sqlite3_export_extra_symbols;
91 #ifndef CROSS_PLATFORM
92 const struct sqlite3_api_routines_relational *RdbDoubleWriteTest::originalKvApi = sqlite3_export_relational_symbols;
93 struct sqlite3_api_routines_relational RdbDoubleWriteTest::mockKvApi = *sqlite3_export_relational_symbols;
94 #endif
95 const int BLOB_SIZE = 3;
96 const uint8_t EXPECTED_BLOB_DATA[]{ 1, 2, 3 };
97 const int CHECKAGE = 18;
98 const double CHECKCOLUMN = 100.5;
99 const int HUGE_DATA_SIZE = 6 * 1024 * 1024; // 1MB
100 
101 class DoubleWriteTestOpenCallback : public RdbOpenCallback {
102 public:
103     int OnCreate(RdbStore &store) override;
104     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
105     int OnOpen(RdbStore &rdbStore) override;
106     static const std::string CREATE_TABLE_TEST;
107 };
108 
109 const std::string DoubleWriteTestOpenCallback::CREATE_TABLE_TEST =
110     std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
111                                                                   "name TEXT NOT NULL, age INTEGER, salary "
112                                                                   "REAL, blobType BLOB)");
113 
OnCreate(RdbStore & store)114 int DoubleWriteTestOpenCallback::OnCreate(RdbStore &store)
115 {
116     return store.ExecuteSql(CREATE_TABLE_TEST);
117 }
118 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)119 int DoubleWriteTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
120 {
121     return E_OK;
122 }
123 
OnOpen(RdbStore & rdbStore)124 int DoubleWriteTestOpenCallback::OnOpen(RdbStore &rdbStore)
125 {
126     int version = 0;
127     rdbStore.GetVersion(version);
128     EXPECT_TRUE(version > -1);
129     return E_OK;
130 }
131 
MockNotSupportBinlog(const char * notUsed)132 static int MockNotSupportBinlog(const char *notUsed)
133 {
134     return SQLITE_ERROR;
135 }
136 
MockSupportBinlog(const char * notUsed)137 static int MockSupportBinlog(const char *notUsed)
138 {
139     return SQLITE_OK;
140 }
141 
142 #ifndef CROSS_PLATFORM
MockNotSupportBinlogWithParam(const char * name)143 static int MockNotSupportBinlogWithParam(const char *name)
144 {
145     return SQLITE_ERROR;
146 }
147 
MockSupportBinlogWithParam(const char * name)148 static int MockSupportBinlogWithParam(const char *name)
149 {
150     return SQLITE_OK;
151 }
152 #endif
MockReplayBinlog(sqlite3 * srcDb,sqlite3 * destDb)153 static int MockReplayBinlog(sqlite3 *srcDb, sqlite3 *destDb)
154 {
155     return SQLITE_OK;
156 }
157 
MockCleanBinlog(sqlite3 * db,BinlogFileCleanModeE mode)158 static int MockCleanBinlog(sqlite3 *db, BinlogFileCleanModeE mode)
159 {
160     return SQLITE_OK;
161 }
162 
SetUpTestCase(void)163 void RdbDoubleWriteTest::SetUpTestCase(void)
164 {
165 }
166 
TearDownTestCase(void)167 void RdbDoubleWriteTest::TearDownTestCase(void)
168 {
169 }
170 
SetUp(void)171 void RdbDoubleWriteTest::SetUp(void)
172 {
173     mockExtraApi.is_support_binlog = MockNotSupportBinlog;
174     mockExtraApi.replay_binlog = MockReplayBinlog;
175     mockExtraApi.clean_binlog = MockCleanBinlog;
176     sqlite3_export_extra_symbols = &mockExtraApi;
177 #ifndef CROSS_PLATFORM
178     mockKvApi.is_support_binlog = MockNotSupportBinlogWithParam;
179     sqlite3_export_relational_symbols = &mockKvApi;
180 #endif
181     store = nullptr;
182     slaveStore = nullptr;
183     RdbHelper::DeleteRdbStore(RdbDoubleWriteTest::DATABASE_NAME);
184 }
185 
TearDown(void)186 void RdbDoubleWriteTest::TearDown(void)
187 {
188     RdbDoubleWriteTest::WaitForAsyncRepairFinish();
189     store = nullptr;
190     slaveStore = nullptr;
191     RdbHelper::DeleteRdbStore(RdbDoubleWriteTest::DATABASE_NAME);
192     sqlite3_export_extra_symbols = originalExtraApi;
193 #ifndef CROSS_PLATFORM
194     sqlite3_export_relational_symbols = originalKvApi;
195 #endif
196 }
197 
InitDb(HAMode mode,bool isOpenSlave)198 void RdbDoubleWriteTest::InitDb(HAMode mode, bool isOpenSlave)
199 {
200     int errCode = E_OK;
201     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
202     config.SetHaMode(mode);
203     DoubleWriteTestOpenCallback helper;
204     RdbDoubleWriteTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
205     ASSERT_NE(RdbDoubleWriteTest::store, nullptr);
206     store->ExecuteSql("DELETE FROM test");
207 
208     if (isOpenSlave) {
209         RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
210         DoubleWriteTestOpenCallback slaveHelper;
211         RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
212         ASSERT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
213         slaveStore->ExecuteSql("DELETE FROM test");
214     }
215 }
216 
217 /**
218  * @tc.name: RdbStore_DoubleWrite_001
219  * @tc.desc: test RdbStore doubleWrite
220  * @tc.type: FUNC
221  */
222 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_001, TestSize.Level1)
223 {
224     InitDb();
225     int64_t id;
226     ValuesBucket values;
227 
228     values.PutInt("id", 1);
229     values.PutString("name", std::string("zhangsan"));
230     values.PutInt("age", 18);
231     values.PutDouble("salary", 100.5);
232     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
233     int ret = store->Insert(id, "test", values);
234     EXPECT_EQ(ret, E_OK);
235     EXPECT_EQ(1, id);
236 
237     values.Clear();
238     values.PutInt("id", 2);
239     values.PutString("name", std::string("lisi"));
240     values.PutInt("age", 18);
241     values.PutDouble("salary", 100.5);
242     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
243     ret = store->Insert(id, "test", values);
244     EXPECT_EQ(ret, E_OK);
245     EXPECT_EQ(2, id);
246 
247     values.Clear();
248     values.PutInt("id", 3);
249     values.PutString("name", std::string("lisi"));
250     values.PutInt("age", 20L);
251     values.PutDouble("salary", 100.5f);
252     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
253     ret = store->Insert(id, "test", values);
254     EXPECT_EQ(ret, E_OK);
255     EXPECT_EQ(3, id);
256 
257     RdbDoubleWriteTest::CheckResultSet(slaveStore);
258 }
259 
Insert(int64_t start,int count,bool isSlave,int dataSize)260 void RdbDoubleWriteTest::Insert(int64_t start, int count, bool isSlave, int dataSize)
261 {
262     ValuesBucket values;
263     int64_t id = start;
264     int ret = E_OK;
265     for (int i = 0; i < count; i++) {
266         values.Clear();
267         values.PutInt("id", id);
268         if (dataSize > 0) {
269             values.PutString("name", std::string(dataSize, 'a'));
270         } else {
271             values.PutString("name", std::string("zhangsan"));
272         }
273         values.PutInt("age", CHECKAGE);
274         values.PutDouble("salary", CHECKCOLUMN);
275         values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
276         if (isSlave) {
277             ret = slaveStore->Insert(id, "test", values);
278         } else {
279             ret = store->Insert(id, "test", values);
280         }
281         EXPECT_EQ(ret, E_OK);
282         id++;
283     }
284 }
285 
WaitForBackupFinish(int32_t expectStatus,int maxTimes)286 void RdbDoubleWriteTest::WaitForBackupFinish(int32_t expectStatus, int maxTimes)
287 {
288     int32_t curStatus = store->GetBackupStatus();
289     int tryTimes = 0;
290     while (curStatus != expectStatus && (++tryTimes <= maxTimes)) {
291         usleep(50000); // 50000 delay
292         curStatus = store->GetBackupStatus();
293     }
294     LOG_INFO("----------cur backup Status:%{public}d---------", curStatus);
295     ASSERT_EQ(curStatus, expectStatus);
296 }
297 
WaitForAsyncRepairFinish(int maxTimes)298 void RdbDoubleWriteTest::WaitForAsyncRepairFinish(int maxTimes)
299 {
300     LOG_INFO("---- start wait for async finish----");
301     sleep(1);
302     int tryTimes = 0;
303     auto keyFiles = RdbSecurityManager::KeyFiles(DATABASE_NAME + "-async.restore");
304     while (keyFiles.Lock(false) != E_OK && (++tryTimes <= maxTimes)) {
305         sleep(1);
306     }
307     LOG_INFO("---- end wait for async finish ----, %{public}d", tryTimes);
308 }
309 
TryInterruptBackup()310 void RdbDoubleWriteTest::TryInterruptBackup()
311 {
312     int err = store->InterruptBackup();
313     int tryTimes = 0;
314     while (err != E_OK && (++tryTimes <= 1000)) { // 1000 is try time
315         usleep(10000);                            // 10000 delay
316         err = store->InterruptBackup();
317     }
318     EXPECT_EQ(err, E_OK);
319     LOG_INFO("----------interrupt backup---------");
320 }
321 
CheckResultSet(std::shared_ptr<RdbStore> & store)322 void RdbDoubleWriteTest::CheckResultSet(std::shared_ptr<RdbStore> &store)
323 {
324     std::shared_ptr<ResultSet> resultSet =
325         store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector<std::string>{ "zhangsan" });
326     EXPECT_NE(resultSet, nullptr);
327 
328     int columnIndex;
329     int intVal;
330     std::string strVal;
331     ColumnType columnType;
332     int position;
333     int ret = resultSet->GetRowIndex(position);
334     EXPECT_EQ(ret, E_OK);
335     EXPECT_EQ(position, -1);
336 
337     ret = resultSet->GetColumnType(0, columnType);
338     EXPECT_EQ(ret, E_ROW_OUT_RANGE);
339 
340     ret = resultSet->GoToFirstRow();
341     EXPECT_EQ(ret, E_OK);
342 
343     ret = resultSet->GetColumnIndex("id", columnIndex);
344     EXPECT_EQ(ret, E_OK);
345     EXPECT_EQ(columnIndex, 0);
346     ret = resultSet->GetColumnType(columnIndex, columnType);
347     EXPECT_EQ(ret, E_OK);
348     EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
349     ret = resultSet->GetInt(columnIndex, intVal);
350     EXPECT_EQ(ret, E_OK);
351     EXPECT_EQ(1, intVal);
352 
353     ret = resultSet->GetColumnIndex("name", columnIndex);
354     EXPECT_EQ(ret, E_OK);
355     ret = resultSet->GetColumnType(columnIndex, columnType);
356     EXPECT_EQ(ret, E_OK);
357     EXPECT_EQ(columnType, ColumnType::TYPE_STRING);
358     ret = resultSet->GetString(columnIndex, strVal);
359     EXPECT_EQ(ret, E_OK);
360     EXPECT_EQ("zhangsan", strVal);
361 
362     RdbDoubleWriteTest::CheckAge(resultSet);
363     RdbDoubleWriteTest::CheckSalary(resultSet);
364     RdbDoubleWriteTest::CheckBlob(resultSet);
365 
366     ret = resultSet->GoToNextRow();
367     EXPECT_EQ(ret, E_ROW_OUT_RANGE);
368 
369     ret = resultSet->GetColumnType(columnIndex, columnType);
370     EXPECT_EQ(ret, E_ROW_OUT_RANGE);
371 
372     ret = resultSet->Close();
373     EXPECT_EQ(ret, E_OK);
374 }
375 
CheckAge(std::shared_ptr<ResultSet> & resultSet)376 void RdbDoubleWriteTest::CheckAge(std::shared_ptr<ResultSet> &resultSet)
377 {
378     int columnIndex;
379     int intVal;
380     ColumnType columnType;
381     int ret = resultSet->GetColumnIndex("age", columnIndex);
382     EXPECT_EQ(ret, E_OK);
383     ret = resultSet->GetColumnType(columnIndex, columnType);
384     EXPECT_EQ(ret, E_OK);
385     EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
386     ret = resultSet->GetInt(columnIndex, intVal);
387     EXPECT_EQ(ret, E_OK);
388     EXPECT_EQ(CHECKAGE, intVal);
389 }
390 
CheckSalary(std::shared_ptr<ResultSet> & resultSet)391 void RdbDoubleWriteTest::CheckSalary(std::shared_ptr<ResultSet> &resultSet)
392 {
393     int columnIndex;
394     double dVal;
395     ColumnType columnType;
396     int ret = resultSet->GetColumnIndex("salary", columnIndex);
397     EXPECT_EQ(ret, E_OK);
398     ret = resultSet->GetColumnType(columnIndex, columnType);
399     EXPECT_EQ(ret, E_OK);
400     EXPECT_EQ(columnType, ColumnType::TYPE_FLOAT);
401     ret = resultSet->GetDouble(columnIndex, dVal);
402     EXPECT_EQ(ret, E_OK);
403     EXPECT_EQ(CHECKCOLUMN, dVal);
404 }
405 
CheckBlob(std::shared_ptr<ResultSet> & resultSet)406 void RdbDoubleWriteTest::CheckBlob(std::shared_ptr<ResultSet> &resultSet)
407 {
408     int columnIndex;
409     std::vector<uint8_t> blob;
410     ColumnType columnType;
411     int ret = resultSet->GetColumnIndex("blobType", columnIndex);
412     EXPECT_EQ(ret, E_OK);
413     ret = resultSet->GetColumnType(columnIndex, columnType);
414     EXPECT_EQ(ret, E_OK);
415     EXPECT_EQ(columnType, ColumnType::TYPE_BLOB);
416     ret = resultSet->GetBlob(columnIndex, blob);
417     EXPECT_EQ(ret, E_OK);
418     EXPECT_EQ(BLOB_SIZE, static_cast<int>(blob.size()));
419     for (int i = 0; i < BLOB_SIZE; i++) {
420         EXPECT_EQ(EXPECTED_BLOB_DATA[i], blob[i]);
421     }
422 }
423 
CheckNumber(std::shared_ptr<RdbStore> & store,int num,int errCode,const std::string & tableName)424 void RdbDoubleWriteTest::CheckNumber(
425     std::shared_ptr<RdbStore> &store, int num, int errCode, const std::string &tableName)
426 {
427     std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM " + tableName);
428     ASSERT_NE(resultSet, nullptr);
429     int countNum;
430     int ret = resultSet->GetRowCount(countNum);
431     EXPECT_EQ(ret, errCode);
432     EXPECT_EQ(num, countNum);
433 }
434 
435 /**
436  * @tc.name: RdbStore_DoubleWrite_003
437  * @tc.desc: test RdbStore execute
438  * @tc.type: FUNC
439  */
440 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_003, TestSize.Level1)
441 {
442     InitDb();
443 
444     int64_t id;
445     ValuesBucket values;
446     values.PutInt("id", 1);
447     values.PutString("name", std::string("zhangsan"));
448     values.PutInt("age", 25);
449     values.PutDouble("salary", CHECKCOLUMN);
450     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
451     int ret = store->Insert(id, "test", values);
452     EXPECT_EQ(ret, E_OK);
453     auto [ret2, outValue2] = store->Execute("UPDATE test SET age= 18 WHERE id = 1");
454     EXPECT_EQ(E_OK, ret2);
455 
456     RdbDoubleWriteTest::CheckResultSet(slaveStore);
457 }
458 
459 /**
460  * @tc.name: RdbStore_DoubleWrite_004
461  * @tc.desc: test RdbStore updata
462  * @tc.type: FUNC
463  */
464 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_004, TestSize.Level1)
465 {
466     InitDb();
467 
468     int64_t id;
469 
470     ValuesBucket values;
471     values.PutInt("id", 1);
472     values.PutString("name", std::string("zhangsan"));
473     values.PutInt("age", 25);
474     values.PutDouble("salary", 100.5);
475     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
476     int ret = store->Insert(id, "test", values);
477 
478     int changedRows;
479     values.Clear();
480     values.PutInt("age", 18);
481     ret = store->Update(changedRows, "test", values);
482     EXPECT_EQ(ret, E_OK);
483     EXPECT_EQ(1, changedRows);
484 
485     RdbDoubleWriteTest::CheckResultSet(slaveStore);
486 }
487 
488 /**
489  * @tc.name: RdbStore_DoubleWrite_005
490  * @tc.desc: test RdbStore delete
491  * @tc.type: FUNC
492  */
493 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_005, TestSize.Level1)
494 {
495     InitDb();
496 
497     ValuesBucket values;
498     int64_t id;
499     values.PutInt("id", 1);
500     values.PutString("name", std::string("zhangsan"));
501     values.PutInt("age", 18);
502     values.PutDouble("salary", 100.5);
503     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
504     int ret = store->Insert(id, "test", values);
505     EXPECT_EQ(ret, E_OK);
506     EXPECT_EQ(1, id);
507 
508     values.Clear();
509     values.PutInt("id", 2);
510     values.PutString("name", std::string("lisi"));
511     values.PutInt("age", 18);
512     values.PutDouble("salary", 100.5);
513     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
514     ret = store->Insert(id, "test", values);
515     EXPECT_EQ(ret, E_OK);
516     EXPECT_EQ(2, id);
517 
518     values.Clear();
519     values.PutInt("id", 3);
520     values.PutString("name", std::string("lisi"));
521     values.PutInt("age", 20L);
522     values.PutDouble("salary", 100.5f);
523     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
524     ret = store->Insert(id, "test", values);
525     EXPECT_EQ(ret, E_OK);
526     EXPECT_EQ(3, id);
527 
528     int deletedRows;
529     ret = store->Delete(deletedRows, "test", "id = 2");
530     ret = store->Delete(deletedRows, "test", "id = 3");
531     EXPECT_EQ(ret, E_OK);
532     EXPECT_EQ(1, deletedRows);
533 
534     RdbDoubleWriteTest::CheckNumber(slaveStore, 1);
535 }
536 
537 /**
538  * @tc.name: RdbStore_DoubleWrite_007
539  * @tc.desc: open SINGLE db, write, close, open MAIN_REPLICA db, check slave
540  * @tc.type: FUNC
541  */
542 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_007, TestSize.Level1)
543 {
544     int errCode = E_OK;
545     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
546     config.SetHaMode(HAMode::SINGLE);
547     DoubleWriteTestOpenCallback helper;
548     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
549     EXPECT_NE(store, nullptr);
550 
551     int64_t id = 10;
552     int count = 100;
553     Insert(id, count);
554 
555     store = nullptr;
556     config.SetHaMode(HAMode::MAIN_REPLICA);
557     RdbDoubleWriteTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
558     EXPECT_NE(RdbDoubleWriteTest::store, nullptr);
559 
560     WaitForBackupFinish(BACKUP_FINISHED);
561 
562     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
563     DoubleWriteTestOpenCallback slaveHelper;
564     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
565     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
566 
567     RdbDoubleWriteTest::CheckNumber(RdbDoubleWriteTest::slaveStore, count);
568 }
569 
570 /**
571  * @tc.name: RdbStore_DoubleWrite_008
572  * @tc.desc: open MAIN_REPLICA db, write, close, corrupt, reopen db allow rebuild, db returns to normal
573  * @tc.type: FUNC
574  */
575 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_008, TestSize.Level1)
576 {
577     InitDb();
578     int64_t id = 10;
579     int count = 100;
580     Insert(id, count);
581     LOG_INFO("RdbStore_DoubleWrite_008 insert finish");
582 
583     store = nullptr;
584 
585     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
586     ASSERT_TRUE(file.is_open() == true);
587     file.seekp(30, std::ios::beg);
588     ASSERT_TRUE(file.good() == true);
589     char bytes[2] = { 0x6, 0x6 };
590     file.write(bytes, 2);
591     ASSERT_TRUE(file.good() == true);
592     file.close();
593     LOG_INFO("RdbStore_DoubleWrite_008 corrupt db finish");
594 
595     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
596     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
597     int errCode = E_OK;
598     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
599     config.SetHaMode(HAMode::MAIN_REPLICA);
600     config.SetAllowRebuild(true);
601     DoubleWriteTestOpenCallback helper;
602     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
603     EXPECT_EQ(errCode, E_OK);
604     ASSERT_NE(store, nullptr);
605     RebuiltType rebuiltType;
606     store->GetRebuilt(rebuiltType);
607     EXPECT_EQ(rebuiltType, RebuiltType::REPAIRED);
608     LOG_INFO("RdbStore_DoubleWrite_008 reopen db finish");
609 
610     RdbDoubleWriteTest::CheckNumber(store, count);
611 }
612 
613 /**
614  * @tc.name: RdbStore_DoubleWrite_009
615  * @tc.desc: open MAIN_REPLICA db, write, slave db has 100 more data than main db, restore, check count
616  * @tc.type: FUNC
617  */
618 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_009, TestSize.Level1)
619 {
620     InitDb();
621     int64_t id = 10;
622     Insert(id, 100);
623     id = 200;
624     Insert(id, 100, true);
625     RdbDoubleWriteTest::CheckNumber(store, 100);
626     RdbDoubleWriteTest::CheckNumber(slaveStore, 200);
627     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
628     RdbDoubleWriteTest::CheckNumber(store, 200);
629 }
630 
631 /**
632  * @tc.name: RdbStore_DoubleWrite_010
633  * @tc.desc: open MAIN_REPLICA db, write, close all, corrupt slave, open MAIN_REPLICA db, slave returns to normal
634  * @tc.type: FUNC
635  */
636 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_010, TestSize.Level1)
637 {
638     InitDb();
639     int64_t id = 10;
640     int count = 100;
641     Insert(id, count);
642     LOG_INFO("RdbStore_DoubleWrite_010 insert finish");
643 
644     slaveStore = nullptr;
645     store = nullptr;
646 
647     std::fstream file(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
648     ASSERT_TRUE(file.is_open() == true);
649     file.seekp(30, std::ios::beg);
650     ASSERT_TRUE(file.good() == true);
651     char bytes[2] = { 0x6, 0x6 };
652     file.write(bytes, 2);
653     ASSERT_TRUE(file.good() == true);
654     file.close();
655     LOG_INFO("RdbStore_DoubleWrite_010 corrupt db finish");
656     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
657     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
658 
659     int errCode = E_OK;
660     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
661     config.SetHaMode(HAMode::MAIN_REPLICA);
662     DoubleWriteTestOpenCallback helper;
663     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
664     EXPECT_EQ(errCode, E_OK);
665     ASSERT_NE(store, nullptr);
666     LOG_INFO("RdbStore_DoubleWrite_010 reopen main db finish");
667 
668     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
669     DoubleWriteTestOpenCallback slaveHelper;
670     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
671     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
672     LOG_INFO("RdbStore_DoubleWrite_010 reopen slave db finish");
673     WaitForBackupFinish(BACKUP_FINISHED);
674     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
675 }
676 
677 /**
678  * @tc.name: RdbStore_DoubleWrite_011
679  * @tc.desc: open MAIN_REPLICA db, write, close slave, corrupt slave, backup, check slave
680  * @tc.type: FUNC
681  */
682 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_011, TestSize.Level1)
683 {
684     InitDb();
685     int64_t id = 10;
686     int count = 100;
687     Insert(id, count);
688     LOG_INFO("RdbStore_DoubleWrite_011 insert finish");
689 
690     slaveStore = nullptr;
691 
692     std::fstream file(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
693     ASSERT_TRUE(file.is_open() == true);
694     file.seekp(30, std::ios::beg);
695     ASSERT_TRUE(file.good() == true);
696     char bytes[2] = { 0x6, 0x6 };
697     file.write(bytes, 2);
698     ASSERT_TRUE(file.good() == true);
699     file.close();
700     LOG_INFO("RdbStore_DoubleWrite_011 corrupt db finish");
701 
702     EXPECT_NE(store->Backup(std::string(""), {}), E_OK);
703     LOG_INFO("RdbStore_DoubleWrite_011 backup db finish");
704     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
705 
706     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
707     DoubleWriteTestOpenCallback slaveHelper;
708     int errCode;
709     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
710     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
711     LOG_INFO("RdbStore_DoubleWrite_011 reopen slave db finish");
712 
713     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
714 }
715 
716 /**
717  * @tc.name: RdbStore_DoubleWrite_012
718  * @tc.desc: test RdbStore transaction
719  * @tc.type: FUNC
720  */
721 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_012, TestSize.Level1)
722 {
723     InitDb();
724 
725     int err = store->BeginTransaction();
726     EXPECT_EQ(err, E_OK);
727     int64_t id;
728     ValuesBucket values;
729     values.PutInt("id", 1);
730     values.PutString("name", std::string("zhangsan"));
731     values.PutInt("age", 25);
732     values.PutDouble("salary", CHECKCOLUMN);
733     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
734     int ret = store->Insert(id, "test", values);
735     EXPECT_EQ(ret, E_OK);
736     auto [ret2, outValue2] = store->Execute("UPDATE test SET age= 18 WHERE id = 1");
737     EXPECT_EQ(E_OK, ret2);
738     err = store->Commit();
739     EXPECT_EQ(err, E_OK);
740 
741     RdbDoubleWriteTest::CheckResultSet(slaveStore);
742 }
743 
744 /**
745  * @tc.name: RdbStore_DoubleWrite_013
746  * @tc.desc: open MANUAL_TRIGGER db, open slave, write, slave is empty, backup, check slave, write, check slave
747  * @tc.type: FUNC
748  */
749 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_013, TestSize.Level1)
750 {
751     int errCode = E_OK;
752     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
753     config.SetHaMode(HAMode::MANUAL_TRIGGER);
754     DoubleWriteTestOpenCallback helper;
755     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
756     EXPECT_EQ(errCode, E_OK);
757     ASSERT_NE(store, nullptr);
758     LOG_INFO("RdbStore_DoubleWrite_013 reopen main db finish");
759 
760     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
761     DoubleWriteTestOpenCallback slaveHelper;
762     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
763     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
764     LOG_INFO("RdbStore_DoubleWrite_013 reopen slave db finish");
765 
766     int64_t id = 10;
767     int count = 100;
768     Insert(id, count);
769     LOG_INFO("RdbStore_DoubleWrite_013 insert finish");
770 
771     RdbDoubleWriteTest::CheckNumber(slaveStore, 0);
772 
773     errCode = store->Backup(std::string(""), {});
774     EXPECT_EQ(errCode, E_OK);
775     LOG_INFO("RdbStore_DoubleWrite_013 backup finish");
776 
777     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
778 
779     id = 1000;
780     Insert(id, count);
781     LOG_INFO("RdbStore_DoubleWrite_013 insert finish");
782     RdbDoubleWriteTest::CheckNumber(slaveStore, 200); // 200 is all count
783 }
784 
785 /**
786  * @tc.name: RdbStore_DoubleWrite_014
787  * @tc.desc: open MANUAL_TRIGGER db, write, backup, open slave, check slave, write, check slave
788  * @tc.type: FUNC
789  */
790 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_014, TestSize.Level1)
791 {
792     int errCode = E_OK;
793     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
794     config.SetHaMode(HAMode::MANUAL_TRIGGER);
795     DoubleWriteTestOpenCallback helper;
796     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
797     EXPECT_EQ(errCode, E_OK);
798     ASSERT_NE(store, nullptr);
799     LOG_INFO("RdbStore_DoubleWrite_014 reopen main db finish");
800 
801     int64_t id = 10;
802     int count = 100;
803     Insert(id, count);
804     LOG_INFO("RdbStore_DoubleWrite_014 insert finish");
805 
806     errCode = store->Backup(std::string(""), {});
807     EXPECT_EQ(errCode, E_OK);
808     LOG_INFO("RdbStore_DoubleWrite_014 backup finish");
809 
810     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
811     DoubleWriteTestOpenCallback slaveHelper;
812     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
813     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
814     LOG_INFO("RdbStore_DoubleWrite_014 reopen slave db finish");
815 
816     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
817 
818     id = 1000;
819     Insert(id, count);
820     LOG_INFO("RdbStore_DoubleWrite_014 insert finish");
821     RdbDoubleWriteTest::CheckNumber(slaveStore, 200); // 200 is all count
822 }
823 
824 /**
825  * @tc.name: RdbStore_DoubleWrite_015
826  * @tc.desc: open MAIN_REPLICA db, write, close, corrupt, slave create table, open MAIN_REPLICA db. check count
827  * @tc.type: FUNC
828  */
829 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_015, TestSize.Level1)
830 {
831     InitDb();
832     int64_t id = 10;
833     int count = 100;
834     ValuesBucket values;
835     for (int i = 0; i < count; i++) {
836         id++;
837         values.Clear();
838         values.PutInt("id", id);
839         values.PutString("name", std::string("zhangsan"));
840         values.PutInt("age", 18);
841         values.PutDouble("salary", CHECKCOLUMN);
842         values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
843         int ret = store->Insert(id, "test", values);
844         EXPECT_EQ(ret, E_OK);
845     }
846     LOG_INFO("RdbStore_DoubleWrite_015 insert finish");
847 
848     store = nullptr;
849 
850     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
851     ASSERT_TRUE(file.is_open() == true);
852     file.seekp(30, std::ios::beg);
853     ASSERT_TRUE(file.good() == true);
854     char bytes[2] = { 0x6, 0x6 };
855     file.write(bytes, 2);
856     ASSERT_TRUE(file.good() == true);
857     file.close();
858     LOG_INFO("RdbStore_DoubleWrite_015 corrupt db finish");
859     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
860     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
861 
862     int errCode = slaveStore->ExecuteSql("CREATE TABLE IF NOT EXISTS xx (id INTEGER PRIMARY KEY AUTOINCREMENT,"
863                                          "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
864     EXPECT_EQ(errCode, E_OK);
865     EXPECT_EQ(slaveStore->Insert(id, "xx", values), E_OK);
866 
867     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
868     config.SetHaMode(HAMode::MAIN_REPLICA);
869     config.SetAllowRebuild(true);
870     DoubleWriteTestOpenCallback helper;
871     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
872     EXPECT_EQ(errCode, E_OK);
873     ASSERT_NE(store, nullptr);
874     LOG_INFO("RdbStore_DoubleWrite_015 reopen db finish");
875 
876     RdbDoubleWriteTest::CheckNumber(store, 1, E_OK, std::string("xx"));
877     RdbDoubleWriteTest::CheckNumber(store, count);
878     RdbDoubleWriteTest::CheckNumber(slaveStore, 1, E_OK, std::string("xx"));
879     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
880 }
881 
882 /**
883  * @tc.name: RdbStore_DoubleWrite_016
884  * @tc.desc: open MAIN_REPLICA db, write, close, delete db file, reopen, check count
885  * @tc.type: FUNC
886  */
887 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_016, TestSize.Level1)
888 {
889     InitDb();
890     int64_t id = 10;
891     int count = 100;
892     Insert(id, count);
893     LOG_INFO("RdbStore_DoubleWrite_016 insert finish");
894 
895     store = nullptr;
896     LOG_INFO("RdbStore_DoubleWrite_016 close finish");
897 
898     SqliteUtils::DeleteFile(DATABASE_NAME);
899     SqliteUtils::DeleteFile(DATABASE_NAME + "-shm");
900     SqliteUtils::DeleteFile(DATABASE_NAME + "-wal");
901     LOG_INFO("RdbStore_DoubleWrite_016 delete db file finish");
902 
903     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
904     config.SetHaMode(HAMode::MAIN_REPLICA);
905     DoubleWriteTestOpenCallback helper;
906     int errCode;
907     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
908     EXPECT_EQ(errCode, E_OK);
909     ASSERT_NE(store, nullptr);
910     LOG_INFO("RdbStore_DoubleWrite_016 reopen db finish");
911 
912     WaitForBackupFinish(BACKUP_FINISHED);
913 
914     RdbDoubleWriteTest::CheckNumber(store, count);
915     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
916 }
917 
918 /**
919  * @tc.name: RdbStore_DoubleWrite_018
920  * @tc.desc: open MAIN_REPLICA db, update slave, insert, M succ && S failed,
921  *           check failureFlag, backup, check failureFlag
922  * @tc.type: FUNC
923  */
924 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_018, TestSize.Level1)
925 {
926     InitDb();
927 
928     int64_t id;
929     ValuesBucket values;
930     values.PutInt("id", 1);
931     values.PutString("name", std::string("zhangsan"));
932     values.PutInt("age", 25);
933     values.PutDouble("salary", CHECKCOLUMN);
934     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
935     int ret = store->Insert(id, "test", values);
936     EXPECT_EQ(ret, E_OK);
937 
938     auto [ret2, outValue2] = slaveStore->Execute("UPDATE test SET id = 3 WHERE id = 1");
939     EXPECT_EQ(E_OK, ret2);
940 
941     int64_t id2;
942     ValuesBucket values2;
943     values2.PutInt("id", 3);
944     values2.PutString("name", std::string("zhangsan"));
945     values2.PutInt("age", 25);
946     values2.PutDouble("salary", CHECKCOLUMN);
947     values2.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
948     int ret3 = store->Insert(id2, "test", values2);
949     EXPECT_EQ(E_OK, ret3);
950     std::string failureFlagPath = RdbDoubleWriteTest::DATABASE_NAME + +"-slaveFailure";
951     bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
952     ASSERT_TRUE(isFlagFileExists);
953     ASSERT_TRUE(store->IsSlaveDiffFromMaster());
954 
955     int errCode;
956     errCode = store->Backup(std::string(""), {});
957     EXPECT_EQ(errCode, E_OK);
958     isFlagFileExists = OHOS::FileExists(failureFlagPath);
959     ASSERT_FALSE(isFlagFileExists);
960 }
961 
962 /**
963  * @tc.name: RdbStore_DoubleWrite_019
964  * @tc.desc: open MAIN_REPLICA db, update slave, insert, M succ && S failed,
965  *           check failureFlag, reopen, check failureFlag
966  * @tc.type: FUNC
967  */
968 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_019, TestSize.Level1)
969 {
970     InitDb();
971 
972     int64_t id;
973     ValuesBucket values;
974     values.PutInt("id", 1);
975     values.PutString("name", std::string("zhangsan"));
976     values.PutInt("age", 25);
977     values.PutDouble("salary", CHECKCOLUMN);
978     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
979     int ret = store->Insert(id, "test", values);
980     EXPECT_EQ(ret, E_OK);
981 
982     auto [ret2, outValue2] = slaveStore->Execute("UPDATE test SET id = 3 WHERE id = 1");
983     EXPECT_EQ(E_OK, ret2);
984 
985     int64_t id2;
986     ValuesBucket values2;
987     values2.PutInt("id", 3);
988     values2.PutString("name", std::string("zhangsan"));
989     values2.PutInt("age", 25);
990     values2.PutDouble("salary", CHECKCOLUMN);
991     values2.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
992     int ret3 = store->Insert(id2, "test", values2);
993     EXPECT_EQ(E_OK, ret3);
994     std::string failureFlagPath = RdbDoubleWriteTest::DATABASE_NAME + +"-slaveFailure";
995     bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
996     ASSERT_TRUE(isFlagFileExists);
997     ASSERT_TRUE(store->IsSlaveDiffFromMaster());
998 
999     store = nullptr;
1000     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1001     config.SetHaMode(HAMode::MAIN_REPLICA);
1002     config.SetAllowRebuild(true);
1003     DoubleWriteTestOpenCallback helper;
1004     int errCode;
1005     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1006     WaitForBackupFinish(BACKUP_FINISHED);
1007     store = nullptr;
1008     isFlagFileExists = OHOS::FileExists(failureFlagPath);
1009     ASSERT_FALSE(isFlagFileExists);
1010 }
1011 
1012 /**
1013  * @tc.name: RdbStore_DoubleWrite_026
1014  * @tc.desc: open MANUAL_TRIGGER db, write, restore, insert, check count
1015  * @tc.type: FUNC
1016  */
1017 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_026, TestSize.Level1)
1018 {
1019     int errCode = E_OK;
1020     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1021     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1022     DoubleWriteTestOpenCallback helper;
1023     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1024     EXPECT_EQ(errCode, E_OK);
1025     ASSERT_NE(store, nullptr);
1026 
1027     int64_t id = 10;
1028     int count = 100;
1029     Insert(id, count);
1030 
1031     EXPECT_EQ(store->Restore(std::string(""), {}), E_INVALID_FILE_PATH);
1032 
1033     id = 2000;
1034     Insert(id, count);
1035     RdbDoubleWriteTest::CheckNumber(store, count + count);
1036 }
1037 
1038 /**
1039  * @tc.name: RdbStore_DoubleWrite_027
1040  * @tc.desc: open MANUAL_TRIGGER db, write, close, corrupt db, reopen, insert, check count
1041  * @tc.type: FUNC
1042  */
1043 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_027, TestSize.Level1)
1044 {
1045     int errCode = E_OK;
1046     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1047     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1048     config.SetAllowRebuild(true);
1049     DoubleWriteTestOpenCallback helper;
1050 
1051     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1052     DoubleWriteTestOpenCallback slaveHelper;
1053     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1054     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1055 
1056     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1057     EXPECT_EQ(errCode, E_OK);
1058     ASSERT_NE(store, nullptr);
1059 
1060     int64_t id = 10;
1061     int count = 100;
1062     Insert(id, count);
1063     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1064 
1065     store = nullptr;
1066 
1067     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1068     ASSERT_TRUE(file.is_open() == true);
1069     file.seekp(30, std::ios::beg);
1070     ASSERT_TRUE(file.good() == true);
1071     char bytes[2] = { 0x6, 0x6 };
1072     file.write(bytes, 2);
1073     ASSERT_TRUE(file.good() == true);
1074     file.close();
1075 
1076     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1077     EXPECT_EQ(errCode, E_OK);
1078     ASSERT_NE(store, nullptr);
1079 
1080     id = 1000;
1081     Insert(id, count);
1082     RdbDoubleWriteTest::CheckNumber(store, count + count);
1083 }
1084 
1085 /**
1086  * @tc.name: RdbStore_DoubleWrite_029
1087  * @tc.desc: open db, write, corrupt slave db, backup, backup, check count
1088  * @tc.type: FUNC
1089  */
1090 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_029, TestSize.Level1)
1091 {
1092     InitDb();
1093     int64_t id = 10;
1094     int count = 100;
1095     Insert(id, count);
1096 
1097     std::fstream slaveFile(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::trunc);
1098     ASSERT_TRUE(slaveFile.is_open() == true);
1099     slaveFile << "0000";
1100     slaveFile.flush();
1101     slaveFile.close();
1102 
1103     std::fstream slaveWalFile(SLAVE_DATABASE_NAME + "-wal", std::ios::in | std::ios::out | std::ios::trunc);
1104     ASSERT_TRUE(slaveWalFile.is_open() == true);
1105     slaveWalFile << "0000";
1106     slaveWalFile.flush();
1107     slaveWalFile.close();
1108 
1109     EXPECT_NE(store->Backup(std::string(""), {}), E_OK);
1110     LOG_INFO("RdbStore_DoubleWrite_029 backup again");
1111     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
1112 
1113     RdbDoubleWriteTest::CheckNumber(store, count);
1114     RdbDoubleWriteTest::CheckNumber(slaveStore, -1, E_SQLITE_CORRUPT);
1115 
1116     int errCode = E_OK;
1117     slaveStore = nullptr;
1118     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1119     DoubleWriteTestOpenCallback slaveHelper;
1120     RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1121     EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1122 
1123     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1124 }
1125 
1126 /**
1127  * @tc.name: RdbStore_DoubleWrite_030
1128  * @tc.desc: open db, write, update slave, insert, check failure, restore, check count
1129  * @tc.type: FUNC
1130  */
1131 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_030, TestSize.Level1)
1132 {
1133     InitDb();
1134     int64_t id = 10;
1135     int count = 100;
1136     Insert(id, count);
1137 
1138     auto [ret2, outValue2] = slaveStore->Execute("UPDATE test SET id = 666 WHERE id = 22");
1139     EXPECT_EQ(E_OK, ret2);
1140 
1141     id = 666;
1142     Insert(id, 1);
1143 
1144     std::string failureFlagPath = RdbDoubleWriteTest::DATABASE_NAME + +"-slaveFailure";
1145     bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
1146     ASSERT_TRUE(isFlagFileExists);
1147 
1148     EXPECT_NE(store->Restore(std::string(""), {}), E_OK);
1149 
1150     RdbDoubleWriteTest::CheckNumber(store, count + 1);
1151     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1152 }
1153 
1154 /**
1155  * @tc.name: RdbStore_DoubleWrite_031
1156  * @tc.desc: open db, delete main.db, deleteRdbStore, check slave db
1157  * @tc.type: FUNC
1158  */
1159 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_031, TestSize.Level1)
1160 {
1161     InitDb();
1162     remove(RdbDoubleWriteTest::DATABASE_NAME.c_str());
1163     RdbHelper::DeleteRdbStore(RdbDoubleWriteTest::DATABASE_NAME);
1164     EXPECT_NE(access(RdbDoubleWriteTest::SLAVE_DATABASE_NAME.c_str(), F_OK), 0);
1165 }
1166 
1167 /**
1168  * @tc.name: RdbStore_DoubleWrite_032
1169  * @tc.desc: open db, delete main.db, deleteRdbStore, check slave db
1170  * @tc.type: FUNC
1171  */
1172 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_032, TestSize.Level1)
1173 {
1174     InitDb();
1175     remove(RdbDoubleWriteTest::DATABASE_NAME.c_str());
1176     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1177     RdbHelper::DeleteRdbStore(config);
1178     EXPECT_NE(access(RdbDoubleWriteTest::SLAVE_DATABASE_NAME.c_str(), F_OK), 0);
1179 }
1180 
1181 /**
1182  * @tc.name: RdbStore_DoubleWrite_033
1183  * @tc.desc: open db, write, close, corrupt, open SINGLE db, check
1184  * @tc.type: FUNC
1185  */
1186 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_033, TestSize.Level1)
1187 {
1188     InitDb();
1189     int64_t id = 10;
1190     int count = 100;
1191     Insert(id, count);
1192 
1193     store = nullptr;
1194     slaveStore = nullptr;
1195 
1196     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1197     ASSERT_TRUE(file.is_open() == true);
1198     file.seekp(30, std::ios::beg);
1199     ASSERT_TRUE(file.good() == true);
1200     char bytes[2] = { 0x6, 0x6 };
1201     file.write(bytes, 2);
1202     ASSERT_TRUE(file.good() == true);
1203     file.close();
1204 
1205     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
1206     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
1207     int errCode = E_OK;
1208     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1209     config.SetHaMode(HAMode::SINGLE);
1210     DoubleWriteTestOpenCallback helper;
1211     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1212     EXPECT_EQ(errCode, E_OK);
1213     ASSERT_NE(store, nullptr);
1214 
1215     RebuiltType rebuiltType;
1216     store->GetRebuilt(rebuiltType);
1217     EXPECT_EQ(rebuiltType, RebuiltType::REPAIRED);
1218 
1219     RdbDoubleWriteTest::CheckNumber(store, count);
1220 }
1221 
1222 /**
1223  * @tc.name: RdbStore_DoubleWrite_034
1224  * @tc.desc: open db, close, open SINGLE db, create index, write, reopen, check slave db
1225  * @tc.type: FUNC
1226  */
1227 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_034, TestSize.Level1)
1228 {
1229     InitDb();
1230     store = nullptr;
1231     slaveStore = nullptr;
1232     int errCode = E_OK;
1233     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1234     config.SetHaMode(HAMode::SINGLE);
1235     DoubleWriteTestOpenCallback helper;
1236     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1237     EXPECT_EQ(errCode, E_OK);
1238     ASSERT_NE(store, nullptr);
1239     EXPECT_EQ(store->ExecuteSql("CREATE index age_index ON test(age);"), E_OK);
1240     int64_t id = 10;
1241     int count = 10;
1242     Insert(id, count);
1243     store = nullptr;
1244 
1245     config.SetHaMode(HAMode::MAIN_REPLICA);
1246     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1247     ASSERT_NE(store, nullptr);
1248     RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1249     DoubleWriteTestOpenCallback slaveHelper;
1250     slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
1251     ASSERT_NE(RdbDoubleWriteTest::slaveStore, nullptr);
1252     WaitForBackupFinish(BACKUP_FINISHED);
1253     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1254     store = nullptr;
1255     slaveStore = nullptr;
1256 }
1257 
1258 /**
1259  * @tc.name: RdbStore_DoubleWrite_Manual_Trigger_Not_Verify_Db
1260  * @tc.desc: open MANUAL_TRIGGER db, write, corrupt db, check backup with verify and no verify
1261  * @tc.type: FUNC
1262  */
1263 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Manual_Trigger_Not_Verify_Db, TestSize.Level0)
1264 {
1265     int errCode = E_OK;
1266     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1267     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1268     DoubleWriteTestOpenCallback helper;
1269     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1270     EXPECT_EQ(errCode, E_OK);
1271     ASSERT_NE(store, nullptr);
1272     LOG_INFO("RdbStore_DoubleWrite_Manual_Trigger_Not_Verify_Db reopen main db finish");
1273 
1274     int64_t id = 10;
1275     int count = 100;
1276     Insert(id, count);
1277     LOG_INFO("RdbStore_DoubleWrite_Manual_Trigger_Not_Verify_Db insert finish");
1278 
1279     RdbDoubleWriteTest::CheckNumber(store, count);
1280     store = nullptr;
1281 
1282     std::fstream file(RdbDoubleWriteTest::DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1283     ASSERT_TRUE(file.is_open());
1284 
1285     file.seekp(0x2000, std::ios::beg);
1286     ASSERT_TRUE(file.good());
1287 
1288     char bytes[128];
1289     std::fill_n(bytes, 128, 0xff);
1290     file.write(bytes, 128);
1291     file.flush();
1292     file.close();
1293     LOG_INFO("RdbStore_DoubleWrite_Manual_Trigger_Not_Verify_Db corrupt db finish");
1294 
1295     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1296     EXPECT_EQ(errCode, E_OK);
1297     ASSERT_NE(store, nullptr);
1298 
1299     errCode = store->Backup(std::string(""));
1300     EXPECT_EQ(errCode, E_SQLITE_CORRUPT);
1301 
1302     errCode = store->Backup(std::string(""), {}, false);
1303     EXPECT_EQ(errCode, E_OK);
1304     store = nullptr;
1305 }
1306 
1307 /**
1308  * @tc.name: RdbStore_DoubleWrite_Huge_DB_001
1309  * @tc.desc: test db is deleted while open huge database, in MANUAL_TRIGGER
1310  * @tc.type: FUNC
1311  */
1312 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_001, TestSize.Level3)
1313 {
1314     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_001 ----");
1315     InitDb(HAMode::MANUAL_TRIGGER);
1316     int errCode = store->Backup(std::string(""), {});
1317     EXPECT_EQ(errCode, E_OK);
1318     int64_t id = 10;
1319     int count = 200;
1320     LOG_INFO("---- step 1: insert huge data ----");
1321     Insert(id, count, false, HUGE_DATA_SIZE);
1322     RdbDoubleWriteTest::CheckNumber(store, count);
1323     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1324     LOG_INFO("---- step 2: close store ----");
1325     store = nullptr;
1326     slaveStore = nullptr;
1327     LOG_INFO("---- step 3: remove db file ----");
1328     remove(RdbDoubleWriteTest::DATABASE_NAME.c_str());
1329     LOG_INFO("---- step 4: reopen and trigger restore ----");
1330     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
1331     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
1332     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1333     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1334     DoubleWriteTestOpenCallback helper;
1335     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1336     if (errCode != E_SQLITE_BUSY) {
1337         EXPECT_EQ(errCode, E_OK);
1338         ASSERT_NE(store, nullptr);
1339         LOG_INFO("---- step 5: execute sql while restore ----");
1340         EXPECT_EQ(store->ExecuteSql("select * from test;"), E_DATABASE_BUSY);
1341         LOG_INFO("---- step 6: check db count ----");
1342         RdbDoubleWriteTest::WaitForAsyncRepairFinish();
1343         RdbDoubleWriteTest::CheckNumber(store, count);
1344     }
1345     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_001 ----");
1346 }
1347 
1348 /**
1349  * @tc.name: RdbStore_DoubleWrite_Huge_DB_002
1350  * @tc.desc: test db is deleted while open huge database, in MAIN_REPLICA
1351  * @tc.type: FUNC
1352  */
1353 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_002, TestSize.Level3)
1354 {
1355     if (!IsUsingArkData()) {
1356         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1357     }
1358     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_002 ----");
1359     InitDb();
1360     int64_t id = 10;
1361     int count = 200;
1362     LOG_INFO("---- step 1: insert huge data ----");
1363     Insert(id, count, false, HUGE_DATA_SIZE);
1364     RdbDoubleWriteTest::CheckNumber(store, count);
1365     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1366     LOG_INFO("---- step 2: close store ----");
1367     store = nullptr;
1368     slaveStore = nullptr;
1369     LOG_INFO("---- step 3: remove db file ----");
1370     remove(RdbDoubleWriteTest::DATABASE_NAME.c_str());
1371     LOG_INFO("---- step 4: reopen and trigger restore ----");
1372     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
1373     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
1374     int errCode = E_OK;
1375     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1376     config.SetHaMode(HAMode::MAIN_REPLICA);
1377     DoubleWriteTestOpenCallback helper;
1378     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1379     if (errCode != E_SQLITE_BUSY) {
1380         EXPECT_EQ(errCode, E_OK);
1381         ASSERT_NE(store, nullptr);
1382         LOG_INFO("---- step 5: execute sql while restore ----");
1383         EXPECT_EQ(store->ExecuteSql("select * from test;"), E_DATABASE_BUSY);
1384         LOG_INFO("---- step 6: check db count ----");
1385         RdbDoubleWriteTest::WaitForAsyncRepairFinish();
1386         RdbDoubleWriteTest::CheckNumber(store, count);
1387     }
1388     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_002 ----");
1389 }
1390 
1391 /**
1392  * @tc.name: RdbStore_DoubleWrite_Huge_DB_003
1393  * @tc.desc: test async restore for huge db in MAIN_REPLICA
1394  * @tc.type: FUNC
1395  */
1396 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_003, TestSize.Level3)
1397 {
1398     if (!IsUsingArkData()) {
1399         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1400     }
1401     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_003 ----");
1402     InitDb();
1403     int64_t id = 10;
1404     int count = 200;
1405     LOG_INFO("---- step 1: insert huge data ----");
1406     Insert(id, count, false, HUGE_DATA_SIZE);
1407     RdbDoubleWriteTest::CheckNumber(store, count);
1408     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1409     LOG_INFO("---- step 2: corrupt store ----");
1410     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1411     ASSERT_TRUE(file.is_open() == true);
1412     file.seekp(30, std::ios::beg);
1413     ASSERT_TRUE(file.good() == true);
1414     char bytes[2] = { 0x6, 0x6 };
1415     file.write(bytes, 2);
1416     ASSERT_TRUE(file.good() == true);
1417     file.close();
1418     LOG_INFO("---- step 3: manually trigger repair ----");
1419     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
1420     EXPECT_EQ(store->ExecuteSql("select * from test;"), E_DATABASE_BUSY);
1421     LOG_INFO("---- step 4: check db count ----");
1422     RdbDoubleWriteTest::WaitForAsyncRepairFinish();
1423     RdbDoubleWriteTest::CheckNumber(store, count);
1424     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_003 ----");
1425 }
1426 
1427 /**
1428  * @tc.name: RdbStore_DoubleWrite_Huge_DB_004
1429  * @tc.desc: test async restore for huge db in MANUAL_TRIGGER
1430  * @tc.type: FUNC
1431  */
1432 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_004, TestSize.Level3)
1433 {
1434     if (!IsUsingArkData()) {
1435         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1436     }
1437     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_004 ----");
1438     InitDb(HAMode::MANUAL_TRIGGER);
1439     int errCode = store->Backup(std::string(""), {});
1440     EXPECT_EQ(errCode, E_OK);
1441     int64_t id = 10;
1442     int count = 200;
1443     LOG_INFO("---- step 1: insert huge data ----");
1444     Insert(id, count, false, HUGE_DATA_SIZE);
1445     RdbDoubleWriteTest::CheckNumber(store, count);
1446     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1447     LOG_INFO("---- step 2: corrupt store ----");
1448     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1449     ASSERT_TRUE(file.is_open() == true);
1450     file.seekp(30, std::ios::beg);
1451     ASSERT_TRUE(file.good() == true);
1452     char bytes[2] = { 0x6, 0x6 };
1453     file.write(bytes, 2);
1454     ASSERT_TRUE(file.good() == true);
1455     file.close();
1456     LOG_INFO("---- step 3: manually trigger repair ----");
1457     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
1458     EXPECT_EQ(store->ExecuteSql("select * from test;"), E_DATABASE_BUSY);
1459     LOG_INFO("---- step 4: check db count ----");
1460     RdbDoubleWriteTest::WaitForAsyncRepairFinish();
1461     RdbDoubleWriteTest::CheckNumber(store, count);
1462     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_004 ----");
1463 }
1464 
1465 /**
1466  * @tc.name: RdbStore_DoubleWrite_Huge_DB_005
1467  * @tc.desc: test restore is called while doing async restore
1468  * @tc.type: FUNC
1469  */
1470 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_005, TestSize.Level3)
1471 {
1472     if (!IsUsingArkData()) {
1473         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1474     }
1475     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_005 ----");
1476     InitDb(HAMode::MANUAL_TRIGGER);
1477     int errCode = store->Backup(std::string(""), {});
1478     EXPECT_EQ(errCode, E_OK);
1479     int64_t id = 10;
1480     int count = 200;
1481     LOG_INFO("---- step 1: insert huge data ----");
1482     Insert(id, count, false, HUGE_DATA_SIZE);
1483     RdbDoubleWriteTest::CheckNumber(store, count);
1484     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1485     LOG_INFO("---- step 2: corrupt store ----");
1486     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1487     ASSERT_TRUE(file.is_open() == true);
1488     file.seekp(30, std::ios::beg);
1489     ASSERT_TRUE(file.good() == true);
1490     char bytes[2] = { 0x6, 0x6 };
1491     file.write(bytes, 2);
1492     ASSERT_TRUE(file.good() == true);
1493     file.close();
1494     LOG_INFO("---- step 3: manually trigger repair ----");
1495     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
1496     EXPECT_EQ(store->ExecuteSql("select * from test;"), E_DATABASE_BUSY);
1497     LOG_INFO("---- step 4: trigger repair again ----");
1498     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
1499     LOG_INFO("---- step 5: check db count ----");
1500     RdbDoubleWriteTest::WaitForAsyncRepairFinish();
1501     RdbDoubleWriteTest::CheckNumber(store, count);
1502     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_005 ----");
1503 }
1504 
1505 /**
1506  * @tc.name: RdbStore_DoubleWrite_Huge_DB_006
1507  * @tc.desc: test call restore for huge db when slave db is corrupted
1508  * @tc.type: FUNC
1509  */
1510 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_006, TestSize.Level3)
1511 {
1512     if (!IsUsingArkData()) {
1513         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1514     }
1515     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_006 ----");
1516     InitDb(HAMode::MANUAL_TRIGGER);
1517     int errCode = store->Backup(std::string(""), {});
1518     EXPECT_EQ(errCode, E_OK);
1519     int64_t id = 10;
1520     int count = 200;
1521     LOG_INFO("---- step 1: insert huge data ----");
1522     Insert(id, count, false, HUGE_DATA_SIZE);
1523     RdbDoubleWriteTest::CheckNumber(store, count);
1524     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1525     LOG_INFO("---- step 2: corrupt store ----");
1526     std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1527     ASSERT_TRUE(file.is_open() == true);
1528     file.seekp(30, std::ios::beg);
1529     ASSERT_TRUE(file.good() == true);
1530     char bytes[2] = { 0x6, 0x6 };
1531     file.write(bytes, 2);
1532     ASSERT_TRUE(file.good() == true);
1533     file.close();
1534     LOG_INFO("---- step 3: mark backup db corrupted ----");
1535     SqliteUtils::SetSlaveInvalid(DATABASE_NAME);
1536     EXPECT_TRUE(SqliteUtils::IsSlaveInvalid(DATABASE_NAME));
1537     LOG_INFO("---- step 4: manually trigger repair ----");
1538     EXPECT_EQ(store->Restore(std::string(""), {}), E_SQLITE_CORRUPT);
1539     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_006 ----");
1540 }
1541 
1542 /**
1543  * @tc.name: RdbStore_DoubleWrite_Huge_DB_007
1544  * @tc.desc: test execsql when restore mark is abnormal
1545  * @tc.type: FUNC
1546  */
1547 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_007, TestSize.Level3)
1548 {
1549     if (!IsUsingArkData()) {
1550         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1551     }
1552     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_007 ----");
1553     InitDb(HAMode::MANUAL_TRIGGER);
1554     int errCode = store->Backup(std::string(""), {});
1555     EXPECT_EQ(errCode, E_OK);
1556     int64_t id = 10;
1557     int count = 200;
1558     LOG_INFO("---- step 1: insert huge data ----");
1559     Insert(id, count, false, HUGE_DATA_SIZE);
1560     RdbDoubleWriteTest::CheckNumber(store, count);
1561     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1562     LOG_INFO("---- step 2: mark backup db as restoring ----");
1563     SqliteUtils::SetSlaveRestoring(DATABASE_NAME);
1564     EXPECT_TRUE(SqliteUtils::IsSlaveRestoring(DATABASE_NAME));
1565     LOG_INFO("---- step 3: manually trigger create statement should remove the mark ----");
1566     EXPECT_EQ(store->ExecuteSql("select * from test;"), E_OK);
1567     EXPECT_FALSE(SqliteUtils::IsSlaveRestoring(DATABASE_NAME));
1568     LOG_INFO("---- step 4: lock database for restoring and trigger create statement should not remove the mark  ----");
1569     SqliteUtils::SetSlaveRestoring(DATABASE_NAME);
1570     EXPECT_TRUE(SqliteUtils::IsSlaveRestoring(DATABASE_NAME));
1571     auto keyFiles = RdbSecurityManager::KeyFiles(DATABASE_NAME + "-async.restore");
1572     EXPECT_EQ(keyFiles.Lock(false), E_OK);
1573     LOG_INFO("---- step 5: manually trigger create statement should not remove the mark ----");
1574     EXPECT_EQ(store->ExecuteSql("select * from test;"), E_DATABASE_BUSY);
1575     EXPECT_TRUE(SqliteUtils::IsSlaveRestoring(DATABASE_NAME));
1576     SqliteUtils::SetSlaveRestoring(DATABASE_NAME, false);
1577     keyFiles.Unlock();
1578     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_007 ----");
1579 }
1580 
1581 /**
1582  * @tc.name: RdbStore_DoubleWrite_Huge_DB_008
1583  * @tc.desc: test trigger async repair
1584  * @tc.type: FUNC
1585  */
1586 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_008, TestSize.Level3)
1587 {
1588     if (!IsUsingArkData()) {
1589         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1590     }
1591     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_008 ----");
1592     InitDb(HAMode::MANUAL_TRIGGER);
1593     int errCode = store->Backup(std::string(""), {});
1594     EXPECT_EQ(errCode, E_OK);
1595     int64_t id = 10;
1596     int count = 200;
1597     LOG_INFO("---- step 1: insert huge data ----");
1598     Insert(id, count, false, HUGE_DATA_SIZE);
1599     RdbDoubleWriteTest::CheckNumber(store, count);
1600     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1601     LOG_INFO("---- step 2: corrupt both slave and master db ----");
1602     store = nullptr;
1603     slaveStore = nullptr;
1604     EXPECT_TRUE(SqliteUtils::CopyFile(DATABASE_NAME + "-dwr", DATABASE_NAME));
1605     std::fstream file(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary);
1606     file.seekp(1, std::ios::beg);
1607     std::vector<char> null_buffer(count, '\0');
1608     file.write(null_buffer.data(), count);
1609     file.close();
1610     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
1611     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
1612     SqliteUtils::SetSlaveInvalid(DATABASE_NAME);
1613     EXPECT_TRUE(SqliteUtils::IsSlaveInvalid(DATABASE_NAME));
1614 
1615     LOG_INFO("---- step 3: reopen should give E_SQLITE_CORRUPT ----");
1616     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1617     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1618     DoubleWriteTestOpenCallback helper;
1619     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1620     EXPECT_EQ(errCode, E_SQLITE_CORRUPT);
1621     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_008 ----");
1622 }
1623 
1624 /**
1625  * @tc.name: RdbStore_DoubleWrite_Huge_DB_009
1626  * @tc.desc: test trigger async repair
1627  * @tc.type: FUNC
1628  */
1629 HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_Huge_DB_009, TestSize.Level3)
1630 {
1631     if (!IsUsingArkData()) {
1632         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1633     }
1634     LOG_INFO("---- start RdbStore_DoubleWrite_Huge_DB_009 ----");
1635     InitDb(HAMode::MANUAL_TRIGGER);
1636     int errCode = store->Backup(std::string(""), {});
1637     EXPECT_EQ(errCode, E_OK);
1638     int64_t id = 10;
1639     int count = 200;
1640     LOG_INFO("---- step 1: insert huge data ----");
1641     Insert(id, count, false, HUGE_DATA_SIZE);
1642     RdbDoubleWriteTest::CheckNumber(store, count);
1643     RdbDoubleWriteTest::CheckNumber(slaveStore, count);
1644     LOG_INFO("---- step 2: corrupt master db ----");
1645     store = nullptr;
1646     slaveStore = nullptr;
1647     EXPECT_TRUE(SqliteUtils::CopyFile(DATABASE_NAME + "-dwr", DATABASE_NAME));
1648     SqliteUtils::DeleteFile(RdbDoubleWriteTest::DATABASE_NAME + "-dwr");
1649     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME + "-dwr");
1650     LOG_INFO("---- step 3: reopen should give ok ----");
1651     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1652     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1653     DoubleWriteTestOpenCallback helper;
1654     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1655     if (errCode != E_SQLITE_BUSY) {
1656         EXPECT_EQ(errCode, E_OK);
1657         ASSERT_NE(store, nullptr);
1658         LOG_INFO("---- step 4: trigger statement should busy ----");
1659         EXPECT_EQ(store->ExecuteSql("select * from test;"), E_DATABASE_BUSY);
1660         store = nullptr;
1661     }
1662     LOG_INFO("---- step 5: check db count ----");
1663     RdbDoubleWriteTest::WaitForAsyncRepairFinish();
1664     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1665     ASSERT_NE(store, nullptr);
1666     RdbDoubleWriteTest::CheckNumber(store, count);
1667     LOG_INFO("---- end RdbStore_DoubleWrite_Huge_DB_009 ----");
1668 }
1669 
1670 /*
1671  * @tc.name: RdbStore_Mock_Binlog_001
1672  * @tc.desc: test call backup and restore when binlog is supported
1673  * @tc.type: FUNC
1674  */
1675 HWTEST_F(RdbDoubleWriteTest, RdbStore_Mock_Binlog_001, TestSize.Level0)
1676 {
1677     if (!IsUsingArkData()) {
1678         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1679     }
1680     mockExtraApi.is_support_binlog = MockSupportBinlog;
1681     sqlite3_export_extra_symbols = &mockExtraApi;
1682 #ifndef CROSS_PLATFORM
1683     mockKvApi.is_support_binlog = MockSupportBinlogWithParam;
1684     sqlite3_export_relational_symbols = &mockKvApi;
1685 #endif
1686 
1687     InitDb(HAMode::MANUAL_TRIGGER, false);
1688     EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
1689     EXPECT_EQ(store->Restore(std::string(""), {}), E_OK);
1690 }
1691 
1692 /*
1693  * @tc.name: RdbStore_Mock_Binlog_002
1694  * @tc.desc: test call CheckReplicaIntegrity when binlog is supported
1695  * @tc.type: FUNC
1696  */
1697 HWTEST_F(RdbDoubleWriteTest, RdbStore_Mock_Binlog_002, TestSize.Level0)
1698 {
1699     if (!IsUsingArkData()) {
1700         GTEST_SKIP() << "Current testcase is not compatible from current rdb";
1701     }
1702     mockExtraApi.is_support_binlog = MockSupportBinlog;
1703     sqlite3_export_extra_symbols = &mockExtraApi;
1704 #ifndef CROSS_PLATFORM
1705     mockKvApi.is_support_binlog = MockSupportBinlogWithParam;
1706     sqlite3_export_relational_symbols = &mockKvApi;
1707 #endif
1708     InitDb(HAMode::MAIN_REPLICA, false);
1709     store = nullptr;
1710 
1711     // open slave for conflict by compress
1712     sqlite3 *db = nullptr;
1713     int rc = sqlite3_open_v2(RdbDoubleWriteTest::SLAVE_DATABASE_NAME.c_str(),
1714         &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "compressvfs");
1715     EXPECT_EQ(rc, SQLITE_OK);
1716     EXPECT_NE(db, nullptr);
1717     const char *ddl = DoubleWriteTestOpenCallback::CREATE_TABLE_TEST.c_str();
1718     EXPECT_EQ(sqlite3_exec(db, ddl, nullptr, nullptr, nullptr), SQLITE_OK);
1719     sqlite3_close_v2(db);
1720 
1721     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1722     config.SetHaMode(HAMode::MAIN_REPLICA);
1723     EXPECT_EQ(Connection::CheckReplicaIntegrity(config), E_OK);
1724 }
1725 
1726 /**
1727  * @tc.name: CreateReplicaStatement_Test_001
1728  * @tc.desc: Normal testCase of CreateReplicaStatement.
1729  * @tc.type: FUNC
1730  */
1731 HWTEST_F(RdbDoubleWriteTest, CreateReplicaStatement_Test_001, TestSize.Level2)
1732 {
1733     InitDb();
1734 
1735     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1736     config.SetHaMode(HAMode::MAIN_REPLICA);
1737     auto [errCode, readConn] = SqliteConnection::Create(config, false);
1738     EXPECT_EQ(errCode, SQLITE_OK);
1739     ASSERT_NE(readConn, nullptr);
1740     auto [err, statement] = readConn->CreateReplicaStatement("select * from test;", readConn);
1741     EXPECT_EQ(err, SQLITE_OK);
1742     EXPECT_NE(statement, nullptr);
1743     statement = nullptr;
1744     readConn = nullptr;
1745 }
1746 
1747 /**
1748  * @tc.name: CreateReplicaStatement_Test_002
1749  * @tc.desc: Abnormal testCase of CreateReplicaStatement.
1750  * @tc.type: FUNC
1751  */
1752 HWTEST_F(RdbDoubleWriteTest, CreateReplicaStatement_Test_002, TestSize.Level2)
1753 {
1754     InitDb();
1755     SqliteUtils::DeleteFile(RdbDoubleWriteTest::SLAVE_DATABASE_NAME);
1756 
1757     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1758     config.SetHaMode(HAMode::MAIN_REPLICA);
1759     auto [errCode, readConn] = SqliteConnection::Create(config, false);
1760     EXPECT_EQ(errCode, SQLITE_OK);
1761     ASSERT_NE(readConn, nullptr);
1762     auto [err, statement] = readConn->CreateReplicaStatement("select * from test;", readConn);
1763     EXPECT_EQ(err, SQLITE_OK);
1764     EXPECT_NE(statement, nullptr);
1765     statement = nullptr;
1766     readConn = nullptr;
1767 }
1768 
1769 /**
1770  * @tc.name: CreateReplicaStatement_Test_003
1771  * @tc.desc: Abnormal testCase of CreateReplicaStatement.
1772  * @tc.type: FUNC
1773  */
1774 HWTEST_F(RdbDoubleWriteTest, CreateReplicaStatement_Test_003, TestSize.Level2)
1775 {
1776     InitDb();
1777     EXPECT_TRUE(SqliteUtils::CopyFile(SLAVE_DATABASE_NAME + "-dwr", SLAVE_DATABASE_NAME));
1778 
1779     RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME);
1780     config.SetHaMode(HAMode::MANUAL_TRIGGER);
1781     auto [errCode, readConn] = SqliteConnection::Create(config, false);
1782     EXPECT_EQ(errCode, SQLITE_OK);
1783     ASSERT_NE(readConn, nullptr);
1784     auto [err, statement] = readConn->CreateReplicaStatement("select * from test;", readConn);
1785     EXPECT_EQ(err, SQLITE_OK);
1786     EXPECT_NE(statement, nullptr);
1787 }
1788