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