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 protected:
44 struct Result {
45 uint16_t mask_ = DeviceMatrix::INVALID_LEVEL;
46 std::string deviceId_;
ResultDeviceMatrixTest::Result47 Result(){};
48 };
49 static constexpr const char *TEST_DEVICE = "14a0a92a428005db27c40bad46bf145fede38ec37effe0347cd990fcb031f320";
50 static constexpr const char *TEST_BUNDLE = "matrix_test";
51 static constexpr const char *TEST_STORE = "matrix_store";
52 static constexpr const char *TEST_USER = "0";
53 void InitRemoteMatrixMeta();
54 void InitMetaData();
55
56 static inline std::vector<std::pair<std::string, std::string>> staticStores_ = { { "bundle0", "store0" },
57 { "bundle1", "store0" } };
58 static inline std::vector<std::pair<std::string, std::string>> dynamicStores_ = { { "bundle0", "store1" },
59 { "bundle3", "store0" } };
60 static BlockData<Result> isFinished_;
61 static std::shared_ptr<DBStoreMock> dbStoreMock_;
62 static uint32_t selfToken_;
63 StoreMetaData metaData_;
64 StoreMetaDataLocal localMeta_;
65 static CheckerMock instance_;
66 static constexpr uint32_t CURRENT_VERSION = 3;
67 };
68 BlockData<DeviceMatrixTest::Result> DeviceMatrixTest::isFinished_(1, Result());
69 std::shared_ptr<DBStoreMock> DeviceMatrixTest::dbStoreMock_ = std::make_shared<DBStoreMock>();
70 uint32_t DeviceMatrixTest::selfToken_ = 0;
71 CheckerMock DeviceMatrixTest::instance_;
SetUpTestCase(void)72 void DeviceMatrixTest::SetUpTestCase(void)
73 {
74 MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr);
75 MetaDataManager::GetInstance().SetCloudSyncer([]() {
76 DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK);
77 });
78 selfToken_ = IPCSkeleton::GetCallingTokenID();
79 FeatureSystem::GetInstance().GetCreator("kv_store")();
80 std::vector<CheckerManager::StoreInfo> dynamicStores;
81 for (auto &[bundle, store] : dynamicStores_) {
82 dynamicStores.push_back({ 0, 0, bundle, store });
83 instance_.SetDynamic(dynamicStores);
84 }
85 std::vector<CheckerManager::StoreInfo> staticStores;
86 for (auto &[bundle, store] : staticStores_) {
87 staticStores.push_back({ 0, 0, bundle, store });
88 instance_.SetStatic(staticStores);
89 }
90 Bootstrap::GetInstance().LoadCheckers();
91 DeviceMatrix::GetInstance().Initialize(selfToken_, "service_meta");
92 mkdir("/data/service/el1/public/database/matrix_test", (S_IRWXU | S_IRWXG | S_IRWXO));
93 mkdir("/data/service/el1/public/database/matrix_test/kvdb", (S_IRWXU | S_IRWXG | S_IRWXO));
94 }
95
TearDownTestCase(void)96 void DeviceMatrixTest::TearDownTestCase(void)
97 {
98 EventCenter::GetInstance().Unsubscribe(DeviceMatrix::MATRIX_BROADCAST);
99 }
100
SetUp()101 void DeviceMatrixTest::SetUp()
102 {
103 isFinished_.Clear(Result());
104 DeviceMatrix::GetInstance().Clear();
105 InitMetaData();
106 InitRemoteMatrixMeta();
107 }
108
TearDown()109 void DeviceMatrixTest::TearDown()
110 {
111 (void)remove("/data/service/el1/public/database/matrix_test/kvdb");
112 (void)remove("/data/service/el1/public/database/matrix_test");
113 }
114
InitRemoteMatrixMeta()115 void DeviceMatrixTest::InitRemoteMatrixMeta()
116 {
117 MatrixMetaData metaData;
118 metaData.version = CURRENT_VERSION;
119 metaData.dynamic = 0x7;
120 metaData.deviceId = TEST_DEVICE;
121 metaData.origin = MatrixMetaData::Origin::REMOTE_RECEIVED;
122 metaData.dynamicInfo.clear();
123 for (auto &[bundleName, _] : dynamicStores_) {
124 metaData.dynamicInfo.push_back(bundleName);
125 }
126 MetaDataManager::GetInstance().DelMeta(metaData.GetKey());
127 MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData);
128 }
129
InitMetaData()130 void DeviceMatrixTest::InitMetaData()
131 {
132 metaData_.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid;
133 metaData_.appId = TEST_BUNDLE;
134 metaData_.bundleName = TEST_BUNDLE;
135 metaData_.user = TEST_USER;
136 metaData_.area = EL1;
137 metaData_.tokenId = IPCSkeleton::GetCallingTokenID();
138 metaData_.instanceId = 0;
139 metaData_.isAutoSync = true;
140 metaData_.storeType = true;
141 metaData_.storeId = TEST_STORE;
142 metaData_.dataType = 1;
143 PolicyValue value;
144 value.type = PolicyType::IMMEDIATE_SYNC_ON_ONLINE;
145 localMeta_.policies = { std::move(value) };
146 }
147
148 /**
149 * @tc.name: GetMetaStoreCode
150 * @tc.desc: get the meta data store mask code;
151 * @tc.type: FUNC
152 * @tc.require:
153 * @tc.author: blue sky
154 */
155 HWTEST_F(DeviceMatrixTest, GetMetaStoreCode, TestSize.Level0)
156 {
157 StoreMetaData meta;
158 meta.bundleName = "distributeddata";
159 meta.tokenId = selfToken_;
160 meta.storeId = "service_meta";
161 meta.dataType = 1;
162 auto code = DeviceMatrix::GetInstance().GetCode(meta);
163 ASSERT_EQ(code, DeviceMatrix::META_STORE_MASK);
164 }
165
166 /**
167 * @tc.name: GetAllCode
168 * @tc.desc: get all dynamic store mask code;
169 * @tc.type: FUNC
170 * @tc.require:
171 * @tc.author: blue sky
172 */
173 HWTEST_F(DeviceMatrixTest, GetAllCode, TestSize.Level0)
174 {
175 StoreMetaData meta = metaData_;
176
177 for (size_t i = 0; i < dynamicStores_.size(); ++i) {
178 meta.appId = dynamicStores_[i].first;
179 meta.bundleName = dynamicStores_[i].first;
180 ASSERT_EQ(DeviceMatrix::GetInstance().GetCode(meta), 0x1 << (i + 1));
181 }
182 }
183
184 /**
185 * @tc.name: GetOtherStoreCode
186 * @tc.desc: get the other store mask code;
187 * @tc.type: FUNC
188 * @tc.require:
189 * @tc.author: blue sky
190 */
191 HWTEST_F(DeviceMatrixTest, GetOtherStoreCode, TestSize.Level0)
192 {
193 StoreMetaData meta = metaData_;
194 auto code = DeviceMatrix::GetInstance().GetCode(meta);
195 ASSERT_EQ(code, 0);
196 }
197
198 /**
199 * @tc.name: BroadcastMeta
200 * @tc.desc: broadcast the meta store change;
201 * @tc.type: FUNC
202 * @tc.require:
203 * @tc.author: blue sky
204 */
205 HWTEST_F(DeviceMatrixTest, BroadcastMeta, TestSize.Level0)
206 {
207 DeviceMatrix::DataLevel level = {
208 .dynamic = DeviceMatrix::META_STORE_MASK,
209 };
210 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
211 ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK);
212 }
213
214 /**
215 * @tc.name: BroadcastFirst
216 * @tc.desc: broadcast all stores change;
217 * @tc.type: FUNC
218 * @tc.require:
219 * @tc.author: blue sky
220 */
221 HWTEST_F(DeviceMatrixTest, BroadcastFirst, TestSize.Level0)
222 {
223 StoreMetaData meta = metaData_;
224 meta.appId = dynamicStores_[0].first;
225 meta.bundleName = dynamicStores_[0].first;
226 auto code = DeviceMatrix::GetInstance().GetCode(meta);
227 ASSERT_EQ(code, 0x2);
228 DeviceMatrix::DataLevel level = {
229 .dynamic = code,
230 };
231 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
232 ASSERT_EQ(mask.first, code);
233 }
234
235 /**
236 * @tc.name: BroadcastOthers
237 * @tc.desc: broadcast the device profile store change;
238 * @tc.type: FUNC
239 * @tc.require:
240 * @tc.author: blue sky
241 */
242 HWTEST_F(DeviceMatrixTest, BroadcastOthers, TestSize.Level0)
243 {
244 StoreMetaData meta = metaData_;
245 auto code = DeviceMatrix::GetInstance().GetCode(meta);
246 DeviceMatrix::DataLevel level = {
247 .dynamic = code,
248 };
249 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
250 ASSERT_EQ(mask.first, 0);
251 }
252
253 /**
254 * @tc.name: BroadcastAll
255 * @tc.desc: broadcast the all store change;
256 * @tc.type: FUNC
257 * @tc.require:
258 * @tc.author: blue sky
259 */
260 HWTEST_F(DeviceMatrixTest, BroadcastAll, TestSize.Level0)
261 {
262 DeviceMatrix::DataLevel level = {
263 .dynamic = DeviceMatrix::META_STORE_MASK,
264 };
265 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
266 ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK);
267 StoreMetaData meta = metaData_;
268 for (size_t i = 0; i < dynamicStores_.size(); ++i) {
269 meta.appId = dynamicStores_[i].first;
270 meta.bundleName = dynamicStores_[i].first;
271 auto code = DeviceMatrix::GetInstance().GetCode(meta);
272 level.dynamic = code;
273 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
274 ASSERT_EQ(mask.first, (0x1 << (i + 1)) + 1);
275 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, code);
276 }
277 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, DeviceMatrix::META_STORE_MASK);
278 level.dynamic = DeviceMatrix::GetInstance().GetCode(metaData_);
279 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
280 ASSERT_EQ(mask.first, 0);
281
282 level.dynamic = 0xFFFF;
283 level.statics = 0x000D;
284 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
285 ASSERT_EQ(mask.first, 0x0);
286 }
287
288 /**
289 * @tc.name: UpdateMatrixMeta
290 * @tc.desc: update the remote matrix meta the all store change;
291 * @tc.type: FUNC
292 * @tc.require:
293 * @tc.author: blue sky
294 */
295 HWTEST_F(DeviceMatrixTest, UpdateMatrixMeta, TestSize.Level0)
296 {
297 MatrixMetaData metaData;
298 metaData.version = 4;
299 metaData.dynamic = 0x1F;
300 metaData.deviceId = TEST_DEVICE;
301 metaData.origin = MatrixMetaData::Origin::REMOTE_RECEIVED;
302 metaData.dynamicInfo = { TEST_BUNDLE, dynamicStores_[0].first };
303 MetaDataManager::GetInstance().Subscribe(MatrixMetaData::GetPrefix({ TEST_DEVICE }),
__anonfb618eeb0202(const std::string &, const std::string &value, int32_t flag) 304 [](const std::string &, const std::string &value, int32_t flag) {
305 if (flag != MetaDataManager::INSERT && flag != MetaDataManager::UPDATE) {
306 return true;
307 }
308 MatrixMetaData meta;
309 MatrixMetaData::Unmarshall(value, meta);
310 Result result;
311 result.deviceId_ = meta.deviceId;
312 isFinished_.SetValue(result);
313 return true;
314 });
315 MetaDataManager::GetInstance().DelMeta(metaData.GetKey());
316 MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData);
317
318 auto result = isFinished_.GetValue();
319 ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE));
320
321 DeviceMatrix::DataLevel level = {
322 .dynamic = 0x2,
323 };
324 auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
325 ASSERT_EQ(mask.first, 0);
326 level.dynamic = DeviceMatrix::META_STORE_MASK;
327 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
328 ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK);
329 level.dynamic = 0x4;
330 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
331 ASSERT_EQ(mask.first, 0x3);
332 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, DeviceMatrix::META_STORE_MASK);
333 DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, 0x2);
334 level.dynamic = 0xFFFF;
335 level.statics = 0x000D;
336 mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level);
337 ASSERT_EQ(mask.first, 0x0);
338 MetaDataManager::GetInstance().Unsubscribe(MatrixMetaData::GetPrefix({ TEST_DEVICE }));
339 }