1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "device_matrix.h"
16
17 #include "block_data.h"
18 #include "bootstrap.h"
19 #include "checker/checker_manager.h"
20 #include "device_manager_adapter.h"
21 #include "eventcenter/event_center.h"
22 #include "feature/feature_system.h"
23 #include "gtest/gtest.h"
24 #include "ipc_skeleton.h"
25 #include "matrix_event.h"
26 #include "metadata/meta_data_manager.h"
27 #include "metadata/store_meta_data_local.h"
28 #include "mock/checker_mock.h"
29 #include "mock/db_store_mock.h"
30 #include "types.h"
31 using namespace testing::ext;
32 using namespace OHOS::DistributedData;
33 using namespace OHOS::DistributedKv;
34 using namespace OHOS;
35 using DMAdapter = DeviceManagerAdapter;
36 using namespace DistributedDB;
37 class DeviceMatrixTest : public testing::Test {
38 public:
39 static void SetUpTestCase(void);
40 static void TearDownTestCase(void);
41 void SetUp();
42 void TearDown();
43
44 protected:
45 struct Result {
46 uint16_t mask_ = DeviceMatrix::INVALID_LEVEL;
47 std::string deviceId_;
ResultDeviceMatrixTest::Result48 Result(){};
49 };
50 static constexpr const char *TEST_DEVICE = "14a0a92a428005db27c40bad46bf145fede38ec37effe0347cd990fcb031f320";
51 static constexpr const char *TEST_BUNDLE = "matrix_test";
52 static constexpr const char *TEST_STORE = "matrix_store";
53 static constexpr const char *TEST_USER = "0";
54 void InitRemoteMatrixMeta();
55 void InitMetaData();
56
57 static inline std::vector<std::pair<std::string, std::string>> staticStores_ = { { "bundle0", "store0" },
58 { "bundle1", "store0" } };
59 static inline std::vector<std::pair<std::string, std::string>> dynamicStores_ = { { "bundle0", "store1" },
60 { "bundle3", "store0" } };
61 static BlockData<Result> isFinished_;
62 static std::shared_ptr<DBStoreMock> dbStoreMock_;
63 static uint32_t selfToken_;
64 StoreMetaData metaData_;
65 StoreMetaDataLocal localMeta_;
66 static CheckerMock instance_;
67 static constexpr uint32_t CURRENT_VERSION = 3;
68 };
69 BlockData<DeviceMatrixTest::Result> DeviceMatrixTest::isFinished_(1, Result());
70 std::shared_ptr<DBStoreMock> DeviceMatrixTest::dbStoreMock_ = std::make_shared<DBStoreMock>();
71 uint32_t DeviceMatrixTest::selfToken_ = 0;
72 CheckerMock DeviceMatrixTest::instance_;
SetUpTestCase(void)73 void DeviceMatrixTest::SetUpTestCase(void)
74 {
75 MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr);
76 MetaDataManager::GetInstance().SetCloudSyncer([]() {
77 DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK);
78 });
79 selfToken_ = IPCSkeleton::GetCallingTokenID();
80 FeatureSystem::GetInstance().GetCreator("kv_store")();
81 std::vector<CheckerManager::StoreInfo> dynamicStores;
82 for (auto &[bundle, store] : dynamicStores_) {
83 dynamicStores.push_back({ 0, 0, bundle, store });
84 instance_.SetDynamic(dynamicStores);
85 }
86 std::vector<CheckerManager::StoreInfo> staticStores;
87 for (auto &[bundle, store] : staticStores_) {
88 staticStores.push_back({ 0, 0, bundle, store });
89 instance_.SetStatic(staticStores);
90 }
91 Bootstrap::GetInstance().LoadCheckers();
92 DeviceMatrix::GetInstance().Initialize(selfToken_, "service_meta");
93 mkdir("/data/service/el1/public/database/matrix_test", (S_IRWXU | S_IRWXG | S_IRWXO));
94 mkdir("/data/service/el1/public/database/matrix_test/kvdb", (S_IRWXU | S_IRWXG | S_IRWXO));
95 }
96
TearDownTestCase(void)97 void DeviceMatrixTest::TearDownTestCase(void)
98 {
99 EventCenter::GetInstance().Unsubscribe(DeviceMatrix::MATRIX_BROADCAST);
100 }
101
SetUp()102 void DeviceMatrixTest::SetUp()
103 {
104 isFinished_.Clear(Result());
105 DeviceMatrix::GetInstance().Clear();
106 InitMetaData();
107 InitRemoteMatrixMeta();
108 }
109
TearDown()110 void DeviceMatrixTest::TearDown()
111 {
112 (void)remove("/data/service/el1/public/database/matrix_test/kvdb");
113 (void)remove("/data/service/el1/public/database/matrix_test");
114 }
115
InitRemoteMatrixMeta()116 void DeviceMatrixTest::InitRemoteMatrixMeta()
117 {
118 MatrixMetaData metaData;
119 metaData.version = CURRENT_VERSION;
120 metaData.dynamic = 0x7;
121 metaData.deviceId = TEST_DEVICE;
122 metaData.origin = MatrixMetaData::Origin::REMOTE_RECEIVED;
123 metaData.dynamicInfo.clear();
124 for (auto &[bundleName, _] : dynamicStores_) {
125 metaData.dynamicInfo.push_back(bundleName);
126 }
127 MetaDataManager::GetInstance().DelMeta(metaData.GetKey());
128 MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData);
129 }
130
InitMetaData()131 void DeviceMatrixTest::InitMetaData()
132 {
133 metaData_.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid;
134 metaData_.appId = TEST_BUNDLE;
135 metaData_.bundleName = TEST_BUNDLE;
136 metaData_.user = TEST_USER;
137 metaData_.area = EL1;
138 metaData_.tokenId = IPCSkeleton::GetCallingTokenID();
139 metaData_.instanceId = 0;
140 metaData_.isAutoSync = true;
141 metaData_.storeType = true;
142 metaData_.storeId = TEST_STORE;
143 metaData_.dataType = 1;
144 PolicyValue value;
145 value.type = PolicyType::IMMEDIATE_SYNC_ON_ONLINE;
146 localMeta_.policies = { std::move(value) };
147 }
148
149 /**
150 * @tc.name: GetMetaStoreCode
151 * @tc.desc: get the meta data store mask code;
152 * @tc.type: FUNC
153 * @tc.require:
154 * @tc.author: blue sky
155 */
HWTEST_F(DeviceMatrixTest, GetMetaStoreCode, TestSize.Level0)156 HWTEST_F(DeviceMatrixTest, GetMetaStoreCode, TestSize.Level0)
157 {
158 StoreMetaData meta;
159 meta.bundleName = "distributeddata";
160 meta.tokenId = selfToken_;
161 meta.storeId = "service_meta";
162 meta.dataType = 1;
163 auto code = DeviceMatrix::GetInstance().GetCode(meta);
164 ASSERT_EQ(code, DeviceMatrix::META_STORE_MASK);
165 }
166
167 /**
168 * @tc.name: GetAllCode
169 * @tc.desc: get all dynamic store mask code;
170 * @tc.type: FUNC
171 * @tc.require:
172 * @tc.author: blue sky
173 */
HWTEST_F(DeviceMatrixTest, GetAllCode, TestSize.Level0)174 HWTEST_F(DeviceMatrixTest, GetAllCode, TestSize.Level0)
175 {
176 StoreMetaData meta = metaData_;
177
178 for (size_t i = 0; i < dynamicStores_.size(); ++i) {
179 meta.appId = dynamicStores_[i].first;
180 meta.bundleName = dynamicStores_[i].first;
181 ASSERT_EQ(DeviceMatrix::GetInstance().GetCode(meta), 0x1 << (i + 1));
182 }
183 }
184
185 /**
186 * @tc.name: GetOtherStoreCode
187 * @tc.desc: get the other store mask code;
188 * @tc.type: FUNC
189 * @tc.require:
190 * @tc.author: blue sky
191 */
HWTEST_F(DeviceMatrixTest, GetOtherStoreCode, TestSize.Level0)192 HWTEST_F(DeviceMatrixTest, GetOtherStoreCode, TestSize.Level0)
193 {
194 StoreMetaData meta = metaData_;
195 auto code = DeviceMatrix::GetInstance().GetCode(meta);
196 ASSERT_EQ(code, 0);
197 }
198
199 /**
200 * @tc.name: BroadcastMeta
201 * @tc.desc: broadcast the meta store change;
202 * @tc.type: FUNC
203 * @tc.require:
204 * @tc.author: blue sky
205 */
HWTEST_F(DeviceMatrixTest, BroadcastMeta, TestSize.Level0)206 HWTEST_F(DeviceMatrixTest, BroadcastMeta, TestSize.Level0)
207 {
208 DeviceMatrix::DataLevel level = {
209 .dynamic = DeviceMatrix::META_STORE_MASK,
210 };
211 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
212 ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK);
213 }
214
215 /**
216 * @tc.name: BroadcastFirst
217 * @tc.desc: broadcast all stores change;
218 * @tc.type: FUNC
219 * @tc.require:
220 * @tc.author: blue sky
221 */
HWTEST_F(DeviceMatrixTest, BroadcastFirst, TestSize.Level0)222 HWTEST_F(DeviceMatrixTest, BroadcastFirst, TestSize.Level0)
223 {
224 StoreMetaData meta = metaData_;
225 meta.appId = dynamicStores_[0].first;
226 meta.bundleName = dynamicStores_[0].first;
227 auto code = DeviceMatrix::GetInstance().GetCode(meta);
228 ASSERT_EQ(code, 0x2);
229 DeviceMatrix::DataLevel level = {
230 .dynamic = code,
231 };
232 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
233 ASSERT_EQ(mask.first, code);
234 }
235
236 /**
237 * @tc.name: BroadcastOthers
238 * @tc.desc: broadcast the device profile store change;
239 * @tc.type: FUNC
240 * @tc.require:
241 * @tc.author: blue sky
242 */
HWTEST_F(DeviceMatrixTest, BroadcastOthers, TestSize.Level0)243 HWTEST_F(DeviceMatrixTest, BroadcastOthers, TestSize.Level0)
244 {
245 StoreMetaData meta = metaData_;
246 auto code = DeviceMatrix::GetInstance().GetCode(meta);
247 DeviceMatrix::DataLevel level = {
248 .dynamic = code,
249 };
250 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
251 ASSERT_EQ(mask.first, 0);
252 }
253
254 /**
255 * @tc.name: BroadcastAll
256 * @tc.desc: broadcast the all store change;
257 * @tc.type: FUNC
258 * @tc.require:
259 * @tc.author: blue sky
260 */
HWTEST_F(DeviceMatrixTest, BroadcastAll, TestSize.Level0)261 HWTEST_F(DeviceMatrixTest, BroadcastAll, TestSize.Level0)
262 {
263 DeviceMatrix::DataLevel level = {
264 .dynamic = DeviceMatrix::META_STORE_MASK,
265 };
266 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
267 ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK);
268 StoreMetaData meta = metaData_;
269 for (size_t i = 0; i < dynamicStores_.size(); ++i) {
270 meta.appId = dynamicStores_[i].first;
271 meta.bundleName = dynamicStores_[i].first;
272 auto code = DeviceMatrix::GetInstance().GetCode(meta);
273 level.dynamic = code;
274 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
275 ASSERT_EQ(mask.first, (0x1 << (i + 1)) + 1);
276 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, code);
277 }
278 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, DeviceMatrix::META_STORE_MASK);
279 level.dynamic = DeviceMatrix::GetInstance().GetCode(metaData_);
280 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
281 ASSERT_EQ(mask.first, 0);
282
283 level.dynamic = 0xFFFF;
284 level.statics = 0x000D;
285 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
286 ASSERT_EQ(mask.first, 0x0);
287 }
288
289 /**
290 * @tc.name: UpdateMatrixMeta
291 * @tc.desc: update the remote matrix meta the all store change;
292 * @tc.type: FUNC
293 * @tc.require:
294 * @tc.author: blue sky
295 */
HWTEST_F(DeviceMatrixTest, UpdateMatrixMeta, TestSize.Level0)296 HWTEST_F(DeviceMatrixTest, UpdateMatrixMeta, TestSize.Level0)
297 {
298 MatrixMetaData metaData;
299 metaData.version = 4;
300 metaData.dynamic = 0x1F;
301 metaData.deviceId = TEST_DEVICE;
302 metaData.origin = MatrixMetaData::Origin::REMOTE_RECEIVED;
303 metaData.dynamicInfo = { TEST_BUNDLE, dynamicStores_[0].first };
304 MetaDataManager::GetInstance().Subscribe(MatrixMetaData::GetPrefix({ TEST_DEVICE }),
305 [](const std::string &, const std::string &value, int32_t flag) {
306 if (flag != MetaDataManager::INSERT && flag != MetaDataManager::UPDATE) {
307 return true;
308 }
309 MatrixMetaData meta;
310 MatrixMetaData::Unmarshall(value, meta);
311 Result result;
312 result.deviceId_ = meta.deviceId;
313 isFinished_.SetValue(result);
314 return true;
315 });
316 MetaDataManager::GetInstance().DelMeta(metaData.GetKey());
317 MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData);
318
319 auto result = isFinished_.GetValue();
320 ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE));
321
322 DeviceMatrix::DataLevel level = {
323 .dynamic = 0x2,
324 };
325 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
326 ASSERT_EQ(mask.first, 0);
327 level.dynamic = DeviceMatrix::META_STORE_MASK;
328 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
329 ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK);
330 level.dynamic = 0x4;
331 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
332 ASSERT_EQ(mask.first, 0x3);
333 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, DeviceMatrix::META_STORE_MASK);
334 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, 0x2);
335 level.dynamic = 0xFFFF;
336 level.statics = 0x000D;
337 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
338 ASSERT_EQ(mask.first, 0x0);
339 MetaDataManager::GetInstance().Unsubscribe(MatrixMetaData::GetPrefix({ TEST_DEVICE }));
340 }