1/* 2 * Copyright (C) 2022 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 */ 15import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from 'deccjsunit/index' 16import data_relationalStore from '@ohos.data.relationalStore' 17import ability_featureAbility from '@ohos.ability.featureAbility' 18import fileio from '@ohos.file.fs' 19 20const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" 21const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " 22 + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)" 23const DATABASE_DIR = "/data/storage/el2/database/entry/rdb/" 24var rdbStore 25var context = ability_featureAbility.getContext() 26const STORE_CONFIG = { 27 name: "BackupResotreTest.db", 28 encrypt: true, 29 securityLevel: data_relationalStore.SecurityLevel.S1, 30} 31const DATABASE_BACKUP_NAME = "Backup.db" 32 33async function CreatRdbStore(STORE_CONFIG) { 34 let rdbStore = await data_relationalStore.getRdbStore(context, STORE_CONFIG) 35 await rdbStore.executeSql(CREATE_TABLE_TEST, null) 36 let u8 = new Uint8Array([1, 2, 3]) 37 { 38 const valueBucket = { 39 "name": "zhangsan", 40 "age": 18, 41 "salary": 100.5, 42 "blobType": u8, 43 } 44 await rdbStore.insert("test", valueBucket) 45 } 46 { 47 const valueBucket = { 48 "name": "lisi", 49 "age": 28, 50 "salary": 100.5, 51 "blobType": u8, 52 } 53 await rdbStore.insert("test", valueBucket) 54 } 55 { 56 const valueBucket = { 57 "name": "wangwu", 58 "age": 38, 59 "salary": 90.0, 60 "blobType": u8, 61 } 62 await rdbStore.insert("test", valueBucket) 63 } 64 return rdbStore 65} 66 67async function BackupTest(backupName) { 68 try { 69 let promiseRestore = rdbStore.backup(backupName) 70 promiseRestore.then(() => { 71 expect(false).assertTrue() 72 }).catch((err) => { 73 expect(true).assertTrue() 74 }) 75 await promiseRestore 76 } catch { 77 expect(true).assertTrue() 78 } 79 80 rdbStore = null 81} 82 83async function RestoreTest(restoreName) { 84 try { 85 let promiseRestore = rdbStore.restore(restoreName) 86 promiseRestore.then(() => { 87 expect(false).assertTrue() 88 }).catch((err) => { 89 expect(true).assertTrue() 90 }) 91 await promiseRestore 92 } catch { 93 expect(true).assertTrue() 94 } 95 96 rdbStore = null 97} 98 99describe('rdbStoreBackupRestoreWithFAContextTest', function () { 100 beforeAll(async function () { 101 console.info(TAG + 'beforeAll') 102 }) 103 104 beforeEach(async function () { 105 console.info(TAG + 'beforeEach') 106 rdbStore = await CreatRdbStore(STORE_CONFIG) 107 }) 108 109 afterEach(async function () { 110 console.info(TAG + 'afterEach') 111 rdbStore = null 112 await data_relationalStore.deleteRdbStore(context, STORE_CONFIG.name) 113 await data_relationalStore.deleteRdbStore(context, DATABASE_BACKUP_NAME) 114 }) 115 116 afterAll(async function () { 117 console.info(TAG + 'afterAll') 118 }) 119 120 console.log(TAG + "*************Unit Test Begin*************") 121 122 /** 123 * @tc.name RDB Backup Restore test 124 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0010 125 * @tc.desc RDB backup and restore function test 126 */ 127 it('RdbBackupRestoreTest_0010', 0, async function (done) { 128 console.log(TAG + "************* RdbBackupRestoreTest_0010 start *************") 129 130 try { 131 await rdbStore.backup(DATABASE_BACKUP_NAME) 132 // expect(true).assertEqual(fileio.accessSync(DATABASE_DIR + DATABASE_BACKUP_NAME)) 133 // expect(true).assertEqual(fileio.accessSync(DATABASE_DIR + STORE_CONFIG.name)) 134 135 await rdbStore.restore(DATABASE_BACKUP_NAME) 136 // expect(true).assertEqual(fileio.accessSync(DATABASE_DIR + STORE_CONFIG.name)) 137 } catch (err) { 138 expect().assertFail() 139 } 140 141 // RDB after restored, data query test 142 let predicates = new data_relationalStore.RdbPredicates("test") 143 predicates.equalTo("name", "zhangsan") 144 let resultSet = await rdbStore.query(predicates) 145 try { 146 console.log(TAG + "After restore resultSet query done") 147 expect(true).assertEqual(resultSet.goToFirstRow()) 148 const id = resultSet.getLong(resultSet.getColumnIndex("id")) 149 const name = resultSet.getString(resultSet.getColumnIndex("name")) 150 const blobType = resultSet.getBlob(resultSet.getColumnIndex("blobType")) 151 expect(1).assertEqual(id) 152 expect("zhangsan").assertEqual(name) 153 expect(1).assertEqual(blobType[0]) 154 } catch (err) { 155 expect(false).assertTrue() 156 } 157 resultSet.close() 158 resultSet = null 159 done() 160 console.log(TAG + "************* RdbBackupRestoreTest_0010 end *************") 161 }) 162 163 /** 164 * @tc.name RDB Backup test 165 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0020 166 * @tc.desc RDB backup function test 167 */ 168 it('RdbBackupRestoreTest_0020', 0, async function (done) { 169 console.log(TAG + "************* RdbBackupRestoreTest_0020 start *************") 170 // RDB backup function test, backup file name empty 171 BackupTest("") 172 173 // RDB backup function test, backup file name already exists 174 BackupTest(STORE_CONFIG.name) 175 176 done() 177 console.log(TAG + "************* RdbBackupRestoreTest_0020 end *************") 178 }) 179 180 /** 181 * @tc.name RDB BackupRestore test 182 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0030 183 * @tc.desc RDB restore function test 184 */ 185 it('RdbBackupRestoreTest_0030', 0, async function (done) { 186 console.log(TAG + "************* RdbBackupRestoreTest_0030 start *************") 187 await rdbStore.backup(DATABASE_BACKUP_NAME) 188 189 // RDB restore function test, backup file name empty 190 RestoreTest("") 191 192 // RDB restore function test, backup file is specified to database name 193 RestoreTest(STORE_CONFIG.name) 194 195 done() 196 console.log(TAG + "************* RdbBackupRestoreTest_0030 end *************") 197 }) 198 199 /** 200 * @tc.name RDB BackupRestore test 201 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0040 202 * @tc.desc RDB restore function test 203 */ 204 it('RdbBackupRestoreTest_0040', 0, async function (done) { 205 console.log(TAG + "************* RdbBackupRestoreTest_0040 start *************") 206 let dbName = "notExistName.db" 207 208 // RDB restore function test, backup file does not exists 209 try { 210 expect(false).assertEqual(fileio.accessSync(DATABASE_DIR + dbName)) 211 } catch (errCode) { 212 expect(13900002).assertEqual(errCode.code) 213 } 214 RestoreTest(dbName) 215 done() 216 console.log(TAG + "************* RdbBackupRestoreTest_0040 end *************") 217 }) 218 219 /** 220 * @tc.name RDB BackupRestore test 221 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0050 222 * @tc.desc RDB backup function test 223 */ 224 it('RdbBackupRestoreBackupTest_0050', 0, async function (done) { 225 console.log(TAG + "************* RdbBackupRestoreBackupTest_0050 start *************") 226 227 const STORE_NAME = "AfterCloseTest.db"; 228 const rdbStore = await data_relationalStore.getRdbStore( 229 context, 230 { 231 name: STORE_NAME, 232 securityLevel: data_relationalStore.SecurityLevel.S1 233 } 234 ) 235 try { 236 await rdbStore.close(); 237 console.info(`${TAG} close succeeded`); 238 } catch (err) { 239 expect(null).assertFail(); 240 console.error(`${TAG} close failed, code is ${err.code},message is ${err.message}`); 241 } 242 243 try { 244 let dbName = "QueryTest_bak.db" 245 await rdbStore.backup(dbName) 246 } catch (err) { 247 console.log("catch err: failed, err: code=" + err.code + " message=" + err.message) 248 expect("14800014").assertEqual(err.code) 249 } 250 251 await data_relationalStore.deleteRdbStore(context, STORE_NAME); 252 done(); 253 console.log(TAG + "************* RdbBackupRestoreBackupTest_0050 end *************") 254 }) 255 /** 256 * @tc.name RDB BackupRestore test 257 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0060 258 * @tc.desc RDB restore function test 259 */ 260 it('RdbBackupRestoreBackupTest_0060', 0, async function (done) { 261 console.log(TAG + "************* RdbBackupRestoreBackupTest_0060 start *************") 262 263 const STORE_NAME = "AfterCloseTest.db"; 264 const rdbStore = await data_relationalStore.getRdbStore( 265 context, 266 { 267 name: STORE_NAME, 268 securityLevel: data_relationalStore.SecurityLevel.S1 269 } 270 ) 271 272 let dbName = "notExistName.db" 273 BackupTest(dbName); 274 275 try { 276 await rdbStore.close(); 277 console.info(`${TAG} close succeeded`); 278 } catch (err) { 279 expect(null).assertFail(); 280 console.error(`${TAG} close failed, code is ${err.code},message is ${err.message}`); 281 } 282 283 try { 284 await rdbStore.restore(dbName) 285 } catch (err) { 286 console.log("catch err: failed, err: code=" + err.code + " message=" + err.message) 287 expect("14800014").assertEqual(err.code) 288 } 289 290 await data_relationalStore.deleteRdbStore(context, STORE_NAME); 291 done(); 292 console.log(TAG + "************* RdbBackupRestoreBackupTest_0060 end *************") 293 }) 294 /** 295 * @tc.name RDB BackupRestore by sql test 296 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0062 297 * @tc.desc sql func empty param test 298 */ 299 it('RdbBackupRestoreBackupTest_0062', 0, async function (done) { 300 console.log(TAG + "************* RdbBackupRestoreBackupTest_0062 start *************") 301 302 const DEST_STORE_NAME = "Dest.db"; 303 const destDb = await data_relationalStore.getRdbStore( 304 context, 305 { 306 name: DEST_STORE_NAME, 307 securityLevel: data_relationalStore.SecurityLevel.S3 308 } 309 ) 310 311 try { 312 await destDb.executeSql(`select import_db_from_path()`); 313 } catch (error) { 314 console.error("****** RdbBackupRestoreBackupTest_0062 ******" + JSON.stringify(error)); 315 expect(error.code).assertEqual(14800021); 316 } 317 318 expect('ok', await destDb.execute("pragma integrity_check")); 319 await data_relationalStore.deleteRdbStore(context, DEST_STORE_NAME); 320 done(); 321 }) 322 323 /** 324 * @tc.name RDB BackupRestore by sql test 325 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0063 326 * @tc.desc empty path test 327 */ 328 it('RdbBackupRestoreBackupTest_0063', 0, async function (done) { 329 console.log(TAG + "************* RdbBackupRestoreBackupTest_0063 start *************") 330 331 const DEST_STORE_NAME = "Dest.db"; 332 const destDb = await data_relationalStore.getRdbStore( 333 context, 334 { 335 name: DEST_STORE_NAME, 336 securityLevel: data_relationalStore.SecurityLevel.S3 337 } 338 ) 339 340 try { 341 await destDb.executeSql(`select import_db_from_path('')`); 342 } catch (error) { 343 console.error("****** RdbBackupRestoreBackupTest_0063 ******" + JSON.stringify(error)); 344 expect(error.code).assertEqual(14800030); 345 } 346 expect('ok', await destDb.execute("pragma integrity_check")); 347 await data_relationalStore.deleteRdbStore(context, DEST_STORE_NAME); 348 done(); 349 }) 350 351 /** 352 * @tc.name RDB BackupRestore by sql test 353 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0064 354 * @tc.desc souce db not exist test 355 */ 356 it('RdbBackupRestoreBackupTest_0064', 0, async function (done) { 357 console.log(TAG + "************* RdbBackupRestoreBackupTest_0064 start *************") 358 359 const DEST_STORE_NAME = "Dest.db"; 360 const destDb = await data_relationalStore.getRdbStore( 361 context, 362 { 363 name: DEST_STORE_NAME, 364 securityLevel: data_relationalStore.SecurityLevel.S3 365 } 366 ) 367 368 try { 369 await destDb.executeSql(`select import_db_from_path('/path/not_exist.db')`); 370 } catch (error) { 371 console.error("****** RdbBackupRestoreBackupTest_0064 ******" + JSON.stringify(error)); 372 expect(error.code).assertEqual(14800030); 373 } 374 expect('ok', await destDb.execute("pragma integrity_check")); 375 await data_relationalStore.deleteRdbStore(context, DEST_STORE_NAME); 376 done(); 377 }) 378 379 /** 380 * @tc.name RDB BackupRestore by sql test 381 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0065 382 * @tc.desc RDB dest store in transaction 383 */ 384 it('RdbBackupRestoreBackupTest_0065', 0, async function (done) { 385 console.log(TAG + "************* RdbBackupRestoreBackupTest_0065 start *************") 386 387 const SOURCE_STORE_NAME = "Source.db"; 388 const SOURCE_STORE_PATH = "/data/storage/el2/database/entry/rdb/Source.db"; 389 390 const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + 391 "data1 text," + "data2 long, " + "data3 double," + "data4 blob)"; 392 const sourceDb = await data_relationalStore.getRdbStore( 393 context, 394 { 395 name: SOURCE_STORE_NAME, 396 securityLevel: data_relationalStore.SecurityLevel.S3 397 } 398 ) 399 400 await sourceDb.executeSql(CREATE_TABLE_TEST, null); 401 await sourceDb.close(); 402 403 const DEST_STORE_NAME = "Dest.db"; 404 const destDb = await data_relationalStore.getRdbStore( 405 context, 406 { 407 name: DEST_STORE_NAME, 408 securityLevel: data_relationalStore.SecurityLevel.S3 409 } 410 ) 411 412 destDb.beginTransaction(); 413 414 try { 415 await destDb.executeSql(`select import_db_from_path('${SOURCE_STORE_PATH}')`); 416 } catch (error) { 417 console.error("****** RdbBackupRestoreBackupTest_0065 ******" + JSON.stringify(error)); 418 expect(error.code).assertEqual(14800024); 419 } 420 expect('ok', await destDb.execute("pragma integrity_check")); 421 await data_relationalStore.deleteRdbStore(context, SOURCE_STORE_NAME); 422 await data_relationalStore.deleteRdbStore(context, DEST_STORE_NAME); 423 done(); 424 }) 425 426 /** 427 * @tc.name RDB import_db_from_path sql func test 428 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0070 429 * @tc.desc source store corrupted 430 */ 431 it('RdbBackupRestoreBackupTest_0070', 0, async function (done) { 432 console.log(TAG + "************* RdbBackupRestoreBackupTest_0070 start *************") 433 434 const SOURCE_STORE_NAME = "Source.db"; 435 const SOURCE_STORE_PATH = "/data/storage/el2/database/entry/rdb/Source.db"; 436 437 const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + 438 "data1 text," + "data2 long, " + "data3 double," + "data4 blob)"; 439 const sourceDb = await data_relationalStore.getRdbStore( 440 context, 441 { 442 name: SOURCE_STORE_NAME, 443 securityLevel: data_relationalStore.SecurityLevel.S3 444 } 445 ) 446 447 await sourceDb.executeSql(CREATE_TABLE_TEST, null); 448 await sourceDb.close(); 449 450 const fileStream = await fileio.createStream(SOURCE_STORE_PATH, 'r+'); 451 const buffer = new ArrayBuffer(32); 452 const uint8View = new Uint8Array(buffer); 453 uint8View.forEach((val, index) => { 454 uint8View[index] = 0xFF; 455 }); 456 457 await fileStream.write(buffer, { offset: 0x0f40, length: uint8View.length }); 458 fileStream.closeSync(); 459 460 const DEST_STORE_NAME = "Dest.db"; 461 const destDb = await data_relationalStore.getRdbStore( 462 context, 463 { 464 name: DEST_STORE_NAME, 465 securityLevel: data_relationalStore.SecurityLevel.S3 466 } 467 ) 468 469 try { 470 await destDb.executeSql(`select import_db_from_path('${SOURCE_STORE_PATH}')`); 471 } catch (error) { 472 console.error("****** RdbBackupRestoreBackupTest_0070 ******" + JSON.stringify(error)); 473 expect(error.code).assertEqual(14800011); 474 } 475 expect('ok', await destDb.execute("pragma integrity_check")); 476 await data_relationalStore.deleteRdbStore(context, SOURCE_STORE_NAME); 477 await data_relationalStore.deleteRdbStore(context, DEST_STORE_NAME); 478 done(); 479 }) 480 481 /** 482 * @tc.name RDB import_db_from_path sql func test 483 * @tc.number SUB_DDM_RDB_JS_RdbBackupRestoreTest_0080 484 * @tc.desc execute import check row count 485 */ 486 it('RdbBackupRestoreBackupTest_0080', 0, async function (done) { 487 console.log(TAG + "************* RdbBackupRestoreBackupTest_0080 start *************") 488 489 const SOURCE_STORE_NAME = "Source.db"; 490 491 const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + 492 "data1 text," + "data2 long, " + "data3 double," + "data4 blob)"; 493 const sourceDb = await data_relationalStore.getRdbStore( 494 context, 495 { 496 name: SOURCE_STORE_NAME, 497 securityLevel: data_relationalStore.SecurityLevel.S3 498 } 499 ) 500 501 await sourceDb.executeSql(CREATE_TABLE_TEST, null); 502 let times = 100; 503 504 while (times--) { 505 const valuesBuckets = new Array(100).fill(0).map((it, index) => { 506 return { 507 "data1": "hello" + index, 508 "data2": 10, 509 "data3": 1.0, 510 "data4": new Uint8Array([1, 2, 3]), 511 } 512 }); 513 await sourceDb.batchInsert('test', valuesBuckets); 514 } 515 516 let predicates = await new data_relationalStore.RdbPredicates("test") 517 let resultSet = sourceDb.querySync(predicates); 518 console.log(TAG + "************* RdbBackupRestoreBackupTest_0080 start ************* rowCount: " + resultSet.rowCount); 519 520 await resultSet.close(); 521 await sourceDb.close(); 522 523 524 const DEST_STORE_NAME = "Dest.db"; 525 const destDb = await data_relationalStore.getRdbStore( 526 context, 527 { 528 name: DEST_STORE_NAME, 529 securityLevel: data_relationalStore.SecurityLevel.S3 530 } 531 ) 532 533 try { 534 await destDb.executeSql("select import_db_from_path('/data/storage/el2/database/entry/rdb/Source.db')"); 535 536 let predicates = await new data_relationalStore.RdbPredicates("test") 537 let resultSet = destDb.querySync(predicates); 538 expect(resultSet.rowCount).assertEqual(100 * 100); 539 } catch (error) { 540 console.error("****** RdbBackupRestoreBackupTest_0080 ******" + JSON.stringify(error)); 541 expect().assertFail(); 542 } 543 expect('ok', await destDb.execute("pragma integrity_check")); 544 await data_relationalStore.deleteRdbStore(context, SOURCE_STORE_NAME); 545 await data_relationalStore.deleteRdbStore(context, DEST_STORE_NAME); 546 done(); 547 }) 548 549 console.log(TAG + "*************Unit Test End*************") 550} 551) 552