Browse code

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>

Albin Kerouanton authored on 2025/08/08 23:14:24
Showing 1 changed files
... ...
@@ -18,43 +18,77 @@ TESTDIRS="${TESTDIRS:-./...}"
18 18
 
19 19
 mkdir -p bundles
20 20
 
21
-cd api
22
-api_pkg_list=$(go list $TESTDIRS)
21
+case "$TESTDIRS" in
22
+	"./api"* | "./...")
23
+		api_pkg_list=$(go -C ./api list -mod=readonly "${TESTDIRS/#\.\/api/\.}")
24
+		;;
25
+esac
23 26
 if [ -n "${api_pkg_list}" ]; then
24
-	gotestsum --format=standard-quiet --jsonfile=../bundles/api-go-test-report.json --junitfile=../bundles/api-junit-report.xml -- \
27
+	# These are tests for a separate module. Run tests for this module with
28
+	# '-mod=readonly' to prevent the "vendor/" directory being used, which
29
+	# does have a copy of these files, but does not contain test files.
30
+	#
31
+	# From the Go documentation https://golang.org/ref/mod:
32
+	#
33
+	# - `-mod=mod` tells the go command to ignore the vendor directory and to
34
+	#   automatically update `go.mod`, for example, when an imported package
35
+	#   is not provided by any known module.
36
+	# - `-mod=readonly` tells the go command to ignore the vendor directory
37
+	#   and to report an error if `go.mod` needs to be updated.
38
+	gotestsum --format=standard-quiet --jsonfile=bundles/api-go-test-report.json --junitfile=bundles/api-junit-report.xml -- \
25 39
 		"${BUILDFLAGS[@]}" \
26 40
 		-cover \
27
-		-coverprofile=../bundles/api-coverage.out \
41
+		-coverprofile=bundles/api-coverage.out \
28 42
 		-covermode=atomic \
43
+		-mod=readonly \
29 44
 		${TESTFLAGS} \
30 45
 		${api_pkg_list}
31 46
 fi
32 47
 
33
-cd ../client
34
-
35
-client_pkg_list=$(go list $TESTDIRS)
48
+case "$TESTDIRS" in
49
+	"./client"* | "./...")
50
+		client_pkg_list=$(go -C ./client list -mod=readonly "${TESTDIRS/#\.\/client/\.}")
51
+		;;
52
+esac
36 53
 if [ -n "${client_pkg_list}" ]; then
37
-	gotestsum --format=standard-quiet --jsonfile=../bundles/client-go-test-report.json --junitfile=../bundles/client-junit-report.xml -- \
54
+	# These are tests for a separate module. Run tests for this module with
55
+	# '-mod=readonly' to prevent the "vendor/" directory being used, which
56
+	# does have a copy of these files, but does not contain test files.
57
+	#
58
+	# From the Go documentation https://golang.org/ref/mod:
59
+	#
60
+	# - `-mod=mod` tells the go command to ignore the vendor directory and to
61
+	#   automatically update `go.mod`, for example, when an imported package
62
+	#   is not provided by any known module.
63
+	# - `-mod=readonly` tells the go command to ignore the vendor directory
64
+	#   and to report an error if `go.mod` needs to be updated.
65
+	gotestsum --format=standard-quiet --jsonfile=bundles/client-go-test-report.json --junitfile=bundles/client-junit-report.xml -- \
38 66
 		"${BUILDFLAGS[@]}" \
39 67
 		-cover \
40
-		-coverprofile=../bundles/client-coverage.out \
68
+		-coverprofile=bundles/client-coverage.out \
41 69
 		-covermode=atomic \
70
+		-mod=readonly \
42 71
 		${TESTFLAGS} \
43 72
 		${client_pkg_list}
44 73
 fi
45 74
 
46
-cd ..
47
-
48
-exclude_paths='/vendor/|/integration'
49
-pkgs=$(go list $TESTDIRS | grep -vE "($exclude_paths)")
75
+case "$TESTDIRS" in
76
+	"./api"* | "./client"*)
77
+		# modules are handled above
78
+		;;
79
+	*)
80
+		exclude_paths='/vendor/|/integration'
81
+		pkgs=$(go list "$TESTDIRS" | grep -vE "($exclude_paths)")
50 82
 
51
-pkg_list=$(echo "${pkgs}" | grep --fixed-strings -v "/libnetwork" || :)
52
-libnetwork_pkg_list=$(echo "${pkgs}" | grep --fixed-strings "/libnetwork" || :)
83
+		pkg_list=$(echo "${pkgs}" | grep --fixed-strings -v "/libnetwork" || :)
84
+		libnetwork_pkg_list=$(echo "${pkgs}" | grep --fixed-strings "/libnetwork" || :)
53 85
 
54
-echo "${libnetwork_pkg_list}" | grep --fixed-strings "libnetwork/drivers/bridge" \
55
-	&& if ! type docker-proxy; then
56
-		hack/make.sh binary-proxy install-proxy
57
-	fi
86
+		echo "${libnetwork_pkg_list}" | grep --fixed-strings "libnetwork/drivers/bridge" \
87
+			&& if ! type docker-proxy; then
88
+				hack/make.sh binary-proxy install-proxy
89
+			fi
90
+		;;
91
+esac
58 92
 
59 93
 if [ -n "${pkg_list}" ]; then
60 94
 	gotestsum --format=standard-quiet --jsonfile=bundles/go-test-report.json --junitfile=bundles/junit-report.xml -- \