tests.trivial-builders.references: refactor expression

Define package `testScriptBin` that contains the substituted test script.
* Add an `installCheckPhase` to check the result script with ShellCheck.
* Passthru as `references.testScriptBin` to run the
  (substituted) test script directly (without VM).
* Drop the logic in build script that detects if
  it is run in the Nix sandbox.
* Inline sample application; drop invoke-*.nix.

Format expressions.
* Format with `nixpkgs-fmt`.
* Use multi-line style of set patterns.

Call the samples with `callPackage`.
* Rename `sample` -> `samples`.
* Take individual packages / build helpers directly from the
  set pattern.
* Define `cleanSamples` to filter out overriders such as `<pkg>.override`.
  added by `callPackage`.

Passthru samples and invocation results for easier debugging.
* Passthru samples, references, directReferences
* Provide tests.trivial-builders.writeStringReferencesToFile with such
  samples argument.
This commit is contained in:
Yueh-Shun Li 2023-07-14 05:19:15 +08:00
parent 1d56e7909d
commit 79a1e9d729
8 changed files with 148 additions and 89 deletions

View file

@ -14,21 +14,24 @@
{ callPackage, lib, stdenv }:
let
inherit (lib) recurseIntoAttrs;
references = callPackage ./references.nix {};
in
recurseIntoAttrs {
concat = callPackage ./concat-test.nix {};
linkFarm = callPackage ./link-farm.nix {};
overriding = callPackage ../test-overriding.nix {};
# VM test not supported beyond linux yet
references =
# VM test not supported beyond linux yet
if stdenv.hostPlatform.isLinux
then callPackage ./references.nix {}
then references
else null;
writeCBin = callPackage ./writeCBin.nix {};
writeShellApplication = callPackage ./writeShellApplication.nix {};
writeScriptBin = callPackage ./writeScriptBin.nix {};
writeShellScript = callPackage ./write-shell-script.nix {};
writeShellScriptBin = callPackage ./writeShellScriptBin.nix {};
writeStringReferencesToFile = callPackage ./writeStringReferencesToFile.nix {};
writeStringReferencesToFile = callPackage ./writeStringReferencesToFile.nix {
inherit (references) samples;
};
writeTextFile = callPackage ./write-text-file.nix {};
}

View file

@ -1,4 +0,0 @@
{ pkgs ? import ../../../.. { config = {}; overlays = []; } }:
pkgs.lib.mapAttrs
(k: v: pkgs.writeDirectReferencesToFile v)
(import ./sample.nix { inherit pkgs; })

View file

@ -1,4 +0,0 @@
{ pkgs ? import ../../../.. { config = {}; overlays = []; } }:
pkgs.lib.mapAttrs
(k: v: pkgs.writeReferencesToFile v)
(import ./sample.nix { inherit pkgs; })

View file

