From 81d932906aa7ef45e2a4c9553dd56e13d4e45bf7 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 6 May 2023 12:58:22 -0700 Subject: [PATCH] Make golang::binaries_from_targets smarter and use it from test Result: `make` works, but `make test` still broken ``` $ make kubectl +++ [1211 11:15:46] Building go targets for linux/amd64 ./cmd/kubectl (static) $ make WHAT=./cmd/kubectl/ +++ [1211 11:15:53] Building go targets for linux/amd64 ./cmd/kubectl/ (non-static) $ make WHAT=cmd/kubectl/ +++ [1211 11:16:02] Building go targets for linux/amd64 ./cmd/kubectl/ (non-static) $ make WHAT=k8s.io/kubernetes/cmd/kubectl +++ [1211 11:16:16] Building go targets for linux/amd64 k8s.io/kubernetes/cmd/kubectl (static) $ make WHAT=./staging/src/k8s.io/api +++ [1211 11:16:31] Building go targets for linux/amd64 ./staging/src/k8s.io/api (non-static) $ make WHAT=staging/src/k8s.io/api +++ [1211 11:16:43] Building go targets for linux/amd64 ./staging/src/k8s.io/api (non-static) $ make WHAT=k8s.io/api +++ [1211 11:16:50] Building go targets for linux/amd64 k8s.io/api (non-static) ``` ``` $ make test WHAT=./cmd/kubectl +++ [1211 11:17:23] Set GOMAXPROCS automatically to 6 +++ [1211 11:17:23] Running tests without code coverage and with -race cmd/kubectl/kubectl.go:25:2: cannot find package "k8s.io/client-go/plugin/pkg/client/auth" in any of: /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/client-go/plugin/pkg/client/auth (vendor tree) /home/thockin/sdk/gotip/src/k8s.io/client-go/plugin/pkg/client/auth (from $GOROOT) /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/client-go/plugin/pkg/client/auth (from $GOPATH) cmd/kubectl/kubectl.go:20:2: cannot find package "k8s.io/component-base/cli" in any of: /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/component-base/cli (vendor tree) /home/thockin/sdk/gotip/src/k8s.io/component-base/cli (from $GOROOT) /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/component-base/cli (from $GOPATH) cmd/kubectl/kubectl.go:21:2: cannot find package "k8s.io/kubectl/pkg/cmd" in any of: /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/kubectl/pkg/cmd (vendor tree) /home/thockin/sdk/gotip/src/k8s.io/kubectl/pkg/cmd (from $GOROOT) /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/kubectl/pkg/cmd (from $GOPATH) cmd/kubectl/kubectl.go:22:2: cannot find package "k8s.io/kubectl/pkg/cmd/util" in any of: /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/kubectl/pkg/cmd/util (vendor tree) /home/thockin/sdk/gotip/src/k8s.io/kubectl/pkg/cmd/util (from $GOROOT) /home/thockin/src/kubernetes/_output/local/go/src/k8s.io/kubectl/pkg/cmd/util (from $GOPATH) make: *** [Makefile:191: test] Error 1 ``` --- hack/lib/golang.sh | 36 ++++++++++++++++++++++++------- hack/make-rules/test.sh | 47 +++++------------------------------------ 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/hack/lib/golang.sh b/hack/lib/golang.sh index ec17613050f..1a6dd82eb58 100755 --- a/hack/lib/golang.sh +++ b/hack/lib/golang.sh @@ -368,9 +368,13 @@ kube::golang::is_statically_linked_library() { return 1; } -# kube::binaries_from_targets take a list of build targets and return the -# full go package to be built +# binaries_from_targets takes a list of build targets, which might be go +# targets (e.g. example.com/foo/bar or ./foo/bar) or local paths (e.g. foo/bar) +# and produces a respective list (on stdout) of our best guess at Go target +# names. kube::golang::binaries_from_targets() { + # We can't just `go list -find` on each input because sometimes they are + # files (e.g. ".../pkg.test") which don't exist. Also it's very slow. local target for target; do if [ "${target}" = "ginkgo" ] || @@ -380,17 +384,33 @@ kube::golang::binaries_from_targets() { # "ginkgo" is the one that is documented in the Makefile. The others # are for backwards compatibility. echo "github.com/onsi/ginkgo/v2/ginkgo" - elif [[ "${target}" =~ ^([[:alnum:]]+".")+[[:alnum:]]+"/" ]]; then + continue + fi + + if [[ "${target}" =~ ^([[:alnum:]]+".")+[[:alnum:]]+"/" ]]; then # If the target starts with what looks like a domain name, assume it has a - # fully-qualified package name rather than one that needs the Kubernetes - # package prepended. + # fully-qualified Go package name. echo "${target}" - elif [[ "${target}" =~ ^vendor/ ]]; then + continue + fi + + if [[ "${target}" =~ ^vendor/ ]]; then # Strip vendor/ prefix, since we're building in gomodule mode. echo "${target#"vendor/"}" - else - echo "${KUBE_GO_PACKAGE}/${target}" + continue fi + + # If the target starts with "./", assume it is a local path which qualifies + # as a Go target name. + if [[ "${target}" =~ ^\./ ]]; then + echo "${target}" + continue + fi + + # Otherwise assume it's a relative path (e.g. foo/bar or foo/bar/bar.test). + # We probably SHOULDN'T accept this, but we did in the past and it would be + # rude to break things if we don't NEED to. + echo "./${target}" done } diff --git a/hack/make-rules/test.sh b/hack/make-rules/test.sh index 9f9db16f1ea..6874d9d397a 100755 --- a/hack/make-rules/test.sh +++ b/hack/make-rules/test.sh @@ -182,46 +182,6 @@ junitFilenamePrefix() { echo "${KUBE_JUNIT_REPORT_DIR}/junit_$(kube::util::sortable_date)" } -verifyAndSuggestPackagePath() { - local specified_package_path="$1" - local alternative_package_path="$2" - local original_package_path="$3" - local suggestion_package_path="$4" - - if [[ "${specified_package_path}" =~ '/...'$ ]]; then - specified_package_path=${specified_package_path::-4} - fi - - if ! [ -d "${specified_package_path}" ]; then - # 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 - 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 - kube::log::info "try changing \"${original_package_path}\" to \"${suggestion_package_path}\"" - fi - exit 1 - fi -} - -verifyPathsToPackagesUnderTest() { - local packages_under_test=("$@") - - for package_path in "${packages_under_test[@]}"; do - local local_package_path="${package_path}" - local go_package_path="${GOPATH}/src/${package_path}" - - if [[ "${package_path:0:2}" == "./" ]] ; then - verifyAndSuggestPackagePath "${local_package_path}" "${go_package_path}" "${package_path}" "${package_path:2}" - else - verifyAndSuggestPackagePath "${go_package_path}" "${local_package_path}" "${package_path}" "./${package_path}" - fi - done -} - produceJUnitXMLReport() { local -r junit_filename_prefix=$1 if [[ -z "${junit_filename_prefix}" ]]; then @@ -257,14 +217,17 @@ runTests() { local junit_filename_prefix junit_filename_prefix=$(junitFilenamePrefix) - verifyPathsToPackagesUnderTest "$@" + # Try to normalize input names. + local -a targets + while IFS="" read -r target; do targets+=("$target"); done < <(kube::golang::binaries_from_targets "$@") # If we're not collecting coverage, run all requested tests with one 'go test' # command, which is much faster. if [[ ! ${KUBE_COVER} =~ ^[yY]$ ]]; then kube::log::status "Running tests without code coverage ${KUBE_RACE:+"and with ${KUBE_RACE}"}" + # shellcheck disable=SC2031 go test "${goflags[@]:+${goflags[@]}}" \ - "${KUBE_TIMEOUT}" "${@}" \ + "${KUBE_TIMEOUT}" "${targets[@]}" \ "${testargs[@]:+${testargs[@]}}" \ | tee ${junit_filename_prefix:+"${junit_filename_prefix}.stdout"} \ | grep --binary-files=text "${go_test_grep_pattern}" && rc=$? || rc=$?