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 }