diff options
Diffstat (limited to 'nixpkgs/pkgs/test')
107 files changed, 3824 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/test/cc-wrapper/cc-main.c b/nixpkgs/pkgs/test/cc-wrapper/cc-main.c new file mode 100644 index 000000000000..06f28bc33c69 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/cc-main.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/cflags-main.c b/nixpkgs/pkgs/test/cc-wrapper/cflags-main.c new file mode 100644 index 000000000000..9491232b5387 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/cflags-main.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <foo.h> + +int main(int argc, char **argv) +{ + if (foo() != 42) + return 1; + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/core-foundation-main.c b/nixpkgs/pkgs/test/cc-wrapper/core-foundation-main.c new file mode 100644 index 000000000000..fb3bd3126191 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/core-foundation-main.c @@ -0,0 +1,7 @@ +#include <CoreFoundation/CoreFoundation.h> + +int main(int argc, char** argv) +{ + CFShow(CFSTR("ok")); + return 0; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/cxx-main.cc b/nixpkgs/pkgs/test/cc-wrapper/cxx-main.cc new file mode 100644 index 000000000000..83f704617a46 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/cxx-main.cc @@ -0,0 +1,7 @@ +#include <iostream> + +int main(int argc, char **argv) +{ + std::cerr << "ok" << std::endl; + return 0; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/default.nix b/nixpkgs/pkgs/test/cc-wrapper/default.nix new file mode 100644 index 000000000000..43e8e7a21426 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/default.nix @@ -0,0 +1,104 @@ +{ lib, stdenv, glibc, buildPackages }: + +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 && ( + (stdenv.cc.isClang && lib.versionAtLeast (lib.getVersion stdenv.cc.name) "5.0.0") + || (stdenv.cc.isGNU && stdenv.isLinux) + ); + staticLibc = lib.optionalString (stdenv.hostPlatform.libc == "glibc") "-L ${glibc.static}/lib"; + emulator = stdenv.hostPlatform.emulator buildPackages; +in stdenv.mkDerivation { + name = "cc-wrapper-test"; + + buildCommand = '' + set -o pipefail + + NIX_DEBUG=1 $CC -v + NIX_DEBUG=1 $CXX -v + + printf "checking whether compiler builds valid C binaries... " >&2 + $CC -o cc-check ${./cc-main.c} + ${emulator} ./cc-check + + printf "checking whether compiler builds valid C++ binaries... " >&2 + $CXX -o cxx-check ${./cxx-main.cc} + ${emulator} ./cxx-check + + ${lib.optionalString (stdenv.isDarwin && stdenv.cc.isClang) '' + printf "checking whether compiler can build with CoreFoundation.framework... " >&2 + mkdir -p foo/lib + $CC -framework CoreFoundation -o core-foundation-check ${./core-foundation-main.c} + ${emulator} ./core-foundation-check + ''} + + + ${lib.optionalString (!stdenv.isDarwin) '' + printf "checking whether compiler builds valid static C binaries... " >&2 + $CC ${staticLibc} -static -o cc-static ${./cc-main.c} + ${emulator} ./cc-static + ${lib.optionalString (stdenv.cc.isGNU && lib.versionAtLeast (lib.getVersion stdenv.cc.name) "8.0.0") '' + printf "checking whether compiler builds valid static pie C binaries... " >&2 + $CC ${staticLibc} -static-pie -o cc-static-pie ${./cc-main.c} + ${emulator} ./cc-static-pie + ''} + ''} + + ${# See: https://github.com/llvm/llvm-project/commit/ed1d07282cc9d8e4c25d585e03e5c8a1b6f63a74 + # `gcc` does not support this so we gate the test on `clang` + lib.optionalString stdenv.cc.isClang '' + printf "checking whether cc-wrapper accepts -- followed by positional (file) args..." >&2 + mkdir -p positional + + # Make sure `--` is not parsed as a "non flag arg"; we should get an + # input file error here and *not* a linker error. + { ! $CC --; } |& grep -q "no input files" + + # And that positional file args _must_ be files (this is just testing + # that we remembered to put the `--` back in the args to the compiler): + { ! $CC -c -- -o foo ${./foo.c}; } \ + |& grep -q "no such file or directory: '-o'" + + # Now check that we accept single and multiple positional file args: + $CC -c -DVALUE=42 -o positional/foo.o -- ${./foo.c} + $CC -o positional/main -- positional/foo.o ${./ldflags-main.c} + ${emulator} ./positional/main + ''} + + printf "checking whether compiler uses NIX_CFLAGS_COMPILE... " >&2 + mkdir -p foo/include + cp ${./foo.c} foo/include/foo.h + NIX_CFLAGS_COMPILE="-Ifoo/include -DVALUE=42" $CC -o cflags-check ${./cflags-main.c} + ${emulator} ./cflags-check + + printf "checking whether compiler uses NIX_LDFLAGS... " >&2 + mkdir -p foo/lib + $CC -shared \ + ${lib.optionalString stdenv.isDarwin "-Wl,-install_name,@rpath/libfoo.dylib"} \ + -DVALUE=42 \ + -o foo/lib/libfoo${stdenv.hostPlatform.extensions.sharedLibrary} \ + ${./foo.c} + + NIX_LDFLAGS="-L$NIX_BUILD_TOP/foo/lib -rpath $NIX_BUILD_TOP/foo/lib" $CC -lfoo -o ldflags-check ${./ldflags-main.c} + ${emulator} ./ldflags-check + + printf "Check whether -nostdinc and -nostdinc++ is handled correctly" >&2 + mkdir -p std-include + cp ${./stdio.h} std-include/stdio.h + NIX_DEBUG=1 $CC -I std-include -nostdinc -o nostdinc-main ${./nostdinc-main.c} + ${emulator} ./nostdinc-main + $CXX -I std-include -nostdinc++ -o nostdinc-main++ ${./nostdinc-main.c} + ${emulator} ./nostdinc-main++ + + ${lib.optionalString sanitizersWorking '' + printf "checking whether sanitizers are fully functional... ">&2 + $CC -o sanitizers -fsanitize=address,undefined ${./sanitizers.c} + ASAN_OPTIONS=use_sigaltstack=0 ${emulator} ./sanitizers + ''} + + touch $out + ''; + + meta.platforms = lib.platforms.all; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/foo.c b/nixpkgs/pkgs/test/cc-wrapper/foo.c new file mode 100644 index 000000000000..8be674be3103 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/foo.c @@ -0,0 +1,4 @@ +unsigned int foo(void) +{ + return VALUE; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/ldflags-main.c b/nixpkgs/pkgs/test/cc-wrapper/ldflags-main.c new file mode 100644 index 000000000000..89832b3bbad2 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/ldflags-main.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +extern unsigned int foo(void); + +int main(int argc, char **argv) +{ + if (foo() != 42) { + return 1; + } + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/multilib.nix b/nixpkgs/pkgs/test/cc-wrapper/multilib.nix new file mode 100644 index 000000000000..a26880681f22 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/multilib.nix @@ -0,0 +1,37 @@ +{ lib, stdenv }: + +stdenv.mkDerivation { + name = "cc-multilib-test"; + + # XXX: "depend" on cc-wrapper test? + + # TODO: Have tests report pointer size or something; ensure they are what we asked for + buildCommand = '' + NIX_DEBUG=1 $CC -v + NIX_DEBUG=1 $CXX -v + + printf "checking whether compiler builds valid C binaries...\n " >&2 + $CC -o cc-check ${./cc-main.c} + ./cc-check + + printf "checking whether compiler builds valid 32bit C binaries...\n " >&2 + $CC -m32 -o c32-check ${./cc-main.c} + ./c32-check + + printf "checking whether compiler builds valid 64bit C binaries...\n " >&2 + $CC -m64 -o c64-check ${./cc-main.c} + ./c64-check + + printf "checking whether compiler builds valid 32bit C++ binaries...\n " >&2 + $CXX -m32 -o cxx32-check ${./cxx-main.cc} + ./cxx32-check + + printf "checking whether compiler builds valid 64bit C++ binaries...\n " >&2 + $CXX -m64 -o cxx64-check ${./cxx-main.cc} + ./cxx64-check + + touch $out + ''; + + meta.platforms = lib.platforms.x86_64; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/nostdinc-main.c b/nixpkgs/pkgs/test/cc-wrapper/nostdinc-main.c new file mode 100644 index 000000000000..f71d155b1b27 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/nostdinc-main.c @@ -0,0 +1,8 @@ +// This one should not come from libc because of -nostdinc +#include <stdio.h> + +int main(int argc, char *argv[]) { + // provided by our own stdio.h + foo(); + return 0; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/sanitizers.c b/nixpkgs/pkgs/test/cc-wrapper/sanitizers.c new file mode 100644 index 000000000000..93dd78a903ce --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/sanitizers.c @@ -0,0 +1,8 @@ +#include <sanitizer/asan_interface.h> +#include <stdio.h> + +int main(int argc, char **argv) +{ + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/nixpkgs/pkgs/test/cc-wrapper/stdio.h b/nixpkgs/pkgs/test/cc-wrapper/stdio.h new file mode 100644 index 000000000000..4bddf1d9d486 --- /dev/null +++ b/nixpkgs/pkgs/test/cc-wrapper/stdio.h @@ -0,0 +1 @@ +static void foo(void) {} diff --git a/nixpkgs/pkgs/test/config.nix b/nixpkgs/pkgs/test/config.nix new file mode 100644 index 000000000000..734e1aace148 --- /dev/null +++ b/nixpkgs/pkgs/test/config.nix @@ -0,0 +1,24 @@ +{ lib, ... }: +lib.recurseIntoAttrs { + + # https://github.com/NixOS/nixpkgs/issues/175196 + allowPkgsInPermittedInsecurePackages = + let pkgs = import ../.. { + config = { + permittedInsecurePackages = + tempAllow pkgs.authy "2.1.0" [ "electron-9.4.4" ]; + }; + }; + # A simplification of `tempAllow` that doesn't check the version, but + # has the same strictness characteristics. Actually checking a version + # here would add undue maintenance. + # + # Original: + # tempAllow = p: v: pa: + # lib.optionals (lib.assertMsg (p.version == v) "${p.name} is no longer at version ${v}, consider removing the tempAllow") pa; + # + tempAllow = p: v: pa: builtins.seq v builtins.seq p.version pa; + + in pkgs.hello; + +} diff --git a/nixpkgs/pkgs/test/coq/default.nix b/nixpkgs/pkgs/test/coq/default.nix new file mode 100644 index 000000000000..cf59dd473b4c --- /dev/null +++ b/nixpkgs/pkgs/test/coq/default.nix @@ -0,0 +1,6 @@ +{ lib, callPackage }: + +lib.recurseIntoAttrs { + overrideCoqDerivation = callPackage ./overrideCoqDerivation { }; +} + diff --git a/nixpkgs/pkgs/test/coq/overrideCoqDerivation/default.nix b/nixpkgs/pkgs/test/coq/overrideCoqDerivation/default.nix new file mode 100644 index 000000000000..c251c498e609 --- /dev/null +++ b/nixpkgs/pkgs/test/coq/overrideCoqDerivation/default.nix @@ -0,0 +1,40 @@ +{ lib, coq, mkCoqPackages, runCommand }: + +let + + # This is just coq, but with dontFilter set to true. We need to set + # dontFilter to true here so that _all_ packages are visibile in coqPackages. + # There may be some versions of the top-level coq and coqPackages that don't + # build QuickChick, which is what we are using for this test below. + coqWithAllPackages = coq // { dontFilter = true; }; + + coqPackages = mkCoqPackages coqWithAllPackages; + + # This is the main test. This uses overrideCoqDerivation to + # override arguments to mkCoqDerivation. + # + # Here, we override the defaultVersion and release arguments to + # mkCoqDerivation. + overriddenQuickChick = + coqPackages.lib.overrideCoqDerivation + { + defaultVersion = "9999"; + release."9999".sha256 = lib.fakeSha256; + } + coqPackages.QuickChick; +in + +runCommand + "coq-overrideCoqDerivation-test-0.1" + { meta.maintainers = with lib.maintainers; [cdepillabout]; } + '' + # Confirm that the computed version number for the overridden QuickChick does + # actually become 9999, as set above. + if [ "${overriddenQuickChick.version}" -eq "9999" ]; then + echo "overriddenQuickChick version was successfully set to 9999" + touch $out + else + echo "ERROR: overriddenQuickChick version was supposed to be 9999, but was actually: ${overriddenQuickChick.version}" + exit 1 + fi + '' diff --git a/nixpkgs/pkgs/test/cross/default.nix b/nixpkgs/pkgs/test/cross/default.nix new file mode 100644 index 000000000000..ff83aedca123 --- /dev/null +++ b/nixpkgs/pkgs/test/cross/default.nix @@ -0,0 +1,154 @@ +{ pkgs, lib }: + +let + + testedSystems = lib.filterAttrs (name: value: let + platform = lib.systems.elaborate value; + in platform.isLinux || platform.isWindows + ) lib.systems.examples; + + getExecutable = pkgs: pkgFun: exec: + "${pkgFun pkgs}${exec}${pkgs.stdenv.hostPlatform.extensions.executable}"; + + compareTest = { emulator, pkgFun, hostPkgs, crossPkgs, exec, args ? [] }: let + pkgName = (pkgFun hostPkgs).name; + args' = lib.concatStringsSep " " args; + in crossPkgs.runCommand "test-${pkgName}-${crossPkgs.hostPlatform.config}" { + nativeBuildInputs = [ pkgs.dos2unix ]; + } '' + # Just in case we are using wine, get rid of that annoying extra + # stuff. + export WINEDEBUG=-all + + HOME=$(pwd) + mkdir -p $out + + # We need to remove whitespace, unfortunately + # Windows programs use \r but Unix programs use \n + + echo Running native-built program natively + + # find expected value natively + ${getExecutable hostPkgs pkgFun exec} ${args'} \ + | dos2unix > $out/expected + + echo Running cross-built program in emulator + + # run emulator to get actual value + ${emulator} ${getExecutable crossPkgs pkgFun exec} ${args'} \ + | dos2unix > $out/actual + + echo Comparing results... + + if [ "$(cat $out/actual)" != "$(cat $out/expected)" ]; then + echo "${pkgName} did not output expected value:" + cat $out/expected + echo "instead it output:" + cat $out/actual + exit 1 + else + echo "${pkgName} test passed" + echo "both produced output:" + cat $out/actual + fi + ''; + + mapMultiPlatformTest = crossSystemFun: test: lib.mapAttrs (name: system: test rec { + crossPkgs = import pkgs.path { + localSystem = { inherit (pkgs.stdenv.hostPlatform) config; }; + crossSystem = crossSystemFun system; + }; + + emulator = crossPkgs.hostPlatform.emulator pkgs; + + # Apply some transformation on windows to get dlls in the right + # place. Unfortunately mingw doesn’t seem to be able to do linking + # properly. + platformFun = pkg: if crossPkgs.hostPlatform.isWindows then + pkgs.buildEnv { + name = "${pkg.name}-winlinks"; + paths = [pkg] ++ pkg.buildInputs; + } else pkg; + }) testedSystems; + + tests = { + + file = {platformFun, crossPkgs, emulator}: compareTest { + inherit emulator crossPkgs; + hostPkgs = pkgs; + exec = "/bin/file"; + args = [ + "${pkgs.file}/share/man/man1/file.1.gz" + "${pkgs.dejavu_fonts}/share/fonts/truetype/DejaVuMathTeXGyre.ttf" + ]; + pkgFun = pkgs: platformFun pkgs.file; + }; + + hello = {platformFun, crossPkgs, emulator}: compareTest { + inherit emulator crossPkgs; + hostPkgs = pkgs; + exec = "/bin/hello"; + pkgFun = pkgs: pkgs.hello; + }; + + pkg-config = {platformFun, crossPkgs, emulator}: crossPkgs.runCommand + "test-pkg-config-${crossPkgs.hostPlatform.config}" + { + depsBuildBuild = [ crossPkgs.pkgsBuildBuild.pkg-config ]; + nativeBuildInputs = [ crossPkgs.pkgsBuildHost.pkg-config crossPkgs.buildPackages.zlib ]; + depsBuildTarget = [ crossPkgs.pkgsBuildTarget.pkg-config ]; + buildInputs = [ crossPkgs.zlib ]; + NIX_DEBUG = 7; + } '' + mkdir $out + ${crossPkgs.pkgsBuildBuild.pkg-config.targetPrefix}pkg-config --cflags zlib > "$out/for-build" + ${crossPkgs.pkgsBuildHost.pkg-config.targetPrefix}pkg-config --cflags zlib > "$out/for-host" + ! diff "$out/for-build" "$out/for-host" + ''; + }; + + # see https://github.com/NixOS/nixpkgs/issues/213453 + # this is a good test of a lot of tricky glibc/libgcc corner cases + mbuffer = let + mbuffer = pkgs.pkgsCross.aarch64-multiplatform.mbuffer; + emulator = with lib.systems; (elaborate examples.aarch64-multiplatform).emulator pkgs; + in + pkgs.runCommand "test-mbuffer" {} '' + echo hello | ${emulator} ${mbuffer}/bin/mbuffer + touch $out + ''; + + # This is meant to be a carefully curated list of builds/packages + # that tend to break when refactoring our cross-compilation + # infrastructure. + # + # It should strike a balance between being small enough to fit in + # a single eval (i.e. not so large that hydra-eval-jobs is needed) + # so we can ask @ofborg to check it, yet should have good examples + # of things that often break. So, no buckshot `mapTestOnCross` + # calls here. + sanity = [ + mbuffer + #pkgs.pkgsCross.gnu64.bash # https://github.com/NixOS/nixpkgs/issues/243164 + pkgs.gcc_multi.cc + pkgs.pkgsMusl.stdenv + pkgs.pkgsLLVM.stdenv + pkgs.pkgsStatic.bash + pkgs.pkgsCross.arm-embedded.stdenv + pkgs.pkgsCross.sheevaplug.stdenv # for armv5tel + pkgs.pkgsCross.raspberryPi.stdenv # for armv6l + pkgs.pkgsCross.armv7l-hf-multiplatform.stdenv + pkgs.pkgsCross.m68k.stdenv + pkgs.pkgsCross.aarch64-multiplatform.pkgsBuildTarget.gcc + pkgs.pkgsCross.powernv.pkgsBuildTarget.gcc + pkgs.pkgsCross.mips64el-linux-gnuabi64.stdenv + pkgs.pkgsCross.mips64el-linux-gnuabin32.stdenv + pkgs.pkgsCross.mingwW64.stdenv + ]; + +in { + gcc = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = false;})) tests); + llvm = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = true;})) tests); + + inherit mbuffer sanity; +} diff --git a/nixpkgs/pkgs/test/cuda/cuda-library-samples/extension.nix b/nixpkgs/pkgs/test/cuda/cuda-library-samples/extension.nix new file mode 100644 index 000000000000..4c721a9e9e1b --- /dev/null +++ b/nixpkgs/pkgs/test/cuda/cuda-library-samples/extension.nix @@ -0,0 +1,3 @@ +final: prev: { + cuda-library-samples = final.callPackage ./generic.nix { }; +} diff --git a/nixpkgs/pkgs/test/cuda/cuda-library-samples/generic.nix b/nixpkgs/pkgs/test/cuda/cuda-library-samples/generic.nix new file mode 100644 index 000000000000..e9a481c94a7a --- /dev/null +++ b/nixpkgs/pkgs/test/cuda/cuda-library-samples/generic.nix @@ -0,0 +1,71 @@ +{ lib, backendStdenv, fetchFromGitHub +, cmake, addOpenGLRunpath +, cudatoolkit +, cutensor +}: + +let + rev = "5aab680905d853bce0dbad4c488e4f7e9f7b2302"; + src = fetchFromGitHub { + owner = "NVIDIA"; + repo = "CUDALibrarySamples"; + inherit rev; + sha256 = "0gwgbkq05ygrfgg5hk07lmap7n7ampxv0ha1axrv8qb748ph81xs"; + }; + commonAttrs = { + version = lib.strings.substring 0 7 rev + "-" + lib.versions.majorMinor cudatoolkit.version; + nativeBuildInputs = [ cmake addOpenGLRunpath ]; + buildInputs = [ cudatoolkit ]; + postFixup = '' + for exe in $out/bin/*; do + addOpenGLRunpath $exe + done + ''; + meta = { + description = "examples of using libraries using CUDA"; + longDescription = '' + CUDA Library Samples contains examples demonstrating the use of + features in the math and image processing libraries cuBLAS, cuTENSOR, + cuSPARSE, cuSOLVER, cuFFT, cuRAND, NPP and nvJPEG. + ''; + license = lib.licenses.bsd3; + maintainers = with lib.maintainers; [ obsidian-systems-maintenance ]; + }; + }; +in + +{ + cublas = backendStdenv.mkDerivation (commonAttrs // { + pname = "cuda-library-samples-cublas"; + + src = "${src}/cuBLASLt"; + }); + + cusolver = backendStdenv.mkDerivation (commonAttrs // { + pname = "cuda-library-samples-cusolver"; + + src = "${src}/cuSOLVER"; + + sourceRoot = "cuSOLVER/gesv"; + }); + + cutensor = backendStdenv.mkDerivation (commonAttrs // { + pname = "cuda-library-samples-cutensor"; + + src = "${src}/cuTENSOR"; + + buildInputs = [ cutensor ]; + + cmakeFlags = [ + "-DCUTENSOR_EXAMPLE_BINARY_INSTALL_DIR=${builtins.placeholder "out"}/bin" + ]; + + # CUTENSOR_ROOT is double escaped + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace "\''${CUTENSOR_ROOT}/include" "${cutensor.dev}/include" + ''; + + CUTENSOR_ROOT = cutensor; + }); +} diff --git a/nixpkgs/pkgs/test/cuda/cuda-samples/extension.nix b/nixpkgs/pkgs/test/cuda/cuda-samples/extension.nix new file mode 100644 index 000000000000..05861ee5e0eb --- /dev/null +++ b/nixpkgs/pkgs/test/cuda/cuda-samples/extension.nix @@ -0,0 +1,23 @@ +final: prev: let + + sha256 = { + "10.0" = "1zvh4xsdyc59m87brpcmssxsjlp9dkynh4asnkcmc3g94f53l0jw"; + "10.1" = "1s8ka0hznrni36ajhzf2gqpdrl8kd8fi047qijxks5l2abc093qd"; + "10.2" = "01p1innzgh9siacpld6nsqimj8jkg93rk4gj8q4crn62pa5vhd94"; + "11.0" = "1n3vjc8c7zdig2xgl5fppavrphqzhdiv9m9nk6smh4f99fwi0705"; + "11.1" = "1kjixk50i8y1bkiwbdn5lkv342crvkmbvy1xl5j3lsa1ica21kwh"; + "11.2" = "1p1qjvfbm28l933mmnln02rqrf0cy9kbpsyb488d1haiqzvrazl1"; + "11.3" = "0kbibb6pgz8j5iq6284axcnmycaha9bw8qlmdp6yfwmnahq1v0yz"; + "11.4" = "082dkk5y34wyvjgj2p5j1d00rk8xaxb9z0mhvz16bd469r1bw2qk"; + "11.5" = "sha256-AKRZbke0K59lakhTi8dX2cR2aBuWPZkiQxyKaZTvHrI="; + "11.6" = "sha256-AsLNmAplfuQbXg9zt09tXAuFJ524EtTYsQuUlV1tPkE="; + "11.7" = throw "The tag 11.7 of cuda-samples does not exist"; + "11.8" = "sha256-7+1P8+wqTKUGbCUBXGMDO9PkxYr2+PLDx9W2hXtXbuc="; + "12.0" = "sha256-Lj2kbdVFrJo5xPYPMiE4BS7Z8gpU5JLKXVJhZABUe/g="; + }.${prev.cudaVersion}; + +in { + cuda-samples = final.callPackage ./generic.nix { + inherit sha256; + }; +} diff --git a/nixpkgs/pkgs/test/cuda/cuda-samples/generic.nix b/nixpkgs/pkgs/test/cuda/cuda-samples/generic.nix new file mode 100644 index 000000000000..267eca10d8e8 --- /dev/null +++ b/nixpkgs/pkgs/test/cuda/cuda-samples/generic.nix @@ -0,0 +1,61 @@ +{ lib +, cudaPackages +, fetchFromGitHub +, fetchpatch +, addOpenGLRunpath +, cudatoolkit +, pkg-config +, sha256 +, glfw3 +, freeimage +}: +cudaPackages.backendStdenv.mkDerivation rec { + pname = "cuda-samples"; + version = lib.versions.majorMinor cudatoolkit.version; + + src = fetchFromGitHub { + owner = "NVIDIA"; + repo = pname; + rev = "v${version}"; + inherit sha256; + }; + + nativeBuildInputs = [ pkg-config addOpenGLRunpath glfw3 freeimage ]; + + buildInputs = [ cudatoolkit ]; + + # See https://github.com/NVIDIA/cuda-samples/issues/75. + patches = lib.optionals (version == "11.3") [ + (fetchpatch { + url = "https://github.com/NVIDIA/cuda-samples/commit/5c3ec60faeb7a3c4ad9372c99114d7bb922fda8d.patch"; + sha256 = "sha256-0XxdmNK9MPpHwv8+qECJTvXGlFxc+fIbta4ynYprfpU="; + }) + ]; + + enableParallelBuilding = true; + + preConfigure = '' + export CUDA_PATH=${cudatoolkit} + ''; + + installPhase = '' + runHook preInstall + + install -Dm755 -t $out/bin bin/${cudaPackages.backendStdenv.hostPlatform.parsed.cpu.name}/${cudaPackages.backendStdenv.hostPlatform.parsed.kernel.name}/release/* + + runHook postInstall + ''; + + postFixup = '' + for exe in $out/bin/*; do + addOpenGLRunpath $exe + done + ''; + + meta = { + description = "Samples for CUDA Developers which demonstrates features in CUDA Toolkit"; + # CUDA itself is proprietary, but these sample apps are not. + license = lib.licenses.bsd3; + maintainers = with lib.maintainers; [ obsidian-systems-maintenance ]; + }; +} diff --git a/nixpkgs/pkgs/test/cuda/default.nix b/nixpkgs/pkgs/test/cuda/default.nix new file mode 100644 index 000000000000..7989e4e2b7d2 --- /dev/null +++ b/nixpkgs/pkgs/test/cuda/default.nix @@ -0,0 +1,28 @@ +{ callPackage }: + +rec { + cuda-samplesPackages = callPackage ./cuda-samples { }; + inherit (cuda-samplesPackages) + cuda-samples_cudatoolkit_10 + cuda-samples_cudatoolkit_10_0 + cuda-samples_cudatoolkit_10_1 + cuda-samples_cudatoolkit_10_2 + cuda-samples_cudatoolkit_11 + cuda-samples_cudatoolkit_11_0 + cuda-samples_cudatoolkit_11_1 + cuda-samples_cudatoolkit_11_2 + cuda-samples_cudatoolkit_11_3 + cuda-samples_cudatoolkit_11_4; + + cuda-library-samplesPackages = callPackage ./cuda-library-samples { }; + inherit (cuda-library-samplesPackages) + cuda-library-samples_cudatoolkit_10 + cuda-library-samples_cudatoolkit_10_1 + cuda-library-samples_cudatoolkit_10_2 + cuda-library-samples_cudatoolkit_11 + cuda-library-samples_cudatoolkit_11_0 + cuda-library-samples_cudatoolkit_11_1 + cuda-library-samples_cudatoolkit_11_2 + cuda-library-samples_cudatoolkit_11_3 + cuda-library-samples_cudatoolkit_11_4; +} diff --git a/nixpkgs/pkgs/test/cue/default.nix b/nixpkgs/pkgs/test/cue/default.nix new file mode 100644 index 000000000000..2cc8bf34bb04 --- /dev/null +++ b/nixpkgs/pkgs/test/cue/default.nix @@ -0,0 +1,24 @@ +{ writeCueValidator, runCommand, writeText, ... }: + +let + validator = writeCueValidator + (writeText "schema.cue" '' + #Def1: { + field1: string + } + '') + { document = "#Def1"; }; +in runCommand "cue-validation" {} '' + cat > valid.json <<EOF + { "field1": "abc" } + EOF + cat > invalid.json <<EOF + { "field2": "abc" } + EOF + ${validator} valid.json + if ${validator} invalid.json; then + echo "this example should fail" + exit 1 + fi + touch $out +'' diff --git a/nixpkgs/pkgs/test/default.nix b/nixpkgs/pkgs/test/default.nix new file mode 100644 index 000000000000..6bfa1c4393c4 --- /dev/null +++ b/nixpkgs/pkgs/test/default.nix @@ -0,0 +1,96 @@ +{ pkgs, callPackage }: + +with pkgs; + +{ + cc-wrapper = callPackage ./cc-wrapper { }; + cc-wrapper-gcc = callPackage ./cc-wrapper { stdenv = gccStdenv; }; + cc-wrapper-gcc7 = callPackage ./cc-wrapper { stdenv = gcc7Stdenv; }; + cc-wrapper-gcc8 = callPackage ./cc-wrapper { stdenv = gcc8Stdenv; }; + cc-wrapper-gcc9 = callPackage ./cc-wrapper { stdenv = gcc9Stdenv; }; + cc-wrapper-clang = callPackage ./cc-wrapper { stdenv = llvmPackages.stdenv; }; + cc-wrapper-libcxx = callPackage ./cc-wrapper { stdenv = llvmPackages.libcxxStdenv; }; + cc-wrapper-clang-5 = callPackage ./cc-wrapper { stdenv = llvmPackages_5.stdenv; }; + cc-wrapper-libcxx-5 = callPackage ./cc-wrapper { stdenv = llvmPackages_5.libcxxStdenv; }; + cc-wrapper-clang-6 = callPackage ./cc-wrapper { stdenv = llvmPackages_6.stdenv; }; + cc-wrapper-libcxx-6 = callPackage ./cc-wrapper { stdenv = llvmPackages_6.libcxxStdenv; }; + cc-wrapper-clang-7 = callPackage ./cc-wrapper { stdenv = llvmPackages_7.stdenv; }; + cc-wrapper-libcxx-7 = callPackage ./cc-wrapper { stdenv = llvmPackages_7.libcxxStdenv; }; + cc-wrapper-clang-8 = callPackage ./cc-wrapper { stdenv = llvmPackages_8.stdenv; }; + cc-wrapper-libcxx-8 = callPackage ./cc-wrapper { stdenv = llvmPackages_8.libcxxStdenv; }; + cc-wrapper-clang-9 = callPackage ./cc-wrapper { stdenv = llvmPackages_9.stdenv; }; + cc-wrapper-libcxx-9 = callPackage ./cc-wrapper { stdenv = llvmPackages_9.libcxxStdenv; }; + stdenv-inputs = callPackage ./stdenv-inputs { }; + stdenv = callPackage ./stdenv { }; + + config = callPackage ./config.nix { }; + + haskell = callPackage ./haskell { }; + + hooks = callPackage ./hooks { }; + + cc-multilib-gcc = callPackage ./cc-wrapper/multilib.nix { stdenv = gccMultiStdenv; }; + cc-multilib-clang = callPackage ./cc-wrapper/multilib.nix { stdenv = clangMultiStdenv; }; + + fetchurl = callPackages ../build-support/fetchurl/tests.nix { }; + fetchpatch = callPackages ../build-support/fetchpatch/tests.nix { }; + fetchpatch2 = callPackages ../build-support/fetchpatch/tests.nix { fetchpatch = fetchpatch2; }; + fetchzip = callPackages ../build-support/fetchzip/tests.nix { }; + fetchgit = callPackages ../build-support/fetchgit/tests.nix { }; + fetchFirefoxAddon = callPackages ../build-support/fetchfirefoxaddon/tests.nix { }; + + install-shell-files = callPackage ./install-shell-files {}; + + kernel-config = callPackage ./kernel.nix {}; + + ld-library-path = callPackage ./ld-library-path {}; + + macOSSierraShared = callPackage ./macos-sierra-shared {}; + + cross = callPackage ./cross {}; + + php = recurseIntoAttrs (callPackages ./php {}); + + pkg-config = recurseIntoAttrs (callPackage ../top-level/pkg-config/tests.nix { }); + + buildRustCrate = callPackage ../build-support/rust/build-rust-crate/test { }; + importCargoLock = callPackage ../build-support/rust/test/import-cargo-lock { }; + + vim = callPackage ./vim {}; + + nixos-functions = callPackage ./nixos-functions {}; + + overriding = callPackage ./overriding.nix { }; + + texlive = callPackage ./texlive {}; + + cuda = callPackage ./cuda { }; + + trivial-builders = callPackage ../build-support/trivial-builders/test/default.nix {}; + + writers = callPackage ../build-support/writers/test.nix {}; + + testers = callPackage ../build-support/testers/test/default.nix {}; + + dhall = callPackage ./dhall { }; + + cue-validation = callPackage ./cue {}; + + coq = callPackage ./coq {}; + + dotnet = recurseIntoAttrs (callPackages ./dotnet { }); + + makeHardcodeGsettingsPatch = callPackage ./make-hardcode-gsettings-patch { }; + + makeWrapper = callPackage ./make-wrapper { }; + makeBinaryWrapper = callPackage ./make-binary-wrapper { + 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)) + [ "undefined" "address" ]; + }; + }; + + pkgs-lib = recurseIntoAttrs (import ../pkgs-lib/tests { inherit pkgs; }); +} diff --git a/nixpkgs/pkgs/test/dhall/buildDhallUrl/default.nix b/nixpkgs/pkgs/test/dhall/buildDhallUrl/default.nix new file mode 100644 index 000000000000..a75101a303d6 --- /dev/null +++ b/nixpkgs/pkgs/test/dhall/buildDhallUrl/default.nix @@ -0,0 +1,14 @@ +{ dhallPackages, lib }: + +# This file tests that dhallPackages.buildDhallUrl is able to successfully +# build a Nix Dhall package for a given remote Dhall import. +# +# TODO: It would be nice to extend this test to make sure that the resulting +# Nix Dhall package is has the expected contents. + +dhallPackages.buildDhallUrl { + url = "https://raw.githubusercontent.com/cdepillabout/example-dhall-nix/e6a675c72ecd4dd23d254a02aea8181fe875747f/mydhallfile.dhall"; + hash = "sha256-434x+QjHRzuprBdw0h6wmwB1Zj6yZqQb533me8XdO4c="; + dhallHash = "sha256-434x+QjHRzuprBdw0h6wmwB1Zj6yZqQb533me8XdO4c="; + source = true; +} diff --git a/nixpkgs/pkgs/test/dhall/default.nix b/nixpkgs/pkgs/test/dhall/default.nix new file mode 100644 index 000000000000..4c7eba6c9579 --- /dev/null +++ b/nixpkgs/pkgs/test/dhall/default.nix @@ -0,0 +1,6 @@ +{ lib, callPackage }: + +lib.recurseIntoAttrs { + buildDhallUrl = callPackage ./buildDhallUrl { }; + generateDhallDirectoryPackage = callPackage ./generateDhallDirectoryPackage { }; +} diff --git a/nixpkgs/pkgs/test/dhall/generateDhallDirectoryPackage/default.nix b/nixpkgs/pkgs/test/dhall/generateDhallDirectoryPackage/default.nix new file mode 100644 index 000000000000..4771e1629806 --- /dev/null +++ b/nixpkgs/pkgs/test/dhall/generateDhallDirectoryPackage/default.nix @@ -0,0 +1,17 @@ +{ dhallPackages, fetchFromGitHub }: + +# This file tests that dhallPackages.generateDhallDirectoryPackage works. +# +# TODO: It would be nice to extend this test to make sure that the resulting +# Nix file has the expected contents, but it might be tough to do that easily +# without IFD. + +dhallPackages.generateDhallDirectoryPackage { + src = fetchFromGitHub { + owner = "cdepillabout"; + repo = "example-dhall-nix"; + rev = "e6a675c72ecd4dd23d254a02aea8181fe875747f"; + sha256 = "sha256-c/EZq76s/+hmLkaeJWKqgh2KrHuJRYI6kWry0E0YQ6s="; + }; + file = "mydhallfile.dhall"; +} diff --git a/nixpkgs/pkgs/test/dotnet/default.nix b/nixpkgs/pkgs/test/dotnet/default.nix new file mode 100644 index 000000000000..7592b09d76e3 --- /dev/null +++ b/nixpkgs/pkgs/test/dotnet/default.nix @@ -0,0 +1,5 @@ +{ callPackage }: + +{ + project-references = callPackage ./project-references { }; +} diff --git a/nixpkgs/pkgs/test/dotnet/project-references/application/Application.cs b/nixpkgs/pkgs/test/dotnet/project-references/application/Application.cs new file mode 100644 index 000000000000..ae2c956a4df7 --- /dev/null +++ b/nixpkgs/pkgs/test/dotnet/project-references/application/Application.cs @@ -0,0 +1 @@ +ProjectReferencesTest.Library.Hello(); diff --git a/nixpkgs/pkgs/test/dotnet/project-references/application/Application.csproj b/nixpkgs/pkgs/test/dotnet/project-references/application/Application.csproj new file mode 100644 index 000000000000..6507637a5535 --- /dev/null +++ b/nixpkgs/pkgs/test/dotnet/project-references/application/Application.csproj @@ -0,0 +1,10 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <OutputType>exe</OutputType> + </PropertyGroup> + + <ItemGroup> + <ProjectReference Include="../library/Library.csproj" /> + <PackageReference Include="ProjectReferencesTest.Library" Version="*" Condition=" '$(ContinuousIntegrationBuild)'=='true' " /> + </ItemGroup> +</Project> diff --git a/nixpkgs/pkgs/test/dotnet/project-references/default.nix b/nixpkgs/pkgs/test/dotnet/project-references/default.nix new file mode 100644 index 000000000000..f40b9196c209 --- /dev/null +++ b/nixpkgs/pkgs/test/dotnet/project-references/default.nix @@ -0,0 +1,38 @@ +# Tests the `projectReferences = [ ... ];` feature of buildDotnetModule. +# The `library` derivation exposes a .nupkg, which is then consumed by the `application` derivation. +# https://nixos.org/manual/nixpkgs/unstable/index.html#packaging-a-dotnet-application + +{ lib +, dotnet-sdk +, buildDotnetModule +, runCommand +}: + +let + nugetDeps = ./nuget-deps.nix; + + # Specify the TargetFramework via an environment variable so that we don't + # have to update the .csproj files when updating dotnet-sdk + TargetFramework = "net${lib.versions.majorMinor (lib.getVersion dotnet-sdk)}"; + + library = buildDotnetModule { + name = "project-references-test-library"; + src = ./library; + inherit nugetDeps TargetFramework; + + packNupkg = true; + }; + + application = buildDotnetModule { + name = "project-references-test-application"; + src = ./application; + inherit nugetDeps TargetFramework; + + projectReferences = [ library ]; + }; +in + +runCommand "project-references-test" { } '' + ${application}/bin/Application + touch $out +'' diff --git a/nixpkgs/pkgs/test/dotnet/project-references/library/Library.cs b/nixpkgs/pkgs/test/dotnet/project-references/library/Library.cs new file mode 100644 index 000000000000..a4af4a0fea2d --- /dev/null +++ b/nixpkgs/pkgs/test/dotnet/project-references/library/Library.cs @@ -0,0 +1,8 @@ +namespace ProjectReferencesTest; +public static class Library +{ + public static void Hello() + { + System.Console.WriteLine("Hello, World!"); + } +} diff --git a/nixpkgs/pkgs/test/dotnet/project-references/library/Library.csproj b/nixpkgs/pkgs/test/dotnet/project-references/library/Library.csproj new file mode 100644 index 000000000000..b9a71276d24a --- /dev/null +++ b/nixpkgs/pkgs/test/dotnet/project-references/library/Library.csproj @@ -0,0 +1,5 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <PackageId>ProjectReferencesTest.Library</PackageId> + </PropertyGroup> +</Project> diff --git a/nixpkgs/pkgs/test/dotnet/project-references/nuget-deps.nix b/nixpkgs/pkgs/test/dotnet/project-references/nuget-deps.nix new file mode 100644 index 000000000000..f3a17967e25c --- /dev/null +++ b/nixpkgs/pkgs/test/dotnet/project-references/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/nixpkgs/pkgs/test/haskell/cabalSdist/default.nix b/nixpkgs/pkgs/test/haskell/cabalSdist/default.nix new file mode 100644 index 000000000000..1031e51e4f14 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/cabalSdist/default.nix @@ -0,0 +1,28 @@ +{ lib, haskellPackages, runCommand }: + +let + localRaw = haskellPackages.callPackage ./local/generated.nix {}; +in +lib.recurseIntoAttrs rec { + + helloFromCabalSdist = haskellPackages.buildFromCabalSdist haskellPackages.hello; + + # A more complicated example with a cabal hook. + hercules-ci-cnix-store = haskellPackages.buildFromCabalSdist haskellPackages.hercules-ci-cnix-store; + + localFromCabalSdist = haskellPackages.buildFromCabalSdist localRaw; + + assumptionLocalHasDirectReference = runCommand "localHasDirectReference" { + drvPath = builtins.unsafeDiscardOutputDependency localRaw.drvPath; + } '' + grep ${./local} $drvPath >/dev/null + touch $out + ''; + + localHasNoDirectReference = runCommand "localHasNoDirectReference" { + drvPath = builtins.unsafeDiscardOutputDependency localFromCabalSdist.drvPath; + } '' + grep -v ${./local} $drvPath >/dev/null + touch $out + ''; +} diff --git a/nixpkgs/pkgs/test/haskell/cabalSdist/local/CHANGELOG.md b/nixpkgs/pkgs/test/haskell/cabalSdist/local/CHANGELOG.md new file mode 100644 index 000000000000..53cc3ae43d8a --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/cabalSdist/local/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for local + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/nixpkgs/pkgs/test/haskell/cabalSdist/local/app/Main.hs b/nixpkgs/pkgs/test/haskell/cabalSdist/local/app/Main.hs new file mode 100644 index 000000000000..65ae4a05d5db --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/cabalSdist/local/app/Main.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = putStrLn "Hello, Haskell!" diff --git a/nixpkgs/pkgs/test/haskell/cabalSdist/local/generated.nix b/nixpkgs/pkgs/test/haskell/cabalSdist/local/generated.nix new file mode 100644 index 000000000000..bfa299962bcb --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/cabalSdist/local/generated.nix @@ -0,0 +1,12 @@ +# nix run ../../../../..#cabal2nix -- ./. +{ mkDerivation, base, lib }: +mkDerivation { + pname = "local"; + version = "0.1.0.0"; + src = ./.; + isLibrary = false; + isExecutable = true; + executableHaskellDepends = [ base ]; + description = "Nixpkgs test case"; + license = lib.licenses.mit; +} diff --git a/nixpkgs/pkgs/test/haskell/cabalSdist/local/local.cabal b/nixpkgs/pkgs/test/haskell/cabalSdist/local/local.cabal new file mode 100644 index 000000000000..1670aa3af631 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/cabalSdist/local/local.cabal @@ -0,0 +1,13 @@ +cabal-version: 2.4 +name: local +version: 0.1.0.0 + +synopsis: Nixpkgs test case +license: MIT +extra-source-files: CHANGELOG.md + +executable local + main-is: Main.hs + build-depends: base + hs-source-dirs: app + default-language: Haskell2010 diff --git a/nixpkgs/pkgs/test/haskell/default.nix b/nixpkgs/pkgs/test/haskell/default.nix new file mode 100644 index 000000000000..8f1f21d65b51 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/default.nix @@ -0,0 +1,10 @@ +{ lib, callPackage }: + +lib.recurseIntoAttrs { + shellFor = callPackage ./shellFor { }; + cabalSdist = callPackage ./cabalSdist { }; + documentationTarball = callPackage ./documentationTarball { }; + setBuildTarget = callPackage ./setBuildTarget { }; + incremental = callPackage ./incremental { }; + upstreamStackHpackVersion = callPackage ./upstreamStackHpackVersion { }; +} diff --git a/nixpkgs/pkgs/test/haskell/documentationTarball/default.nix b/nixpkgs/pkgs/test/haskell/documentationTarball/default.nix new file mode 100644 index 000000000000..337510281012 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/documentationTarball/default.nix @@ -0,0 +1,21 @@ +{ pkgs, haskellPackages }: + +let + drv = haskellPackages.vector; + docs = pkgs.haskell.lib.compose.documentationTarball drv; + +in pkgs.runCommand "test haskell.lib.compose.documentationTarball" { + meta = { + inherit (docs.meta) platforms; + }; +} '' + tar xvzf "${docs}/${drv.name}-docs.tar.gz" + + # Check for Haddock html + find "${drv.name}-docs" | grep -q "Data-Vector.html" + + # Check for source html + find "${drv.name}-docs" | grep -q "src/Data.Vector.html" + + touch "$out" +'' diff --git a/nixpkgs/pkgs/test/haskell/incremental/default.nix b/nixpkgs/pkgs/test/haskell/incremental/default.nix new file mode 100644 index 000000000000..4509939ba4f4 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/incremental/default.nix @@ -0,0 +1,35 @@ +# Demonstration of incremental builds for Haskell. Useful for speeding up CI. +# +# See: https://www.haskellforall.com/2022/12/nixpkgs-support-for-incremental-haskell.html +# See: https://felixspringer.xyz/homepage/blog/incrementalHaskellBuildsWithNix + +{ haskell, lib }: + +let + inherit (haskell.lib.compose) overrideCabal; + + # Incremental builds work with GHC >=9.4. + temporary = haskell.packages.ghc944.temporary; + + # This will do a full build of `temporary`, while writing the intermediate build products + # (compiled modules, etc.) to the `intermediates` output. + temporary-full-build-with-incremental-output = overrideCabal (drv: { + doInstallIntermediates = true; + enableSeparateIntermediatesOutput = true; + }) temporary; + + # This will do an incremental build of `temporary` by copying the previously + # compiled modules and intermediate build products into the source tree + # before running the build. + # + # GHC will then naturally pick up and reuse these products, making this build + # complete much more quickly than the previous one. + temporary-incremental-build = overrideCabal (drv: { + previousIntermediates = temporary-full-build-with-incremental-output.intermediates; + }) temporary; +in + temporary-incremental-build.overrideAttrs (old: { + meta = { + maintainers = lib.teams.mercury.members; + }; + }) diff --git a/nixpkgs/pkgs/test/haskell/setBuildTarget/Bar.hs b/nixpkgs/pkgs/test/haskell/setBuildTarget/Bar.hs new file mode 100644 index 000000000000..010014082c7d --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/setBuildTarget/Bar.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = putStrLn "Hello, Bar!" diff --git a/nixpkgs/pkgs/test/haskell/setBuildTarget/Foo.hs b/nixpkgs/pkgs/test/haskell/setBuildTarget/Foo.hs new file mode 100644 index 000000000000..fec7bb11fe6c --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/setBuildTarget/Foo.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = putStrLn "Hello, Foo!" diff --git a/nixpkgs/pkgs/test/haskell/setBuildTarget/Setup.hs b/nixpkgs/pkgs/test/haskell/setBuildTarget/Setup.hs new file mode 100644 index 000000000000..9a994af677b0 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/setBuildTarget/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/nixpkgs/pkgs/test/haskell/setBuildTarget/default.nix b/nixpkgs/pkgs/test/haskell/setBuildTarget/default.nix new file mode 100644 index 000000000000..f0c78c510449 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/setBuildTarget/default.nix @@ -0,0 +1,43 @@ +{ pkgs, haskellPackages }: + +let + # This can be regenerated by running `cabal2nix .` in the current directory. + pkgDef = + { mkDerivation, base, lib }: + mkDerivation { + pname = "haskell-setBuildTarget"; + version = "0.1.0.0"; + src = ./.; + isLibrary = false; + isExecutable = true; + executableHaskellDepends = [ base ]; + license = lib.licenses.bsd3; + }; + + drv = haskellPackages.callPackage pkgDef {}; + + test = target: excluded: + let only = pkgs.haskell.lib.compose.setBuildTarget target drv; + in '' + if [[ ! -f "${only}/bin/${target}" ]]; then + echo "${target} was not built" + exit 1 + fi + + if [[ -f "${only}/bin/${excluded}" ]]; then + echo "${excluded} was built, when it should not have been" + exit 1 + fi + ''; + +in +pkgs.runCommand "test haskell.lib.compose.setBuildTarget" { + meta = { + inherit (drv.meta) platforms; + }; +} '' + ${test "foo" "bar"} + ${test "bar" "foo"} + touch "$out" +'' + diff --git a/nixpkgs/pkgs/test/haskell/setBuildTarget/haskell-setBuildTarget.cabal b/nixpkgs/pkgs/test/haskell/setBuildTarget/haskell-setBuildTarget.cabal new file mode 100644 index 000000000000..7395e139451c --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/setBuildTarget/haskell-setBuildTarget.cabal @@ -0,0 +1,16 @@ +cabal-version: >=1.10 +name: haskell-setBuildTarget +version: 0.1.0.0 +author: Isaac Shapira +maintainer: fresheyeball@protonmail.com +build-type: Simple + +executable foo + main-is: Foo.hs + build-depends: base + default-language: Haskell2010 + +executable bar + main-is: Bar.hs + build-depends: base + default-language: Haskell2010 diff --git a/nixpkgs/pkgs/test/haskell/shellFor/default.nix b/nixpkgs/pkgs/test/haskell/shellFor/default.nix new file mode 100644 index 000000000000..83daf079cc0f --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/shellFor/default.nix @@ -0,0 +1,57 @@ +{ lib, writeText, haskellPackages, cabal-install }: + +(haskellPackages.shellFor { + packages = p: [ p.constraints p.linear ]; + # WARNING: When updating this, make sure that the libraries passed to + # `extraDependencies` are not actually transitive dependencies of libraries in + # `packages` above. We explicitly want to test that it is possible to specify + # `extraDependencies` that are not in the closure of `packages`. + extraDependencies = p: { libraryHaskellDepends = [ p.conduit ]; }; + nativeBuildInputs = [ cabal-install ]; + phases = [ "unpackPhase" "buildPhase" "installPhase" ]; + unpackPhase = '' + sourceRoot=$(pwd)/scratch + mkdir -p "$sourceRoot" + cd "$sourceRoot" + tar -xf ${haskellPackages.constraints.src} + tar -xf ${haskellPackages.linear.src} + cp ${writeText "cabal.project" "packages: constraints* linear*"} cabal.project + ''; + buildPhase = '' + export HOME=$(mktemp -d) + mkdir -p $HOME/.cabal + touch $HOME/.cabal/config + + # Check that the extraDependencies.libraryHaskellDepends arg is correctly + # picked up. This uses ghci to interpret a small Haskell program that uses + # a package from extraDependencies. + ghci <<EOF + :set -XOverloadedStrings + :m + Conduit + runResourceT $ connect (yield "done") (sinkFile "outfile") + EOF + + if [[ "done" != "$(cat outfile)" ]]; then + echo "ERROR: extraDependencies appear not to be available in the environment" + exit 1 + fi + + # Check packages arg + cabal v2-build --offline --verbose constraints linear --ghc-options="-O0 -j$NIX_BUILD_CORES" + ''; + installPhase = '' + touch $out + ''; +}).overrideAttrs (oldAttrs: { + meta = + let + oldMeta = oldAttrs.meta or {}; + oldMaintainers = oldMeta.maintainers or []; + additionalMaintainers = with lib.maintainers; [ cdepillabout ]; + allMaintainers = oldMaintainers ++ additionalMaintainers; + in + oldMeta // { + maintainers = allMaintainers; + inherit (cabal-install.meta) platforms; + }; +}) diff --git a/nixpkgs/pkgs/test/haskell/upstreamStackHpackVersion/default.nix b/nixpkgs/pkgs/test/haskell/upstreamStackHpackVersion/default.nix new file mode 100644 index 000000000000..ddf267702592 --- /dev/null +++ b/nixpkgs/pkgs/test/haskell/upstreamStackHpackVersion/default.nix @@ -0,0 +1,151 @@ + +# This derivation confirms that the version of hpack used by stack in Nixpkgs +# is the exact same version as the upstream stack release. +# +# It is important to make sure the version of hpack used by stack in Nixpkgs +# matches with the version of hpack used by the upstream stack release. This +# is because hpack works slightly differently based on the version, and it can +# be frustrating to use hpack in a team setting when members are using different +# versions. See for more info: https://github.com/NixOS/nixpkgs/issues/223390 +# +# This test is written as a fixed-output derivation, because we need to access +# accesses the internet to download the upstream stack release. + +{ cacert, curl, lib, stack, stdenv }: + +let + # Find the hpack derivation that is a dependency of stack. Throw exception + # if hpack cannot be found. + hpack = + lib.findFirst + (v: v.pname or "" == "hpack") + (throw "could not find stack's hpack dependency") + stack.passthru.getCabalDeps.executableHaskellDepends; + + # This is a statically linked version of stack, so it should be usable within + # the Nixpkgs builder (at least on x86_64-linux). + stackDownloadUrl = + "https://github.com/commercialhaskell/stack/releases/download/v${stack.version}/stack-${stack.version}-linux-x86_64-static.tar.gz"; + + # This test code has been explicitly pulled out of the derivation below so + # that it can be hashed and added to the `name` of the derivation. This is + # so that this test derivation won't be cached if the body of the test is + # modified. + # + # WARNING: When modifying this script, make sure you don't introduce any + # paths to the Nix store within it. We only want this derivation to be re-run + # when the stack version (or the version of its hpack dependency) changes in + # Nixpkgs. + testScript = '' + curl=( + curl + --location + --max-redirs 20 + --retry 3 + --disable-epsv + --cookie-jar cookies + --user-agent "curl " + --insecure + ) + + # Fetch the statically-linked upstream Stack binary. + "''${curl[@]}" "${stackDownloadUrl}" > ./stack.tar.gz + tar xf ./stack.tar.gz + + upstream_stack_version_output="$(./stack-${stack.version}-linux-x86_64-static/stack --version)" + echo "upstream \`stack --version\` output: $upstream_stack_version_output" + + nixpkgs_stack_version_output="$(stack --version)" + echo "nixpkgs \`stack --version\` output: $nixpkgs_stack_version_output" + + # Confirm that the upstream stack version is the same as the stack version + # in Nixpkgs. This check isn't strictly necessary, but it is a good sanity + # check. + + if [[ "$upstream_stack_version_output" =~ "Version "([0-9]+((\.[0-9]+)+)) ]]; then + upstream_stack_version="''${BASH_REMATCH[1]}" + + echo "parsed upstream stack version: $upstream_stack_version" + echo "stack version from nixpkgs: ${stack.version}" + + if [[ "${stack.version}" != "$upstream_stack_version" ]]; then + echo "ERROR: stack version in Nixpkgs (${stack.version}) does not match the upstream version for some reason: $upstream_stack_version" + exit 1 + fi + else + echo "ERROR: Upstream stack version cannot be found in --version output: $upstream_stack_version" + exit 1 + fi + + # Confirm that the hpack version used in the upstream stack release is the + # same as the hpack version used by the Nixpkgs stack binary. + + if [[ "$upstream_stack_version_output" =~ hpack-([0-9]+((\.[0-9]+)+)) ]]; then + upstream_hpack_version="''${BASH_REMATCH[1]}" + + echo "parsed upstream stack's hpack version: $upstream_hpack_version" + echo "Nixpkgs stack's hpack version: ${hpack.version}" + + if [[ "${hpack.version}" != "$upstream_hpack_version" ]]; then + echo "ERROR: stack's hpack version in Nixpkgs (${hpack.version}) does not match the upstream stack's hpack version: $upstream_hpack_version" + echo "The stack derivation in Nixpkgs needs to be fixed up so that it depends on hpack-$upstream_hpack_version, instead of ${hpack.name}" + exit 1 + fi + else + echo "ERROR: Upstream stack's hpack version cannot be found in --version output: $upstream_hpack_version" + exit 1 + fi + + # Output a string with a known hash. + echo "success" > $out + ''; + + testScriptHash = builtins.hashString "sha256" testScript; +in + +stdenv.mkDerivation { + + # This name is very important. + # + # The idea here is that want this derivation to be re-run everytime the + # version of stack (or the version of its hpack dependency) changes in + # Nixpkgs. We also want to re-run this derivation whenever the test script + # is changed. + # + # Nix/Hydra will re-run derivations if their name changes (even if they are a + # FOD and they have the same hash). + # + # The name of this derivation contains the stack version string, the hpack + # version string, and a hash of the test script. So Nix will know to + # re-run this version when (and only when) one of those values change. + name = "upstream-stack-hpack-version-test-${stack.name}-${hpack.name}-${testScriptHash}"; + + # This is the sha256 hash for the string "success", which is output upon this + # test succeeding. + outputHash = "sha256-gbK9TqmMjbZlVPvI12N6GmmhMPMx/rcyt1yqtMSGj9U="; + outputHashMode = "flat"; + outputHashAlgo = "sha256"; + + nativeBuildInputs = [ curl stack ]; + + impureEnvVars = lib.fetchers.proxyImpureEnvVars; + + buildCommand = '' + # Make sure curl can access HTTPS sites, like GitHub. + # + # Note that we absolutely don't want the Nix store path of the cacert + # derivation in the testScript, because we don't want to rebuild this + # derivation when only the cacert derivation changes. + export SSL_CERT_FILE="${cacert}/etc/ssl/certs/ca-bundle.crt" + '' + testScript; + + meta = with lib; { + description = "Test that the stack in Nixpkgs uses the same version of Hpack as the upstream stack release"; + maintainers = with maintainers; [ cdepillabout ]; + + # This derivation internally runs a statically-linked version of stack from + # upstream. This statically-linked version of stack is only available for + # x86_64-linux, so this test can only be run on x86_64-linux. + platforms = [ "x86_64-linux" ]; + }; +} diff --git a/nixpkgs/pkgs/test/hooks/default.nix b/nixpkgs/pkgs/test/hooks/default.nix new file mode 100644 index 000000000000..aabf939b6865 --- /dev/null +++ b/nixpkgs/pkgs/test/hooks/default.nix @@ -0,0 +1,8 @@ +# To run these tests: +# nix-build -A tests.hooks + +{ stdenv, tests, lib }: + +{ + default-stdenv-hooks = lib.recurseIntoAttrs tests.stdenv.hooks; +} diff --git a/nixpkgs/pkgs/test/install-shell-files/default.nix b/nixpkgs/pkgs/test/install-shell-files/default.nix new file mode 100644 index 000000000000..aef5acc1de6b --- /dev/null +++ b/nixpkgs/pkgs/test/install-shell-files/default.nix @@ -0,0 +1,125 @@ +{ lib, runCommandLocal, recurseIntoAttrs, 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; } + ''; +} diff --git a/nixpkgs/pkgs/test/kernel.nix b/nixpkgs/pkgs/test/kernel.nix new file mode 100644 index 000000000000..2ccd188b1edb --- /dev/null +++ b/nixpkgs/pkgs/test/kernel.nix @@ -0,0 +1,73 @@ +# 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; + + # to see the result once the module transformed the lose structured config + getConfig = structuredConfig: + (lts_kernel.override { + structuredExtraConfig = structuredConfig; + }).configfile.structuredConfig; + + mandatoryVsOptionalConfig = mkMerge [ + { NIXOS_FAKE_USB_DEBUG = yes;} + { NIXOS_FAKE_USB_DEBUG = option 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: + ]; + + mkDefaultWorksConfig = mkMerge [ + { "NIXOS_TEST_BOOLEAN" = yes; } + { "NIXOS_TEST_BOOLEAN" = lib.mkDefault no; } + ]; + + allOptionalRemainOptional = mkMerge [ + { NIXOS_FAKE_USB_DEBUG = option yes;} + { NIXOS_FAKE_USB_DEBUG = option yes;} + ]; + +in +runTests { + testEasy = { + expr = (getConfig { NIXOS_FAKE_USB_DEBUG = 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; + }; + + testYesWinsOverNo = { + expr = (getConfig mkDefaultWorksConfig)."NIXOS_TEST_BOOLEAN".tristate; + expected = "y"; + }; + + 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; + }; + +} diff --git a/nixpkgs/pkgs/test/ld-library-path/default.nix b/nixpkgs/pkgs/test/ld-library-path/default.nix new file mode 100644 index 000000000000..74c52cef2532 --- /dev/null +++ b/nixpkgs/pkgs/test/ld-library-path/default.nix @@ -0,0 +1,88 @@ +{ lib, stdenv }: + +# This tests that libraries listed in LD_LIBRARY_PATH take precedence over those listed in RPATH. + +let + # A simple test library: libgreeting.so which exports a single function getGreeting() returning the good old hello greeting. + libgreeting = stdenv.mkDerivation { + name = "libgreeting"; + + code = '' + const char* getGreeting() { return "Hello, world!"; } + ''; + + unpackPhase = '' + echo "$code" > libgreeting.c + ''; + + installPhase = '' + mkdir -p $out/lib + $CC -c -fpic libgreeting.c + $CC -shared libgreeting.o -o $out/lib/libgreeting.so + ''; + }; + + # A variant of libgreeting.so that returns a different message. + libgoodbye = libgreeting.overrideAttrs (_: { + name = "libgoodbye"; + code = '' + const char* getGreeting() { return "Goodbye, world!"; } + ''; + }); + + # A simple consumer of libgreeting.so that just prints the greeting to stdout. + testProgram = stdenv.mkDerivation { + name = "greeting-test"; + + buildInputs = [ libgreeting ]; + + code = '' + #include <stdio.h> + + extern const char* getGreeting(void); + + int main() { + puts(getGreeting()); + } + ''; + + unpackPhase = '' + echo "$code" > greeting-test.c + ''; + + installPhase = '' + mkdir -p $out/bin + $CC -c greeting-test.c + $CC greeting-test.o -lgreeting -o $out/bin/greeting-test + + # Now test the installed binaries right after compiling them. In particular, + # don't do this in installCheckPhase because fixupPhase has been run by then! + ( + export PATH=$out/bin + set -x + + # Verify that our unmodified binary works as expected. + [ "$(greeting-test)" = "Hello, world!" ] + + # And finally, test that a library in LD_LIBRARY_PATH takes precedence over the linked-in library. + [ "$(LD_LIBRARY_PATH=${libgoodbye}/lib greeting-test)" = "Goodbye, world!" ] + ) + ''; + + }; +in stdenv.mkDerivation { + name = "test-LD_LIBRARY_PATH"; + nativeBuildInputs = [ testProgram ]; + + buildCommand = '' + # And for good measure, repeat the tests again from a separate derivation, + # as fixupPhase done by the stdenv can (and has!) affect the result. + + [ "$(greeting-test)" = "Hello, world!" ] + [ "$(LD_LIBRARY_PATH=${libgoodbye}/lib greeting-test)" = "Goodbye, world!" ] + + touch $out + ''; + + meta.platforms = lib.platforms.linux; +} diff --git a/nixpkgs/pkgs/test/macos-sierra-shared/default.nix b/nixpkgs/pkgs/test/macos-sierra-shared/default.nix new file mode 100644 index 000000000000..810d5d97829b --- /dev/null +++ b/nixpkgs/pkgs/test/macos-sierra-shared/default.nix @@ -0,0 +1,90 @@ +{ lib, clangStdenv, clang-sierraHack-stdenv, stdenvNoCC }: + +let + makeBigExe = stdenv: prefix: rec { + + count = 320; + + sillyLibs = lib.genList (i: stdenv.mkDerivation rec { + name = "${prefix}-fluff-${toString i}"; + unpackPhase = '' + src=$PWD + cat << 'EOF' > ${name}.c + unsigned int asdf_${toString i}(void) { + return ${toString i}; + } + EOF + ''; + buildPhase = '' + $CC -std=c99 -shared ${name}.c -o lib${name}.dylib -Wl,-install_name,$out/lib/lib${name}.dylib + ''; + installPhase = '' + mkdir -p "$out/lib" + mv lib${name}.dylib "$out/lib" + ''; + meta.platforms = lib.platforms.darwin; + }) count; + + finalExe = stdenv.mkDerivation { + name = "${prefix}-final-asdf"; + unpackPhase = '' + src=$PWD + cat << 'EOF' > main.cxx + + #include <cstdlib> + #include <iostream> + + ${toString (lib.genList (i: "extern \"C\" unsigned int asdf_${toString i}(void); ") count)} + + unsigned int (*funs[])(void) = { + ${toString (lib.genList (i: "asdf_${toString i},") count)} + }; + + int main(int argc, char **argv) { + bool ret; + unsigned int i = 0; + for (auto f : funs) { + if (f() != i++) { + std::cerr << "Failed to get expected response from function #" << i << std::endl; + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; + } + EOF + ''; + buildPhase = '' + $CXX -std=c++11 main.cxx ${toString (map (x: "-l${x.name}") sillyLibs)} -o ${prefix}-asdf + ''; + buildInputs = sillyLibs; + installPhase = '' + mkdir -p "$out/bin" + mv ${prefix}-asdf "$out/bin" + ''; + meta.platforms = lib.platforms.darwin; + }; + + }; + + good = makeBigExe clang-sierraHack-stdenv "good"; + + bad = makeBigExe clangStdenv "bad"; + +in stdenvNoCC.mkDerivation { + name = "macos-sierra-shared-test"; + buildInputs = [ good.finalExe bad.finalExe ]; + # TODO(@Ericson2314): Be impure or require exact MacOS version of builder? + buildCommand = '' + if bad-asdf &> /dev/null + then echo "WARNING: bad-asdf did not fail, not running on sierra?" >&2 + else echo "bad-asdf should fail on sierra, OK" >&2 + fi + + # Must succeed on all supported MacOS versions + good-asdf + echo "good-asdf should succeed on sierra, OK" + + touch $out + ''; + meta.platforms = lib.platforms.darwin; +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.c b/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.c new file mode 100644 index 000000000000..3ae8678d4421 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.c @@ -0,0 +1,23 @@ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> + +int main(int argc, char **argv) { + char **argv_tmp = calloc(4 + argc + 2 + 1, sizeof(*argv_tmp)); + assert(argv_tmp != NULL); + argv_tmp[0] = argv[0]; + argv_tmp[1] = "-x"; + argv_tmp[2] = "-y"; + argv_tmp[3] = "-z"; + argv_tmp[4] = "-abc"; + for (int i = 1; i < argc; ++i) { + argv_tmp[4 + i] = argv[i]; + } + argv_tmp[4 + argc + 0] = "-foo"; + argv_tmp[4 + argc + 1] = "-bar"; + argv_tmp[4 + argc + 2] = NULL; + argv = argv_tmp; + + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.cmdline new file mode 100644 index 000000000000..f42d26f3adf0 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.cmdline @@ -0,0 +1,3 @@ + --append-flags "-foo -bar" \ + --add-flags "-x -y -z" \ + --add-flags -abc diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.env b/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.env new file mode 100644 index 000000000000..3626b8cf97b0 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/add-flags.env @@ -0,0 +1,8 @@ +CWD=SUBST_CWD +SUBST_ARGV0 +-x +-y +-z +-abc +-foo +-bar diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/argv0.c b/nixpkgs/pkgs/test/make-binary-wrapper/argv0.c new file mode 100644 index 000000000000..70c36889dc89 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/argv0.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + argv[0] = "alternative-name"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/argv0.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/argv0.cmdline new file mode 100644 index 000000000000..1cadce8312a4 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/argv0.cmdline @@ -0,0 +1 @@ + --argv0 alternative-name diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/argv0.env b/nixpkgs/pkgs/test/make-binary-wrapper/argv0.env new file mode 100644 index 000000000000..04c13d32ee6d --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/argv0.env @@ -0,0 +1,2 @@ +CWD=SUBST_CWD +alternative-name diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/basic.c b/nixpkgs/pkgs/test/make-binary-wrapper/basic.c new file mode 100644 index 000000000000..1c1266181377 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/basic.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/basic.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/basic.cmdline new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/basic.cmdline diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/basic.env b/nixpkgs/pkgs/test/make-binary-wrapper/basic.env new file mode 100644 index 000000000000..b0da31959447 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/basic.env @@ -0,0 +1,2 @@ +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/chdir.c b/nixpkgs/pkgs/test/make-binary-wrapper/chdir.c new file mode 100644 index 000000000000..9e0b7e2c7f52 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/chdir.c @@ -0,0 +1,11 @@ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +int main(int argc, char **argv) { + assert_success(chdir("./tmp/foo")); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/chdir.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/chdir.cmdline new file mode 100644 index 000000000000..d6ab081e8d35 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/chdir.cmdline @@ -0,0 +1 @@ + --chdir ./tmp/foo diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/chdir.env b/nixpkgs/pkgs/test/make-binary-wrapper/chdir.env new file mode 100644 index 000000000000..ea1c61054e50 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/chdir.env @@ -0,0 +1,2 @@ +CWD=SUBST_CWD/tmp/foo +SUBST_ARGV0 diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/combination.c b/nixpkgs/pkgs/test/make-binary-wrapper/combination.c new file mode 100644 index 000000000000..8ce8a4722a0b --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/combination.c @@ -0,0 +1,53 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +void set_env_prefix(char *env, char *sep, char *prefix) { + char *existing = getenv(env); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", prefix, sep, existing)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, prefix, 1)); + } +} + +void set_env_suffix(char *env, char *sep, char *suffix) { + char *existing = getenv(env); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", existing, sep, suffix)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, suffix, 1)); + } +} + +int main(int argc, char **argv) { + assert_success(setenv("MESSAGE", "HELLO", 0)); + set_env_prefix("PATH", ":", "/usr/bin/"); + set_env_suffix("PATH", ":", "/usr/local/bin/"); + putenv("MESSAGE2=WORLD"); + + char **argv_tmp = calloc(3 + argc + 0 + 1, sizeof(*argv_tmp)); + assert(argv_tmp != NULL); + argv_tmp[0] = argv[0]; + argv_tmp[1] = "-x"; + argv_tmp[2] = "-y"; + argv_tmp[3] = "-z"; + for (int i = 1; i < argc; ++i) { + argv_tmp[3 + i] = argv[i]; + } + argv_tmp[3 + argc + 0] = NULL; + argv = argv_tmp; + + argv[0] = "my-wrapper"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/combination.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/combination.cmdline new file mode 100644 index 000000000000..fb3861235c8b --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/combination.cmdline @@ -0,0 +1,6 @@ + --argv0 my-wrapper \ + --set-default MESSAGE HELLO \ + --prefix PATH : /usr/bin/ \ + --suffix PATH : /usr/local/bin/ \ + --add-flags "-x -y -z" \ + --set MESSAGE2 WORLD diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/combination.env b/nixpkgs/pkgs/test/make-binary-wrapper/combination.env new file mode 100644 index 000000000000..886420c01d1e --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/combination.env @@ -0,0 +1,8 @@ +MESSAGE=HELLO +PATH=/usr/bin/:/usr/local/bin/ +MESSAGE2=WORLD +CWD=SUBST_CWD +my-wrapper +-x +-y +-z diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/cross.nix b/nixpkgs/pkgs/test/make-binary-wrapper/cross.nix new file mode 100644 index 000000000000..36758086b92b --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/cross.nix @@ -0,0 +1,23 @@ +{ stdenv +, runCommand +, makeBinaryWrapper +, binutils +, expectedArch ? stdenv.hostPlatform.parsed.cpu.name +}: + +runCommand "make-binary-wrapper-test-cross" { + nativeBuildInputs = [ + makeBinaryWrapper + binutils + ]; + inherit expectedArch; +} '' + touch prog + chmod +x prog + makeWrapper prog $out + read -r _ arch < <($READELF --file-header $out | grep Machine:) + if [[ ''${arch,,} != *"''${expectedArch,,}"* ]]; then + echo "expected $expectedArch, got $arch" + exit 1 + fi +'' diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/default.nix b/nixpkgs/pkgs/test/make-binary-wrapper/default.nix new file mode 100644 index 000000000000..4c6fffd100a7 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/default.nix @@ -0,0 +1,61 @@ +{ lib +, stdenv +, pkgsCross +, makeBinaryWrapper +, writeText +, runCommand +, runCommandCC +}: + +let + env = { nativeBuildInputs = [ makeBinaryWrapper ]; }; + envCheck = runCommandCC "envcheck" env '' + cc -Wall -Werror -Wpedantic -o $out ${./envcheck.c} + ''; + makeGoldenTest = testname: runCommand "make-binary-wrapper-test-${testname}" env '' + mkdir -p tmp/foo # for the chdir test + + params=$(<"${./.}/${testname}.cmdline") + eval "makeCWrapper /send/me/flags $params" > wrapper.c + + diff wrapper.c "${./.}/${testname}.c" + + if [ -f "${./.}/${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 + if ! diff env.txt golden-env.txt; then + echo "env/argv should be:" + cat golden-env.txt + echo "env/argv output is:" + cat env.txt + exit 1 + fi + else + # without a golden env, we expect the wrapper compilation to fail + ! eval "makeWrapper ${envCheck} wrapped $params" &> error.txt + fi + + cp wrapper.c $out + ''; + tests = lib.genAttrs [ + "add-flags" + "argv0" + "basic" + "chdir" + "combination" + "env" + "inherit-argv0" + "invalid-env" + "overlength-strings" + "prefix" + "suffix" + ] makeGoldenTest // lib.optionalAttrs (! stdenv.isDarwin) { + cross = pkgsCross.${if stdenv.buildPlatform.isAarch64 then "gnu64" else "aarch64-multiplatform"}.callPackage ./cross.nix { }; + }; +in + +writeText "make-binary-wrapper-tests" '' + ${lib.concatStringsSep "\n" (builtins.attrValues tests)} +'' // tests diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/env.c b/nixpkgs/pkgs/test/make-binary-wrapper/env.c new file mode 100644 index 000000000000..7e0422dee3bd --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/env.c @@ -0,0 +1,14 @@ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +int main(int argc, char **argv) { + putenv("PART1=HELLO"); + assert_success(setenv("PART2", "WORLD", 0)); + assert_success(unsetenv("SOME_OTHER_VARIABLE")); + putenv("PART3=\"!!\n\""); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/env.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/env.cmdline new file mode 100644 index 000000000000..3c89f33e2dce --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/env.cmdline @@ -0,0 +1,4 @@ + --set PART1 HELLO \ + --set-default PART2 WORLD \ + --unset SOME_OTHER_VARIABLE \ + --set PART3 $'"!!\n"' diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/env.env b/nixpkgs/pkgs/test/make-binary-wrapper/env.env new file mode 100644 index 000000000000..c7661e165e09 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/env.env @@ -0,0 +1,6 @@ +PART1=HELLO +PART2=WORLD +PART3="!! +" +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/envcheck.c b/nixpkgs/pkgs/test/make-binary-wrapper/envcheck.c new file mode 100644 index 000000000000..848fbdaa80f2 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/envcheck.c @@ -0,0 +1,22 @@ +#include <limits.h> +#include <stdio.h> +#include <unistd.h> + +int main(int argc, char **argv, char **envp) { + for (char **env = envp; *env != 0; ++env) { + puts(*env); + } + + char cwd[PATH_MAX]; + if (getcwd(cwd, sizeof(cwd))) { + printf("CWD=%s\n", cwd); + } else { + perror("getcwd() error"); + return 1; + } + + for (int i=0; i < argc; ++i) { + puts(argv[i]); + } + return 0; +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.c b/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.c new file mode 100644 index 000000000000..e1c2bc926aa7 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.c @@ -0,0 +1,6 @@ +#include <unistd.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.cmdline new file mode 100644 index 000000000000..088076799835 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.cmdline @@ -0,0 +1 @@ + --inherit-argv0 diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.env b/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.env new file mode 100644 index 000000000000..c46ca95eefbc --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/inherit-argv0.env @@ -0,0 +1,2 @@ +CWD=SUBST_CWD +./wrapped diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/invalid-env.c b/nixpkgs/pkgs/test/make-binary-wrapper/invalid-env.c new file mode 100644 index 000000000000..4dfd36fb68a0 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/invalid-env.c @@ -0,0 +1,14 @@ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +int main(int argc, char **argv) { + putenv("==TEST1"); + #error Illegal environment variable name `=` (cannot contain `=`) + assert_success(setenv("", "TEST2", 0)); + #error Environment variable name can't be empty. + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/invalid-env.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/invalid-env.cmdline new file mode 100644 index 000000000000..a03b001e754e --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/invalid-env.cmdline @@ -0,0 +1,2 @@ + --set "=" "TEST1" \ + --set-default "" "TEST2" diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.c b/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.c new file mode 100644 index 000000000000..579705d33e94 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.c @@ -0,0 +1,25 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +void set_env_prefix(char *env, char *sep, char *prefix) { + char *existing = getenv(env); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", prefix, sep, existing)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, prefix, 1)); + } +} + +int main(int argc, char **argv) { + set_env_prefix("PATH", ":", "/nix/store/00000000000000000000000000000000-loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.cmdline new file mode 100644 index 000000000000..686abbb1cdb9 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.cmdline @@ -0,0 +1 @@ + --prefix PATH : /nix/store/00000000000000000000000000000000-loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.env b/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.env new file mode 100644 index 000000000000..83a02f5f8343 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/overlength-strings.env @@ -0,0 +1,3 @@ +PATH=/nix/store/00000000000000000000000000000000-loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/prefix.c b/nixpkgs/pkgs/test/make-binary-wrapper/prefix.c new file mode 100644 index 000000000000..ea8fbdc64a84 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/prefix.c @@ -0,0 +1,26 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +void set_env_prefix(char *env, char *sep, char *prefix) { + char *existing = getenv(env); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", prefix, sep, existing)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, prefix, 1)); + } +} + +int main(int argc, char **argv) { + set_env_prefix("PATH", ":", "/usr/bin/"); + set_env_prefix("PATH", ":", "/usr/local/bin/"); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/prefix.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/prefix.cmdline new file mode 100644 index 000000000000..99cebf9503f4 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/prefix.cmdline @@ -0,0 +1,2 @@ + --prefix PATH : /usr/bin/ \ + --prefix PATH : /usr/local/bin/ diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/prefix.env b/nixpkgs/pkgs/test/make-binary-wrapper/prefix.env new file mode 100644 index 000000000000..033676457c57 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/prefix.env @@ -0,0 +1,3 @@ +PATH=/usr/local/bin/:/usr/bin/ +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/suffix.c b/nixpkgs/pkgs/test/make-binary-wrapper/suffix.c new file mode 100644 index 000000000000..d33f86c070ca --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/suffix.c @@ -0,0 +1,26 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +void set_env_suffix(char *env, char *sep, char *suffix) { + char *existing = getenv(env); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", existing, sep, suffix)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, suffix, 1)); + } +} + +int main(int argc, char **argv) { + set_env_suffix("PATH", ":", "/usr/bin/"); + set_env_suffix("PATH", ":", "/usr/local/bin/"); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/suffix.cmdline b/nixpkgs/pkgs/test/make-binary-wrapper/suffix.cmdline new file mode 100644 index 000000000000..95d291f3c169 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/suffix.cmdline @@ -0,0 +1,2 @@ + --suffix PATH : /usr/bin/ \ + --suffix PATH : /usr/local/bin/ diff --git a/nixpkgs/pkgs/test/make-binary-wrapper/suffix.env b/nixpkgs/pkgs/test/make-binary-wrapper/suffix.env new file mode 100644 index 000000000000..3ce4cc54de41 --- /dev/null +++ b/nixpkgs/pkgs/test/make-binary-wrapper/suffix.env @@ -0,0 +1,3 @@ +PATH=/usr/bin/:/usr/local/bin/ +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/default.nix b/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/default.nix new file mode 100644 index 000000000000..6c5d2318c6d8 --- /dev/null +++ b/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/default.nix @@ -0,0 +1,58 @@ +{ runCommandLocal +, git +, clang-tools +, makeHardcodeGsettingsPatch +}: + +let + mkTest = + { + name, + expected, + src, + schemaIdToVariableMapping, + }: + + let + patch = makeHardcodeGsettingsPatch { + inherit src schemaIdToVariableMapping; + }; + in + runCommandLocal + "makeHardcodeGsettingsPatch-tests-${name}" + + { + nativeBuildInputs = [ + git + clang-tools + ]; + } + + '' + cp -r --no-preserve=all "${src}" src + cp -r --no-preserve=all "${expected}" src-expected + + pushd src + patch < "${patch}" + popd + + find src -name '*.c' -print0 | while read -d $'\0' sourceFile; do + sourceFile=''${sourceFile#src/} + clang-format -style='{BasedOnStyle: InheritParentConfig, ColumnLimit: 240}' -i "src/$sourceFile" "src-expected/$sourceFile" + git diff --no-index "src/$sourceFile" "src-expected/$sourceFile" | cat + done + touch "$out" + ''; +in +{ + basic = mkTest { + name = "basic"; + src = ./fixtures/example-project; + schemaIdToVariableMapping = { + "org.gnome.evolution-data-server.addressbook" = "EDS"; + "org.gnome.evolution.calendar" = "EVO"; + "org.gnome.seahorse.nautilus.window" = "SEANAUT"; + }; + expected = ./fixtures/example-project-patched; + }; +} diff --git a/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/fixtures/example-project-patched/main.c b/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/fixtures/example-project-patched/main.c new file mode 100644 index 000000000000..7822a42b840a --- /dev/null +++ b/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/fixtures/example-project-patched/main.c @@ -0,0 +1,85 @@ +#include <gio/gio.h> +#include <glib-object.h> + +void schema_id_literal() { + GSettings *settings; + { + g_autoptr(GSettingsSchemaSource) schema_source; + g_autoptr(GSettingsSchema) schema; + schema_source = g_settings_schema_source_new_from_directory("@EDS@", g_settings_schema_source_get_default(), TRUE, NULL); + schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution-data-server.addressbook", FALSE); + settings = g_settings_new_full(schema, NULL, NULL); + } + g_object_unref(settings); +} + +#define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook" +int schema_id_from_constant() { + GSettings *settings; + { + g_autoptr(GSettingsSchemaSource) schema_source; + g_autoptr(GSettingsSchema) schema; + schema_source = g_settings_schema_source_new_from_directory("@EDS@", g_settings_schema_source_get_default(), TRUE, NULL); + schema = g_settings_schema_source_lookup(schema_source, SELF_UID_PATH_ID, FALSE); + settings = g_settings_new_full(schema, NULL, NULL); + } + g_object_unref(settings); +} + +void schema_id_autoptr() { + g_autoptr(GSettings) settings = NULL; + { + g_autoptr(GSettingsSchemaSource) schema_source; + g_autoptr(GSettingsSchema) schema; + schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL); + schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE); + settings = g_settings_new_full(schema, NULL, NULL); + } +} + +void schema_id_with_backend() { + GSettings *settings; + { + g_autoptr(GSettingsSchemaSource) schema_source; + g_autoptr(GSettingsSchema) schema; + schema_source = g_settings_schema_source_new_from_directory("@EDS@", g_settings_schema_source_get_default(), TRUE, NULL); + schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution-data-server.addressbook", FALSE); + settings = g_settings_new_full(schema, g_settings_backend_get_default(), NULL); + } + g_object_unref(settings); +} + +void schema_id_with_backend_and_path() { + GSettings *settings; + { + g_autoptr(GSettingsSchemaSource) schema_source; + g_autoptr(GSettingsSchema) schema; + schema_source = g_settings_schema_source_new_from_directory("@SEANAUT@", g_settings_schema_source_get_default(), TRUE, NULL); + schema = g_settings_schema_source_lookup(schema_source, "org.gnome.seahorse.nautilus.window", FALSE); + settings = g_settings_new_full(schema, g_settings_backend_get_default(), "/org/gnome/seahorse/nautilus/windows/123/"); + } + g_object_unref(settings); +} + +void schema_id_with_path() { + GSettings *settings; + { + g_autoptr(GSettingsSchemaSource) schema_source; + g_autoptr(GSettingsSchema) schema; + schema_source = g_settings_schema_source_new_from_directory("@SEANAUT@", g_settings_schema_source_get_default(), TRUE, NULL); + schema = g_settings_schema_source_lookup(schema_source, "org.gnome.seahorse.nautilus.window", FALSE); + settings = g_settings_new_full(schema, NULL, "/org/gnome/seahorse/nautilus/windows/123/"); + } + g_object_unref(settings); +} + +int main() { + schema_id_literal(); + schema_id_from_constant(); + schema_id_autoptr(); + schema_id_with_backend(); + schema_id_with_backend_and_path(); + schema_id_with_path(); + + return 0; +} diff --git a/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/fixtures/example-project/main.c b/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/fixtures/example-project/main.c new file mode 100644 index 000000000000..afcb3686ec84 --- /dev/null +++ b/nixpkgs/pkgs/test/make-hardcode-gsettings-patch/fixtures/example-project/main.c @@ -0,0 +1,49 @@ +#include <gio/gio.h> +#include <glib-object.h> + +void schema_id_literal() { + GSettings *settings; + settings = g_settings_new("org.gnome.evolution-data-server.addressbook"); + g_object_unref(settings); +} + +#define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook" +int schema_id_from_constant() { + GSettings *settings; + settings = g_settings_new(SELF_UID_PATH_ID); + g_object_unref(settings); +} + +void schema_id_autoptr() { + g_autoptr(GSettings) settings = NULL; + settings = g_settings_new("org.gnome.evolution.calendar"); +} + +void schema_id_with_backend() { + GSettings *settings; + settings = g_settings_new_with_backend("org.gnome.evolution-data-server.addressbook", g_settings_backend_get_default()); + g_object_unref(settings); +} + +void schema_id_with_backend_and_path() { + GSettings *settings; + settings = g_settings_new_with_backend_and_path("org.gnome.seahorse.nautilus.window", g_settings_backend_get_default(), "/org/gnome/seahorse/nautilus/windows/123/"); + g_object_unref(settings); +} + +void schema_id_with_path() { + GSettings *settings; + settings = g_settings_new_with_path("org.gnome.seahorse.nautilus.window", "/org/gnome/seahorse/nautilus/windows/123/"); + g_object_unref(settings); +} + +int main() { + schema_id_literal(); + schema_id_from_constant(); + schema_id_autoptr(); + schema_id_with_backend(); + schema_id_with_backend_and_path(); + schema_id_with_path(); + + return 0; +} diff --git a/nixpkgs/pkgs/test/make-wrapper/default.nix b/nixpkgs/pkgs/test/make-wrapper/default.nix new file mode 100644 index 000000000000..5cc7cee5a864 --- /dev/null +++ b/nixpkgs/pkgs/test/make-wrapper/default.nix @@ -0,0 +1,139 @@ +{ lib +, writeText +, writeCBin +, writeShellScript +, makeWrapper +, runCommand +, which +, ... +}: + +let + # Testfiles + foofile = writeText "foofile" "foo"; + barfile = writeText "barfile" "bar"; + + # Wrapped binaries + wrappedArgv0 = writeCBin "wrapped-argv0" '' + #include <stdio.h> + #include <stdlib.h> + + void main(int argc, char** argv) { + printf("argv0=%s", argv[0]); + exit(0); + } + ''; + wrappedBinaryVar = writeShellScript "wrapped-var" '' + echo "VAR=$VAR" + ''; + wrappedBinaryArgs = writeShellScript "wrapped-args" '' + echo "$@" + ''; + + mkWrapperBinary = { name, args, wrapped ? wrappedBinaryVar }: runCommand name + { + nativeBuildInputs = [ makeWrapper ]; + } '' + mkdir -p $out/bin + makeWrapper "${wrapped}" "$out/bin/${name}" ${lib.escapeShellArgs args} + ''; + + mkTest = cmd: toExpect: '' + output="$(${cmd})" + if [[ "$output" != '${toExpect}' ]]; then + echo "test failed: the output of ${cmd} was '$output', expected '${toExpect}'" + echo "the wrapper contents:" + for i in ${cmd}; do + if [[ $i =~ ^test- ]]; then + cat $(which $i) + fi + done + exit 1 + fi + ''; +in +runCommand "make-wrapper-test" +{ + nativeBuildInputs = [ + which + (mkWrapperBinary { name = "test-argv0"; args = [ "--argv0" "foo" ]; wrapped = "${wrappedArgv0}/bin/wrapped-argv0"; }) + (mkWrapperBinary { name = "test-set"; args = [ "--set" "VAR" "abc" ]; }) + (mkWrapperBinary { name = "test-set-default"; args = [ "--set-default" "VAR" "abc" ]; }) + (mkWrapperBinary { name = "test-unset"; args = [ "--unset" "VAR" ]; }) + (mkWrapperBinary { name = "test-run"; args = [ "--run" "echo bar" ]; }) + (mkWrapperBinary { name = "test-run-and-set"; args = [ "--run" "export VAR=foo" "--set" "VAR" "bar" ]; }) + (mkWrapperBinary { name = "test-args"; args = [ "--add-flags" "abc" "--append-flags" "xyz" ]; wrapped = wrappedBinaryArgs; }) + (mkWrapperBinary { name = "test-prefix"; args = [ "--prefix" "VAR" ":" "abc" ]; }) + (mkWrapperBinary { name = "test-prefix-noglob"; args = [ "--prefix" "VAR" ":" "./*" ]; }) + (mkWrapperBinary { name = "test-suffix"; args = [ "--suffix" "VAR" ":" "abc" ]; }) + (mkWrapperBinary { name = "test-prefix-and-suffix"; args = [ "--prefix" "VAR" ":" "foo" "--suffix" "VAR" ":" "bar" ]; }) + (mkWrapperBinary { name = "test-prefix-multi"; args = [ "--prefix" "VAR" ":" "abc:foo:foo" ]; }) + (mkWrapperBinary { name = "test-suffix-each"; args = [ "--suffix-each" "VAR" ":" "foo bar:def" ]; }) + (mkWrapperBinary { name = "test-prefix-each"; args = [ "--prefix-each" "VAR" ":" "foo bar:def" ]; }) + (mkWrapperBinary { name = "test-suffix-contents"; args = [ "--suffix-contents" "VAR" ":" "${foofile} ${barfile}" ]; }) + (mkWrapperBinary { name = "test-prefix-contents"; args = [ "--prefix-contents" "VAR" ":" "${foofile} ${barfile}" ]; }) + ]; +} + ( + # --argv0 works + mkTest "test-argv0" "argv0=foo" + + # --set works + + mkTest "test-set" "VAR=abc" + # --set overwrites the variable + + mkTest "VAR=foo test-set" "VAR=abc" + # --set-default works + + mkTest "test-set-default" "VAR=abc" + # --set-default doesn"t overwrite the variable + + mkTest "VAR=foo test-set-default" "VAR=foo" + # --unset works + + mkTest "VAR=foo test-unset" "VAR=" + + # --add-flags and --append-flags work + + mkTest "test-args" "abc xyz" + # given flags are kept + + mkTest "test-args foo" "abc foo xyz" + + # --run works + + mkTest "test-run" "bar\nVAR=" + # --run & --set works + + mkTest "test-run-and-set" "VAR=bar" + + # --prefix works + + mkTest "VAR=foo test-prefix" "VAR=abc:foo" + # sets variable if not set yet + + mkTest "test-prefix" "VAR=abc" + # prepends value only once + + mkTest "VAR=abc test-prefix" "VAR=abc" + # Moves value to the front if it already existed + + mkTest "VAR=foo:abc test-prefix" "VAR=abc:foo" + + mkTest "VAR=abc:foo:bar test-prefix-multi" "VAR=abc:foo:bar" + # Doesn't overwrite parts of the string + + mkTest "VAR=test:abcde:test test-prefix" "VAR=abc:test:abcde:test" + # Only append the value once when given multiple times in a parameter + # to makeWrapper + + mkTest "test-prefix" "VAR=abc" + # --prefix doesn't expand globs + + mkTest "VAR=f?oo test-prefix-noglob" "VAR=./*:f?oo" + + + # --suffix works + + mkTest "VAR=foo test-suffix" "VAR=foo:abc" + # sets variable if not set yet + + mkTest "test-suffix" "VAR=abc" + # adds the same value only once + + mkTest "VAR=abc test-suffix" "VAR=abc" + + mkTest "VAR=abc:foo test-suffix" "VAR=abc:foo" + # --prefix in combination with --suffix + + mkTest "VAR=abc test-prefix-and-suffix" "VAR=foo:abc:bar" + + # --suffix-each works + + mkTest "VAR=abc test-suffix-each" "VAR=abc:foo:bar:def" + # --prefix-each works + + mkTest "VAR=abc test-prefix-each" "VAR=bar:def:foo:abc" + # --suffix-contents works + + mkTest "VAR=abc test-suffix-contents" "VAR=abc:foo:bar" + # --prefix-contents works + + mkTest "VAR=abc test-prefix-contents" "VAR=bar:foo:abc" + + "touch $out" + ) diff --git a/nixpkgs/pkgs/test/nixos-functions/default.nix b/nixpkgs/pkgs/test/nixos-functions/default.nix new file mode 100644 index 000000000000..bdd5e3c6d8b4 --- /dev/null +++ b/nixpkgs/pkgs/test/nixos-functions/default.nix @@ -0,0 +1,31 @@ +/* + +This file is a test that makes sure that the `pkgs.nixos` and +`pkgs.testers.nixosTest` functions work. It's far from a perfect test suite, +but better than not checking them at all on hydra. + +To run this test: + + nixpkgs$ nix-build -A tests.nixos-functions + + */ +{ pkgs, lib, stdenv, ... }: + +let + dummyVersioning = { + revision = "test"; + versionSuffix = "test"; + label = "test"; + }; +in lib.optionalAttrs stdenv.hostPlatform.isLinux ( + pkgs.recurseIntoAttrs { + + nixos-test = (pkgs.nixos { + system.nixos = dummyVersioning; + boot.loader.grub.enable = false; + fileSystems."/".device = "/dev/null"; + system.stateVersion = lib.trivial.release; + }).toplevel; + + } +) diff --git a/nixpkgs/pkgs/test/overriding.nix b/nixpkgs/pkgs/test/overriding.nix new file mode 100644 index 000000000000..f2519088f138 --- /dev/null +++ b/nixpkgs/pkgs/test/overriding.nix @@ -0,0 +1,66 @@ +{ lib, pkgs, stdenvNoCC }: + +let + tests = + let + p = pkgs.python3Packages.xpybutil.overridePythonAttrs (_: { dontWrapPythonPrograms = true; }); + in + [ + ({ + name = "overridePythonAttrs"; + expr = !lib.hasInfix "wrapPythonPrograms" p.postFixup; + expected = true; + }) + ({ + name = "repeatedOverrides-pname"; + expr = repeatedOverrides.pname == "a-better-hello-with-blackjack"; + expected = true; + }) + ({ + name = "repeatedOverrides-entangled-pname"; + expr = repeatedOverrides.entangled.pname == "a-better-figlet-with-blackjack"; + expected = true; + }) + ({ + name = "overriding-using-only-attrset"; + expr = (pkgs.hello.overrideAttrs { pname = "hello-overriden"; }).pname == "hello-overriden"; + expected = true; + }) + ({ + 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; + }) + ]; + + addEntangled = origOverrideAttrs: f: + origOverrideAttrs ( + lib.composeExtensions f (self: super: { + passthru = super.passthru // { + entangled = super.passthru.entangled.overrideAttrs f; + overrideAttrs = addEntangled self.overrideAttrs; + }; + }) + ); + + entangle = pkg1: pkg2: pkg1.overrideAttrs (self: super: { + passthru = super.passthru // { + entangled = pkg2; + overrideAttrs = addEntangled self.overrideAttrs; + }; + }); + + example = entangle pkgs.hello pkgs.figlet; + + overrides1 = example.overrideAttrs (_: super: { pname = "a-better-${super.pname}"; }); + + repeatedOverrides = overrides1.overrideAttrs (_: super: { pname = "${super.pname}-with-blackjack"; }); +in + +stdenvNoCC.mkDerivation { + name = "test-overriding"; + 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; +} diff --git a/nixpkgs/pkgs/test/php/default.nix b/nixpkgs/pkgs/test/php/default.nix new file mode 100644 index 000000000000..3c6c8f61b6db --- /dev/null +++ b/nixpkgs/pkgs/test/php/default.nix @@ -0,0 +1,116 @@ +{ lib +, php +, runCommand +}: + +let + runTest = name: body: runCommand name { } '' + testFailed= + checking() { + echo -n "Checking $1... " > /dev/stderr + } + ok() { + echo ok > /dev/stderr + } + nok() { + echo fail > /dev/stderr + testFailed=1 + } + + ${body} + + if test -n "$testFailed"; then + exit 1 + fi + + touch $out + ''; + + check = cond: if cond then "ok" else "nok"; +in +{ + withExtensions-enables-previously-disabled-extensions = runTest "php-test-withExtensions-enables-previously-disabled-extensions" '' + php="${php}" + + checking "that imagick is not present by default" + $php/bin/php -r 'exit(extension_loaded("imagick") ? 1 : 0);' && ok || nok + + phpWithImagick="${php.withExtensions ({ all, ... }: [ all.imagick ])}" + checking "that imagick extension is present when enabled" + $phpWithImagick/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok + ''; + + overrideAttrs-preserves-enabled-extensions = + let + customPhp = + (php.withExtensions ({ all, ... }: [ all.imagick ])).overrideAttrs (attrs: { + postInstall = attrs.postInstall or "" + '' + touch "$out/oApee-was-here" + ''; + }); + in + runTest "php-test-overrideAttrs-preserves-enabled-extensions" '' + php="${customPhp}" + phpUnwrapped="${customPhp.unwrapped}" + + checking "if overrides took hold" + test -f "$phpUnwrapped/oApee-was-here" && ok || nok + + checking "if imagick extension is still present" + $php/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok + + checking "if imagick extension is linked against the overridden PHP" + echo $php + $php/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok + ''; + + unwrapped-overrideAttrs-stacks = + let + customPhp = + lib.pipe php.unwrapped [ + (pkg: pkg.overrideAttrs (attrs: { + postInstall = attrs.postInstall or "" + '' + touch "$out/oAs-first" + ''; + })) + + (pkg: pkg.overrideAttrs (attrs: { + postInstall = attrs.postInstall or "" + '' + touch "$out/oAs-second" + ''; + })) + ]; + in + runTest "php-test-unwrapped-overrideAttrs-stacks" '' + checking "if first override remained" + ${check (builtins.match ".*oAs-first.*" customPhp.postInstall != null)} + + checking "if second override is there" + ${check (builtins.match ".*oAs-second.*" customPhp.postInstall != null)} + ''; + + wrapped-overrideAttrs-stacks = + let + customPhp = + lib.pipe php [ + (pkg: pkg.overrideAttrs (attrs: { + postInstall = attrs.postInstall or "" + '' + touch "$out/oAs-first" + ''; + })) + + (pkg: pkg.overrideAttrs (attrs: { + postInstall = attrs.postInstall or "" + '' + touch "$out/oAs-second" + ''; + })) + ]; + in + runTest "php-test-wrapped-overrideAttrs-stacks" '' + checking "if first override remained" + ${check (builtins.match ".*oAs-first.*" customPhp.unwrapped.postInstall != null)} + + checking "if second override is there" + ${check (builtins.match ".*oAs-second.*" customPhp.unwrapped.postInstall != null)} + ''; +} diff --git a/nixpkgs/pkgs/test/simple/builder.sh b/nixpkgs/pkgs/test/simple/builder.sh new file mode 100644 index 000000000000..908faec3c388 --- /dev/null +++ b/nixpkgs/pkgs/test/simple/builder.sh @@ -0,0 +1,43 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi +set -x + +export NIX_DEBUG=1 + +source $stdenv/setup + +export NIX_ENFORCE_PURITY=1 + +mkdir $out +mkdir $out/bin + +cat > hello.c <<EOF +#include <stdio.h> + +int main(int argc, char * * argv) +{ + printf("Hello World!\n"); + return 0; +} +EOF + +#gcc -I/nix/store/foo -I /nix/store/foo -I/usr/lib -I /usr/lib hello.c -o $out/bin/hello +gcc -I`pwd` -L /nix/store/abcd/lib -isystem /usr/lib hello.c -o $out/bin/hello + +$out/bin/hello + +cat > hello2.cc <<EOF +#include <iostream> + +int main(int argc, char * * argv) +{ + std::cout << "Hello World!\n"; + std::cout << VALUE << std::endl; + return 0; +} +EOF + +g++ hello2.cc -o $out/bin/hello2 -DVALUE="1 + 2 * 3" + +$out/bin/hello2 + +ld -v diff --git a/nixpkgs/pkgs/test/stdenv-inputs/bar.c b/nixpkgs/pkgs/test/stdenv-inputs/bar.c new file mode 100644 index 000000000000..2d7299c2d462 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv-inputs/bar.c @@ -0,0 +1,3 @@ +unsigned int bar(void) { + return 42; +} diff --git a/nixpkgs/pkgs/test/stdenv-inputs/cc-main.c b/nixpkgs/pkgs/test/stdenv-inputs/cc-main.c new file mode 100644 index 000000000000..06f28bc33c69 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv-inputs/cc-main.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/nixpkgs/pkgs/test/stdenv-inputs/default.nix b/nixpkgs/pkgs/test/stdenv-inputs/default.nix new file mode 100644 index 000000000000..6a2e441d0191 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv-inputs/default.nix @@ -0,0 +1,68 @@ +{ lib, stdenv }: + +let + foo = stdenv.mkDerivation { + name = "foo-test"; + + dontUnpack = true; + + installPhase = '' + mkdir -p $out/bin $out/include $out/lib + $CC -o $out/bin/foo ${./cc-main.c} + 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"} \ + -o $out/lib/libfoo${stdenv.hostPlatform.extensions.sharedLibrary} \ + ${./foo.c} + ''; + }; + + bar = stdenv.mkDerivation { + name = "bar-test"; + outputs = [ "out" "dev" ]; + + dontUnpack = true; + + installPhase = '' + mkdir -p $out/bin $dev/include $dev/lib + $CC -o $out/bin/bar ${./cc-main.c} + 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"} \ + -o $dev/lib/libbar${stdenv.hostPlatform.extensions.sharedLibrary} \ + ${./bar.c} + ''; + }; +in + +stdenv.mkDerivation { + name = "stdenv-inputs-test"; + phases = [ "buildPhase" ]; + + buildInputs = [ foo bar ]; + + buildPhase = '' + env + + printf "checking whether binaries are available... " >&2 + foo && bar + + printf "checking whether compiler can find headers... " >&2 + $CC -o include-check ${./include-main.c} + ./include-check + + printf "checking whether compiler can find headers... " >&2 + $CC -o include-check ${./include-main.c} + ./include-check + + printf "checking whether compiler can find libraries... " >&2 + $CC -lfoo -lbar -o lib-check ${./lib-main.c} + ./lib-check + + touch $out + ''; + + meta.platforms = lib.platforms.all; +} diff --git a/nixpkgs/pkgs/test/stdenv-inputs/foo.c b/nixpkgs/pkgs/test/stdenv-inputs/foo.c new file mode 100644 index 000000000000..0253a26d5d2c --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv-inputs/foo.c @@ -0,0 +1,3 @@ +unsigned int foo(void) { + return 42; +} diff --git a/nixpkgs/pkgs/test/stdenv-inputs/include-main.c b/nixpkgs/pkgs/test/stdenv-inputs/include-main.c new file mode 100644 index 000000000000..35e5ee0d90f7 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv-inputs/include-main.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <foo.h> +#include <bar.h> + +int main(int argc, char **argv) +{ + if (foo() != 42) + return 1; + if (bar() != 42) + return 1; + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/nixpkgs/pkgs/test/stdenv-inputs/lib-main.c b/nixpkgs/pkgs/test/stdenv-inputs/lib-main.c new file mode 100644 index 000000000000..c9488fe43e55 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv-inputs/lib-main.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +extern unsigned int foo(void); +extern unsigned int bar(void); + +int main(int argc, char **argv) +{ + if (foo() != 42) + return 1; + if (bar() != 42) + return 1; + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/nixpkgs/pkgs/test/stdenv/default.nix b/nixpkgs/pkgs/test/stdenv/default.nix new file mode 100644 index 000000000000..0fa87cccc219 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv/default.nix @@ -0,0 +1,293 @@ +# To run these tests: +# nix-build -A tests.stdenv + +{ stdenv +, pkgs +, lib +, testers +}: + +let + # early enough not to rebuild gcc but late enough to have patchelf + earlyPkgs = stdenv.__bootPackages.stdenv.__bootPackages; + earlierPkgs = stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages; + # use a early stdenv so when hacking on stdenv this test can be run quickly + bootStdenv = stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv; + pkgsStructured = import pkgs.path { config = { structuredAttrsByDefault = true; }; inherit (stdenv.hostPlatform) system; }; + bootStdenvStructuredAttrsByDefault = pkgsStructured.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv; + + runCommand = earlierPkgs.runCommand; + + + ccWrapperSubstitutionsTest = { name, stdenv', extraAttrs ? { } }: + + stdenv'.cc.overrideAttrs (previousAttrs: ({ + inherit name; + + postFixup = previousAttrs.postFixup + '' + declare -p wrapperName + echo "env.wrapperName = $wrapperName" + [[ $wrapperName == "CC_WRAPPER" ]] || (echo "'\$wrapperName' was not 'CC_WRAPPER'" && false) + declare -p suffixSalt + echo "env.suffixSalt = $suffixSalt" + [[ $suffixSalt == "${stdenv'.cc.suffixSalt}" ]] || (echo "'\$suffxSalt' was not '${stdenv'.cc.suffixSalt}'" && false) + + grep -q "@out@" $out/bin/cc || echo "@out@ in $out/bin/cc was substituted" + grep -q "@suffixSalt@" $out/bin/cc && (echo "$out/bin/cc contains unsubstituted variables" && false) + + touch $out + ''; + } // extraAttrs)); + + testEnvAttrset = { name, stdenv', extraAttrs ? { } }: + stdenv'.mkDerivation + ({ + inherit name; + env = { + string = "testing-string"; + }; + + passAsFile = [ "buildCommand" ]; + buildCommand = '' + declare -p string + echo "env.string = $string" + [[ $string == "testing-string" ]] || (echo "'\$string' was not 'testing-string'" && false) + [[ "$(declare -p string)" == 'declare -x string="testing-string"' ]] || (echo "'\$string' was not exported" && false) + touch $out + ''; + } // extraAttrs); + + testPrependAndAppendToVar = { name, stdenv', extraAttrs ? { } }: + stdenv'.mkDerivation + ({ + inherit name; + env = { + string = "testing-string"; + }; + + passAsFile = [ "buildCommand" ] ++ lib.optionals (extraAttrs ? extraTest) [ "extraTest" ]; + buildCommand = '' + declare -p string + appendToVar string hello + # test that quoted strings work + prependToVar string "world" + 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) + + [[ $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 + 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 + [[ "$nonExistant" == " created hello" ]] + fi + + eval "$extraTest" + + touch $out + ''; + } // extraAttrs); + +in + +{ + # tests for hooks in `stdenv.defaultNativeBuildInputs` + hooks = lib.recurseIntoAttrs (import ./hooks.nix { stdenv = bootStdenv; pkgs = earlyPkgs; inherit lib; }); + + outputs-no-out = runCommand "outputs-no-out-assert" { + result = earlierPkgs.testers.testBuildFailure (bootStdenv.mkDerivation { + NIX_DEBUG = 1; + name = "outputs-no-out"; + outputs = ["foo"]; + buildPhase = ":"; + installPhase = '' + touch $foo + ''; + }); + + # Assumption: the first output* variable to be configured is + # _overrideFirst outputDev "dev" "out" + expectedMsg = "error: _assignFirst: could not find a non-empty variable whose name to assign to outputDev.\n The following variables were all unset or empty:\n dev out"; + } '' + grep -F "$expectedMsg" $result/testBuildFailure.log >/dev/null + touch $out + ''; + + test-env-attrset = testEnvAttrset { name = "test-env-attrset"; stdenv' = bootStdenv; }; + + # Test compatibility with derivations using `env` as a regular variable. + test-env-derivation = bootStdenv.mkDerivation rec { + name = "test-env-derivation"; + env = bootStdenv.mkDerivation { + name = "foo"; + buildCommand = '' + mkdir "$out" + touch "$out/bar" + ''; + }; + + passAsFile = [ "buildCommand" ]; + buildCommand = '' + declare -p env + [[ $env == "${env}" ]] + touch "$out" + ''; + }; + + test-inputDerivation = let + inherit (stdenv.mkDerivation { + dep1 = derivation { name = "dep1"; builder = "/bin/sh"; args = [ "-c" ": > $out" ]; system = builtins.currentSystem; }; + dep2 = derivation { name = "dep2"; builder = "/bin/sh"; args = [ "-c" ": > $out" ]; system = builtins.currentSystem; }; + passAsFile = [ "dep2" ]; + }) inputDerivation; + in + runCommand "test-inputDerivation" { + exportReferencesGraph = [ "graph" inputDerivation ]; + } '' + grep ${inputDerivation.dep1} graph + grep ${inputDerivation.dep2} graph + touch $out + ''; + + test-prepend-append-to-var = testPrependAndAppendToVar { + name = "test-prepend-append-to-var"; + stdenv' = bootStdenv; + }; + + test-structured-env-attrset = testEnvAttrset { + name = "test-structured-env-attrset"; + stdenv' = bootStdenv; + extraAttrs = { __structuredAttrs = true; }; + }; + + test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { + name = "test-cc-wrapper-substitutions"; + stdenv' = bootStdenv; + }; + + structuredAttrsByDefault = lib.recurseIntoAttrs { + + hooks = lib.recurseIntoAttrs (import ./hooks.nix { stdenv = bootStdenvStructuredAttrsByDefault; pkgs = earlyPkgs; inherit lib; }); + + test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { + name = "test-cc-wrapper-substitutions-structuredAttrsByDefault"; + stdenv' = bootStdenvStructuredAttrsByDefault; + }; + + test-structured-env-attrset = testEnvAttrset { + name = "test-structured-env-attrset-structuredAttrsByDefault"; + stdenv' = bootStdenvStructuredAttrsByDefault; + }; + + test-prepend-append-to-var = testPrependAndAppendToVar { + name = "test-prepend-append-to-var-structuredAttrsByDefault"; + stdenv' = bootStdenvStructuredAttrsByDefault; + extraAttrs = { + # will be a bash indexed array in attrs.sh + # declare -a list=('a' 'b' ) + # and a json array in attrs.json + # "list":["a","b"] + list = [ "a" "b" ]; + # will be a bash associative array(dictionary) in attrs.sh + # declare -A array=(['a']='1' ['b']='2' ) + # and a json object in attrs.json + # {"array":{"a":"1","b":"2"} + array = { a = "1"; b = "2"; }; + extraTest = '' + declare -p array + array+=(["c"]="3") + declare -p array + + [[ "''${array[c]}" == "3" ]] || (echo "c element of '\$array' was not '3'" && false) + + declare -p list + prependToVar list hello + # test that quoted strings work + appendToVar list "world" + declare -p list + + [[ "''${list[0]}" == "hello" ]] || (echo "first element of '\$list' was not 'hello'" && false) + [[ "''${list[1]}" == "a" ]] || (echo "first element of '\$list' was not 'a'" && false) + [[ "''${list[-1]}" == "world" ]] || (echo "last element of '\$list' was not 'world'" && false) + ''; + }; + }; + + test-golden-example-structuredAttrs = + let + goldenSh = earlyPkgs.writeText "goldenSh" '' + declare -A EXAMPLE_ATTRS=(['foo']='bar' ) + declare EXAMPLE_BOOL_FALSE= + declare EXAMPLE_BOOL_TRUE=1 + declare EXAMPLE_INT=123 + declare EXAMPLE_INT_NEG=-123 + declare -a EXAMPLE_LIST=('foo' 'bar' ) + declare EXAMPLE_STR='foo bar' + ''; + goldenJson = earlyPkgs.writeText "goldenSh" '' + { + "EXAMPLE_ATTRS": { + "foo": "bar" + }, + "EXAMPLE_BOOL_FALSE": false, + "EXAMPLE_BOOL_TRUE": true, + "EXAMPLE_INT": 123, + "EXAMPLE_INT_NEG": -123, + "EXAMPLE_LIST": [ + "foo", + "bar" + ], + "EXAMPLE_NESTED_ATTRS": { + "foo": { + "bar": "baz" + } + }, + "EXAMPLE_NESTED_LIST": [ + [ + "foo", + "bar" + ], + [ + "baz" + ] + ], + "EXAMPLE_STR": "foo bar" + } + ''; + in + bootStdenvStructuredAttrsByDefault.mkDerivation { + name = "test-golden-example-structuredAttrsByDefault"; + nativeBuildInputs = [ earlyPkgs.jq ]; + + EXAMPLE_BOOL_TRUE = true; + EXAMPLE_BOOL_FALSE = false; + EXAMPLE_INT = 123; + EXAMPLE_INT_NEG = -123; + EXAMPLE_STR = "foo bar"; + EXAMPLE_LIST = [ "foo" "bar" ]; + EXAMPLE_NESTED_LIST = [ [ "foo" "bar" ] [ "baz" ] ]; + EXAMPLE_ATTRS = { foo = "bar"; }; + EXAMPLE_NESTED_ATTRS = { foo.bar = "baz"; }; + + inherit goldenSh; + inherit goldenJson; + + buildCommand = '' + mkdir -p $out + cat $NIX_ATTRS_SH_FILE | grep "EXAMPLE" | grep -v -E 'installPhase|jq' > $out/sh + jq 'with_entries(select(.key|match("EXAMPLE")))' $NIX_ATTRS_JSON_FILE > $out/json + diff $out/sh $goldenSh + diff $out/json $goldenJson + ''; + }; + + }; +} diff --git a/nixpkgs/pkgs/test/stdenv/gcc-stageCompare.nix b/nixpkgs/pkgs/test/stdenv/gcc-stageCompare.nix new file mode 100644 index 000000000000..e5c2ed5921b3 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv/gcc-stageCompare.nix @@ -0,0 +1,32 @@ +# This test *must* be run prior to releasing any build of either stdenv or the +# gcc that it exports! This check should also be part of CI for any PR that +# causes a rebuild of `stdenv.cc`. +# +# When we used gcc's internal bootstrap it did this check as part of (and +# serially with) the gcc derivation. Now that we bootstrap externally this +# check can be done in parallel with any/all of stdenv's referrers. But we +# must remember to do the check. +# + +{ stdenv +, pkgs +, lib +}: + +assert stdenv.cc.isGNU; +with pkgs; +# rebuild gcc using the "final" stdenv +let gcc-stageCompare = (gcc-unwrapped.override { + reproducibleBuild = true; + profiledCompiler = false; + stdenv = overrideCC stdenv (wrapCCWith { + cc = stdenv.cc; + }); + }).overrideAttrs(_: { + NIX_OUTPATH_USED_AS_RANDOM_SEED = stdenv.cc.cc.out; + }); +in (runCommand "gcc-stageCompare" {} '' + diff -sr ${pkgs.gcc-unwrapped.checksum}/checksums ${gcc-stageCompare.checksum}/checksums && touch $out +'').overrideAttrs (a: { + meta = (a.meta or { }) // { platforms = lib.platforms.linux; }; +}) diff --git a/nixpkgs/pkgs/test/stdenv/hooks.nix b/nixpkgs/pkgs/test/stdenv/hooks.nix new file mode 100644 index 000000000000..eb1b3f61bda6 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv/hooks.nix @@ -0,0 +1,136 @@ +{ stdenv, pkgs, lib }: + +# ordering should match defaultNativeBuildInputs + +{ + # TODO: add audit-tmpdir + compress-man-pages = + let + manFile = pkgs.writeText "small-man" '' + .TH HELLO "1" "May 2022" "hello 2.12.1" "User Commands" + .SH NAME + hello - friendly greeting program + ''; + in + stdenv.mkDerivation { + name = "test-compress-man-pages"; + buildCommand = '' + mkdir -p $out/share/man + cp ${manFile} $out/share/man/small-man.1 + compressManPages $out + [[ -e $out/share/man/small-man.1.gz ]] + ''; + }; + make-symlinks-relative = stdenv.mkDerivation { + name = "test-make-symlinks-relative"; + outputs = [ "out" "man" ]; + buildCommand = '' + mkdir -p $out/{bar,baz} + mkdir -p $man/share/{x,y} + source1="$out/bar/foo" + destination1="$out/baz/foo" + source2="$man/share/x/file1" + destination2="$man/share/y/file2" + echo foo > $source1 + echo foo > $source2 + ln -s $source1 $destination1 + ln -s $source2 $destination2 + echo "symlink before patching: $(readlink $destination1)" + echo "symlink before patching: $(readlink $destination2)" + + _makeSymlinksRelativeInAllOutputs + + echo "symlink after patching: $(readlink $destination1)" + ([[ -e $destination1 ]] && echo "symlink isn't broken") || (echo "symlink is broken" && exit 1) + ([[ $(readlink $destination1) == "../bar/foo" ]] && echo "absolute symlink was made relative") || (echo "symlink was not made relative" && exit 1) + echo "symlink after patching: $(readlink $destination2)" + ([[ -e $destination2 ]] && echo "symlink isn't broken") || (echo "symlink is broken" && exit 1) + ([[ $(readlink $destination2) == "../x/file1" ]] && echo "absolute symlink was made relative") || (echo "symlink was not made relative" && exit 1) + ''; + }; + move-docs = stdenv.mkDerivation { + name = "test-move-docs"; + buildCommand = '' + mkdir -p $out/{man,doc,info} + touch $out/{man,doc,info}/foo + cat $out/{man,doc,info}/foo + + _moveToShare + + (cat $out/share/{man,doc,info}/foo 2>/dev/null && echo "man,doc,info were moved") || (echo "man,doc,info were not moved" && exit 1) + ''; + }; + move-lib64 = stdenv.mkDerivation { + name = "test-move-lib64"; + buildCommand = '' + mkdir -p $out/lib64 + touch $out/lib64/foo + cat $out/lib64/foo + + _moveLib64 + + # check symlink + [[ -h $out/lib64 ]] + ([[ -e $out/lib64 ]] && echo "symlink isn't broken") || (echo "symlink is broken" && exit 1) + [[ -e $out/lib/foo ]] + ''; + }; + move-sbin = stdenv.mkDerivation { + name = "test-move-sbin"; + buildCommand = '' + mkdir -p $out/sbin + touch $out/sbin/foo + cat $out/sbin/foo + + _moveSbin + + # check symlink + [[ -h $out/sbin ]] + ([[ -e $out/sbin ]] && echo "symlink isn't broken") || (echo "symlink is broken" && exit 1) + [[ -e $out/bin/foo ]] + ''; + }; + # TODO: add multiple-outputs + patch-shebangs = import ./patch-shebangs.nix { inherit stdenv lib pkgs; }; + prune-libtool-files = + let + libFoo = pkgs.writeText "libFoo" '' + # Generated by libtool (GNU libtool) 2.4.6 + old_library=''' + dependency_libs=' -Lbar.la -Lbaz.la' + ''; + in + stdenv.mkDerivation { + name = "test-prune-libtool-files"; + buildCommand = '' + mkdir -p $out/lib + cp ${libFoo} $out/lib/libFoo.la + _pruneLibtoolFiles + grep "^dependency_libs=''' #pruned" $out/lib/libFoo.la + # confirm file doesn't only contain the above + grep "^old_library='''" $out/lib/libFoo.la + ''; + }; + reproducible-builds = stdenv.mkDerivation { + name = "test-reproducible-builds"; + buildCommand = '' + # can't be tested more precisely because the value of random-seed changes depending on the output + [[ $NIX_CFLAGS_COMPILE =~ "-frandom-seed=" ]] + touch $out + ''; + }; + set-source-date-epoch-to-latest = stdenv.mkDerivation { + name = "test-set-source-date-epoch-to-latest"; + buildCommand = '' + sourceRoot=$NIX_BUILD_TOP/source + mkdir -p $sourceRoot + touch --date=1/1/2015 $sourceRoot/foo + + _updateSourceDateEpochFromSourceRoot + + [[ $SOURCE_DATE_EPOCH == "1420070400" ]] + touch $out + ''; + }; + # TODO: add strip +} diff --git a/nixpkgs/pkgs/test/stdenv/patch-shebangs.nix b/nixpkgs/pkgs/test/stdenv/patch-shebangs.nix new file mode 100644 index 000000000000..888d4a53a273 --- /dev/null +++ b/nixpkgs/pkgs/test/stdenv/patch-shebangs.nix @@ -0,0 +1,115 @@ +{ lib, stdenv, pkgs }: + +# since the tests are using a early stdenv, the stdenv will have dontPatchShebangs=1, so it has to be unset +# https://github.com/NixOS/nixpkgs/blob/768a982bfc9d29a6bd3beb963ed4b054451ce3d0/pkgs/stdenv/linux/default.nix#L148-L153 + +# strictDeps has to be disabled because the shell isn't in buildInputs + +let + tests = { + bad-shebang = stdenv.mkDerivation { + name = "bad-shebang"; + strictDeps = false; + dontUnpack = true; + installPhase = '' + mkdir -p $out/bin + echo "#!/bin/bash" > $out/bin/test + echo "echo -n hello" >> $out/bin/test + chmod +x $out/bin/test + dontPatchShebangs= + ''; + passthru = { + assertion = "grep '^#!${stdenv.shell}' $out/bin/test > /dev/null"; + }; + }; + + ignores-nix-store = stdenv.mkDerivation { + name = "ignores-nix-store"; + strictDeps = false; + dontUnpack = true; + installPhase = '' + mkdir -p $out/bin + echo "#!$NIX_STORE/path/to/bash" > $out/bin/test + echo "echo -n hello" >> $out/bin/test + chmod +x $out/bin/test + dontPatchShebangs= + ''; + passthru = { + assertion = "grep \"^#!$NIX_STORE/path/to/bash\" $out/bin/test > /dev/null"; + }; + }; + + updates-nix-store = stdenv.mkDerivation { + name = "updates-nix-store"; + strictDeps = false; + dontUnpack = true; + installPhase = '' + mkdir -p $out/bin + echo "#!$NIX_STORE/path/to/bash" > $out/bin/test + echo "echo -n hello" >> $out/bin/test + chmod +x $out/bin/test + patchShebangs --update $out/bin/test + dontPatchShebangs=1 + ''; + passthru = { + assertion = "grep '^#!${stdenv.shell}' $out/bin/test > /dev/null"; + }; + }; + + split-string = stdenv.mkDerivation { + name = "split-string"; + strictDeps = false; + dontUnpack = true; + installPhase = '' + mkdir -p $out/bin + echo "#!/usr/bin/env -S bash --posix" > $out/bin/test + echo "echo -n hello" >> $out/bin/test + chmod +x $out/bin/test + dontPatchShebangs= + ''; + passthru = { + assertion = "grep -v '^#!${pkgs.coreutils}/bin/env -S ${stdenv.shell} --posix' $out/bin/test > /dev/null"; + }; + }; + + }; +in +stdenv.mkDerivation { + name = "test-patch-shebangs"; + passthru = { inherit (tests) bad-shebang ignores-nix-store updates-nix-store split-string; }; + buildCommand = '' + validate() { + local name=$1 + local testout=$2 + local assertion=$3 + + echo -n "... $name: " >&2 + + local rc=0 + (out=$testout eval "$assertion") || rc=1 + + if [ "$rc" -eq 0 ]; then + echo "yes" >&2 + else + echo "no" >&2 + fi + + return "$rc" + } + + echo "checking whether patchShebangs works properly... ">&2 + + fail= + ${lib.concatStringsSep "\n" (lib.mapAttrsToList (_: test: '' + validate "${test.name}" "${test}" ${lib.escapeShellArg test.assertion} || fail=1 + '') tests)} + + if [ "$fail" ]; then + echo "failed" + exit 1 + else + echo "succeeded" + touch $out + fi + ''; +} diff --git a/nixpkgs/pkgs/test/texlive/default.nix b/nixpkgs/pkgs/test/texlive/default.nix new file mode 100644 index 000000000000..32a503b51bdd --- /dev/null +++ b/nixpkgs/pkgs/test/texlive/default.nix @@ -0,0 +1,514 @@ +{ lib, stdenv, buildEnv, runCommand, fetchurl, file, texlive, writeShellScript, writeText }: + +{ + + tlpdbNix = runCommand "texlive-test-tlpdb-nix" { + nixpkgsTlpdbNix = ../../tools/typesetting/tex/texlive/tlpdb.nix; + tlpdbNix = texlive.tlpdb.nix; + } + '' + mkdir -p "$out" + diff -u "''${nixpkgsTlpdbNix}" "''${tlpdbNix}" | tee "$out/tlpdb.nix.patch" + ''; + + opentype-fonts = runCommand "texlive-test-opentype" { + nativeBuildInputs = [ + (with texlive; combine { inherit scheme-medium libertinus-fonts; }) + ]; + input = builtins.toFile "opentype-testfile.tex" '' + \documentclass{article} + \usepackage{fontspec} + \setmainfont{Libertinus Serif} + \begin{document} + \LaTeX{} is great + \end{document} + ''; + } + '' + export HOME="$(mktemp -d)" + # We use the same testfile to test two completely different + # font discovery mechanisms, both of which were once broken: + # - lualatex uses its own luaotfload script (#220228) + # - xelatex uses fontconfig (#228196) + # both of the following two commands need to succeed. + lualatex -halt-on-error "$input" + xelatex -halt-on-error "$input" + echo success > $out + ''; + + chktex = runCommand "texlive-test-chktex" { + nativeBuildInputs = [ + (with texlive; combine { inherit scheme-infraonly chktex; }) + ]; + input = builtins.toFile "chktex-sample.tex" '' + \documentclass{article} + \begin{document} + \LaTeX is great + \end{document} + ''; + } '' + chktex -v -nall -w1 "$input" 2>&1 | tee "$out" + grep "One warning printed" "$out" + ''; + + dvipng = lib.recurseIntoAttrs { + # https://github.com/NixOS/nixpkgs/issues/75605 + basic = runCommand "texlive-test-dvipng-basic" { + nativeBuildInputs = [ file texlive.combined.scheme-medium ]; + input = fetchurl { + name = "test_dvipng.tex"; + url = "http://git.savannah.nongnu.org/cgit/dvipng.git/plain/test_dvipng.tex?id=b872753590a18605260078f56cbd6f28d39dc035"; + sha256 = "1pjpf1jvwj2pv5crzdgcrzvbmn7kfmgxa39pcvskl4pa0c9hl88n"; + }; + } '' + cp "$input" ./document.tex + + latex document.tex + dvipng -T tight -strict -picky document.dvi + for f in document*.png; do + file "$f" | tee output + grep PNG output + done + + mkdir "$out" + mv document*.png "$out"/ + ''; + + # test dvipng's limited capability to render postscript specials via GS + ghostscript = runCommand "texlive-test-ghostscript" { + nativeBuildInputs = [ file (with texlive; combine { inherit scheme-small dvipng; }) ]; + input = builtins.toFile "postscript-sample.tex" '' + \documentclass{minimal} + \begin{document} + Ni + \special{ps: + newpath + 0 0 moveto + 7 7 rlineto + 0 7 moveto + 7 -7 rlineto + stroke + showpage + } + \end{document} + ''; + gs_trap = writeShellScript "gs_trap.sh" '' + exit 1 + ''; + } '' + cp "$gs_trap" ./gs + export PATH=$PWD:$PATH + # check that the trap works + gs && exit 1 + + cp "$input" ./document.tex + + latex document.tex + dvipng -T 1in,1in -strict -picky document.dvi + for f in document*.png; do + file "$f" | tee output + grep PNG output + done + + mkdir "$out" + mv document*.png "$out"/ + ''; + }; + + # https://github.com/NixOS/nixpkgs/issues/75070 + dvisvgm = runCommand "texlive-test-dvisvgm" { + nativeBuildInputs = [ file texlive.combined.scheme-medium ]; + input = builtins.toFile "dvisvgm-sample.tex" '' + \documentclass{article} + \begin{document} + mwe + \end{document} + ''; + } '' + cp "$input" ./document.tex + + latex document.tex + dvisvgm document.dvi -n -o document_dvi.svg + cat document_dvi.svg + file document_dvi.svg | grep SVG + + pdflatex document.tex + dvisvgm -P document.pdf -n -o document_pdf.svg + cat document_pdf.svg + file document_pdf.svg | grep SVG + + mkdir "$out" + mv document*.svg "$out"/ + ''; + + texdoc = runCommand "texlive-test-texdoc" { + nativeBuildInputs = [ + (with texlive; combine { + inherit scheme-infraonly luatex texdoc; + pkgFilter = pkg: lib.elem pkg.tlType [ "run" "bin" "doc" ]; + }) + ]; + } '' + texdoc --version + + texdoc --debug --list texdoc | tee "$out" + grep texdoc.pdf "$out" + ''; + + # test that language files are generated as expected + hyphen-base = runCommand "texlive-test-hyphen-base" { + hyphenBase = lib.head texlive.hyphen-base.pkgs; + schemeFull = texlive.combined.scheme-full; + schemeInfraOnly = texlive.combined.scheme-infraonly; + } '' + mkdir -p "$out"/{scheme-infraonly,scheme-full} + + # create language files with no hyphenation patterns + cat "$hyphenBase"/tex/generic/config/language.us >language.dat + cat "$hyphenBase"/tex/generic/config/language.us.def >language.def + cat "$hyphenBase"/tex/generic/config/language.us.lua >language.dat.lua + + cat >>language.dat.lua <<EOF + } + EOF + + cat >>language.def <<EOF + %%% No changes may be made beyond this point. + + \uselanguage {USenglish} %%% This MUST be the last line of the file. + EOF + + for fname in language.{dat,def,dat.lua} ; do + diff --ignore-matching-lines='^\(%\|--\) Generated by ' -u \ + {"$hyphenBase","$schemeFull"/share/texmf-var}/tex/generic/config/"$fname" \ + | tee "$out/scheme-full/$fname.patch" + diff --ignore-matching-lines='^\(%\|--\) Generated by ' -u \ + {,"$schemeInfraOnly"/share/texmf-var/tex/generic/config/}"$fname" \ + | tee "$out/scheme-infraonly/$fname.patch" + done + ''; + + # test that fmtutil.cnf is fully regenerated on scheme-full + fmtutilCnf = runCommand "texlive-test-fmtutil.cnf" { + kpathsea = lib.head texlive.kpathsea.pkgs; + schemeFull = texlive.combined.scheme-full; + } '' + mkdir -p "$out" + + diff --ignore-matching-lines='^# Generated by ' -u \ + {"$kpathsea","$schemeFull"/share/texmf-var}/web2c/fmtutil.cnf \ + | tee "$out/fmtutil.cnf.patch" + ''; + + # verify that the restricted mode gets enabled when + # needed (detected by checking if it disallows --gscmd) + repstopdf = runCommand "texlive-test-repstopdf" { + nativeBuildInputs = [ (texlive.combine { inherit (texlive) scheme-infraonly epstopdf; }) ]; + } '' + ! (epstopdf --gscmd echo /dev/null 2>&1 || true) | grep forbidden >/dev/null + (repstopdf --gscmd echo /dev/null 2>&1 || true) | grep forbidden >/dev/null + mkdir "$out" + ''; + + # verify that the restricted mode gets enabled when + # needed (detected by checking if it disallows --gscmd) + rpdfcrop = runCommand "texlive-test-rpdfcrop" { + nativeBuildInputs = [ (texlive.combine { inherit (texlive) scheme-infraonly pdfcrop; }) ]; + } '' + ! (pdfcrop --gscmd echo $(command -v pdfcrop) 2>&1 || true) | grep 'restricted mode' >/dev/null + (rpdfcrop --gscmd echo $(command -v pdfcrop) 2>&1 || true) | grep 'restricted mode' >/dev/null + mkdir "$out" + ''; + + # check that all binaries run successfully, in the following sense: + # (1) run --version, -v, --help, -h successfully; or + # (2) run --help, -h, or no argument with error code but show help text; or + # (3) run successfully on a test.tex or similar file + # we ignore the binaries that cannot be tested as above, and are either + # compiled binaries or trivial shell wrappers + binaries = let + # TODO known broken binaries + broken = [ + # *.inc files in source container rather than run + "texaccents" + + # 'Error initialising QuantumRenderer: no suitable pipeline found' + "tlcockpit" + ] ++ lib.optional stdenv.isDarwin "epspdftk"; # wish shebang is a script, not a binary! + + # (1) binaries requiring -v + shortVersion = [ "devnag" "diadia" "pmxchords" "ptex2pdf" "simpdftex" "ttf2afm" ]; + # (1) binaries requiring --help or -h + help = [ "arlatex" "bundledoc" "cachepic" "checklistings" "dvipos" "extractres" "fig4latex" "fragmaster" + "kpsewhere" "latex-git-log" "ltxfileinfo" "mendex" "perltex" "pn2pdf" "psbook" "psnup" "psresize" "purifyeps" + "simpdftex" "tex2xindy" "texluac" "texluajitc" "urlbst" "yplan" ]; + shortHelp = [ "adhocfilelist" "authorindex" "bbl2bib" "bibdoiadd" "bibmradd" "biburl2doi" "bibzbladd" "ctanupload" + "disdvi" "dvibook" "dviconcat" "getmapdl" "latex2man" "listings-ext.sh" "pygmentex" ]; + # (2) binaries that return non-zero exit code even if correctly asked for help + ignoreExitCode = [ "authorindex" "dvibook" "dviconcat" "dvipos" "extractres" "fig4latex" "fragmaster" "latex2man" + "latex-git-log" "listings-ext.sh" "psbook" "psnup" "psresize" "purifyeps" "tex2xindy" "texluac" + "texluajitc" ]; + # (2) binaries that print help on no argument, returning non-zero exit code + noArg = [ "a2ping" "bg5+latex" "bg5+pdflatex" "bg5latex" "bg5pdflatex" "cef5latex" "cef5pdflatex" "ceflatex" + "cefpdflatex" "cefslatex" "cefspdflatex" "chkdvifont" "dvi2fax" "dvired" "dviselect" "dvitodvi" "epsffit" + "findhyph" "gbklatex" "gbkpdflatex" "komkindex" "kpsepath" "listbib" "listings-ext" "mag" "mathspic" "mf2pt1" + "mk4ht" "mkt1font" "mkgrkindex" "musixflx" "pdf2ps" "pdftosrc" "pdfxup" "pedigree" "pfb2pfa" "pk2bm" "prepmx" + "ps2pk" "psselect" "pstops" "rubibtex" "rubikrotation" "sjislatex" "sjispdflatex" "srcredact" "t4ht" + "teckit_compile" "tex4ht" "texdiff" "texdirflatten" "texplate" "tie" "ttf2kotexfont" "ttfdump" "vlna" "vpl2ovp" + "vpl2vpl" "yplan" ]; + # (3) binaries requiring a .tex file + contextTest = [ "htcontext" ]; + latexTest = [ "de-macro" "e2pall" "htlatex" "htxelatex" "makeindex" "pslatex" "rumakeindex" "tpic2pdftex" + "wordcount" "xhlatex" ]; + texTest = [ "fontinst" "htmex" "httex" "httexi" "htxetex" ]; + # tricky binaries or scripts that are obviously working but are hard to test + # (e.g. because they expect user input no matter the arguments) + # (printafm comes from ghostscript, not texlive) + ignored = [ + # compiled binaries + "dt2dv" "dv2dt" "dvi2tty" "dvidvi" "dvispc" "otp2ocp" "outocp" "pmxab" + + # GUI scripts that accept no argument or crash without a graphics server; please test manualy + "epspdftk" "texdoctk" "tlshell" "xasy" + + # requires Cinderella, not open source and not distributed via Nixpkgs + "ketcindy" + ]; + # binaries that need a combined scheme and cannot work standalone + needScheme = [ + # pfarrei: require working kpse to find lua module + "a5toa4" + + # bibexport: requires kpsewhich + "bibexport" + + # crossrefware: require bibtexperllibs under TEXMFROOT + "bbl2bib" "bibdoiadd" "bibmradd" "biburl2doi" "bibzbladd" "checkcites" "ltx2crossrefxml" + + # require other texlive binaries in PATH + "allcm" "allec" "chkweb" "fontinst" "ht*" "installfont-tl" "kanji-config-updmap-sys" "kanji-config-updmap-user" + "kpse*" "latexfileversion" "mkocp" "mkofm" "mtxrunjit" "pdftex-quiet" "pslatex" "rumakeindex" "texconfig" + "texconfig-sys" "texexec" "texlinks" "texmfstart" "typeoutfileinfo" "wordcount" "xdvi" "xhlatex" + + # misc luatex binaries searching for luatex in PATH + "citeproc-lua" "context" "contextjit" "ctanbib" "digestif" "epspdf" "l3build" "luafindfont" "luaotfload-tool" + "luatools" "make4ht" "pmxchords" "tex4ebook" "texdoc" "texlogsieve" "xindex" + + # requires full TEXMFROOT (e.g. for config) + "mktexfmt" "mktexmf" "mktexpk" "mktextfm" "psnup" "psresize" "pstops" "tlmgr" "updmap" "webquiz" + + # texlive-scripts: requires texlive.infra's TeXLive::TLUtils under TEXMFROOT + "fmtutil" "fmtutil-sys" "fmtutil-user" + + # texlive-scripts: not used in nixpkgs, need updmap in PATH + "updmap-sys" "updmap-user" + ]; + + # simple test files + contextTestTex = writeText "context-test.tex" '' + \starttext + A simple test file. + \stoptext + ''; + latexTestTex = writeText "latex-test.tex" '' + \documentclass{article} + \begin{document} + A simple test file. + \end{document} + ''; + texTestTex = writeText "tex-test.tex" '' + Hello. + \bye + ''; + + # link all binaries in single derivation + allPackages = with lib; concatLists (catAttrs "pkgs" (filter isAttrs (attrValues texlive))); + binPackages = lib.filter (p: p.tlType == "bin") allPackages; + binaries = buildEnv { name = "texlive-binaries"; paths = binPackages; }; + in + runCommand "texlive-test-binaries" + { + inherit binaries contextTestTex latexTestTex texTestTex; + texliveScheme = texlive.combined.scheme-full; + } + '' + loadables="$(command -v bash)" + loadables="''${loadables%/bin/bash}/lib/bash" + enable -f "$loadables/realpath" realpath + mkdir -p "$out" + export HOME="$(mktemp -d)" + declare -i binCount=0 ignoredCount=0 brokenCount=0 failedCount=0 + cp "$contextTestTex" context-test.tex + cp "$latexTestTex" latex-test.tex + cp "$texTestTex" tex-test.tex + + testBin () { + path="$(realpath "$bin")" + path="''${path##*/}" + if [[ -z "$ignoreExitCode" ]] ; then + PATH="$path" "$bin" $args >"$out/$base.log" 2>&1 + ret=$? + if [[ $ret == 0 ]] && grep -i 'command not found' "$out/$base.log" >/dev/null ; then + echo "command not found when running '$base''${args:+ $args}'" + return 1 + fi + return $ret + else + PATH="$path" "$bin" $args >"$out/$base.log" 2>&1 + ret=$? + if [[ $ret == 0 ]] && grep -i 'command not found' "$out/$base.log" >/dev/null ; then + echo "command not found when running '$base''${args:+ $args}'" + return 1 + fi + if ! grep -Ei '(Example:|Options:|Syntax:|Usage:|improper command|SYNOPSIS)' "$out/$base.log" >/dev/null ; then + echo "did not find usage info when running '$base''${args:+ $args}'" + return $ret + fi + fi + } + + for bin in "$binaries"/bin/* ; do + base="''${bin##*/}" + args= + ignoreExitCode= + binCount=$((binCount + 1)) + case "$base" in + ${lib.concatStringsSep "|" ignored}) + ignoredCount=$((ignoredCount + 1)) + continue ;; + ${lib.concatStringsSep "|" broken}) + brokenCount=$((brokenCount + 1)) + continue ;; + ${lib.concatStringsSep "|" help}) + args=--help ;; + ${lib.concatStringsSep "|" shortHelp}) + args=-h ;; + ${lib.concatStringsSep "|" noArg}) + ;; + ${lib.concatStringsSep "|" contextTest}) + args=context-test.tex ;; + ${lib.concatStringsSep "|" latexTest}) + args=latex-test.tex ;; + ${lib.concatStringsSep "|" texTest}) + args=tex-test.tex ;; + ${lib.concatStringsSep "|" shortVersion}) + args=-v ;; + ebong) + touch empty + args=empty ;; + ht) + args='latex latex-test.tex' ;; + pdf2dsc) + args='--help --help --help' ;; + typeoutfileinfo) + args=/dev/null ;; + *) + args=--version ;; + esac + + case "$base" in + ${lib.concatStringsSep "|" (ignoreExitCode ++ noArg)}) + ignoreExitCode=1 ;; + esac + + case "$base" in + ${lib.concatStringsSep "|" needScheme}) + bin="$texliveScheme/bin/$base" + if [[ ! -f "$bin" ]] ; then + ignoredCount=$((ignoredCount + 1)) + continue + fi ;; + esac + + if testBin ; then : ; else # preserve exit code + echo "failed '$base''${args:+ $args}' (exit code: $?)" + sed 's/^/ > /' < "$out/$base.log" + failedCount=$((failedCount + 1)) + fi + done + + echo "tested $binCount binaries: $ignoredCount ignored, $brokenCount broken, $failedCount failed" + [[ $failedCount = 0 ]] + ''; + + # check that all scripts have a Nix shebang + shebangs = let + allPackages = with lib; concatLists (catAttrs "pkgs" (filter isAttrs (attrValues texlive))); + binPackages = lib.filter (p: p.tlType == "bin") allPackages; + in + runCommand "texlive-test-shebangs" { } + ('' + echo "checking that all texlive scripts shebangs are in '$NIX_STORE'" + declare -i scriptCount=0 invalidCount=0 + '' + + (lib.concatMapStrings + (pkg: '' + for bin in '${pkg.outPath}'/bin/* ; do + grep -I -q . "$bin" || continue # ignore binary files + scriptCount=$((scriptCount + 1)) + read -r cmdline < "$bin" + read -r interp <<< "$cmdline" + if [[ "$interp" != "#!$NIX_STORE"/* && "$interp" != "#! $NIX_STORE"/* ]] ; then + echo "error: non-nix shebang '$interp' in script '$bin'" + invalidCount=$((invalidCount + 1)) + fi + done + '') + binPackages) + + '' + echo "checked $scriptCount scripts, found $invalidCount non-nix shebangs" + [[ $invalidCount -gt 0 ]] && exit 1 + mkdir -p "$out" + '' + ); + + # verify that the precomputed licensing information in default.nix + # does indeed match the metadata of the individual packages. + # + # This is part of the test suite (and not the normal evaluation) to save + # time for "normal" evaluations. To be more in line with the other tests, this + # also builds a derivation, even though it is essentially an eval-time assertion. + licenses = + let + concatLicenses = builtins.foldl' (acc: el: if builtins.elem el acc then acc else acc ++ [ el ]); + # converts a license to its attribute name in lib.licenses + licenseToAttrName = license: + builtins.head (builtins.attrNames + (lib.filterAttrs (n: v: license == v) lib.licenses)); + lt = (a: b: a < b); + + savedLicenses = scheme: scheme.meta.license; + savedLicensesAttrNames = scheme: map licenseToAttrName (savedLicenses scheme); + + correctLicenses = scheme: builtins.foldl' + (acc: pkg: concatLicenses acc (lib.toList (pkg.meta.license or []))) + [] + scheme.passthru.packages; + correctLicensesAttrNames = scheme: + lib.sort lt + (map licenseToAttrName (correctLicenses scheme)); + + hasLicenseMismatch = scheme: + (lib.isDerivation scheme) && + (savedLicensesAttrNames scheme) != (correctLicensesAttrNames scheme); + incorrectSchemes = lib.filterAttrs + (n: hasLicenseMismatch) + texlive.combined; + prettyPrint = name: scheme: + '' + license info for ${name} is incorrect! Note that order is enforced. + saved: [ ${lib.concatStringsSep " " (savedLicensesAttrNames scheme)} ] + correct: [ ${lib.concatStringsSep " " (correctLicensesAttrNames scheme)} ] + ''; + errorText = lib.concatStringsSep "\n\n" (lib.mapAttrsToList prettyPrint incorrectSchemes); + in + runCommand "texlive-test-license" { + inherit errorText; + } + (if (incorrectSchemes == {}) + then "echo everything is fine! > $out" + else '' + echo "$errorText" + false + ''); +} diff --git a/nixpkgs/pkgs/test/vim/default.nix b/nixpkgs/pkgs/test/vim/default.nix new file mode 100644 index 000000000000..4d8e59a306a8 --- /dev/null +++ b/nixpkgs/pkgs/test/vim/default.nix @@ -0,0 +1,26 @@ +{ vimUtils, vim-full, writeText, vimPlugins +, lib, fetchFromGitHub +, pkgs +}: +let + inherit (vimUtils) buildVimPluginFrom2Nix; + + packages.myVimPackage.start = with vimPlugins; [ vim-nix ]; + +in + pkgs.recurseIntoAttrs (rec { + vim_empty_config = vimUtils.vimrcFile { beforePlugins = ""; customRC = ""; }; + + ### vim tests + ################## + + test_vim_with_vim_nix_using_plug = vim-full.customize { + name = "vim-with-vim-addon-nix-using-plug"; + vimrcConfig.plug.plugins = with vimPlugins; [ vim-nix ]; + }; + + test_vim_with_vim_nix = vim-full.customize { + name = "vim-with-vim-addon-nix"; + vimrcConfig.packages.myVimPackage.start = with vimPlugins; [ vim-nix ]; + }; +}) |