diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp index e1b46f8dbbe64bb50428beea5d0a43392abfd756..3fb63369cbb5e0fb2e346c4639652e62ad8602c5 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp @@ -341,6 +341,12 @@ bool ITypesUtil::Marshalling(const Options &input, MessageParcel &data) ZLOGE("schema is failed"); return false; } + + if (!data.WriteString(input.hapName)) { + ZLOGE("hapName is failed"); + return false; + } + std::unique_ptr buffer = std::make_unique(sizeof(input)); Options *target = reinterpret_cast(buffer.get()); target->createIfMissing = input.createIfMissing; @@ -362,6 +368,12 @@ bool ITypesUtil::Unmarshalling(Options &output, MessageParcel &data) ZLOGE("read schema failed"); return false; } + + if (!data.ReadString(output.hapName)) { + ZLOGE("read hapName failed"); + return false; + } + const Options *source = reinterpret_cast(data.ReadRawData(sizeof(output))); if (source == nullptr) { return false; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn b/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn index 8e548ea5fda62c106ef098730e039dfec687966a..3b36ff909a381adda5da7fdf00ef7746feadc444 100755 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn @@ -136,6 +136,27 @@ ohos_unittest("SingleKvStoreClientTest") { ] } +ohos_unittest("DeviceKvStoreTest") { + module_out_path = module_output_path + + sources = [ "unittest/device_kvstore_test.cpp" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "samgr_standard:samgr_proxy", + ] + + deps = [ + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] +} + ohos_unittest("BlobTest") { module_out_path = module_output_path @@ -159,6 +180,7 @@ group("unittest") { deps += [ ":BlobTest", + ":DeviceKvStoreTest", ":DistributedKvDataManagerEncryptTest", ":DistributedKvDataManagerTest", ":LocalSubscribeStoreTest", diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/device_kvstore_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/device_kvstore_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2546eb7ea60d19f681cb34f692097710e37da766 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/device_kvstore_test.cpp @@ -0,0 +1,1123 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "distributed_kv_data_manager.h" +#include "types.h" + +using namespace testing::ext; +using namespace OHOS::DistributedKv; + +class DeviceKvStoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); + static std::string GetKey(const std::string &key); + + static std::shared_ptr kvStore_; // declare kvstore instance. + static Status status_; + static std::string deviceId_; + static Options options_; + static int MAX_VALUE_SIZE; +}; + +const std::string VALID_SCHEMA = "{\"SCHEMA_VERSION\":\"1.0\"," + "\"SCHEMA_MODE\":\"STRICT\"," + "\"SCHEMA_SKIPSIZE\":0," + "\"SCHEMA_DEFINE\":{" + "\"age\":\"INTEGER, NOT NULL\"" + "}," + "\"SCHEMA_INDEXES\":[\"$.age\"]}"; + +std::shared_ptr DeviceKvStoreTest::kvStore_ = nullptr; +Status DeviceKvStoreTest::status_ = Status::ERROR; +std::string DeviceKvStoreTest::deviceId_; +Options DeviceKvStoreTest::options_; +int DeviceKvStoreTest::MAX_VALUE_SIZE = 4 * 1024 * 1024; // max value size is 4M. + +void DeviceKvStoreTest::SetUpTestCase(void) +{ + DistributedKvDataManager manager; + options_.area = EL1; + AppId appId = { "odmf" }; + StoreId storeId = { "student_device" }; // define kvstore(database) name. + // [create and] open and initialize kvstore instance. + status_ = manager.GetSingleKvStore(options_, appId, storeId, kvStore_); + DeviceInfo deviceInfo; + manager.GetLocalDevice(deviceInfo); + deviceId_ = deviceInfo.deviceId; +} + +void DeviceKvStoreTest::TearDownTestCase(void) +{ + remove("/data/service/el1/public/database/odmf/key"); + remove("/data/service/el1/public/database/odmf/kvdb"); + remove("/data/service/el1/public/database/odmf"); +} + +void DeviceKvStoreTest::SetUp(void) +{} + +void DeviceKvStoreTest::TearDown(void) +{} + +std::string DeviceKvStoreTest::GetKey(const std::string& key) +{ + std::ostringstream oss; + oss << std::setfill('0') << std::setw(sizeof(uint32_t)) << deviceId_.length(); + oss << deviceId_ << std::string(key.begin(), key.end()); + return oss.str(); +} + +class DeviceObserverTestImpl : public KvStoreObserver { +public: + std::vector insertEntries_; + std::vector updateEntries_; + std::vector deleteEntries_; + bool isClear_ = false; + DeviceObserverTestImpl(); + ~DeviceObserverTestImpl() + {} + + DeviceObserverTestImpl(const DeviceObserverTestImpl &) = delete; + DeviceObserverTestImpl &operator=(const DeviceObserverTestImpl &) = delete; + DeviceObserverTestImpl(DeviceObserverTestImpl &&) = delete; + DeviceObserverTestImpl &operator=(DeviceObserverTestImpl &&) = delete; + + void OnChange(const ChangeNotification &changeNotification); + + // reset the callCount_ to zero. + void ResetToZero(); + + uint64_t GetCallCount() const; + +private: + uint64_t callCount_; +}; + +void DeviceObserverTestImpl::OnChange(const ChangeNotification &changeNotification) +{ + callCount_++; + const auto &insert = changeNotification.GetInsertEntries(); + insertEntries_.clear(); + for (const auto &entry : insert) { + insertEntries_.push_back(entry); + } + + const auto &update = changeNotification.GetUpdateEntries(); + updateEntries_.clear(); + for (const auto &entry : update) { + updateEntries_.push_back(entry); + } + + const auto &del = changeNotification.GetDeleteEntries(); + deleteEntries_.clear(); + for (const auto &entry : del) { + deleteEntries_.push_back(entry); + } + + isClear_ = changeNotification.IsClear(); +} + +DeviceObserverTestImpl::DeviceObserverTestImpl() +{ + callCount_ = 0; + insertEntries_ = {}; + updateEntries_ = {}; + deleteEntries_ = {}; + isClear_ = false; +} + +void DeviceObserverTestImpl::ResetToZero() +{ + callCount_ = 0; +} + +uint64_t DeviceObserverTestImpl::GetCallCount() const +{ + return callCount_; +} + +class DeviceSyncCallbackTestImpl : public KvStoreSyncCallback { +public: + void SyncCompleted(const std::map &results); +}; + +void DeviceSyncCallbackTestImpl::SyncCompleted(const std::map &results) +{} + +/** +* @tc.name: GetStoreId001 +* @tc.desc: Get a Device KvStore instance. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, GetStoreId001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; + + auto storID = kvStore_->GetStoreId(); + EXPECT_EQ(storID.storeId, "student_device"); +} + +/** +* @tc.name: PutGetDelete001 +* @tc.desc: put value and delete value +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, PutGetDelete001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; + + Key skey = {"single_001"}; + Value sval = {"value_001"}; + auto status = kvStore_->Put(skey, sval); + EXPECT_EQ(status, Status::SUCCESS) << "Put data failed"; + + auto delStatus = kvStore_->Delete(skey); + EXPECT_EQ(delStatus, Status::SUCCESS) << "Delete data failed"; + + auto notExistStatus = kvStore_->Delete(skey); + EXPECT_EQ(notExistStatus, Status::SUCCESS) << "Delete non-existing data failed"; + + auto spaceStatus = kvStore_->Put(skey, {""}); + EXPECT_EQ(spaceStatus, Status::SUCCESS) << "Put space failed"; + + auto spaceKeyStatus = kvStore_->Put({""}, {""}); + EXPECT_NE(spaceKeyStatus, Status::SUCCESS) << "Put space keys failed"; + + Status validStatus = kvStore_->Put(skey, sval); + EXPECT_EQ(validStatus, Status::SUCCESS) << "Put valid keys and values failed"; + + Value rVal; + auto validPutStatus = kvStore_->Get({ GetKey("single_001")}, rVal); + EXPECT_EQ(validPutStatus, Status::SUCCESS) << "Get value failed"; + EXPECT_EQ(sval, rVal) << "Got and put values not equal"; +} + +/** +* @tc.name: GetEntriesAndResultSet001 +* @tc.desc: Batch put values and get values. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, GetEntriesAndResultSet001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; + + // prepare 10 + size_t sum = 10; + int sum_1 = 10; + std::string prefix = "prefix_"; + for (size_t i = 0; i < sum; i++) { + kvStore_->Put({prefix + std::to_string(i)}, {std::to_string(i)}); + } + + std::vector results; + kvStore_->GetEntries({ GetKey(prefix) }, results); + EXPECT_EQ(results.size(), sum) << "entries size is not equal 10."; + + std::shared_ptr resultSet; + Status status = kvStore_->GetResultSet({ GetKey(prefix) }, resultSet); + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(resultSet->GetCount(), sum_1) << "resultSet size is not equal 10."; + resultSet->IsFirst(); + resultSet->IsAfterLast(); + resultSet->IsBeforeFirst(); + resultSet->MoveToPosition(1); + resultSet->IsLast(); + resultSet->MoveToPrevious(); + resultSet->MoveToNext(); + resultSet->MoveToLast(); + resultSet->MoveToFirst(); + resultSet->GetPosition(); + Entry entry; + resultSet->GetEntry(entry); + + for (size_t i = 0; i < sum; i++) { + kvStore_->Delete({GetKey(prefix + std::to_string(i))}); + } + + auto closeResultSetStatus = kvStore_->CloseResultSet(resultSet); + EXPECT_EQ(closeResultSetStatus, Status::SUCCESS) << "Close resultSet failed."; +} + +/** +* @tc.name: Subscribe001 +* @tc.desc: Put data and get callback. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, Subscribe001, TestSize.Level1) +{ + auto observer = std::make_shared(); + auto subStatus = kvStore_->SubscribeKvStore(SubscribeType::SUBSCRIBE_TYPE_ALL, observer); + EXPECT_EQ(subStatus, Status::SUCCESS) << "Subscribe observer failed."; + // subscribe repeated observer; + auto repeatedSubStatus = kvStore_->SubscribeKvStore(SubscribeType::SUBSCRIBE_TYPE_ALL, observer); + EXPECT_NE(repeatedSubStatus, Status::SUCCESS) << "Repeat subscribe kvStore observer failed."; + + auto unSubStatus = kvStore_->UnSubscribeKvStore(SubscribeType::SUBSCRIBE_TYPE_ALL, observer); + EXPECT_EQ(unSubStatus, Status::SUCCESS) << "Unsubscribe observer failed."; +} + +/** +* @tc.name: SyncCallback001 +* @tc.desc: Register sync callback. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SyncCallback001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; + + auto syncCallback = std::make_shared(); + auto syncStatus = kvStore_->RegisterSyncCallback(syncCallback); + EXPECT_EQ(syncStatus, Status::SUCCESS) << "Register sync callback failed."; + + auto unRegStatus = kvStore_->UnRegisterSyncCallback(); + EXPECT_EQ(unRegStatus, Status::SUCCESS) << "Unregister sync callback failed."; + + Key skey = {"single_001"}; + Value sval = {"value_001"}; + kvStore_->Put(skey, sval); + kvStore_->Delete(skey); + + std::map results; + results.insert({"aaa", Status::INVALID_ARGUMENT}); + syncCallback->SyncCompleted(results); +} + +/** +* @tc.name: RemoveDeviceData001 +* @tc.desc: Remove device data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, RemoveDeviceData001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; + + Key skey = {"single_001"}; + Value sval = {"value_001"}; + kvStore_->Put(skey, sval); + + std::string deviceId = "no_exist_device_id"; + auto removeStatus = kvStore_->RemoveDeviceData(deviceId); + EXPECT_NE(removeStatus, Status::SUCCESS) << "Remove device should not return success"; + + Value retVal; + auto getRet = kvStore_->Get(GetKey(skey.ToString()), retVal); + EXPECT_EQ(getRet, Status::SUCCESS) << "Get value failed."; + EXPECT_EQ(retVal.Size(), sval.Size()) << "data base should be null."; +} + +/** +* @tc.name: SyncData001 +* @tc.desc: Synchronize device data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SyncData001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; + std::string deviceId = "no_exist_device_id"; + std::vector deviceIds = { deviceId }; + auto syncStatus = kvStore_->Sync(deviceIds, SyncMode::PUSH); + EXPECT_NE(syncStatus, Status::SUCCESS) << "Sync device should not return success"; +} + +/** +* @tc.name: TestSchemaStoreC001 +* @tc.desc: Test schema device store. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, TestSchemaStoreC001, TestSize.Level1) +{ + std::shared_ptr deviceKvStore; + DistributedKvDataManager manager; + Options options; + options.encrypt = true; + options.schema = VALID_SCHEMA; + options.area = EL1; + AppId appId = { "odmf" }; + StoreId storeId = { "schema_device_id" }; + (void)manager.GetSingleKvStore(options, appId, storeId, deviceKvStore); + ASSERT_NE(deviceKvStore, nullptr) << "kvStorePtr is null."; + auto result = deviceKvStore->GetStoreId(); + EXPECT_EQ(result.storeId, "schema_device_id"); + + Key testKey = {"TestSchemaStoreC001_key"}; + Value testValue = {"{\"age\":10}"}; + auto testStatus = deviceKvStore->Put(testKey, testValue); + EXPECT_EQ(testStatus, Status::SUCCESS) << "putting data failed"; + Value resultValue; + auto status = deviceKvStore->Get(GetKey(testKey.ToString()), resultValue); + EXPECT_EQ(status, Status::SUCCESS) << "get value failed."; + manager.DeleteKvStore(appId, storeId, options.baseDir); +} + +/** +* @tc.name: SyncData001 +* @tc.desc: Synchronize device data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SyncData002, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStorePtr is null."; + std::string deviceId = "no_exist_device_id"; + std::vector deviceIds = { deviceId }; + uint32_t allowedDelayMs = 200; + auto syncStatus = kvStore_->Sync(deviceIds, SyncMode::PUSH, allowedDelayMs); + EXPECT_EQ(syncStatus, Status::SUCCESS) << "sync device should return success"; +} + +/** +* @tc.name: SyncData002 +* @tc.desc: Set sync parameters - success. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SetSync001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; + KvSyncParam syncParam{ 500 }; // 500ms + auto ret = kvStore_->SetSyncParam(syncParam); + EXPECT_EQ(ret, Status::SUCCESS) << "set sync param should return success"; + + KvSyncParam syncParamRet; + kvStore_->GetSyncParam(syncParamRet); + EXPECT_EQ(syncParamRet.allowedDelayMs, syncParam.allowedDelayMs); +} + +/** +* @tc.name: SyncData002 +* @tc.desc: Set sync parameters - failed. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SetSync002, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; + KvSyncParam syncParam2{ 50 }; // 50ms + auto ret = kvStore_->SetSyncParam(syncParam2); + EXPECT_NE(ret, Status::SUCCESS) << "set sync param should not return success"; + + KvSyncParam syncParamRet2; + ret = kvStore_->GetSyncParam(syncParamRet2); + EXPECT_NE(syncParamRet2.allowedDelayMs, syncParam2.allowedDelayMs); +} + +/** +* @tc.name: SingleKvStoreDdmPutBatch001 +* @tc.desc: Batch put data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SingleKvStoreDdmPutBatch001, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + // store entries to kvstore. + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "KvStoreDdmPutBatch001_1"; + entry1.value = "age:20"; + entry2.key = "KvStoreDdmPutBatch001_2"; + entry2.value = "age:19"; + entry3.key = "KvStoreDdmPutBatch001_3"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + Status status = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status) << "PutBatch data return wrong status"; + // get value from kvstore. + Value valueRet1; + Status statusRet1 = kvStore_->Get(GetKey(entry1.key.ToString()), valueRet1); + EXPECT_EQ(Status::SUCCESS, statusRet1) << "Get data return wrong status"; + EXPECT_EQ(entry1.value, valueRet1) << "value and valueRet are not equal"; + + Value valueRet2; + Status statusRet2 = kvStore_->Get(GetKey(entry2.key.ToString()), valueRet2); + EXPECT_EQ(Status::SUCCESS, statusRet2) << "Get data return wrong status"; + EXPECT_EQ(entry2.value, valueRet2) << "value and valueRet are not equal"; + + Value valueRet3; + Status statusRet3 = kvStore_->Get(GetKey(entry3.key.ToString()), valueRet3); + EXPECT_EQ(Status::SUCCESS, statusRet3) << "Get data return wrong status"; + EXPECT_EQ(entry3.value, valueRet3) << "value and valueRet are not equal"; +} + +/** +* @tc.name: SingleKvStoreDdmPutBatch002 +* @tc.desc: Batch update data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SingleKvStoreDdmPutBatch002, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + // before update. + std::vector entriesBefore; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreDdmPutBatch002_1"; + entry1.value = "age:20"; + entry2.key = "SingleKvStoreDdmPutBatch002_2"; + entry2.value = "age:19"; + entry3.key = "SingleKvStoreDdmPutBatch002_3"; + entry3.value = "age:23"; + entriesBefore.push_back(entry1); + entriesBefore.push_back(entry2); + entriesBefore.push_back(entry3); + + Status status = kvStore_->PutBatch(entriesBefore); + EXPECT_EQ(Status::SUCCESS, status) << "PutBatch data return wrong status"; + + // after update. + std::vector entriesAfter; + Entry entry4, entry5, entry6; + entry4.key = "SingleKvStoreDdmPutBatch002_1"; + entry4.value = "age:20, sex:girl"; + entry5.key = "SingleKvStoreDdmPutBatch002_2"; + entry5.value = "age:19, sex:boy"; + entry6.key = "SingleKvStoreDdmPutBatch002_3"; + entry6.value = "age:23, sex:girl"; + entriesAfter.push_back(entry4); + entriesAfter.push_back(entry5); + entriesAfter.push_back(entry6); + + status = kvStore_->PutBatch(entriesAfter); + EXPECT_EQ(Status::SUCCESS, status) << "PutBatch failed, wrong status"; + + // get value from kvstore. + Value valueRet1; + Status statusRet1 = kvStore_->Get(GetKey(entry4.key.ToString()), valueRet1); + EXPECT_EQ(Status::SUCCESS, statusRet1) << "Get data failed, wrong status"; + EXPECT_EQ(entry4.value, valueRet1) << "value and valueRet are not equal"; + + Value valueRet2; + Status statusRet2 = kvStore_->Get(GetKey(entry5.key.ToString()), valueRet2); + EXPECT_EQ(Status::SUCCESS, statusRet2) << "Get data failed, wrong status"; + EXPECT_EQ(entry5.value, valueRet2) << "value and valueRet are not equal"; + + Value valueRet3; + Status statusRet3 = kvStore_->Get(GetKey(entry6.key.ToString()), valueRet3); + EXPECT_EQ(Status::SUCCESS, statusRet3) << "Get data return wrong status"; + EXPECT_EQ(entry6.value, valueRet3) << "value and valueRet are not equal"; +} + +/** +* @tc.name: DdmPutBatch003 +* @tc.desc: Batch put data that contains invalid data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmPutBatch003, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = " "; + entry1.value = "age:20"; + entry2.key = "student_name_caixu"; + entry2.value = " "; + entry3.key = "student_name_liuyue"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + Status status = kvStore_->PutBatch(entries); + Status target = options_.baseDir.empty() ? Status::SUCCESS : Status::INVALID_ARGUMENT; + EXPECT_EQ(target, status) << "PutBatch data return wrong status"; +} + +/** +* @tc.name: DdmPutBatch004 +* @tc.desc: Batch put data that contains invalid data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmPutBatch004, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = ""; + entry1.value = "age:20"; + entry2.key = "student_name_caixu"; + entry2.value = ""; + entry3.key = "student_name_liuyue"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + Status status = kvStore_->PutBatch(entries); + Status target = options_.baseDir.empty() ? Status::SUCCESS : Status::INVALID_ARGUMENT; + EXPECT_EQ(target, status) << "PutBatch data return wrong status"; +} + +static std::string SingleGenerate1025KeyLen() +{ + std::string str("prefix"); + // Generate a key with a length of more than 1024 bytes. + for (int i = 0; i < 1024; i++) { + str += "a"; + } + return str; +} +/** +* @tc.name: DdmPutBatch005 +* @tc.desc: Batch put data that contains invalid data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmPutBatch005, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = SingleGenerate1025KeyLen(); + entry1.value = "age:20"; + entry2.key = "student_name_caixu"; + entry2.value = "age:19"; + entry3.key = "student_name_liuyue"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + Status status = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::INVALID_ARGUMENT, status) << "PutBatch data return wrong status"; +} + +/** +* @tc.name: DdmPutBatch006 +* @tc.desc: Batch put large data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmPutBatch006, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + std::vector val(MAX_VALUE_SIZE); + for (int i = 0; i < MAX_VALUE_SIZE; i++) { + val[i] = static_cast(i); + } + Value value = val; + + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreDdmPutBatch006_1"; + entry1.value = value; + entry2.key = "SingleKvStoreDdmPutBatch006_2"; + entry2.value = value; + entry3.key = "SingleKvStoreDdmPutBatch006_3"; + entry3.value = value; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + Status status = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status) << "PutBatch data return wrong status"; + + // get value from kvstore. + Value valueRet1; + Status statusRet1 = kvStore_->Get(GetKey("SingleKvStoreDdmPutBatch006_1"), valueRet1); + EXPECT_EQ(Status::SUCCESS, statusRet1) << "Get data return wrong status"; + EXPECT_EQ(entry1.value, valueRet1) << "value and valueRet are not equal"; + + Value valueRet2; + Status statusRet2 = kvStore_->Get(GetKey("SingleKvStoreDdmPutBatch006_2"), valueRet2); + EXPECT_EQ(Status::SUCCESS, statusRet2) << "Get data return wrong status"; + EXPECT_EQ(entry2.value, valueRet2) << "value and valueRet are not equal"; + + Value valueRet3; + Status statusRet3 = kvStore_->Get(GetKey("SingleKvStoreDdmPutBatch006_3"), valueRet3); + EXPECT_EQ(Status::SUCCESS, statusRet3) << "Get data return wrong status"; + EXPECT_EQ(entry3.value, valueRet3) << "value and valueRet are not equal"; +} + +/** +* @tc.name: DdmDeleteBatch001 +* @tc.desc: Batch delete data. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch001, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + // store entries to kvstore. + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreDdmDeleteBatch001_1"; + entry1.value = "age:20"; + entry2.key = "SingleKvStoreDdmDeleteBatch001_2"; + entry2.value = "age:19"; + entry3.key = "SingleKvStoreDdmDeleteBatch001_3"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + std::vector keys; + keys.push_back("SingleKvStoreDdmDeleteBatch001_1"); + keys.push_back("SingleKvStoreDdmDeleteBatch001_2"); + keys.push_back("SingleKvStoreDdmDeleteBatch001_3"); + + Status status1 = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status1) << "PutBatch data return wrong status"; + + Status status2 = kvStore_->DeleteBatch(keys); + EXPECT_EQ(Status::SUCCESS, status2) << "DeleteBatch data return wrong status"; + std::vector results; + kvStore_->GetEntries(GetKey("SingleKvStoreDdmDeleteBatch001_"), results); + size_t sum = 0; + EXPECT_EQ(results.size(), sum) << "entries size is not equal 0."; +} + +/** +* @tc.name: DdmDeleteBatch002 +* @tc.desc: Batch delete data when some keys are not in KvStore. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch002, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + // store entries to kvstore. + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreDdmDeleteBatch002_1"; + entry1.value = "age:20"; + entry2.key = "SingleKvStoreDdmDeleteBatch002_2"; + entry2.value = "age:19"; + entry3.key = "SingleKvStoreDdmDeleteBatch002_3"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + std::vector keys; + keys.push_back("SingleKvStoreDdmDeleteBatch002_1"); + keys.push_back("SingleKvStoreDdmDeleteBatch002_2"); + keys.push_back("SingleKvStoreDdmDeleteBatch002_3"); + keys.push_back("SingleKvStoreDdmDeleteBatch002_4"); + + Status status1 = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status1) << "PutBatch data return wrong status"; + + Status status2 = kvStore_->DeleteBatch(keys); + EXPECT_EQ(Status::SUCCESS, status2) << "DeleteBatch data return wrong status"; + std::vector results; + kvStore_->GetEntries(GetKey("SingleKvStoreDdmDeleteBatch002_"), results); + size_t sum = 0; + EXPECT_EQ(results.size(), sum) << "entries size is not equal 0."; +} + +/** +* @tc.name: DdmDeleteBatch003 +* @tc.desc: Batch delete data when some keys are invalid. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch003, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + // Store entries to KvStore. + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreDdmDeleteBatch003_1"; + entry1.value = "age:20"; + entry2.key = "SingleKvStoreDdmDeleteBatch003_2"; + entry2.value = "age:19"; + entry3.key = "SingleKvStoreDdmDeleteBatch003_3"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + std::vector keys; + keys.push_back("SingleKvStoreDdmDeleteBatch003_1"); + keys.push_back("SingleKvStoreDdmDeleteBatch003_2"); + keys.push_back(""); + + Status status1 = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status1) << "PutBatch data return wrong status"; + + Status status2 = kvStore_->DeleteBatch(keys); + Status target = options_.baseDir.empty() ? Status::SUCCESS : Status::INVALID_ARGUMENT; + size_t sum = options_.baseDir.empty() ? 1 : 3; + EXPECT_EQ(target, status2) << "DeleteBatch data return wrong status"; + std::vector results; + kvStore_->GetEntries(GetKey("SingleKvStoreDdmDeleteBatch003_"), results); + EXPECT_EQ(results.size(), sum) << "entries size is not equal 3."; +} + +/** +* @tc.name: DdmDeleteBatch004 +* @tc.desc: Batch delete data when some keys are invalid. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch004, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + // store entries to kvstore. + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreDdmDeleteBatch004_1"; + entry1.value = "age:20"; + entry2.key = "SingleKvStoreDdmDeleteBatch004_2"; + entry2.value = "age:19"; + entry3.key = "SingleKvStoreDdmDeleteBatch004_3"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + std::vector keys; + keys.push_back("SingleKvStoreDdmDeleteBatch004_1"); + keys.push_back("SingleKvStoreDdmDeleteBatch004_2"); + keys.push_back(" "); + + Status status1 = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status1) << "PutBatch data return wrong status"; + + std::vector results1; + kvStore_->GetEntries(GetKey("SingleKvStoreDdmDeleteBatch004_"), results1); + size_t sum1 = 3; + EXPECT_EQ(results1.size(), sum1) << "entries size1111 is not equal 3."; + + Status status2 = kvStore_->DeleteBatch(keys); + Status target = options_.baseDir.empty() ? Status::SUCCESS : Status::INVALID_ARGUMENT; + size_t sum = options_.baseDir.empty() ? 1 : 3; + EXPECT_EQ(target, status2) << "DeleteBatch data return wrong status"; + std::vector results; + kvStore_->GetEntries(GetKey("SingleKvStoreDdmDeleteBatch004_"), results); + EXPECT_EQ(results.size(), sum) << "entries size is not equal 3."; +} + +/** +* @tc.name: DdmDeleteBatch005 +* @tc.desc: Batch delete data when some keys are invalid. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch005, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + + // store entries to kvstore. + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreDdmDeleteBatch005_1"; + entry1.value = "age:20"; + entry2.key = "SingleKvStoreDdmDeleteBatch005_2"; + entry2.value = "age:19"; + entry3.key = "SingleKvStoreDdmDeleteBatch005_3"; + entry3.value = "age:23"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + std::vector keys; + keys.push_back("SingleKvStoreDdmDeleteBatch005_1"); + keys.push_back("SingleKvStoreDdmDeleteBatch005_2"); + Key keyTmp = SingleGenerate1025KeyLen(); + keys.push_back(keyTmp); + + Status status1 = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status1) << "PutBatch data return wrong status"; + + std::vector results1; + kvStore_->GetEntries(GetKey("SingleKvStoreDdmDeleteBatch005_"), results1); + size_t sum1 = 3; + EXPECT_EQ(results1.size(), sum1) << "entries111 size is not equal 3."; + + Status status2 = kvStore_->DeleteBatch(keys); + EXPECT_EQ(Status::INVALID_ARGUMENT, status2) << "DeleteBatch data return wrong status"; + std::vector results; + kvStore_->GetEntries(GetKey("SingleKvStoreDdmDeleteBatch005_"), results); + size_t sum = 3; + EXPECT_EQ(results.size(), sum) << "entries size is not equal 3."; +} + +/** +* @tc.name: Transaction001 +* @tc.desc: Batch delete data when some keys are invalid. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, Transaction001, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + std::shared_ptr observer = std::make_shared(); + observer->ResetToZero(); + + SubscribeType subscribeType = SubscribeType::SUBSCRIBE_TYPE_ALL; + Status status = kvStore_->SubscribeKvStore(subscribeType, observer); + EXPECT_EQ(Status::SUCCESS, status) << "SubscribeKvStore return wrong status"; + + Key key1 = "SingleKvStoreTransaction001_1"; + Value value1 = "subscribe"; + + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreTransaction001_2"; + entry1.value = "subscribe"; + entry2.key = "SingleKvStoreTransaction001_3"; + entry2.value = "subscribe"; + entry3.key = "SingleKvStoreTransaction001_4"; + entry3.value = "subscribe"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + std::vector keys; + keys.push_back("SingleKvStoreTransaction001_2"); + keys.push_back("ISingleKvStoreTransaction001_3"); + + status = kvStore_->StartTransaction(); + EXPECT_EQ(Status::SUCCESS, status) << "StartTransaction return wrong status"; + + status = kvStore_->Put(key1, value1); // insert or update key-value + EXPECT_EQ(Status::SUCCESS, status) << "Put data return wrong status"; + status = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status) << "PutBatch data return wrong status"; + status = kvStore_->Delete(key1); + EXPECT_EQ(Status::SUCCESS, status) << "Delete data return wrong status"; + status = kvStore_->DeleteBatch(keys); + EXPECT_EQ(Status::SUCCESS, status) << "DeleteBatch data return wrong status"; + status = kvStore_->Commit(); + EXPECT_EQ(Status::SUCCESS, status) << "Commit return wrong status"; + + usleep(200000); + EXPECT_EQ(static_cast(observer->GetCallCount()), 1); + + status = kvStore_->UnSubscribeKvStore(subscribeType, observer); + EXPECT_EQ(Status::SUCCESS, status) << "UnSubscribeKvStore return wrong status"; +} + +/** +* @tc.name: Transaction002 +* @tc.desc: Batch delete data when some keys are invalid. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, Transaction002, TestSize.Level2) +{ + EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; + std::shared_ptr observer = std::make_shared(); + observer->ResetToZero(); + + SubscribeType subscribeType = SubscribeType::SUBSCRIBE_TYPE_ALL; + Status status = kvStore_->SubscribeKvStore(subscribeType, observer); + EXPECT_EQ(Status::SUCCESS, status) << "SubscribeKvStore return wrong status"; + + Key key1 = "SingleKvStoreTransaction002_1"; + Value value1 = "subscribe"; + + std::vector entries; + Entry entry1, entry2, entry3; + entry1.key = "SingleKvStoreTransaction002_2"; + entry1.value = "subscribe"; + entry2.key = "SingleKvStoreTransaction002_3"; + entry2.value = "subscribe"; + entry3.key = "SingleKvStoreTransaction002_4"; + entry3.value = "subscribe"; + entries.push_back(entry1); + entries.push_back(entry2); + entries.push_back(entry3); + + std::vector keys; + keys.push_back("SingleKvStoreTransaction002_2"); + keys.push_back("SingleKvStoreTransaction002_3"); + + status = kvStore_->StartTransaction(); + EXPECT_EQ(Status::SUCCESS, status) << "StartTransaction return wrong status"; + + status = kvStore_->Put(key1, value1); // insert or update key-value + EXPECT_EQ(Status::SUCCESS, status) << "Put data return wrong status"; + status = kvStore_->PutBatch(entries); + EXPECT_EQ(Status::SUCCESS, status) << "PutBatch data return wrong status"; + status = kvStore_->Delete(key1); + EXPECT_EQ(Status::SUCCESS, status) << "Delete data return wrong status"; + status = kvStore_->DeleteBatch(keys); + EXPECT_EQ(Status::SUCCESS, status) << "DeleteBatch data return wrong status"; + status = kvStore_->Rollback(); + EXPECT_EQ(Status::SUCCESS, status) << "Commit return wrong status"; + + usleep(200000); + EXPECT_EQ(static_cast(observer->GetCallCount()), 0); + EXPECT_EQ(static_cast(observer->insertEntries_.size()), 0); + EXPECT_EQ(static_cast(observer->updateEntries_.size()), 0); + EXPECT_EQ(static_cast(observer->deleteEntries_.size()), 0); + + status = kvStore_->UnSubscribeKvStore(subscribeType, observer); + EXPECT_EQ(Status::SUCCESS, status) << "UnSubscribeKvStore return wrong status"; + observer = nullptr; +} + +/** +* @tc.name: DeviceSync001 +* @tc.desc: Test sync enable. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DeviceSync001 ,TestSize.Level1) +{ + std::shared_ptr kvStore; + DistributedKvDataManager manager; + Options options; + options.encrypt = true; + options.area = EL1; + AppId appId = { "odmf" }; + StoreId storeId = { "schema_device_id001" }; + manager.GetSingleKvStore(options, appId, storeId, kvStore); + ASSERT_NE(kvStore, nullptr) << "kvStore is null."; + auto result = kvStore->GetStoreId(); + EXPECT_EQ(result.storeId, "schema_device_id001"); + + auto testStatus = kvStore->SetCapabilityEnabled(true); + EXPECT_EQ(testStatus, Status::SUCCESS) << "set fail"; + manager.DeleteKvStore(appId, storeId, options.baseDir); +} + +/** +* @tc.name: DeviceSync002 +* @tc.desc: Test sync enable. +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, DeviceSync002 ,TestSize.Level1) +{ + std::shared_ptr kvStore; + DistributedKvDataManager manager; + Options options; + options.encrypt = true; + options.area = EL1; + AppId appId = { "odmf" }; + StoreId storeId = { "schema_device_id002" }; + manager.GetSingleKvStore(options, appId, storeId, kvStore); + ASSERT_NE(kvStore, nullptr) << "kvStore is null."; + auto result = kvStore->GetStoreId(); + EXPECT_EQ(result.storeId, "schema_device_id002"); + + std::vector local = {"A", "B"}; + std::vector remote = {"C", "D"}; + auto testStatus = kvStore->SetCapabilityRange(local, remote); + EXPECT_EQ(testStatus, Status::SUCCESS) << "set range fail"; + manager.DeleteKvStore(appId, storeId, options.baseDir); +} + +/** +* @tc.name: SyncWithCondition001 +* @tc.desc: sync device data with condition; +* @tc.type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang +*/ +HWTEST_F(DeviceKvStoreTest, SyncWithCondition001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; + std::vector deviceIds = {"invalid_device_id1", "invalid_device_id2"}; + DataQuery dataQuery; + dataQuery.KeyPrefix("name"); + auto syncStatus = kvStore_->Sync(deviceIds, SyncMode::PUSH, dataQuery, nullptr); + EXPECT_NE(syncStatus, Status::SUCCESS) << "sync device should not return success"; +} + +/** + * @tc.name: SubscribeWithQuery001 + * desc: subscribe and sync device data with query; + * type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang + */ +HWTEST_F(DeviceKvStoreTest, SubscribeWithQuery001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; + std::vector deviceIds = {"invalid_device_id1", "invalid_device_id2"}; + DataQuery dataQuery; + dataQuery.KeyPrefix("name"); + auto syncStatus = kvStore_->SubscribeWithQuery(deviceIds, dataQuery); + EXPECT_NE(syncStatus, Status::SUCCESS) << "sync device should not return success"; +} + +/** + * @tc.name: UnSubscribeWithQuery001 + * desc: subscribe and sync device data with query; + * type: FUNC +* @tc.require: I5DE2A +* @tc.author: Sven Wang + */ +HWTEST_F(DeviceKvStoreTest, UnSubscribeWithQuery001, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; + std::vector deviceIds = {"invalid_device_id1", "invalid_device_id2"}; + DataQuery dataQuery; + dataQuery.KeyPrefix("name"); + auto unSubscribeStatus = kvStore_->UnsubscribeWithQuery(deviceIds, dataQuery); + EXPECT_NE(unSubscribeStatus, Status::SUCCESS) << "sync device should not return success"; +} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp index b2f5b3ec330cc1a85ff354b797b1cb9aee245e4e..dd91f64411cb15b956e4e7cd44d5b1dbdae7cb85 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp @@ -12,16 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #define LOG_TAG "DistributedKvDataManagerEncryptTest" +#include #include "distributed_kv_data_manager.h" #include "kvstore_death_recipient.h" -#include -#include -#include -#include "types.h" #include "log_print.h" +#include "types.h" + using namespace testing::ext; using namespace OHOS::DistributedKv; @@ -64,8 +62,8 @@ StoreId DistributedKvDataManagerEncryptTest::storeId; void DistributedKvDataManagerEncryptTest::RemoveAllStore(DistributedKvDataManager manager) { manager.CloseAllKvStore(appId); - manager.DeleteKvStore(appId, storeId); - manager.DeleteAllKvStore(appId); + manager.DeleteKvStore(appId, storeId, createEnc.baseDir); + manager.DeleteAllKvStore(appId, createEnc.baseDir); } void DistributedKvDataManagerEncryptTest::SetUpTestCase(void) { @@ -78,11 +76,17 @@ void DistributedKvDataManagerEncryptTest::SetUpTestCase(void) appId.appId = "com.ohos.nb.service"; storeId.storeId = "EncryptStoreId"; + + createEnc.area = EL1; + createEnc.baseDir = std::string("/data/service/el1/public/database/") + appId.appId; + mkdir(createEnc.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); } void DistributedKvDataManagerEncryptTest::TearDownTestCase(void) { RemoveAllStore(manager); + remove((createEnc.baseDir + "/kvdb").c_str()); + remove(createEnc.baseDir.c_str()); } void DistributedKvDataManagerEncryptTest::SetUp(void) diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp index 01e28821015a9e00337a8dc0c60f1306a04e4aa8..0a0b807d1f47c23a707720a4ae323cb3036602df 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp @@ -12,13 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #define LOG_TAG "DistributedKvDataManagerTest" - #include "distributed_kv_data_manager.h" -#include #include #include + #include "kvstore_death_recipient.h" #include "log_print.h" #include "types.h" @@ -77,22 +75,26 @@ Entry DistributedKvDataManagerTest::entryB; void DistributedKvDataManagerTest::RemoveAllStore(DistributedKvDataManager manager) { manager.CloseAllKvStore(appId); - manager.DeleteAllKvStore(appId); + manager.DeleteAllKvStore(appId, create.baseDir); } void DistributedKvDataManagerTest::SetUpTestCase(void) { + userId.userId = "account0"; + appId.appId = "ohos.kvdatamanager.test"; create.createIfMissing = true; create.encrypt = false; create.autoSync = true; create.kvStoreType = SINGLE_VERSION; + create.area = EL1; + create.baseDir = std::string("/data/service/el1/public/database/") + appId.appId; + mkdir(create.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); noCreate.createIfMissing = false; noCreate.encrypt = false; noCreate.autoSync = true; noCreate.kvStoreType = SINGLE_VERSION; - - userId.userId = "account0"; - appId.appId = "com.ohos.kvdatamanager.test"; + noCreate.area = EL1; + noCreate.baseDir = create.baseDir; storeId64.storeId = "a000000000b000000000c000000000d000000000e000000000f000000000g000"; storeId65.storeId = "a000000000b000000000c000000000d000000000e000000000f000000000g000" @@ -110,6 +112,8 @@ void DistributedKvDataManagerTest::SetUpTestCase(void) void DistributedKvDataManagerTest::TearDownTestCase(void) { RemoveAllStore(manager); + remove((create.baseDir + "/kvdb").c_str()); + remove(create.baseDir.c_str()); } void DistributedKvDataManagerTest::SetUp(void) @@ -524,7 +528,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore001, TestSize.Level1) Status stat = manager.CloseKvStore(appId, storeId64); ASSERT_EQ(stat, Status::SUCCESS); - stat = manager.DeleteKvStore(appId, storeId64); + stat = manager.DeleteKvStore(appId, storeId64, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); } @@ -544,7 +548,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore002, TestSize.Level1) ASSERT_NE(kvStore, nullptr); // first close it if opened, and then delete it. - Status stat = manager.DeleteKvStore(appId, storeId64); + Status stat = manager.DeleteKvStore(appId, storeId64, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); } @@ -558,7 +562,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore002, TestSize.Level1) HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore003, TestSize.Level1) { ZLOGI("DeleteKvStore003 begin."); - Status stat = manager.DeleteKvStore(appId, storeId64); + Status stat = manager.DeleteKvStore(appId, storeId64, create.baseDir); EXPECT_EQ(stat, Status::STORE_NOT_FOUND); } @@ -614,7 +618,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore001, TestSize.Level1) stat = manager.CloseKvStore(appId, storeIdTest); EXPECT_EQ(stat, Status::SUCCESS); - stat = manager.DeleteAllKvStore(appId); + stat = manager.DeleteAllKvStore(appId, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); } @@ -639,7 +643,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore002, TestSize.Level1) Status stat = manager.CloseKvStore(appId, storeId64); EXPECT_EQ(stat, Status::SUCCESS); - stat = manager.DeleteAllKvStore(appId); + stat = manager.DeleteAllKvStore(appId, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); } @@ -653,7 +657,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore002, TestSize.Level1) HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore003, TestSize.Level1) { ZLOGI("DeleteAllKvStore003 begin."); - Status stat = manager.DeleteAllKvStore(appId); + Status stat = manager.DeleteAllKvStore(appId, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); } @@ -679,9 +683,9 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore004, TestSize.Level1) EXPECT_EQ(stat, Status::SUCCESS); stat = manager.CloseKvStore(appId, storeIdTest); EXPECT_EQ(stat, Status::SUCCESS); - stat = manager.DeleteKvStore(appId, storeIdTest); + stat = manager.DeleteKvStore(appId, storeIdTest, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); - stat = manager.DeleteAllKvStore(appId); + stat = manager.DeleteAllKvStore(appId, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); } diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp index 9804c2ad854ccaa94c42625885940837e1f45b25..4a191cee7cc14015f30f1a217f6817764c302f78 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp @@ -14,12 +14,11 @@ */ #define LOG_TAG "LocalSubscribeStoreTest" - -#include #include #include #include #include + #include "distributed_kv_data_manager.h" #include "log_print.h" #include "types.h" @@ -51,13 +50,16 @@ StoreId LocalSubscribeStoreTest::storeId; void LocalSubscribeStoreTest::SetUpTestCase(void) { + mkdir("/data/service/el1/public/database/odmf", (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); } void LocalSubscribeStoreTest::TearDownTestCase(void) { manager.CloseKvStore(appId, kvStore); kvStore = nullptr; - manager.DeleteKvStore(appId, storeId); + manager.DeleteKvStore(appId, storeId, "/data/service/el1/public/database/odmf"); + remove("/data/service/el1/public/database/odmf/kvdb"); + remove("/data/service/el1/public/database/odmf"); } void LocalSubscribeStoreTest::SetUp(void) @@ -67,10 +69,11 @@ void LocalSubscribeStoreTest::SetUp(void) options.encrypt = false; // not supported yet. options.autoSync = true; // not supported yet. options.kvStoreType = KvStoreType::SINGLE_VERSION; - + options.area = EL1; + options.baseDir = std::string("/data/service/el1/public/database/odmf"); appId.appId = "odmf"; // define app name. storeId.storeId = "student"; // define kvstore(database) name - manager.DeleteKvStore(appId, storeId); + manager.DeleteKvStore(appId, storeId, options.baseDir); // [create and] open and initialize kvstore instance. statusGetKvStore = manager.GetSingleKvStore(options, appId, storeId, kvStore); EXPECT_EQ(Status::SUCCESS, statusGetKvStore) << "statusGetKvStore return wrong status"; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp index 666d875b82972a77eb76288785b266f7e971fad9..be8915a0de03ac91b27fd1ad4f387a1160cfa8e2 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp @@ -35,7 +35,7 @@ public: void TearDown(); static std::shared_ptr singleKvStorePtr; // declare kvstore instance. - static Status statusGetKvStore; + static Status status_; static int MAX_VALUE_SIZE; }; @@ -48,7 +48,7 @@ const std::string VALID_SCHEMA_STRICT_DEFINE = "{\"SCHEMA_VERSION\":\"1.0\"," "\"SCHEMA_INDEXES\":[\"$.age\"]}"; std::shared_ptr SingleKvStoreClientTest::singleKvStorePtr = nullptr; -Status SingleKvStoreClientTest::statusGetKvStore = Status::ERROR; +Status SingleKvStoreClientTest::status_ = Status::ERROR; int SingleKvStoreClientTest::MAX_VALUE_SIZE = 4 * 1024 * 1024; // max value size is 4M. void SingleKvStoreClientTest::SetUpTestCase(void) @@ -56,16 +56,21 @@ void SingleKvStoreClientTest::SetUpTestCase(void) DistributedKvDataManager manager; Options options = { .createIfMissing = true, .encrypt = false, .autoSync = true, .kvStoreType = KvStoreType::SINGLE_VERSION }; - + options.area = EL1; + options.baseDir = std::string("/data/service/el1/public/database/odmf"); AppId appId = { "odmf" }; StoreId storeId = { "student_single" }; // define kvstore(database) name. - + mkdir(options.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); // [create and] open and initialize kvstore instance. - statusGetKvStore = manager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); + status_ = manager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); } void SingleKvStoreClientTest::TearDownTestCase(void) -{} +{ + remove("/data/service/el1/public/database/odmf/key"); + remove("/data/service/el1/public/database/odmf/kvdb"); + remove("/data/service/el1/public/database/odmf"); +} void SingleKvStoreClientTest::SetUp(void) {} @@ -350,10 +355,13 @@ HWTEST_F(SingleKvStoreClientTest, TestSchemaStoreC001, TestSize.Level1) { std::shared_ptr schemaSingleKvStorePtr; DistributedKvDataManager manager; - Options options = { .createIfMissing = true, .encrypt = true, .autoSync = true, - .kvStoreType = KvStoreType::SINGLE_VERSION }; + Options options; + options.encrypt = true; + options.area = EL1; + options.kvStoreType = KvStoreType::SINGLE_VERSION; + options.baseDir = "/data/service/el1/public/database/odmf"; options.schema = VALID_SCHEMA_STRICT_DEFINE; - AppId appId = { "schema_app_id" }; + AppId appId = { "odmf" }; StoreId storeId = { "schema_store_id" }; (void)manager.GetSingleKvStore(options, appId, storeId, schemaSingleKvStorePtr); ASSERT_NE(schemaSingleKvStorePtr, nullptr) << "kvStorePtr is null."; @@ -367,6 +375,7 @@ HWTEST_F(SingleKvStoreClientTest, TestSchemaStoreC001, TestSize.Level1) Value resultValue; auto getRet = schemaSingleKvStorePtr->Get(testKey, resultValue); EXPECT_EQ(getRet, Status::SUCCESS) << "get value failed."; + manager.DeleteKvStore(appId, storeId, options.baseDir); } /** @@ -431,7 +440,7 @@ HWTEST_F(SingleKvStoreClientTest, SetSync002, TestSize.Level1) * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch001, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmPutBatch001, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -474,7 +483,7 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch001, TestSize.Level2) * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch002, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmPutBatch002, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "SinglekvStorePtr is nullptr"; @@ -528,13 +537,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch002, TestSize.Level2) } /** -* @tc.name: SingleKvStoreDdmPutBatch003 +* @tc.name: DdmPutBatch003 * @tc.desc: Batch put data that contains invalid data. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch003, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmPutBatch003, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -555,13 +564,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch003, TestSize.Level2) } /** -* @tc.name: SingleKvStoreDdmPutBatch004 +* @tc.name: DdmPutBatch004 * @tc.desc: Batch put data that contains invalid data. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch004, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmPutBatch004, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -581,7 +590,7 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch004, TestSize.Level2) EXPECT_EQ(Status::INVALID_ARGUMENT, status) << "singleKvStorePtr putbatch data return wrong status"; } -std::string SingleGenerate1025KeyLen() +static std::string SingleGenerate1025KeyLen() { std::string str("prefix"); // Generate a key with a length of more than 1024 bytes. @@ -591,13 +600,13 @@ std::string SingleGenerate1025KeyLen() return str; } /** -* @tc.name: SingleKvStoreDdmPutBatch005 +* @tc.name: DdmPutBatch005 * @tc.desc: Batch put data that contains invalid data. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch005, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmPutBatch005, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -619,13 +628,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch005, TestSize.Level2) } /** -* @tc.name: SingleKvStoreDdmPutBatch006 +* @tc.name: DdmPutBatch006 * @tc.desc: Batch put large data. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch006, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmPutBatch006, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -667,13 +676,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmPutBatch006, TestSize.Level2) } /** -* @tc.name: SingleKvStoreDdmDeleteBatch001 +* @tc.name: DdmDeleteBatch001 * @tc.desc: Batch delete data. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch001, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch001, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -707,13 +716,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch001, TestSize.Level } /** -* @tc.name: SingleKvStoreDdmDeleteBatch002 +* @tc.name: DdmDeleteBatch002 * @tc.desc: Batch delete data when some keys are not in KvStore. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch002, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch002, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -748,13 +757,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch002, TestSize.Level } /** -* @tc.name: SingleKvStoreDdmDeleteBatch003 +* @tc.name: DdmDeleteBatch003 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch003, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch003, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "SinglekvStorePtr is nullptr"; @@ -788,13 +797,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch003, TestSize.Level } /** -* @tc.name: SingleKvStoreDdmDeleteBatch004 +* @tc.name: DdmDeleteBatch004 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch004, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch004, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -833,13 +842,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch004, TestSize.Level } /** -* @tc.name: SingleKvStoreDdmDeleteBatch005 +* @tc.name: DdmDeleteBatch005 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch005, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch005, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; @@ -879,13 +888,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDdmDeleteBatch005, TestSize.Level } /** -* @tc.name: SingleKvStoreTransaction001 +* @tc.name: Transaction001 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreTransaction001, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, Transaction001, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; std::shared_ptr observer = std::make_shared(); @@ -936,13 +945,13 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreTransaction001, TestSize.Level2) } /** -* @tc.name: SingleKvStoreTransaction002 +* @tc.name: Transaction002 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC * @tc.require: AR000DPSEA * @tc.author: shanshuangshuang */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreTransaction002, TestSize.Level2) +HWTEST_F(SingleKvStoreClientTest, Transaction002, TestSize.Level2) { EXPECT_NE(nullptr, singleKvStorePtr) << "singleKvStorePtr is nullptr"; std::shared_ptr observer = std::make_shared(); @@ -997,19 +1006,22 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreTransaction002, TestSize.Level2) } /** -* @tc.name: SingleKvStoreDeviceSync001 +* @tc.name: DeviceSync001 * @tc.desc: Test sync enable. * @tc.type: FUNC * @tc.require:AR000EPAM8 AR000EPAMD * @tc.author: HongBo */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDeviceSync001 ,TestSize.Level1) +HWTEST_F(SingleKvStoreClientTest, DeviceSync001 ,TestSize.Level1) { std::shared_ptr schemaSingleKvStorePtr; DistributedKvDataManager manager; - Options options = { .createIfMissing = true, .encrypt = true, .autoSync = true, - .kvStoreType = KvStoreType::SINGLE_VERSION}; - AppId appId = { "schema_app_id001" }; + Options options; + options.encrypt = true; + options.area = EL1; + options.kvStoreType = KvStoreType::SINGLE_VERSION; + options.baseDir = "/data/service/el1/public/database/odmf"; + AppId appId = { "odmf" }; StoreId storeId = { "schema_store_id001" }; manager.GetSingleKvStore(options, appId, storeId, schemaSingleKvStorePtr); ASSERT_NE(schemaSingleKvStorePtr, nullptr) << "kvStorePtr is null."; @@ -1018,22 +1030,26 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDeviceSync001 ,TestSize.Level1) auto testStatus = schemaSingleKvStorePtr->SetCapabilityEnabled(true); EXPECT_EQ(testStatus, Status::SUCCESS) << "set fail"; + manager.DeleteKvStore(appId, storeId, options.baseDir); } /** -* @tc.name: SingleKvStoreDeviceSync002 +* @tc.name: DeviceSync002 * @tc.desc: Test sync enable. * @tc.type: FUNC * @tc.require:SR000EPA22 AR000EPAM9 * @tc.author: HongBo */ -HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDeviceSync002 ,TestSize.Level1) +HWTEST_F(SingleKvStoreClientTest, DeviceSync002 ,TestSize.Level1) { std::shared_ptr schemaSingleKvStorePtr; DistributedKvDataManager manager; - Options options = { .createIfMissing = true, .encrypt = true, .autoSync = true, - .kvStoreType = KvStoreType::SINGLE_VERSION}; - AppId appId = { "schema_app_id002" }; + Options options; + options.encrypt = true; + options.area = EL1; + options.kvStoreType = KvStoreType::SINGLE_VERSION; + options.baseDir = "/data/service/el1/public/database/odmf"; + AppId appId = { "odmf" }; StoreId storeId = { "schema_store_id002" }; manager.GetSingleKvStore(options, appId, storeId, schemaSingleKvStorePtr); ASSERT_NE(schemaSingleKvStorePtr, nullptr) << "kvStorePtr is null."; @@ -1044,6 +1060,7 @@ HWTEST_F(SingleKvStoreClientTest, SingleKvStoreDeviceSync002 ,TestSize.Level1) std::vector remote = {"C", "D"}; auto testStatus = schemaSingleKvStorePtr->SetCapabilityRange(local, remote); EXPECT_EQ(testStatus, Status::SUCCESS) << "set range fail"; + manager.DeleteKvStore(appId, storeId, options.baseDir); } /** diff --git a/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h b/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h index 56252f5612a6823abeca46c960fc0815eae241ce..cec4b7bd1bb7fa3860303bf0601d0d93edb978b8 100644 --- a/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h +++ b/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h @@ -15,9 +15,10 @@ #ifndef SDB_AUTO_SYNC_TIMER_H #define SDB_AUTO_SYNC_TIMER_H - +#include #include "kv_scheduler.h" #include "kvdb_service.h" +#include "concurrent_map.h" namespace OHOS::DistributedKv { class AutoSyncTimer { diff --git a/frameworks/innerkitsimpl/kvdb/include/device_store_impl.h b/frameworks/innerkitsimpl/kvdb/include/device_store_impl.h index 5b50a4002741a36c90d4b427f15a54dd7a464a66..7bd0e3f42c49add26bfbb714153ae8e3a018a38b 100644 --- a/frameworks/innerkitsimpl/kvdb/include/device_store_impl.h +++ b/frameworks/innerkitsimpl/kvdb/include/device_store_impl.h @@ -30,6 +30,7 @@ protected: std::vector GetPrefix(const DataQuery &query) const override; Convert GetConvert() const override; std::vector ConvertNetwork(const Key &in, bool withLen = false) const; + std::vector ToLocal(const Key &in, bool withLen) const; }; } #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_DEVICE_STORE_IMPL_H diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h index 548490ebca6a7c5835e64eb7bbb1c536e31ea866..87cc3e0b5cb262ccc17b7303413b0c8d0908431d 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h @@ -55,10 +55,8 @@ public: virtual Status DisableCapability(const AppId &appId, const StoreId &storeId) = 0; virtual Status SetCapability(const AppId &appId, const StoreId &storeId, const std::vector &local, const std::vector &remote) = 0; - virtual Status AddSubscribeInfo(const AppId &appId, const StoreId &storeId, - const std::vector &devices, const std::string &query) = 0; - virtual Status RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, - const std::vector &devices, const std::string &query) = 0; + virtual Status AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; + virtual Status RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; virtual Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) = 0; virtual Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) = 0; @@ -77,8 +75,8 @@ protected: TRANS_ENABLE_CAP, TRANS_DISABLE_CAP, TRANS_SET_CAP, - TRANS_ADD_SUB_INFO, - TRANS_RMV_SUB_INFO, + TRANS_ADD_SUB, + TRANS_RMV_SUB, TRANS_SUB, TRANS_UNSUB, TRANS_BUTT, diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h index fb513f2351a69af4cf0487058aa3d11b51e0b082..00d2a7e38e4e6759bd492a2967877cf032ba94d5 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h @@ -39,10 +39,8 @@ public: Status DisableCapability(const AppId &appId, const StoreId &storeId) override; Status SetCapability(const AppId &appId, const StoreId &storeId, const std::vector &local, const std::vector &remote) override; - Status AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const std::vector &devices, - const std::string &query) override; - Status RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const std::vector &devices, - const std::string &query) override; + Status AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; + Status RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; sptr GetSyncAgent(const AppId &appId); diff --git a/frameworks/innerkitsimpl/kvdb/include/security_manager.h b/frameworks/innerkitsimpl/kvdb/include/security_manager.h index bf288173063daf3463a8f20db396ad8765b78216..c70ea53fd312aa6bd1831718760416ce0b61e75b 100644 --- a/frameworks/innerkitsimpl/kvdb/include/security_manager.h +++ b/frameworks/innerkitsimpl/kvdb/include/security_manager.h @@ -22,8 +22,8 @@ class API_EXPORT SecurityManager { public: using DBPassword = DistributedDB::CipherPassword; static SecurityManager &GetInstance(); - DBPassword GetDBPassword(const AppId &appId, const StoreId &storeId, const std::string &path); - void DelDBPassword(const AppId &appId, const StoreId &storeId, const std::string &path); + DBPassword GetDBPassword(const StoreId &storeId, const std::string &path, bool encrypt); + void DelDBPassword(const StoreId &storeId, const std::string &path); private: static constexpr const char *ROOT_KEY_ALIAS = "distributed_db_root_key"; @@ -37,6 +37,10 @@ private: static constexpr const char *HKS_BLOB_TYPE_AAD = "distributeddata"; static constexpr int KEY_SIZE = 32; static constexpr int HOURS_PER_YEAR = (24 * 365); + + static std::vector Random(int32_t len); + std::vector LoadRandomKey(const StoreId &storeId, const std::string &path); + bool SaveRandomKey(const StoreId &storeId, const std::string &path, const std::vector &key); }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SECURITY_MANAGER_H diff --git a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index 92b6d9a4d3225d2f8d16e403ffc757f7ba8983ba..ccc185ab699c10014e00fbb7da9e5c9e8f2040b4 100644 --- a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -57,7 +57,8 @@ public: Status GetCount(const DataQuery &query, int &count) const override; Status GetSecurityLevel(SecurityLevel &secLevel) const override; Status RemoveDeviceData(const std::string &device) override; - Status Close(); + int32_t Close(bool isForce = false); + int32_t AddRef(); // IPC interface Status Sync(const std::vector &devices, SyncMode mode, uint32_t delay) override; @@ -68,8 +69,8 @@ public: Status SetSyncParam(const KvSyncParam &syncParam) override; Status GetSyncParam(KvSyncParam &syncParam) override; Status SetCapabilityEnabled(bool enabled) const override; - Status SetCapabilityRange( - const std::vector &localLabels, const std::vector &remoteLabels) const override; + Status SetCapabilityRange(const std::vector &local, + const std::vector &remote) const override; Status SubscribeWithQuery(const std::vector &devices, const DataQuery &query) override; Status UnsubscribeWithQuery(const std::vector &devices, const DataQuery &query) override; @@ -93,6 +94,7 @@ private: std::string appId_; std::string storeId_; bool autoSync_ = false; + int32_t ref_ = 1; mutable std::shared_mutex rwMutex_; std::shared_ptr syncObserver_ = nullptr; ConcurrentMap>> observers_; diff --git a/frameworks/innerkitsimpl/kvdb/include/store_factory.h b/frameworks/innerkitsimpl/kvdb/include/store_factory.h index 26510719b6ffb3eeb7c6a32128e4de1d6dec9769..0eddf03f7212bbc668a984c56442372a0e474406 100644 --- a/frameworks/innerkitsimpl/kvdb/include/store_factory.h +++ b/frameworks/innerkitsimpl/kvdb/include/store_factory.h @@ -24,11 +24,10 @@ namespace OHOS::DistributedKv { class API_EXPORT StoreFactory { public: static StoreFactory &GetInstance(); - std::shared_ptr GetOrOpenStore( - const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status); + std::shared_ptr GetOrOpenStore(const AppId &appId, const StoreId &storeId, const Options &options, + Status &status, bool &isCreate); Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path); - Status Close(const AppId &appId, const StoreId &storeId); - bool IsOpen(const AppId &appId, const StoreId &storeId); + Status Close(const AppId &appId, const StoreId &storeId, bool isForce = false); private: using DBManager = DistributedDB::KvStoreDelegateManager; diff --git a/frameworks/innerkitsimpl/kvdb/include/store_manager.h b/frameworks/innerkitsimpl/kvdb/include/store_manager.h index 5e90d38202de1d21d9a205d0554389a4e39cdc33..df747f7a86503fd4d16304db523eceb9cc67d7b2 100644 --- a/frameworks/innerkitsimpl/kvdb/include/store_manager.h +++ b/frameworks/innerkitsimpl/kvdb/include/store_manager.h @@ -20,8 +20,8 @@ namespace OHOS::DistributedKv { class StoreManager { public: static StoreManager &GetInstance(); - std::shared_ptr GetKVStore( - const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status); + std::shared_ptr GetKVStore(const AppId &appId, const StoreId &storeId, const Options &options, + Status &status); Status CloseKVStore(const AppId &appId, const StoreId &storeId); Status CloseKVStore(const AppId &appId, std::shared_ptr &kvStore); Status CloseAllKVStore(const AppId &appId); diff --git a/frameworks/innerkitsimpl/kvdb/include/store_util.h b/frameworks/innerkitsimpl/kvdb/include/store_util.h index 018e2a1d39b5e7629b823dc1724af3dc1589362e..46687d3b3307696cddc71c20bca52749fca650c7 100644 --- a/frameworks/innerkitsimpl/kvdb/include/store_util.h +++ b/frameworks/innerkitsimpl/kvdb/include/store_util.h @@ -29,7 +29,9 @@ public: static std::string Anonymous(const std::string &name); static uint32_t Anonymous(const void *ptr); static Status ConvertStatus(DBStatus status); - static int32_t InitPath(const std::string &path); + static bool InitPath(const std::string &path); + static bool Remove(const std::string &path); + }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_UTIL_H diff --git a/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp b/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp index 75cdc3e30e21064c610b54f6637610b164d9ac11..16ac9dc75191152bb02b735a52bb56a06fde49e0 100644 --- a/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp @@ -12,12 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #define LOG_TAG "AutoSyncTimer" +#include "auto_sync_timer.h" -#include #include "kvdb_service_client.h" -#include "auto_sync_timer.h" +#include "log_print.h" + namespace OHOS::DistributedKv { AutoSyncTimer &AutoSyncTimer::GetInstance() { @@ -57,7 +57,7 @@ void AutoSyncTimer::AddSyncStores(const std::string &appId, std::set st bool AutoSyncTimer::HasSyncStores() { - return stores_.Empty(); + return !stores_.Empty(); } std::map> AutoSyncTimer::GetStoreIds() @@ -90,8 +90,10 @@ std::function AutoSyncTimer::ProcessTask() if (service == nullptr) { return; } + auto storeIds = GetStoreIds(); for (const auto &id : storeIds) { + ZLOGD("DoSync appId:%{public}s store size:%{public}zu", id.first.c_str(), id.second.size()); for (const auto &storeId : id.second) { service->Sync({ id.first }, storeId, {}); } diff --git a/frameworks/innerkitsimpl/kvdb/src/device_store_impl.cpp b/frameworks/innerkitsimpl/kvdb/src/device_store_impl.cpp index 37c740ec3d13090ad09c1ba46b12b6aa883cdae0..a9a7794df37f19d7e3288253910ea2461da05166 100644 --- a/frameworks/innerkitsimpl/kvdb/src/device_store_impl.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/device_store_impl.cpp @@ -22,13 +22,18 @@ #include "log_print.h" namespace OHOS::DistributedKv { std::vector DeviceStoreImpl::ToLocalDBKey(const Key &key) const +{ + return ToLocal(key, true); +} + +std::vector DeviceStoreImpl::ToLocal(const Key &in, bool withLen) const { auto uuid = DevManager::GetInstance().GetLocalDevice().uuid; if (uuid.empty()) { return {}; } - std::vector input = SingleStoreImpl::GetPrefix(key); + std::vector input = withLen ? SingleStoreImpl::GetPrefix(in) : in.Data(); if (input.empty()) { return {}; } @@ -38,9 +43,12 @@ std::vector DeviceStoreImpl::ToLocalDBKey(const Key &key) const std::vector dbKey; dbKey.insert(dbKey.end(), uuid.begin(), uuid.end()); dbKey.insert(dbKey.end(), input.begin(), input.end()); - uint32_t length = uuid.length(); - length = htole32(length); - dbKey.insert(dbKey.end(), &length, &length + sizeof(length)); + if (withLen) { + uint32_t length = uuid.length(); + length = htole32(length); + uint8_t *buf = reinterpret_cast(&length); + dbKey.insert(dbKey.end(), buf, buf + sizeof(length)); + } return dbKey; } @@ -48,14 +56,22 @@ std::vector DeviceStoreImpl::ToWholeDBKey(const Key &key) const { // | device uuid | original key | uuid len | // |-------------|--------------|-----4----| - return ConvertNetwork(key); + return ConvertNetwork(key, true); } Key DeviceStoreImpl::ToKey(DBKey &&key) const { // | uuid |original key|uuid len| // |---- -----|------------|---4----| + if (key.size() < sizeof(uint32_t)) { + return std::move(key); + } + uint32_t length = *(reinterpret_cast(&(*(key.end() - sizeof(uint32_t))))); + if (length > key.size() - sizeof(uint32_t)) { + return std::move(key); + } + length = le32toh(length); key.erase(key.begin(), key.begin() + length); key.erase(key.end() - sizeof(uint32_t), key.end()); @@ -84,7 +100,15 @@ std::vector DeviceStoreImpl::GetPrefix(const DataQuery &query) const SingleStoreImpl::Convert DeviceStoreImpl::GetConvert() const { return [](const DBKey &key, std::string &deviceId) { + if (key.size() < sizeof(uint32_t)) { + return std::move(key); + } + uint32_t length = *(reinterpret_cast(&(*(key.end() - sizeof(uint32_t))))); + if (length > key.size() - sizeof(uint32_t)) { + return std::move(key); + } + length = le32toh(length); deviceId = { key.begin(), key.begin() + length }; Key result(std::vector(key.begin() + length, key.end() - sizeof(uint32_t))); @@ -98,18 +122,23 @@ std::vector DeviceStoreImpl::ConvertNetwork(const Key &in, bool withLen // | network ID len | networkID | original key| // |--------4-------|-----------|------------| if (in.Size() < sizeof(uint32_t)) { - return in.Data(); + return ToLocal(in, withLen); } - size_t deviceLen = *(reinterpret_cast(in.Data().data())); - std::string networkId(in.Data().begin() + sizeof(uint32_t), in.Data().begin() + sizeof(uint32_t) + deviceLen); + std::string deviceLen(in.Data().data(), in.Data().data() + sizeof(uint32_t)); std::regex patten("^[0-9]*$"); - if (!std::regex_match(networkId, patten)) { - ZLOGE("device id length is error."); - return in.Data(); + if (!std::regex_match(deviceLen, patten)) { + return ToLocal(in, withLen); + } + + uint32_t devLen = atol(deviceLen.c_str()); + if (devLen > in.Data().size() + sizeof(uint32_t)) { + return ToLocal(in, withLen); } + + std::string networkId(in.Data().begin() + sizeof(uint32_t), in.Data().begin() + sizeof(uint32_t) + devLen); std::string uuid = DevManager::GetInstance().ToUUID(networkId); if (uuid.empty()) { - return in.Data(); + return ToLocal(in, withLen); } // output @@ -118,11 +147,12 @@ std::vector DeviceStoreImpl::ConvertNetwork(const Key &in, bool withLen // | Mandatory | Mandatory | Optional | std::vector out; out.insert(out.end(), uuid.begin(), uuid.end()); - out.insert(out.end(), in.Data().begin() + sizeof(uint32_t) + deviceLen, in.Data().end()); + out.insert(out.end(), in.Data().begin() + sizeof(uint32_t) + devLen, in.Data().end()); if (withLen) { uint32_t length = uuid.length(); length = htole32(length); - out.insert(out.end(), &length, &length + sizeof(length)); + uint8_t *buf = reinterpret_cast(&length); + out.insert(out.end(), buf, buf + sizeof(length)); } return out; } diff --git a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp index 452f757de8362a814b87d43eb7231e6ea25f622f..9f6327929bab4cea0787129dfe95b33c21ddf043 100644 --- a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp @@ -28,7 +28,7 @@ namespace OHOS::DistributedKv { #define IPC_SEND(code, reply, ...) \ ({ \ - int32_t __status; \ + int32_t __status = SUCCESS; \ do { \ MessageParcel request; \ if (!request.WriteInterfaceToken(GetDescriptor())) { \ @@ -232,26 +232,24 @@ Status KVDBServiceClient::SetCapability(const AppId &appId, const StoreId &store return static_cast(status); } -Status KVDBServiceClient::AddSubscribeInfo( - const AppId &appId, const StoreId &storeId, const std::vector &devices, const std::string &query) +Status KVDBServiceClient::AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) { MessageParcel reply; - int32_t status = IPC_SEND(TRANS_ADD_SUB_INFO, reply, appId, storeId, devices, query); + int32_t status = IPC_SEND(TRANS_ADD_SUB, reply, appId, storeId, syncInfo.seqId, syncInfo.devices, syncInfo.query); if (status != SUCCESS) { ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, query:%{public}s", status, - appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(query).c_str()); + appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(syncInfo.query).c_str()); } return static_cast(status); } -Status KVDBServiceClient::RmvSubscribeInfo( - const AppId &appId, const StoreId &storeId, const std::vector &devices, const std::string &query) +Status KVDBServiceClient::RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) { MessageParcel reply; - int32_t status = IPC_SEND(TRANS_RMV_SUB_INFO, reply, appId, storeId, devices, query); + int32_t status = IPC_SEND(TRANS_RMV_SUB, reply, appId, storeId, syncInfo.seqId, syncInfo.devices, syncInfo.query); if (status != SUCCESS) { ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, query:%{public}s", status, - appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(query).c_str()); + appId.appId.c_str(), storeId.storeId.c_str(), StoreUtil::Anonymous(syncInfo.query).c_str()); } return static_cast(status); } diff --git a/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp b/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp index d5d7b40dbe29bac62e5f2878e36957023ac140ea..44325e6c338799ab64efcd56bb5ccd902f5fb68f 100644 --- a/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp @@ -12,8 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "security_manager.h" +#include +#include + +#include "file_ex.h" +#include "store_util.h" namespace OHOS::DistributedKv { SecurityManager &SecurityManager::GetInstance() { @@ -21,13 +25,88 @@ SecurityManager &SecurityManager::GetInstance() return instance; } -SecurityManager::DBPassword SecurityManager::GetDBPassword( - const AppId &appId, const StoreId &storeId, const std::string &path) +SecurityManager::DBPassword SecurityManager::GetDBPassword(const StoreId &storeId, const std::string &path, + bool encrypt) { - return SecurityManager::DBPassword(); + if (!encrypt) { + return DBPassword(); + } + + auto secKey = LoadRandomKey(storeId, path); + if (secKey.empty()) { + secKey = Random(KEY_SIZE); + SaveRandomKey(storeId, path, secKey); + } + + DBPassword password; + password.SetValue(secKey.data(), secKey.size()); + secKey.assign(secKey.size(), 0); + return password; +} + +void SecurityManager::DelDBPassword(const StoreId &storeId, const std::string &path) +{ + auto keyPath = path + "/key/" + storeId.storeId + ".key"; + StoreUtil::Remove(keyPath); + keyPath = path + "/key/" + storeId.storeId + ".rekey"; + StoreUtil::Remove(keyPath); +} + +std::vector SecurityManager::Random(int32_t len) +{ + std::random_device randomDevice; + std::uniform_int_distribution distribution(0, std::numeric_limits::max()); + std::vector key(len); + for (int32_t i = 0; i < len; i++) { + key[i] = static_cast(distribution(randomDevice)); + } + return key; +} + +std::vector SecurityManager::LoadRandomKey(const StoreId &storeId, const std::string &path) +{ + auto keyPath = path + "/key/" + storeId.storeId + ".key"; + if (!FileExists(keyPath)) { + return {}; + } + + std::vector content; + auto loaded = LoadBufferFromFile(keyPath, content); + if (!loaded) { + return {}; + } + + if (content.size() < (sizeof(time_t) / sizeof(uint8_t)) + KEY_SIZE + 1) { + return {}; + } + + size_t offset = 0; + if (content[offset] != char((sizeof(time_t) / sizeof(uint8_t)) + KEY_SIZE)) { + return {}; + } + + offset++; + std::vector date; + date.assign(content.begin() + offset, content.begin() + (sizeof(time_t) / sizeof(uint8_t)) + offset); + offset += (sizeof(time_t) / sizeof(uint8_t)); + std::vector key{content.begin() + offset, content.begin() + KEY_SIZE + offset}; + content.assign(content.size(), 0); + return key; } -void SecurityManager::DelDBPassword(const AppId &appId, const StoreId &storeId, const std::string &path) +bool SecurityManager::SaveRandomKey(const StoreId &storeId, const std::string &path, const std::vector &key) { + auto keyPath = path + "/key"; + StoreUtil::InitPath(keyPath); + keyPath = keyPath + "/" + storeId.storeId + ".key"; + std::vector content; + auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::system_clock::now()); + std::vector date(reinterpret_cast(&time), reinterpret_cast(&time) + sizeof(time)); + content.push_back(char((sizeof(time_t) / sizeof(uint8_t)) + KEY_SIZE)); + content.insert(content.end(), date.begin(), date.end()); + content.insert(content.end(), key.begin(), key.end()); + auto ret = SaveBufferToFile(keyPath, content); + content.assign(content.size(), 0); + return ret; } } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index 483a8b4cf72d5de20318c42f960ac84196757f5c..b393982359acdc6a7369f386e430ca0cc461fdb8 100644 --- a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -15,6 +15,7 @@ #define LOG_TAG "SingleStoreImpl" #include "single_store_impl.h" +#include "auto_sync_timer.h" #include "dds_trace.h" #include "dev_manager.h" #include "kvdb_service_client.h" @@ -22,7 +23,6 @@ #include "log_print.h" #include "store_result_set.h" #include "store_util.h" -#include "auto_sync_timer.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedDataDfx; SingleStoreImpl::SingleStoreImpl(std::shared_ptr dbStore, const AppId &appId, const Options &options) @@ -307,7 +307,7 @@ Status SingleStoreImpl::Get(const Key &key, Value &value) DBKey dbKey = ToWholeDBKey(key); if (dbKey.empty()) { - ZLOGE("invalid key:%{public}s, size:%{public}zu", key.ToString().c_str(), key.Size()); + ZLOGE("invalid key:%{public}s, size:%{public}zu", StoreUtil::Anonymous(key.ToString()).c_str(), key.Size()); return INVALID_ARGUMENT; } @@ -316,7 +316,7 @@ Status SingleStoreImpl::Get(const Key &key, Value &value) value = std::move(dbValue); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x, key:%{public}s", status, key.ToString().c_str()); + ZLOGE("status:0x%{public}x, key:%{public}s", status, StoreUtil::Anonymous(key.ToString()).c_str()); } return status; } @@ -326,7 +326,8 @@ Status SingleStoreImpl::GetEntries(const Key &prefix, std::vector &entrie DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); DBKey dbPrefix = GetPrefix(prefix); if (dbPrefix.empty() && !prefix.Empty()) { - ZLOGE("invalid prefix:%{public}s, size:%{public}zu", prefix.ToString().c_str(), prefix.Size()); + ZLOGE("invalid prefix:%{public}s, size:%{public}zu", StoreUtil::Anonymous(prefix.ToString()).c_str(), + prefix.Size()); return INVALID_ARGUMENT; } @@ -334,7 +335,7 @@ Status SingleStoreImpl::GetEntries(const Key &prefix, std::vector &entrie dbQuery.PrefixKey(dbPrefix); auto status = GetEntries(dbQuery, entries); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x, prefix:%{public}s", status, prefix.ToString().c_str()); + ZLOGE("status:0x%{public}x, prefix:%{public}s", status, StoreUtil::Anonymous(prefix.ToString()).c_str()); } return status; } @@ -346,7 +347,7 @@ Status SingleStoreImpl::GetEntries(const DataQuery &query, std::vector &e dbQuery.PrefixKey(GetPrefix(query)); auto status = GetEntries(dbQuery, entries); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x, query:%{public}s", status, query.ToString().c_str()); + ZLOGE("status:0x%{public}x, query:%{public}s", status, StoreUtil::Anonymous(query.ToString()).c_str()); } return status; } @@ -356,7 +357,8 @@ Status SingleStoreImpl::GetResultSet(const Key &prefix, std::shared_ptrGetCount(dbQuery, result); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x query:%{public}s", status, query.ToString().c_str()); + ZLOGE("status:0x%{public}x query:%{public}s", status, StoreUtil::Anonymous(query.ToString()).c_str()); } return status; } @@ -453,13 +455,14 @@ Status SingleStoreImpl::RemoveDeviceData(const std::string &device) return status; } -Status SingleStoreImpl::Sync(const std::vector &devices, SyncMode mode, uint32_t allowedDelayMs) +Status SingleStoreImpl::Sync(const std::vector &devices, SyncMode mode, uint32_t delay) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); KVDBService::SyncInfo syncInfo; syncInfo.seqId = KvStoreUtils::GenerateSequenceId(); syncInfo.mode = mode; - syncInfo.delay = mode; + syncInfo.delay = delay; + syncInfo.devices = devices; return DoSync(syncInfo, syncObserver_); } @@ -528,8 +531,8 @@ Status SingleStoreImpl::SetCapabilityEnabled(bool enabled) const return service->DisableCapability({ appId_ }, { storeId_ }); } -Status SingleStoreImpl::SetCapabilityRange( - const std::vector &localLabels, const std::vector &remoteLabels) const +Status SingleStoreImpl::SetCapabilityRange(const std::vector &localLabels, + const std::vector &remoteLabels) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); auto service = KVDBServiceClient::GetInstance(); @@ -546,7 +549,18 @@ Status SingleStoreImpl::SubscribeWithQuery(const std::vector &devic if (service == nullptr) { return SERVER_UNAVAILABLE; } - return service->AddSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); + SyncInfo syncInfo; + syncInfo.seqId = KvStoreUtils::GenerateSequenceId(); + syncInfo.devices = devices; + syncInfo.query = query.ToString(); + auto syncAgent = service->GetSyncAgent({ appId_ }); + if (syncAgent == nullptr) { + ZLOGE("failed! invalid agent app:%{public}s, store:%{public}s!", appId_.c_str(), storeId_.c_str()); + return ILLEGAL_STATE; + } + + syncAgent->AddSyncCallback(syncObserver_, syncInfo.seqId); + return service->AddSubscribeInfo({ appId_ }, { storeId_ }, syncInfo); } Status SingleStoreImpl::UnsubscribeWithQuery(const std::vector &devices, const DataQuery &query) @@ -556,16 +570,41 @@ Status SingleStoreImpl::UnsubscribeWithQuery(const std::vector &dev if (service == nullptr) { return SERVER_UNAVAILABLE; } - return service->RmvSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); + SyncInfo syncInfo; + syncInfo.seqId = KvStoreUtils::GenerateSequenceId(); + syncInfo.devices = devices; + syncInfo.query = query.ToString(); + auto syncAgent = service->GetSyncAgent({ appId_ }); + if (syncAgent == nullptr) { + ZLOGE("failed! invalid agent app:%{public}s, store:%{public}s!", appId_.c_str(), storeId_.c_str()); + return ILLEGAL_STATE; + } + + syncAgent->AddSyncCallback(syncObserver_, syncInfo.seqId); + return service->RmvSubscribeInfo({ appId_ }, { storeId_ }, syncInfo); +} + +int32_t SingleStoreImpl::AddRef() +{ + ref_++; + return ref_; } -Status SingleStoreImpl::Close() +int32_t SingleStoreImpl::Close(bool isForce) { + if (isForce) { + ref_ = 1; + } + ref_--; + if (ref_ != 0) { + return ref_; + } + observers_.Clear(); syncObserver_->Clean(); std::unique_lock lock(rwMutex_); dbStore_ = nullptr; - return SUCCESS; + return ref_; } std::vector SingleStoreImpl::ToLocalDBKey(const Key &key) const @@ -650,8 +689,11 @@ std::vector SingleStoreImpl::GetPrefix(const Key &prefix) const auto begin = std::find_if(prefix.Data().begin(), prefix.Data().end(), [](int ch) { return !std::isspace(ch); }); auto rBegin = std::find_if(prefix.Data().rbegin(), prefix.Data().rend(), [](int ch) { return !std::isspace(ch); }); auto end = static_cast(rBegin.base()); - std::vector dbKey; - dbKey.assign(begin, end); + if (end <= begin) { + return {}; + } + + std::vector dbKey(begin, end); if (dbKey.size() >= MAX_KEY_LENGTH) { dbKey.clear(); } @@ -690,6 +732,7 @@ void SingleStoreImpl::DoAutoSync() if (!autoSync_) { return; } - AutoSyncTimer::GetInstance().DoAutoSync(appId_, {{storeId_}}); + ZLOGD("app:%{public}s, store:%{public}s!", appId_.c_str(), storeId_.c_str()); + AutoSyncTimer::GetInstance().DoAutoSync(appId_, { { storeId_ } }); } } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp index 9e8ad54b0da2dd9f0d10926e8000f02da76e1745..7a9d1868f5765d037132b56f46e481786153ef4f 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp @@ -34,18 +34,22 @@ StoreFactory::StoreFactory() (void)DBManager::SetProcessSystemAPIAdapter(std::make_shared()); } -std::shared_ptr StoreFactory::GetOrOpenStore( - const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status) +std::shared_ptr StoreFactory::GetOrOpenStore(const AppId &appId, const StoreId &storeId, + const Options &options, Status &status, bool &isCreate) { - DBStatus dbStatus = DBStatus::OK; std::shared_ptr kvStore; + isCreate = false; stores_.Compute(appId, [&](auto &, auto &stores) { if (stores.find(storeId) != stores.end()) { kvStore = stores[storeId]; + kvStore->AddRef(); + status = SUCCESS; return !stores.empty(); } - auto dbManager = GetDBManager(path, appId); - auto password = SecurityManager::GetInstance().GetDBPassword(appId, storeId, path); + + auto dbManager = GetDBManager(options.baseDir, appId); + auto password = SecurityManager::GetInstance().GetDBPassword(storeId, options.baseDir, options.encrypt); + DBStatus dbStatus = DBStatus::DB_ERROR; dbManager->GetKvStore(storeId, GetDBOption(options, password), [&dbManager, &kvStore, &appId, &dbStatus, &options](auto status, auto *store) { dbStatus = status; @@ -60,67 +64,65 @@ std::shared_ptr StoreFactory::GetOrOpenStore( kvStore = std::make_shared(dbStore, appId, options); } }); - + status = StoreUtil::ConvertStatus(dbStatus); if (kvStore == nullptr) { ZLOGE("failed! status:%{public}d appId:%{public}s storeId:%{public}s path:%{public}s", dbStatus, appId.appId.c_str(), storeId.storeId.c_str(), options.baseDir.c_str()); return !stores.empty(); } - + isCreate = true; stores[storeId] = kvStore; return !stores.empty(); }); - status = StoreUtil::ConvertStatus(dbStatus); return kvStore; } Status StoreFactory::Delete(const AppId &appId, const StoreId &storeId, const std::string &path) { - Close(appId, storeId); + Close(appId, storeId, true); auto dbManager = GetDBManager(path, appId); auto status = dbManager->DeleteKvStore(storeId); - SecurityManager::GetInstance().DelDBPassword(appId, storeId, path); + SecurityManager::GetInstance().DelDBPassword(storeId, path); return StoreUtil::ConvertStatus(status); } -Status StoreFactory::Close(const AppId &appId, const StoreId &storeId) +Status StoreFactory::Close(const AppId &appId, const StoreId &storeId, bool isForce) { - stores_.ComputeIfPresent(appId, [&storeId](auto &, auto &values) { + Status status = STORE_NOT_OPEN; + stores_.ComputeIfPresent(appId, [&storeId, &status, isForce](auto &, auto &values) { for (auto it = values.begin(); it != values.end();) { if (!storeId.storeId.empty() && (it->first != storeId.storeId)) { ++it; - } else { - it->second->Close(); + continue; + } + + status = SUCCESS; + auto ref = it->second->Close(isForce); + if (ref <= 0) { it = values.erase(it); + } else { + ++it; } } return !values.empty(); }); - return SUCCESS; -} - -bool StoreFactory::IsOpen(const AppId &appId, const StoreId &storeId) -{ - bool isExits = false; - stores_.ComputeIfPresent(appId, [&storeId, &isExits](auto &, auto &values) { - isExits = (values.find(storeId) != values.end()); - return !values.empty(); - }); - return isExits; + return status; } std::shared_ptr StoreFactory::GetDBManager(const std::string &path, const AppId &appId) { std::shared_ptr dbManager; dbManagers_.Compute(path, [&dbManager, &appId](const auto &path, std::shared_ptr &manager) { - if (manager == nullptr) { - manager = std::make_shared(appId.appId, "default"); - std::string fullPath = path + "/kvdb"; - StoreUtil::InitPath(fullPath); - manager->SetKvStoreConfig({ fullPath }); + if (manager != nullptr) { + dbManager = manager; + return true; } - dbManager = manager; - return true; + std::string fullPath = path + "/kvdb"; + auto result = StoreUtil::InitPath(fullPath); + dbManager = std::make_shared(appId.appId, "default"); + dbManager->SetKvStoreConfig({ fullPath }); + manager = dbManager; + return result; }); return dbManager; } @@ -129,7 +131,7 @@ StoreFactory::DBOption StoreFactory::GetDBOption(const Options &options, const D { DBOption dbOption; dbOption.syncDualTupleMode = true; // tuple of (appid+storeid) - dbOption.createIfNecessary = true; + dbOption.createIfNecessary = options.createIfMissing; dbOption.isMemoryDb = (!options.persistent); dbOption.isEncryptedDb = options.encrypt; if (options.encrypt) { diff --git a/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp b/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp index 30e79260ca7a1415f52ada62d55111df3fa0b78d..7f225f5fbea63c1773bc0b144b207af4dbd880e1 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp @@ -25,38 +25,48 @@ StoreManager &StoreManager::GetInstance() return instance; } -std::shared_ptr StoreManager::GetKVStore( - const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status) +std::shared_ptr StoreManager::GetKVStore(const AppId &appId, const StoreId &storeId, + const Options &options, Status &status) { - if (StoreFactory::GetInstance().IsOpen(appId, storeId)) { - return StoreFactory::GetInstance().GetOrOpenStore(appId, storeId, options, path, status); + if (!appId.IsValid() || !storeId.IsValid() || !options.IsValidType()) { + status = INVALID_ARGUMENT; + return nullptr; } auto service = KVDBServiceClient::GetInstance(); if (service != nullptr) { service->BeforeCreate(appId, storeId, options); } - auto kvStore = StoreFactory::GetInstance().GetOrOpenStore(appId, storeId, options, path, status); - auto password = SecurityManager::GetInstance().GetDBPassword(appId, storeId, path); - std::vector pwd(password.GetData(), password.GetData() + password.GetSize()); - if (service != nullptr) { - // delay notify - service->AfterCreate(appId, storeId, options, pwd); + + bool isCreate = false; + auto kvStore = StoreFactory::GetInstance().GetOrOpenStore(appId, storeId, options, status, isCreate); + if (isCreate) { + auto password = SecurityManager::GetInstance().GetDBPassword(storeId, options.baseDir, options.encrypt); + std::vector pwd(password.GetData(), password.GetData() + password.GetSize()); + if (service != nullptr) { + // delay notify + service->AfterCreate(appId, storeId, options, pwd); + } + pwd.assign(pwd.size(), 0); } - pwd.assign(pwd.size(), 0); return kvStore; } Status StoreManager::CloseKVStore(const AppId &appId, const StoreId &storeId) { + if (!appId.IsValid() || !storeId.IsValid()) { + return INVALID_ARGUMENT; + } + return StoreFactory::GetInstance().Close(appId, storeId); } Status StoreManager::CloseKVStore(const AppId &appId, std::shared_ptr &kvStore) { - if (kvStore == nullptr) { + if (!appId.IsValid() || kvStore == nullptr) { return INVALID_ARGUMENT; } + StoreId storeId{ kvStore->GetStoreId() }; kvStore = nullptr; return StoreFactory::GetInstance().Close(appId, storeId); @@ -64,11 +74,19 @@ Status StoreManager::CloseKVStore(const AppId &appId, std::shared_ptrDelete(appId, storeId); diff --git a/frameworks/innerkitsimpl/kvdb/src/store_util.cpp b/frameworks/innerkitsimpl/kvdb/src/store_util.cpp index 7fdea1e17854e911a387f2e6bb545aaf46b33b4c..32b381e3db21286d9685bd3d407faa4ba2e72a43 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_util.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_util.cpp @@ -14,13 +14,13 @@ */ #define LOG_TAG "StoreUtil" #include "store_util.h" - #include #include - #include "log_print.h" #include "types.h" + namespace OHOS::DistributedKv { +constexpr mode_t DEFAULT_UMASK = 0002; constexpr int32_t HEAD_SIZE = 3; constexpr int32_t END_SIZE = 3; constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; @@ -89,7 +89,7 @@ Status StoreUtil::ConvertStatus(StoreUtil::DBStatus status) case DBStatus::INVALID_ARGS: return Status::INVALID_ARGUMENT; case DBStatus::NOT_FOUND: - return Status::KEY_NOT_FOUND; + return Status::NOT_FOUND; case DBStatus::INVALID_VALUE_FIELDS: return Status::INVALID_VALUE_FIELDS; case DBStatus::INVALID_FIELD_TYPE: @@ -108,6 +108,12 @@ Status StoreUtil::ConvertStatus(StoreUtil::DBStatus status) return Status::TIME_OUT; case DBStatus::OVER_MAX_LIMITS: return Status::OVER_MAX_SUBSCRIBE_LIMITS; + case DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB: + return Status::CRYPT_ERROR; + case DBStatus::SCHEMA_MISMATCH: + return Status::SCHEMA_MISMATCH; + case DBStatus::INVALID_SCHEMA: + return Status::INVALID_SCHEMA; case DBStatus::EKEYREVOKED_ERROR: // fallthrough case DBStatus::SECURITY_OPTION_CHECK_ERROR: return Status::SECURITY_LEVEL_ERROR; @@ -117,15 +123,28 @@ Status StoreUtil::ConvertStatus(StoreUtil::DBStatus status) } return Status::ERROR; } -int32_t StoreUtil::InitPath(const std::string &path) +bool StoreUtil::InitPath(const std::string &path) { if (access(path.c_str(), F_OK) == 0) { return true; } + umask(DEFAULT_UMASK); if (mkdir(path.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) { ZLOGE("mkdir error:%{public}d, path:%{public}s", errno, path.c_str()); return false; } return true; } + +bool StoreUtil::Remove(const std::string &path) +{ + if (access(path.c_str(), F_OK) != 0) { + return true; + } + if (remove(path.c_str()) != 0) { + ZLOGE("remove error:%{public}d, path:%{public}s", errno, path.c_str()); + return false; + } + return true; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp b/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cde2a52d5be2f986b3cce847c1bcb65c9f750ebd --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "auto_sync_timer.h" +#include "store_manager.h" +using namespace testing::ext; +using namespace OHOS::DistributedKv; +class AutoSyncTimerTest : public testing::Test { +public: + class TestSyncCallback : public KvStoreSyncCallback { + public: + void SyncCompleted(const std::map &results) override + { + ASSERT_TRUE(true); + } + }; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +protected: + static std::shared_ptr kvStore_; +}; +std::shared_ptr AutoSyncTimerTest::kvStore_; +void AutoSyncTimerTest::SetUpTestCase(void) +{ + mkdir("/data/service/el1/public/database/ut_test", (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.securityLevel = S1; + options.area = EL1; + options.baseDir = "/data/service/el1/public/database/ut_test"; + AppId appId = { "ut_test" }; + StoreId storeId = { "ut_test_store" }; + Status status = StoreManager::GetInstance().Delete(appId, storeId, options.baseDir); + kvStore_ = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); + ASSERT_EQ(status, SUCCESS); +} + +void AutoSyncTimerTest::TearDownTestCase(void) +{ + remove("/data/service/el1/public/database/ut_test/key"); + remove("/data/service/el1/public/database/ut_test/kvdb"); + remove("/data/service/el1/public/database/ut_test"); +} + +void AutoSyncTimerTest::SetUp(void) +{ + +} + +void AutoSyncTimerTest::TearDown(void) +{ + +} + +/** +* @tc.name: GetStoreId +* @tc.desc: get the store id of the kv store +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(AutoSyncTimerTest, GetStoreId, TestSize.Level0) +{ + AutoSyncTimer::GetInstance().DoAutoSync("ut_test", {{"ut_test_store"}}); + sleep(3); + ASSERT_TRUE(true); +} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp index 59ccb3ff4d4721a6e7db83f14061b9e8265e6ab4..7dde6c23637bcb288554adc2e8b1deb1fbf62198 100644 --- a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp @@ -85,7 +85,7 @@ void SingleStoreImplTest::SetUp(void) StoreId storeId = { "LocalSingleKVStore" }; std::string path = ""; Status status = StoreManager::GetInstance().Delete(appId, storeId, path); - kvStore_ = StoreManager::GetInstance().GetKVStore(appId, storeId, options, path, status); + kvStore_ = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); ASSERT_EQ(status, SUCCESS); } diff --git a/interfaces/innerkits/distributeddata/include/store_errno.h b/interfaces/innerkits/distributeddata/include/store_errno.h index b91f2520d664f56ad9510201215e3e9f37e55834..4e3a271938807333307cb5958126f7fb8c2e7ab7 100644 --- a/interfaces/innerkits/distributeddata/include/store_errno.h +++ b/interfaces/innerkits/distributeddata/include/store_errno.h @@ -25,10 +25,12 @@ enum Status : int32_t { ILLEGAL_STATE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 2, SERVER_UNAVAILABLE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 3, STORE_NOT_OPEN = DISTRIBUTEDDATAMGR_ERR_OFFSET + 4, - STORE_NOT_FOUND = DISTRIBUTEDDATAMGR_ERR_OFFSET + 5, - STORE_ALREADY_SUBSCRIBE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 6, - STORE_NOT_SUBSCRIBE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 7, - KEY_NOT_FOUND = DISTRIBUTEDDATAMGR_ERR_OFFSET + 8, + STORE_ALREADY_SUBSCRIBE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 5, + STORE_NOT_SUBSCRIBE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 6, + NOT_FOUND = DISTRIBUTEDDATAMGR_ERR_OFFSET + 7, + STORE_NOT_FOUND = NOT_FOUND, + KEY_NOT_FOUND = STORE_NOT_FOUND, + DEVICE_NOT_FOUND = STORE_NOT_FOUND, DB_ERROR = DISTRIBUTEDDATAMGR_ERR_OFFSET + 9, NETWORK_ERROR = DISTRIBUTEDDATAMGR_ERR_OFFSET + 10, NO_DEVICE_CONNECTED = DISTRIBUTEDDATAMGR_ERR_OFFSET + 11, @@ -36,7 +38,6 @@ enum Status : int32_t { IPC_ERROR = DISTRIBUTEDDATAMGR_ERR_OFFSET + 13, CRYPT_ERROR = DISTRIBUTEDDATAMGR_ERR_OFFSET + 14, TIME_OUT = DISTRIBUTEDDATAMGR_ERR_OFFSET + 15, - DEVICE_NOT_FOUND = DISTRIBUTEDDATAMGR_ERR_OFFSET + 16, NOT_SUPPORT = DISTRIBUTEDDATAMGR_ERR_OFFSET + 17, SCHEMA_MISMATCH = DISTRIBUTEDDATAMGR_ERR_OFFSET + 18, INVALID_SCHEMA = DISTRIBUTEDDATAMGR_ERR_OFFSET + 19, @@ -50,7 +51,6 @@ enum Status : int32_t { SYSTEM_ACCOUNT_EVENT_PROCESSING = DISTRIBUTEDDATAMGR_ERR_OFFSET + 27, RECOVER_SUCCESS = DISTRIBUTEDDATAMGR_ERR_OFFSET + 28, RECOVER_FAILED = DISTRIBUTEDDATAMGR_ERR_OFFSET + 29, - MIGRATION_KVSTORE_FAILED = DISTRIBUTEDDATAMGR_ERR_OFFSET + 30, EXCEED_MAX_ACCESS_RATE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 31, SECURITY_LEVEL_ERROR = DISTRIBUTEDDATAMGR_ERR_OFFSET + 32, OVER_MAX_SUBSCRIBE_LIMITS = DISTRIBUTEDDATAMGR_ERR_OFFSET + 33, diff --git a/interfaces/innerkits/distributeddata/include/types.h b/interfaces/innerkits/distributeddata/include/types.h index da7608ebc6c00ad2c67319cdc5a0e4783cbd3a89..78cfc83b44c24cdd5f1f617620fc234e52218e31 100644 --- a/interfaces/innerkits/distributeddata/include/types.h +++ b/interfaces/innerkits/distributeddata/include/types.h @@ -253,6 +253,7 @@ struct Options { SyncPolicy syncPolicy = SyncPolicy::HIGH; KvStoreType kvStoreType = DEVICE_COLLABORATION; std::string schema = ""; + std::string hapName = ""; std::string baseDir = ""; inline bool IsValidType() const diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index 476eea88ecfc2b1c9d89975b18f46542b14e1f6b..81c0f86d37217152f4ffefc6a5cee13aee0e1c6e 100644 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -42,6 +42,7 @@ config("module_private_config") { "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/bootstrap/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/config/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/crypto/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/directory/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/app/src/session_manager", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", diff --git a/services/distributeddataservice/app/src/backup_handler.cpp b/services/distributeddataservice/app/src/backup_handler.cpp index ec96f24c44b190b990255f760010c9fb1745738c..d5df22eaa5ddd85fe44fca304352b1f64535f15a 100644 --- a/services/distributeddataservice/app/src/backup_handler.cpp +++ b/services/distributeddataservice/app/src/backup_handler.cpp @@ -12,14 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #define LOG_TAG "BackupHandler" - #include "backup_handler.h" + #include #include #include -#include + #include "account_delegate.h" #ifdef SUPPORT_POWER #include "battery_info.h" @@ -28,13 +27,12 @@ #endif #include "communication_provider.h" #include "constant.h" -#include "kv_store_delegate_manager.h" +#include "crypto_manager.h" #include "kv_scheduler.h" +#include "kv_store_delegate_manager.h" #include "kvstore_data_service.h" #include "log_print.h" #include "metadata/meta_data_manager.h" -#include "metadata/secret_key_meta_data.h" -#include "metadata/store_meta_data.h" #include "time_utils.h" #include "utils/crypto.h" @@ -185,7 +183,7 @@ bool BackupHandler::GetPassword(const StoreMetaData &metaData, DistributedDB::Ci SecretKeyMetaData secretKey; MetaDataManager::GetInstance().LoadMeta(key, secretKey, true); std::vector decryptKey; - KvStoreMetaManager::GetInstance().DecryptWorkKey(secretKey.sKey, decryptKey); + CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey); if (password.SetValue(decryptKey.data(), decryptKey.size()) != DistributedDB::CipherPassword::OK) { std::fill(decryptKey.begin(), decryptKey.end(), 0); ZLOGE("Set secret key value failed. len is (%d)", int32_t(decryptKey.size())); diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index 17cb37cb0adb99bd1aa6d10702377bc78665fdd2..8c62cc7a342b4543502e8fc57a901f42d3be7b51 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -174,7 +174,7 @@ private: bool CheckOptions(const Options &options, const std::vector &metaKey) const; std::set GetUsersByStore(const std::string &appId, const std::string &storeId); std::vector Intersect(const std::set &left, - const std::set &right); + const std::set &right); static Status FillStoreParam( const Options &options, const AppId &appId, const StoreId &storeId, StoreMetaData &metaData); diff --git a/services/distributeddataservice/app/test/BUILD.gn b/services/distributeddataservice/app/test/BUILD.gn index 2183eaa7988609e49594026af6f8293a36766c66..ee273c4b40e313f30104c085bd9b450ca10c1095 100644 --- a/services/distributeddataservice/app/test/BUILD.gn +++ b/services/distributeddataservice/app/test/BUILD.gn @@ -33,6 +33,7 @@ config("module_private_config") { "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/bootstrap/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/config/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/crypto/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/directory/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/app/src/session_manager", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/kvdb", diff --git a/services/distributeddataservice/framework/metadata/meta_data_manager.cpp b/services/distributeddataservice/framework/metadata/meta_data_manager.cpp index a11a5fec98d524f4347610f9d91c251864bca6d9..8a50f4c89be5e7829c7e296bd3ffc9a5bc2ee6e5 100644 --- a/services/distributeddataservice/framework/metadata/meta_data_manager.cpp +++ b/services/distributeddataservice/framework/metadata/meta_data_manager.cpp @@ -134,6 +134,9 @@ bool MetaDataManager::SaveMeta(const std::string &key, const Serializable &value if (!isLocal && syncer_) { syncer_(metaStore_, status); } + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("failed! status:%{public}d isLocal:%{public}d, key:%{public}s", status, isLocal, key.c_str()); + } return status == DistributedDB::DBStatus::OK; } diff --git a/services/distributeddataservice/service/crypto/src/crypto_manager.cpp b/services/distributeddataservice/service/crypto/src/crypto_manager.cpp index 97a0c758fc495b0ed8a27776e6bec99908157521..756bd8cf59af136e0bbc06bc25cd21efbff12a63 100644 --- a/services/distributeddataservice/service/crypto/src/crypto_manager.cpp +++ b/services/distributeddataservice/service/crypto/src/crypto_manager.cpp @@ -28,6 +28,7 @@ CryptoManager::CryptoManager() vecNonce_ = std::vector(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE)); vecAad_ = std::vector(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD)); } + CryptoManager::~CryptoManager() { } @@ -42,14 +43,14 @@ int32_t CryptoManager::GenerateRootKey() { ZLOGI("GenerateRootKey."); struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() }; - struct HksParamSet *param = nullptr; - int32_t ret = HksInitParamSet(¶m); + struct HksParamSet *params = nullptr; + int32_t ret = HksInitParamSet(¶ms); if (ret != HKS_SUCCESS) { ZLOGE("HksInitParamSet() failed with error %{public}d", ret); return ret; } - struct HksParam genKeyParams[] = { + struct HksParam hksParam[] = { { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES }, { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 }, { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT }, @@ -58,34 +59,69 @@ int32_t CryptoManager::GenerateRootKey() { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM }, }; - ret = HksAddParams(param, genKeyParams, sizeof(genKeyParams) / sizeof(genKeyParams[0])); + ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0])); if (ret != HKS_SUCCESS) { ZLOGE("HksAddParams failed with error %{public}d", ret); - HksFreeParamSet(¶m); + HksFreeParamSet(¶ms); return ret; } - ret = HksBuildParamSet(¶m); + ret = HksBuildParamSet(¶ms); if (ret != HKS_SUCCESS) { ZLOGE("HksBuildParamSet failed with error %{public}d", ret); - HksFreeParamSet(¶m); + HksFreeParamSet(¶ms); return ret; } - ret = HksGenerateKey(&rootKeyName, param, nullptr); + ret = HksGenerateKey(&rootKeyName, params, nullptr); + HksFreeParamSet(¶ms); if (ret != HKS_SUCCESS) { ZLOGE("HksGenerateKey failed with error %{public}d", ret); - HksFreeParamSet(¶m); - return ret; } - HksFreeParamSet(¶m); ZLOGI("GenerateRootKey Succeed."); - return HKS_SUCCESS; + return ret; } bool CryptoManager::IsExistRootKey() { - return false; + ZLOGI("GenerateRootKey."); + struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() }; + struct HksParamSet *params = nullptr; + int32_t ret = HksInitParamSet(¶ms); + if (ret != HKS_SUCCESS) { + ZLOGE("HksInitParamSet() failed with error %{public}d", ret); + return ret; + } + + struct HksParam hksParam[] = { + { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES }, + { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 }, + { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT }, + { .tag = HKS_TAG_DIGEST, .uint32Param = 0 }, + { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE }, + { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM }, + }; + + ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0])); + if (ret != HKS_SUCCESS) { + ZLOGE("HksAddParams failed with error %{public}d", ret); + HksFreeParamSet(¶ms); + return ret; + } + + ret = HksBuildParamSet(¶ms); + if (ret != HKS_SUCCESS) { + ZLOGE("HksBuildParamSet failed with error %{public}d", ret); + HksFreeParamSet(¶ms); + return ret; + } + + ret = HksKeyExist(&rootKeyName, params); + HksFreeParamSet(¶ms); + if (ret != HKS_SUCCESS) { + ZLOGE("HksEncrypt failed with error %{public}d", ret); + } + return ret == HKS_SUCCESS; } std::vector CryptoManager::Encrypt(const std::vector &key) @@ -100,7 +136,7 @@ std::vector CryptoManager::Encrypt(const std::vector &key) ZLOGE("HksInitParamSet() failed with error %{public}d", ret); return {}; } - struct HksParam param[] = { + struct HksParam hksParam[] = { { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES }, { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT }, { .tag = HKS_TAG_DIGEST, .uint32Param = 0 }, @@ -109,7 +145,7 @@ std::vector CryptoManager::Encrypt(const std::vector &key) { .tag = HKS_TAG_NONCE, .blob = blobNonce }, { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad }, }; - ret = HksAddParams(params, param, sizeof(param) / sizeof(param[0])); + ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0])); if (ret != HKS_SUCCESS) { ZLOGE("HksAddParams failed with error %{public}d", ret); HksFreeParamSet(¶ms); @@ -126,12 +162,12 @@ std::vector CryptoManager::Encrypt(const std::vector &key) uint8_t cipherBuf[256] = { 0 }; struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf }; ret = HksEncrypt(&rootKeyName, params, &plainKey, &cipherText); + (void)HksFreeParamSet(¶ms); if (ret != HKS_SUCCESS) { ZLOGE("HksEncrypt failed with error %{public}d", ret); - HksFreeParamSet(¶ms); return {}; } - (void)HksFreeParamSet(¶ms); + std::vector encryptedKey(cipherText.data, cipherText.data + cipherText.size); (void)memset_s(cipherBuf, sizeof(cipherBuf), 0, sizeof(cipherBuf)); return encryptedKey; @@ -150,7 +186,7 @@ bool CryptoManager::Decrypt(std::vector &source, std::vector & ZLOGE("HksInitParamSet() failed with error %{public}d", ret); return false; } - struct HksParam param[] = { + struct HksParam hksParam[] = { { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES }, { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT }, { .tag = HKS_TAG_DIGEST, .uint32Param = 0 }, @@ -159,7 +195,7 @@ bool CryptoManager::Decrypt(std::vector &source, std::vector & { .tag = HKS_TAG_NONCE, .blob = blobNonce }, { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad }, }; - ret = HksAddParams(params, param, sizeof(param) / sizeof(param[0])); + ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0])); if (ret != HKS_SUCCESS) { ZLOGE("HksAddParams failed with error %{public}d", ret); HksFreeParamSet(¶ms); @@ -172,15 +208,15 @@ bool CryptoManager::Decrypt(std::vector &source, std::vector & HksFreeParamSet(¶ms); return false; } + uint8_t plainBuf[256] = { 0 }; struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf }; ret = HksDecrypt(&rootKeyName, params, &encryptedKeyBlob, &plainKeyBlob); + (void)HksFreeParamSet(¶ms); if (ret != HKS_SUCCESS) { - ZLOGW("HksDecrypt failed with error %{public}d", ret); - HksFreeParamSet(¶ms); + ZLOGE("HksDecrypt failed with error %{public}d", ret); return false; } - (void)HksFreeParamSet(¶ms); key.assign(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size); (void)memset_s(plainBuf, sizeof(plainBuf), 0, sizeof(plainBuf)); diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 99fe2b923bfad8c199e0a3f2863a2c9f98bd8b67..4267dad0a4dbbc18f28a7b0306cb81cb87fd2621 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -16,6 +16,7 @@ #include "kvdb_service_impl.h" #include +#include #include "accesstoken_kit.h" #include "account/account_delegate.h" @@ -27,8 +28,11 @@ #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" +#include "query_helper.h" +#include "utils/anonymous.h" #include "utils/constant.h" #include "utils/converter.h" + namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; using namespace OHOS::AppDistributedKv; @@ -90,9 +94,9 @@ Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, const S StoreMetaData metaData = GetStoreMetaData(appId, storeId); MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); auto delay = GetSyncDelayTime(syncInfo.delay, storeId); - return KvStoreSyncManager::GetInstance()->AddSyncOperation(reinterpret_cast(this), delay, - std::bind(&KVDBServiceImpl::DoSync, this, metaData, syncInfo, std::placeholders::_1), - std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, std::placeholders::_1)); + return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, + std::bind(&KVDBServiceImpl::DoSync, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), + std::bind(&KVDBServiceImpl::DoComplete, this, metaData.tokenId, syncInfo.seqId, std::placeholders::_1)); } Status KVDBServiceImpl::RegisterSyncCallback(const AppId &appId, sptr callback) @@ -199,34 +203,24 @@ Status KVDBServiceImpl::SetCapability(const AppId &appId, const StoreId &storeId return SUCCESS; } -Status KVDBServiceImpl::AddSubscribeInfo(const AppId &appId, const StoreId &storeId, - const std::vector &devices, const std::string &query) +Status KVDBServiceImpl::AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) { - auto tokenId = IPCSkeleton::GetCallingTokenID(); - syncAgents_.Compute(tokenId, [&appId, &storeId, &devices, &query](auto &key, SyncAgent &value) { - if (value.pid_ != IPCSkeleton::GetCallingPid()) { - value.ReInit(IPCSkeleton::GetCallingPid(), appId); - } - value.conditions_[storeId] = { devices, query }; - return true; - }); - return SUCCESS; + StoreMetaData metaData = GetStoreMetaData(appId, storeId); + MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); + auto delay = GetSyncDelayTime(syncInfo.delay, storeId); + return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, + std::bind(&KVDBServiceImpl::DoSync, this, metaData, syncInfo, std::placeholders::_1, ACTION_SUBSCRIBE), + std::bind(&KVDBServiceImpl::DoComplete, this, metaData.tokenId, syncInfo.seqId, std::placeholders::_1)); } -Status KVDBServiceImpl::RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, - const std::vector &devices, const std::string &query) +Status KVDBServiceImpl::RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) { - auto tokenId = IPCSkeleton::GetCallingTokenID(); - syncAgents_.Compute(tokenId, [&appId, &storeId](auto &key, SyncAgent &value) { - if (value.pid_ != IPCSkeleton::GetCallingPid()) { - ZLOGW("agent already changed! old pid:%{public}d, new pid:%{public}d, appId:%{public}s", - IPCSkeleton::GetCallingPid(), value.pid_, appId.appId.c_str()); - return true; - } - value.conditions_.erase(storeId); - return true; - }); - return SUCCESS; + StoreMetaData metaData = GetStoreMetaData(appId, storeId); + MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); + auto delay = GetSyncDelayTime(syncInfo.delay, storeId); + return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, + std::bind(&KVDBServiceImpl::DoSync, this, metaData, syncInfo, std::placeholders::_1, ACTION_UNSUBSCRIBE), + std::bind(&KVDBServiceImpl::DoComplete, this, metaData.tokenId, syncInfo.seqId, std::placeholders::_1)); } Status KVDBServiceImpl::Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) @@ -274,21 +268,21 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, const std::vector &password) { if (!appId.IsValid() || !storeId.IsValid() || !options.IsValidType()) { - ZLOGE("failed, please type:%{public}d, appId:%{public}s, storeId:%{public}s", options.kvStoreType, + ZLOGE("failed, please check type:%{public}d, appId:%{public}s, storeId:%{public}s", options.kvStoreType, appId.appId.c_str(), storeId.storeId.c_str()); return INVALID_ARGUMENT; } StoreMetaData metaData = GetStoreMetaData(appId, storeId); AddOptions(options, metaData); StoreMetaData oldMeta; - MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), oldMeta); - if (oldMeta != metaData) { + auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), oldMeta); + if (isCreated && oldMeta != metaData) { // implement update - ZLOGI("update meta data appId:%{public}s, storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(), - storeId.storeId.c_str(), metaData.instanceId); - MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData); + ZLOGI("update appId:%{public}s, storeId:%{public}s instanceId:%{public}d type:%{public}d->%{public}d " + "dir:%{public}s", appId.appId.c_str(), storeId.storeId.c_str(), metaData.instanceId, + oldMeta.storeType, metaData.storeType, metaData.dataDir.c_str()); } - + MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData); if (metaData.isEncrypt) { SecretKeyMetaData secretKey; secretKey.storeType = metaData.storeType; @@ -298,6 +292,9 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, auto storeKey = SecretKeyMetaData::GetKey({ metaData.user, "default", metaData.bundleName, metaData.storeId }); MetaDataManager::GetInstance().SaveMeta(storeKey, secretKey, true); } + ZLOGD("appId:%{public}s, storeId:%{public}s instanceId:%{public}d type:%{public}d dir:%{public}s", + appId.appId.c_str(), storeId.storeId.c_str(), metaData.instanceId, metaData.storeType, + metaData.dataDir.c_str()); return SUCCESS; } @@ -344,27 +341,30 @@ Status KVDBServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunc void KVDBServiceImpl::AddOptions(const Options &options, StoreMetaData &metaData) { - metaData.securityLevel = options.securityLevel; - metaData.storeType = options.kvStoreType; + metaData.isAutoSync = options.autoSync; metaData.isBackup = options.backup; metaData.isEncrypt = options.encrypt; - metaData.isAutoSync = options.autoSync; + metaData.storeType = options.kvStoreType; + metaData.securityLevel = options.securityLevel; + metaData.area = options.area; metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData)); - metaData.user = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(metaData.uid); - metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId(); + metaData.appType = "harmony"; + metaData.hapName = options.hapName; metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData); + metaData.schema = options.schema; + metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId(); } StoreMetaData KVDBServiceImpl::GetStoreMetaData(const AppId &appId, const StoreId &storeId) { StoreMetaData metaData; - metaData.deviceId = Commu::GetInstance().GetLocalDevice().uuid; metaData.uid = IPCSkeleton::GetCallingUid(); metaData.tokenId = IPCSkeleton::GetCallingTokenID(); + metaData.instanceId = GetInstIndex(metaData.tokenId, appId); metaData.bundleName = appId.appId; + metaData.deviceId = Commu::GetInstance().GetLocalDevice().uuid; metaData.storeId = storeId.storeId; metaData.user = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(metaData.uid); - metaData.instanceId = GetInstIndex(metaData.tokenId, appId); return metaData; } @@ -395,9 +395,10 @@ int32_t KVDBServiceImpl::GetInstIndex(uint32_t tokenId, const AppId &appId) return tokenInfo.instIndex; } -Status KVDBServiceImpl::DoSync(const StoreMetaData &metaData, const SyncInfo &syncInfo, const SyncEnd &complete) +Status KVDBServiceImpl::DoSync(StoreMetaData metaData, SyncInfo syncInfo, const SyncEnd &complete, int32_t type) { - ZLOGD("start."); + ZLOGD("seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s", syncInfo.seqId, + syncInfo.devices.size(), metaData.bundleName.c_str(), metaData.storeId.c_str()); std::vector uuids; if (syncInfo.devices.empty()) { auto remotes = Commu::GetInstance().GetRemoteDevices(); @@ -412,25 +413,50 @@ Status KVDBServiceImpl::DoSync(const StoreMetaData &metaData, const SyncInfo &sy } } if (uuids.empty()) { - ZLOGE("not found deviceIds."); + ZLOGW("no device online seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s", + syncInfo.seqId, syncInfo.devices.size(), metaData.bundleName.c_str(), metaData.storeId.c_str()); return Status::ERROR; } + DistributedDB::DBStatus status; auto store = storeCache_.GetStore(metaData, nullptr, status); if (store == nullptr) { + ZLOGE("failed! status:%{public}d appId:%{public}s storeId:%{public}s dir:%{public}s", status, + metaData.bundleName.c_str(), metaData.storeId.c_str(), metaData.dataDir.c_str()); return ConvertDbStatus(status); } - status = store->Sync(uuids, static_cast(syncInfo.mode), complete); + bool isSuccess = false; + auto dbQuery = QueryHelper::StringToDbQuery(syncInfo.query, isSuccess); + if (!isSuccess && !syncInfo.query.empty()) { + ZLOGE("failed DBQuery:%{public}s", Anonymous::Change(syncInfo.query).c_str()); + return Status::INVALID_ARGUMENT; + } + + switch (type) { + case ACTION_SYNC: + status = store->Sync(uuids, ConvertDBMode(SyncMode(syncInfo.mode)), complete, dbQuery, false); + break; + case ACTION_SUBSCRIBE: + status = store->SubscribeRemoteQuery(uuids, complete, dbQuery, false); + break; + case ACTION_UNSUBSCRIBE: + status = store->UnSubscribeRemoteQuery(uuids, complete, dbQuery, false); + break; + default: + status = DBStatus::INVALID_ARGS; + break; + } return ConvertDbStatus(status); } -Status KVDBServiceImpl::DoComplete(const StoreMetaData &metaData, const SyncInfo &syncInfo, const DBResult &dbResult) +Status KVDBServiceImpl::DoComplete(uint32_t tokenId, uint64_t seqId, const DBResult &dbResult) { - if (syncInfo.seqId == std::numeric_limits::max()) { + ZLOGD("seqId:0x%{public}" PRIx64 " remote:%{public}zu", seqId, dbResult.size()); + if (seqId == std::numeric_limits::max()) { return SUCCESS; } sptr callback; - syncAgents_.ComputeIfPresent(metaData.tokenId, [&callback](auto &key, SyncAgent &agent) { + syncAgents_.ComputeIfPresent(tokenId, [&callback](auto &key, SyncAgent &agent) { callback = agent.callback_; return true; }); @@ -442,7 +468,7 @@ Status KVDBServiceImpl::DoComplete(const StoreMetaData &metaData, const SyncInfo for (auto &[key, status] : dbResult) { result[key] = ConvertDbStatus(status); } - callback->SyncCompleted(result, syncInfo.seqId); + callback->SyncCompleted(result, seqId); return SUCCESS; } @@ -453,7 +479,7 @@ uint32_t KVDBServiceImpl::GetSyncDelayTime(uint32_t delay, const StoreId &storeI } bool isBackground = Constant::IsBackground(IPCSkeleton::GetCallingPid()); - if (isBackground) { + if (!isBackground) { return delay; } delay = KvStoreSyncManager::SYNC_DEFAULT_DELAY_MS; @@ -467,7 +493,7 @@ uint32_t KVDBServiceImpl::GetSyncDelayTime(uint32_t delay, const StoreId &storeI return delay; } -Status KVDBServiceImpl::ConvertDbStatus(DBStatus status) +Status KVDBServiceImpl::ConvertDbStatus(DBStatus status) const { switch (status) { case DBStatus::BUSY: // fallthrough @@ -506,6 +532,19 @@ Status KVDBServiceImpl::ConvertDbStatus(DBStatus status) return Status::ERROR; } +KVDBServiceImpl::DBMode KVDBServiceImpl::ConvertDBMode(SyncMode syncMode) const +{ + DBMode dbMode; + if (syncMode == SyncMode::PUSH) { + dbMode = DBMode::SYNC_MODE_PUSH_ONLY; + } else if (syncMode == SyncMode::PULL) { + dbMode = DBMode::SYNC_MODE_PULL_ONLY; + } else { + dbMode = DBMode::SYNC_MODE_PUSH_PULL; + } + return dbMode; +} + void KVDBServiceImpl::SyncAgent::ReInit(pid_t pid, const AppId &appId) { ZLOGW("now pid:%{public}d, pid:%{public}d, appId:%{public}s, callback:%{public}d, observer:%{public}zu", pid, pid_, diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index 430c800e8c27e2a8f1223c7e446b5981e3f90b1d..2a9c7aabaab81fba04a7df13ea57dd1a94488e1f 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -45,10 +45,8 @@ public: Status DisableCapability(const AppId &appId, const StoreId &storeId) override; Status SetCapability(const AppId &appId, const StoreId &storeId, const std::vector &local, const std::vector &remote) override; - Status AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const std::vector &devices, - const std::string &query) override; - Status RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const std::vector &devices, - const std::string &query) override; + Status AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; + Status RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status AppExit(pid_t uid, pid_t pid, uint32_t tokenId, const AppId &appId); @@ -62,14 +60,21 @@ private: using SyncEnd = KvStoreSyncManager::SyncEnd; using DBResult = std::map; using DBStatus = DistributedDB::DBStatus; + using DBMode = DistributedDB::SyncMode; + enum SyncAction { + ACTION_SYNC, + ACTION_SUBSCRIBE, + ACTION_UNSUBSCRIBE, + }; void AddOptions(const Options &options, StoreMetaData &metaData); StoreMetaData GetStoreMetaData(const AppId &appId, const StoreId &storeId); StrategyMeta GetStrategyMeta(const AppId &appId, const StoreId &storeId); int32_t GetInstIndex(uint32_t tokenId, const AppId &appId); - Status DoSync(const StoreMetaData &metaData, const SyncInfo &syncInfo, const SyncEnd &complete); - Status DoComplete(const StoreMetaData &metaData, const SyncInfo &syncInfo, const DBResult &dbResult); + Status DoSync(StoreMetaData metaData, SyncInfo syncInfo, const SyncEnd &complete, int32_t type); + Status DoComplete(uint32_t tokenId, uint64_t seqId, const DBResult &dbResult); uint32_t GetSyncDelayTime(uint32_t delay, const StoreId &storeId); - Status ConvertDbStatus(DBStatus status); + Status ConvertDbStatus(DBStatus status) const; + DBMode ConvertDBMode(SyncMode syncMode) const; struct SyncAgent { pid_t pid_ = 0; diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index afe89fafb54c9ab69e1081b6112072e0ef07e29b..1f3a73cc93bb75f0e9e9de9a1dfe67dc1fbfe39f 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -51,9 +51,10 @@ int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Message return -1; } - if (TRANS_HEAD > code || code >= TRANS_BUTT || HANDLERS[code] != nullptr) { + if (TRANS_HEAD > code || code >= TRANS_BUTT || HANDLERS[code] == nullptr) { return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } + AppId appId; StoreId storeId; if (!ITypesUtil::Unmarshal(data, appId, storeId)) { @@ -259,16 +260,15 @@ int32_t KVDBServiceStub::OnSetCapability( return ERR_NONE; } -int32_t KVDBServiceStub::OnAddSubInfo( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) +int32_t KVDBServiceStub::OnAddSubInfo(const AppId &appId, const StoreId &storeId, MessageParcel &data, + MessageParcel &reply) { - std::vector devices; - std::string query; - if (!ITypesUtil::Unmarshal(data, devices, query)) { + SyncInfo syncInfo; + if (!ITypesUtil::Unmarshal(data, syncInfo.seqId, syncInfo.devices, syncInfo.query)) { ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); return IPC_STUB_INVALID_DATA_ERR; } - int32_t status = AddSubscribeInfo(appId, storeId, devices, query); + int32_t status = AddSubscribeInfo(appId, storeId, syncInfo); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), storeId.storeId.c_str()); @@ -277,16 +277,15 @@ int32_t KVDBServiceStub::OnAddSubInfo( return ERR_NONE; } -int32_t KVDBServiceStub::OnRmvSubInfo( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) +int32_t KVDBServiceStub::OnRmvSubInfo(const AppId &appId, const StoreId &storeId, MessageParcel &data, + MessageParcel &reply) { - std::vector devices; - std::string query; - if (!ITypesUtil::Unmarshal(data, devices, query)) { + SyncInfo syncInfo; + if (!ITypesUtil::Unmarshal(data, syncInfo.seqId, syncInfo.devices, syncInfo.query)) { ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); return IPC_STUB_INVALID_DATA_ERR; } - int32_t status = RmvSubscribeInfo(appId, storeId, devices, query); + int32_t status = RmvSubscribeInfo(appId, storeId, syncInfo); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), storeId.storeId.c_str());