@ -6,13 +6,21 @@
#
# -------------------------------------------------------------------------- #
#
# This file can be run independently (quick):
# Execute this build script directly (quick):
#
# $ pkgs/build-support/trivial-builders/references-test.sh
# * Classic
# $ NIX_PATH="nixpkgs=$PWD" nix-shell -p tests.trivial-builders.references.testScriptBin --run references-test
#
# or in the build sandbox with a ~20s VM overhead
# * Flake-based
# $ nix run .#tests.trivial-builders.references.testScriptBin
#
# $ nix-build -A tests.trivial-builders.references
# or in the build sandbox with a ~20s VM overhead:
#
# * Classic
# $ nix-build --no-out-link -A tests.trivial-builders.references
#
# * Flake-based
# $ nix build -L --no-link .#tests.trivial-builders.references
#
# -------------------------------------------------------------------------- #
@ -25,44 +33,29 @@ set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")" # nixpkgs root
if [[ -z ${SAMPLE:-} ]]; then
echo "Running the script directly is currently not supported."
echo "If you need to iterate, remove the raw path, which is not returned by nix-build."
exit 1
# # shellcheck disable=SC2206 # deliberately unquoted
# sample=( $(nix-build --no-out-link sample.nix) )
# # shellcheck disable=SC2206 # deliberately unquoted
# directRefs=( $(nix-build --no-out-link invoke-writeDirectReferencesToFile.nix) )
# # shellcheck disable=SC2206 # deliberately unquoted
# references=( $(nix-build --no-out-link invoke-writeReferencesToFile.nix) )
# echo "sample: ${#sample[@]}"
# echo "direct: ${#directRefs[@]}"
# echo "indirect: ${#references[@]}"
else
# Injected by Nix (to avoid evaluating in a derivation)
# turn them into arrays
# shellcheck disable=SC2206 # deliberately unquoted
sample=( $SAMPLE )
declare -A samples=( @SAMPLES@ )
# shellcheck disable=SC2206 # deliberately unquoted
directRefs=( $DIRECT_REFS )
declare -A directRefs=( @DIRECT_REFS@ )
# shellcheck disable=SC2206 # deliberately unquoted
references=( $REFERENCES )
fi
declare -A references=( @REFERENCES@ )
echo >&2 Testing direct references...
for i in "${!sample[@]}"; do
echo >&2 Checking "#$i" "${sample[$i]}" "${directRefs[$i]}"
for i in "${!samples[@]}"; do
echo >&2 Checking "$i" "${samples[$i]}" "${directRefs[$i]}"
diff -U3 \
<(sort <"${directRefs[$i]}") \
<(nix-store -q --references "${sample[$i]}" | sort)
<(nix-store -q --references "${samples[$i]}" | sort)
done
echo >&2 Testing closure...
for i in "${!sample[@]}"; do
echo >&2 Checking "#$i" "${sample[$i]}" "${references[$i]}"
for i in "${!samples[@]}"; do
echo >&2 Checking "$i" "${samples[$i]}" "${references[$i]}"
diff -U3 \
<(sort <"${references[$i]}") \
<(nix-store -q --requisites "${sample[$i]}" | sort)
<(nix-store -q --requisites "${samples[$i]}" | sort)
done
echo 'OK!'

View file

