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 #define LOG_TAG "CloudDataMockTest"
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 #include "cloud/cloud_server.h"
21 #include "cloud_service_impl.h"
22 #include "communicator/device_manager_adapter.h"
23 #include "device_matrix.h"
24 #include "eventcenter/event_center.h"
25 #include "ipc_skeleton.h"
26 #include "log_print.h"
27 #include "metadata/meta_data_manager.h"
28 #include "mock/access_token_mock.h"
29 #include "mock/account_delegate_mock.h"
30 #include "mock/db_store_mock.h"
31 #include "network_delegate_mock.h"
32
33 using namespace testing::ext;
34 using namespace testing;
35 using namespace DistributedDB;
36 using namespace OHOS::DistributedData;
37 using namespace OHOS::Security::AccessToken;
38 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
39
40 namespace OHOS::Test {
41 namespace DistributedDataTest {
42 static constexpr const char *TEST_CLOUD_BUNDLE = "test_cloud_bundleName";
43 static constexpr const char *TEST_CLOUD_APPID = "test_cloud_appid";
44 static constexpr const char *TEST_CLOUD_STORE = "test_cloud_store";
45 static constexpr const char *TEST_CLOUD_ID = "test_cloud_id";
46 static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_1 = "test_cloud_database_alias_1";
47 static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_2 = "test_cloud_database_alias_2";
48 static constexpr const char *TEST_CLOUD_PATH = "/data/app/el2/100/database/test_cloud_bundleName/entry/rdb/"
49 "test_cloud_store";
50 static constexpr const int32_t TEST_TOKEN_FLAG_CALL_COUNT = 3;
51 class CloudDataMockTest : public testing::Test {
52 public:
53 static void SetUpTestCase(void);
54 static void TearDownTestCase(void);
55 void SetUp();
56 void TearDown();
57
58 static inline std::shared_ptr<AccessTokenKitMock> accTokenMock = nullptr;
59 static SchemaMeta schemaMeta_;
60 static std::shared_ptr<CloudData::CloudServiceImpl> cloudServiceImpl_;
61
62 protected:
63 static void InitMetaData();
64 static void InitSchemaMeta();
65 static void InitCloudInfo();
66 static std::shared_ptr<DBStoreMock> dbStoreMock_;
67 static StoreMetaData metaData_;
68 static CloudInfo cloudInfo_;
69 static NetworkDelegateMock delegate_;
70 static inline AccountDelegateMock *accountDelegateMock = nullptr;
71 };
72
73 class CloudServerMock : public CloudServer {
74 public:
75 std::pair<int32_t, CloudInfo> GetServerInfo(int32_t userId, bool needSpaceInfo) override;
76 std::pair<int32_t, SchemaMeta> GetAppSchema(int32_t userId, const std::string &bundleName) override;
77 virtual ~CloudServerMock() = default;
78 static constexpr uint64_t REMAINSPACE = 1000;
79 static constexpr uint64_t TATALSPACE = 2000;
80 static constexpr int32_t INVALID_USER_ID = -1;
81 };
82
GetServerInfo(int32_t userId,bool needSpaceInfo)83 std::pair<int32_t, CloudInfo> CloudServerMock::GetServerInfo(int32_t userId, bool needSpaceInfo)
84 {
85 CloudInfo cloudInfo;
86 cloudInfo.user = userId;
87 cloudInfo.id = TEST_CLOUD_ID;
88 cloudInfo.remainSpace = REMAINSPACE;
89 cloudInfo.totalSpace = TATALSPACE;
90 cloudInfo.enableCloud = true;
91
92 CloudInfo::AppInfo appInfo;
93 appInfo.bundleName = TEST_CLOUD_BUNDLE;
94 appInfo.appId = TEST_CLOUD_APPID;
95 appInfo.version = 1;
96 appInfo.cloudSwitch = true;
97
98 cloudInfo.apps[TEST_CLOUD_BUNDLE] = std::move(appInfo);
99 return { E_OK, cloudInfo };
100 }
101
GetAppSchema(int32_t userId,const std::string & bundleName)102 std::pair<int32_t, SchemaMeta> CloudServerMock::GetAppSchema(int32_t userId, const std::string &bundleName)
103 {
104 if (userId == INVALID_USER_ID) {
105 return { E_ERROR, CloudDataMockTest::schemaMeta_ };
106 }
107
108 if (bundleName.empty()) {
109 SchemaMeta schemaMeta;
110 return { E_OK, schemaMeta };
111 }
112 return { E_OK, CloudDataMockTest::schemaMeta_ };
113 }
114
115 std::shared_ptr<DBStoreMock> CloudDataMockTest::dbStoreMock_ = std::make_shared<DBStoreMock>();
116 SchemaMeta CloudDataMockTest::schemaMeta_;
117 StoreMetaData CloudDataMockTest::metaData_;
118 CloudInfo CloudDataMockTest::cloudInfo_;
119 std::shared_ptr<CloudData::CloudServiceImpl> CloudDataMockTest::cloudServiceImpl_ =
120 std::make_shared<CloudData::CloudServiceImpl>();
121 NetworkDelegateMock CloudDataMockTest::delegate_;
122
InitMetaData()123 void CloudDataMockTest::InitMetaData()
124 {
125 metaData_.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
126 metaData_.appId = TEST_CLOUD_APPID;
127 metaData_.bundleName = TEST_CLOUD_BUNDLE;
128 metaData_.tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
129 metaData_.user = std::to_string(AccountDelegate::GetInstance()->GetUserByToken(metaData_.tokenId));
130 metaData_.area = OHOS::DistributedKv::EL1;
131 metaData_.instanceId = 0;
132 metaData_.isAutoSync = true;
133 metaData_.storeType = DistributedRdb::RDB_DEVICE_COLLABORATION;
134 metaData_.storeId = TEST_CLOUD_STORE;
135 metaData_.dataDir = TEST_CLOUD_PATH;
136 PolicyValue value;
137 value.type = OHOS::DistributedKv::PolicyType::IMMEDIATE_SYNC_ON_ONLINE;
138 }
139
InitSchemaMeta()140 void CloudDataMockTest::InitSchemaMeta()
141 {
142 SchemaMeta::Field field1;
143 field1.colName = "test_cloud_field_name1";
144 field1.alias = "test_cloud_field_alias1";
145 SchemaMeta::Field field2;
146 field2.colName = "test_cloud_field_name2";
147 field2.alias = "test_cloud_field_alias2";
148
149 SchemaMeta::Table table;
150 table.name = "test_cloud_table_name";
151 table.alias = "test_cloud_table_alias";
152 table.fields.emplace_back(field1);
153 table.fields.emplace_back(field2);
154
155 SchemaMeta::Database database;
156 database.name = TEST_CLOUD_STORE;
157 database.alias = TEST_CLOUD_DATABASE_ALIAS_1;
158 database.tables.emplace_back(table);
159
160 schemaMeta_.version = 1;
161 schemaMeta_.bundleName = TEST_CLOUD_BUNDLE;
162 schemaMeta_.databases.emplace_back(database);
163 database.alias = TEST_CLOUD_DATABASE_ALIAS_2;
164 schemaMeta_.databases.emplace_back(database);
165 schemaMeta_.e2eeEnable = false;
166 }
167
InitCloudInfo()168 void CloudDataMockTest::InitCloudInfo()
169 {
170 cloudInfo_.user = AccountDelegate::GetInstance()->GetUserByToken(IPCSkeleton::GetCallingTokenID());
171 cloudInfo_.id = TEST_CLOUD_ID;
172 cloudInfo_.enableCloud = true;
173
174 CloudInfo::AppInfo appInfo;
175 appInfo.bundleName = TEST_CLOUD_BUNDLE;
176 appInfo.appId = TEST_CLOUD_APPID;
177 appInfo.version = 1;
178 appInfo.cloudSwitch = true;
179
180 cloudInfo_.apps[TEST_CLOUD_BUNDLE] = std::move(appInfo);
181 }
182
SetUpTestCase(void)183 void CloudDataMockTest::SetUpTestCase(void)
184 {
185 accountDelegateMock = new (std::nothrow) AccountDelegateMock();
186 if (accountDelegateMock != nullptr) {
187 AccountDelegate::instance_ = nullptr;
188 AccountDelegate::RegisterAccountInstance(accountDelegateMock);
189 }
190 // 2 means that the GetUserByToken interface will be called twice
191 EXPECT_CALL(*accountDelegateMock, GetUserByToken(_)).Times(2).WillRepeatedly(Return(0));
192
193 accTokenMock = std::make_shared<AccessTokenKitMock>();
194 BAccessTokenKit::accessTokenkit = accTokenMock;
195 EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_))
196 .Times(TEST_TOKEN_FLAG_CALL_COUNT)
197 .WillRepeatedly(Return(ATokenTypeEnum::TOKEN_HAP));
198
199 MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, "");
200 MetaDataManager::GetInstance().SetSyncer(
201 [](const auto &, auto) { DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); });
202
203 auto cloudServerMock = new CloudServerMock();
204 CloudServer::RegisterCloudInstance(cloudServerMock);
205 size_t max = 12;
206 size_t min = 5;
207
208 auto executor = std::make_shared<ExecutorPool>(max, min);
209 cloudServiceImpl_->OnBind(
210 { "CloudDataMockTest", static_cast<uint32_t>(IPCSkeleton::GetSelfTokenID()), std::move(executor) });
211 auto dmExecutor = std::make_shared<ExecutorPool>(max, min);
212 DeviceManagerAdapter::GetInstance().Init(dmExecutor);
213 NetworkDelegate::RegisterNetworkInstance(&delegate_);
214 delegate_.isNetworkAvailable_ = true;
215 InitCloudInfo();
216 InitMetaData();
217 InitSchemaMeta();
218 }
219
TearDownTestCase()220 void CloudDataMockTest::TearDownTestCase()
221 {
222 if (accountDelegateMock != nullptr) {
223 delete accountDelegateMock;
224 accountDelegateMock = nullptr;
225 }
226 accTokenMock = nullptr;
227 BAccessTokenKit::accessTokenkit = nullptr;
228 }
229
SetUp()230 void CloudDataMockTest::SetUp()
231 {
232 MetaDataManager::GetInstance().SaveMeta(cloudInfo_.GetKey(), cloudInfo_, true);
233 MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_, true);
234 StoreMetaMapping storeMetaMapping(metaData_);
235 MetaDataManager::GetInstance().SaveMeta(storeMetaMapping.GetKey(), storeMetaMapping, true);
236 MetaDataManager::GetInstance().SaveMeta(cloudInfo_.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta_, true);
237 }
238
TearDown()239 void CloudDataMockTest::TearDown()
240 {
241 EventCenter::GetInstance().Unsubscribe(CloudEvent::LOCAL_CHANGE);
242 MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true);
243 MetaDataManager::GetInstance().DelMeta(metaData_.GetKey(), true);
244 StoreMetaMapping storeMetaMapping(metaData_);
245 MetaDataManager::GetInstance().DelMeta(storeMetaMapping.GetKey(), true);
246 MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetSchemaKey(TEST_CLOUD_BUNDLE), true);
247 }
248
249 /**
250 * @tc.name: GetSchema001
251 * @tc.desc: Test the scenario where the QueryUsers users not empty and return true in the GetSchema function.
252 * @tc.type: FUNC
253 * @tc.require:
254 * @tc.author:
255 */
256 HWTEST_F(CloudDataMockTest, GetSchema001, TestSize.Level1)
257 {
258 EXPECT_CALL(*accountDelegateMock, GetUserByToken(_)).WillOnce(Return(0));
259 auto cloudServerMock = std::make_shared<CloudServerMock>();
260 auto user = AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID());
261 auto [status, cloudInfo] = cloudServerMock->GetServerInfo(user, true);
262 ASSERT_TRUE(MetaDataManager::GetInstance().DelMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), true));
263 SchemaMeta schemaMeta;
264 ASSERT_FALSE(MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true));
265 std::vector<int> users = { 0, 1 };
266 EXPECT_CALL(*accountDelegateMock, QueryUsers(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(users), Return(true)));
267 EXPECT_CALL(*accountDelegateMock, IsVerified(_)).Times(1).WillOnce(DoAll(Return(true)));
268 DistributedData::StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE,
269 0 };
270 auto event = std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, storeInfo);
271 EventCenter::GetInstance().PostEvent(std::move(event));
272 auto ret = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true);
273 ASSERT_TRUE(ret);
274 }
275
276 /**
277 * @tc.name: GetSchema002
278 * @tc.desc: Test the scenario where the QueryUsers users empty in the GetSchema function.
279 * @tc.type: FUNC
280 * @tc.require:
281 * @tc.author:
282 */
283 HWTEST_F(CloudDataMockTest, GetSchema002, TestSize.Level1)
284 {
285 EXPECT_CALL(*accountDelegateMock, GetUserByToken(_)).WillOnce(Return(0));
286 auto cloudServerMock = std::make_shared<CloudServerMock>();
287 auto user = AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID());
288 auto [status, cloudInfo] = cloudServerMock->GetServerInfo(user, true);
289 ASSERT_TRUE(MetaDataManager::GetInstance().DelMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), true));
290 SchemaMeta schemaMeta;
291 ASSERT_FALSE(MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true));
292
293 std::vector<int> users;
294 EXPECT_CALL(*accountDelegateMock, QueryUsers(_))
295 .Times(1)
296 .WillOnce(
__anon6a5bc3ca0202(std::vector<int> &users) 297 DoAll(SetArgReferee<0>(users), Invoke([](std::vector<int> &users) { users.clear(); }), Return(true)));
298 DistributedData::StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE,
299 0 };
300 auto event = std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, storeInfo);
301 EventCenter::GetInstance().PostEvent(std::move(event));
302 auto ret = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true);
303 ASSERT_FALSE(ret);
304 }
305
306 /**
307 * @tc.name: GetSchema003
308 * @tc.desc: Test the scenario where the QueryUsers return false in the GetSchema function.
309 * @tc.type: FUNC
310 * @tc.require:
311 * @tc.author:
312 */
313 HWTEST_F(CloudDataMockTest, GetSchema003, TestSize.Level1)
314 {
315 EXPECT_CALL(*accountDelegateMock, GetUserByToken(_)).WillOnce(Return(0));
316 auto cloudServerMock = std::make_shared<CloudServerMock>();
317 auto user = AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID());
318 auto [status, cloudInfo] = cloudServerMock->GetServerInfo(user, true);
319 ASSERT_TRUE(MetaDataManager::GetInstance().DelMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), true));
320 SchemaMeta schemaMeta;
321 ASSERT_FALSE(MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true));
322
323 std::vector<int> users;
324 EXPECT_CALL(*accountDelegateMock, QueryUsers(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(users), Return(false)));
325 DistributedData::StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE,
326 0 };
327 auto event = std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, storeInfo);
328 EventCenter::GetInstance().PostEvent(std::move(event));
329 auto ret = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true);
330 ASSERT_FALSE(ret);
331 }
332
333 /**
334 * @tc.name: OnReadyTest_LoginAccount
335 * @tc.desc: Test OnReady function when IsLoginAccount is true or false
336 * @tc.type: FUNC
337 * @tc.require:
338 */
339 HWTEST_F(CloudDataMockTest, OnReadyTest_LoginAccount, TestSize.Level0)
340 {
341 ZLOGI("CloudDataMockTest OnReadyTest_LoginAccount start");
342 std::string device = "test";
343 EXPECT_CALL(*accountDelegateMock, QueryForegroundUsers(_)).WillRepeatedly(testing::Return(false));
344 auto ret = cloudServiceImpl_->OnReady(device);
345 EXPECT_EQ(ret, CloudData::CloudService::SUCCESS);
346
347 EXPECT_CALL(*accountDelegateMock, IsLoginAccount()).Times(1).WillOnce(testing::Return(false));
348 ret = cloudServiceImpl_->OnReady(DeviceManagerAdapter::CLOUD_DEVICE_UUID);
349 EXPECT_NE(ret, CloudData::CloudService::SUCCESS);
350
351 EXPECT_CALL(*accountDelegateMock, IsLoginAccount()).Times(1).WillOnce(testing::Return(true));
352 ret = cloudServiceImpl_->OnReady(DeviceManagerAdapter::CLOUD_DEVICE_UUID);
353 EXPECT_EQ(ret, CloudData::CloudService::SUCCESS);
354 ZLOGI("CloudDataMockTest OnReadyTest_LoginAccount end");
355 }
356
357
358 /**
359 * @tc.name: GetHapInfo001
360 * @tc.desc: Test GetHapInfo function when GetTokenTypeFlag is not TOKEN_HAP.
361 * @tc.type: FUNC
362 * @tc.require:
363 */
364 HWTEST_F(CloudDataMockTest, GetHapInfo001, TestSize.Level1)
365 {
366 ZLOGI("CloudDataMockTest GetHapInfo001 start");
367 DistributedRdb::PredicatesMemo predicates;
368 predicates.tables_.push_back(TEST_CLOUD_BUNDLE);
369 std::vector<std::string> columns;
370 CloudData::Participants participants;
371 EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_))
372 .Times(1)
373 .WillOnce(Return(ATokenTypeEnum::TOKEN_NATIVE));
374 auto [ret, _] = cloudServiceImpl_->AllocResourceAndShare(TEST_CLOUD_STORE, predicates, columns, participants);
375 EXPECT_EQ(ret, E_ERROR);
376 ZLOGI("CloudDataMockTest GetHapInfo001 end");
377 }
378
379 /**
380 * @tc.name: GetHapInfo002
381 * @tc.desc: Test GetHapInfo function when GetTokenTypeFlag is TOKEN_HAP.
382 * @tc.type: FUNC
383 * @tc.require:
384 */
385 HWTEST_F(CloudDataMockTest, GetHapInfo002, TestSize.Level1)
386 {
387 ZLOGI("CloudDataMockTest GetHapInfo002 start");
388 DistributedRdb::PredicatesMemo predicates;
389 predicates.tables_.push_back(TEST_CLOUD_BUNDLE);
390 std::vector<std::string> columns;
391 CloudData::Participants participants;
392 EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_))
393 .Times(1)
394 .WillOnce(Return(ATokenTypeEnum::TOKEN_HAP));
395 EXPECT_CALL(*accTokenMock, GetHapTokenInfo(_, _))
396 .Times(1)
397 .WillOnce(Return(-1));
398 auto [ret, _] = cloudServiceImpl_->AllocResourceAndShare(TEST_CLOUD_STORE, predicates, columns, participants);
399 EXPECT_EQ(ret, E_ERROR);
400 ZLOGI("CloudDataMockTest GetHapInfo002 end");
401 }
402 } // namespace DistributedDataTest
403 } // namespace OHOS::Test