gazelle/0188-add-fucntest.patch
jiangheng12 8bff98f9e5 sync change mbuf_pool_size in lstack.conf to tcp_conn_count * mbuf_count_per_conn
(cherry picked from commit eceb1d603660efbdb92f836432639370c3fca9ac)
2023-02-13 21:50:43 +08:00

1360 lines
42 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 502e0241ea1d6f1ffe01fbfe8272fb90003c3327 Mon Sep 17 00:00:00 2001
From: jiangheng12 <jiangheng14@huawei.com>
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 <CUnit/Basic.h>
+#include <stdlib.h>
+#include <CUnit/Console.h>
+#include <CUnit/Automated.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <string.h>
+#include <securec.h>
+
+// 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <securec.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#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 <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+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 <option> use cmake genenate Makefile, eg: -m(default), -mcoverage, --cmake, --cmake=coverage"
+ echo " -c, --compile Enable compile"
+ echo " -e, --empty Enable compile empty(make clean)"
+ echo
+ echo "TestRun Options"
+ echo " -r, --run-test <option> Run all test, eg: -r, -rscreen(default), -rxml, --run-test, --run-test=screen, --run-test=xml"
+ echo " -s, --specify-test FILE Only Run specify test executable FILE, eg: -smain_test, --specify-test=main_test"
+ echo
+ echo "Coverage Options"
+ echo " -t, --cover-report <option> Enable coverage report. eg: -t, -thtml(default), -ttxt, --cover-report, --cover-report=html, --cover-report=txt"
+ echo " -f, --cover-file FILE Specified FILE coverage report, eg: -fmain.c, --cover-file=main.c"
+ echo
+ echo "IP Options"
+ echo " -i, --ip <option> Modify default ip. eg: -i, -i 192.168.1.8(default), --ip, --ip=192.168.1.8"
+ echo
+}
+
+ARGS=`getopt -o "hcer::m::t::s:f:i:" -l "help,cmake::,empty,cover-report::,run-test::,specify-test:,cover-file:,ip:" -n "test.sh" -- "$@"`
+if [ $? != 0 ]; then
+ usage
+ exit 1
+fi
+
+eval set -- "${ARGS}"
+
+if [ x"$ARGS" = x" --" ]; then
+ #set default value
+ COMPILE_ENABLE=no
+ COVERAGE_ENABLE=no
+ ASAN_ENABLE=no
+ EMPTY_ENABLE=no
+ RUN_TEST=yes
+ RUN_MODE=screen #value: screen or xml
+ COVER_REPORT_ENABLE=no
+ MODIFY_DEFAULT_IP=no
+fi
+
+while true; do
+ case "${1}" in
+ -h|--help)
+ usage; exit 0;;
+ -m|--cmake)
+ CMAKE_ENABLE=yes
+ case "$2" in
+ "") shift 2;;
+ coverage) COVERAGE_ENABLE=yes; shift 2;;
+ asan) ASAN_ENABLE=yes; shift 2;;
+ *) echo "Error param: $2"; exit 1;;
+ esac;;
+ -c|--compile)
+ COMPILE_ENABLE=yes
+ shift;;
+ -e|--empty)
+ EMPTY_ENABLE=yes
+ shift;;
+ -r|--run-test)
+ RUN_TEST=yes
+ case "$2" in
+ "") RUN_MODE=screen; shift 2;;
+ screen) RUN_MODE=screen; shift 2;;
+ xml) RUN_MODE=xml; shift 2;;
+ *)echo "Error param: $2"; exit 1;;
+ esac;;
+ -t|--cover-report)
+ COVER_REPORT_ENABLE=yes
+ case "$2" in
+ "") COVER_STYLE=html;shift 2;;
+ html) COVER_STYLE=html;shift 2;;
+ txt) COVER_STYLE=txt;shift 2;;
+ *)echo "Error param: $2"; exit 1;;
+ esac;;
+ -s|--specify-test)
+ SPECIFY_TEST=$2
+ shift 2;;
+ -f|--cover-file)
+ COVER_FILE=$2
+ shift 2;;
+ -i|--ip)
+ MODIFY_DEFAULT_IP=yes
+ TEST_IP=$2
+ shift 2;;
+ --)
+ shift; break;;
+ esac
+done
+
+function modify_test_ip()
+{
+ echo ---------------------- test modify test ip begin ----------------------
+ set -x
+ sed -i "/host_addr=/chost_addr=\"${TEST_IP}\"" /etc/gazelle/lstack.conf
+ sed -i "/host_addr=/chost_addr=\"${TEST_IP}\"" test_gazellectl/config/lstack.conf
+ sed -i "/host_addr=/chost_addr=\"${TEST_IP}\"" test_lstack/config/lstack.conf
+ sed -i "/host_addr=/chost_addr=\"${TEST_IP}\"" test_wrap/config/lstack.conf
+ sed -i "/^CnHostName=/cCnHostName=${TEST_IP}" /etc/gazelle/config.ini
+ set +x
+ echo ---------------------- test modify test ip end ------------------------
+}
+
+function test_empty()
+{
+ echo ---------------------- test empty begin ----------------------
+ set -x
+ echo "remove directory build"
+ rm -rf build
+ set +x
+ echo ---------------------- test empty end ------------------------
+}
+
+function test_cmake()
+{
+ local CMAKE_OPTION="-DCMAKE_BUILD_TYPE=Debug"
+
+ echo ---------------------- test cmake begin ----------------------
+ if [ ! -d "/opt/libos" ]; then
+ mkdir /opt/libos
+ fi
+ if [ ! -d "build" ]; then
+ mkdir build
+ fi
+ chmod 755 build
+ cd build
+
+ if [ x"${COVERAGE_ENABLE}" = x"yes" ]; then
+ CMAKE_OPTION="${CMAKE_OPTION} -DCOVERAGE_ENABLE=1"
+ fi
+
+ if [ x"${ASAN_ENABLE}" = x"yes" ]; then
+ CMAKE_OPTION="${CMAKE_OPTION} -DASAN_ENABLE=1"
+ fi
+
+ cmake .. ${CMAKE_OPTION}
+ cd -
+ echo ---------------------- test cmake end ------------------------
+ echo
+}
+
+function test_compile()
+{
+ echo ---------------------- test compile begin ----------------------
+ # compile gazelle coverage version
+ cur_dir=`pwd`
+ cd ../../
+ export GAZELLE_COVERAGE_ENABLE=1
+ cp -fr src/ltran/main.c src/ltran/main.bak
+ cp -fr src/lstack/api/lstack_signal.c src/lstack/api/lstack_signal.bak
+ cp -fr src/ltran/ltran_forward.c src/ltran/ltran_forward.bak
+ sed -i 's/__rte_always_inline/ /g' src/ltran/ltran_forward.c
+ sed -i '/kill/cexit(0);' src/ltran/main.c
+ sed -i '/kill/cexit(0);' src/lstack/api/lstack_signal.c
+ rm -fr /lib64/liblstack.* /usr/bin/gazellectl /usr/bin/ltran
+ cd build
+ sh build.sh
+ cd -
+ cp -fr src/ltran/main.bak src/ltran/main.c
+ cp -fr src/lstack/api/lstack_signal.bak src/lstack/api/lstack_signal.c
+ # install gazelle coverage version
+ install -Dpm 0755 src/lstack/liblstack.* /lib64/
+ install -Dpm 0644 src/lstack/lstack.Makefile /etc/gazelle
+ install -Dpm 0644 src/lstack/lstack.conf /etc/gazelle
+
+ install -Dpm 0755 src/ltran/gazellectl /usr/bin
+ install -Dpm 0755 src/ltran/ltran /usr/bin
+ install -Dpm 0644 src/ltran/ltran.conf /etc/gazelle
+ unset GAZELLE_COVERAGE_ENABLE
+ mv src/ltran/main.bak src/ltran/main.c
+ mv src/lstack/api/lstack_signal.bak src/lstack/api/lstack_signal.c
+ mv src/ltran/ltran_forward.bak src/ltran/ltran_forward.c
+ cd $cur_dir
+
+ # compile gazelle test cases
+ cd build
+ make -j
+ cd -
+
+ echo ---------------------- test compile end ------------------------
+ echo
+}
+
+function test_run_all_test()
+{
+ ret=1
+ echo ---------------------- test run begin --------------------------
+ if [ x"${RUN_MODE}" = x"screen" ]; then
+ RUN_MODE=0
+ elif [ x"${RUN_MODE}" = x"xml" ]; then
+ RUN_MODE=1
+ elif [ x"${RUN_MODE}" = x"" ]; then
+ RUN_MODE=0
+ else
+ echo "not suport run mode <${RUN_MODE}>"
+ usage
+ exit 1
+ fi
+
+ cd build
+ if [ x"${SPECIFY_TEST}" = x"" ]; then
+ SPECIFY_TEST=`find -name "*_test"` # run all test
+ else
+ SPECIFY_TEST=`find -name "${SPECIFY_TEST}"`
+ fi
+
+ export LD_LIBRARY_PATH=`pwd`
+ export LD_PRELOAD=libsignal_hijack.so
+
+ TEST_LOG=test_result.log
+ >$TEST_LOG
+
+ for TEST in $SPECIFY_TEST; do
+ echo $TEST
+ $TEST $RUN_MODE
+ if [ $? != 0 ];then
+ echo $TEST FAILED >> $TEST_LOG
+ ret=1
+ else
+ echo $TEST success >> $TEST_LOG
+ ret=0
+ fi
+ done
+ echo ""
+ echo '######################test result begin######################'
+ cat $TEST_LOG
+ echo '#######################test result end#######################'
+ echo ""
+
+ unset LD_LIBRARY_PATH
+ unset LD_PRELOAD
+ cd -
+ echo ---------------------- test run end --------------------------
+ return $ret
+}
+
+function test_coverage()
+{
+ echo ------------------ test generate coverage begin --------------
+ cd build
+
+ if [ x"${COVER_STYLE}" = x"txt" ]; then
+ GCDAS=`find -name "${COVER_FILE}.gcda"`
+ if [ x"$GCDAS" = x"" ]; then
+ echo "not find ${COVER_FILE}.gcda"
+ echo
+ exit 1
+ fi
+
+ for GCDA in $GCDAS; do
+ gcov $GCDA
+ done
+
+ find -name "*.h.gcov" | xargs rm -f
+ echo '#################################'
+ find -name "${COVER_FILE}.gcov"
+ echo '#################################'
+ elif [ x"${COVER_STYLE}" = x"html" ]; then
+ if [ -d coverage ]; then
+ rm -rf coverage
+ fi
+ mkdir coverage
+ if [ x"${COVER_FILE}" = x"" ]; then
+ LCOV_CMD="-d ./"
+ else
+ GCDAS=`find -name "${COVER_FILE}.gcda"`
+ if [ $? != 0 ]; then
+ echo "not match ${COVER_FILE}.gcda"
+ exit 1
+ fi
+
+ for GCDA in ${GCDAS}; do
+ TMP_STR=" -d ${GCDA}";
+ LCOV_CMD="${LCOV_CMD} ${TMP_STR}";
+ done
+ fi
+
+ lcov -c -d ../../../src/ -o coverage/coverage.info --exclude "/usr/*" --exclude "*dpdk*" --rc lcov_branch_coverage=1 --ignore-errors gcov --ignore-errors source --ignore-errors graph
+ if [ $? != 0 ]; then
+ echo "lcov generate coverage.info fail."
+ exit 1
+ fi
+
+ genhtml coverage/coverage.info -o coverage/html --branch-coverage --rc lcov_branch_coverage=1 -s --legend --ignore-errors source
+ if [ $? != 0 ]; then
+ echo "genhtml fail."
+ exit 1
+ fi
+ chmod 755 -R coverage
+ fi
+ cd -
+ echo ------------------ test generate coverage end ----------------
+}
+
+exit_ret=0
+
+starttime=`date +'%Y-%m-%d %H:%M:%S'`
+if [ x"${EMPTY_ENABLE}" = x"yes" ]; then
+ test_empty
+fi
+
+if [ x"${CMAKE_ENABLE}" = x"yes" ]; then
+ test_cmake
+fi
+
+if [ x"${COMPILE_ENABLE}" = x"yes" ]; then
+ test_compile
+fi
+
+if [ x"${MODIFY_DEFAULT_IP}" = x"yes" ]; then
+ modify_test_ip
+fi
+
+if [ x"${RUN_TEST}" = x"yes" ]; then
+ test_run_all_test
+ exit_val=$?
+fi
+
+if [ x"${COVER_REPORT_ENABLE}" = x"yes" ]; then
+ test_coverage
+fi
+endtime=`date +'%Y-%m-%d %H:%M:%S'`
+start_seconds=$(date --date="$starttime" +%s);
+end_seconds=$(date --date="$endtime" +%s);
+echo "Running time "$((end_seconds-start_seconds))"s"
+exit $exit_val
+#set +x
diff --git a/test/functest/test_ltran/CMakeLists.txt b/test/functest/test_ltran/CMakeLists.txt
new file mode 100644
index 0000000..198baeb
--- /dev/null
+++ b/test/functest/test_ltran/CMakeLists.txt
@@ -0,0 +1,20 @@
+# 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)
+
+INCLUDE_DIRECTORIES(../common)
+set(LIB_PATH ${PROJECT_SOURCE_DIR}/../common)
+set(EXECUTABLE_OTPUT_PATH ../)
+
+add_executable(ltran_func_test ltran_func_test.c ${LIB_PATH}/common.c ${LIB_PATH}/utils.c)
+target_include_directories(ltran_func_test PRIVATE ${LIB_PATH})
+target_link_libraries(ltran_func_test PRIVATE cunit securec)
diff --git a/test/functest/test_ltran/config/config_example.conf b/test/functest/test_ltran/config/config_example.conf
new file mode 100644
index 0000000..d83034c
--- /dev/null
+++ b/test/functest/test_ltran/config/config_example.conf
@@ -0,0 +1,14 @@
+forward_kit = "dpdk"
+forward_kit_args = "-l 0,1 --socket-mem 100,0,0,0 --huge-dir /mnt/hugepages --proc-type primary"
+kni_switch = 1
+
+dispatch_subnet = "192.168.1.0"
+dispatch_subnet_length = 8
+dispatch_max_clients = 30
+
+bond_mode = 1
+bond_miimon = 100
+bond_mtu = 1500
+bond_ports = "0x1"
+bond_macs = "52:54:00:13:68:88"
+
diff --git a/test/functest/test_ltran/ltran_func_test.c b/test/functest/test_ltran/ltran_func_test.c
new file mode 100644
index 0000000..d200cd2
--- /dev/null
+++ b/test/functest/test_ltran/ltran_func_test.c
@@ -0,0 +1,195 @@
+/*
+ * 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 <stdlib.h>
+#include <CUnit/Basic.h>
+#include <CUnit/Automated.h>
+#include <CUnit/Console.h>
+#include <unistd.h>
+#include <securec.h>
+
+#include "utils.h"
+#include "common.h"
+
+typedef enum {
+ LTRANFUNC_SCREEN = 0,
+ LTRANFUNC_XMLFILE,
+ LTRANFUNC_CONSOLE
+} CU_RunMode;
+
+static void restore_tmp_config(void)
+{
+ execute_cmd("rm -rf ../test_ltran/config/config_tmp.conf");
+ execute_cmd("cp -f ../test_ltran/config/config_example.conf ../test_ltran/config/config_tmp. conf");
+}
+
+static void test_ltran_sys_log_switch(void)
+{
+ char cmd[MAX_CMD_LEN];
+ int ret;
+
+ // 配置log开关
+ restore_tmp_config();
+ execute_cmd("sed -i 's/map-perfect/map-perfect --syslog daemon/' ../test_ltran/config/confi g_tmp.conf;"
+ "rm -fr /var/log/messages");
+ ret = sprintf_s(cmd, MAX_CMD_LEN, "stdbuf -oL ltran --config-file ../test_ltran/config/confi g_tmp.conf"
+ " > %s 2>&1 &", LTRAN_LOG_PATH);
+ CU_ASSERT(ret > 0);
+
+ reset_env();
+ execute_cmd(cmd);
+ ret = check_journalctl_contains("Runing Process forward", LANTENCY_LOG_TMOUT_S);
+ CU_ASSERT(ret == LIBOS_OK);
+ restore_tmp_config();
+ reset_env();
+}
+
+static void test_ltran_cmd_short_help(void)
+{
+ char cmd[MAX_CMD_LEN];
+ // 检验命令行-h参数
+ int ret = sprintf_s(cmd, MAX_CMD_LEN, "ltran -h > %s 2>&1 &", LTRAN_LOG_PATH);
+ CU_ASSERT(ret > 0);
+
+ execute_cmd(cmd);
+ // 期望提示ltran使用方法
+ ret = check_if_file_contains(LTRAN_LOG_PATH, "Usage:", CAT_LOG_TMOUT_S);
+ CU_ASSERT(ret == LIBOS_OK);
+}
+
+static void test_ltran_cmd_long_help(void)
+{
+ char cmd[MAX_CMD_LEN];
+ // 检验命令行-h参数
+ int ret = sprintf_s(cmd, MAX_CMD_LEN, "ltran --help > %s 2>&1 &", LTRAN_LOG_PATH);
+ CU_ASSERT(ret > 0);
+
+ execute_cmd(cmd);
+ // 期望提示ltran使用方法
+ ret = check_if_file_contains(LTRAN_LOG_PATH, "Usage:", CAT_LOG_TMOUT_S);
+ CU_ASSERT(ret == LIBOS_OK);
+}
+
+static void test_ltran_cmd_short_version(void)
+{
+ char cmd[MAX_CMD_LEN];
+ // 检验命令行-h参数
+ int ret = sprintf_s(cmd, MAX_CMD_LEN, "ltran -v > %s 2>&1 &", LTRAN_LOG_PATH);
+ CU_ASSERT(ret > 0);
+
+ execute_cmd(cmd);
+ // 期望提示ltran使用方法
+ ret = check_if_file_contains(LTRAN_LOG_PATH, "version:", CAT_LOG_TMOUT_S);
+ CU_ASSERT(ret == LIBOS_OK);
+}
+
+static void test_ltran_cmd_long_version(void)
+{
+ char cmd[MAX_CMD_LEN];
+ // 检验命令行-h参数
+ int ret = sprintf_s(cmd, MAX_CMD_LEN, "ltran --version > %s 2>&1 &", LTRAN_LOG_PATH);
+ CU_ASSERT(ret > 0);
+
+ execute_cmd(cmd);
+ // 期望提示ltran使用方法
+ ret = check_if_file_contains(LTRAN_LOG_PATH, "version:", CAT_LOG_TMOUT_S);
+ CU_ASSERT(ret == LIBOS_OK);
+}
+
+static void test_ltran_start_default_config_file(void)
+{
+ char cmd[MAX_CMD_LEN];
+ // 使用默认config_file, 且config_file文件存在
+ execute_cmd("mkdir -p /etc/gazelle");
+ execute_cmd("rm -rf /etc/gazelle/ltran.conf");
+ execute_cmd("cp -rf ../test_ltran/config/config_example.conf /etc/gazelle/ltran.conf");
+ int ret = sprintf_s(cmd, MAX_CMD_LEN, "stdbuf -oL nohup ltran > %s 2>&1 &", LTRAN_LOG_PATH);
+ CU_ASSERT(ret > 0);
+
+ reset_env();
+ execute_cmd(cmd);
+ // 期望启动成功
+ CU_ASSERT(check_if_ltran_start_succeed() == LIBOS_OK);
+ reset_env();
+}
+
+static void test_ltran_start_none_config_file(void)
+{
+ char cmd[MAX_CMD_LEN];
+ // 使用默认config_file但是config_file文件不存在
+ execute_cmd("rm -rf /etc/gazelle/ltran.conf");
+ int ret = sprintf_s(cmd, MAX_CMD_LEN, "ltran > %s 2>&1 &", LTRAN_LOG_PATH);
+ CU_ASSERT(ret > 0);
+
+ reset_env();
+ execute_cmd(cmd);
+ // 期望启动失败
+ CU_ASSERT(check_if_ltran_start_succeed() == LIBOS_ERR);
+ reset_env();
+}
+
+static void suite_ltran_subset_001(CU_pSuite suite)
+{
+ (void)CU_ADD_TEST(suite, test_ltran_cmd_short_help);
+ (void)CU_ADD_TEST(suite, test_ltran_cmd_long_help);
+ (void)CU_ADD_TEST(suite, test_ltran_cmd_short_version);
+ (void)CU_ADD_TEST(suite, test_ltran_cmd_long_version);
+ (void)CU_ADD_TEST(suite, test_ltran_start_default_config_file);
+ (void)CU_ADD_TEST(suite, test_ltran_start_none_config_file);
+ (void)CU_ADD_TEST(suite, test_ltran_sys_log_switch);
+}
+
+int main(int argc, char **argv)
+{
+ CU_pSuite suite;
+ unsigned int num_failures;
+ CU_RunMode g_cunit_mode = LTRANFUNC_SCREEN;
+
+ if (argc > 1) {
+ g_cunit_mode = atoi(argv[1]);
+ }
+
+ if (CU_initialize_registry() != CUE_SUCCESS) {
+ return CU_get_error();
+ }
+
+ suite = CU_add_suite("test_ltran", NULL, NULL);
+ if (suite == NULL) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ suite_ltran_subset_001(suite);
+
+ switch (g_cunit_mode) {
+ case LTRANFUNC_SCREEN:
+ CU_basic_set_mode(CU_BRM_VERBOSE);
+ CU_basic_run_tests();
+ break;
+ case LTRANFUNC_XMLFILE:
+ CU_set_output_filename("test_ltran");
+ CU_list_tests_to_file();
+ CU_automated_run_tests();
+ break;
+ case LTRANFUNC_CONSOLE:
+ CU_console_run_tests();
+ break;
+ default:
+ (void)printf("not suport mode, only suport: 0 or 1\n");
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ num_failures = CU_get_number_of_failures();
+ CU_cleanup_registry();
+ return num_failures;
+}
--
2.23.0