diff options
Diffstat (limited to 'nixpkgs/pkgs/test')
9 files changed, 361 insertions, 2 deletions
diff --git a/nixpkgs/pkgs/test/checkpointBuild/default.nix b/nixpkgs/pkgs/test/checkpointBuild/default.nix new file mode 100644 index 000000000000..4a59760230a6 --- /dev/null +++ b/nixpkgs/pkgs/test/checkpointBuild/default.nix @@ -0,0 +1,57 @@ +{ hello, checkpointBuildTools, runCommandNoCC, texinfo, stdenv, rsync }: +let + baseHelloArtifacts = checkpointBuildTools.prepareCheckpointBuild hello; + patchedHello = hello.overrideAttrs (old: { + buildInputs = [ texinfo ]; + src = runCommandNoCC "patch-hello-src" { } '' + mkdir -p $out + cd $out + tar xf ${hello.src} --strip-components=1 + patch -p1 < ${./hello.patch} + ''; + }); + checkpointBuiltHello = checkpointBuildTools.mkCheckpointedBuild patchedHello baseHelloArtifacts; + + checkpointBuiltHelloWithCheck = checkpointBuiltHello.overrideAttrs (old: { + doCheck = true; + checkPhase = '' + echo "checking if unchanged source file is not recompiled" + [ "$(stat --format="%Y" lib/exitfail.o)" = "$(stat --format="%Y" ${baseHelloArtifacts}/outputs/lib/exitfail.o)" ] + ''; + }); + + baseHelloRemoveFileArtifacts = checkpointBuildTools.prepareCheckpointBuild (hello.overrideAttrs (old: { + patches = [ ./hello-additionalFile.patch ]; + })); + + preparedHelloRemoveFileSrc = runCommandNoCC "patch-hello-src" { } '' + mkdir -p $out + cd $out + tar xf ${hello.src} --strip-components=1 + patch -p1 < ${./hello-additionalFile.patch} + ''; + + patchedHelloRemoveFile = hello.overrideAttrs (old: { + buildInputs = [ texinfo ]; + src = runCommandNoCC "patch-hello-src" { } '' + mkdir -p $out + cd $out + ${rsync}/bin/rsync -cutU --chown=$USER:$USER --chmod=+w -r ${preparedHelloRemoveFileSrc}/* . + patch -p1 < ${./hello-removeFile.patch} + ''; + }); + + checkpointBuiltHelloWithRemovedFile = checkpointBuildTools.mkCheckpointedBuild patchedHelloRemoveFile baseHelloRemoveFileArtifacts; +in +stdenv.mkDerivation { + name = "patched-hello-returns-correct-output"; + buildCommand = '' + touch $out + + echo "testing output of hello binary" + [ "$(${checkpointBuiltHelloWithCheck}/bin/hello)" = "Hello, incremental world!" ] + echo "testing output of hello with removed file" + [ "$(${checkpointBuiltHelloWithRemovedFile}/bin/hello)" = "Hello, incremental world!" ] + ''; +} + diff --git a/nixpkgs/pkgs/test/checkpointBuild/hello-additionalFile.patch b/nixpkgs/pkgs/test/checkpointBuild/hello-additionalFile.patch new file mode 100644 index 000000000000..345bc10ee49e --- /dev/null +++ b/nixpkgs/pkgs/test/checkpointBuild/hello-additionalFile.patch @@ -0,0 +1,67 @@ +:100644 100644 0000000 0000000 M Makefile.in +:000000 100644 0000000 0000000 A src/additionalFile.c +:100644 100644 0000000 0000000 M src/hello.c +:100644 100644 0000000 0000000 M src/system.h + +diff --git a/Makefile.in b/Makefile.in +index 1597d39..f63f830 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -312,7 +312,7 @@ am_lib_libhello_a_OBJECTS = lib/basename-lgpl.$(OBJEXT) \ + lib/version-etc.$(OBJEXT) lib/version-etc-fsf.$(OBJEXT) \ + lib/wctype-h.$(OBJEXT) lib/xmalloc.$(OBJEXT) \ + lib/xalloc-die.$(OBJEXT) lib/xstriconv.$(OBJEXT) \ +- lib/xstrndup.$(OBJEXT) ++ lib/xstrndup.$(OBJEXT) src/additionalFile.$(OBJEXT) + lib_libhello_a_OBJECTS = $(am_lib_libhello_a_OBJECTS) + am_hello_OBJECTS = src/hello.$(OBJEXT) + hello_OBJECTS = $(am_hello_OBJECTS) +@@ -1842,7 +1842,7 @@ lib_libhello_a_SOURCES = lib/basename-lgpl.c lib/c-ctype.h \ + $(am__append_4) $(am__append_5) lib/version-etc.h \ + lib/version-etc.c lib/version-etc-fsf.c lib/wctype-h.c \ + lib/xmalloc.c lib/xalloc-die.c lib/xstriconv.h lib/xstriconv.c \ +- lib/xstrndup.h lib/xstrndup.c ++ lib/xstrndup.h lib/xstrndup.c src/additionalFile.c + lib_libhello_a_LIBADD = $(gl_LIBOBJS) + lib_libhello_a_DEPENDENCIES = $(gl_LIBOBJS) + EXTRA_lib_libhello_a_SOURCES = lib/close.c lib/stripslash.c lib/dup2.c \ +diff --git a/src/additionalFile.c b/src/additionalFile.c +new file mode 100644 +index 0000000..34d683d +--- /dev/null ++++ b/src/additionalFile.c +@@ -0,0 +1,6 @@ ++#include "config.h" ++#include "system.h" ++ ++int somefunc() { ++ return 0; ++} +diff --git a/src/hello.c b/src/hello.c +index 2e7d38e..a8e36dc 100644 +--- a/src/hello.c ++++ b/src/hello.c +@@ -146,7 +146,11 @@ main (int argc, char *argv[]) + #endif + + /* Having initialized gettext, get the default message. */ +- greeting_msg = _("Hello, world!"); ++ if (somefunc() == 0) { ++ greeting_msg = _("Hello, world!"); ++ } else { ++ greeting_msg = _("Hello, incremental world!"); ++ } + + /* Even exiting has subtleties. On exit, if any writes failed, change + the exit status. The /dev/full device on GNU/Linux can be used for +diff --git a/src/system.h b/src/system.h +index d39cdb9..dc425d2 100644 +--- a/src/system.h ++++ b/src/system.h +@@ -59,4 +59,6 @@ + } \ + while (0) + ++int somefunc(); ++ + #endif /* HELLO_SYSTEM_H */ diff --git a/nixpkgs/pkgs/test/checkpointBuild/hello-removeFile.patch b/nixpkgs/pkgs/test/checkpointBuild/hello-removeFile.patch new file mode 100644 index 000000000000..2939790dabce --- /dev/null +++ b/nixpkgs/pkgs/test/checkpointBuild/hello-removeFile.patch @@ -0,0 +1,67 @@ +:100644 100644 0000000 0000000 M Makefile.in +:100644 000000 0000000 0000000 D src/additionalFile.c +:100644 100644 0000000 0000000 M src/hello.c +:100755 100755 0000000 0000000 M tests/hello-1 + +diff --git a/Makefile.in b/Makefile.in +index f63f830..1597d39 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -312,7 +312,7 @@ am_lib_libhello_a_OBJECTS = lib/basename-lgpl.$(OBJEXT) \ + lib/version-etc.$(OBJEXT) lib/version-etc-fsf.$(OBJEXT) \ + lib/wctype-h.$(OBJEXT) lib/xmalloc.$(OBJEXT) \ + lib/xalloc-die.$(OBJEXT) lib/xstriconv.$(OBJEXT) \ +- lib/xstrndup.$(OBJEXT) src/additionalFile.$(OBJEXT) ++ lib/xstrndup.$(OBJEXT) + lib_libhello_a_OBJECTS = $(am_lib_libhello_a_OBJECTS) + am_hello_OBJECTS = src/hello.$(OBJEXT) + hello_OBJECTS = $(am_hello_OBJECTS) +@@ -1842,7 +1842,7 @@ lib_libhello_a_SOURCES = lib/basename-lgpl.c lib/c-ctype.h \ + $(am__append_4) $(am__append_5) lib/version-etc.h \ + lib/version-etc.c lib/version-etc-fsf.c lib/wctype-h.c \ + lib/xmalloc.c lib/xalloc-die.c lib/xstriconv.h lib/xstriconv.c \ +- lib/xstrndup.h lib/xstrndup.c src/additionalFile.c ++ lib/xstrndup.h lib/xstrndup.c + lib_libhello_a_LIBADD = $(gl_LIBOBJS) + lib_libhello_a_DEPENDENCIES = $(gl_LIBOBJS) + EXTRA_lib_libhello_a_SOURCES = lib/close.c lib/stripslash.c lib/dup2.c \ +diff --git a/src/additionalFile.c b/src/additionalFile.c +deleted file mode 100644 +index 34d683d..0000000 +--- a/src/additionalFile.c ++++ /dev/null +@@ -1,6 +0,0 @@ +-#include "config.h" +-#include "system.h" +- +-int somefunc() { +- return 0; +-} +diff --git a/src/hello.c b/src/hello.c +index a8e36dc..53722d9 100644 +--- a/src/hello.c ++++ b/src/hello.c +@@ -126,6 +126,10 @@ parse_options (int argc, char *argv[], const char **greeting_msg) + } + } + ++int somefunc() { ++ return 1; ++} ++ + int + main (int argc, char *argv[]) + { +diff --git a/tests/hello-1 b/tests/hello-1 +index 96ffef8..f0b9f8d 100755 +--- a/tests/hello-1 ++++ b/tests/hello-1 +@@ -21,7 +21,7 @@ export LANGUAGE LC_ALL LC_MESSAGES LANG + + tmpfiles="hello-test1.ok" + cat <<EOF > hello-test1.ok +-Hello, world! ++Hello, incremental world! + EOF + + tmpfiles="$tmpfiles hello-test1.out" diff --git a/nixpkgs/pkgs/test/checkpointBuild/hello.patch b/nixpkgs/pkgs/test/checkpointBuild/hello.patch new file mode 100644 index 000000000000..3d0d50c2f20e --- /dev/null +++ b/nixpkgs/pkgs/test/checkpointBuild/hello.patch @@ -0,0 +1,26 @@ +diff --git a/src/hello.c b/src/hello.c +index 182303c..453962f 100644 +--- a/src/hello.c ++++ b/src/hello.c +@@ -57,7 +57,7 @@ main (int argc, char *argv[]) + #endif + + /* Having initialized gettext, get the default message. */ +- greeting_msg = _("Hello, world!"); ++ greeting_msg = _("Hello, incremental world!"); + + /* Even exiting has subtleties. On exit, if any writes failed, change + the exit status. The /dev/full device on GNU/Linux can be used for +diff --git a/tests/hello-1 b/tests/hello-1 +index 3b7a815..e15fa95 100755 +--- a/tests/hello-1 ++++ b/tests/hello-1 +@@ -21,7 +21,7 @@ export LANGUAGE LC_ALL LC_MESSAGES LANG + + tmpfiles="hello-test1.ok" + cat <<EOF > hello-test1.ok +-Hello, world! ++Hello, incremental world! + EOF + + tmpfiles="$tmpfiles hello-test1.out" diff --git a/nixpkgs/pkgs/test/default.nix b/nixpkgs/pkgs/test/default.nix index cfae7a1edd8c..1459e9c310da 100644 --- a/nixpkgs/pkgs/test/default.nix +++ b/nixpkgs/pkgs/test/default.nix @@ -113,6 +113,8 @@ with pkgs; install-shell-files = callPackage ./install-shell-files {}; + checkpoint-build = callPackage ./checkpointBuild {}; + kernel-config = callPackage ./kernel.nix {}; ld-library-path = callPackage ./ld-library-path {}; diff --git a/nixpkgs/pkgs/test/haskell/incremental/default.nix b/nixpkgs/pkgs/test/haskell/incremental/default.nix index 4509939ba4f4..c7bd43b11af6 100644 --- a/nixpkgs/pkgs/test/haskell/incremental/default.nix +++ b/nixpkgs/pkgs/test/haskell/incremental/default.nix @@ -3,13 +3,13 @@ # See: https://www.haskellforall.com/2022/12/nixpkgs-support-for-incremental-haskell.html # See: https://felixspringer.xyz/homepage/blog/incrementalHaskellBuildsWithNix -{ haskell, lib }: +{ haskell, haskellPackages, lib }: let inherit (haskell.lib.compose) overrideCabal; # Incremental builds work with GHC >=9.4. - temporary = haskell.packages.ghc944.temporary; + temporary = haskellPackages.temporary; # This will do a full build of `temporary`, while writing the intermediate build products # (compiled modules, etc.) to the `intermediates` output. diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/README.md new file mode 100644 index 000000000000..41b3012b7d95 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/README.md @@ -0,0 +1,26 @@ +# CI-related Scripts + +This directory contains scripts used and related to the CI running the `pkgs/by-name` checks in Nixpkgs. See also the [CI GitHub Action](../../../../.github/workflows/check-by-name.yml). + +## `./run-local.sh BASE_BRANCH [REPOSITORY]` + +Runs the `pkgs/by-name` check on the HEAD commit, closely matching what CI does. + +Note that this can't do exactly the same as CI, +because CI needs to rely on GitHub's server-side Git history to compute the mergeability of PRs before the check can be started. +In turn when running locally, we don't want to have to push commits to test them, +and we can also rely on the local Git history to do the mergeability check. + +Arguments: +- `BASE_BRANCH`: The base branch to use, e.g. master or release-23.11 +- `REPOSITORY`: The repository to fetch the base branch from, defaults to https://github.com/NixOS/nixpkgs.git + +## `./fetch-tool.sh BASE_BRANCH OUTPUT_PATH` + +Fetches the Hydra-prebuilt nixpkgs-check-by-name to use from the NixOS channel corresponding to the given base branch. + +This script is used both by [`./run-local.sh`](#run-local-sh-base-branch-repository) and CI. + +Arguments: +- `BASE_BRANCH`: The base branch to use, e.g. master or release-23.11 +- `OUTPUT_PATH`: The output symlink path for the tool diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh new file mode 100755 index 000000000000..19a48b6fb1fd --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Fetches the prebuilt nixpkgs-check-by-name to use from +# the NixOS channel corresponding to the given base branch + +set -o pipefail -o errexit -o nounset + +trace() { echo >&2 "$@"; } + +if (( $# < 2 )); then + trace "Usage: $0 BASE_BRANCH OUTPUT_PATH" + trace "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" + trace "OUTPUT_PATH: The output symlink path for the tool" + exit 1 +fi +baseBranch=$1 +output=$2 + +trace -n "Determining the channel to use for PR base branch $baseBranch.. " +if [[ "$baseBranch" =~ ^(release|staging|staging-next)-([0-9][0-9]\.[0-9][0-9])$ ]]; then + # Use the release channel for all PRs to release-XX.YY, staging-XX.YY and staging-next-XX.YY + preferredChannel=nixos-${BASH_REMATCH[2]} +else + # Use the nixos-unstable channel for all other PRs + preferredChannel=nixos-unstable +fi + +# Check that the channel exists. It doesn't exist for fresh release branches +if curl -fSs "https://channels.nixos.org/$preferredChannel"; then + channel=$preferredChannel + trace "$channel" +else + # Fall back to nixos-unstable, makes sense for fresh release branches + channel=nixos-unstable + trace -e "\e[33mWarning: Preferred channel $preferredChannel could not be fetched, using fallback: $channel\e[0m" +fi + +trace -n "Fetching latest version of channel $channel.. " +# This is probably the easiest way to get Nix to output the path to a downloaded channel! +nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel") +trace "$nixpkgs" + +# This file only exists in channels +trace -e "Git revision of channel $channel is \e[34m$(<"$nixpkgs/.git-revision")\e[0m" + +trace -n "Fetching the prebuilt version of nixpkgs-check-by-name.. " +nix-build -o "$output" "$nixpkgs" -A tests.nixpkgs-check-by-name -j 0 >/dev/null +realpath "$output" >&2 diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh new file mode 100755 index 000000000000..72d3e8dc3de3 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +set -o pipefail -o errexit -o nounset + +trace() { echo >&2 "$@"; } + +tmp=$(mktemp -d) +cleanup() { + # Don't exit early if anything fails to cleanup + set +o errexit + + trace -n "Cleaning up.. " + + [[ -e "$tmp/base" ]] && git worktree remove --force "$tmp/base" + [[ -e "$tmp/merged" ]] && git worktree remove --force "$tmp/merged" + + rm -rf "$tmp" + + trace "Done" +} +trap cleanup exit + + +repo=https://github.com/NixOS/nixpkgs.git + +if (( $# != 0 )); then + baseBranch=$1 + shift +else + trace "Usage: $0 BASE_BRANCH [REPOSITORY]" + trace "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" + trace "REPOSITORY: The repository to fetch the base branch from, defaults to $repo" + exit 1 +fi + +if (( $# != 0 )); then + repo=$1 + shift +fi + +if [[ -n "$(git status --porcelain)" ]]; then + trace -e "\e[33mWarning: Dirty tree, uncommitted changes won't be taken into account\e[0m" +fi +headSha=$(git rev-parse HEAD) +trace -e "Using HEAD commit \e[34m$headSha\e[0m" + +trace -n "Creating Git worktree for the HEAD commit in $tmp/merged.. " +git worktree add --detach -q "$tmp/merged" HEAD +trace "Done" + +trace -n "Fetching base branch $baseBranch to compare against.. " +git fetch -q "$repo" refs/heads/"$baseBranch" +baseSha=$(git rev-parse FETCH_HEAD) +trace -e "\e[34m$baseSha\e[0m" + +trace -n "Creating Git worktree for the base branch in $tmp/base.. " +git worktree add -q "$tmp/base" "$baseSha" +trace "Done" + +trace -n "Merging base branch into the HEAD commit in $tmp/merged.. " +git -C "$tmp/merged" merge -q --no-edit "$baseSha" +trace -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m" + +"$tmp/merged/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh" "$baseBranch" "$tmp/tool" + +trace "Running nixpkgs-check-by-name.." +"$tmp/tool/bin/nixpkgs-check-by-name" --base "$tmp/base" "$tmp/merged" |