diff --git a/0187-test-readv-writev-epoll_create1-accept4.patch b/0187-test-readv-writev-epoll_create1-accept4.patch new file mode 100644 index 0000000..3d124fa --- /dev/null +++ b/0187-test-readv-writev-epoll_create1-accept4.patch @@ -0,0 +1,448 @@ +From 9ff6edf1f5a9140831d03b4ce3bcf35ee5cf710e Mon Sep 17 00:00:00 2001 +From: jackyfan <1376762675@qq.com> +Date: Mon, 12 Dec 2022 16:06:10 +0800 +Subject: [PATCH] test readv writev epoll_create1 accept4 + +--- + examples/README.md | 20 ++++++++++++++++--- + examples/inc/client.h | 1 + + examples/inc/parameter.h | 9 +++++++++ + examples/inc/server.h | 7 ++++++- + examples/inc/utilities.h | 1 + + examples/src/bussiness.c | 25 ++++++++++++++++++++++++ + examples/src/client.c | 10 ++++++++-- + examples/src/parameter.c | 40 +++++++++++++++++++++++++++++++++++++- + examples/src/server.c | 42 +++++++++++++++++++++++++++++++++++----- + 9 files changed, 143 insertions(+), 12 deletions(-) + +diff --git a/examples/README.md b/examples/README.md +index cf2f26f..06a725b 100644 +--- a/examples/README.md ++++ b/examples/README.md +@@ -113,7 +113,7 @@ + * `-D, --domain [unix | posix]`:通信协议。 + * `unix`:基于 unix 协议实现。 + * `posix`:基于 posix 协议实现。 +-* `-A, --api [readwrite | recvsend | recvsendmsg]`:内部实现的接口类型。 ++* `-A, --api [readwrite | recvsend | recvsendmsg | readvwritev]`:内部实现的接口类型。 + * `readwrite` :使用 `read` 和 `write` 接口。 + * `recvsend` :使用 `recv` 和 `send` 接口。 + * `recvsendmsg` :使用 `recvmsg` 和 `sendmsg` 接口。 +@@ -122,7 +122,12 @@ + * `-r, --ringpmd`:是否基于dpdk ring PMD 收发环回。 + * `-d, --debug`:是否打印调试信息。 + * `-h, --help`:获得帮助信息。 +- ++* `-E, --epollcreate`:epoll_create方式。 ++ * `ec`:使用epoll_create(int size)生成epoll专用的文件描述符。 ++ * `ec1`:使用epoll_create1(int flags)生成epoll专用的文件描述符,flags = EPOLL_CLOEXEC。 ++* `-C, --accept`:accept的方式。 ++ * `ac`:使用accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)通过套接口接受连接。 ++ * `ac4`:使用accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags)通过套接口接受连接,flags=SOCK_CLOEXEC。 + ## 使用 + + * **环境配置** +@@ -165,6 +170,12 @@ make + -r, --ringpmd: set to use ringpmd. + -d, --debug: set to print the debug information. + -h, --help: see helps. ++-E, --epollcreate: epoll_create method. ++ ec: use epoll_create(int size) to create epoll fd. ++ ec1:use epoll_create(int flags) to create epoll fd, flags=EPOLL_CLOEXEC. ++-C, --accept: accept method. ++ ac: use accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) to accept a connection on a socket ++ ac4: use accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags) to accept a connection on a socket, flags=SOCK_CLOEXEC. + ``` + + * 创建服务端 +@@ -184,6 +195,8 @@ make + --> [verify]: on + --> [ringpmd]: off + --> [debug]: off ++--> [epoll create]: ec ++--> [accept]: ac + + [program informations]: + --> : [connect num]: 0, [receive]: 0.000 B/s +@@ -205,7 +218,8 @@ make + --> [packet length]: 1024 + --> [verify]: on + --> [ringpmd]: off +---> [debug]: off ++--> [epoll create]: ec ++--> [accept]: ac + + [program informations]: + --> : [connect num]: 80, [send]: 357.959 MB/s +diff --git a/examples/inc/client.h b/examples/inc/client.h +index d3ae017..ad824c7 100644 +--- a/examples/inc/client.h ++++ b/examples/inc/client.h +@@ -39,6 +39,7 @@ struct ClientUnit + char* domain; ///< the communication domain + char* api; ///< the type of api + bool debug; ///< if we print the debug information ++ char* epollcreate; ///< epoll_create method + struct ClientUnit *next; ///< next pointer + }; + +diff --git a/examples/inc/parameter.h b/examples/inc/parameter.h +index ee8fe4e..0683822 100644 +--- a/examples/inc/parameter.h ++++ b/examples/inc/parameter.h +@@ -30,6 +30,9 @@ + #define PARAM_DEFAULT_VERIFY (false) ///< default flag of message verifying + #define PARAM_DEFAULT_DEBUG (false) ///< default flag of debug + #define PARAM_DEFAULT_RINGPMD (false) ///< default flag of ring PMD of dpdk ++#define PARAM_DEFAULT_EPOLLCREATE ("ec") ///< default method of epoll_create ++#define PARAM_DEFAULT_ACCEPT ("ac") ///< default method of accept method ++ + + enum { + #define PARAM_NAME_AS ("as") ///< name of parameter type +@@ -58,6 +61,10 @@ enum { + PARAM_NUM_DEBUG = 'd', + #define PARAM_NAME_HELP ("help") ///< name of parameter help + PARAM_NUM_HELP = 'h', ++#define PARAM_NAME_EPOLLCREATE ("epollcreate") ///< name of parameter epollcreate ++ PARAM_NUM_EPOLLCREATE = 'E', ++#define PARAM_NAME_ACCEPT ("accept") ///< name of parameter accept ++ PARAM_NUM_ACCEPT = 'C', + }; + + #define NO_ARGUMENT 0 ///< options takes no arguments +@@ -92,6 +99,8 @@ struct ProgramParams { + uint32_t pktlen; ///< the packet length + bool verify; ///< if we verify the message or not + bool debug; ///< if we print the debug information or not ++ char* epollcreate; ///< epoll_create method ++ char* accept; ///< accept connections method + bool ringpmd; ///< if we use ring PMD or not + }; + +diff --git a/examples/inc/server.h b/examples/inc/server.h +index fa9096b..45ca895 100644 +--- a/examples/inc/server.h ++++ b/examples/inc/server.h +@@ -13,7 +13,7 @@ + + #ifndef __EXAMPLES_SERVER_H__ + #define __EXAMPLES_SERVER_H__ +- ++#define _GNU_SOURCE + + #include "utilities.h" + #include "parameter.h" +@@ -37,6 +37,8 @@ struct ServerMumUnit + char* domain; ///< communication domain + char* api; ///< the type of api + bool debug; ///< if we print the debug information ++ char* epollcreate; ///< epoll_create method ++ char* accept; ///< accept connections method + struct ServerMumUnit *next; ///< next pointer + }; + +@@ -65,6 +67,7 @@ struct ServerMudWorker + uint16_t port; ///< client port + char* api; ///< the type of api + bool debug; ///< if we print the debug information ++ char* epollcreate; ///< epoll_create method + struct ServerMudWorker *next; ///< next pointer + }; + +@@ -85,6 +88,8 @@ struct ServerMud + char* domain; ///< communication domain + char* api; ///< the type of api + bool debug; ///< if we print the debug information ++ char* accept; ///< accept connections method ++ char* epollcreate; ///< epoll_create method + }; + + +diff --git a/examples/inc/utilities.h b/examples/inc/utilities.h +index a684d35..a083f57 100644 +--- a/examples/inc/utilities.h ++++ b/examples/inc/utilities.h +@@ -40,6 +40,7 @@ + + #include "securec.h" + #include "securectype.h" ++#include "sys/uio.h" + + + #define PRINT_ERROR(format, ...) do \ +diff --git a/examples/src/bussiness.c b/examples/src/bussiness.c +index f55a37b..b084b37 100644 +--- a/examples/src/bussiness.c ++++ b/examples/src/bussiness.c +@@ -25,6 +25,18 @@ static const char bussiness_messages_cap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // t + return read(fd, buffer_in, length); + } else if (strcmp(api, "recvsend") == 0) { + return recv(fd, buffer_in, length, 0); ++ } else if (strcmp(api, "readvwritev") == 0) { ++ struct iovec iov[3]; ++ int iovcnt = 3; ++ uint32_t iov_len_size = length/iovcnt; ++ ++ iov[0].iov_base=buffer_in; ++ iov[0].iov_len = iov_len_size; ++ iov[1].iov_base= buffer_in + iov_len_size; ++ iov[1].iov_len = iov_len_size; ++ iov[2].iov_base = buffer_in + iov_len_size + iov_len_size; ++ iov[2].iov_len = length- iov_len_size - iov_len_size; ++ return readv(fd, iov, iovcnt); + } else { + struct msghdr msg_recv; + struct iovec iov; +@@ -50,6 +62,19 @@ static const char bussiness_messages_cap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // t + return write(fd, buffer_out, length); + } else if (strcmp(api, "recvsend") == 0) { + return send(fd, buffer_out, length, 0); ++ } else if (strcmp(api, "readvwritev") == 0) { ++ struct iovec iov[3]; ++ int iovcnt = 3; ++ uint32_t iov_len_size = length/iovcnt; ++ ++ iov[0].iov_base=buffer_out; ++ iov[0].iov_len = iov_len_size; ++ iov[1].iov_base= buffer_out + iov_len_size; ++ iov[1].iov_len = iov_len_size; ++ iov[2].iov_base = buffer_out + iov_len_size + iov_len_size; ++ iov[2].iov_len = length- iov_len_size - iov_len_size; ++ ++ return writev(fd, iov, iovcnt); + } else { + struct msghdr msg_send; + struct iovec iov; +diff --git a/examples/src/client.c b/examples/src/client.c +index aafcd00..46dd039 100644 +--- a/examples/src/client.c ++++ b/examples/src/client.c +@@ -155,8 +155,13 @@ int32_t client_thread_retry_connect(struct ClientUnit *client_unit, struct Clien + int32_t client_thread_create_epfd_and_reg(struct ClientUnit *client_unit) + { + const uint32_t connect_num = client_unit->connect_num; +- +- client_unit->epfd = epoll_create(CLIENT_EPOLL_SIZE_MAX); ++ //jacky modify ++ if (strcmp(client_unit->epollcreate, "ec1") == 0) { ++ client_unit->epfd = epoll_create1(EPOLL_CLOEXEC); ++ } else { ++ client_unit->epfd = epoll_create(CLIENT_EPOLL_SIZE_MAX); ++ } ++ + if (client_unit->epfd < 0) { + PRINT_ERROR("client can't create epoll %d! ", errno); + return PROGRAM_FAULT; +@@ -364,6 +369,7 @@ int32_t client_create_and_run(struct ProgramParams *params) + client_unit->verify = params->verify; + client_unit->domain = params->domain; + client_unit->api = params->api; ++ client_unit->epollcreate = params->epollcreate; + client_unit->debug = params->debug; + client_unit->next = (struct ClientUnit *)malloc(sizeof(struct ClientUnit)); + +diff --git a/examples/src/parameter.c b/examples/src/parameter.c +index 100ee11..3116a18 100644 +--- a/examples/src/parameter.c ++++ b/examples/src/parameter.c +@@ -29,6 +29,8 @@ const char prog_short_opts[] = \ + "r" // ringpmd + "d" // debug + "h" // help ++ "E" // epollcreate ++ "C" // accept + ; + + // program long options +@@ -47,6 +49,8 @@ const struct ProgramOption prog_long_opts[] = \ + {PARAM_NAME_RINGPMD, NO_ARGUMENT, NULL, PARAM_NUM_RINGPMD}, + {PARAM_NAME_DEBUG, NO_ARGUMENT, NULL, PARAM_NUM_DEBUG}, + {PARAM_NAME_HELP, NO_ARGUMENT, NULL, PARAM_NUM_HELP}, ++ {PARAM_NAME_EPOLLCREATE, REQUIRED_ARGUMETN, NULL, PARAM_NUM_EPOLLCREATE}, ++ {PARAM_NAME_ACCEPT, REQUIRED_ARGUMETN, NULL, PARAM_NUM_ACCEPT}, + }; + + +@@ -139,7 +143,7 @@ void program_param_parse_domain(struct ProgramParams *params) + void program_param_parse_api(struct ProgramParams *params) + { + printf("aaaaaa %s\n", optarg); +- if (strcmp(optarg, "readwrite") == 0 || strcmp(optarg, "recvsend") == 0 || strcmp(optarg, "recvsendmsg") == 0) { ++ if (strcmp(optarg, "readwrite") == 0 || strcmp(optarg, "readvwritev") == 0 || strcmp(optarg, "recvsend") == 0 || strcmp(optarg, "recvsendmsg") == 0) { + params->api = optarg; + } else { + PRINT_ERROR("illigal argument -- %s \n", optarg); +@@ -159,6 +163,28 @@ void program_param_parse_pktlen(struct ProgramParams *params) + } + } + ++// set `epollcreate` parameter ++void program_param_parse_epollcreate(struct ProgramParams *params) ++{ ++ if (strcmp(optarg, "ec") == 0 || strcmp(optarg, "ec1") == 0) { ++ params->epollcreate = optarg; ++ } else { ++ PRINT_ERROR("illigal argument -- %s \n", optarg); ++ exit(PROGRAM_ABORT); ++ } ++} ++ ++// set `accept` parameter ++void program_param_parse_accept(struct ProgramParams *params) ++{ ++ if (strcmp(optarg, "ac") == 0 || strcmp(optarg, "ac4") == 0) { ++ params->accept = optarg; ++ } else { ++ PRINT_ERROR("illigal argument -- %s \n", optarg); ++ exit(PROGRAM_ABORT); ++ } ++} ++ + // initialize the parameters + void program_params_init(struct ProgramParams *params) + { +@@ -174,6 +200,8 @@ void program_params_init(struct ProgramParams *params) + params->verify = PARAM_DEFAULT_VERIFY; + params->ringpmd = PARAM_DEFAULT_RINGPMD; + params->debug = PARAM_DEFAULT_DEBUG; ++ params->epollcreate = PARAM_DEFAULT_EPOLLCREATE; ++ params->accept = PARAM_DEFAULT_ACCEPT; + } + + // print program helps +@@ -202,6 +230,8 @@ void program_params_help(void) + printf("-r, --ringpmd: set to use ringpmd. \n"); + printf("-d, --debug: set to print the debug information. \n"); + printf("-h, --help: see helps. \n"); ++ printf("-E, --epollcreate [ec | ec1]: epoll_create method. \n"); ++ printf("-C, --accept [ac | ac4]: accept method. \n"); + printf("\n"); + } + +@@ -256,6 +286,12 @@ int32_t program_params_parse(struct ProgramParams *params, uint32_t argc, char * + case (PARAM_NUM_DEBUG): + params->debug = true; + break; ++ case (PARAM_NUM_EPOLLCREATE): ++ program_param_parse_epollcreate(params); ++ break; ++ case (PARAM_NUM_ACCEPT): ++ program_param_parse_accept(params); ++ break; + case (PARAM_NUM_HELP): + program_params_help(); + return PROGRAM_ABORT; +@@ -304,5 +340,7 @@ void program_params_print(struct ProgramParams *params) + printf("--> [verify]: %s \n", (params->verify == true) ? "on" : "off"); + printf("--> [ringpmd]: %s \n", (params->ringpmd == true) ? "on" : "off"); + printf("--> [debug]: %s \n", (params->debug == true) ? "on" : "off"); ++ printf("--> [epoll create]: %s \n", params->epollcreate); ++ printf("--> [accept]: %s \n", params->accept); + printf("\n"); + } +diff --git a/examples/src/server.c b/examples/src/server.c +index d1dab72..27572f0 100644 +--- a/examples/src/server.c ++++ b/examples/src/server.c +@@ -86,7 +86,12 @@ void sermud_info_print(struct ServerMud *server_mud) + // the worker thread, unblock, dissymmetric server listens and gets epoll feature descriptors + int32_t sermud_worker_create_epfd_and_reg(struct ServerMudWorker *worker_unit) + { +- worker_unit->epfd = epoll_create(SERVER_EPOLL_SIZE_MAX); ++ if (strcmp(worker_unit->epollcreate, "ec1") == 0) { ++ worker_unit->epfd = epoll_create1(EPOLL_CLOEXEC); ++ } else { ++ worker_unit->epfd = epoll_create(SERVER_EPOLL_SIZE_MAX); ++ } ++ + if (worker_unit->epfd < 0) { + PRINT_ERROR("server can't create epoll %d! ", worker_unit->epfd); + return PROGRAM_FAULT; +@@ -106,7 +111,12 @@ int32_t sermud_worker_create_epfd_and_reg(struct ServerMudWorker *worker_unit) + // the listener thread, unblock, dissymmetric server listens and gets epoll feature descriptors + int32_t sermud_listener_create_epfd_and_reg(struct ServerMud *server_mud) + { +- server_mud->epfd = epoll_create(SERVER_EPOLL_SIZE_MAX); ++ if (strcmp(server_mud->epollcreate, "ec1") == 0) { ++ server_mud->epfd = epoll_create1(EPOLL_CLOEXEC); ++ } else { ++ server_mud->epfd = epoll_create(SERVER_EPOLL_SIZE_MAX); ++ } ++ + if (server_mud->epfd < 0) { + PRINT_ERROR("server can't create epoll %d! ", server_mud->epfd); + return PROGRAM_FAULT; +@@ -131,7 +141,13 @@ int32_t sermud_listener_accept_connects(struct ServerMud *server_mud) + while (true) { + struct sockaddr_in accept_addr; + uint32_t sockaddr_in_len = sizeof(struct sockaddr_in); +- int32_t accept_fd = accept(server_mud->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len); ++ int32_t accept_fd; ++ if (strcmp(server_mud->accept, "ac4") == 0) { ++ accept_fd = accept4(server_mud->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len, SOCK_CLOEXEC); ++ } else { ++ accept_fd = accept(server_mud->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len); ++ } ++ + if (accept_fd < 0) { + break; + } +@@ -155,6 +171,7 @@ int32_t sermud_listener_accept_connects(struct ServerMud *server_mud) + worker->api = server_mud->api; + worker->debug = server_mud->debug; + worker->next = server_mud->workers; ++ worker->epollcreate = server_mud->epollcreate; + + server_mud->workers = worker; + +@@ -308,6 +325,8 @@ int32_t sermud_create_and_run(struct ProgramParams *params) + server_mud->domain = params->domain; + server_mud->api = params->api; + server_mud->debug = params->debug; ++ server_mud->epollcreate = params->epollcreate; ++ server_mud->accept = params->accept; + + if (pthread_create(tid, NULL, sermud_listener_create_and_run, server_mud) < 0) { + PRINT_ERROR("server can't create poisx thread %d! ", errno); +@@ -378,7 +397,12 @@ void sermum_info_print(struct ServerMum *server_mum) + // the single thread, unblock, mutliplexing IO server listens and gets epoll feature descriptors + int32_t sersum_create_epfd_and_reg(struct ServerMumUnit *server_unit) + { +- server_unit->epfd = epoll_create(SERVER_EPOLL_SIZE_MAX); ++ if (strcmp(server_unit->epollcreate, "ec1") == 0) { ++ server_unit->epfd = epoll_create1(EPOLL_CLOEXEC); ++ } else { ++ server_unit->epfd = epoll_create(SERVER_EPOLL_SIZE_MAX); ++ } ++ + if (server_unit->epfd < 0) { + PRINT_ERROR("server can't create epoll %d! ", server_unit->epfd); + return PROGRAM_FAULT; +@@ -403,7 +427,13 @@ int32_t sersum_accept_connects(struct ServerMumUnit *server_unit, struct ServerH + while (true) { + struct sockaddr_in accept_addr; + uint32_t sockaddr_in_len = sizeof(struct sockaddr_in); +- int32_t accept_fd = accept(server_unit->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len); ++ int32_t accept_fd; ++ if (strcmp(server_unit->accept, "ac4") == 0) { ++ accept_fd = accept4(server_unit->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len, SOCK_CLOEXEC); ++ } else { ++ accept_fd = accept(server_unit->listener.fd, (struct sockaddr *)&accept_addr, &sockaddr_in_len); ++ } ++ + if (accept_fd < 0) { + break; + } +@@ -542,6 +572,8 @@ int32_t sermum_create_and_run(struct ProgramParams *params) + server_unit->domain = params->domain; + server_unit->api = params->api; + server_unit->debug = params->debug; ++ server_unit->epollcreate = params->epollcreate; ++ server_unit->accept = params->accept; + server_unit->next = (struct ServerMumUnit *)malloc(sizeof(struct ServerMumUnit)); + + if (pthread_create((tids + i), NULL, sersum_create_and_run, server_unit) < 0) { +-- +2.23.0 + diff --git a/0188-add-fucntest.patch b/0188-add-fucntest.patch new file mode 100644 index 0000000..08393f2 --- /dev/null +++ b/0188-add-fucntest.patch @@ -0,0 +1,1359 @@ +From 502e0241ea1d6f1ffe01fbfe8272fb90003c3327 Mon Sep 17 00:00:00 2001 +From: jiangheng12 +Date: Tue, 7 Feb 2023 11:39:40 +0800 +Subject: [PATCH] add fucntest + +--- + test/functest/CMakeLists.txt | 16 + + test/functest/common/common.c | 248 +++++++++++++ + test/functest/common/common.h | 68 ++++ + test/functest/common/uitls.c | 0 + test/functest/common/utils.c | 261 ++++++++++++++ + test/functest/common/utils.h | 42 +++ + test/functest/signal_hijack/CMakeLists.txt | 16 + + test/functest/signal_hijack/signal_hijack.c | 39 ++ + test/functest/test.sh | 336 ++++++++++++++++++ + test/functest/test_ltran/CMakeLists.txt | 20 ++ + .../test_ltran/config/config_example.conf | 14 + + test/functest/test_ltran/ltran_func_test.c | 195 ++++++++++ + 12 files changed, 1255 insertions(+) + create mode 100644 test/functest/CMakeLists.txt + create mode 100644 test/functest/common/common.c + create mode 100644 test/functest/common/common.h + create mode 100644 test/functest/common/uitls.c + create mode 100644 test/functest/common/utils.c + create mode 100644 test/functest/common/utils.h + create mode 100644 test/functest/signal_hijack/CMakeLists.txt + create mode 100644 test/functest/signal_hijack/signal_hijack.c + create mode 100644 test/functest/test.sh + create mode 100644 test/functest/test_ltran/CMakeLists.txt + create mode 100644 test/functest/test_ltran/config/config_example.conf + create mode 100644 test/functest/test_ltran/ltran_func_test.c + +diff --git a/test/functest/CMakeLists.txt b/test/functest/CMakeLists.txt +new file mode 100644 +index 0000000..ea42854 +--- /dev/null ++++ b/test/functest/CMakeLists.txt +@@ -0,0 +1,16 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++# gazelle is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++ ++cmake_minimum_required(VERSION 3.12.1) ++project(gazelle_integration_test) ++ ++add_subdirectory(signal_hijack) ++ ++add_subdirectory(test_ltran) +diff --git a/test/functest/common/common.c b/test/functest/common/common.c +new file mode 100644 +index 0000000..46f1647 +--- /dev/null ++++ b/test/functest/common/common.c +@@ -0,0 +1,248 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++ * gazelle is licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++// test header ++#include "utils.h" ++#include "common.h" ++ ++int check_if_socket_server_start_succeed(void) ++{ ++ int ret; ++ ret = check_if_process_exist("socket_server"); ++ if (ret != LIBOS_OK) { ++ return LIBOS_ERR; ++ } ++ ++ return LIBOS_OK; ++} ++ ++int check_if_socket_client_start_succeed(void) ++{ ++ int ret; ++ ret = check_if_process_exist("socket_client"); ++ if (ret != LIBOS_OK) { ++ return LIBOS_ERR; ++ } ++ ++ return LIBOS_OK; ++} ++ ++int check_if_socket_ltran_start_succeed(void) ++{ ++ int ret; ++ ++ ret = check_if_process_exist("socket_ltran"); ++ if (ret != LIBOS_OK) { ++ return LIBOS_ERR; ++ } ++ ++ return LIBOS_OK; ++} ++ ++ ++int check_if_process_start_succeed(const char* proces_name) ++{ ++ int ret; ++ ++ ret = check_if_process_exist(proces_name); ++ if (ret != LIBOS_OK) { ++ return LIBOS_ERR; ++ } ++ ++ return LIBOS_OK; ++} ++ ++int check_if_ltran_start_succeed(void) ++{ ++ int ret; ++ ++ ret = check_if_process_exist("ltran"); ++ if (ret != LIBOS_OK) { ++ return LIBOS_ERR; ++ } ++ ++ ret = check_if_file_contains(LTRAN_LOG_PATH, "Runing Process forward", LTRAN_START_TMOUT_S); ++ if (ret != LIBOS_OK) { ++ return LIBOS_ERR; ++ } ++ return LIBOS_OK; ++} ++ ++int check_if_ltran_quit_succeed(void) ++{ ++ char cmd[MAX_CMD_LEN]; ++ ++ FILE *fstream = NULL; ++ char *gets_ret = NULL; ++ char buf[MAX_CMD_RESULT_BUF_LEN]; ++ (void)memset_s(buf, MAX_CMD_RESULT_BUF_LEN, 0, MAX_CMD_RESULT_BUF_LEN); ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ ++ (void)sprintf_s(cmd, MAX_CMD_LEN, "ps aux | grep -w ltran | grep -v grep"); ++#ifdef LLT_DEBUG ++ printf("Executing cmd: %s\n", cmd); ++#endif ++ ++ fstream = popen(cmd, "r"); ++ if (fstream == NULL) { ++ return LIBOS_ERR; ++ } ++ ++ gets_ret = fgets(buf, MAX_CMD_RESULT_BUF_LEN, fstream); ++ if (gets_ret == NULL) { ++ pclose(fstream); ++ return LIBOS_OK; ++ } ++ ++ pclose(fstream); ++ return LIBOS_ERR; ++} ++ ++ ++int check_if_lstack_start_succeed(const char *server_name) ++{ ++ int ret; ++ ret = check_if_process_exist(server_name); ++ if (ret != LIBOS_OK) { ++ return LIBOS_ERR; ++ } ++ ++ // times for lstack online ++ sleep(LSTACK_START_TMOUT_S); ++ return LIBOS_OK; ++} ++ ++void test_benchmark_flow(char *ltran_start_cmd, char *server_start_cmd, char *client_start_cmd, const char *ltran_conf, ++ const char *lstack_conf) ++{ ++ int ret; ++ ++ char ip[MAX_IP_ADDR_LEN]; ++ CU_ASSERT(get_test_ip(lstack_conf, 0, ip, MAX_IP_ADDR_LEN) == LIBOS_OK); ++ ret = sprintf_s(ltran_start_cmd, MAX_CMD_LEN, "ltran --config-file %s > %s 2>&1 &", ltran_conf, LTRAN_LOG_PATH); ++ ret |= sprintf_s(server_start_cmd, MAX_CMD_LEN, "export LSTACK_CONF_PATH=%s;" ++ "GAZELLE_BIND_PROCNAME=benchmark_usr GAZELLE_BIND_THREADNAME=disp " ++ "stdbuf -oL /etc/gazelle/benchmark_usr -sMode dn -pSize 0 -mSize 1024 -pdSize 2 -cFile /etc/gazelle/config.ini" ++ " > %s 2>&1 &", lstack_conf, SOCKET_SERVER_LOG_PATH); ++ ret |= sprintf_s(client_start_cmd, MAX_CMD_LEN, "stdbuf -oL /etc/gazelle/benchmark_ker -sMode \ ++ client -mSize 1024 -tNums 5 -cNums 2 -cFile /etc/gazelle/config.ini > %s 2>&1 &", SOCKET_CLIENT_LOG_PATH); ++ CU_ASSERT(ret > 0); ++ ++ execute_cmd(ltran_start_cmd); ++ CU_ASSERT(check_if_ltran_start_succeed() == LIBOS_OK); ++ ++ execute_cmd(server_start_cmd); ++ ret = check_if_file_contains(SOCKET_SERVER_LOG_PATH, "Packet wrong rate", BENCHMARK_START_TMOUT_S); ++ CU_ASSERT(ret == LIBOS_OK); ++ ++ execute_cmd(client_start_cmd); ++ ret = check_if_file_contains(SOCKET_CLIENT_LOG_PATH, "Packet wrong rate", BENCHMARK_2WCONN_TMOUT_S); ++ CU_ASSERT(ret == LIBOS_OK); ++} ++ ++void test_preload_benchmark_flow_no_ltran(char *server_start_cmd, char *client_start_cmd, const char *lstack_conf) ++{ ++ int ret; ++ ++ ret = sprintf_s(server_start_cmd, MAX_CMD_LEN, "export LSTACK_CONF_PATH=%s;" ++ "GAZELLE_BIND_PROCNAME=benchmark_ker GAZELLE_BIND_THREADNAME=disp LD_PRELOAD=/lib64/liblstack.so " ++ "stdbuf -oL /etc/gazelle/benchmark_ker -sMode dn -pSize 0 -mSize 1024 -pdSize 2 -cFile /etc/gazelle/config.ini" ++ " > %s 2>&1 &", lstack_conf, SOCKET_SERVER_LOG_PATH); ++ ret |= sprintf_s(client_start_cmd, MAX_CMD_LEN, "stdbuf -oL /etc/gazelle/benchmark_ker -sMode " ++ "client -mSize 1024 -tNums 5 -cNums 2 -cFile /etc/gazelle/config.ini > %s 2>&1 &", SOCKET_CLIENT_LOG_PATH); ++ CU_ASSERT(ret > 0); ++ ++ execute_cmd(server_start_cmd); ++ ret = check_if_file_contains(SOCKET_SERVER_LOG_PATH, "Packet wrong rate", BENCHMARK_START_TMOUT_S); ++ CU_ASSERT(ret == LIBOS_OK); ++ ++ execute_cmd(client_start_cmd); ++ ret = check_if_file_contains(SOCKET_CLIENT_LOG_PATH, "Packet wrong rate", BENCHMARK_2WCONN_TMOUT_S); ++ CU_ASSERT(ret == LIBOS_OK); ++} ++ ++void test_preload_benchmark_flow(char *ltran_start_cmd, char *server_start_cmd, char *client_start_cmd, ++ const char *ltran_conf, const char *lstack_conf) ++{ ++ int ret; ++ ++ ret = sprintf_s(ltran_start_cmd, MAX_CMD_LEN, "ltran --config-file %s > %s 2>&1 &", ltran_conf, LTRAN_LOG_PATH); ++ CU_ASSERT(ret > 0); ++ ++ execute_cmd(ltran_start_cmd); ++ CU_ASSERT(check_if_ltran_start_succeed() == LIBOS_OK); ++ ++ test_preload_benchmark_flow_no_ltran(server_start_cmd, client_start_cmd, lstack_conf); ++} ++ ++void rm_log(void) ++{ ++ execute_cmd("rm -f /tmp/ltran.log > /dev/null"); ++ execute_cmd("rm -f /tmp/lstack.log > /dev/null"); ++ execute_cmd("rm -f /tmp/libnet_dfx.log > /dev/null"); ++ execute_cmd("rm -f /tmp/socket_server.log > /dev/null"); ++ execute_cmd("rm -f /tmp/socket_client.log > /dev/null"); ++} ++ ++void kill_ltran(void) ++{ ++ execute_cmd("killall -s TERM ltran > /dev/null 2>&1"); ++ for (;;) { ++ if (check_if_ltran_quit_succeed() == LIBOS_OK) { ++ break; ++ } ++ sleep(SLEPP_CYCLE_S); ++ } ++} ++ ++void kill_gazellectl(void) ++{ ++ execute_cmd("killall -s TERM gazellectl > /dev/null 2>&1"); ++} ++ ++void kill_lstack(void) ++{ ++ execute_cmd("killall -s TERM server_user1 > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM server_user2 > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM server_user3 > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM client_user1 > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM client_user2 > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM client_user3 > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM server_poll_user1 > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM server > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM client > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM benchmark_ker > /dev/null 2>&1"); ++ execute_cmd("killall -s TERM benchmark_usr > /dev/null 2>&1"); ++} ++ ++void reset_env(void) ++{ ++ kill_ltran(); ++ kill_gazellectl(); ++ kill_lstack(); ++ rm_log(); ++} +diff --git a/test/functest/common/common.h b/test/functest/common/common.h +new file mode 100644 +index 0000000..00fab9f +--- /dev/null ++++ b/test/functest/common/common.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++ * gazelle is licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef __COMMON_H__ ++#define __COMMON_H__ ++ ++#define LTRAN_START_TMOUT_S 5 ++#define LSTACK_START_TMOUT_S 2 ++#define LANTENCY_LOG_TMOUT_S 5 ++#define CAT_LOG_TMOUT_S 5 ++#define LSTACK_LOGOUT_TMOUT_S 10 ++#define BENCHMARK_START_TMOUT_S 10 ++#define BENCHMARK_2WCONN_TMOUT_S 20 ++ ++#define MAX_BOND_PORT_NUM 8 ++#define MAX_BOND_MAC_NUM 8 ++ ++#define MAX_PORT_MASK_LEN 64 ++#define MAX_MAC_LEN 64 ++#define MAX_IP_ADDR_LEN 64 ++#define MAX_FILE_PATH_LEN 128 ++ ++#define LTRAN_LOG_PATH "/tmp/ltran.log " ++#define LSTACK_LOG_PATH "/tmp/lstack.log" ++#define LIBNET_DFX_LOG_PATH "/tmp/libnet_dfx.log" ++#define CP_SOCK_FILE "cp.sock" ++ ++#define SOCKET_SERVER_LOG_PATH "/tmp/socket_server.log" ++#define SOCKET_CLIENT_LOG_PATH "/tmp/socket_client.log" ++ ++#define STUB_LSTACK_LIVE_TIME_S 3 ++ ++#define SERVERBIN_IP_OFFSET 1 ++#define KNI_IP_OFFSET 2 ++ ++void test_benchmark_flow(char *ltran_start_cmd, char *server_start_cmd, char *client_start_cmd, const char *ltran_conf, ++ const char *lstack_conf); ++void test_preload_benchmark_flow_no_ltran(char *server_start_cmd, char *client_start_cmd, const char *lstack_conf); ++void test_preload_benchmark_flow(char *ltran_start_cmd, char *server_start_cmd, char *client_start_cmd, ++ const char *ltran_conf, const char *lstack_conf); ++int check_if_process_start_succeed(const char* proces_name); ++int check_if_socket_server_start_succeed(void); ++int check_if_socket_client_start_succeed(void); ++int check_if_socket_ltran_start_succeed(void); ++int check_if_ltran_start_succeed(void); ++int check_if_lstack_start_succeed(const char *ip_addr); ++ ++ ++void rm_log(void); ++void kill_ltran(void); ++void ko_clean(void); ++void ko_init(void); ++ ++void kill_stub_lstack(void); ++ ++void reset_env(void); ++ ++ ++#endif +diff --git a/test/functest/common/uitls.c b/test/functest/common/uitls.c +new file mode 100644 +index 0000000..e69de29 +diff --git a/test/functest/common/utils.c b/test/functest/common/utils.c +new file mode 100644 +index 0000000..d74ddba +--- /dev/null ++++ b/test/functest/common/utils.c +@@ -0,0 +1,261 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++ * gazelle is licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "utils.h" ++ ++#define IP_ADD_STEP 0x1000000 ++/* input path must lstack.conf */ ++int get_test_ip(const char *path, int offset, char *ip, int ip_maxlen) ++{ ++ FILE *fstream = NULL; ++ char cmd[MAX_CMD_LEN] = {0}; ++ struct in_addr tmp_ip; ++ int ret; ++ ++ if (access(path, 0) < 0) { ++ printf("%s is not exit\n", path); ++ return -LIBOS_ERR; ++ } ++ ++ if (ip == NULL) { ++ printf("ip is NULL\n"); ++ return -LIBOS_ERR; ++ } ++ ++ ret = sprintf_s(cmd, MAX_CMD_LEN, "cat %s | grep host_addr= | awk -F '\"' '{print $2}'", path); ++ if (ret < 0) { ++ printf("sprintf_s err ret=%d\n", ret); ++ return -LIBOS_ERR; ++ } ++ ++ fstream = popen(cmd, "r"); ++ if (fstream == NULL) { ++ return -LIBOS_ERR; ++ } ++ ++ if (fgets(ip, ip_maxlen, fstream) == NULL) { ++ pclose(fstream); ++ return -LIBOS_ERR; ++ } ++ pclose(fstream); ++ ++ /* delete \n */ ++ int i = 0; ++ while (i < ip_maxlen && ip[i] != '\0') { ++ if (ip[i] == '\n') { ++ ip[i] = '\0'; ++ break; ++ } ++ i++; ++ } ++ ++ if (inet_pton(AF_INET, ip, &tmp_ip) > 0) { ++ tmp_ip.s_addr += offset * IP_ADD_STEP; ++ if (inet_ntop(AF_INET, &tmp_ip, ip, ip_maxlen)) { ++ return LIBOS_OK; ++ } ++ } ++ ++ return -LIBOS_ERR; ++} ++void execute_cmd(const char *cmd) ++{ ++ int ret; ++#ifdef LLT_DEBUG ++ printf("Executing cmd: %s\n", cmd); ++#endif ++ ret = system(cmd); ++ if (ret < 0) { ++ printf("Executing cmd: %s error!!!\n", cmd); ++ abort(); ++ } ++ return; ++} ++ ++int check_cmd_ret(const char* cmd) ++{ ++ FILE *fstream = NULL; ++ char *gets_ret = NULL; ++ char buf[MAX_CMD_RESULT_BUF_LEN]; ++ (void)memset_s(buf, MAX_CMD_RESULT_BUF_LEN, 0, MAX_CMD_RESULT_BUF_LEN); ++ ++ fstream = popen(cmd, "r"); ++ if (fstream == NULL) { ++ return LIBOS_ERR; ++ } ++ ++ gets_ret = fgets(buf, MAX_CMD_RESULT_BUF_LEN, fstream); ++ if (gets_ret != NULL) { ++ pclose(fstream); ++ return LIBOS_OK; ++ } ++ ++ pclose(fstream); ++ system(cmd); ++ return LIBOS_ERR; ++} ++ ++int check_if_cmd_ret_contains(const char *exec_cmd, const char *expect_ret) ++{ ++ int ret; ++ char cmd[MAX_CMD_LEN]; ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ ++ ret = sprintf_s(cmd, MAX_CMD_LEN, "%s | grep \"%s\"", exec_cmd, expect_ret); ++ if (ret < 0) { ++ return LIBOS_ERR; ++ } ++#ifdef LLT_DEBUG ++ printf("Executing cmd: %s\n", cmd); ++#endif ++ return check_cmd_ret(cmd); ++} ++ ++static int check_cmd_contains(const char *subcmd, const char *expect_str, const unsigned int timeout_s) ++{ ++ char cmd[MAX_CMD_LEN]; ++ unsigned int time_s = 0; ++ int ret; ++ ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ ++ ret = sprintf_s(cmd, MAX_CMD_LEN, "%s | grep --text \"%s\"", subcmd, expect_str); ++ if (ret < 0) { ++ return LIBOS_ERR; ++ } ++ while (time_s < timeout_s) { ++ sleep(SLEPP_CYCLE_S); ++ time_s += SLEPP_CYCLE_S; ++ ++#ifdef LLT_DEBUG ++ printf("Executing cmd: %s\n", cmd); ++#endif ++ ret = check_cmd_ret(cmd); ++ if (ret == LIBOS_OK) { ++ return LIBOS_OK; ++ } ++ } ++ system(subcmd); ++ return LIBOS_ERR; ++} ++ ++int check_cpu_uasge(const char *file_path) ++{ ++ int ret; ++ int usage_integer; ++ int usage_float; ++ ++ FILE *fstream = NULL; ++ fstream = fopen(file_path, "r"); ++ if (fstream == NULL) { ++ return LIBOS_ERR; ++ } ++ ++ ret = fscanf_s(fstream, "%d.%d", &usage_integer, &usage_float); ++ if (ret < 1) { ++ pclose(fstream); ++ return LIBOS_ERR; ++ } ++ ++ ret = LIBOS_OK; ++ if (usage_integer > 40) { /* when low power mode is on, cpu usage should below 40% */ ++ ret = LIBOS_ERR; ++ } ++ pclose(fstream); ++ return ret; ++} ++ ++int check_journalctl_contains(const char *expect_str, const unsigned int timeout_s) ++{ ++ return check_cmd_contains("journalctl", expect_str, timeout_s); ++} ++ ++int check_if_file_contains(const char *filepath, const char *expect_str, const unsigned int timeout_s) ++{ ++ char cmd[MAX_CMD_LEN] = {0}; ++ int ret = sprintf_s(cmd, MAX_CMD_LEN, "cat %s", filepath); ++ if (ret < 0) { ++ return LIBOS_ERR; ++ } ++ ++ return check_cmd_contains(cmd, expect_str, timeout_s); ++} ++ ++int check_if_process_exist(const char *process_name) ++{ ++ char cmd[MAX_CMD_LEN]; ++ int ret; ++ ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ ++ ret = sprintf_s(cmd, MAX_CMD_LEN, "pidof %s", process_name); ++ if (ret < 0) { ++ return LIBOS_ERR; ++ } ++#ifdef LLT_DEBUG ++ printf("Executing cmd: %s\n", cmd); ++#endif ++ ++ return check_cmd_ret(cmd); ++} ++ ++void create_dir(const char *dir_path) ++{ ++ char cmd[MAX_CMD_LEN]; ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ int ret = sprintf_s(cmd, MAX_CMD_LEN, "mkdir -p %s", dir_path); ++ if (ret < 0) { ++ return; ++ } ++ execute_cmd(cmd); ++} ++ ++void remove_dir(const char *dir_path) ++{ ++ char cmd[MAX_CMD_LEN]; ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ int ret = sprintf_s(cmd, MAX_CMD_LEN, "rm -rf %s", dir_path); ++ if (ret < 0) { ++ return; ++ } ++ execute_cmd(cmd); ++} ++ ++void create_file(const char *file_path) ++{ ++ char cmd[MAX_CMD_LEN]; ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ int ret = sprintf_s(cmd, MAX_CMD_LEN, "touch %s", file_path); ++ if (ret < 0) { ++ return; ++ } ++ execute_cmd(cmd); ++} ++ ++void remove_file(const char *file_path) ++{ ++ char cmd[MAX_CMD_LEN]; ++ (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); ++ int ret = sprintf_s(cmd, MAX_CMD_LEN, "rm -f %s", file_path); ++ if (ret < 0) { ++ return; ++ } ++ execute_cmd(cmd); ++} +diff --git a/test/functest/common/utils.h b/test/functest/common/utils.h +new file mode 100644 +index 0000000..f11e04b +--- /dev/null ++++ b/test/functest/common/utils.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++ * gazelle is licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef __UTILS_H__ ++#define __UTILS_H__ ++ ++#define LIBOS_OK 0 ++#define LIBOS_ERR 1 ++ ++#define LIBOS_TRUE 1 ++#define LIBOS_FALSE 0 ++ ++#define MAX_TESTCASE_NAME_LEN 128 ++#define MAX_CMD_RESULT_BUF_LEN 1024 ++#define SLEPP_CYCLE_S 1 ++#define MAX_CMD_LEN 512 ++#define MAX_PATH_LEN 256 ++ ++void execute_cmd(const char *cmd); ++ ++int check_if_cmd_ret_contains(const char *exec_cmd, const char *expect_ret); ++int check_journalctl_contains(const char *expect_ret, const unsigned int timeout_s); ++int check_if_file_contains(const char *file_path, const char *expect_str, const unsigned int timeout_s); ++int check_if_process_exist(const char *process_name); ++int check_cpu_uasge(const char *file_path); ++ ++void create_dir(const char *dir_path); ++void remove_dir(const char *dir_path); ++void create_file(const char *file_path); ++void remove_file(const char *file_path); ++int get_test_ip(const char *path, int offset, char *ip, int ip_maxlen); ++ ++#endif +diff --git a/test/functest/signal_hijack/CMakeLists.txt b/test/functest/signal_hijack/CMakeLists.txt +new file mode 100644 +index 0000000..0921060 +--- /dev/null ++++ b/test/functest/signal_hijack/CMakeLists.txt +@@ -0,0 +1,16 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++# gazelle is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++ ++cmake_minimum_required(VERSION 3.12.1) ++project(gazelle_func_test) ++ ++set(LIBRARY_OUTPUT_PATH ../) ++ ++add_library(signal_hijack SHARED signal_hijack.c) +diff --git a/test/functest/signal_hijack/signal_hijack.c b/test/functest/signal_hijack/signal_hijack.c +new file mode 100644 +index 0000000..cfb82a3 +--- /dev/null ++++ b/test/functest/signal_hijack/signal_hijack.c +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. ++ * gazelle is licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#include ++#include ++#include ++ ++void signal_handler(int signo) ++{ ++ exit(signo); ++} ++ ++__attribute__((constructor)) void signal_reg(void) ++{ ++ int sigs[] = { ++ SIGILL, SIGFPE, SIGABRT, SIGBUS, ++ SIGSEGV, SIGHUP, SIGINT, SIGQUIT, ++ SIGTERM ++ }; ++ int i; ++ struct sigaction sa; ++ sa.sa_handler = signal_handler; ++ sigemptyset(&sa.sa_mask); ++ sa.sa_flags = SA_RESETHAND; ++ for (i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++) { ++ if (sigaction(sigs[i], &sa, NULL) == -1) { ++ perror("Could not set signal handler"); ++ } ++ } ++} +diff --git a/test/functest/test.sh b/test/functest/test.sh +new file mode 100644 +index 0000000..fe8c424 +--- /dev/null ++++ b/test/functest/test.sh +@@ -0,0 +1,336 @@ ++#! /bin/bash ++ ++#set -xe ++ ++usage() ++{ ++ echo "Usage: sh test.sh [OPTIONS]" ++ echo "Use test.sh to control integration test operation" ++ echo ++ echo "Misc:" ++ echo " -h, --help Print this help, then exit" ++ echo ++ echo "Compile Options:" ++ echo " -m, --cmake