diff --git a/doc/languages-frameworks/go.section.md b/doc/languages-frameworks/go.section.md index e947403b2348..bab7ff037d1c 100644 --- a/doc/languages-frameworks/go.section.md +++ b/doc/languages-frameworks/go.section.md @@ -192,6 +192,12 @@ Specifies the contents of the `go.sum` file and triggers rebuilds when it change Defaults to `null` +### `buildTestBinaries` {#var-go-buildTestBinaries} + +This option allows to compile test binaries instead of the usual binaries produced by a package. +Go can [compile test into binaries](https://pkg.go.dev/cmd/go#hdr-Test_packages) using the `go test -c` command. +These binaries can then be executed at a later point (outside the Nix sandbox) to run the tests. +This is mostly useful for downstream consumers to run integration or end-to-end tests that won't work in the Nix sandbox, for example because they require network access. ## Versioned toolchains and builders {#ssec-go-toolchain-versions} diff --git a/doc/redirects.json b/doc/redirects.json index 8210470b5bcb..17263c821fbb 100644 --- a/doc/redirects.json +++ b/doc/redirects.json @@ -613,6 +613,9 @@ "typst-package-scope-and-usage": [ "index.html#typst-package-scope-and-usage" ], + "var-go-buildTestBinaries": [ + "index.html#var-go-buildTestBinaries" + ], "var-meta-teams": [ "index.html#var-meta-teams" ], diff --git a/pkgs/build-support/go/module.nix b/pkgs/build-support/go/module.nix index 5c9b7a84f8a3..5d305e491596 100644 --- a/pkgs/build-support/go/module.nix +++ b/pkgs/build-support/go/module.nix @@ -64,6 +64,12 @@ lib.extendMkDerivation { # Go build flags. GOFLAGS ? [ ], + # Instead of building binary targets with 'go install', build test binaries with 'go test'. + # The binaries found in $out/bin can be executed as go tests outside of the sandbox. + # This is mostly useful outside of nixpkgs, for example to build integration/e2e tests + # that won't run within the sandbox. + buildTestBinaries ? false, + ... }@args: { @@ -338,8 +344,18 @@ lib.extendMkDerivation { export NIX_BUILD_CORES=1 fi for pkg in $(getGoDirs ""); do - echo "Building subPackage $pkg" - buildGoDir install "$pkg" + ${ + if buildTestBinaries then + '' + echo "Building test binary for $pkg" + buildGoDir "test -c -o $GOPATH/bin/" "$pkg" + '' + else + '' + echo "Building subPackage $pkg" + buildGoDir install "$pkg" + '' + } done '' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) '' @@ -359,7 +375,7 @@ lib.extendMkDerivation { '' ); - doCheck = args.doCheck or true; + doCheck = args.doCheck or (!buildTestBinaries); checkPhase = args.checkPhase or '' runHook preCheck diff --git a/pkgs/build-support/go/tests.nix b/pkgs/build-support/go/tests.nix new file mode 100644 index 000000000000..8966fe927aea --- /dev/null +++ b/pkgs/build-support/go/tests.nix @@ -0,0 +1,9 @@ +{ + lib, + callPackage, +}: + +lib.packagesFromDirectoryRecursive { + inherit callPackage; + directory = ./tests; +} diff --git a/pkgs/build-support/go/tests/build-test-binaries/go.mod b/pkgs/build-support/go/tests/build-test-binaries/go.mod new file mode 100644 index 000000000000..26cef8bdf8fc --- /dev/null +++ b/pkgs/build-support/go/tests/build-test-binaries/go.mod @@ -0,0 +1,3 @@ +module build-test-binaries + +go 1.24 diff --git a/pkgs/build-support/go/tests/build-test-binaries/main_test.go b/pkgs/build-support/go/tests/build-test-binaries/main_test.go new file mode 100644 index 000000000000..29378df53b02 --- /dev/null +++ b/pkgs/build-support/go/tests/build-test-binaries/main_test.go @@ -0,0 +1,7 @@ +package main + +import "testing" + +func TestHelloFromTest(t *testing.T) { + t.Log("Hello from test") +} diff --git a/pkgs/build-support/go/tests/build-test-binaries/package.nix b/pkgs/build-support/go/tests/build-test-binaries/package.nix new file mode 100644 index 000000000000..761d793233bd --- /dev/null +++ b/pkgs/build-support/go/tests/build-test-binaries/package.nix @@ -0,0 +1,34 @@ +{ + buildGoModule, + runCommandCC, +}: + +let + testPackage = buildGoModule { + name = "build-test-binaries"; + src = ./.; + vendorHash = null; + buildTestBinaries = true; + }; +in + +runCommandCC "build-test-binaries-check" + { + nativeBuildInputs = [ testPackage ]; + passthru = { inherit testPackage; }; + } + '' + fail() { + echo "Test failed: $1" >&2 + exit 1 + } + + command -v build-test-binaries.test || + fail "build-test-binaries.test not found in PATH" + + build-test-binaries.test -test.v | tee $out || + fail "build-test-binaries.test failed" + + grep -q "Hello from test" $out || + fail "Output does not contain expected string" + '' diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index 6314049ed0bc..b0cc43bcaa63 100644 --- a/pkgs/test/default.nix +++ b/pkgs/test/default.nix @@ -149,6 +149,8 @@ with pkgs; php = recurseIntoAttrs (callPackages ./php { }); + go = recurseIntoAttrs (callPackage ../build-support/go/tests.nix { }); + pkg-config = recurseIntoAttrs (callPackage ../top-level/pkg-config/tests.nix { }) // { __recurseIntoDerivationForReleaseJobs = true; };