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