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 }