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 "DistributedTestAgent"
16 
17 #include <gtest/gtest.h>
18 
19 #include <map>
20 
21 #include "accesstoken_kit.h"
22 #include "distributed_kv_data_manager.h"
23 #include "types.h"
24 #include "distributed_agent.h"
25 #include "directory_ex.h"
26 #include "nativetoken_kit.h"
27 #include "token_setproc.h"
28 #include "log_print.h"
29 
30 using namespace testing::ext;
31 using namespace OHOS;
32 using namespace OHOS::DistributeSystemTest;
33 using namespace OHOS::DistributedKv;
34 using namespace OHOS::Security::AccessToken;
35 namespace OHOS::Test {
36 class DistributedTestAgent : public DistributedAgent {
37 public:
38     bool SetUp() override;
39     bool TearDown() override;
40 
41     int OnProcessMsg(const std::string &msg, int len, std::string &ret, int retLen) override;
42     int OnProcessCmd(const std::string &command, int len, const std::string &args,
43         int argsLen, const std::string &expectValue, int expectValueLen) override;
44 
45     int Get(const std::string &msg, std::string &ret);
46 
47     int Put(const std::string &args);
48     int Delete(const std::string &args);
49     int Sync(const std::string &args);
50 
51 private:
52     static DistributedKvDataManager manager_;
53     static std::shared_ptr<SingleKvStore> singleKvStore_;
54     static constexpr int FILE_PERMISSION = 0777;
55     static constexpr int WAIT_TIME = 5;
56 
57     using MessageFunction = int (DistributedTestAgent::*)(const std::string &msg, std::string &ret);
58     std::map<std::string, MessageFunction> messageFunctionMap_;
59     using CommandFunction = int (DistributedTestAgent::*)(const std::string &args);
60     std::map<std::string, CommandFunction> commandFunctionMap_;
61 };
62 
63 DistributedKvDataManager DistributedTestAgent::manager_;
64 std::shared_ptr<SingleKvStore> DistributedTestAgent::singleKvStore_ = nullptr;
65 
66 class KvStoreSyncCallbackTestImpl : public KvStoreSyncCallback {
67 public:
IsSyncComplete()68     static bool IsSyncComplete()
69     {
70         bool flag = completed_;
71         completed_ = false;
72         return flag;
73     }
74 
SyncCompleted(const std::map<std::string,Status> & results)75     void SyncCompleted(const std::map<std::string, Status> &results) override
76     {
77         ZLOGI("SyncCallback Called!");
78         for (const auto &result : results) {
79             if (result.second == SUCCESS) {
80                 completed_ = true;
81             }
82             ZLOGI("device: %{public}s, status: 0x%{public}x", result.first.c_str(), result.second);
83         }
84     }
85 
86 private:
87     static bool completed_;
88 };
89 
90 bool KvStoreSyncCallbackTestImpl::completed_ = false;
91 
SetUp()92 bool DistributedTestAgent::SetUp()
93 {
94     const char **perms = new const char *[1];
95     perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
96     TokenInfoParams info = {
97         .dcapsNum = 0,
98         .permsNum = 1,
99         .aclsNum = 0,
100         .dcaps = nullptr,
101         .perms = perms,
102         .acls = nullptr,
103         .processName = "distributed_test",
104         .aplStr = "system_basic",
105     };
106     auto tokenId = GetAccessTokenId(&info);
107     SetSelfTokenID(tokenId);
108     AccessTokenKit::ReloadNativeTokenInfo();
109     delete[] perms;
110 
111     Options options = { .createIfMissing = true, .encrypt = false, .autoSync = false,
112         .kvStoreType = KvStoreType::SINGLE_VERSION };
113     options.area = EL1;
114     options.securityLevel = S1;
115     options.baseDir = std::string("/data/service/el1/public/database/odmf");
116     AppId appId = { "odmf" };
117     StoreId storeId = { "student" };
118     mkdir(options.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
119     auto status = manager_.GetSingleKvStore(options, appId, storeId, singleKvStore_);
120     if (status != SUCCESS || singleKvStore_ == nullptr) {
121         return false;
122     }
123     OHOS::ChangeModeDirectory(options.baseDir, FILE_PERMISSION);
124 
125     std::shared_ptr<KvStoreSyncCallback> syncCallback = std::make_shared<KvStoreSyncCallbackTestImpl>();
126     status = singleKvStore_->RegisterSyncCallback(syncCallback);
127     if (status != SUCCESS) {
128         return false;
129     }
130 
131     messageFunctionMap_["get"] = &DistributedTestAgent::Get;
132 
133     commandFunctionMap_["put"] = &DistributedTestAgent::Put;
134     commandFunctionMap_["sync"] = &DistributedTestAgent::Sync;
135     return true;
136 }
137 
TearDown()138 bool DistributedTestAgent::TearDown()
139 {
140     (void)manager_.CloseAllKvStore({ "odmf" });
141     (void)manager_.DeleteKvStore({ "odmf" }, { "student" }, "/data/service/el1/public/database/odmf");
142     (void)remove("/data/service/el1/public/database/odmf/key");
143     (void)remove("/data/service/el1/public/database/odmf/kvdb");
144     (void)remove("/data/service/el1/public/database/odmf");
145     return true;
146 }
147 
OnProcessMsg(const std::string & msg,int len,std::string & ret,int retLen)148 int DistributedTestAgent::OnProcessMsg(const std::string &msg, int len, std::string &ret, int retLen)
149 {
150     if (msg == "SendMessage") {
151         ret = "Send Message OK!";
152         return ret.size();
153     }
154     auto index = msg.find(",");
155     std::string function = msg.substr(0, index);
156     auto iter = messageFunctionMap_.find(function);
157     if (iter != messageFunctionMap_.end()) {
158         return (this->*messageFunctionMap_[function])(msg.substr(index + 1), ret);
159     }
160     return DistributedAgent::OnProcessMsg(msg, len, ret, retLen);
161 }
162 
OnProcessCmd(const std::string & command,int len,const std::string & args,int argsLen,const std::string & expectValue,int expectValueLen)163 int DistributedTestAgent::OnProcessCmd(const std::string &command, int len,
164     const std::string &args, int argsLen, const std::string &expectValue, int expectValueLen)
165 {
166     if (command == "CommandTest") {
167         return SUCCESS;
168     }
169     auto iter = commandFunctionMap_.find(command);
170     if (iter != commandFunctionMap_.end()) {
171         return (this->*commandFunctionMap_[command])(args);
172     }
173     return DistributedAgent::OnProcessCmd(command, len, args, argsLen, expectValue, expectValueLen);
174 }
175 
Get(const std::string & msg,std::string & ret)176 int DistributedTestAgent::Get(const std::string &msg, std::string &ret)
177 {
178     Key key(msg);
179     Value value;
180     auto status = singleKvStore_->Get(key, value);
181     ret = std::to_string(status);
182     ret += ",";
183     if (status == SUCCESS) {
184         ret += value.ToString();
185     }
186     return ret.size();
187 }
188 
Put(const std::string & args)189 int DistributedTestAgent::Put(const std::string &args)
190 {
191     auto index = args.find(",");
192     Key key(args.substr(0, index));
193     Value value(args.substr(index + 1));
194     auto status = singleKvStore_->Put(key, value);
195     return status;
196 }
197 
Sync(const std::string & args)198 int DistributedTestAgent::Sync(const std::string &args)
199 {
200     SyncMode syncMode = static_cast<SyncMode>(std::stoi(args));
201     std::vector<std::string> devices;
202     auto status = singleKvStore_->Sync(devices, syncMode);
203 
204     sleep(WAIT_TIME);
205 
206     auto flag = KvStoreSyncCallbackTestImpl::IsSyncComplete();
207     if (!flag) {
208         status = TIME_OUT;
209     }
210     return status;
211 }
212 } // namespace OHOS::Test
213 
main()214 int main()
215 {
216     OHOS::Test::DistributedTestAgent obj;
217     if (obj.SetUp()) {
218         ZLOGE("Init environment success.");
219         obj.Start("agent.desc");
220         obj.Join();
221     } else {
222         ZLOGE("Init environment fail.");
223     }
224     if (obj.TearDown()) {
225         ZLOGE("Clear environment success.");
226         return 0;
227     } else {
228         ZLOGE("Clear environment failed.");
229         return -1;
230     }
231 }