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 #define LOG_TAG "RdbOpenCallbackTest"
16 #include "rdb_open_callback.h"
17
18 #include <gtest/gtest.h>
19
20 #include <fcntl.h>
21 #include <string>
22
23 #include "common.h"
24 #include "logger.h"
25 #include "rdb_errno.h"
26 #include "rdb_helper.h"
27
28 using namespace testing::ext;
29 using namespace OHOS::Rdb;
30 using namespace OHOS::NativeRdb;
31
32 class RdbOpenCallbackTest : public testing::Test {
33 public:
34 static void SetUpTestCase(void);
35 static void TearDownTestCase(void);
36 void SetUp();
37 void TearDown();
38
39 static const std::string DATABASE_NAME;
40 };
41
42 const std::string RdbOpenCallbackTest::DATABASE_NAME = RDB_TEST_PATH + "open_helper.db";
43
SetUpTestCase(void)44 void RdbOpenCallbackTest::SetUpTestCase(void)
45 {
46 }
47
TearDownTestCase(void)48 void RdbOpenCallbackTest::TearDownTestCase(void)
49 {
50 RdbHelper::DeleteRdbStore(RdbOpenCallbackTest::DATABASE_NAME);
51 }
52
SetUp(void)53 void RdbOpenCallbackTest::SetUp(void)
54 {
55 }
56
TearDown(void)57 void RdbOpenCallbackTest::TearDown(void)
58 {
59 RdbHelper::ClearCache();
60 }
61
62 class OpenCallbackA : public RdbOpenCallback {
63 public:
64 int OnCreate(RdbStore &store) override;
65 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
66 int OnDowngrade(RdbStore &store, int oldVersion, int newVersion) override;
67 int OnOpen(RdbStore &store) override;
68 int onCorruption(std::string databaseFile) override;
69
70 static std::string CreateTableSQL(const std::string &tableName);
71 static std::string DropTableSQL(const std::string &tableName);
72 };
73
CreateTableSQL(const std::string & tableName)74 std::string OpenCallbackA::CreateTableSQL(const std::string &tableName)
75 {
76 return "CREATE TABLE IF NOT EXISTS " + tableName +
77 " (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)";
78 }
79
DropTableSQL(const std::string & tableName)80 std::string OpenCallbackA::DropTableSQL(const std::string &tableName)
81 {
82 return "DROP TABLE IF EXISTS " + tableName + ";";
83 }
84
OnCreate(RdbStore & store)85 int OpenCallbackA::OnCreate(RdbStore &store)
86 {
87 return store.ExecuteSql(CreateTableSQL("test1"));
88 }
89
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)90 int OpenCallbackA::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
91 {
92 LOG_INFO("RdbOpenCallbackTest onUpgrade begin.");
93 if (oldVersion < newVersion) {
94 if (oldVersion <= 1) {
95 return store.ExecuteSql(CreateTableSQL("test2"));
96 }
97 }
98 return E_OK;
99 }
100
OnDowngrade(RdbStore & store,int oldVersion,int newVersion)101 int OpenCallbackA::OnDowngrade(RdbStore &store, int oldVersion, int newVersion)
102 {
103 LOG_INFO("RdbOpenCallbackTest OnDowngrade begin");
104 if (oldVersion > newVersion) {
105 if (oldVersion >= 2) {
106 return store.ExecuteSql(DropTableSQL("test2"));
107 }
108 }
109 return E_OK;
110 }
111
OnOpen(RdbStore & store)112 int OpenCallbackA::OnOpen(RdbStore &store)
113 {
114 int64_t id;
115 ValuesBucket values;
116
117 values.PutInt("id", 1);
118 values.PutString("name", std::string("zhangsan"));
119 values.PutInt("age", 18);
120 int errCode = store.Replace(id, "test1", values);
121 if (errCode != E_OK) {
122 return errCode;
123 }
124
125 values.Clear();
126 values.PutInt("id", 2);
127 values.PutString("name", std::string("lisi"));
128 values.PutInt("age", 18);
129 errCode = store.Replace(id, "test1", values);
130 if (errCode != E_OK) {
131 return errCode;
132 }
133
134 return E_OK;
135 }
136
onCorruption(std::string databaseFile)137 int OpenCallbackA::onCorruption(std::string databaseFile)
138 {
139 int errCode = RdbHelper::DeleteRdbStore(RdbOpenCallbackTest::DATABASE_NAME);
140 if (errCode != E_OK) {
141 return errCode;
142 }
143 return E_OK;
144 }
145
146 /**
147 * @tc.name: RdbOpenCallback_01
148 * @tc.desc: test RdbOpenCallback
149 * @tc.type: FUNC
150 */
151 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_01, TestSize.Level1)
152 {
153 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
154 OpenCallbackA helper;
155
156 int errCode = E_OK;
157 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
158 EXPECT_NE(store, nullptr);
159 EXPECT_EQ(errCode, E_OK);
160
161 int currentVersion;
162 int ret = store->GetVersion(currentVersion);
163 EXPECT_EQ(ret, E_OK);
164 EXPECT_EQ(currentVersion, 1);
165
166 int64_t id;
167 int changedRows;
168 ValuesBucket values;
169
170 values.PutInt("id", 3);
171 values.PutString("name", std::string("lisi"));
172 values.PutInt("age", 20);
173 ret = store->Replace(id, "test1", values);
174 EXPECT_EQ(ret, E_OK);
175 EXPECT_EQ(3, id);
176
177 values.Clear();
178 values.PutInt("age", 20);
179 ret = store->Update(changedRows, "test1", values, "age = ?", std::vector<std::string>{ "18" });
180 EXPECT_EQ(ret, E_OK);
181 EXPECT_EQ(2, changedRows);
182
183 ret = store->Delete(changedRows, "test1", "age = ?", std::vector<std::string>{ "20" });
184 EXPECT_EQ(ret, E_OK);
185 EXPECT_EQ(3, changedRows);
186 }
187
188 /**
189 * @tc.name: RdbOpenCallback_02
190 * @tc.desc: test RdbOpenCallback
191 * @tc.type: FUNC
192 */
193 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_02, TestSize.Level1)
194 {
195 int errCode = E_OK;
196 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
197 OpenCallbackA helper;
198 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 2, helper, errCode);
199 EXPECT_NE(store, nullptr);
200
201 int currentVersion;
202 int ret = store->GetVersion(currentVersion);
203 EXPECT_EQ(ret, E_OK);
204 EXPECT_EQ(currentVersion, 2);
205
206 int64_t id;
207 int changedRows;
208 ValuesBucket values;
209
210 values.PutInt("id", 1);
211 values.PutString("name", std::string("zhangsan"));
212 values.PutInt("age", 18);
213 ret = store->Insert(id, "test2", values);
214 EXPECT_EQ(ret, E_OK);
215 EXPECT_EQ(1, id);
216
217 values.Clear();
218 values.PutInt("id", 2);
219 values.PutString("name", std::string("lisi"));
220 values.PutInt("age", 18);
221 ret = store->Insert(id, "test2", values);
222 EXPECT_EQ(ret, E_OK);
223 EXPECT_EQ(2, id);
224
225 values.Clear();
226 values.PutInt("id", 3L);
227 values.PutString("name", std::string("lisi"));
228 values.PutInt("age", 20);
229 ret = store->Insert(id, "test2", values);
230 EXPECT_EQ(ret, E_OK);
231 EXPECT_EQ(3, id);
232
233 values.Clear();
234 values.PutInt("age", 20);
235 ret = store->Update(changedRows, "test2", values, "age = ?", std::vector<std::string>{ "18" });
236 EXPECT_EQ(ret, E_OK);
237 EXPECT_EQ(2, changedRows);
238
239 ret = store->Delete(changedRows, "test2", "age = ?", std::vector<std::string>{ "20" });
240 EXPECT_EQ(ret, E_OK);
241 EXPECT_EQ(3, changedRows);
242 }
243
244 /**
245 * @tc.name: RdbOpenCallback_03
246 * @tc.desc: test RdbOpenCallback
247 * @tc.type: FUNC
248 */
249 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_03, TestSize.Level1)
250 {
251 int errCode = E_OK;
252 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
253 OpenCallbackA helper;
254 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
255 EXPECT_NE(store, nullptr);
256
257 int currentVersion;
258 int ret = store->GetVersion(currentVersion);
259 EXPECT_EQ(ret, E_OK);
260 EXPECT_EQ(currentVersion, 1);
261
262 int64_t id;
263 ValuesBucket values;
264
265 values.PutInt("id", 1);
266 values.PutString("name", std::string("zhangsan"));
267 values.PutInt("age", 18);
268 ret = store->Insert(id, "test2", values);
269 EXPECT_NE(ret, E_OK);
270 }
271
272 class OpenCallbackB : public RdbOpenCallback {
273 public:
274 int OnCreate(RdbStore &store) override;
275 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
276
277 static std::string CreateTableSQL(const std::string &tableName);
278 static std::string DropTableSQL(const std::string &tableName);
279 };
280
CreateTableSQL(const std::string & tableName)281 std::string OpenCallbackB::CreateTableSQL(const std::string &tableName)
282 {
283 return "CREATE TABLE IF NOT EXISTS " + tableName +
284 " (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)";
285 }
286
DropTableSQL(const std::string & tableName)287 std::string OpenCallbackB::DropTableSQL(const std::string &tableName)
288 {
289 return "DROP TABLE IF EXISTS " + tableName + ";";
290 }
291
OnCreate(RdbStore & store)292 int OpenCallbackB::OnCreate(RdbStore &store)
293 {
294 return store.ExecuteSql(CreateTableSQL("test1"));
295 }
296
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)297 int OpenCallbackB::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
298 {
299 if (oldVersion < newVersion) {
300 if (oldVersion <= 1) {
301 return store.ExecuteSql(CreateTableSQL("test2"));
302 }
303 }
304 return E_OK;
305 }
306
307 /**
308 * @tc.name: RdbOpenCallback_04
309 * @tc.desc: test RdbOpenCallback
310 * @tc.type: FUNC
311 */
312 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_04, TestSize.Level1)
313 {
314 int errCode = E_OK;
315 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
316 OpenCallbackB helper;
317 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 2, helper, errCode);
318 EXPECT_NE(store, nullptr);
319
320 int currentVersion;
321 int ret = store->GetVersion(currentVersion);
322 EXPECT_EQ(ret, E_OK);
323 EXPECT_EQ(currentVersion, 2);
324
325 int64_t id;
326 int changedRows;
327 ValuesBucket values;
328
329 values.PutInt("id", 1);
330 values.PutString("name", std::string("zhangsan"));
331 values.PutInt("age", 18);
332 ret = store->Insert(id, "test2", values);
333 EXPECT_EQ(ret, E_OK);
334 EXPECT_EQ(1, id);
335
336 values.Clear();
337 values.PutInt("id", 2);
338 values.PutString("name", std::string("lisi"));
339 values.PutInt("age", 18);
340 ret = store->Insert(id, "test2", values);
341 EXPECT_EQ(ret, E_OK);
342 EXPECT_EQ(2, id);
343
344 values.Clear();
345 values.PutInt("id", 3L);
346 values.PutString("name", std::string("lisi"));
347 values.PutInt("age", 20);
348 ret = store->Insert(id, "test2", values);
349 EXPECT_EQ(ret, E_OK);
350 EXPECT_EQ(3, id);
351
352 values.Clear();
353 values.PutInt("age", 20);
354 ret = store->Update(changedRows, "test2", values, "age = ?", std::vector<std::string>{ "18" });
355 EXPECT_EQ(ret, E_OK);
356 EXPECT_EQ(2, changedRows);
357
358 ret = store->Delete(changedRows, "test2", "age = ?", std::vector<std::string>{ "20" });
359 EXPECT_EQ(ret, E_OK);
360 EXPECT_EQ(3, changedRows);
361 }
362
363 /**
364 * @tc.name: RdbOpenCallback_05
365 * @tc.desc: test RdbOpenCallback
366 * @tc.type: FUNC
367 */
368 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_05, TestSize.Level1)
369 {
370 int errCode = E_OK;
371 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
372 OpenCallbackB helper;
373 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
374 EXPECT_NE(store, nullptr);
375
376 int currentVersion;
377 int ret = store->GetVersion(currentVersion);
378 EXPECT_EQ(ret, E_OK);
379 EXPECT_EQ(currentVersion, 1);
380
381 int64_t id;
382 ValuesBucket values;
383 values.PutInt("id", 1);
384 values.PutString("name", std::string("zhangsan"));
385 values.PutInt("age", 18);
386 ret = store->Insert(id, "test2", values);
387 EXPECT_EQ(ret, E_OK);
388
389 ret = helper.OnDowngrade(*store, 2, 1);
390 EXPECT_EQ(ret, E_OK);
391
392 ret = helper.OnOpen(*store);
393 EXPECT_EQ(ret, E_OK);
394 }
395
396 /**
397 * @tc.name: RdbOpenCallback_06
398 * @tc.desc: test rdb open with not a database
399 * @tc.type: FUNC
400 */
401 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_06, TestSize.Level1)
402 {
403 int errCode = E_OK;
404 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
405 OpenCallbackB helper;
406 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
407 EXPECT_NE(store, nullptr);
408 store->ExecuteSql(OpenCallbackB::CreateTableSQL("test1"));
409 store.reset();
410 store = nullptr;
411 int fd = open(RdbOpenCallbackTest::DATABASE_NAME.c_str(), O_WRONLY);
412 char str[] = "3333333333sss333333333333333333";
413 lseek(fd, 0, SEEK_SET);
414 write(fd, str, sizeof(str));
415 close(fd);
416 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
417 EXPECT_NE(store, nullptr);
418 store = nullptr;
419 RdbHelper::DeleteRdbStore(RdbOpenCallbackTest::DATABASE_NAME);
420 }
421
422 /**
423 * @tc.name: RdbOpenCallback_07
424 * @tc.desc: test rdb open with not a database and write file is not a database
425 * @tc.type: FUNC
426 */
427 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_07, TestSize.Level1)
428 {
429 int errCode = E_OK;
430 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
431 OpenCallbackB helper;
432 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
433 EXPECT_NE(store, nullptr);
434 store->ExecuteSql(OpenCallbackB::CreateTableSQL("test1"));
435 store.reset();
436 store = nullptr;
437 int fd = open(RdbOpenCallbackTest::DATABASE_NAME.c_str(), O_WRONLY);
438 char str[] = "3333333333sss333333333333333333";
439 lseek(fd, 0, SEEK_SET);
440 write(fd, str, sizeof(str));
441 close(fd);
442 char writeStr[] = "13333333333sss333333333333333333";
443 int writeFd = open((RdbOpenCallbackTest::DATABASE_NAME + "-dwr").c_str(), O_WRONLY);
444 lseek(writeFd, 0, SEEK_SET);
445 write(writeFd, writeStr, sizeof(writeStr));
446 close(writeFd);
447 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
448 EXPECT_EQ(store, nullptr);
449 RdbHelper::DeleteRdbStore(RdbOpenCallbackTest::DATABASE_NAME);
450 }
451
452 /**
453 * @tc.name: RdbOpenCallback_08
454 * @tc.desc: test rdb open with not a database and write file is not a database
455 * @tc.type: FUNC
456 */
457 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_08, TestSize.Level1)
458 {
459 int errCode = E_OK;
460 RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
461 OpenCallbackB helper;
462 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
463 EXPECT_NE(store, nullptr);
464 for (int i = 1; i < 11; ++i) {
465 std::string testName = "test" + std::to_string(i);
466 store->ExecuteSql(OpenCallbackB::CreateTableSQL(testName));
467 }
468 store.reset();
469 store = nullptr;
470 int fd = open(RdbOpenCallbackTest::DATABASE_NAME.c_str(), O_WRONLY);
471 char str[] = "3333333333sss333333333333333333";
472 lseek(fd, 0, SEEK_SET);
473 write(fd, str, sizeof(str));
474 close(fd);
475 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
476 EXPECT_NE(store, nullptr);
477 store = nullptr;
478 RdbHelper::DeleteRdbStore(RdbOpenCallbackTest::DATABASE_NAME);
479 }
480
481