From 96136be3f89b5f24a4074b232adaacd8daf69324 Mon Sep 17 00:00:00 2001 From: ZhaoJinghui Date: Sat, 28 Jun 2025 18:05:35 +0800 Subject: [PATCH] add testcase Signed-off-by: ZhaoJinghui Change-Id: I69bd0c742f8d396aeb933a4e8253eebf16f721ef --- .../app/src/kvstore_data_service.cpp | 16 +- .../app/src/kvstore_data_service.h | 5 +- .../unittest/kvstore_data_service_test.cpp | 311 +++++++++++++++++- .../service/test/BUILD.gn | 2 + .../service/test/rdb_service_impl_test.cpp | 235 ++++++++++++- 5 files changed, 545 insertions(+), 24 deletions(-) diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index aff30c73f..c77fc1334 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -524,11 +524,7 @@ int32_t KvStoreDataService::OnBackup(MessageParcel &data, MessageParcel &reply) return -1; } - std::string content; - if (!GetSecretKeyBackup(backupInfo.bundleInfos, backupInfo.userId, iv, content)) { - DeleteCloneKey(); - return -1; - }; + auto content = GetSecretKeyBackup(backupInfo.bundleInfos, backupInfo.userId, iv); DeleteCloneKey(); std::string backupPath = DirectoryManager::GetInstance().GetClonePath(backupInfo.userId); @@ -575,9 +571,8 @@ std::vector KvStoreDataService::ReEncryptKey(const std::string &key, Se return reEncryptedKey; } -bool KvStoreDataService::GetSecretKeyBackup( - const std::vector &bundleInfos, - const std::string &userId, const std::vector &iv, std::string &content) +std::string KvStoreDataService::GetSecretKeyBackup(const std::vector &bundleInfos, + const std::string &userId, const std::vector &iv) { SecretKeyBackupData backupInfos; std::string deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; @@ -609,8 +604,7 @@ bool KvStoreDataService::GetSecretKeyBackup( backupInfos.infos.push_back(std::move(item)); } } - content = Serializable::Marshall(backupInfos); - return true; + return Serializable::Marshall(backupInfos); } int32_t KvStoreDataService::OnRestore(MessageParcel &data, MessageParcel &reply) @@ -1424,4 +1418,4 @@ void KvStoreDataService::DumpBundleInfo(int fd, std::map &bundleInfos, - const std::string &userId, const std::vector &iv, std::string &content); + std::string GetSecretKeyBackup(const std::vector &bundleInfos, + const std::string &userId, const std::vector &iv); private: void NotifyAccountEvent(const AccountEventInfo &eventInfo); diff --git a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp index beee71e60..574366db9 100644 --- a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp +++ b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp @@ -30,6 +30,7 @@ #include "system_ability.h" #include "system_ability_definition.h" #include "upgrade_manager.h" +#include "utils/base64_utils.h" using namespace testing::ext; using namespace OHOS; @@ -703,6 +704,22 @@ HWTEST_F(KvStoreDataServiceTest, DumpBundleInfo001, TestSize.Level0) EXPECT_NO_FATAL_FAILURE(kvStoreDataServiceTest.DumpBundleInfo(fd, params)); } +/** +* @tc.name: OnExtensionRestore001 +* @tc.desc: restore with invalid fd +* @tc.type: FUNC +* @tc.require: +* @tc.author: zhaojh +*/ +HWTEST_F(KvStoreDataServiceTest, OnExtension001, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + data.WriteFileDescriptor(-1); + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("invalid", data, reply), 0); +} + /** * @tc.name: OnExtensionRestore001 * @tc.desc: restore with invalid fd @@ -846,7 +863,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore006, TestSize.Level0) * @tc.desc: test OnExtension function backup invalid json * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup001, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -862,7 +879,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup001, TestSize.Level0) { * @tc.desc: test OnExtension function backup application empty * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup002, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -880,7 +897,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup002, TestSize.Level0) { * @tc.desc: test OnExtension function backup no userInfo * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup003, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -899,7 +916,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup003, TestSize.Level0) { * @tc.desc: test OnExtension function backup userinfo empty * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup004, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -919,7 +936,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup004, TestSize.Level0) { * @tc.desc: test OnExtension function backup secret key length invalid * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup005, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -943,7 +960,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup005, TestSize.Level0) { * @tc.desc: test OnExtension function backup secret iv length invalid * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup006, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -967,7 +984,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup006, TestSize.Level0) { * @tc.desc: test OnExtension function backup no bundle * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup007, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -1001,7 +1018,7 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup007, TestSize.Level0) { * @tc.desc: test OnExtension function backup no bundle * @tc.type: FUNC * @tc.require: - * @tc.author: SQL + * @tc.author: zhaojh */ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup008, TestSize.Level0) { KvStoreDataService kvStoreDataServiceTest; @@ -1057,4 +1074,280 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup008, TestSize.Level0) { EXPECT_TRUE(backupData.infos.size() == 1); } -} // namespace OHOS::Test \ No newline at end of file + +/** + * @tc.name: ReEncryptKey001 + * @tc.desc: test ReEncryptKey load meta failed + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, ReEncryptKey001, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + SecretKeyMetaData secretKeyMeta; + StoreMetaData storeMeta; + std::vector iv; + auto ret = kvStoreDataServiceTest.ReEncryptKey("", secretKeyMeta, storeMeta, iv); + EXPECT_TRUE(ret.empty()); +} + +/** + * @tc.name: ReEncryptKey002 + * @tc.desc: test ReEncryptKey failed when meta sKey is invalid + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, ReEncryptKey002, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + StoreMetaData testMeta; + testMeta.bundleName = "com.example.restore_test"; + testMeta.storeId = "Source"; + testMeta.user = "100"; + testMeta.area = CryptoManager::Area::EL1; + testMeta.instanceId = 0; + testMeta.deviceId = + DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + testMeta.isEncrypt = true; + testMeta.dataDir = "TEST_DIR"; + SecretKeyMetaData testSecret; + CryptoManager::CryptoParams encryptParams = { .area = testMeta.area }; + testSecret.storeType = 10; + testSecret.time = std::vector{233, 39, 137, 103, 0, 0, 0, 0}; + testSecret.nonce = encryptParams.nonce; + testSecret.area = encryptParams.area; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetKey(), testMeta, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetSecretKey(), testSecret, true), true); + + SecretKeyMetaData secretKeyMeta; + std::vector iv; + auto ret = kvStoreDataServiceTest.ReEncryptKey(testMeta.GetSecretKey(), secretKeyMeta, testMeta, iv); + EXPECT_TRUE(ret.empty()); +} + +/** + * @tc.name: ReEncryptKey003 + * @tc.desc: test reEncryptKey failed when iv is invalid + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, ReEncryptKey003, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + StoreMetaData testMeta; + testMeta.bundleName = "com.example.restore_test"; + testMeta.storeId = "Source"; + testMeta.user = "100"; + testMeta.area = CryptoManager::Area::EL1; + testMeta.instanceId = 0; + testMeta.deviceId = + DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + testMeta.isEncrypt = true; + testMeta.dataDir = "TEST_DIR"; + std::vector sKey{2, 249, 221, 119, 177, 216, 217, 134, 185, 139, + 114, 38, 140, 64, 165, 35, 77, 169, 0, 226, + 226, 166, 37, 73, 181, 229, 42, 88, 108, 111, + 131, 104, 141, 43, 96, 119, 214, 34, 177, 129, + 233, 96, 98, 164, 87, 115, 187, 170}; + SecretKeyMetaData testSecret; + CryptoManager::CryptoParams encryptParams = { .area = testMeta.area }; + testSecret.sKey = CryptoManager::GetInstance().Encrypt(sKey, encryptParams); + testSecret.storeType = 10; + testSecret.time = std::vector{233, 39, 137, 103, 0, 0, 0, 0}; + testSecret.nonce = encryptParams.nonce; + testSecret.area = encryptParams.area; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetKey(), testMeta, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetSecretKey(), testSecret, true), true); + + SecretKeyMetaData secretKeyMeta; + std::vector iv; + auto ret = kvStoreDataServiceTest.ReEncryptKey(testMeta.GetSecretKey(), secretKeyMeta, testMeta, iv); + EXPECT_TRUE(ret.empty()); +} + +/** + * @tc.name: OnExtensionRestore_InvalidUserId + * @tc.desc: Test OnRestore returns -1 when userId is empty + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_InvalidUserId, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + // Prepare a valid backup file (content doesn't matter, as IV size will fail first) + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, NORMAL_BACKUP_DATA), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + std::string cloneInfoStr = + "[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"27," + "145,118,212,62,156,133,135,50,68,188,239,20,170,227,190,37,142,218," + "158,177,32,5,160,13,114,186,141,59,91,44,200\",\"encryption_algname\":" + "\"AES256\",\"gcmParams_iv\":\"1,2,3,4,5,6,7,8,9,10\"}},{\"type\":\"userId\",\"detail\":\"\"}]"; + data.WriteString(cloneInfoStr); + + // Should return -1 due to IV size error + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), -1); + close(fd); +} + +/** + * @tc.name: OnExtensionRestore_InvalidIvSize + * @tc.desc: Test OnRestore returns -1 when IV size is incorrect + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_InvalidIvSize, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, NORMAL_BACKUP_DATA), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + // Prepare cloneInfoStr with invalid IV (length != AES_256_NONCE_SIZE) + std::string cloneInfoStr = + "[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"27," + "145,118,212,62,156,133,135,50,68,188,239,20,170,227,190,37,142,218," + "158,177,32,5,160,13,114,186,141,59,91,44,200\",\"encryption_algname\":" + "\"AES256\",\"gcmParams_iv\":\"1,2,3,4,5,6,7,8,9,10\"}},{\"type\":\"userId\",\"detail\":\"100\"}]"; + data.WriteString(cloneInfoStr); + + // Should return -1 due to IV size error + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), -1); + close(fd); +} + +/** + * @tc.name: OnExtensionRestore_ImportCloneKeyFailed + * @tc.desc: Test OnRestore returns -1 when ImportCloneKey fails (invalid key size) + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_ImportCloneKeyFailed, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + // Prepare a valid backup file (content doesn't matter, as ImportCloneKey will fail first) + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, NORMAL_BACKUP_DATA), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + // Prepare cloneInfoStr with invalid encryption_symkey (too short, so ImportCloneKey fails) + std::string cloneInfoStr = + "[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"1,2,3\",\"encryption_algname\":\"AES256\"," + "\"gcmParams_iv\":\"97,160,201,177,46,37,129,18,112,220,107,106,25,231,15,15,""58,85,31,83,123,216,211,2,222," + "49,122,72,21,251,83,16\"}},{\"type\":\"userId\",\"detail\":\"100\"}]"; + data.WriteString(cloneInfoStr); + + // Should return -1 due to ImportCloneKey failure + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), -1); + close(fd); +} + +/** + * @tc.name: OnExtensionRestore_RestoreSuccess + * @tc.desc: Test OnRestore returns 0 when ImportCloneKey succeeds + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_RestoreSuccess, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + StoreMetaData testMeta; + testMeta.bundleName = "com.myapp.example"; + testMeta.storeId = "storeId"; + testMeta.user = "100"; + testMeta.area = CryptoManager::Area::EL1; + testMeta.instanceId = 0; + testMeta.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + testMeta.isEncrypt = true; + testMeta.dataDir = "TEST_DIR"; + std::vector sKey(32, 0); + SecretKeyMetaData testSecret; + CryptoManager::CryptoParams encryptParams = { .area = testMeta.area }; + testSecret.sKey = CryptoManager::GetInstance().Encrypt(sKey, encryptParams); + testSecret.storeType = 10; + testSecret.time = std::vector{ 233, 39, 137, 103, 0, 0, 0, 0 }; + testSecret.nonce = encryptParams.nonce; + testSecret.area = encryptParams.area; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetKey(), testMeta, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetSecretKey(), testSecret, true), true); + + std::string symKey = "27,145,118,212,62,156,133,135,50,68,188,239,20,170,227,190,37,142," + "218,158,177,32,5,160,13,114,186,141,59,91,44,200"; + std::vector iv{ 97, 160, 201, 177, 46, 37, 129, 18, 112, 220, 107, 106, 25, 231, 15, 15, 58, 85, 31, 83, + 123, 216, 211, 2, 222, 49, 122, 72, 21, 251, 83, 16 }; + + ASSERT_EQ(kvStoreDataServiceTest.ImportCloneKey(symKey), true); + + SecretKeyMetaData secretKeyMeta; + auto reEncryptedKey = kvStoreDataServiceTest.ReEncryptKey(testMeta.GetSecretKey(), secretKeyMeta, testMeta, iv); + kvStoreDataServiceTest.DeleteCloneKey(); + auto encodeEncryptedKey = DistributedData::Base64::Encode(reEncryptedKey); + + const std::string backupData = + std::string("{\"infos\":[{\"bundleName\":\"com.myapp.example\",\"dbName\":\"storeId\"," + "\"instanceId\":0,\"storeType\":\"10\",\"user\":\"100\",\"sKey\":\"") + + encodeEncryptedKey + std::string("\",\"time\":[50,180,137,103,0,0,0,0]}]}"); + + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, backupData), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + std::string cloneInfoStr = + std::string("[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"") + symKey + + std::string("\",\"encryption_algname\":\"AES256\",\"gcmParams_iv\":\"97,160,201,177,46,37,129,18,112,220,107," + "106,25,231,15,15,58,85,31,83,123,216,211,2,222,49,122,72,21,251,83,16\"}}," + "{\"type\":\"userId\",\"detail\":\"100\"}]"); + data.WriteString(cloneInfoStr); + + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), 0); + close(fd); +} + +/** + * @tc.name: WriteBackupInfo_FwriteFail + * @tc.desc: Test WriteBackupInfo returns false when fwrite fails + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(KvStoreDataServiceTest, WriteBackupInfo_FwriteFail, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + std::string content = "test_content"; + // Try to open a directory as a file, which should fail at fopen + bool result = kvStoreDataServiceTest.WriteBackupInfo(content, "/"); + EXPECT_FALSE(result); +} +} // namespace OHOS::Test diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index eb5bd16e4..e55cc2d2e 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -560,6 +560,8 @@ ohos_unittest("RdbServiceImplTest") { } module_out_path = module_output_path sources = [ + "${data_service_path}/service/test/mock/general_store_mock.cpp", + "${data_service_path}/service/test/mock/cursor_mock.cpp", "mock/checker_mock.cpp", "mock/db_change_data_mock.cpp", "mock/db_store_mock.cpp", diff --git a/services/distributeddataservice/service/test/rdb_service_impl_test.cpp b/services/distributeddataservice/service/test/rdb_service_impl_test.cpp index 5a59ce33d..3eb8d822b 100644 --- a/services/distributeddataservice/service/test/rdb_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/rdb_service_impl_test.cpp @@ -30,6 +30,8 @@ #include "metadata/store_meta_data.h" #include "metadata/store_meta_data_local.h" #include "mock/db_store_mock.h" +#include "mock/general_store_mock.h" +#include "store/general_value.h" #include "rdb_service_impl.h" #include "rdb_types.h" #include "relational_store_manager.h" @@ -539,6 +541,7 @@ HWTEST_F(RdbServiceImplTest, DoCompensateSync001, TestSize.Level0) EXPECT_EQ(GeneralStore::GetPriorityLevel(GeneralStore::GetHighMode(static_cast(mode))), 1); }); service.DoCompensateSync(event); + EventCenter::GetInstance().Unsubscribe(CloudEvent::LOCAL_CHANGE); } /** @@ -2065,5 +2068,235 @@ HWTEST_F(RdbServiceImplTest, RegisterEvent_009, TestSize.Level1) EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true), true); } +/** + * @tc.name: SetDistributedTables004 + * @tc.desc: Test SetDistributedTables when type is device. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, SetDistributedTables004, TestSize.Level0) +{ + RdbServiceImpl service; + RdbSyncerParam param; + param.bundleName_ = TEST_BUNDLE; + param.storeName_ = "SetDistributedTables004"; + param.type_ = StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN; + std::vector tables; + std::vector references; + + auto meta = service.GetStoreMetaData(param); + ASSERT_EQ(MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true), true); + + auto creator = [](const StoreMetaData &metaData) -> GeneralStore* { + auto store = new (std::nothrow) GeneralStoreMock(); + return store; + }; + AutoCache::GetInstance().RegCreator(DistributedRdb::RDB_DEVICE_COLLABORATION, creator); + + int32_t result = + service.SetDistributedTables(param, tables, references, false, + DistributedTableType::DISTRIBUTED_DEVICE); + EXPECT_EQ(result, RDB_OK); + ASSERT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true), true); +} + +/** + * @tc.name: RemoteQuery003 + * @tc.desc: test RemoteQuery, when CheckAccess pass but query failed. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, RemoteQuery003, TestSize.Level0) +{ + RdbServiceImpl service; + RdbSyncerParam param; + param.bundleName_ = TEST_BUNDLE; + param.storeName_ = "RemoteQuery003"; + std::vector selectionArgs; + auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + auto ret = service.RemoteQuery(param, deviceId, "", selectionArgs); + EXPECT_EQ(ret.first, RDB_ERROR); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyWithoutPath(), false), true); +} + +/** + * @tc.name: Sync003 + * @tc.desc: Test Sync when mode is nearby begin. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, Sync003, TestSize.Level0) +{ + RdbServiceImpl service; + RdbSyncerParam param; + param.bundleName_ = TEST_BUNDLE; + param.storeName_ = "Sync003"; + RdbService::Option option { DistributedData::GeneralStore::NEARBY_BEGIN }; + PredicatesMemo predicates; + + int32_t result = service.Sync(param, option, predicates, nullptr); + EXPECT_EQ(result, RDB_OK); +} + +/** + * @tc.name: Sync004 + * @tc.desc: Test Sync when mode is cloud begin. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, Sync004, TestSize.Level0) +{ + RdbServiceImpl service; + RdbSyncerParam param; + param.bundleName_ = TEST_BUNDLE; + param.storeName_ = "Sync004"; + RdbService::Option option { DistributedData::GeneralStore::CLOUD_BEGIN }; + PredicatesMemo predicates; + + int32_t result = service.Sync(param, option, predicates, nullptr); + EXPECT_EQ(result, RDB_OK); +} + +/** + * @tc.name: QuerySharingResource_PermissionDenied_001 + * @tc.desc: Test QuerySharingResource returns RDB_ERROR when CheckAccess fails. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, QuerySharingResource_PermissionDenied_001, TestSize.Level0) +{ + RdbServiceImpl service; + RdbSyncerParam param; + // param.bundleName_ and param.storeName_ left empty to trigger CheckAccess failure + PredicatesMemo predicates; + predicates.tables_ = {"table1"}; + std::vector columns = {"col1", "col2"}; + + auto result = service.QuerySharingResource(param, predicates, columns); + EXPECT_EQ(result.first, RDB_ERROR); + EXPECT_EQ(result.second, nullptr); +} + +/** + * @tc.name: QuerySharingResource_PermissionDenied_002 + * @tc.desc: Test QuerySharingResource returns RDB_ERROR when not system app. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, QuerySharingResource_PermissionDenied_002, TestSize.Level0) +{ + RdbServiceImpl service; + RdbSyncerParam param; + param.bundleName_ = TEST_BUNDLE; + param.storeName_ = TEST_STORE; + PredicatesMemo predicates; + predicates.tables_ = {"table1"}; + std::vector columns = {"col1", "col2"}; + + auto result = service.QuerySharingResource(param, predicates, columns); + EXPECT_EQ(result.first, RDB_ERROR); + EXPECT_EQ(result.second, nullptr); +} + +/** + * @tc.name: SaveSecretKeyMeta_CloneKeyUpdate_001 + * @tc.desc: Test SaveSecretKeyMeta updates clone secret key when area < 0 or nonce is empty. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, SaveSecretKeyMeta_CloneKeyUpdate_001, TestSize.Level0) +{ + // Prepare metaData and secret key + auto meta = metaData_; + meta.isEncrypt = true; + std::vector password = Random(KEY_LENGTH); + + // Prepare cloneKey with area < 0 and empty nonce + SecretKeyMetaData cloneKey; + CryptoManager::CryptoParams params; + cloneKey.sKey = CryptoManager::GetInstance().Encrypt(password, params); + cloneKey.area = -1; + cloneKey.nonce.clear(); + cloneKey.storeType = meta.storeType; + + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(meta.GetCloneSecretKey(), cloneKey, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true), true); + + // Call SaveSecretKeyMeta, should trigger UpdateSecretMeta for cloneKey + RdbServiceImpl service; + service.SaveSecretKeyMeta(meta, password); + + // Clean up + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetCloneSecretKey(), true), true); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true), true); +} + +/** + * @tc.name: SaveSecretKeyMeta_CloneKeyUpdate_EmptySKey_002 + * @tc.desc: Test SaveSecretKeyMeta does not update clone secret key if sKey is empty. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, SaveSecretKeyMeta_CloneKeyUpdate_EmptySKey_002, TestSize.Level0) +{ + auto meta = metaData_; + meta.isEncrypt = true; + std::vector password = Random(KEY_LENGTH); + + // Prepare cloneKey with empty sKey + SecretKeyMetaData cloneKey; + cloneKey.sKey.clear(); + cloneKey.area = -1; + cloneKey.nonce.clear(); + cloneKey.storeType = meta.storeType; + + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(meta.GetCloneSecretKey(), cloneKey, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true), true); + + RdbServiceImpl service; + service.SaveSecretKeyMeta(meta, password); + + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetCloneSecretKey(), true), true); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true), true); +} + +/** + * @tc.name: SaveSecretKeyMeta_CloneKeyUpdate_NoUpdate_003 + * @tc.desc: Test SaveSecretKeyMeta does not update clone secret key if area >= 0 and nonce not empty. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaojh + */ +HWTEST_F(RdbServiceImplTest, SaveSecretKeyMeta_CloneKeyUpdate_NoUpdate_003, TestSize.Level0) +{ + auto meta = metaData_; + meta.isEncrypt = true; + std::vector password = Random(KEY_LENGTH); + + // Prepare cloneKey with area >= 0 and nonce not empty + SecretKeyMetaData cloneKey; + CryptoManager::CryptoParams params; + cloneKey.sKey = CryptoManager::GetInstance().Encrypt(password, params); + cloneKey.area = 1; + cloneKey.nonce = { 1, 2, 3, 4 }; + cloneKey.storeType = meta.storeType; + + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(meta.GetCloneSecretKey(), cloneKey, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true), true); + + RdbServiceImpl service; + service.SaveSecretKeyMeta(meta, password); + + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetCloneSecretKey(), true), true); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true), true); +} } // namespace DistributedRDBTest -} // namespace OHOS::Test \ No newline at end of file +} // namespace OHOS::Test -- Gitee