diff --git a/hack/.shellcheck_failures b/hack/.shellcheck_failures index 06f051c65fc..b322c254fe8 100644 --- a/hack/.shellcheck_failures +++ b/hack/.shellcheck_failures @@ -23,7 +23,6 @@ ./hack/lib/test.sh ./hack/lib/version.sh ./hack/make-rules/make-help.sh -./hack/make-rules/test.sh ./hack/make-rules/update.sh ./hack/make-rules/verify.sh ./hack/pin-dependency.sh diff --git a/hack/make-rules/test.sh b/hack/make-rules/test.sh index 2ced45589e9..8bd403625da 100755 --- a/hack/make-rules/test.sh +++ b/hack/make-rules/test.sh @@ -18,7 +18,7 @@ set -o errexit set -o nounset set -o pipefail -KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../.. +KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/../.. source "${KUBE_ROOT}/hack/lib/init.sh" kube::golang::setup_env @@ -43,7 +43,7 @@ fi kube::test::find_dirs() { ( - cd ${KUBE_ROOT} + cd "${KUBE_ROOT}" find -L . -not \( \ \( \ -path './_artifacts/*' \ @@ -161,12 +161,12 @@ while getopts "hp:i:" opt ; do kube::test::usage exit 1 ;; - ?) + :) + kube::log::usage "Option -${OPTARG} " kube::test::usage exit 1 ;; - :) - kube::log::usage "Option -${OPTARG} " + ?) kube::test::usage exit 1 ;; @@ -175,6 +175,7 @@ done shift $((OPTIND - 1)) # Use eval to preserve embedded quoted strings. +testargs=() eval "testargs=(${KUBE_TEST_ARGS:-})" # Used to filter verbose test output. @@ -202,10 +203,18 @@ for arg; do fi done if [[ ${#testcases[@]} -eq 0 ]]; then - testcases=($(kube::test::find_dirs)) + while IFS='' read -r line; do testcases+=("$line"); done < <(kube::test::find_dirs) fi set -- "${testcases[@]+${testcases[@]}}" +if [[ -n "${KUBE_RACE}" ]] ; then + goflags+=("${KUBE_RACE}") +fi + +if [[ -n "${KUBE_TIMEOUT}" ]] ; then + while IFS='' read -r line; do goflags+=("$line"); done < <(echo "${KUBE_TIMEOUT}" | tr ' ' '\n') +fi + junitFilenamePrefix() { if [[ -z "${KUBE_JUNIT_REPORT_DIR}" ]]; then echo "" @@ -217,7 +226,8 @@ junitFilenamePrefix() { # barely fits there and in coverage mode test names are # appended to generated file names, easily exceeding # 255 chars in length. So let's just use a sha1 hash of it. - local KUBE_TEST_API_HASH="$(echo -n "${KUBE_TEST_API//\//-}"| ${SHA1SUM} |awk '{print $1}')" + local KUBE_TEST_API_HASH + KUBE_TEST_API_HASH="$(echo -n "${KUBE_TEST_API//\//-}"| ${SHA1SUM} |awk '{print $1}')" echo "${KUBE_JUNIT_REPORT_DIR}/junit_${KUBE_TEST_API_HASH}_$(kube::util::sortable_date)" } @@ -235,7 +245,8 @@ verifyAndSuggestPackagePath() { # Because k8s sets a localized $GOPATH for testing, seeing the actual # directory can be confusing. Instead, just show $GOPATH if it exists in the # $specified_package_path. - local printable_package_path=$(echo "${specified_package_path}" | sed "s|${GOPATH}|\${GOPATH}|") + local printable_package_path + printable_package_path=${specified_package_path//${GOPATH}/\$\{GOPATH\}} kube::log::error "specified test path '${printable_package_path}' does not exist" if [ -d "${alternative_package_path}" ]; then @@ -246,7 +257,7 @@ verifyAndSuggestPackagePath() { } verifyPathsToPackagesUnderTest() { - local packages_under_test=($@) + local packages_under_test=("$@") for package_path in "${packages_under_test[@]}"; do local local_package_path="${package_path}" @@ -268,16 +279,16 @@ produceJUnitXMLReport() { local test_stdout_filenames local junit_xml_filename - test_stdout_filenames=$(ls ${junit_filename_prefix}*.stdout) + test_stdout_filenames=$(ls "${junit_filename_prefix}"*.stdout) junit_xml_filename="${junit_filename_prefix}.xml" if ! command -v go-junit-report >/dev/null 2>&1; then kube::log::error "go-junit-report not found; please install with " \ "go get -u github.com/jstemmer/go-junit-report" return fi - cat ${test_stdout_filenames} | go-junit-report > "${junit_xml_filename}" + go-junit-report < "${test_stdout_filenames}" > "${junit_xml_filename}" if [[ ! ${KUBE_KEEP_VERBOSE_TEST_OUTPUT} =~ ^[yY]$ ]]; then - rm ${test_stdout_filenames} + rm "${test_stdout_filenames}" fi kube::log::status "Saved JUnit XML test report to ${junit_xml_filename}" } @@ -293,7 +304,7 @@ runTests() { if [[ ! ${KUBE_COVER} =~ ^[yY]$ ]]; then kube::log::status "Running tests without code coverage" go test "${goflags[@]:+${goflags[@]}}" \ - ${KUBE_RACE} ${KUBE_TIMEOUT} "${@}" \ + "${@}" \ "${testargs[@]:+${testargs[@]}}" \ | tee ${junit_filename_prefix:+"${junit_filename_prefix}.stdout"} \ | grep --binary-files=text "${go_test_grep_pattern}" && rc=$? || rc=$? @@ -324,21 +335,19 @@ runTests() { # vendor/k8s.io/client-go/1.4/rest: causes cover internal errors # https://github.com/golang/go/issues/16540 cover_ignore_dirs="vendor/k8s.io/code-generator/cmd/generator|vendor/k8s.io/client-go/1.4/rest" - for path in $(echo ${cover_ignore_dirs} | sed 's/|/ /g'); do + for path in ${cover_ignore_dirs//|/ }; do echo -e "skipped\tk8s.io/kubernetes/${path}" done printf "%s\n" "${@}" \ | grep -Ev ${cover_ignore_dirs} \ - | xargs -I{} -n 1 -P ${KUBE_COVERPROCS} \ + | xargs -I{} -n 1 -P "${KUBE_COVERPROCS}" \ bash -c "set -o pipefail; _pkg=\"\$0\"; _pkg_out=\${_pkg//\//_}; \ - go test ${goflags[@]:+${goflags[@]}} \ - ${KUBE_RACE} \ - ${KUBE_TIMEOUT} \ + go test ${goflags[*]:+${goflags[*]}} \ -cover -covermode=\"${KUBE_COVERMODE}\" \ -coverprofile=\"${cover_report_dir}/\${_pkg}/${cover_profile}\" \ \"\${_pkg}\" \ - ${testargs[@]:+${testargs[@]}} \ + ${testargs[*]:+${testargs[*]}} \ | tee ${junit_filename_prefix:+\"${junit_filename_prefix}-\$_pkg_out.stdout\"} \ | grep \"${go_test_grep_pattern}\"" \ {} \ @@ -356,9 +365,9 @@ runTests() { # Include all coverage reach data in the combined profile, but exclude the # 'mode' lines, as there should be only one. - for x in `find "${cover_report_dir}" -name "${cover_profile}"`; do - cat ${x} | grep -h -v "^mode:" || true - done + while IFS='' read -r x; do + grep -h -v "^mode:" < "${x}" || true + done < <(find "${cover_report_dir}" -name "${cover_profile}") } >"${COMBINED_COVER_PROFILE}" coverage_html_file="${cover_report_dir}/combined-coverage.html" @@ -381,7 +390,8 @@ reportCoverageToCoveralls() { checkFDs() { # several unittests panic when httptest cannot open more sockets # due to the low default files limit on OS X. Warn about low limit. - local fileslimit="$(ulimit -n)" + local fileslimit + fileslimit="$(ulimit -n)" if [[ ${fileslimit} -lt 1000 ]]; then echo "WARNING: ulimit -n (files) should be at least 1000, is ${fileslimit}, may cause test failure"; fi @@ -391,9 +401,9 @@ checkFDs # Convert the CSVs to arrays. -IFS=';' read -a apiVersions <<< "${KUBE_TEST_API_VERSIONS}" +IFS=';' read -r -a apiVersions <<< "${KUBE_TEST_API_VERSIONS}" apiVersionsCount=${#apiVersions[@]} -for (( i=0; i<${apiVersionsCount}; i++ )); do +for (( i=0; i