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 #define LOG_TAG "DistributedTest"
16 
17 #include <gtest/gtest.h>
18 
19 #include "accesstoken_kit.h"
20 #include "directory_ex.h"
21 #include "distributed_kv_data_manager.h"
22 #include "distributed_major.h"
23 #include "log_print.h"
24 #include "nativetoken_kit.h"
25 #include "token_setproc.h"
26 #include "types.h"
27 
28 using namespace testing::ext;
29 using namespace OHOS;
30 using namespace OHOS::DistributedKv;
31 using namespace OHOS::DistributeSystemTest;
32 using namespace OHOS::Security::AccessToken;
33 namespace OHOS::Test {
34 class DistributedTest : public DistributeTest {
35 public:
36     static void SetUpTestCase();
37     static void TearDownTestCase();
38     void SetUp() override;
39     void TearDown() override;
40 
41     Status GetRemote(const Key &key, Value &value);
42 
43     static DistributedKvDataManager manager_;
44     static std::shared_ptr<SingleKvStore> singleKvStore_;
45     static constexpr int FILE_PERMISSION = 0777;
46     static constexpr int WAIT_TIME = 5;
47 };
48 
49 DistributedKvDataManager DistributedTest::manager_;
50 std::shared_ptr<SingleKvStore> DistributedTest::singleKvStore_ = nullptr;
51 
52 class KvStoreSyncCallbackTestImpl : public KvStoreSyncCallback {
53 public:
IsSyncComplete()54     static bool IsSyncComplete()
55     {
56         bool flag = completed_;
57         completed_ = false;
58         return flag;
59     }
60 
SyncCompleted(const std::map<std::string,Status> & results)61     void SyncCompleted(const std::map<std::string, Status> &results) override
62     {
63         ZLOGI("SyncCallback Called!");
64         for (const auto &result : results) {
65             if (result.second == SUCCESS) {
66                 completed_ = true;
67             }
68             ZLOGI("device: %{public}s, status: 0x%{public}x", result.first.c_str(), result.second);
69         }
70     }
71 
72 private:
73     static bool completed_;
74 };
75 
76 bool KvStoreSyncCallbackTestImpl::completed_ = false;
77 
SetUpTestCase()78 void DistributedTest::SetUpTestCase()
79 {
80     const char **perms = new const char *[1];
81     perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
82     TokenInfoParams info = {
83         .dcapsNum = 0,
84         .permsNum = 1,
85         .aclsNum = 0,
86         .dcaps = nullptr,
87         .perms = perms,
88         .acls = nullptr,
89         .processName = "distributed_test",
90         .aplStr = "system_basic",
91     };
92     auto tokenId = GetAccessTokenId(&info);
93     SetSelfTokenID(tokenId);
94     AccessTokenKit::ReloadNativeTokenInfo();
95     delete[] perms;
96 
97     Options options = { .createIfMissing = true, .encrypt = false, .autoSync = false,
98                         .kvStoreType = KvStoreType::SINGLE_VERSION };
99     options.area = EL1;
100     options.securityLevel = S1;
101     options.baseDir = std::string("/data/service/el1/public/database/odmf");
102     AppId appId = { "odmf" };
103     StoreId storeId = { "student" };
104     mkdir(options.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
105     auto status = manager_.GetSingleKvStore(options, appId, storeId, singleKvStore_);
106     ASSERT_EQ(status, SUCCESS);
107     ASSERT_NE(singleKvStore_, nullptr);
108     OHOS::ChangeModeDirectory(options.baseDir, FILE_PERMISSION);
109 
110     std::shared_ptr<KvStoreSyncCallback> syncCallback = std::make_shared<KvStoreSyncCallbackTestImpl>();
111     status = singleKvStore_->RegisterSyncCallback(syncCallback);
112     ASSERT_EQ(status, SUCCESS);
113 }
114 
TearDownTestCase()115 void DistributedTest::TearDownTestCase()
116 {
117     (void)manager_.CloseAllKvStore({ "odmf" });
118     (void)manager_.DeleteKvStore({ "odmf" }, { "student" }, "/data/service/el1/public/database/odmf");
119     (void)remove("/data/service/el1/public/database/odmf/key");
120     (void)remove("/data/service/el1/public/database/odmf/kvdb");
121     (void)remove("/data/service/el1/public/database/odmf");
122 }
123 
SetUp()124 void DistributedTest::SetUp()
125 {}
126 
TearDown()127 void DistributedTest::TearDown()
128 {}
129 
GetRemote(const Key & key,Value & value)130 Status DistributedTest::GetRemote(const Key &key, Value &value)
131 {
132     Status status = ERROR;
133     std::string message = "get";
134     message += ",";
135     message += key.ToString();
136     (void)SendMessage(AGENT_NO::ONE, message, message.size(),
137         [&](const std::string &returnBuf, int length) -> bool {
138             auto index = returnBuf.find(",");
139             status = Status(std::stoi(returnBuf.substr(0, index)));
140             if (length > static_cast<int>(index + 1)) {
141                 value = Value(returnBuf.substr(index + 1));
142             }
143             return true;
144         });
145     return status;
146 }
147 
148 /**
149 * @tc.name: SendMessage001
150 * @tc.desc: Verify distributed test framework SendMessage
151 * @tc.type: FUNC
152 */
153 HWTEST_F(DistributedTest, SendMessage001, TestSize.Level1)
154 {
155     ZLOGI("SendMessage001 Start");
156 
157     std::string message = "SendMessage";
158     std::string result = "";
159     auto flag = SendMessage(AGENT_NO::ONE, message, message.size(),
__anonc4f6ba850202(const std::string &returnBuf, int length) 160         [&](const std::string &returnBuf, int length) -> bool {
161             result = returnBuf;
162             return true;
163         });
164     ASSERT_TRUE(flag);
165     ASSERT_EQ(result, "Send Message OK!");
166 
167     ZLOGI("SendMessage001 end");
168 }
169 
170 /**
171 * @tc.name: RunCommand001
172 * @tc.desc: Verify distributed test framework RunCommand
173 * @tc.type: FUNC
174 */
175 HWTEST_F(DistributedTest, RunCommand001, TestSize.Level1)
176 {
177     ZLOGI("RunCommand001 Start");
178 
179     std::string command = "CommandTest";
180     std::string arguments = "";
181     std::string result = "0";
182     auto flag = RunCmdOnAgent(AGENT_NO::ONE, command, arguments, result);
183     ASSERT_TRUE(flag);
184     auto status = GetReturnVal();
185     ASSERT_EQ(status, SUCCESS);
186 
187     ZLOGI("RunCommand001 end");
188 }
189 
190 /**
191 * @tc.name: SyncData001
192 * @tc.desc: Sync data with push mode and get data from other device
193 * @tc.type: FUNC
194 */
195 HWTEST_F(DistributedTest, SyncData001, TestSize.Level1)
196 {
197     ZLOGI("SyncData001 begin");
198 
199     Key key = { "key1" };
200     Value valueLocal = { "value1" };
201     auto status = singleKvStore_->Put(key, valueLocal);
202     ASSERT_EQ(status, SUCCESS);
203 
204     std::vector<std::string> devices;
205     status = singleKvStore_->Sync(devices, SyncMode::PUSH);
206     ASSERT_EQ(status, SUCCESS);
207 
208     sleep(WAIT_TIME);
209 
210     auto flag = KvStoreSyncCallbackTestImpl::IsSyncComplete();
211     ASSERT_TRUE(flag);
212 
213     Value valueRemote;
214     status = GetRemote(key, valueRemote);
215     ASSERT_EQ(status, SUCCESS);
216     ASSERT_EQ(valueLocal.ToString(), valueRemote.ToString());
217 
218     ZLOGI("SyncData001 end");
219 }
220 
221 /**
222 * @tc.name: SyncData002
223 * @tc.desc: Sync data with pull mode by other device and get data from other device
224 * @tc.type: FUNC
225 */
226 HWTEST_F(DistributedTest, SyncData002, TestSize.Level1)
227 {
228     ZLOGI("SyncData002 begin");
229 
230     Key key = { "key2" };
231     Value valueLocal = { "value2" };
232     auto status = singleKvStore_->Put(key, valueLocal);
233     ASSERT_EQ(status, SUCCESS);
234 
235     SyncMode mode = SyncMode::PULL;
236     std::string arguments = std::to_string(mode);
237     auto flag = RunCmdOnAgent(AGENT_NO::ONE, "sync", arguments, "0");
238     ASSERT_TRUE(flag);
239     status = static_cast<Status>(GetReturnVal());
240     ASSERT_EQ(status, SUCCESS);
241 
242     Value valueRemote;
243     status = GetRemote(key, valueRemote);
244     ASSERT_EQ(status, SUCCESS);
245     ASSERT_EQ(valueLocal.ToString(), valueRemote.ToString());
246 
247     ZLOGI("SyncData002 end");
248 }
249 } // namespace OHOS::Test
250 
main(int argc,char * argv[])251 int main(int argc, char *argv[])
252 {
253     g_pDistributetestEnv = new DistributeTestEnvironment("major.desc");
254     testing::AddGlobalTestEnvironment(g_pDistributetestEnv);
255     testing::GTEST_FLAG(output) = "xml:./";
256     testing::InitGoogleTest(&argc, argv);
257     return RUN_ALL_TESTS();
258 }