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