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 <albinker@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Albin Kerouanton
2025-08-08 16:14:24 +02:00
committed by Sebastiaan van Stijn
parent 98286b9cd8
commit 8013d80c24

View File

@@ -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 -- \