@ -1,4 +1,19 @@
{ lib, testers, pkgs, writeText, hello, figlet, stdenvNoCC }:
{ lib
, stdenvNoCC
, testers
, callPackage
, writeText
# nativeBuildInputs
, shellcheck-minimal
# Samples
, samples ? cleanSamples (callPackage ./samples.nix { })
# Filter out the non-string-like attributes such as <pkg>.override added by
# callPackage.
, cleanSamples ? lib.filterAttrs (n: lib.isStringLike)
# Test targets
, writeDirectReferencesToFile
, writeReferencesToFile
}:
# -------------------------------------------------------------------------- #
#
@ -6,21 +21,74 @@
#
# -------------------------------------------------------------------------- #
#
# This file can be run independently (quick):
# Execute this build script directly (quick):
#
# $ pkgs/build-support/trivial-builders/references-test.sh
# * Classic
# $ NIX_PATH="nixpkgs=$PWD" nix-shell -p tests.trivial-builders.references.testScriptBin --run references-test
#
# or in the build sandbox with a ~20s VM overhead
# * Flake-based
# $ nix run .#tests.trivial-builders.references.testScriptBin
#
# $ nix-build -A tests.trivial-builders.references
# or in the build sandbox with a ~20s VM overhead:
#
# * Classic
# $ nix-build --no-out-link -A tests.trivial-builders.references
#
# * Flake-based
# $ nix build -L --no-link .#tests.trivial-builders.references
#
# -------------------------------------------------------------------------- #
let
invokeSamples = file:
lib.concatStringsSep " " (
lib.attrValues (import file { inherit pkgs; })
);
# Map each attribute to an element specification of Bash associative arrary
# and concatenate them with white spaces, to be used to define a
# one-line Bash associative array.
samplesToString = attrs:
lib.concatMapStringsSep " " (name: "[${name}]=${lib.escapeShellArg "${attrs.${name}}"}") (builtins.attrNames attrs);
references = lib.mapAttrs (n: v: writeReferencesToFile v) samples;
directReferences = lib.mapAttrs (n: v: writeDirectReferencesToFile v) samples;
testScriptBin = stdenvNoCC.mkDerivation (finalAttrs: {
name = "references-test";
src = ./references-test.sh;
dontUnpack = true;
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p "$out/bin"
substitute "$src" "$out/bin/${finalAttrs.meta.mainProgram}" \
--replace "@SAMPLES@" ${lib.escapeShellArg (samplesToString samples)} \
--replace "@REFERENCES@" ${lib.escapeShellArg (samplesToString references)} \
--replace "@DIRECT_REFS@" ${lib.escapeShellArg (samplesToString directReferences)}
runHook postInstall
chmod +x "$out/bin/${finalAttrs.meta.mainProgram}"
'';
doInstallCheck = true;
nativeInstallCheckInputs = [
shellcheck-minimal
];
installCheckPhase = ''
runHook preInstallCheck
shellcheck "$out/bin/${finalAttrs.meta.mainProgram}"
runHook postInstallCheck
'';
passthru = {
inherit
directReferences
references
samples
;
};
meta = with lib; {
mainProgram = "references-test";
};
});
in
testers.nixosTest {
name = "nixpkgs-trivial-builders";
@ -28,22 +96,25 @@ testers.nixosTest {
virtualisation.writableStore = true;
# Test runs without network, so we don't substitute and prepare our deps
nix.settings.substituters = lib.mkForce [];
nix.settings.substituters = lib.mkForce [ ];
environment.etc."pre-built-paths".source = writeText "pre-built-paths" (
builtins.toJSON [hello figlet stdenvNoCC]
builtins.toJSON [ testScriptBin ]
);
environment.variables = {
SAMPLE = invokeSamples ./sample.nix;
REFERENCES = invokeSamples ./invoke-writeReferencesToFile.nix;
DIRECT_REFS = invokeSamples ./invoke-writeDirectReferencesToFile.nix;
};
};
testScript =
''
machine.succeed("""
${./references-test.sh} 2>/dev/console
${lib.getExe testScriptBin} 2>/dev/console
""")
'';
passthru = {
inherit
directReferences
references
samples
testScriptBin
;
};
meta = {
maintainers = with lib.maintainers; [
roberth

View file

@ -1,29 +0,0 @@
{ pkgs ? import ../../../.. { config = { }; overlays = [ ]; } }:
let
inherit (pkgs)
figlet
zlib
hello
writeText
runCommand
;
in
{
hello = hello;
figlet = figlet;
zlib = zlib;
zlib-dev = zlib.dev;
norefs = writeText "hi" "hello";
norefsDup = writeText "hi" "hello";
helloRef = writeText "hi" "hello ${hello}";
helloRefDup = writeText "hi" "hello ${hello}";
path = ./invoke-writeReferencesToFile.nix;
pathLike.outPath = ./invoke-writeReferencesToFile.nix;
helloFigletRef = writeText "hi" "hello ${hello} ${figlet}";
selfRef = runCommand "self-ref-1" {} "echo $out >$out";
selfRef2 = runCommand "self-ref-2" {} ''echo "${figlet}, $out" >$out'';
inherit (pkgs)
emptyFile
emptyDirectory
;
}

View file

@ -0,0 +1,30 @@
{ lib
, runCommand
, writeText
, emptyFile
, emptyDirectory
, figlet
, hello
, zlib
}:
{
inherit
figlet
hello
zlib
;
zlib-dev = zlib.dev;
norefs = writeText "hi" "hello";
norefsDup = writeText "hi" "hello";
helloRef = writeText "hi" "hello ${hello}";
helloRefDup = writeText "hi" "hello ${hello}";
path = ./samples.nix;
pathLike.outPath = ./samples.nix;
helloFigletRef = writeText "hi" "hello ${hello} ${figlet}";
selfRef = runCommand "self-ref-1" { } "echo $out >$out";
selfRef2 = runCommand "self-ref-2" { } ''echo "${figlet}, $out" >$out'';
inherit
emptyFile
emptyDirectory
;
}

View file

@ -1,14 +1,13 @@
{ callPackage, lib, pkgs, runCommand, writeText, writeStringReferencesToFile }:
{ callPackage, lib, pkgs, runCommand, samples, writeText, writeStringReferencesToFile }:
let
sample = import ./sample.nix { inherit pkgs; };
samplePaths = lib.unique (lib.attrValues sample);
samplePaths = lib.unique (lib.attrValues samples);
stri = x: "${x}";
sampleText = writeText "sample-text" (lib.concatStringsSep "\n" (lib.unique (map stri samplePaths)));
stringReferencesText =
writeStringReferencesToFile
((lib.concatMapStringsSep "fillertext"
stri
(lib.attrValues sample)) + ''
(lib.attrValues samples)) + ''
STORE=${builtins.storeDir};\nsystemctl start bar-foo.service
'');
in