1 /*
2 * Copyright (C) 2021 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 "ut_runtime.h"
16 using namespace Hdc;
17
18 namespace HdcTest {
Runtime()19 Runtime::Runtime()
20 {
21 uv_loop_init(&loopMain);
22 bCheckResult = false;
23 checkFinish = false;
24 hashInitialize = false;
25 // UintTest Running log level LOG_INFO/LOG_ALL
26 Base::SetLogLevel(Hdc::LOG_INFO);
27 // three nodes all run host, at least 5+(reserve:2)=7 threads for use
28 // client 1 + (server+daemon)= SIZE_THREAD_POOL*2+1
29 string threadNum = std::to_string(SIZE_THREAD_POOL * 2);
30 uv_os_setenv("UV_THREADPOOL_SIZE", threadNum.c_str());
31 ResetUtTmpFolder();
32
33 serverRunning = false;
34 daemonRunning = false;
35 };
36
~Runtime()37 Runtime::~Runtime()
38 {
39 constexpr int sleepTime = 500;
40 if (hashInitialize) {
41 Base::TryCloseLoop(&loopMain, "Runtime childUV");
42 uv_loop_close(&loopMain);
43 }
44 while (serverRunning || daemonRunning) {
45 uv_sleep(sleepTime);
46 }
47 };
48
InnerCall(int method)49 int Runtime::InnerCall(int method)
50 {
51 return TestRuntimeCommand(method, DEBUG_ADDRESS.c_str(), DEBUG_TCP_CONNECT_KEY.c_str());
52 }
53
CheckStopServer(uv_idle_t * arg)54 void Runtime::CheckStopServer(uv_idle_t *arg)
55 {
56 Runtime *thisClass = (Runtime *)arg->data;
57 thisClass->serverRunning = true;
58 if (!thisClass->checkFinish) {
59 return;
60 }
61 WRITE_LOG(LOG_DEBUG, "Try stop test server");
62 thisClass->server->PostStopInstanceMessage();
63 Base::TryCloseHandle((uv_handle_t *)&thisClass->checkServerStop);
64 }
65
StartServer(uv_work_t * arg)66 void Runtime::StartServer(uv_work_t *arg)
67 {
68 constexpr int sleepTime = 1000;
69 Runtime *thisClass = static_cast<Runtime *>(arg->data);
70 uv_sleep(sleepTime);
71 HdcServer server(true);
72 server.Initial(DEFAULT_SERVER_ADDR.c_str());
73 thisClass->server = &server;
74
75 uv_idle_t *idt = &thisClass->checkServerStop;
76 idt->data = thisClass;
77 uv_idle_init(&server.loopMain, idt);
78 uv_idle_start(idt, CheckStopServer);
79
80 server.WorkerPendding();
81 WRITE_LOG(LOG_DEBUG, "TestServerForClient free");
82 }
83
CheckStopDaemon(uv_idle_t * arg)84 void Runtime::CheckStopDaemon(uv_idle_t *arg)
85 {
86 Runtime *thisClass = (Runtime *)arg->data;
87 thisClass->daemonRunning = true;
88 if (!thisClass->checkFinish) {
89 return;
90 }
91 WRITE_LOG(LOG_DEBUG, "Try stop test daemon");
92 thisClass->daemon->PostStopInstanceMessage();
93 Base::TryCloseHandle((uv_handle_t *)&thisClass->checkDaemonStop);
94 }
95
StartDaemon(uv_work_t * arg)96 void Runtime::StartDaemon(uv_work_t *arg)
97 {
98 Runtime *thisClass = static_cast<Runtime *>(arg->data);
99 HdcDaemon daemon(false);
100 daemon.InitMod(true, false);
101 thisClass->daemon = &daemon;
102
103 uv_idle_t *idt = &thisClass->checkDaemonStop;
104 idt->data = thisClass;
105 uv_idle_init(&daemon.loopMain, idt);
106 uv_idle_start(idt, CheckStopDaemon);
107
108 daemon.WorkerPendding();
109 WRITE_LOG(LOG_DEBUG, "TestDaemon free");
110 }
111
CheckServerDaemonReady()112 int Runtime::CheckServerDaemonReady()
113 {
114 constexpr auto waitCount = 10;
115 if (++waitServerDaemonReadyCount > waitCount) {
116 return ERR_UT_MODULE_WAITMAX;
117 }
118 if (!serverRunning || !daemonRunning) {
119 return ERR_UT_MODULE_NOTREADY;
120 }
121 if (bConnectToDaemon) {
122 PreConnectDaemon(DEBUG_ADDRESS.c_str(), DEBUG_TCP_CONNECT_KEY.c_str());
123 }
124 hashInitialize = true;
125 return RET_SUCCESS;
126 }
127
DoCheck(uv_timer_t * handle)128 void Runtime::DoCheck(uv_timer_t *handle)
129 {
130 Runtime *thisClass = (Runtime *)handle->data;
131 do {
132 int checkRet = thisClass->CheckServerDaemonReady();
133 if (checkRet == ERR_UT_MODULE_WAITMAX) {
134 break;
135 } else if (checkRet == ERR_UT_MODULE_NOTREADY) {
136 return;
137 }
138 // every case can be add more test...
139 switch (thisClass->checkType) {
140 case UT_MOD_SHELL:
141 thisClass->bCheckResult = TestShellExecute(thisClass);
142 break;
143 case UT_MOD_BASE:
144 thisClass->bCheckResult = TestBaseCommand(thisClass);
145 break;
146 case UT_MOD_FILE:
147 thisClass->bCheckResult = TestFileCommand(thisClass);
148 break;
149 case UT_MOD_FORWARD:
150 thisClass->bCheckResult = TestForwardCommand(thisClass);
151 break;
152 case UT_MOD_APP:
153 thisClass->bCheckResult = TestAppCommand(thisClass);
154 break;
155 default:
156 break;
157 }
158 } while (false);
159 uv_close((uv_handle_t *)handle, Base::CloseIdleCallback);
160 thisClass->checkFinish = true;
161 }
162
Initial(bool bConnectToDaemonIn)163 bool Runtime::Initial(bool bConnectToDaemonIn)
164 {
165 bConnectToDaemon = bConnectToDaemonIn;
166 constexpr int sleepTime = 300;
167 auto funcServerFinish = [](uv_work_t *req, int status) -> void {
168 auto thisClass = (Runtime *)req->data;
169 thisClass->serverRunning = false;
170 WRITE_LOG(LOG_DEBUG, "Ut runtime frame server thread finish");
171 delete req;
172 };
173 auto funcDaemonFinish = [](uv_work_t *req, int status) -> void {
174 auto thisClass = (Runtime *)req->data;
175 thisClass->daemonRunning = false;
176 WRITE_LOG(LOG_DEBUG, "Ut runtime frame daemon thread finish");
177 delete req;
178 };
179
180 Base::StartWorkThread(&loopMain, StartServer, funcServerFinish, this);
181 Base::StartWorkThread(&loopMain, StartDaemon, funcDaemonFinish, this);
182 Base::TimerUvTask(&loopMain, this, DoCheck, sleepTime);
183 return true;
184 }
185
CheckEntry(UtModType type)186 bool Runtime::CheckEntry(UtModType type)
187 {
188 checkFinish = false;
189 checkType = type;
190
191 WorkerPendding();
192 return bCheckResult;
193 }
194
ResetUtTmpFolder()195 bool Runtime::ResetUtTmpFolder()
196 {
197 #ifdef DEF_NULL
198 struct stat statbuf;
199 if (!stat(UT_TMP_PATH.c_str(), &statbuf))
200 unlink(UT_TMP_PATH.c_str()); // exist
201 #endif
202 string sCmd = "rm -rf " + UT_TMP_PATH;
203 struct stat statbuf;
204 if (!stat(UT_TMP_PATH.c_str(), &statbuf)) {
205 system(sCmd.c_str());
206 }
207 constexpr uint32_t perm = 0666;
208 mkdir(UT_TMP_PATH.c_str(), perm);
209 return true;
210 }
211
ResetUtTmpFile(string file)212 bool Runtime::ResetUtTmpFile(string file)
213 {
214 string utFile = Base::StringFormat("%s/%s", UT_TMP_PATH.c_str(), file.c_str());
215 string sCmd = "rm -f " + utFile;
216 struct stat statbuf;
217 if (!stat(utFile.c_str(), &statbuf)) {
218 system(sCmd.c_str());
219 }
220 return true;
221 }
222
WorkerPendding()223 void Runtime::WorkerPendding()
224 {
225 uv_run(&loopMain, UV_RUN_DEFAULT);
226 WRITE_LOG(LOG_DEBUG, "TesPendding free");
227 }
228 } // namespace HdcTest
229