From ed8d2d30e7d298fa05395a79cc3502240d9c0721 Mon Sep 17 00:00:00 2001 From: DCCooper <1866858@gmail.com> Date: Mon, 1 Nov 2021 16:24:14 +0800 Subject: [PATCH 13/16] test:cleancode test for better experience change: 1. shellcheck fix for scripts in used hack 2. use busyobx instead of openeuler base image to speed up test 3. add test-unit-cover, test-sdv-cover, test-cover for project to generate coverage files Signed-off-by: DCCooper <1866858@gmail.com> --- Makefile | 18 ++++ hack/all_coverage.sh | 26 ++++++ hack/merge_coverage.sh | 55 +++++++++++ hack/sdv_coverage.sh | 104 +++++++++++++++++++++ hack/unit_test.sh | 82 +++++++++++----- tests/src/integration_test_set_new_root.sh | 7 +- 6 files changed, 268 insertions(+), 24 deletions(-) create mode 100755 hack/all_coverage.sh create mode 100644 hack/merge_coverage.sh create mode 100755 hack/sdv_coverage.sh diff --git a/Makefile b/Makefile index d41a9fdb..73482a41 100644 --- a/Makefile +++ b/Makefile @@ -112,6 +112,24 @@ test-integration: ## Test integration case @./tests/test.sh integration @echo "Integration test done!" +.PHONY: test-unit-cover +test-unit-cover: ## Test unit case and generate coverage + @echo "Unit test cover starting..." + @./hack/unit_test.sh cover + @echo "Unit test cover done!" + +.PHONY: test-sdv-cover +test-sdv-cover: ## Test integration case and generate coverage + @echo "Integration test cover starting..." + @./hack/sdv_coverage.sh + @echo "Integration test cover done!" + +.PHONY: test-cover +test-cover: test-sdv-cover test-unit-cover ## Test both unit and sdv case and generate unity coverage + @echo "Test cover starting..." + @./hack/all_coverage.sh + @echo "Test cover done!" + ##@ Development .PHONY: build-image diff --git a/hack/all_coverage.sh b/hack/all_coverage.sh new file mode 100755 index 00000000..9f9eb5ff --- /dev/null +++ b/hack/all_coverage.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +# isula-build 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. +# Author: Xiang Li +# Create: 2020-03-01 +# Description: shell script for all coverage +# Note: use this file by typing make test-cover +# Do not run this script directly + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit; pwd) +# shellcheck disable=SC1091 +source "${SCRIPT_DIR}"/merge_coverage.sh + +unit_coverage=${PWD}/cover_unit_test_all.out +sdv_coverage=${PWD}/cover_sdv_test_all.out +output_file=${PWD}/cover_test_all + +merge_cover "${output_file}" "${sdv_coverage}" "${unit_coverage}" diff --git a/hack/merge_coverage.sh b/hack/merge_coverage.sh new file mode 100644 index 00000000..6e529a34 --- /dev/null +++ b/hack/merge_coverage.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +# isula-build 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. +# Author: Xiang Li +# Create: 2021-11-01 +# Description: merge coverage from input coverage files +# Note: Do not run this script directly + +# Usage: merge_cover outputfile file1 file2 ... fileN +# Input: first: outputfile name +# remaining: coverage files +function merge_cover() { + output_file_name="$1" + input_coverages=( "${@:2}" ) + + output_coverage_file=${output_file_name}.out + output_html_file=${output_file_name}.html + output_merge_cover=${output_file_name}.merge + grep -r -h -v "^mode:" "${input_coverages[@]}" | sort > "$output_merge_cover" + current="" + count=0 + echo "mode: set" > "$output_coverage_file" + # read the cover report from merge_cover, convert it, write to final coverage + while read -r line; do + block=$(echo "$line" | cut -d ' ' -f1-2) + num=$(echo "$line" | cut -d ' ' -f3) + if [ "$current" == "" ]; then + current=$block + count=$num + elif [ "$block" == "$current" ]; then + count=$((count + num)) + else + # if the sorted two lines are not in the same code block, write the statics result of last code block to the final coverage + echo "$current" $count >> "${output_coverage_file}" + current=$block + count=$num + fi + done < "$output_merge_cover" + rm -rf "${output_merge_cover}" + + # merge the results of last line to the final coverage + if [ "$current" != "" ]; then + echo "$current" "$count" >> "${output_coverage_file}" + fi + + go tool cover -html="${output_coverage_file}" -o "$output_html_file" +} diff --git a/hack/sdv_coverage.sh b/hack/sdv_coverage.sh new file mode 100755 index 00000000..874d9373 --- /dev/null +++ b/hack/sdv_coverage.sh @@ -0,0 +1,104 @@ +#!/bin/bash + +# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +# isula-build 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. +# Author: Xiang Li +# Create: 2020-03-01 +# Description: shell script for coverage +# Note: use this file by typing make test-sdv-cover or make test-cover +# Do not run this script directly + +project_root=${PWD} +vendor_name="isula.org" +project_name="isula-build" +main_relative_path="cmd/daemon" +exclude_pattern="gopkgs|api/services" +go_test_mod_method="-mod=vendor" +go_test_count_method="-count=1" +go_test_cover_method="-covermode=set" +main_pkg="${vendor_name}/${project_name}/${main_relative_path}" +main_test_file=${project_root}/${main_relative_path}/main_test.go +main_file=${project_root}/${main_relative_path}/main.go +coverage_file=${project_root}/cover_sdv_test_all.out +coverage_html=${project_root}/cover_sdv_test_all.html +coverage_log=${project_root}/cover_sdv_test_all.log +main_test_binary_file=${project_root}/main.test + +function precheck() { + if pgrep isula-builder > /dev/null 2>&1; then + echo "isula-builder is already running, please stop it first" + exit 1 + fi +} + +function modify_main_test() { + # first backup file + cp "${main_file}" "${main_file}".bk + cp "${main_test_file}" "${main_test_file}".bk + # delete Args field for main.go + local comment_pattern="Args: util.NoArgs" + sed -i "/$comment_pattern/s/^#*/\/\/ /" "${main_file}" + # add new line for main_test.go + code_snippet="func TestMain(t *testing.T) { main() }" + echo "$code_snippet" >> "${main_test_file}" +} + +function recover_main_test() { + mv "${main_file}".bk "${main_file}" + mv "${main_test_file}".bk "${main_test_file}" +} + +function build_main_test_binary() { + pkgs=$(go list ${go_test_mod_method} "${project_root}"/... | grep -Ev ${exclude_pattern} | tr "\r\n" ",") + go test -coverpkg="${pkgs}" ${main_pkg} ${go_test_mod_method} ${go_test_cover_method} ${go_test_count_method} -c -o="${main_test_binary_file}" +} + +function run_main_test_binary() { + ${main_test_binary_file} -test.coverprofile="${coverage_file}" > "${coverage_log}" 2>&1 & + main_test_pid=$! + for _ in $(seq 1 10); do + if isula-build info > /dev/null 2>&1; then + break + else + sleep 1 + fi + done +} + +function run_coverage_test() { + # do cover tests + echo "sdv coverage test" + # cover_test_xxx + # cover_test_xxx + # cover_test_xxx + # cover_test_xxx +} + +function finish_coverage_test() { + kill -15 $main_test_pid +} + +function generate_coverage() { + go tool cover -html="${coverage_file}" -o="${coverage_html}" +} + +function cleanup() { + rm "$main_test_binary_file" +} + +precheck +modify_main_test +build_main_test_binary +recover_main_test +run_main_test_binary +run_coverage_test +finish_coverage_test +generate_coverage +cleanup diff --git a/hack/unit_test.sh b/hack/unit_test.sh index a94a2d38..94a44a95 100755 --- a/hack/unit_test.sh +++ b/hack/unit_test.sh @@ -12,32 +12,72 @@ # Author: iSula Team # Create: 2020-07-11 # Description: go test script +# Note: use this file by typing make unit-test or make unit-test-cover +# Do not run this script directly + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit; pwd) +# shellcheck disable=SC1091 +source "${SCRIPT_DIR}"/merge_coverage.sh export GO111MODULE=on +run_coverage=$1 +covers_folder=${PWD}/covers +testlog=${PWD}"/unit_test_log" +exclude_pattern="gopkgs|api/services" +go_test_mod_method="-mod=vendor" +go_test_count_method="-count=1" +go_test_timeout_flag="-timeout=300s" +go_test_race_flag="-race" -TEST_ARGS="" -if [ ! -z "${TEST_REG}" ]; then - TEST_ARGS+=" -args TEST_REG=${TEST_REG}" -fi -if [ ! -z "${SKIP_REG}" ]; then - TEST_ARGS+=" -args SKIP_REG=${SKIP_REG}" -fi -echo "Testing with args ${TEST_ARGS}" +function precheck() { + if pgrep isula-builder > /dev/null 2>&1; then + echo "isula-builder is already running, please stop it first" + exit 1 + fi +} -testlog=${PWD}"/unit_test_log" -rm -f "${testlog}" -touch "${testlog}" -golist=$(go list ./... | grep -v gopkgs) -for path in ${golist}; do - echo "Start to test: ${path}" - # TEST_ARGS is " -args SKIP_REG=foo", so no double quote for it - go test -race -mod=vendor -cover -count=1 -timeout 300s -v "${path}" ${TEST_ARGS} >> "${testlog}" - cat "${testlog}" | grep -E -- "--- FAIL:|^FAIL" - if [ $? -eq 0 ]; then +function run_unit_test() { + TEST_ARGS="" + if [ -n "${TEST_REG}" ]; then + TEST_ARGS+=" -args TEST_REG=${TEST_REG}" + fi + if [ -n "${SKIP_REG}" ]; then + TEST_ARGS+=" -args SKIP_REG=${SKIP_REG}" + fi + echo "Testing with args ${TEST_ARGS}" + + rm -f "${testlog}" + if [[ -n $run_coverage ]]; then + mkdir -p "${covers_folder}" + fi + for package in $(go list ${go_test_mod_method} ./... | grep -Ev ${exclude_pattern}); do + echo "Start to test: ${package}" + if [[ -n $run_coverage ]]; then + coverprofile_file="${covers_folder}/$(echo "$package" | tr / -).cover" + coverprofile_flag="-coverprofile=${coverprofile_file}" + go_test_covermode_flag="-covermode=set" + go_test_race_flag="" + fi + # TEST_ARGS is " -args SKIP_REG=foo", so no double quote for it + # shellcheck disable=SC2086 + go test -v ${go_test_race_flag} ${go_test_mod_method} ${coverprofile_flag} ${go_test_covermode_flag} -coverpkg=${package} ${go_test_count_method} ${go_test_timeout_flag} "${package}" ${TEST_ARGS} >> "${testlog}" + done + + if grep -E -- "--- FAIL:|^FAIL" "${testlog}"; then echo "Testing failed... Please check ${testlog}" - exit 1 fi tail -n 1 "${testlog}" -done -rm -f "${testlog}" + rm -f "${testlog}" +} + +function generate_unit_test_coverage() { + if [[ -n ${run_coverage} ]]; then + merge_cover "cover_unit_test_all" "${covers_folder}" + rm -rf "${covers_folder}" + fi +} + +precheck +run_unit_test +generate_unit_test_coverage diff --git a/tests/src/integration_test_set_new_root.sh b/tests/src/integration_test_set_new_root.sh index bb11a080..ae8d436b 100644 --- a/tests/src/integration_test_set_new_root.sh +++ b/tests/src/integration_test_set_new_root.sh @@ -12,6 +12,7 @@ # Author: Weizheng Xing # Create: 2021-05-29 # Description: test set new run and data root in configuration.toml +# History: 2021-8-18 Xiang Li use busyobx instead of openeuler base image to speed up test top_dir=$(git rev-parse --show-toplevel) # shellcheck disable=SC1091 @@ -20,7 +21,7 @@ source "$top_dir"/tests/lib/common.sh run_root="/var/run/new-isula-build" data_root="/var/lib/new-isula-build" config_file="/etc/isula-build/configuration.toml" -base_image="hub.oepkgs.net/openeuler/openeuler:21.03" +image="hub.oepkgs.net/openeuler/busybox:latest" function clean() { @@ -47,10 +48,10 @@ function pre_test() function do_test() { tree_node_befor=$(tree -L 3 $data_root | wc -l) - run_with_debug "isula-build ctr-img pull $base_image" + run_with_debug "isula-build ctr-img pull $image" tree_node_after=$(tree -L 3 $data_root | wc -l) - if [ $((tree_node_after - tree_node_befor)) -eq 8 ] && run_with_debug "isula-build ctr-img rm $base_image"; then + if [ $((tree_node_after - tree_node_befor)) -eq 8 ] && run_with_debug "isula-build ctr-img rm $image"; then echo "PASS" else echo "Sets of run and data root are not effective" -- 2.27.0