about summary refs log tree commit diff
path: root/pkgs/test
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/test')
-rw-r--r--pkgs/test/auto-patchelf-hook/package.nix4
-rw-r--r--pkgs/test/cc-wrapper/default.nix21
-rw-r--r--pkgs/test/cc-wrapper/hardening.nix136
-rw-r--r--pkgs/test/check-by-name/README.md31
-rw-r--r--pkgs/test/check-by-name/pinned-version.txt2
-rwxr-xr-xpkgs/test/check-by-name/run-local.sh73
-rwxr-xr-xpkgs/test/check-by-name/update-pinned-tool.sh22
-rw-r--r--pkgs/test/cuda/default.nix2
-rw-r--r--pkgs/test/default.nix10
-rw-r--r--pkgs/test/dhall/buildDhallUrl/default.nix2
-rw-r--r--pkgs/test/dotnet/default.nix6
-rw-r--r--pkgs/test/dotnet/final-attrs/default.nix76
-rw-r--r--pkgs/test/dotnet/nuget-deps/default.nix44
-rw-r--r--pkgs/test/dotnet/nuget-deps/nuget-deps.nix6
-rw-r--r--pkgs/test/dotnet/project-references/default.nix12
-rw-r--r--pkgs/test/dotnet/structured-attrs/default.nix36
-rw-r--r--pkgs/test/dotnet/structured-attrs/nuget-deps.nix5
-rw-r--r--pkgs/test/dotnet/structured-attrs/src/Application.cs10
-rw-r--r--pkgs/test/dotnet/structured-attrs/src/Application.csproj5
-rw-r--r--pkgs/test/dotnet/use-dotnet-from-env/default.nix60
-rw-r--r--pkgs/test/dotnet/use-dotnet-from-env/nuget-deps.nix5
-rw-r--r--pkgs/test/dotnet/use-dotnet-from-env/src/Application.cs3
-rw-r--r--pkgs/test/dotnet/use-dotnet-from-env/src/Application.csproj5
-rw-r--r--pkgs/test/haskell/cabalSdist/default.nix24
-rw-r--r--pkgs/test/haskell/cabalSdist/local/generated.nix2
-rw-r--r--pkgs/test/haskell/setBuildTarget/default.nix10
-rw-r--r--pkgs/test/install-shell-files/default.nix126
-rw-r--r--pkgs/test/kernel.nix89
-rw-r--r--pkgs/test/make-binary-wrapper/default.nix19
-rw-r--r--pkgs/test/overriding.nix130
-rw-r--r--pkgs/test/release/default.nix24
-rw-r--r--pkgs/test/replace-vars/default.nix74
-rw-r--r--pkgs/test/replace-vars/source.txt5
-rw-r--r--pkgs/test/stdenv-inputs/default.nix4
-rw-r--r--pkgs/test/stdenv/default.nix112
-rw-r--r--pkgs/test/stdenv/patch-shebangs.nix14
-rw-r--r--pkgs/test/systemd/nixos/default.nix67
-rw-r--r--pkgs/test/texlive/default.nix12
-rw-r--r--pkgs/test/vim/default.nix5
39 files changed, 863 insertions, 430 deletions
diff --git a/pkgs/test/auto-patchelf-hook/package.nix b/pkgs/test/auto-patchelf-hook/package.nix
index be03ee68c0391..37413c7301eef 100644
--- a/pkgs/test/auto-patchelf-hook/package.nix
+++ b/pkgs/test/auto-patchelf-hook/package.nix
@@ -59,7 +59,9 @@ stdenv.mkDerivation {
 
   # Additional phase performing the actual test.
   installCheckPhase =
-    let allDeps = runtimeDependencies ++ [ (lib.getLib freetype) ];
+    let allDeps = runtimeDependencies ++ [
+        (lib.getLib freetype)
+      ];
     in
     ''
       local binary="$out/bin/ToneLib-Jam"
diff --git a/pkgs/test/cc-wrapper/default.nix b/pkgs/test/cc-wrapper/default.nix
index a0088751d4a24..3de359d15b4a7 100644
--- a/pkgs/test/cc-wrapper/default.nix
+++ b/pkgs/test/cc-wrapper/default.nix
@@ -3,9 +3,9 @@
 let
   # Sanitizers are not supported on Darwin.
   # Sanitizer headers aren't available in older libc++ stdenvs due to a bug
-  sanitizersWorking = (stdenv.buildPlatform == stdenv.hostPlatform) && !stdenv.isDarwin && !stdenv.hostPlatform.isMusl && (
+  sanitizersWorking = (stdenv.buildPlatform == stdenv.hostPlatform) && !stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isMusl && (
     (stdenv.cc.isClang && lib.versionAtLeast (lib.getVersion stdenv.cc.name) "5.0.0")
-    || (stdenv.cc.isGNU && stdenv.isLinux)
+    || (stdenv.cc.isGNU && stdenv.hostPlatform.isLinux)
   );
   staticLibc = lib.optionalString (stdenv.hostPlatform.libc == "glibc") "-L ${glibc.static}/lib";
   emulator = stdenv.hostPlatform.emulator buildPackages;
@@ -46,7 +46,18 @@ in stdenv.mkDerivation {
       $READELF -d ./atomics.so | grep libatomic.so && echo "ok" >&2 || echo "failed" >&2
     ''}
 
-    ${lib.optionalString (stdenv.isDarwin && stdenv.cc.isClang) ''
+    # Test that linking libc++ works, and statically.
+    ${lib.optionalString isCxx ''
+      echo "checking whether can link with libc++... " >&2
+      NIX_DEBUG=1 $CXX ${./cxx-main.cc} -c -o cxx-main.o
+      NIX_DEBUG=1 $CC cxx-main.o -lc++ -o cxx-main
+      NIX_DEBUG=1 $CC cxx-main.o ${lib.getLib stdenv.cc.libcxx}/lib/libc++.a -o cxx-main-static
+      ${emulator} ./cxx-main
+      ${emulator} ./cxx-main-static
+      rm cxx-main{,-static,.o}
+    ''}
+
+    ${lib.optionalString (stdenv.hostPlatform.isDarwin && stdenv.cc.isClang) ''
       echo "checking whether compiler can build with CoreFoundation.framework... " >&2
       mkdir -p foo/lib
       $CC -framework CoreFoundation -o core-foundation-check ${./core-foundation-main.c}
@@ -54,7 +65,7 @@ in stdenv.mkDerivation {
     ''}
 
 
-    ${lib.optionalString (!stdenv.isDarwin) ''
+    ${lib.optionalString (!stdenv.hostPlatform.isDarwin) ''
       echo "checking whether compiler builds valid static C binaries... " >&2
       $CC ${staticLibc} -static -o cc-static ${./cc-main.c}
       ${emulator} ./cc-static
@@ -95,7 +106,7 @@ in stdenv.mkDerivation {
     echo "checking whether compiler uses NIX_LDFLAGS... " >&2
     mkdir -p foo/lib
     $CC -shared \
-      ${lib.optionalString stdenv.isDarwin "-Wl,-install_name,@rpath/libfoo.dylib"} \
+      ${lib.optionalString stdenv.hostPlatform.isDarwin "-Wl,-install_name,@rpath/libfoo.dylib"} \
       -DVALUE=42 \
       -o foo/lib/libfoo${stdenv.hostPlatform.extensions.sharedLibrary} \
       ${./foo.c}
diff --git a/pkgs/test/cc-wrapper/hardening.nix b/pkgs/test/cc-wrapper/hardening.nix
index 41ddaefdfea8d..270e9a2e87616 100644
--- a/pkgs/test/cc-wrapper/hardening.nix
+++ b/pkgs/test/cc-wrapper/hardening.nix
@@ -3,6 +3,7 @@
 , runCommand
 , runCommandWith
 , runCommandCC
+, hello
 , debian-devscripts
 }:
 
@@ -18,6 +19,7 @@ let
       allowSubstitutes = false;
     } // env;
   } ''
+    [ -n "$postConfigure" ] && eval "$postConfigure"
     [ -n "$preBuild" ] && eval "$preBuild"
     n=$out/bin/test-bin
     mkdir -p "$(dirname "$n")"
@@ -29,10 +31,32 @@ let
   f2exampleWithStdEnv = writeCBinWithStdenv ./fortify2-example.c;
   f3exampleWithStdEnv = writeCBinWithStdenv ./fortify3-example.c;
 
+  # for when we need a slightly more complicated program
+  helloWithStdEnv = stdenv': env: (hello.override { stdenv = stdenv'; }).overrideAttrs ({
+    preBuild = ''
+      export CFLAGS="$TEST_EXTRA_FLAGS"
+    '';
+    NIX_DEBUG = "1";
+    postFixup = ''
+      cp $out/bin/hello $out/bin/test-bin
+    '';
+  } // env);
+
   stdenvUnsupport = additionalUnsupported: stdenv.override {
     cc = stdenv.cc.override {
-      cc = (lib.extendDerivation true {
-        hardeningUnsupportedFlags = (stdenv.cc.cc.hardeningUnsupportedFlags or []) ++ additionalUnsupported;
+      cc = (lib.extendDerivation true rec {
+        # this is ugly - have to cross-reference from
+        # hardeningUnsupportedFlagsByTargetPlatform to hardeningUnsupportedFlags
+        # because the finalAttrs mechanism that hardeningUnsupportedFlagsByTargetPlatform
+        # implementations use to do this won't work with lib.extendDerivation.
+        # but it's simplified by the fact that targetPlatform is already fixed
+        # at this point.
+        hardeningUnsupportedFlagsByTargetPlatform = _: hardeningUnsupportedFlags;
+        hardeningUnsupportedFlags = (
+          if stdenv.cc.cc ? hardeningUnsupportedFlagsByTargetPlatform
+          then stdenv.cc.cc.hardeningUnsupportedFlagsByTargetPlatform stdenv.targetPlatform
+          else (stdenv.cc.cc.hardeningUnsupportedFlags or [])
+        ) ++ additionalUnsupported;
       } stdenv.cc.cc);
     };
     allowedRequisites = null;
@@ -45,24 +69,39 @@ let
     ignorePie ? true,
     ignoreRelRO ? true,
     ignoreStackProtector ? true,
+    ignoreStackClashProtection ? true,
     expectFailure ? false,
   }: let
+    stackClashStr = "Stack clash protection: yes";
     expectFailureClause = lib.optionalString expectFailure
-      " && echo 'ERROR: Expected hardening-check to fail, but it passed!' >&2 && exit 1";
+      " && echo 'ERROR: Expected hardening-check to fail, but it passed!' >&2 && false";
   in runCommandCC "check-test-bin" {
     nativeBuildInputs = [ debian-devscripts ];
     buildInputs = [ testBin ];
-    meta.platforms = lib.platforms.linux;  # ELF-reliant
-  } ''
-    hardening-check --nocfprotection \
-      ${lib.optionalString ignoreBindNow "--nobindnow"} \
-      ${lib.optionalString ignoreFortify "--nofortify"} \
-      ${lib.optionalString ignorePie "--nopie"} \
-      ${lib.optionalString ignoreRelRO "--norelro"} \
-      ${lib.optionalString ignoreStackProtector "--nostackprotector"} \
-      $(PATH=$HOST_PATH type -P test-bin) ${expectFailureClause}
-    touch $out
-  '';
+    meta.platforms = if ignoreStackClashProtection
+      then lib.platforms.linux  # ELF-reliant
+      else [ "x86_64-linux" ];  # stackclashprotection test looks for x86-specific instructions
+  } (''
+    if ${lib.optionalString (!expectFailure) "!"} {
+      hardening-check --nocfprotection \
+        ${lib.optionalString ignoreBindNow "--nobindnow"} \
+        ${lib.optionalString ignoreFortify "--nofortify"} \
+        ${lib.optionalString ignorePie "--nopie"} \
+        ${lib.optionalString ignoreRelRO "--norelro"} \
+        ${lib.optionalString ignoreStackProtector "--nostackprotector"} \
+        $(PATH=$HOST_PATH type -P test-bin) | tee $out
+  '' + lib.optionalString (!ignoreStackClashProtection) ''
+      # stack clash protection doesn't actually affect the exit code of
+      # hardening-check (likely authors think false negatives too common)
+      { grep -F '${stackClashStr}' $out || { echo "Didn't find '${stackClashStr}' in output" && false ;} ;}
+  '' + ''
+    } ; then
+  '' + lib.optionalString expectFailure ''
+      echo 'ERROR: Expected hardening-check to fail, but it passed!' >&2
+  '' + ''
+      exit 2
+    fi
+  '');
 
   nameDrvAfterAttrName = builtins.mapAttrs (name: drv:
     drv.overrideAttrs (_: { name = "test-${name}"; })
@@ -151,6 +190,13 @@ in nameDrvAfterAttrName ({
     ignoreStackProtector = false;
   });
 
+  # protection patterns generated by clang not detectable?
+  stackClashProtectionExplicitEnabled = brokenIf stdenv.cc.isClang (checkTestBin (helloWithStdEnv stdenv {
+    hardeningEnable = [ "stackclashprotection" ];
+  }) {
+    ignoreStackClashProtection = false;
+  });
+
   bindNowExplicitDisabled = checkTestBin (f2exampleWithStdEnv stdenv {
     hardeningDisable = [ "bindnow" ];
   }) {
@@ -211,12 +257,19 @@ in nameDrvAfterAttrName ({
     expectFailure = true;
   };
 
+  stackClashProtectionExplicitDisabled = checkTestBin (helloWithStdEnv stdenv {
+    hardeningDisable = [ "stackclashprotection" ];
+  }) {
+    ignoreStackClashProtection = false;
+    expectFailure = true;
+  };
+
   # most flags can't be "unsupported" by compiler alone and
   # binutils doesn't have an accessible hardeningUnsupportedFlags
   # mechanism, so can only test a couple of flags through altered
   # stdenv trickery
 
-  fortifyStdenvUnsupp = checkTestBin (f2exampleWithStdEnv (stdenvUnsupport ["fortify"]) {
+  fortifyStdenvUnsupp = checkTestBin (f2exampleWithStdEnv (stdenvUnsupport ["fortify" "fortify3"]) {
     hardeningEnable = [ "fortify" ];
   }) {
     ignoreFortify = false;
@@ -237,13 +290,14 @@ in nameDrvAfterAttrName ({
     expectFailure = true;
   };
 
-  fortify3StdenvUnsuppDoesntUnsuppFortify = brokenIf stdenv.hostPlatform.isMusl (checkTestBin (f2exampleWithStdEnv (stdenvUnsupport ["fortify3"]) {
+  # musl implementation undetectable by this means even if present
+  fortify3StdenvUnsuppDoesntUnsuppFortify1 = brokenIf stdenv.hostPlatform.isMusl (checkTestBin (f1exampleWithStdEnv (stdenvUnsupport ["fortify3"]) {
     hardeningEnable = [ "fortify" ];
   }) {
     ignoreFortify = false;
   });
 
-  fortify3StdenvUnsuppDoesntUnsuppFortifyExecTest = fortifyExecTest (f2exampleWithStdEnv (stdenvUnsupport ["fortify3"]) {
+  fortify3StdenvUnsuppDoesntUnsuppFortify1ExecTest = fortifyExecTest (f1exampleWithStdEnv (stdenvUnsupport ["fortify3"]) {
     hardeningEnable = [ "fortify" ];
   });
 
@@ -254,12 +308,19 @@ in nameDrvAfterAttrName ({
     expectFailure = true;
   };
 
+  stackClashProtectionStdenvUnsupp = checkTestBin (helloWithStdEnv (stdenvUnsupport ["stackclashprotection"]) {
+    hardeningEnable = [ "stackclashprotection" ];
+  }) {
+    ignoreStackClashProtection = false;
+    expectFailure = true;
+  };
+
   # NIX_HARDENING_ENABLE set in the shell overrides hardeningDisable
   # and hardeningEnable
 
   stackProtectorReenabledEnv = checkTestBin (f2exampleWithStdEnv stdenv {
     hardeningDisable = [ "stackprotector" ];
-    preBuild = ''
+    postConfigure = ''
       export NIX_HARDENING_ENABLE="stackprotector"
     '';
   }) {
@@ -268,7 +329,7 @@ in nameDrvAfterAttrName ({
 
   stackProtectorReenabledFromAllEnv = checkTestBin (f2exampleWithStdEnv stdenv {
     hardeningDisable = [ "all" ];
-    preBuild = ''
+    postConfigure = ''
       export NIX_HARDENING_ENABLE="stackprotector"
     '';
   }) {
@@ -277,7 +338,7 @@ in nameDrvAfterAttrName ({
 
   stackProtectorRedisabledEnv = checkTestBin (f2exampleWithStdEnv stdenv {
     hardeningEnable = [ "stackprotector" ];
-    preBuild = ''
+    postConfigure = ''
       export NIX_HARDENING_ENABLE=""
     '';
   }) {
@@ -285,25 +346,26 @@ in nameDrvAfterAttrName ({
     expectFailure = true;
   };
 
-  fortify3EnabledEnvEnablesFortify = brokenIf stdenv.hostPlatform.isMusl (checkTestBin (f2exampleWithStdEnv stdenv {
+  # musl implementation undetectable by this means even if present
+  fortify3EnabledEnvEnablesFortify1 = brokenIf stdenv.hostPlatform.isMusl (checkTestBin (f1exampleWithStdEnv stdenv {
     hardeningDisable = [ "fortify" "fortify3" ];
-    preBuild = ''
+    postConfigure = ''
       export NIX_HARDENING_ENABLE="fortify3"
     '';
   }) {
     ignoreFortify = false;
   });
 
-  fortify3EnabledEnvEnablesFortifyExecTest = fortifyExecTest (f2exampleWithStdEnv stdenv {
+  fortify3EnabledEnvEnablesFortify1ExecTest = fortifyExecTest (f1exampleWithStdEnv stdenv {
     hardeningDisable = [ "fortify" "fortify3" ];
-    preBuild = ''
+    postConfigure = ''
       export NIX_HARDENING_ENABLE="fortify3"
     '';
   });
 
   fortifyEnabledEnvDoesntEnableFortify3 = checkTestBin (f3exampleWithStdEnv stdenv {
     hardeningDisable = [ "fortify" "fortify3" ];
-    preBuild = ''
+    postConfigure = ''
       export NIX_HARDENING_ENABLE="fortify"
     '';
   }) {
@@ -312,9 +374,8 @@ in nameDrvAfterAttrName ({
   };
 
   # NIX_HARDENING_ENABLE can't enable an unsupported feature
-
   stackProtectorUnsupportedEnabledEnv = checkTestBin (f2exampleWithStdEnv (stdenvUnsupport ["stackprotector"]) {
-    preBuild = ''
+    postConfigure = ''
       export NIX_HARDENING_ENABLE="stackprotector"
     '';
   }) {
@@ -322,23 +383,29 @@ in nameDrvAfterAttrName ({
     expectFailure = true;
   };
 
+  # current implementation prevents the command-line from disabling
+  # fortify if cc-wrapper is enabling it.
+
   # undetectable by this means on static even if present
   fortify1ExplicitEnabledCmdlineDisabled = brokenIf stdenv.hostPlatform.isStatic (checkTestBin (f1exampleWithStdEnv stdenv {
     hardeningEnable = [ "fortify" ];
-    preBuild = ''
+    postConfigure = ''
       export TEST_EXTRA_FLAGS='-D_FORTIFY_SOURCE=0'
     '';
   }) {
     ignoreFortify = false;
-    expectFailure = true;
+    expectFailure = false;
   });
 
+  # current implementation doesn't force-disable fortify if
+  # command-line enables it even if we use hardeningDisable.
+
   # musl implementation undetectable by this means even if present
   fortify1ExplicitDisabledCmdlineEnabled = brokenIf (
     stdenv.hostPlatform.isMusl || stdenv.hostPlatform.isStatic
   ) (checkTestBin (f1exampleWithStdEnv stdenv {
     hardeningDisable = [ "fortify" ];
-    preBuild = ''
+    postConfigure = ''
       export TEST_EXTRA_FLAGS='-D_FORTIFY_SOURCE=1'
     '';
   }) {
@@ -347,14 +414,14 @@ in nameDrvAfterAttrName ({
 
   fortify1ExplicitDisabledCmdlineEnabledExecTest = fortifyExecTest (f1exampleWithStdEnv stdenv {
     hardeningDisable = [ "fortify" ];
-    preBuild = ''
+    postConfigure = ''
       export TEST_EXTRA_FLAGS='-D_FORTIFY_SOURCE=1'
     '';
   });
 
   fortify1ExplicitEnabledCmdlineDisabledNoWarn = f1exampleWithStdEnv stdenv {
     hardeningEnable = [ "fortify" ];
-    preBuild = ''
+    postConfigure = ''
       export TEST_EXTRA_FLAGS='-D_FORTIFY_SOURCE=0 -Werror'
     '';
   };
@@ -393,4 +460,9 @@ in {
     ignoreStackProtector = false;
     expectFailure = true;
   };
+
+  allExplicitDisabledStackClashProtection = checkTestBin tb {
+    ignoreStackClashProtection = false;
+    expectFailure = true;
+  };
 }))
diff --git a/pkgs/test/check-by-name/README.md b/pkgs/test/check-by-name/README.md
deleted file mode 100644
index c68e7a93b7d0e..0000000000000
--- a/pkgs/test/check-by-name/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# `pkgs/by-name` check CI scripts
-
-This directory contains scripts and files used and related to the CI running the `pkgs/by-name` checks in Nixpkgs.
-See also the [CI GitHub Action](../../../.github/workflows/check-by-name.yml).
-
-## `./run-local.sh BASE_BRANCH [REPOSITORY]`
-
-Runs the `pkgs/by-name` check on the HEAD commit, closely matching what CI does.
-
-Note that this can't do exactly the same as CI,
-because CI needs to rely on GitHub's server-side Git history to compute the mergeability of PRs before the check can be started.
-In turn when running locally, we don't want to have to push commits to test them,
-and we can also rely on the local Git history to do the mergeability check.
-
-Arguments:
-- `BASE_BRANCH`: The base branch to use, e.g. master or release-23.11
-- `REPOSITORY`: The repository to fetch the base branch from, defaults to https://github.com/NixOS/nixpkgs.git
-
-## `./update-pinned-tool.sh`
-
-Updates the pinned [nixpkgs-check-by-name tool](https://github.com/NixOS/nixpkgs-check-by-name) in [`./pinned-version.txt`](./pinned-version.txt) to the latest [release](https://github.com/NixOS/nixpkgs-check-by-name/releases).
-Each release contains a pre-built x86_64-linux version of the tool which is used by CI.
-
-This script currently needs to be called manually when the CI tooling needs to be updated.
-
-Why not just build the tooling right from the PRs Nixpkgs version?
-- Because it allows CI to check all PRs, even if they would break the CI tooling.
-- Because it makes the CI check very fast, since no Nix builds need to be done, even for mass rebuilds.
-- Because it improves security, since we don't have to build potentially untrusted code from PRs.
-  The tool only needs a very minimal Nix evaluation at runtime, which can work with [readonly-mode](https://nixos.org/manual/nix/stable/command-ref/opt-common.html#opt-readonly-mode) and [restrict-eval](https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-restrict-eval).
-
diff --git a/pkgs/test/check-by-name/pinned-version.txt b/pkgs/test/check-by-name/pinned-version.txt
index 17e51c385ea38..d917d3e26adc9 100644
--- a/pkgs/test/check-by-name/pinned-version.txt
+++ b/pkgs/test/check-by-name/pinned-version.txt
@@ -1 +1 @@
-0.1.1
+0.1.2
diff --git a/pkgs/test/check-by-name/run-local.sh b/pkgs/test/check-by-name/run-local.sh
deleted file mode 100755
index b1b662046bf39..0000000000000
--- a/pkgs/test/check-by-name/run-local.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env nix-shell
-#!nix-shell -i bash -p jq
-
-set -o pipefail -o errexit -o nounset
-
-trace() { echo >&2 "$@"; }
-
-tmp=$(mktemp -d)
-cleanup() {
-    # Don't exit early if anything fails to cleanup
-    set +o errexit
-
-    trace -n "Cleaning up.. "
-
-    [[ -e "$tmp/base" ]] && git worktree remove --force "$tmp/base"
-    [[ -e "$tmp/merged" ]] && git worktree remove --force "$tmp/merged"
-
-    rm -rf "$tmp"
-
-    trace "Done"
-}
-trap cleanup exit
-
-
-repo=https://github.com/NixOS/nixpkgs.git
-
-if (( $# != 0 )); then
-    baseBranch=$1
-    shift
-else
-    trace "Usage: $0 BASE_BRANCH [REPOSITORY]"
-    trace "BASE_BRANCH: The base branch to use, e.g. master or release-23.11"
-    trace "REPOSITORY: The repository to fetch the base branch from, defaults to $repo"
-    exit 1
-fi
-
-if (( $# != 0 )); then
-    repo=$1
-    shift
-fi
-
-if [[ -n "$(git status --porcelain)" ]]; then
-    trace -e "\e[33mWarning: Dirty tree, uncommitted changes won't be taken into account\e[0m"
-fi
-headSha=$(git rev-parse HEAD)
-trace -e "Using HEAD commit \e[34m$headSha\e[0m"
-
-trace -n "Creating Git worktree for the HEAD commit in $tmp/merged.. "
-git worktree add --detach -q "$tmp/merged" HEAD
-trace "Done"
-
-trace -n "Fetching base branch $baseBranch to compare against.. "
-git fetch -q "$repo" refs/heads/"$baseBranch"
-baseSha=$(git rev-parse FETCH_HEAD)
-trace -e "\e[34m$baseSha\e[0m"
-
-trace -n "Creating Git worktree for the base branch in $tmp/base.. "
-git worktree add -q "$tmp/base" "$baseSha"
-trace "Done"
-
-trace -n "Merging base branch into the HEAD commit in $tmp/merged.. "
-git -C "$tmp/merged" merge -q --no-edit "$baseSha"
-trace -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m"
-
-trace -n "Reading pinned nixpkgs-check-by-name version from pinned-version.txt.. "
-toolVersion=$(<"$tmp/merged/pkgs/test/check-by-name/pinned-version.txt")
-trace -e "\e[34m$toolVersion\e[0m"
-
-trace -n "Building tool.. "
-nix-build https://github.com/NixOS/nixpkgs-check-by-name/tarball/"$toolVersion" -o "$tmp/tool" -A build
-
-trace "Running nixpkgs-check-by-name.."
-"$tmp/tool/bin/nixpkgs-check-by-name" --base "$tmp/base" "$tmp/merged"
diff --git a/pkgs/test/check-by-name/update-pinned-tool.sh b/pkgs/test/check-by-name/update-pinned-tool.sh
deleted file mode 100755
index 7240bd597f131..0000000000000
--- a/pkgs/test/check-by-name/update-pinned-tool.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env nix-shell
-#!nix-shell -i bash -p jq curl
-
-set -o pipefail -o errexit -o nounset
-
-trace() { echo >&2 "$@"; }
-
-SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
-
-repository=NixOS/nixpkgs-check-by-name
-pin_file=$SCRIPT_DIR/pinned-version.txt
-
-trace -n "Fetching latest release of $repository.. "
-latestRelease=$(curl -sSfL \
-  -H "Accept: application/vnd.github+json" \
-  -H "X-GitHub-Api-Version: 2022-11-28" \
-  https://api.github.com/repos/"$repository"/releases/latest)
-latestVersion=$(jq .tag_name -r <<< "$latestRelease")
-trace "$latestVersion"
-
-trace "Updating $pin_file"
-echo "$latestVersion" > "$pin_file"
diff --git a/pkgs/test/cuda/default.nix b/pkgs/test/cuda/default.nix
index dd9ad8b814dc5..b6d9ec4294c02 100644
--- a/pkgs/test/cuda/default.nix
+++ b/pkgs/test/cuda/default.nix
@@ -3,7 +3,6 @@
   recurseIntoAttrs,
 
   cudaPackages,
-  cudaPackagesGoogle,
 
   cudaPackages_10_0,
   cudaPackages_10_1,
@@ -43,7 +42,6 @@ in
     _: ps:
     lib.pipe ps [
       (lib.filterAttrs isTest)
-      (as: as // { __attrsFailEvaluation = true; })
       recurseIntoAttrs
     ]
   ))
diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix
index 2b978ff3e1bcf..adb112fd36680 100644
--- a/pkgs/test/default.nix
+++ b/pkgs/test/default.nix
@@ -12,7 +12,6 @@ with pkgs;
         # Are throw aliases.
         (filter (n: n != "llvmPackages_rocm"))
         (filter (n: n != "llvmPackages_latest"))
-        (filter (n: n != "llvmPackages_git"))
         (filter (n: n != "llvmPackages_6"))
         (filter (n: n != "llvmPackages_7"))
         (filter (n: n != "llvmPackages_8"))
@@ -49,7 +48,6 @@ with pkgs;
           sets = lib.pipe gccTests ([
             (filterAttrs (_: v: lib.meta.availableOn stdenv.hostPlatform v.stdenv.cc))
             # Broken
-            (filterAttrs (n: _: n != "gcc49Stdenv"))
             (filterAttrs (n: _: n != "gccMultiStdenv"))
           ] ++ lib.optionals (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64) [
             # fails with things like
@@ -83,6 +81,8 @@ with pkgs;
     inherit gccTests;
   };
 
+  devShellTools = callPackage ../build-support/dev-shell-tools/tests { };
+
   stdenv-inputs = callPackage ./stdenv-inputs { };
   stdenv = callPackage ./stdenv { };
 
@@ -105,6 +105,8 @@ with pkgs;
   cc-multilib-gcc = callPackage ./cc-wrapper/multilib.nix { stdenv = gccMultiStdenv; };
   cc-multilib-clang = callPackage ./cc-wrapper/multilib.nix { stdenv = clangMultiStdenv; };
 
+  compress-drv = callPackage ../build-support/compress-drv/test.nix { };
+
   fetchurl = callPackages ../build-support/fetchurl/tests.nix { };
   fetchtorrent = callPackages ../build-support/fetchtorrent/tests.nix { };
   fetchpatch = callPackages ../build-support/fetchpatch/tests.nix { };
@@ -165,7 +167,7 @@ with pkgs;
     makeBinaryWrapper = pkgs.makeBinaryWrapper.override {
       # Enable sanitizers in the tests only, to avoid the performance cost in regular usage.
       # The sanitizers cause errors on aarch64-darwin, see https://github.com/NixOS/nixpkgs/pull/150079#issuecomment-994132734
-      sanitizers = pkgs.lib.optionals (! (pkgs.stdenv.isDarwin && pkgs.stdenv.isAarch64))
+      sanitizers = pkgs.lib.optionals (! (pkgs.stdenv.hostPlatform.isDarwin && pkgs.stdenv.hostPlatform.isAarch64))
         [ "undefined" "address" ];
     };
   };
@@ -180,5 +182,7 @@ with pkgs;
 
   systemd = callPackage ./systemd { };
 
+  replaceVars = recurseIntoAttrs (callPackage ./replace-vars { });
+
   substitute = recurseIntoAttrs (callPackage ./substitute { });
 }
diff --git a/pkgs/test/dhall/buildDhallUrl/default.nix b/pkgs/test/dhall/buildDhallUrl/default.nix
index a75101a303d64..f266cde11a516 100644
--- a/pkgs/test/dhall/buildDhallUrl/default.nix
+++ b/pkgs/test/dhall/buildDhallUrl/default.nix
@@ -1,4 +1,4 @@
-{ dhallPackages, lib }:
+{ dhallPackages }:
 
 # This file tests that dhallPackages.buildDhallUrl is able to successfully
 # build a Nix Dhall package for a given remote Dhall import.
diff --git a/pkgs/test/dotnet/default.nix b/pkgs/test/dotnet/default.nix
index 7592b09d76e3c..601cf5c15e4e8 100644
--- a/pkgs/test/dotnet/default.nix
+++ b/pkgs/test/dotnet/default.nix
@@ -1,5 +1,9 @@
-{ callPackage }:
+{ lib, callPackage }:
 
 {
   project-references = callPackage ./project-references { };
+  use-dotnet-from-env = lib.recurseIntoAttrs (callPackage ./use-dotnet-from-env { });
+  structured-attrs = lib.recurseIntoAttrs (callPackage ./structured-attrs { });
+  final-attrs = lib.recurseIntoAttrs (callPackage ./final-attrs { });
+  nuget-deps = lib.recurseIntoAttrs (callPackage ./nuget-deps { });
 }
diff --git a/pkgs/test/dotnet/final-attrs/default.nix b/pkgs/test/dotnet/final-attrs/default.nix
new file mode 100644
index 0000000000000..cfc476361157e
--- /dev/null
+++ b/pkgs/test/dotnet/final-attrs/default.nix
@@ -0,0 +1,76 @@
+{
+  lib,
+  dotnet-sdk,
+  buildPackages, # buildDotnetModule
+  testers,
+  runCommand,
+}:
+let
+  copyrightString = "Original Copyright";
+  originalCopyright = builtins.toFile "original-copyright.txt" copyrightString;
+  overridenCopyright = builtins.toFile "overridden-copyright.txt" (
+    copyrightString + " with override!"
+  );
+
+  inherit (buildPackages) buildDotnetModule;
+
+  app-recursive = buildDotnetModule (finalAttrs: {
+    name = "final-attrs-rec-test-application";
+    src = ../structured-attrs/src;
+    nugetDeps = ../structured-attrs/nuget-deps.nix;
+    dotnetFlags = [ "--property:Copyright=${finalAttrs.passthru.copyrightString}" ];
+    env.TargetFramework = "net${lib.versions.majorMinor (lib.getVersion dotnet-sdk)}";
+    __structuredAttrs = true;
+    passthru = {
+      inherit copyrightString;
+    };
+  });
+
+  app-const = buildDotnetModule {
+    name = "final-attrs-const-test-application";
+    src = ../structured-attrs/src;
+    nugetDeps = ../structured-attrs/nuget-deps.nix;
+    dotnetFlags = [ "--property:Copyright=${copyrightString}" ];
+    env.TargetFramework = "net${lib.versions.majorMinor (lib.getVersion dotnet-sdk)}";
+    __structuredAttrs = true;
+    passthru = {
+      inherit copyrightString;
+    };
+  };
+
+  override =
+    app:
+    app.overrideAttrs (previousAttrs: {
+      passthru = previousAttrs.passthru // {
+        copyrightString = previousAttrs.passthru.copyrightString + " with override!";
+      };
+    });
+
+  run =
+    name: app:
+    runCommand name { } ''
+      ${app}/bin/Application >"$out"
+    '';
+in
+{
+  check-output = testers.testEqualContents {
+    assertion = "buildDotnetModule produces the expected output when called with a recursive function";
+    expected = originalCopyright;
+    actual = run "dotnet-final-attrs-test-rec-output" app-recursive;
+  };
+  output-matches-const = testers.testEqualContents {
+    assertion = "buildDotnetModule produces the same output when called with attrs or a recursive function";
+    expected = run "dotnet-final-attrs-test-const" app-const;
+    actual = run "dotnet-final-attrs-test-rec" app-recursive;
+  };
+  override-has-no-effect = testers.testEqualContents {
+    assertion = "buildDotnetModule produces the expected output when called with a recursive function";
+    expected = originalCopyright;
+    actual = run "dotnet-final-attrs-test-override-const-output" (override app-const);
+  };
+  override-modifies-output = testers.testEqualContents {
+    assertion = "buildDotnetModule produces the expected output when called with a recursive function";
+    expected = overridenCopyright;
+    actual = run "dotnet-final-attrs-test-override-rec-output" (override app-recursive);
+  };
+}
diff --git a/pkgs/test/dotnet/nuget-deps/default.nix b/pkgs/test/dotnet/nuget-deps/default.nix
new file mode 100644
index 0000000000000..bf0e1445e93eb
--- /dev/null
+++ b/pkgs/test/dotnet/nuget-deps/default.nix
@@ -0,0 +1,44 @@
+# Tests that `nugetDeps` in buildDotnetModule can handle various types.
+
+{
+  lib,
+  dotnet-sdk,
+  buildPackages, # buildDotnetModule
+  runCommand,
+}:
+
+let
+  inherit (lib)
+    mapAttrs
+    ;
+
+  inherit (buildPackages)
+    emptyDirectory
+    buildDotnetModule
+    ;
+
+in
+mapAttrs
+  (
+    name: nugetDeps:
+    buildDotnetModule {
+      name = "nuget-deps-${name}";
+      unpackPhase = ''
+        runHook preUnpack
+
+        mkdir test
+        cd test
+        dotnet new console -o .
+        ls -l
+
+        runHook postUnpack
+      '';
+      inherit nugetDeps;
+    }
+  )
+  {
+    "null" = null;
+    "file" = ./nuget-deps.nix;
+    "derivation" = emptyDirectory;
+    "list" = [ emptyDirectory ];
+  }
diff --git a/pkgs/test/dotnet/nuget-deps/nuget-deps.nix b/pkgs/test/dotnet/nuget-deps/nuget-deps.nix
new file mode 100644
index 0000000000000..dbfecc1b26058
--- /dev/null
+++ b/pkgs/test/dotnet/nuget-deps/nuget-deps.nix
@@ -0,0 +1,6 @@
+# This file was automatically generated by passthru.fetch-deps.
+# Please dont edit it manually, your changes might get overwritten!
+
+{ fetchNuGet }:
+[
+]
diff --git a/pkgs/test/dotnet/project-references/default.nix b/pkgs/test/dotnet/project-references/default.nix
index f40b9196c2091..762686a7d01ff 100644
--- a/pkgs/test/dotnet/project-references/default.nix
+++ b/pkgs/test/dotnet/project-references/default.nix
@@ -4,11 +4,13 @@
 
 { lib
 , dotnet-sdk
-, buildDotnetModule
+, buildPackages # buildDotnetModule
 , runCommand
 }:
 
 let
+  inherit (buildPackages) buildDotnetModule;
+
   nugetDeps = ./nuget-deps.nix;
 
   # Specify the TargetFramework via an environment variable so that we don't
@@ -18,7 +20,8 @@ let
   library = buildDotnetModule {
     name = "project-references-test-library";
     src = ./library;
-    inherit nugetDeps TargetFramework;
+    inherit nugetDeps;
+    env.TargetFramework = TargetFramework;
 
     packNupkg = true;
   };
@@ -26,7 +29,8 @@ let
   application = buildDotnetModule {
     name = "project-references-test-application";
     src = ./application;
-    inherit nugetDeps TargetFramework;
+    inherit nugetDeps;
+    env.TargetFramework = TargetFramework;
 
     projectReferences = [ library ];
   };
@@ -34,5 +38,5 @@ in
 
 runCommand "project-references-test" { } ''
   ${application}/bin/Application
-  touch $out
+  mkdir $out
 ''
diff --git a/pkgs/test/dotnet/structured-attrs/default.nix b/pkgs/test/dotnet/structured-attrs/default.nix
new file mode 100644
index 0000000000000..cf96fef8dbdcc
--- /dev/null
+++ b/pkgs/test/dotnet/structured-attrs/default.nix
@@ -0,0 +1,36 @@
+{ lib
+, dotnet-sdk
+, buildPackages # buildDotnetModule
+, testers
+, runCommand
+}:
+let
+  # Note: without structured attributes, we can’t use derivation arguments that
+  # contain spaces unambiguously because arguments are passed as space-separated
+  # environment variables.
+  copyrightString = "Public domain 🅮";
+
+  inherit (buildPackages) buildDotnetModule;
+
+  app = buildDotnetModule {
+    name = "structured-attrs-test-application";
+    src = ./src;
+    nugetDeps = ./nuget-deps.nix;
+    dotnetFlags = [ "--property:Copyright=${copyrightString}" ];
+    env.TargetFramework = "net${lib.versions.majorMinor (lib.getVersion dotnet-sdk)}";
+    __structuredAttrs = true;
+  };
+in
+{
+  no-structured-attrs = testers.testBuildFailure (app.overrideAttrs {
+    __structuredAttrs = false;
+  });
+
+  check-output = testers.testEqualContents {
+    assertion = "buildDotnetModule sets AssemblyCopyrightAttribute with structured attributes";
+    expected = builtins.toFile "expected-copyright.txt" copyrightString;
+    actual = runCommand "dotnet-structured-attrs-test" { } ''
+      ${app}/bin/Application >"$out"
+    '';
+  };
+}
diff --git a/pkgs/test/dotnet/structured-attrs/nuget-deps.nix b/pkgs/test/dotnet/structured-attrs/nuget-deps.nix
new file mode 100644
index 0000000000000..f3a17967e25c8
--- /dev/null
+++ b/pkgs/test/dotnet/structured-attrs/nuget-deps.nix
@@ -0,0 +1,5 @@
+# This file was automatically generated by passthru.fetch-deps.
+# Please dont edit it manually, your changes might get overwritten!
+
+{ fetchNuGet }: [
+]
diff --git a/pkgs/test/dotnet/structured-attrs/src/Application.cs b/pkgs/test/dotnet/structured-attrs/src/Application.cs
new file mode 100644
index 0000000000000..3bc548105c2b4
--- /dev/null
+++ b/pkgs/test/dotnet/structured-attrs/src/Application.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Reflection;
+
+Console.Write(
+    (
+        (AssemblyCopyrightAttribute)Assembly
+            .GetExecutingAssembly()
+            .GetCustomAttributes(typeof(AssemblyCopyrightAttribute), true)[0]
+    ).Copyright
+);
diff --git a/pkgs/test/dotnet/structured-attrs/src/Application.csproj b/pkgs/test/dotnet/structured-attrs/src/Application.csproj
new file mode 100644
index 0000000000000..decaa6d961aab
--- /dev/null
+++ b/pkgs/test/dotnet/structured-attrs/src/Application.csproj
@@ -0,0 +1,5 @@
+<Project Sdk="Microsoft.NET.Sdk">
+    <PropertyGroup>
+        <OutputType>exe</OutputType>
+    </PropertyGroup>
+</Project>
diff --git a/pkgs/test/dotnet/use-dotnet-from-env/default.nix b/pkgs/test/dotnet/use-dotnet-from-env/default.nix
new file mode 100644
index 0000000000000..711a98eb0c29d
--- /dev/null
+++ b/pkgs/test/dotnet/use-dotnet-from-env/default.nix
@@ -0,0 +1,60 @@
+{ lib
+, dotnet-sdk
+, buildPackages # buildDotnetModule, dotnet-runtime
+, testers
+, runCommand
+, removeReferencesTo
+}:
+let
+  inherit (buildPackages) buildDotnetModule dotnet-runtime;
+
+  app = buildDotnetModule {
+    name = "use-dotnet-from-env-test-application";
+    src = ./src;
+    nugetDeps = ./nuget-deps.nix;
+    useDotnetFromEnv = true;
+    env.TargetFramework = "net${lib.versions.majorMinor (lib.getVersion dotnet-sdk)}";
+  };
+
+  appWithoutFallback = app.overrideAttrs (oldAttrs: {
+    nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ]) ++ [
+      removeReferencesTo
+    ];
+    postFixup = (oldAttrs.postFixup or "") + ''
+      remove-references-to -t ${dotnet-runtime} "$out/bin/Application"
+    '';
+  });
+
+  runtimeVersion = lib.getVersion dotnet-runtime;
+  runtimeVersionFile = builtins.toFile "dotnet-version.txt" runtimeVersion;
+in
+{
+  fallback = testers.testEqualContents {
+    assertion = "buildDotnetModule sets fallback DOTNET_ROOT in wrapper";
+    expected = runtimeVersionFile;
+    actual = runCommand "use-dotnet-from-env-fallback-test" { } ''
+      ${app}/bin/Application >"$out"
+    '';
+  };
+
+  # Check that appWithoutFallback does not use fallback .NET runtime.
+  without-fallback = testers.testBuildFailure (runCommand "use-dotnet-from-env-without-fallback-test" { } ''
+    ${appWithoutFallback}/bin/Application >"$out"
+  '');
+
+  # NB assumes that without-fallback above to passes.
+  use-dotnet-root-env = testers.testEqualContents {
+    assertion = "buildDotnetModule uses DOTNET_ROOT from environment in wrapper";
+    expected = runtimeVersionFile;
+    actual = runCommand "use-dotnet-from-env-root-test" { env.DOTNET_ROOT = dotnet-runtime; } ''
+      ${appWithoutFallback}/bin/Application >"$out"
+    '';
+  };
+  use-dotnet-path-env = testers.testEqualContents {
+    assertion = "buildDotnetModule uses DOTNET_ROOT from dotnet in PATH in wrapper";
+    expected = runtimeVersionFile;
+    actual = runCommand "use-dotnet-from-env-path-test" { dotnetRuntime = dotnet-runtime; } ''
+      PATH=$dotnetRuntime''${PATH+:}$PATH ${appWithoutFallback}/bin/Application >"$out"
+    '';
+  };
+}
diff --git a/pkgs/test/dotnet/use-dotnet-from-env/nuget-deps.nix b/pkgs/test/dotnet/use-dotnet-from-env/nuget-deps.nix
new file mode 100644
index 0000000000000..f3a17967e25c8
--- /dev/null
+++ b/pkgs/test/dotnet/use-dotnet-from-env/nuget-deps.nix
@@ -0,0 +1,5 @@
+# This file was automatically generated by passthru.fetch-deps.
+# Please dont edit it manually, your changes might get overwritten!
+
+{ fetchNuGet }: [
+]
diff --git a/pkgs/test/dotnet/use-dotnet-from-env/src/Application.cs b/pkgs/test/dotnet/use-dotnet-from-env/src/Application.cs
new file mode 100644
index 0000000000000..5efc571ca9a3e
--- /dev/null
+++ b/pkgs/test/dotnet/use-dotnet-from-env/src/Application.cs
@@ -0,0 +1,3 @@
+using System;
+
+Console.Write(Environment.Version.ToString());
diff --git a/pkgs/test/dotnet/use-dotnet-from-env/src/Application.csproj b/pkgs/test/dotnet/use-dotnet-from-env/src/Application.csproj
new file mode 100644
index 0000000000000..decaa6d961aab
--- /dev/null
+++ b/pkgs/test/dotnet/use-dotnet-from-env/src/Application.csproj
@@ -0,0 +1,5 @@
+<Project Sdk="Microsoft.NET.Sdk">
+    <PropertyGroup>
+        <OutputType>exe</OutputType>
+    </PropertyGroup>
+</Project>
diff --git a/pkgs/test/haskell/cabalSdist/default.nix b/pkgs/test/haskell/cabalSdist/default.nix
index 1031e51e4f141..4432e95ab56ec 100644
--- a/pkgs/test/haskell/cabalSdist/default.nix
+++ b/pkgs/test/haskell/cabalSdist/default.nix
@@ -1,7 +1,18 @@
-{ lib, haskellPackages, runCommand }:
+{ lib, haskell, haskellPackages, runCommand }:
 
 let
-  localRaw = haskellPackages.callPackage ./local/generated.nix {};
+  src = lib.fileset.toSource {
+    root = ./local;
+    fileset = lib.fileset.unions [
+      ./local/app
+      ./local/CHANGELOG.md
+      ./local/local.cabal
+    ];
+  };
+  # This prevents the source from depending on the formatting of the ./local/generated.nix file
+  localRaw = haskell.lib.compose.overrideSrc {
+    inherit src;
+  } (haskellPackages.callPackage ./local/generated.nix {});
 in
 lib.recurseIntoAttrs rec {
 
@@ -12,17 +23,22 @@ lib.recurseIntoAttrs rec {
 
   localFromCabalSdist = haskellPackages.buildFromCabalSdist localRaw;
 
+  # NOTE: ./local refers to the "./." path in `./local/generated.nix`.
+  # This test makes sure that localHasNoDirectReference can actually fail if
+  # it doesn't do anything. If this test fails, either the test setup was broken,
+  # or Haskell packaging has changed the way `src` is treated in such a way that
+  # either the test or the design of `buildFromCabalSdist` needs to be reconsidered.
   assumptionLocalHasDirectReference = runCommand "localHasDirectReference" {
     drvPath = builtins.unsafeDiscardOutputDependency localRaw.drvPath;
   } ''
-    grep ${./local} $drvPath >/dev/null
+    grep ${src} $drvPath >/dev/null
     touch $out
   '';
 
   localHasNoDirectReference = runCommand "localHasNoDirectReference" {
     drvPath = builtins.unsafeDiscardOutputDependency localFromCabalSdist.drvPath;
   } ''
-    grep -v ${./local} $drvPath >/dev/null
+    grep -v ${src} $drvPath >/dev/null
     touch $out
   '';
 }
diff --git a/pkgs/test/haskell/cabalSdist/local/generated.nix b/pkgs/test/haskell/cabalSdist/local/generated.nix
index bfa299962bcb4..fae1e45f3d978 100644
--- a/pkgs/test/haskell/cabalSdist/local/generated.nix
+++ b/pkgs/test/haskell/cabalSdist/local/generated.nix
@@ -3,7 +3,7 @@
 mkDerivation {
   pname = "local";
   version = "0.1.0.0";
-  src = ./.;
+  src = ./.; # also referred to as ./local in the test; these are the same path constants
   isLibrary = false;
   isExecutable = true;
   executableHaskellDepends = [ base ];
diff --git a/pkgs/test/haskell/setBuildTarget/default.nix b/pkgs/test/haskell/setBuildTarget/default.nix
index f0c78c5104499..39d5db698bcd0 100644
--- a/pkgs/test/haskell/setBuildTarget/default.nix
+++ b/pkgs/test/haskell/setBuildTarget/default.nix
@@ -7,7 +7,15 @@ let
       mkDerivation {
         pname = "haskell-setBuildTarget";
         version = "0.1.0.0";
-        src = ./.;
+        src = lib.fileset.toSource {
+          root = ./.;
+          fileset = lib.fileset.unions [
+            ./haskell-setBuildTarget.cabal
+            ./Bar.hs
+            ./Foo.hs
+            ./Setup.hs
+          ];
+        };
         isLibrary = false;
         isExecutable = true;
         executableHaskellDepends = [ base ];
diff --git a/pkgs/test/install-shell-files/default.nix b/pkgs/test/install-shell-files/default.nix
index aef5acc1de6bf..21894698fe1bb 100644
--- a/pkgs/test/install-shell-files/default.nix
+++ b/pkgs/test/install-shell-files/default.nix
@@ -1,125 +1,3 @@
-{ lib, runCommandLocal, recurseIntoAttrs, installShellFiles }:
+{ installShellFiles }:
 
-let
-  runTest = name: env: buildCommand:
-    runCommandLocal "install-shell-files--${name}" ({
-      nativeBuildInputs = [ installShellFiles ];
-      meta.platforms = lib.platforms.all;
-    } // env) buildCommand;
-in
-
-recurseIntoAttrs {
-  # installManPage
-
-  install-manpage = runTest "install-manpage" {} ''
-    mkdir -p doc
-    echo foo > doc/foo.1
-    echo bar > doc/bar.2.gz
-    echo baz > doc/baz.3
-
-    installManPage doc/*
-
-    cmp doc/foo.1 $out/share/man/man1/foo.1
-    cmp doc/bar.2.gz $out/share/man/man2/bar.2.gz
-    cmp doc/baz.3 $out/share/man/man3/baz.3
-  '';
-  install-manpage-outputs = runTest "install-manpage-outputs" {
-    outputs = [ "out" "man" "devman" ];
-  } ''
-    mkdir -p doc
-    echo foo > doc/foo.1
-    echo bar > doc/bar.3
-
-    installManPage doc/*
-
-    # assert they didn't go into $out
-    [[ ! -f $out/share/man/man1/foo.1 && ! -f $out/share/man/man3/bar.3 ]]
-
-    # foo.1 alone went into man
-    cmp doc/foo.1 ''${!outputMan:?}/share/man/man1/foo.1
-    [[ ! -f ''${!outputMan:?}/share/man/man3/bar.3 ]]
-
-    # bar.3 alone went into devman
-    cmp doc/bar.3 ''${!outputDevman:?}/share/man/man3/bar.3
-    [[ ! -f ''${!outputDevman:?}/share/man/man1/foo.1 ]]
-
-    touch $out
-  '';
-
-  # installShellCompletion
-
-  install-completion = runTest "install-completion" {} ''
-    echo foo > foo
-    echo bar > bar
-    echo baz > baz
-    echo qux > qux.zsh
-    echo quux > quux
-
-    installShellCompletion --bash foo bar --zsh baz qux.zsh --fish quux
-
-    cmp foo $out/share/bash-completion/completions/foo
-    cmp bar $out/share/bash-completion/completions/bar
-    cmp baz $out/share/zsh/site-functions/_baz
-    cmp qux.zsh $out/share/zsh/site-functions/_qux
-    cmp quux $out/share/fish/vendor_completions.d/quux
-  '';
-  install-completion-output = runTest "install-completion-output" {
-    outputs = [ "out" "bin" ];
-  } ''
-    echo foo > foo
-
-    installShellCompletion --bash foo
-
-    # assert it didn't go into $out
-    [[ ! -f $out/share/bash-completion/completions/foo ]]
-
-    cmp foo ''${!outputBin:?}/share/bash-completion/completions/foo
-
-    touch $out
-  '';
-  install-completion-name = runTest "install-completion-name" {} ''
-    echo foo > foo
-    echo bar > bar
-    echo baz > baz
-
-    installShellCompletion --bash --name foobar.bash foo --zsh --name _foobar bar --fish baz
-
-    cmp foo $out/share/bash-completion/completions/foobar.bash
-    cmp bar $out/share/zsh/site-functions/_foobar
-    cmp baz $out/share/fish/vendor_completions.d/baz
-  '';
-  install-completion-inference = runTest "install-completion-inference" {} ''
-    echo foo > foo.bash
-    echo bar > bar.zsh
-    echo baz > baz.fish
-
-    installShellCompletion foo.bash bar.zsh baz.fish
-
-    cmp foo.bash $out/share/bash-completion/completions/foo.bash
-    cmp bar.zsh $out/share/zsh/site-functions/_bar
-    cmp baz.fish $out/share/fish/vendor_completions.d/baz.fish
-  '';
-  install-completion-cmd = runTest "install-completion-cmd" {} ''
-    echo foo > foo.bash
-    echo bar > bar.zsh
-    echo baz > baz.fish
-    echo qux > qux.fish
-
-    installShellCompletion --cmd foobar --bash foo.bash --zsh bar.zsh --fish baz.fish --name qux qux.fish
-
-    cmp foo.bash $out/share/bash-completion/completions/foobar.bash
-    cmp bar.zsh $out/share/zsh/site-functions/_foobar
-    cmp baz.fish $out/share/fish/vendor_completions.d/foobar.fish
-    cmp qux.fish $out/share/fish/vendor_completions.d/qux
-  '';
-  install-completion-fifo = runTest "install-completion-fifo" {} ''
-    installShellCompletion \
-      --bash --name foo.bash <(echo foo) \
-      --zsh --name _foo <(echo bar) \
-      --fish --name foo.fish <(echo baz)
-
-    [[ $(<$out/share/bash-completion/completions/foo.bash) == foo ]] || { echo "foo.bash comparison failed"; exit 1; }
-    [[ $(<$out/share/zsh/site-functions/_foo) == bar ]] || { echo "_foo comparison failed"; exit 1; }
-    [[ $(<$out/share/fish/vendor_completions.d/foo.fish) == baz ]] || { echo "foo.fish comparison failed"; exit 1; }
-  '';
-}
+installShellFiles.tests
diff --git a/pkgs/test/kernel.nix b/pkgs/test/kernel.nix
index 2ccd188b1edb0..210d69f7ffae3 100644
--- a/pkgs/test/kernel.nix
+++ b/pkgs/test/kernel.nix
@@ -1,13 +1,7 @@
-# to run these tests:
-# nix-instantiate --eval --strict . -A tests.kernel-config
-#
 # make sure to use NON EXISTING kernel settings else they may conflict with
 # common-config.nix
 { lib, pkgs }:
 
-with lib;
-with kernel;
-
 let
   lts_kernel = pkgs.linuxPackages.kernel;
 
@@ -17,57 +11,60 @@ let
       structuredExtraConfig = structuredConfig;
     }).configfile.structuredConfig;
 
-  mandatoryVsOptionalConfig = mkMerge [
-    { NIXOS_FAKE_USB_DEBUG = yes;}
-    { NIXOS_FAKE_USB_DEBUG = option yes; }
+  mandatoryVsOptionalConfig = lib.mkMerge [
+    { NIXOS_FAKE_USB_DEBUG = lib.kernel.yes;}
+    { NIXOS_FAKE_USB_DEBUG = lib.kernel.option lib.kernel.yes; }
   ];
 
-  freeformConfig = mkMerge [
-    { NIXOS_FAKE_MMC_BLOCK_MINORS = freeform "32"; } # same as default, won't trigger any error
-    { NIXOS_FAKE_MMC_BLOCK_MINORS = freeform "64"; } # will trigger an error but the message is not great:
+  freeformConfig = lib.mkMerge [
+    { NIXOS_FAKE_MMC_BLOCK_MINORS = lib.kernel.freeform "32"; } # same as default, won't trigger any error
+    { NIXOS_FAKE_MMC_BLOCK_MINORS = lib.kernel.freeform "64"; } # will trigger an error but the message is not great:
   ];
 
-  mkDefaultWorksConfig = mkMerge [
-    { "NIXOS_TEST_BOOLEAN"  = yes; }
-    { "NIXOS_TEST_BOOLEAN"  = lib.mkDefault no; }
+  mkDefaultWorksConfig = lib.mkMerge [
+    { "NIXOS_TEST_BOOLEAN"  = lib.kernel.yes; }
+    { "NIXOS_TEST_BOOLEAN"  = lib.mkDefault lib.kernel.no; }
   ];
 
-  allOptionalRemainOptional = mkMerge [
-    { NIXOS_FAKE_USB_DEBUG = option yes;}
-    { NIXOS_FAKE_USB_DEBUG = option yes;}
+  allOptionalRemainOptional = lib.mkMerge [
+    { NIXOS_FAKE_USB_DEBUG = lib.kernel.option lib.kernel.yes;}
+    { NIXOS_FAKE_USB_DEBUG = lib.kernel.option lib.kernel.yes;}
   ];
 
-in
-runTests {
-  testEasy = {
-    expr = (getConfig { NIXOS_FAKE_USB_DEBUG = yes;}).NIXOS_FAKE_USB_DEBUG;
-    expected = { tristate = "y"; optional = false; freeform = null; };
-  };
+  failures = lib.runTests {
+    testEasy = {
+      expr = (getConfig { NIXOS_FAKE_USB_DEBUG = lib.kernel.yes;}).NIXOS_FAKE_USB_DEBUG;
+      expected = { tristate = "y"; optional = false; freeform = null; };
+    };
 
-  # mandatory flag should win over optional
-  testMandatoryCheck = {
-    expr = (getConfig mandatoryVsOptionalConfig).NIXOS_FAKE_USB_DEBUG.optional;
-    expected = false;
-  };
+    # mandatory flag should win over optional
+    testMandatoryCheck = {
+      expr = (getConfig mandatoryVsOptionalConfig).NIXOS_FAKE_USB_DEBUG.optional;
+      expected = false;
+    };
 
-  testYesWinsOverNo = {
-    expr = (getConfig mkDefaultWorksConfig)."NIXOS_TEST_BOOLEAN".tristate;
-    expected = "y";
-  };
+    testYesWinsOverNo = {
+      expr = (getConfig mkDefaultWorksConfig)."NIXOS_TEST_BOOLEAN".tristate;
+      expected = "y";
+    };
 
-  testAllOptionalRemainOptional = {
-    expr = (getConfig allOptionalRemainOptional)."NIXOS_FAKE_USB_DEBUG".optional;
-    expected = true;
-  };
+    testAllOptionalRemainOptional = {
+      expr = (getConfig allOptionalRemainOptional)."NIXOS_FAKE_USB_DEBUG".optional;
+      expected = true;
+    };
+
+    # check that freeform options are unique
+    # Should trigger
+    # > The option `settings.NIXOS_FAKE_MMC_BLOCK_MINORS.freeform' has conflicting definitions, in `<unknown-file>' and `<unknown-file>'
+    testTreeform = let
+      res = builtins.tryEval ( (getConfig freeformConfig).NIXOS_FAKE_MMC_BLOCK_MINORS.freeform);
+    in {
+      expr = res.success;
+      expected = false;
+    };
 
-  # check that freeform options are unique
-  # Should trigger
-  # > The option `settings.NIXOS_FAKE_MMC_BLOCK_MINORS.freeform' has conflicting definitions, in `<unknown-file>' and `<unknown-file>'
-  testTreeform = let
-    res = builtins.tryEval ( (getConfig freeformConfig).NIXOS_FAKE_MMC_BLOCK_MINORS.freeform);
-  in {
-    expr = res.success;
-    expected = false;
   };
+in
 
-}
+lib.optional (failures != [])
+  (throw "The following kernel unit tests failed: ${lib.generators.toPretty {} failures}")
diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix
index 4c6fffd100a72..29e4272fd672c 100644
--- a/pkgs/test/make-binary-wrapper/default.nix
+++ b/pkgs/test/make-binary-wrapper/default.nix
@@ -15,16 +15,25 @@ let
   makeGoldenTest = testname: runCommand "make-binary-wrapper-test-${testname}" env ''
     mkdir -p tmp/foo # for the chdir test
 
-    params=$(<"${./.}/${testname}.cmdline")
+    source=${lib.fileset.toSource {
+      root = ./.;
+      fileset = lib.fileset.unions [
+        (./. + "/${testname}.cmdline")
+        (./. + "/${testname}.c")
+        (lib.fileset.maybeMissing (./. + "/${testname}.env"))
+      ];
+    }}
+
+    params=$(<"$source/${testname}.cmdline")
     eval "makeCWrapper /send/me/flags $params" > wrapper.c
 
-    diff wrapper.c "${./.}/${testname}.c"
+    diff wrapper.c "$source/${testname}.c"
 
-    if [ -f "${./.}/${testname}.env" ]; then
+    if [ -f "$source/${testname}.env" ]; then
       eval "makeWrapper ${envCheck} wrapped $params"
       env -i ./wrapped > env.txt
       sed "s#SUBST_ARGV0#${envCheck}#;s#SUBST_CWD#$PWD#" \
-        "${./.}/${testname}.env" > golden-env.txt
+        "$source/${testname}.env" > golden-env.txt
       if ! diff env.txt golden-env.txt; then
         echo "env/argv should be:"
         cat golden-env.txt
@@ -51,7 +60,7 @@ let
     "overlength-strings"
     "prefix"
     "suffix"
-  ] makeGoldenTest // lib.optionalAttrs (! stdenv.isDarwin) {
+  ] makeGoldenTest // lib.optionalAttrs (! stdenv.hostPlatform.isDarwin) {
     cross = pkgsCross.${if stdenv.buildPlatform.isAarch64 then "gnu64" else "aarch64-multiplatform"}.callPackage ./cross.nix { };
   };
 in
diff --git a/pkgs/test/overriding.nix b/pkgs/test/overriding.nix
index f2519088f138a..a9fa482e4e588 100644
--- a/pkgs/test/overriding.nix
+++ b/pkgs/test/overriding.nix
@@ -5,33 +5,61 @@ let
     let
       p = pkgs.python3Packages.xpybutil.overridePythonAttrs (_: { dontWrapPythonPrograms = true; });
     in
-    [
-      ({
-        name = "overridePythonAttrs";
+    {
+      overridePythonAttrs = {
         expr = !lib.hasInfix "wrapPythonPrograms" p.postFixup;
         expected = true;
-      })
-      ({
-        name = "repeatedOverrides-pname";
+      };
+      repeatedOverrides-pname = {
         expr = repeatedOverrides.pname == "a-better-hello-with-blackjack";
         expected = true;
-      })
-      ({
-        name = "repeatedOverrides-entangled-pname";
+      };
+      repeatedOverrides-entangled-pname = {
         expr = repeatedOverrides.entangled.pname == "a-better-figlet-with-blackjack";
         expected = true;
-      })
-      ({
-        name = "overriding-using-only-attrset";
+      };
+      overriding-using-only-attrset = {
         expr = (pkgs.hello.overrideAttrs { pname = "hello-overriden"; }).pname == "hello-overriden";
         expected = true;
-      })
-      ({
+      };
+      overriding-using-only-attrset-no-final-attrs = {
         name = "overriding-using-only-attrset-no-final-attrs";
         expr = ((stdenvNoCC.mkDerivation { pname = "hello-no-final-attrs"; }).overrideAttrs { pname = "hello-no-final-attrs-overridden"; }).pname == "hello-no-final-attrs-overridden";
         expected = true;
-      })
-    ];
+      };
+      buildGoModule-overrideAttrs = {
+        expr = lib.all (
+          attrPath:
+          let
+            attrPathPretty = lib.concatStringsSep "." attrPath;
+            valueNative = lib.getAttrFromPath attrPath pet_0_4_0;
+            valueOverridden = lib.getAttrFromPath attrPath pet_0_4_0-overridden;
+          in
+          lib.warnIfNot
+            (valueNative == valueOverridden)
+            "pet_0_4_0.${attrPathPretty} (${valueNative}) does not equal pet_0_4_0-overridden.${attrPathPretty} (${valueOverridden})"
+            true
+        ) [
+          [ "drvPath" ]
+          [ "name" ]
+          [ "pname" ]
+          [ "version" ]
+          [ "vendorHash" ]
+          [ "goModules" "drvPath" ]
+          [ "goModules" "name" ]
+          [ "goModules" "outputHash" ]
+        ];
+        expected = true;
+      };
+      buildGoModule-goModules-overrideAttrs = {
+        expr = pet-foo.goModules.FOO == "foo";
+        expected = true;
+      };
+      buildGoModule-goModules-overrideAttrs-vendored = {
+        expr = lib.isString pet-vendored.drvPath;
+        expected = true;
+      };
+    };
 
   addEntangled = origOverrideAttrs: f:
     origOverrideAttrs (
@@ -55,6 +83,74 @@ let
   overrides1 = example.overrideAttrs (_: super: { pname = "a-better-${super.pname}"; });
 
   repeatedOverrides = overrides1.overrideAttrs (_: super: { pname = "${super.pname}-with-blackjack"; });
+
+  pet_0_3_4 = pkgs.buildGoModule rec {
+    pname = "pet";
+    version = "0.3.4";
+
+    src = pkgs.fetchFromGitHub {
+      owner = "knqyf263";
+      repo = "pet";
+      rev = "v${version}";
+      hash = "sha256-Gjw1dRrgM8D3G7v6WIM2+50r4HmTXvx0Xxme2fH9TlQ=";
+    };
+
+    vendorHash = "sha256-ciBIR+a1oaYH+H1PcC8cD8ncfJczk1IiJ8iYNM+R6aA=";
+
+    meta = {
+      description = "Simple command-line snippet manager, written in Go";
+      homepage = "https://github.com/knqyf263/pet";
+      license = lib.licenses.mit;
+      maintainers = with lib.maintainers; [ kalbasit ];
+    };
+  };
+
+  pet_0_4_0 = pkgs.buildGoModule rec {
+    pname = "pet";
+    version = "0.4.0";
+
+    src = pkgs.fetchFromGitHub {
+      owner = "knqyf263";
+      repo = "pet";
+      rev = "v${version}";
+      hash = "sha256-gVTpzmXekQxGMucDKskGi+e+34nJwwsXwvQTjRO6Gdg=";
+    };
+
+    vendorHash = "sha256-dUvp7FEW09V0xMuhewPGw3TuAic/sD7xyXEYviZ2Ivs=";
+
+    meta = {
+      description = "Simple command-line snippet manager, written in Go";
+      homepage = "https://github.com/knqyf263/pet";
+      license = lib.licenses.mit;
+      maintainers = with lib.maintainers; [ kalbasit ];
+    };
+  };
+
+  pet_0_4_0-overridden = pet_0_3_4.overrideAttrs (finalAttrs: previousAttrs: {
+  version = "0.4.0";
+
+  src = pkgs.fetchFromGitHub {
+    inherit (previousAttrs.src) owner repo;
+    rev = "v${finalAttrs.version}";
+    hash = "sha256-gVTpzmXekQxGMucDKskGi+e+34nJwwsXwvQTjRO6Gdg=";
+  };
+
+  vendorHash = "sha256-dUvp7FEW09V0xMuhewPGw3TuAic/sD7xyXEYviZ2Ivs=";
+  });
+
+  pet-foo = pet_0_3_4.overrideAttrs (
+    finalAttrs: previousAttrs: {
+      passthru = previousAttrs.passthru // {
+        overrideModAttrs = lib.composeExtensions previousAttrs.passthru.overrideModAttrs (
+          finalModAttrs: previousModAttrs: {
+            FOO = "foo";
+          }
+        );
+      };
+    }
+  );
+
+  pet-vendored = pet-foo.overrideAttrs { vendorHash = null; };
 in
 
 stdenvNoCC.mkDerivation {
@@ -62,5 +158,5 @@ stdenvNoCC.mkDerivation {
   passthru = { inherit tests; };
   buildCommand = ''
     touch $out
-  '' + lib.concatMapStringsSep "\n" (t: "([[ ${lib.boolToString t.expr} == ${lib.boolToString t.expected} ]] && echo '${t.name} success') || (echo '${t.name} fail' && exit 1)") tests;
+  '' + lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs (name: t: "([[ ${lib.boolToString t.expr} == ${lib.boolToString t.expected} ]] && echo '${name} success') || (echo '${name} fail' && exit 1)") tests));
 }
diff --git a/pkgs/test/release/default.nix b/pkgs/test/release/default.nix
index 2ab730b5c4822..2fdc6d0dc38c5 100644
--- a/pkgs/test/release/default.nix
+++ b/pkgs/test/release/default.nix
@@ -13,8 +13,21 @@ pkgs.runCommand "all-attrs-eval-under-tryEval" {
   nativeBuildInputs = [
     nix
     pkgs.gitMinimal
-  ] ++ lib.optional pkgs.stdenv.isLinux pkgs.inotify-tools;
+  ] ++ lib.optional pkgs.stdenv.hostPlatform.isLinux pkgs.inotify-tools;
   strictDeps = true;
+
+  src = with lib.fileset; toSource {
+    root = pkgs-path;
+    fileset = unions [
+      ../../../default.nix
+      ../../../doc
+      ../../../lib
+      ../../../maintainers
+      ../../../nixos
+      ../../../pkgs
+      ../../../.version
+    ];
+  };
 }
 ''
   datadir="${nix}/share"
@@ -31,15 +44,8 @@ pkgs.runCommand "all-attrs-eval-under-tryEval" {
 
   nix-store --init
 
-  cp -r ${pkgs-path}/lib lib
-  cp -r ${pkgs-path}/pkgs pkgs
-  cp -r ${pkgs-path}/default.nix default.nix
-  cp -r ${pkgs-path}/nixos nixos
-  cp -r ${pkgs-path}/maintainers maintainers
-  cp -r ${pkgs-path}/.version .version
-  cp -r ${pkgs-path}/doc doc
   echo "Running pkgs/top-level/release-attrpaths-superset.nix"
-  nix-instantiate --eval --strict --json pkgs/top-level/release-attrpaths-superset.nix -A names > /dev/null
+  nix-instantiate --eval --strict --json $src/pkgs/top-level/release-attrpaths-superset.nix -A names > /dev/null
 
   mkdir $out
   echo success > $out/${nix.version}
diff --git a/pkgs/test/replace-vars/default.nix b/pkgs/test/replace-vars/default.nix
new file mode 100644
index 0000000000000..76dc81de49c81
--- /dev/null
+++ b/pkgs/test/replace-vars/default.nix
@@ -0,0 +1,74 @@
+{
+  replaceVars,
+  emptyDirectory,
+  emptyFile,
+  runCommand,
+  testers,
+}:
+let
+  inherit (testers) testEqualContents testBuildFailure;
+in
+{
+  # Success case for `replaceVars`.
+  replaceVars = testEqualContents {
+    assertion = "replaceVars";
+    actual = replaceVars ./source.txt {
+      free = "free";
+      "equal in" = "are the same in";
+      brotherhood = "shared humanity";
+    };
+
+    expected = builtins.toFile "expected" ''
+      All human beings are born free and are the same in dignity and rights.
+      They are endowed with reason and conscience and should act towards
+      one another in a spirit of shared humanity.
+
+        -- eroosevelt@humanrights.un.org
+    '';
+  };
+
+  # There might eventually be a usecase for this, but it's not supported at the moment.
+  replaceVars-fails-on-directory =
+    runCommand "replaceVars-fails" { failed = testBuildFailure (replaceVars emptyDirectory { }); }
+      ''
+        grep -e "ERROR: file.*empty-directory.*does not exist" $failed/testBuildFailure.log
+        touch $out
+      '';
+
+  replaceVars-fails-in-build-phase =
+    runCommand "replaceVars-fails"
+      { failed = testBuildFailure (replaceVars emptyFile { not-found = "boo~"; }); }
+      ''
+        grep -e "ERROR: pattern @not-found@ doesn't match anything in file.*empty-file" $failed/testBuildFailure.log
+        touch $out
+      '';
+
+  replaceVars-fails-in-check-phase =
+    runCommand "replaceVars-fails"
+      {
+        failed =
+          let
+            src = builtins.toFile "source.txt" ''
+              Header.
+              before @whatIsThis@ middle @It'sOdd2Me@ after.
+              @cannot detect due to space@
+              Trailer.
+            '';
+          in
+          testBuildFailure (replaceVars src { });
+      }
+      ''
+        grep -e "unsubstituted Nix identifiers.*source.txt" $failed/testBuildFailure.log
+        grep -F "@whatIsThis@" $failed/testBuildFailure.log
+        grep -F "@It'sOdd2Me@" $failed/testBuildFailure.log
+        grep -F 'more precise `substitute` function' $failed/testBuildFailure.log
+
+        # Shouldn't see irrelevant details.
+        ! grep -q -E -e "Header|before|middle|after|Trailer" $failed/testBuildFailure.log
+
+        # Shouldn't see the "cannot detect" version.
+        ! grep -q -F "cannot detect due to space" $failed/testBuildFailure.log
+
+        touch $out
+      '';
+}
diff --git a/pkgs/test/replace-vars/source.txt b/pkgs/test/replace-vars/source.txt
new file mode 100644
index 0000000000000..b3d293859e8b3
--- /dev/null
+++ b/pkgs/test/replace-vars/source.txt
@@ -0,0 +1,5 @@
+All human beings are born @free@ and @equal in@ dignity and rights.
+They are endowed with reason and conscience and should act towards
+one another in a spirit of @brotherhood@.
+
+  -- eroosevelt@humanrights.un.org
diff --git a/pkgs/test/stdenv-inputs/default.nix b/pkgs/test/stdenv-inputs/default.nix
index 6a2e441d01917..deb97b8224237 100644
--- a/pkgs/test/stdenv-inputs/default.nix
+++ b/pkgs/test/stdenv-inputs/default.nix
@@ -12,7 +12,7 @@ let
       chmod +x $out/bin/foo
       cp ${./foo.c} $out/include/foo.h
       $CC -shared \
-        ${lib.optionalString stdenv.isDarwin "-Wl,-install_name,$out/lib/libfoo.dylib"} \
+        ${lib.optionalString stdenv.hostPlatform.isDarwin "-Wl,-install_name,$out/lib/libfoo.dylib"} \
         -o $out/lib/libfoo${stdenv.hostPlatform.extensions.sharedLibrary} \
         ${./foo.c}
     '';
@@ -30,7 +30,7 @@ let
       chmod +x $out/bin/bar
       cp ${./bar.c} $dev/include/bar.h
       $CC -shared \
-        ${lib.optionalString stdenv.isDarwin "-Wl,-install_name,$dev/lib/libbar.dylib"} \
+        ${lib.optionalString stdenv.hostPlatform.isDarwin "-Wl,-install_name,$dev/lib/libbar.dylib"} \
         -o $dev/lib/libbar${stdenv.hostPlatform.extensions.sharedLibrary} \
         ${./bar.c}
     '';
diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix
index e06759fa28bd4..d8f11f98e9b8b 100644
--- a/pkgs/test/stdenv/default.nix
+++ b/pkgs/test/stdenv/default.nix
@@ -74,19 +74,19 @@ let
           declare -p string
 
           declare -A associativeArray=(["X"]="Y")
-          [[ $(appendToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not catch prepending associativeArray" && false)
-          [[ $(prependToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not catch prepending associativeArray" && false)
+          [[ $(appendToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "appendToVar did not throw appending to associativeArray" && false)
+          [[ $(prependToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not throw prepending associativeArray" && false)
 
           [[ $string == "world testing-string hello" ]] || (echo "'\$string' was not 'world testing-string hello'" && false)
 
           # test appending to a unset variable
           appendToVar nonExistant created hello
-          typeset -p nonExistant
+          declare -p nonExistant
           if [[ -n $__structuredAttrs ]]; then
             [[ "''${nonExistant[@]}" == "created hello" ]]
           else
             # there's a extra " " in front here and a extra " " in the end of prependToVar
-            # shouldn't matter because these functions will mostly be used for $*Flags and the Flag variable will in most cases already exit
+            # shouldn't matter because these functions will mostly be used for $*Flags and the Flag variable will in most cases already exist
             [[ "$nonExistant" == " created hello" ]]
           fi
 
@@ -96,9 +96,80 @@ let
         '';
       } // extraAttrs);
 
+  testConcatTo = { name, stdenv', extraAttrs ? { } }:
+    stdenv'.mkDerivation
+      ({
+        inherit name;
+
+        string = "a *";
+        list = ["c" "d"];
+
+        passAsFile = [ "buildCommand" ] ++ lib.optionals (extraAttrs ? extraTest) [ "extraTest" ];
+        buildCommand = ''
+          declare -A associativeArray=(["X"]="Y")
+          [[ $(concatTo nowhere associativeArray 2>&1) =~ "trying to use" ]] || (echo "concatTo did not throw concatenating associativeArray" && false)
+
+          empty_array=()
+          empty_string=""
+
+          declare -a flagsArray
+          concatTo flagsArray string list notset=e=f empty_array=g empty_string=h
+          declare -p flagsArray
+          [[ "''${flagsArray[0]}" == "a" ]] || (echo "'\$flagsArray[0]' was not 'a'" && false)
+          [[ "''${flagsArray[1]}" == "*" ]] || (echo "'\$flagsArray[1]' was not '*'" && false)
+          [[ "''${flagsArray[2]}" == "c" ]] || (echo "'\$flagsArray[2]' was not 'c'" && false)
+          [[ "''${flagsArray[3]}" == "d" ]] || (echo "'\$flagsArray[3]' was not 'd'" && false)
+          [[ "''${flagsArray[4]}" == "e=f" ]] || (echo "'\$flagsArray[4]' was not 'e=f'" && false)
+          [[ "''${flagsArray[5]}" == "g" ]] || (echo "'\$flagsArray[5]' was not 'g'" && false)
+          [[ "''${flagsArray[6]}" == "h" ]] || (echo "'\$flagsArray[6]' was not 'h'" && false)
+
+          # test concatenating to unset variable
+          concatTo nonExistant string list notset=e=f empty_array=g empty_string=h
+          declare -p nonExistant
+          [[ "''${nonExistant[0]}" == "a" ]] || (echo "'\$nonExistant[0]' was not 'a'" && false)
+          [[ "''${nonExistant[1]}" == "*" ]] || (echo "'\$nonExistant[1]' was not '*'" && false)
+          [[ "''${nonExistant[2]}" == "c" ]] || (echo "'\$nonExistant[2]' was not 'c'" && false)
+          [[ "''${nonExistant[3]}" == "d" ]] || (echo "'\$nonExistant[3]' was not 'd'" && false)
+          [[ "''${nonExistant[4]}" == "e=f" ]] || (echo "'\$nonExistant[4]' was not 'e=f'" && false)
+          [[ "''${nonExistant[5]}" == "g" ]] || (echo "'\$nonExistant[5]' was not 'g'" && false)
+          [[ "''${nonExistant[6]}" == "h" ]] || (echo "'\$nonExistant[6]' was not 'h'" && false)
+
+          eval "$extraTest"
+
+          touch $out
+        '';
+      } // extraAttrs);
+
+  testConcatStringsSep = { name, stdenv' }:
+    stdenv'.mkDerivation
+      {
+        inherit name;
+
+        # NOTE: Testing with "&" as separator is intentional, because unquoted
+        # "&" has a special meaning in the "${var//pattern/replacement}" syntax.
+        # Cf. https://github.com/NixOS/nixpkgs/pull/318614#discussion_r1706191919
+        passAsFile = [ "buildCommand" ];
+        buildCommand = ''
+          declare -A associativeArray=(["X"]="Y")
+          [[ $(concatStringsSep ";" associativeArray 2>&1) =~ "trying to use" ]] || (echo "concatStringsSep did not throw concatenating associativeArray" && false)
+
+          string="lorem ipsum dolor sit amet"
+          stringWithSep="$(concatStringsSep "&" string)"
+          [[ "$stringWithSep" == "lorem&ipsum&dolor&sit&amet" ]] || (echo "'\$stringWithSep' was not 'lorem&ipsum&dolor&sit&amet'" && false)
+
+          array=("lorem ipsum" "dolor" "sit amet")
+          arrayWithSep="$(concatStringsSep "&" array)"
+          [[ "$arrayWithSep" == "lorem ipsum&dolor&sit amet" ]] || (echo "'\$arrayWithSep' was not 'lorem ipsum&dolor&sit amet'" && false)
+
+          touch $out
+        '';
+      };
 in
 
 {
+  # Disable on Darwin due to assumptions with __bootPackages
+  __attrsFailEvaluation = stdenv.hostPlatform.isDarwin;
+
   # tests for hooks in `stdenv.defaultNativeBuildInputs`
   hooks = lib.recurseIntoAttrs (import ./hooks.nix { stdenv = bootStdenv; pkgs = earlyPkgs; inherit lib; });
 
@@ -193,6 +264,16 @@ in
     stdenv' = bootStdenv;
   };
 
+  test-concat-to = testConcatTo {
+    name = "test-concat-to";
+    stdenv' = bootStdenv;
+  };
+
+  test-concat-strings-sep = testConcatStringsSep {
+    name = "test-concat-strings-sep";
+    stdenv' = bootStdenv;
+  };
+
   test-structured-env-attrset = testEnvAttrset {
     name = "test-structured-env-attrset";
     stdenv' = bootStdenv;
@@ -252,6 +333,29 @@ in
       };
     };
 
+    test-concat-to = testConcatTo {
+      name = "test-concat-to-structuredAttrsByDefault";
+      stdenv' = bootStdenvStructuredAttrsByDefault;
+      extraAttrs = {
+        # test that whitespace is kept in the bash array for structuredAttrs
+        listWithSpaces = [ "c c" "d d" ];
+        extraTest = ''
+          declare -a flagsWithSpaces
+          concatTo flagsWithSpaces string listWithSpaces
+          declare -p flagsWithSpaces
+          [[ "''${flagsWithSpaces[0]}" == "a" ]] || (echo "'\$flagsWithSpaces[0]' was not 'a'" && false)
+          [[ "''${flagsWithSpaces[1]}" == "*" ]] || (echo "'\$flagsWithSpaces[1]' was not '*'" && false)
+          [[ "''${flagsWithSpaces[2]}" == "c c" ]] || (echo "'\$flagsWithSpaces[2]' was not 'c c'" && false)
+          [[ "''${flagsWithSpaces[3]}" == "d d" ]] || (echo "'\$flagsWithSpaces[3]' was not 'd d'" && false)
+        '';
+      };
+    };
+
+    test-concat-strings-sep = testConcatStringsSep {
+      name = "test-concat-strings-sep-structuredAttrsByDefault";
+      stdenv' = bootStdenvStructuredAttrsByDefault;
+    };
+
     test-golden-example-structuredAttrs =
       let
         goldenSh = earlyPkgs.writeText "goldenSh" ''
diff --git a/pkgs/test/stdenv/patch-shebangs.nix b/pkgs/test/stdenv/patch-shebangs.nix
index db9ca2fcaafef..51edf128f7d55 100644
--- a/pkgs/test/stdenv/patch-shebangs.nix
+++ b/pkgs/test/stdenv/patch-shebangs.nix
@@ -87,6 +87,20 @@ let
       };
     };
 
+    dont-patch-builtins = stdenv.mkDerivation {
+      name = "dont-patch-builtins";
+      strictDeps = false;
+      dontUnpack = true;
+      installPhase = ''
+        mkdir -p $out/bin
+        echo "#!/usr/bin/builtin" > $out/bin/test
+        chmod +x $out/bin/test
+        dontPatchShebangs=
+      '';
+      passthru = {
+        assertion = "grep '^#!/usr/bin/builtin' $out/bin/test > /dev/null";
+      };
+    };
   };
 in
 stdenv.mkDerivation {
diff --git a/pkgs/test/systemd/nixos/default.nix b/pkgs/test/systemd/nixos/default.nix
index e45399b635167..37b42ea7ae273 100644
--- a/pkgs/test/systemd/nixos/default.nix
+++ b/pkgs/test/systemd/nixos/default.nix
@@ -1,37 +1,42 @@
 { pkgs, lib, stdenv, ... }:
 
-lib.runTests {
-  # Merging two non-list definitions must still result in an error
-  # about a conflicting definition.
-  test-unitOption-merging-non-lists-conflict =
-    let nixos = pkgs.nixos {
-        system.stateVersion = lib.trivial.release;
-        systemd.services.systemd-test-nixos = {
-          serviceConfig = lib.mkMerge [
-            { StateDirectory = "foo"; }
-            { StateDirectory = "bar"; }
-          ];
+let
+  failures = lib.runTests {
+    # Merging two non-list definitions must still result in an error
+    # about a conflicting definition.
+    test-unitOption-merging-non-lists-conflict =
+      let nixos = pkgs.nixos {
+          system.stateVersion = lib.trivial.release;
+          systemd.services.systemd-test-nixos = {
+            serviceConfig = lib.mkMerge [
+              { StateDirectory = "foo"; }
+              { StateDirectory = "bar"; }
+            ];
+          };
         };
-      };
-    in {
-    expr = (builtins.tryEval (nixos.config.systemd.services.systemd-test-nixos.serviceConfig.StateDirectory)).success;
-    expected = false;
-  };
+      in {
+      expr = (builtins.tryEval (nixos.config.systemd.services.systemd-test-nixos.serviceConfig.StateDirectory)).success;
+      expected = false;
+    };
 
-  # Merging must lift non-list definitions to a list
-  # if at least one of them is a list.
-  test-unitOption-merging-list-non-list-append =
-    let nixos = pkgs.nixos {
-        system.stateVersion = lib.trivial.release;
-        systemd.services.systemd-test-nixos = {
-          serviceConfig = lib.mkMerge [
-            { StateDirectory = "foo"; }
-            { StateDirectory = ["bar"]; }
-          ];
+    # Merging must lift non-list definitions to a list
+    # if at least one of them is a list.
+    test-unitOption-merging-list-non-list-append =
+      let nixos = pkgs.nixos {
+          system.stateVersion = lib.trivial.release;
+          systemd.services.systemd-test-nixos = {
+            serviceConfig = lib.mkMerge [
+              { StateDirectory = "foo"; }
+              { StateDirectory = ["bar"]; }
+            ];
+          };
         };
-      };
-    in {
-    expr = nixos.config.systemd.services.systemd-test-nixos.serviceConfig.StateDirectory;
-    expected = [ "foo" "bar" ];
+      in {
+      expr = nixos.config.systemd.services.systemd-test-nixos.serviceConfig.StateDirectory;
+      expected = [ "foo" "bar" ];
+    };
   };
-}
+in
+
+lib.optional (failures != [])
+  (throw "The following systemd unit tests failed: ${lib.generators.toPretty {} failures}")
diff --git a/pkgs/test/texlive/default.nix b/pkgs/test/texlive/default.nix
index e363b5776e890..f9e0bc51e3d4d 100644
--- a/pkgs/test/texlive/default.nix
+++ b/pkgs/test/texlive/default.nix
@@ -190,7 +190,7 @@ rec {
 
   texdoc = runCommand "texlive-test-texdoc" {
     nativeBuildInputs = [
-      (texlive.withPackages (ps: with ps; [ luatex ps.texdoc ps.texdoc.texdoc ]))
+      (texlive.withPackages (ps: [ ps.luatex ps.texdoc ps.texdoc.texdoc ]))
     ];
   } ''
     texdoc --version
@@ -375,7 +375,7 @@ rec {
 
         # 'Error initialising QuantumRenderer: no suitable pipeline found'
         "tlcockpit"
-      ] ++ lib.optional stdenv.isDarwin "epspdftk";  # wish shebang is a script, not a binary!
+      ] ++ lib.optional stdenv.hostPlatform.isDarwin "epspdftk";  # wish shebang is a script, not a binary!
 
       # (1) binaries requiring -v
       shortVersion = [ "devnag" "diadia" "pmxchords" "ptex2pdf" "simpdftex" "ttf2afm" ];
@@ -668,14 +668,14 @@ rec {
   # verify that all fixed hashes are present
   # this is effectively an eval-time assertion, converted into a derivation for
   # ease of testing
-  fixedHashes = with lib; let
+  fixedHashes = let
     fods = lib.concatMap
-      (p: lib.optional (p ? tex && isDerivation p.tex) p.tex
+      (p: lib.optional (p ? tex && lib.isDerivation p.tex) p.tex
         ++ lib.optional (p ? texdoc) p.texdoc
         ++ lib.optional (p ? texsource) p.texsource
         ++ lib.optional (p ? tlpkg) p.tlpkg)
-      (attrValues texlive.pkgs);
-    errorText = concatMapStrings (p: optionalString (! p ? outputHash) "${p.pname}-${p.tlOutputName} does not have a fixed output hash\n") fods;
+      (lib.attrValues texlive.pkgs);
+    errorText = lib.concatMapStrings (p: lib.optionalString (! p ? outputHash) "${p.pname}-${p.tlOutputName} does not have a fixed output hash\n") fods;
   in runCommand "texlive-test-fixed-hashes" {
     inherit errorText;
     passAsFile = [ "errorText" ];
diff --git a/pkgs/test/vim/default.nix b/pkgs/test/vim/default.nix
index 33e1e551d4f92..5a3bf376fb884 100644
--- a/pkgs/test/vim/default.nix
+++ b/pkgs/test/vim/default.nix
@@ -1,7 +1,4 @@
-{ vimUtils, vim-full, writeText, vimPlugins
-, lib, fetchFromGitHub
-, pkgs
-}:
+{ vimUtils, vim-full, vimPlugins, pkgs }:
 let
   inherit (vimUtils) buildVimPlugin;