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_mod.h" 16cc290419Sopenharmony_ci#include <openssl/evp.h> 17cc290419Sopenharmony_ci#include <openssl/md5.h> 18cc290419Sopenharmony_ciusing namespace Hdc; 19cc290419Sopenharmony_ci 20cc290419Sopenharmony_cinamespace HdcTest { 21cc290419Sopenharmony_cibool TestBaseCommand(void *runtimePtr) 22cc290419Sopenharmony_ci{ 23cc290419Sopenharmony_ci Runtime *rt = (Runtime *)runtimePtr; 24cc290419Sopenharmony_ci uint8_t *bufPtr = nullptr; 25cc290419Sopenharmony_ci int bytesIO = 0; 26cc290419Sopenharmony_ci bool ret = false; 27cc290419Sopenharmony_ci // test 'discover' 28cc290419Sopenharmony_ci rt->InnerCall(UT_DISCOVER); 29cc290419Sopenharmony_ci if ((bytesIO = Base::ReadBinFile((UT_TMP_PATH + "/base-discover.result").c_str(), 30cc290419Sopenharmony_ci reinterpret_cast<void **>(&bufPtr), 0)) < 0) { 31cc290419Sopenharmony_ci return false; 32cc290419Sopenharmony_ci } 33cc290419Sopenharmony_ci if (!strcmp("0", reinterpret_cast<char *>(bufPtr))) { 34cc290419Sopenharmony_ci delete[] bufPtr; 35cc290419Sopenharmony_ci bufPtr = nullptr; 36cc290419Sopenharmony_ci return false; 37cc290419Sopenharmony_ci } 38cc290419Sopenharmony_ci delete[] bufPtr; 39cc290419Sopenharmony_ci bufPtr = nullptr; 40cc290419Sopenharmony_ci // test 'targets' 41cc290419Sopenharmony_ci rt->InnerCall(UT_LIST_TARGETS); 42cc290419Sopenharmony_ci constexpr int expert = 5; 43cc290419Sopenharmony_ci if ((bytesIO = Base::ReadBinFile((UT_TMP_PATH + "/base-list.result").c_str(), 44cc290419Sopenharmony_ci reinterpret_cast<void **>(&bufPtr), 0)) < expert) { 45cc290419Sopenharmony_ci goto Finish; 46cc290419Sopenharmony_ci } 47cc290419Sopenharmony_ci if (strcmp(MESSAGE_SUCCESS.c_str(), reinterpret_cast<char *>(bufPtr))) { 48cc290419Sopenharmony_ci goto Finish; 49cc290419Sopenharmony_ci } 50cc290419Sopenharmony_ci delete[] bufPtr; 51cc290419Sopenharmony_ci bufPtr = nullptr; 52cc290419Sopenharmony_ci // test 'any' 53cc290419Sopenharmony_ci rt->InnerCall(UT_CONNECT_ANY); 54cc290419Sopenharmony_ci if ((bytesIO = Base::ReadBinFile((UT_TMP_PATH + "/base-any.result").c_str(), 55cc290419Sopenharmony_ci reinterpret_cast<void **>(&bufPtr), 0)) < 0) { 56cc290419Sopenharmony_ci goto Finish; 57cc290419Sopenharmony_ci } 58cc290419Sopenharmony_ci if (strcmp(MESSAGE_SUCCESS.c_str(), reinterpret_cast<char *>(bufPtr))) { 59cc290419Sopenharmony_ci goto Finish; 60cc290419Sopenharmony_ci } 61cc290419Sopenharmony_ci // all pass 62cc290419Sopenharmony_ci ret = true; 63cc290419Sopenharmony_ci 64cc290419Sopenharmony_ciFinish: 65cc290419Sopenharmony_ci if (bufPtr) { 66cc290419Sopenharmony_ci delete[] bufPtr; 67cc290419Sopenharmony_ci bufPtr = nullptr; 68cc290419Sopenharmony_ci } 69cc290419Sopenharmony_ci return ret; 70cc290419Sopenharmony_ci} 71cc290419Sopenharmony_ci 72cc290419Sopenharmony_cibool TestShellExecute(void *runtimePtr) 73cc290419Sopenharmony_ci{ 74cc290419Sopenharmony_ci Runtime *rt = (Runtime *)runtimePtr; 75cc290419Sopenharmony_ci uint8_t *bufPtr = nullptr; 76cc290419Sopenharmony_ci int bytesIO = 0; 77cc290419Sopenharmony_ci bool ret = false; 78cc290419Sopenharmony_ci char bufString[BUF_SIZE_DEFAULT4] = ""; 79cc290419Sopenharmony_ci string resultFile = "execute.result"; 80cc290419Sopenharmony_ci while (true) { 81cc290419Sopenharmony_ci // test1 82cc290419Sopenharmony_ci rt->InnerCall(UT_SHELL_BASIC); 83cc290419Sopenharmony_ci constexpr int expert = 10; 84cc290419Sopenharmony_ci if ((bytesIO = Base::ReadBinFile((UT_TMP_PATH + "/" + resultFile).c_str(), 85cc290419Sopenharmony_ci reinterpret_cast<void **>(&bufPtr), 0)) < expert) { 86cc290419Sopenharmony_ci break; 87cc290419Sopenharmony_ci } 88cc290419Sopenharmony_ci Base::RunPipeComand(const_cast<const char *>("id"), bufString, sizeof(bufString), false); 89cc290419Sopenharmony_ci if (strcmp(bufString, reinterpret_cast<char *>(bufPtr))) { 90cc290419Sopenharmony_ci break; 91cc290419Sopenharmony_ci } 92cc290419Sopenharmony_ci delete[] bufPtr; 93cc290419Sopenharmony_ci bufPtr = nullptr; 94cc290419Sopenharmony_ci 95cc290419Sopenharmony_ci // test 2 96cc290419Sopenharmony_ci rt->ResetUtTmpFile(resultFile); 97cc290419Sopenharmony_ci rt->InnerCall(UT_SHELL_LIGHT); 98cc290419Sopenharmony_ci if ((bytesIO = Base::ReadBinFile((UT_TMP_PATH + "/" + resultFile).c_str(), 99cc290419Sopenharmony_ci reinterpret_cast<void **>(&bufPtr), 0)) < expert) { 100cc290419Sopenharmony_ci break; 101cc290419Sopenharmony_ci } 102cc290419Sopenharmony_ci Base::RunPipeComand(const_cast<const char *>("cat /etc/passwd"), bufString, sizeof(bufString), false); 103cc290419Sopenharmony_ci if (strcmp(bufString, reinterpret_cast<char *>(bufPtr))) { 104cc290419Sopenharmony_ci break; 105cc290419Sopenharmony_ci } 106cc290419Sopenharmony_ci delete[] bufPtr; 107cc290419Sopenharmony_ci bufPtr = nullptr; 108cc290419Sopenharmony_ci 109cc290419Sopenharmony_ci // all pass 110cc290419Sopenharmony_ci ret = true; 111cc290419Sopenharmony_ci break; 112cc290419Sopenharmony_ci } 113cc290419Sopenharmony_ci if (bufPtr) { 114cc290419Sopenharmony_ci delete[] bufPtr; 115cc290419Sopenharmony_ci } 116cc290419Sopenharmony_ci return ret; 117cc290419Sopenharmony_ci} 118cc290419Sopenharmony_ci 119cc290419Sopenharmony_civector<uint8_t> Md5Sum(uint8_t *buf, int size) 120cc290419Sopenharmony_ci{ 121cc290419Sopenharmony_ci vector<uint8_t> ret; 122cc290419Sopenharmony_ci uint8_t md5Hash[MD5_DIGEST_LENGTH] = { 0 }; 123cc290419Sopenharmony_ci if (EVP_Digest(buf, size, md5Hash, NULL, EVP_md5(), NULL)) { 124cc290419Sopenharmony_ci ret.insert(ret.begin(), md5Hash, md5Hash + sizeof(md5Hash)); 125cc290419Sopenharmony_ci } 126cc290419Sopenharmony_ci return ret; 127cc290419Sopenharmony_ci} 128cc290419Sopenharmony_ci 129cc290419Sopenharmony_ci// file send like recv in our code, so just test send is enough 130cc290419Sopenharmony_cibool TestFileCommand(void *runtimePtr) 131cc290419Sopenharmony_ci{ 132cc290419Sopenharmony_ci Runtime *rt = (Runtime *)runtimePtr; 133cc290419Sopenharmony_ci bool ret = false; 134cc290419Sopenharmony_ci char bufString[BUF_SIZE_DEFAULT] = ""; 135cc290419Sopenharmony_ci uint8_t *bufLocal = nullptr; 136cc290419Sopenharmony_ci uint8_t *bufRemote = nullptr; 137cc290419Sopenharmony_ci int sizeLocal = 0; 138cc290419Sopenharmony_ci int sizeRemote = 0; 139cc290419Sopenharmony_ci string localFile = Base::StringFormat("%s/file.local", UT_TMP_PATH.c_str()); 140cc290419Sopenharmony_ci string remoteFile = Base::StringFormat("%s/file.remote", UT_TMP_PATH.c_str()); 141cc290419Sopenharmony_ci do { 142cc290419Sopenharmony_ci // to be use random buf, not bash result 143cc290419Sopenharmony_ci string cmd = Base::StringFormat("find /usr > %s", localFile.c_str()); 144cc290419Sopenharmony_ci Base::RunPipeComand(cmd.c_str(), bufString, sizeof(bufString), false); 145cc290419Sopenharmony_ci rt->InnerCall(UT_FILE_SEND); 146cc290419Sopenharmony_ci if ((sizeLocal = Base::ReadBinFile(localFile.c_str(), reinterpret_cast<void **>(&bufLocal), 0)) < 0) { 147cc290419Sopenharmony_ci break; 148cc290419Sopenharmony_ci }; 149cc290419Sopenharmony_ci if ((sizeRemote = Base::ReadBinFile(remoteFile.c_str(), reinterpret_cast<void **>(&bufRemote), 0)) < 0) { 150cc290419Sopenharmony_ci break; 151cc290419Sopenharmony_ci }; 152cc290419Sopenharmony_ci auto localHash = Md5Sum(bufLocal, sizeLocal); 153cc290419Sopenharmony_ci auto remoteHash = Md5Sum(bufRemote, sizeRemote); 154cc290419Sopenharmony_ci if (memcmp(localHash.data(), remoteHash.data(), localHash.size())) { 155cc290419Sopenharmony_ci break; 156cc290419Sopenharmony_ci } 157cc290419Sopenharmony_ci ret = true; 158cc290419Sopenharmony_ci } while (false); 159cc290419Sopenharmony_ci 160cc290419Sopenharmony_ci if (bufLocal) { 161cc290419Sopenharmony_ci delete[] bufLocal; 162cc290419Sopenharmony_ci } 163cc290419Sopenharmony_ci if (bufRemote) { 164cc290419Sopenharmony_ci delete[] bufRemote; 165cc290419Sopenharmony_ci } 166cc290419Sopenharmony_ci return ret; 167cc290419Sopenharmony_ci} 168cc290419Sopenharmony_ci 169cc290419Sopenharmony_civoid UtForwardWaiter(uv_loop_t *loop, uv_tcp_t *server) 170cc290419Sopenharmony_ci{ 171cc290419Sopenharmony_ci auto funcOnNewConn = [](uv_stream_t *server, int status) -> void { 172cc290419Sopenharmony_ci auto funcOnRead = [](uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) -> void { 173cc290419Sopenharmony_ci if (nread > 0 && !strcmp(buf->base, MESSAGE_SUCCESS.c_str())) { 174cc290419Sopenharmony_ci Base::WriteBinFile((UT_TMP_PATH + "/forward.result").c_str(), 175cc290419Sopenharmony_ci reinterpret_cast<uint8_t *>(MESSAGE_SUCCESS.c_str()), 176cc290419Sopenharmony_ci MESSAGE_SUCCESS.size(), true); 177cc290419Sopenharmony_ci } 178cc290419Sopenharmony_ci uv_close((uv_handle_t *)client, [](uv_handle_t *handle) { free(handle); }); 179cc290419Sopenharmony_ci free(buf->base); 180cc290419Sopenharmony_ci }; 181cc290419Sopenharmony_ci if (status < 0) { 182cc290419Sopenharmony_ci return; 183cc290419Sopenharmony_ci } 184cc290419Sopenharmony_ci uv_tcp_t *client = new uv_tcp_t(); 185cc290419Sopenharmony_ci uv_tcp_init(server->loop, client); 186cc290419Sopenharmony_ci if (uv_accept(server, (uv_stream_t *)client) == 0) { 187cc290419Sopenharmony_ci uv_read_start((uv_stream_t *)client, 188cc290419Sopenharmony_ci [](uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { 189cc290419Sopenharmony_ci buf->base = new char[suggested_size](); 190cc290419Sopenharmony_ci buf->len = suggested_size; 191cc290419Sopenharmony_ci }, 192cc290419Sopenharmony_ci funcOnRead); 193cc290419Sopenharmony_ci } else { 194cc290419Sopenharmony_ci uv_close((uv_handle_t *)client, [](uv_handle_t *handle) { free(handle); }); 195cc290419Sopenharmony_ci } 196cc290419Sopenharmony_ci }; 197cc290419Sopenharmony_ci const int utForwardTargetPort = 8082; 198cc290419Sopenharmony_ci struct sockaddr_in addr; 199cc290419Sopenharmony_ci if (uv_tcp_init(loop, server) || uv_ip4_addr("127.0.0.1", utForwardTargetPort, &addr)) { 200cc290419Sopenharmony_ci return; 201cc290419Sopenharmony_ci } 202cc290419Sopenharmony_ci if (uv_tcp_bind(server, (const struct sockaddr *)&addr, 0) || uv_listen((uv_stream_t *)server, 5, funcOnNewConn)) { 203cc290419Sopenharmony_ci return; 204cc290419Sopenharmony_ci } 205cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "UtForwardWaiter listen on port:%d", utForwardTargetPort); 206cc290419Sopenharmony_ci} 207cc290419Sopenharmony_ci 208cc290419Sopenharmony_cibool UtForwardConnect(uv_loop_t *loop, uv_tcp_t *client, uv_tcp_t *server) 209cc290419Sopenharmony_ci{ 210cc290419Sopenharmony_ci auto funcConn = [](uv_connect_t *req, int status) -> void { 211cc290419Sopenharmony_ci uv_tcp_t *server = (uv_tcp_t *)req->data; 212cc290419Sopenharmony_ci delete req; 213cc290419Sopenharmony_ci if (status < 0) { 214cc290419Sopenharmony_ci return; 215cc290419Sopenharmony_ci } 216cc290419Sopenharmony_ci Base::SendToStream((uv_stream_t *)req->handle, (uint8_t *)MESSAGE_SUCCESS.c_str(), MESSAGE_SUCCESS.size()); 217cc290419Sopenharmony_ci Base::DelayDoSimple(req->handle->loop, 3000, [=](const uint8_t flag, string &msg, const void *p) { 218cc290419Sopenharmony_ci uv_close((uv_handle_t *)server, nullptr); // notify UtForwardWaiter stop 219cc290419Sopenharmony_ci }); 220cc290419Sopenharmony_ci }; 221cc290419Sopenharmony_ci 222cc290419Sopenharmony_ci const int utForwardListenPort = 8081; 223cc290419Sopenharmony_ci struct sockaddr_in addr; 224cc290419Sopenharmony_ci bool ret = false; 225cc290419Sopenharmony_ci uv_connect_t *connReq = new uv_connect_t(); 226cc290419Sopenharmony_ci connReq->data = server; 227cc290419Sopenharmony_ci do { 228cc290419Sopenharmony_ci if (uv_tcp_init(loop, client)) { 229cc290419Sopenharmony_ci break; 230cc290419Sopenharmony_ci } 231cc290419Sopenharmony_ci uv_ip4_addr("127.0.0.1", utForwardListenPort, &addr); 232cc290419Sopenharmony_ci if (uv_tcp_connect(connReq, client, (const struct sockaddr *)&addr, funcConn)) { 233cc290419Sopenharmony_ci break; 234cc290419Sopenharmony_ci } 235cc290419Sopenharmony_ci 236cc290419Sopenharmony_ci ret = true; 237cc290419Sopenharmony_ci } while (false); 238cc290419Sopenharmony_ci return ret; 239cc290419Sopenharmony_ci} 240cc290419Sopenharmony_ci 241cc290419Sopenharmony_civoid TestForwardExternThread(void *arg) 242cc290419Sopenharmony_ci{ 243cc290419Sopenharmony_ci uv_loop_t loop; 244cc290419Sopenharmony_ci uv_tcp_t server; 245cc290419Sopenharmony_ci uv_tcp_t client; 246cc290419Sopenharmony_ci const int clientForwardTimeout = 1000; 247cc290419Sopenharmony_ci bool *clientOK = (bool *)arg; 248cc290419Sopenharmony_ci auto funcDelayCallUtForwardConnect = [&](const uint8_t flag, string &msg, const void *p) -> void { 249cc290419Sopenharmony_ci if (!*clientOK) { 250cc290419Sopenharmony_ci // client create forward timeout 251cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "Client forward timeout"); 252cc290419Sopenharmony_ci uv_stop(&loop); 253cc290419Sopenharmony_ci } 254cc290419Sopenharmony_ci UtForwardConnect(&loop, &client, &server); 255cc290419Sopenharmony_ci }; 256cc290419Sopenharmony_ci 257cc290419Sopenharmony_ci uv_loop_init(&loop); 258cc290419Sopenharmony_ci UtForwardWaiter(&loop, &server); 259cc290419Sopenharmony_ci Base::DelayDoSimple(&loop, clientForwardTimeout, funcDelayCallUtForwardConnect); 260cc290419Sopenharmony_ci uv_run(&loop, UV_RUN_DEFAULT); 261cc290419Sopenharmony_ci uv_loop_close(&loop); 262cc290419Sopenharmony_ci}; 263cc290419Sopenharmony_ci 264cc290419Sopenharmony_cibool TestForwardCommand(void *runtimePtr) 265cc290419Sopenharmony_ci{ 266cc290419Sopenharmony_ci Runtime *rt = (Runtime *)runtimePtr; 267cc290419Sopenharmony_ci uv_thread_t td; 268cc290419Sopenharmony_ci char buf[BUF_SIZE_TINY] = ""; 269cc290419Sopenharmony_ci bool clientOK = false; 270cc290419Sopenharmony_ci int sizeResult = 0; 271cc290419Sopenharmony_ci uv_thread_create(&td, TestForwardExternThread, &clientOK); 272cc290419Sopenharmony_ci rt->InnerCall(UT_FORWARD_TCP2TCP); 273cc290419Sopenharmony_ci clientOK = true; 274cc290419Sopenharmony_ci uv_thread_join(&td); 275cc290419Sopenharmony_ci // all done, we will check result ok 276cc290419Sopenharmony_ci string localFile = Base::StringFormat("%s/forward.result", UT_TMP_PATH.c_str()); 277cc290419Sopenharmony_ci if ((sizeResult = Base::ReadBinFile(localFile.c_str(), reinterpret_cast<void **>(buf), sizeof(buf))) < 0) { 278cc290419Sopenharmony_ci return false; 279cc290419Sopenharmony_ci }; 280cc290419Sopenharmony_ci if (strcmp(buf, MESSAGE_SUCCESS.c_str())) { 281cc290419Sopenharmony_ci return false; 282cc290419Sopenharmony_ci } 283cc290419Sopenharmony_ci return true; 284cc290419Sopenharmony_ci} 285cc290419Sopenharmony_ci 286cc290419Sopenharmony_cibool TestAppCommand(void *runtimePtr) 287cc290419Sopenharmony_ci{ 288cc290419Sopenharmony_ci Runtime *rt = (Runtime *)runtimePtr; 289cc290419Sopenharmony_ci char bufString[BUF_SIZE_DEFAULT] = ""; 290cc290419Sopenharmony_ci string localFile = Base::StringFormat("%s/app.hap", UT_TMP_PATH.c_str()); 291cc290419Sopenharmony_ci string cmd = Base::StringFormat("id --help > %s", localFile.c_str()); // I know it is a invalid hap file 292cc290419Sopenharmony_ci Base::RunPipeComand(cmd.c_str(), bufString, sizeof(bufString), false); 293cc290419Sopenharmony_ci rt->InnerCall(UT_APP_INSTALL); 294cc290419Sopenharmony_ci 295cc290419Sopenharmony_ci constexpr int expert = 5; 296cc290419Sopenharmony_ci if (Base::ReadBinFile((UT_TMP_PATH + "/appinstall.result").c_str(), reinterpret_cast<void **>(&bufString), 297cc290419Sopenharmony_ci sizeof(bufString)) < expert) { 298cc290419Sopenharmony_ci return false; 299cc290419Sopenharmony_ci } 300cc290419Sopenharmony_ci if (strcmp(MESSAGE_SUCCESS.c_str(), reinterpret_cast<char *>(bufString))) { 301cc290419Sopenharmony_ci return false; 302cc290419Sopenharmony_ci } 303cc290419Sopenharmony_ci return true; 304cc290419Sopenharmony_ci} 305cc290419Sopenharmony_ci} // namespace HdcTest