From d37c0c7ded0e107167a98dc1eda2000142d274f0 Mon Sep 17 00:00:00 2001
From: zhongtao <zhongtao17@huawei.com>
Date: Tue, 7 Nov 2023 16:39:50 +0800
Subject: [PATCH 12/14] add runc attach implement unit test and ci test

Signed-off-by: zhongtao <zhongtao17@huawei.com>
---
 CI/test_cases/container_cases/attach.sh     | 153 ++++++++++++++++++++
 CI/test_cases/container_cases/cri_stream.sh |   6 +-
 test/cmd/isulad-shim/common/common_ut.cc    |  42 ++++++
 3 files changed, 197 insertions(+), 4 deletions(-)
 create mode 100755 CI/test_cases/container_cases/attach.sh

diff --git a/CI/test_cases/container_cases/attach.sh b/CI/test_cases/container_cases/attach.sh
new file mode 100755
index 00000000..0d362757
--- /dev/null
+++ b/CI/test_cases/container_cases/attach.sh
@@ -0,0 +1,153 @@
+#!/bin/bash
+#
+# attributes: isula attach test
+# concurrent: NA
+# spend time: 5
+
+#######################################################################
+##- Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
+# - iSulad 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.
+##- @Description:CI
+##- @Author: zhongtao
+##- @Create: 2023-11-06
+#######################################################################
+
+declare -r curr_path=$(dirname $(readlink -f "$0"))
+source ../helpers.sh
+
+# $1 : retry limit
+# $2 : retry_interval
+# $3 : retry function
+function do_retry()
+{
+    for i in $(seq 1 "$1"); do
+        $3 $4 $5
+        if [ $? -ne 0 ]; then
+            return 0
+        fi
+        sleep $2
+    done
+    return 1
+}
+
+function get_ioCopy()
+{
+    ps -T -p $(cat /var/run/isulad.pid) | grep IoCopy
+    return $?
+}
+
+function inspect_container_status()
+{
+    [[ $(isula inspect -f '{{.State.Status}}' ${1}) != "${2}" ]]
+    return $?
+}
+
+function set_up()
+{
+    local ret=0
+    local runtime=$1
+
+    isula run -tid --name test --runtime $runtime busybox sh
+    [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run container with image: ${image}" && ((ret++))
+    
+    msg_info "${test} finished with return ${ret}..."
+    return ${ret}
+}
+
+function test_attach_fun()
+{
+    local ret=0
+    local retry_limit=20
+    local retry_interval=1
+    container_name="test"
+    local test="test_attach_fun => (${FUNCNAME[@]})"
+
+    msg_info "${test} starting..."
+
+    expect <<-END
+spawn isula attach test
+send \n
+expect "*"
+sleep 1
+send "ls \r"
+expect "*"
+send "exit \r"
+expect "*"
+sleep 2
+expect eof
+END
+    [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to attach container test" && ((ret++))
+
+    count=$(isula logs test | grep ls | wc -l)
+    [[ $count -ne 1 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to do attach" && ((ret++))
+
+    do_retry ${retry_limit} ${retry_interval} inspect_container_status  ${container_name} exited
+    [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} -  incorrent container status: not Exited" && ((ret++))
+
+    (isula attach test > /tmp/test_attach1.log 2>&1) &
+    sleep 2
+    cat /tmp/test_attach1.log | grep "You cannot attach to a stopped container, start it first"
+    [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to do attach, except fail" && ((ret++))
+
+    rm -rf /tmp/test_attach1.log
+
+    do_retry ${retry_limit} ${retry_interval} get_ioCopy
+    [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - residual IO copy thread in CRI exec operation" && ((ret++))
+
+    msg_info "${test} finished with return ${ret}..."
+    return ${ret}
+}
+
+function tear_down()
+{
+    local ret=0
+
+    isula rm -f test
+    [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to rm container: test" && ((ret++))
+
+    return ${ret}
+}
+
+function do_test_t()
+{
+    local ret=0
+    local runtime=$1
+    local test="basic attach test => (${runtime})"
+    msg_info "${test} starting..."
+
+    set_up $runtime || ((ret++))
+
+    test_attach_fun  || ((ret++))
+
+    tear_down || ((ret++))
+
+    msg_info "${test} finished with return ${ret}..."
+
+    return $ret
+}
+
+ret=0
+
+isula pull busybox
+[[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE}
+
+isula images | grep busybox
+[[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - missing list image: ${image}" && ((ret++))
+
+for element in ${RUNTIME_LIST[@]};
+do
+    do_test_t $element
+    if [ $? -ne 0 ];then
+        let "ret=$ret + 1"
+    fi
+done
+
+show_result $ret "basic attach"
+
diff --git a/CI/test_cases/container_cases/cri_stream.sh b/CI/test_cases/container_cases/cri_stream.sh
index 2360e240..43ed3891 100755
--- a/CI/test_cases/container_cases/cri_stream.sh
+++ b/CI/test_cases/container_cases/cri_stream.sh
@@ -187,10 +187,8 @@ function do_test_t()
     test_cri_exec_fun  || ((ret++))
     test_cri_exec_abn || ((ret++))
 
-    # runc attach not support
-    if [ $runtime == "lcr" ]; then
-        test_cri_attach || ((ret++))
-    fi
+    test_cri_attach || ((ret++))
+
     tear_down || ((ret++))
 
     msg_info "${test} finished with return ${ret}..."
diff --git a/test/cmd/isulad-shim/common/common_ut.cc b/test/cmd/isulad-shim/common/common_ut.cc
index 63395232..fb60f628 100644
--- a/test/cmd/isulad-shim/common/common_ut.cc
+++ b/test/cmd/isulad-shim/common/common_ut.cc
@@ -87,3 +87,45 @@ TEST_F(CommonUnitTest, test_combined_output)
     params[0] = non_cmd.c_str();
     EXPECT_EQ(cmd_combined_output(non_cmd.c_str(), params, output, &output_len), -1);
 }
+
+TEST_F(CommonUnitTest, test_get_attach_fifo_item)
+{
+    struct isula_linked_list *attach_fifos = NULL;
+    attach_fifos = (struct isula_linked_list *)isula_common_calloc_s(sizeof(struct isula_linked_list));
+    ASSERT_TRUE(attach_fifos != nullptr);
+
+    isula_linked_list_init(attach_fifos);
+
+    EXPECT_EQ(get_attach_fifo_item(4, attach_fifos), nullptr);
+    EXPECT_EQ(get_attach_fifo_item(-1, attach_fifos), nullptr);
+    EXPECT_EQ(get_attach_fifo_item(4, NULL), nullptr);
+
+    struct shim_fifos_fd fifos1 = {
+        .in_fd = 1,
+        .out_fd = 2,
+        .err_fd = 3,
+    };
+    struct shim_fifos_fd fifos2 = {
+        .in_fd = 4,
+        .out_fd = 5,
+        .err_fd = 6,
+    };
+    struct isula_linked_list *node1 = NULL;
+    struct isula_linked_list *node2 = NULL;
+    node1 = (struct isula_linked_list *)isula_common_calloc_s(sizeof(struct isula_linked_list));
+    ASSERT_TRUE(node1 != nullptr);
+    node1->elem = &fifos1;
+    isula_linked_list_add(attach_fifos, node1);
+
+    node2 = (struct isula_linked_list *)isula_common_calloc_s(sizeof(struct isula_linked_list));
+    ASSERT_TRUE(node2 != nullptr);
+    node2->elem = &fifos2;
+    isula_linked_list_add(attach_fifos, node2);
+
+    EXPECT_EQ(get_attach_fifo_item(1, attach_fifos), node1);
+    EXPECT_EQ(get_attach_fifo_item(4, attach_fifos), node2);
+
+    free(node1);
+    free(node2);
+    free(attach_fifos);
+}
-- 
2.42.0

