diff options
Diffstat (limited to 'pkgs/test')
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; |