• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #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