about summary refs log tree commit diff
path: root/pkgs/test
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/test')
-rw-r--r--pkgs/test/default.nix3
-rw-r--r--pkgs/test/hooks/default.nix8
-rw-r--r--pkgs/test/simple/builder.sh1
-rw-r--r--pkgs/test/stdenv/default.nix256
-rw-r--r--pkgs/test/stdenv/hooks.nix126
5 files changed, 394 insertions, 0 deletions
diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix
index bf0842f266989..818001018b3ae 100644
--- a/pkgs/test/default.nix
+++ b/pkgs/test/default.nix
@@ -21,11 +21,14 @@ with pkgs;
   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; };
 
diff --git a/pkgs/test/hooks/default.nix b/pkgs/test/hooks/default.nix
new file mode 100644
index 0000000000000..aabf939b68657
--- /dev/null
+++ b/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/pkgs/test/simple/builder.sh b/pkgs/test/simple/builder.sh
index 65f7e4c11ba1b..908faec3c3888 100644
--- a/pkgs/test/simple/builder.sh
+++ b/pkgs/test/simple/builder.sh
@@ -1,3 +1,4 @@
+if [ -e .attrs.sh ]; then source .attrs.sh; fi
 set -x
 
 export NIX_DEBUG=1
diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix
new file mode 100644
index 0000000000000..5ff18298f217a
--- /dev/null
+++ b/pkgs/test/stdenv/default.nix
@@ -0,0 +1,256 @@
+# To run these tests:
+# nix-build -A tests.stdenv
+
+{ stdenv
+, pkgs
+, lib
+,
+}:
+
+let
+  # early enough not to rebuild gcc but late enough to have patchelf
+  earlyPkgs = 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;
+
+
+  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; });
+
+  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-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; });
+
+    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/pkgs/test/stdenv/hooks.nix b/pkgs/test/stdenv/hooks.nix
new file mode 100644
index 0000000000000..7f25d7dbd2db0
--- /dev/null
+++ b/pkgs/test/stdenv/hooks.nix
@@ -0,0 +1,126 @@
+{ stdenv, pkgs }:
+
+# 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";
+    buildCommand = ''
+      mkdir -p $out/{bar,baz}
+      source1="$out/bar/foo"
+      destination1="$out/baz/foo"
+      echo foo > $source1
+      ln -s $source1 $destination1
+      echo "symlink before patching: $(readlink $destination1)"
+
+      _makeSymlinksRelative
+
+      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)
+    '';
+  };
+  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
+  # TODO: move patch-shebangs test from pkgs/test/patch-shebangs/default.nix to here
+  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
+}