• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "kv_general_ut.h"
17 #include "kv_store_errno.h"
18 #include "storage_engine_manager.h"
19 #include "virtual_cloud_db.h"
20 
21 namespace DistributedDB {
SetUp()22 void KVGeneralUt::SetUp()
23 {
24     virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
25     CloseAllDelegate();
26     BasicUnitTest::SetUp();
27 }
28 
TearDown()29 void KVGeneralUt::TearDown()
30 {
31     CloseAllDelegate();
32     virtualCloudDb_ = nullptr;
33     BasicUnitTest::TearDown();
34 }
35 
InitDelegate(const StoreInfo & info)36 int KVGeneralUt::InitDelegate(const StoreInfo &info)
37 {
38     KvStoreDelegateManager manager(info.appId, info.userId);
39     manager.SetKvStoreConfig(GetKvStoreConfig());
40     KvStoreNbDelegate::Option option;
41     std::lock_guard<std::mutex> autoLock(storeMutex_);
42     if (option_.has_value()) {
43         option = option_.value();
44     }
45     KvStoreNbDelegate *store = nullptr;
46     DBStatus status = DBStatus::OK;
47     manager.GetKvStore(info.storeId, option, [&status, &store](DBStatus ret, KvStoreNbDelegate *delegate) {
48         status = ret;
49         store = delegate;
50     });
51     if (status != DBStatus::OK) {
52         LOGE("[KVGeneralUt] Init delegate failed %d", static_cast<int>(status));
53         return -E_INTERNAL_ERROR;
54     }
55     if (processCommunicator_ != nullptr) {
56         manager.SetProcessCommunicator(processCommunicator_);
57     }
58     stores_[info] = store;
59     LOGI("[KVGeneralUt] Init delegate app %s store %s user %s success", info.appId.c_str(),
60          info.storeId.c_str(), info.userId.c_str());
61     return E_OK;
62 }
63 
CloseDelegate(const StoreInfo & info)64 int KVGeneralUt::CloseDelegate(const StoreInfo &info)
65 {
66     std::lock_guard<std::mutex> autoLock(storeMutex_);
67     auto iter = stores_.find(info);
68     if (iter == stores_.end()) {
69         LOGW("[KVGeneralUt] Close not exist delegate app %s store %s user %s", info.appId.c_str(),
70             info.storeId.c_str(), info.userId.c_str());
71         return E_OK;
72     }
73     KvStoreDelegateManager manager(info.appId, info.userId);
74     manager.SetKvStoreConfig(GetKvStoreConfig());
75     auto ret = manager.CloseKvStore(iter->second);
76     if (ret != DBStatus::OK) {
77         LOGI("[KVGeneralUt] Close delegate app %s store %s user %s failed %d", info.appId.c_str(),
78              info.storeId.c_str(), info.userId.c_str(), static_cast<int>(ret));
79         return -E_INTERNAL_ERROR;
80     }
81     LOGI("[KVGeneralUt] Close delegate app %s store %s user %s success", info.appId.c_str(),
82          info.storeId.c_str(), info.userId.c_str());
83     stores_.erase(iter);
84     return E_OK;
85 }
86 
CloseAllDelegate()87 void KVGeneralUt::CloseAllDelegate()
88 {
89     std::vector<StoreInfo> infoList;
90     {
91         std::lock_guard<std::mutex> autoLock(storeMutex_);
92         for (const auto &item : stores_) {
93             infoList.push_back(item.first);
94         }
95     }
96     for (const auto &info : infoList) {
97         (void)CloseDelegate(info);
98     }
99 }
100 
SetOption(const KvStoreNbDelegate::Option & option)101 void KVGeneralUt::SetOption(const KvStoreNbDelegate::Option &option)
102 {
103     std::lock_guard<std::mutex> autoLock(storeMutex_);
104     option_ = option;
105 }
106 
GetKvStoreConfig()107 KvStoreConfig KVGeneralUt::GetKvStoreConfig()
108 {
109     KvStoreConfig config;
110     config.dataDir = GetTestDir();
111     return config;
112 }
113 
GetDelegate(const DistributedDB::StoreInfo & info) const114 KvStoreNbDelegate *KVGeneralUt::GetDelegate(const DistributedDB::StoreInfo &info) const
115 {
116     std::lock_guard<std::mutex> autoLock(storeMutex_);
117     auto iter = stores_.find(info);
118     if (iter == stores_.end()) {
119         LOGW("[KVGeneralUt] Not exist delegate app %s store %s user %s", info.appId.c_str(),
120             info.storeId.c_str(), info.userId.c_str());
121         return nullptr;
122     }
123     return iter->second;
124 }
125 
BlockPush(const StoreInfo & from,const StoreInfo & to,DBStatus expectRet)126 void KVGeneralUt::BlockPush(const StoreInfo &from, const StoreInfo &to, DBStatus expectRet)
127 {
128     auto fromStore = GetDelegate(from);
129     ASSERT_NE(fromStore, nullptr);
130     auto toDevice  = GetDevice(to);
131     ASSERT_FALSE(toDevice.empty());
132     std::map<std::string, DBStatus> syncRet;
133     tool_.SyncTest(fromStore, {toDevice}, SyncMode::SYNC_MODE_PUSH_ONLY, syncRet);
134     for (const auto &item : syncRet) {
135         EXPECT_EQ(item.second, expectRet);
136     }
137 }
138 
GetDataBaseSchema(bool invalidSchema)139 DataBaseSchema KVGeneralUt::GetDataBaseSchema(bool invalidSchema)
140 {
141     DataBaseSchema schema;
142     TableSchema tableSchema;
143     tableSchema.name = invalidSchema ? "invalid_schema_name" : CloudDbConstant::CLOUD_KV_TABLE_NAME;
144     Field field;
145     field.colName = CloudDbConstant::CLOUD_KV_FIELD_KEY;
146     field.type = TYPE_INDEX<std::string>;
147     field.primary = true;
148     tableSchema.fields.push_back(field);
149     field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE;
150     field.primary = false;
151     tableSchema.fields.push_back(field);
152     field.colName = CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE;
153     tableSchema.fields.push_back(field);
154     field.colName = CloudDbConstant::CLOUD_KV_FIELD_VALUE;
155     tableSchema.fields.push_back(field);
156     field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME;
157     field.type = TYPE_INDEX<int64_t>;
158     tableSchema.fields.push_back(field);
159     schema.tables.push_back(tableSchema);
160     return schema;
161 }
162 
SetCloud(KvStoreNbDelegate * & delegate,bool invalidSchema)163 DBStatus KVGeneralUt::SetCloud(KvStoreNbDelegate *&delegate, bool invalidSchema)
164 {
165     std::lock_guard<std::mutex> autoLock(storeMutex_);
166     std::map<std::string, std::shared_ptr<ICloudDb>> cloudDbs;
167     cloudDbs[DistributedDBUnitTest::USER_ID] = virtualCloudDb_;
168     delegate->SetCloudDB(cloudDbs);
169     std::map<std::string, DataBaseSchema> schemas;
170     schemas[DistributedDBUnitTest::USER_ID] = GetDataBaseSchema(invalidSchema);
171     return delegate->SetCloudDbSchema(schemas);
172 }
173 
GetDeviceEntries(KvStoreNbDelegate * delegate,const std::string & deviceId,bool isSelfDevice,std::vector<Entry> & entries)174 DBStatus KVGeneralUt::GetDeviceEntries(KvStoreNbDelegate *delegate, const std::string &deviceId, bool isSelfDevice,
175     std::vector<Entry> &entries)
176 {
177     if (isSelfDevice) {
178         communicatorAggregator_->SetLocalDeviceId(deviceId);
179     } else {
180         communicatorAggregator_->SetLocalDeviceId(deviceId + "_");
181     }
182     return delegate->GetDeviceEntries(deviceId, entries);
183 }
184 
BlockCloudSync(const StoreInfo & from,const std::string & deviceId,DBStatus expectRet)185 void KVGeneralUt::BlockCloudSync(const StoreInfo &from, const std::string &deviceId, DBStatus expectRet)
186 {
187     auto fromStore = GetDelegate(from);
188     ASSERT_NE(fromStore, nullptr);
189 
190     communicatorAggregator_->SetLocalDeviceId(deviceId);
191     CloudSyncOption syncOption;
192     syncOption.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
193     syncOption.users.push_back(DistributedDBUnitTest::USER_ID);
194     syncOption.devices.push_back("cloud");
195     tool_.BlockSync(fromStore, DBStatus::OK, syncOption, expectRet);
196 }
197 
GetRemoteSoftwareVersion(const StoreInfo & info,const std::string & dev,const std::string & user)198 std::pair<DBStatus, uint64_t> KVGeneralUt::GetRemoteSoftwareVersion(const StoreInfo &info, const std::string &dev,
199     const std::string &user)
200 {
201     uint64_t version = 0;
202     int errCode = QueryMetaValue(info, dev, user,
203         [&version](const std::shared_ptr<Metadata> &metadata, const std::string &device,
204         const std::string &userId) {
205         version = metadata->GetRemoteSoftwareVersion(device, userId);
206         return E_OK;
207     });
208     return {TransferDBErrno(errCode), version};
209 }
210 
GetRemoteSchemaVersion(const StoreInfo & info,const std::string & dev,const std::string & user)211 std::pair<DBStatus, uint64_t> KVGeneralUt::GetRemoteSchemaVersion(const StoreInfo &info, const std::string &dev,
212     const std::string &user)
213 {
214     uint64_t version = 0;
215     int errCode = QueryMetaValue(info, dev, user,
216         [&version](const std::shared_ptr<Metadata> &metadata, const std::string &device,
217         const std::string &userId) {
218         version = metadata->GetRemoteSchemaVersion(device, userId);
219         return E_OK;
220     });
221     return {TransferDBErrno(errCode), version};
222 }
223 
SetRemoteSoftwareVersion(const StoreInfo & info,const std::string & dev,const std::string & user,uint64_t version)224 DBStatus KVGeneralUt::SetRemoteSoftwareVersion(const StoreInfo &info, const std::string &dev, const std::string &user,
225     uint64_t version)
226 {
227     int errCode = QueryMetaValue(info, dev, user,
228         [version](const std::shared_ptr<Metadata> &metadata, const std::string &device,
229         const std::string &userId) {
230         return metadata->SetRemoteSoftwareVersion(device, userId, version);
231     });
232     return TransferDBErrno(errCode);
233 }
234 
GetLocalSchemaVersion(const DistributedDB::StoreInfo & info)235 std::pair<DBStatus, uint64_t> KVGeneralUt::GetLocalSchemaVersion(const DistributedDB::StoreInfo &info)
236 {
237     uint64_t version = 0;
238     int errCode = QueryMetaValue(info, "", "",
239         [&version](const std::shared_ptr<Metadata> &metadata, const std::string &device,
240         const std::string &userId) {
241         auto [ret, schemaVersion] = metadata->GetLocalSchemaVersion();
242         version = schemaVersion;
243         return ret;
244     });
245     return {TransferDBErrno(errCode), version};
246 }
247 
QueryMetaValue(const StoreInfo & info,const std::string & dev,const std::string & user,const std::function<int (const std::shared_ptr<Metadata> &,const std::string &,const std::string &)> & queryFunc)248 int KVGeneralUt::QueryMetaValue(const StoreInfo &info, const std::string &dev, const std::string &user,
249     const std::function<int(const std::shared_ptr<Metadata> &, const std::string &, const std::string &)> &queryFunc)
250 {
251     int errCode = E_OK;
252     auto properties = GetDBProperties(info);
253     auto store = new(std::nothrow) SQLiteSingleVerNaturalStore;
254     if (store == nullptr) {
255         errCode = -E_INVALID_ARGS;
256         LOGI("[KVGeneralUt] create natural store failed with oom");
257         return errCode;
258     }
259     errCode = store->Open(properties);
260     if (errCode != E_OK) {
261         RefObject::KillAndDecObjRef(store);
262         return errCode;
263     }
264     auto meta = std::make_shared<Metadata>();
265     errCode = meta->Initialize(store);
266     if (errCode != E_OK) {
267         store->Close();
268         RefObject::KillAndDecObjRef(store);
269         return errCode;
270     }
271     if (queryFunc) {
272         errCode = queryFunc(meta, dev, user);
273     }
274     meta = nullptr;
275     store->Close();
276     RefObject::KillAndDecObjRef(store);
277     return errCode;
278 }
279 
GetDBProperties(const StoreInfo & info)280 KvDBProperties KVGeneralUt::GetDBProperties(const StoreInfo &info)
281 {
282     KvDBProperties properties;
283     properties.SetStringProp(KvDBProperties::DATA_DIR, GetTestDir());
284     properties.SetStringProp(KvDBProperties::STORE_ID, info.storeId);
285     KvStoreNbDelegate::Option option;
286     std::lock_guard<std::mutex> autoLock(storeMutex_);
287     if (option_.has_value()) {
288         option = option_.value();
289     }
290     auto idDir = DBCommon::TransferStringToHex(DBCommon::GetStoreIdentifier(info, "", option.syncDualTupleMode, false));
291     properties.SetStringProp(KvDBProperties::IDENTIFIER_DIR, idDir);
292     properties.SetStringProp(KvDBProperties::IDENTIFIER_DATA, idDir + "KVGeneralUt");
293     properties.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE);
294     return properties;
295 }
296 }