From 8013d80c24bf9fe5eb0fa20eea19db4f7d299a32 Mon Sep 17 00:00:00 2001 From: Albin Kerouanton Date: Fri, 8 Aug 2025 16:14:24 +0200 Subject: [PATCH] hack/test/unit: run in the right module when TESTDIRS is used Since 'api/' and 'client/' are separate Go modules, tests need to be run separately in each module. Commit 900a0516d changed the hack/test/unit script to account for that. But since that commit, if that script is invoked with TESTDIRS set, it will try every module instead of locating the one containing TESTDIRS. When trying to run tests that are within one of the modules (`api`, `client`), Go may find the test while listing (`go -C api list ./pkg/...`); go -C api list ./pkg/... github.com/moby/moby/api/pkg/progress github.com/moby/moby/api/pkg/stdcopy github.com/moby/moby/api/pkg/streamformatter But when running tests from outside the module directory, it may use the vendor directory, and find no tests to run; go test -count 1 -run TestValidateRestartPolicy github.com/moby/moby/api/types/container ? github.com/moby/moby/api/types/container [no test files] To fix this, there's two options; we can first change to the respective module's directory so that `go test` is run from within the module's context; go -C api test -count 1 -run TestValidateRestartPolicy github.com/moby/moby/api/types/container ok github.com/moby/moby/api/types/container 0.003s Or, to avoid having to change the directory, we can use `-mod=readonly` or `-mod=mod`. From the Go documentation https://golang.org/ref/mod: > - `-mod=mod` tells the go command to ignore the vendor directory and to > automatically update `go.mod`, for example, when an imported package > is not provided by any known module. > - `-mod=readonly` tells the go command to ignore the vendor directory > and to report an error if `go.mod` needs to be updated. With that option set, the tests are run; go test -mod=readonly -count 1 -run TestValidateRestartPolicy github.com/moby/moby/api/types/container ok github.com/moby/moby/api/types/container 0.003s Signed-off-by: Albin Kerouanton Signed-off-by: Sebastiaan van Stijn --- hack/test/unit | 72 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/hack/test/unit b/hack/test/unit index c4008df097..e759447805 100755 --- a/hack/test/unit +++ b/hack/test/unit @@ -18,43 +18,77 @@ TESTDIRS="${TESTDIRS:-./...}" mkdir -p bundles -cd api -api_pkg_list=$(go list $TESTDIRS) +case "$TESTDIRS" in + "./api"* | "./...") + api_pkg_list=$(go -C ./api list -mod=readonly "${TESTDIRS/#\.\/api/\.}") + ;; +esac if [ -n "${api_pkg_list}" ]; then - gotestsum --format=standard-quiet --jsonfile=../bundles/api-go-test-report.json --junitfile=../bundles/api-junit-report.xml -- \ + # These are tests for a separate module. Run tests for this module with + # '-mod=readonly' to prevent the "vendor/" directory being used, which + # does have a copy of these files, but does not contain test files. + # + # From the Go documentation https://golang.org/ref/mod: + # + # - `-mod=mod` tells the go command to ignore the vendor directory and to + # automatically update `go.mod`, for example, when an imported package + # is not provided by any known module. + # - `-mod=readonly` tells the go command to ignore the vendor directory + # and to report an error if `go.mod` needs to be updated. + gotestsum --format=standard-quiet --jsonfile=bundles/api-go-test-report.json --junitfile=bundles/api-junit-report.xml -- \ "${BUILDFLAGS[@]}" \ -cover \ - -coverprofile=../bundles/api-coverage.out \ + -coverprofile=bundles/api-coverage.out \ -covermode=atomic \ + -mod=readonly \ ${TESTFLAGS} \ ${api_pkg_list} fi -cd ../client - -client_pkg_list=$(go list $TESTDIRS) +case "$TESTDIRS" in + "./client"* | "./...") + client_pkg_list=$(go -C ./client list -mod=readonly "${TESTDIRS/#\.\/client/\.}") + ;; +esac if [ -n "${client_pkg_list}" ]; then - gotestsum --format=standard-quiet --jsonfile=../bundles/client-go-test-report.json --junitfile=../bundles/client-junit-report.xml -- \ + # These are tests for a separate module. Run tests for this module with + # '-mod=readonly' to prevent the "vendor/" directory being used, which + # does have a copy of these files, but does not contain test files. + # + # From the Go documentation https://golang.org/ref/mod: + # + # - `-mod=mod` tells the go command to ignore the vendor directory and to + # automatically update `go.mod`, for example, when an imported package + # is not provided by any known module. + # - `-mod=readonly` tells the go command to ignore the vendor directory + # and to report an error if `go.mod` needs to be updated. + gotestsum --format=standard-quiet --jsonfile=bundles/client-go-test-report.json --junitfile=bundles/client-junit-report.xml -- \ "${BUILDFLAGS[@]}" \ -cover \ - -coverprofile=../bundles/client-coverage.out \ + -coverprofile=bundles/client-coverage.out \ -covermode=atomic \ + -mod=readonly \ ${TESTFLAGS} \ ${client_pkg_list} fi -cd .. +case "$TESTDIRS" in + "./api"* | "./client"*) + # modules are handled above + ;; + *) + exclude_paths='/vendor/|/integration' + pkgs=$(go list "$TESTDIRS" | grep -vE "($exclude_paths)") -exclude_paths='/vendor/|/integration' -pkgs=$(go list $TESTDIRS | grep -vE "($exclude_paths)") + pkg_list=$(echo "${pkgs}" | grep --fixed-strings -v "/libnetwork" || :) + libnetwork_pkg_list=$(echo "${pkgs}" | grep --fixed-strings "/libnetwork" || :) -pkg_list=$(echo "${pkgs}" | grep --fixed-strings -v "/libnetwork" || :) -libnetwork_pkg_list=$(echo "${pkgs}" | grep --fixed-strings "/libnetwork" || :) - -echo "${libnetwork_pkg_list}" | grep --fixed-strings "libnetwork/drivers/bridge" \ - && if ! type docker-proxy; then - hack/make.sh binary-proxy install-proxy - fi + echo "${libnetwork_pkg_list}" | grep --fixed-strings "libnetwork/drivers/bridge" \ + && if ! type docker-proxy; then + hack/make.sh binary-proxy install-proxy + fi + ;; +esac if [ -n "${pkg_list}" ]; then gotestsum --format=standard-quiet --jsonfile=bundles/go-test-report.json --junitfile=bundles/junit-report.xml -- \