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 }