Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
Shell
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183#!/usr/bin/env bash
# Property tests for lib/path/default.nix# It generates random path-like strings and runs the functions on# them, checking that the expected laws of the functions hold# Run:# [nixpkgs]$ lib/path/tests/prop.sh# or:# [nixpkgs]$ nix-build lib/tests/release.nix
set -euo pipefailshopt -s inherit_errexit
# https://stackoverflow.com/a/246128SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
if test -z "${TEST_LIB:-}"; then TEST_LIB=$SCRIPT_DIR/../..fi
tmp="$(mktemp -d)"clean_up() { rm -rf "$tmp"}trap clean_up EXITmkdir -p "$tmp/work"cd "$tmp/work"
# Defaulting to a random seed but the first argument can override thisseed=${1:-$RANDOM}echo >&2 "Using seed $seed, use \`lib/path/tests/prop.sh $seed\` to reproduce this result"
# The number of random paths to generate. This specific number was chosen to# be fast enough while still generating enough variety to detect bugs.count=500
debug=0# debug=1 # print some extra info# debug=2 # print generated values
# Fine tuning parameters to balance the number of generated invalid paths# to the variance in generated paths.extradotweight=64 # Larger value: more dotsextraslashweight=64 # Larger value: more slashesextranullweight=16 # Larger value: shorter strings
die() { echo >&2 "test case failed: " "$@" exit 1}
if [[ "$debug" -ge 1 ]]; then echo >&2 "Generating $count random path-like strings"fi
# Read stream of null-terminated strings entry-by-entry into bash,# write it to a file and the `strings` array.declare -a strings=()mkdir -p "$tmp/strings"while IFS= read -r -d $'\0' str; do printf "%s" "$str" > "$tmp/strings/${#strings[@]}" strings+=("$str")done < <(awk \ -f "$SCRIPT_DIR"/generate.awk \ -v seed="$seed" \ -v count="$count" \ -v extradotweight="$extradotweight" \ -v extraslashweight="$extraslashweight" \ -v extranullweight="$extranullweight")
if [[ "$debug" -ge 1 ]]; then echo >&2 "Trying to normalise the generated path-like strings with Nix"fi
# Precalculate all normalisations with a single Nix call. Calling Nix for each# string individually would take way too longnix-instantiate --eval --strict --json --show-trace \ --argstr libpath "$TEST_LIB" \ --argstr dir "$tmp/strings" \ "$SCRIPT_DIR"/prop.nix \ >"$tmp/result.json"
# Uses some jq magic to turn the resulting attribute set into an associative# bash array assignmentdeclare -A normalised_result="($(jq ' to_entries | map("[\(.key | @sh)]=\(.value | @sh)") | join(" \n")' -r < "$tmp/result.json"))"
# Looks up a normalisation result for a string# Checks that the normalisation is only failing iff it's an invalid subpath# For valid subpaths, returns 0 and prints the normalisation result# For invalid subpaths, returns 1normalise() { local str=$1 # Uses the same check for validity as in the library implementation if [[ "$str" == "" || "$str" == /* || "$str" =~ ^(.*/)?\.\.(/.*)?$ ]]; then valid= else valid=1 fi
normalised=${normalised_result[$str]} # An empty string indicates failure, this is encoded in ./prop.nix if [[ -n "$normalised" ]]; then if [[ -n "$valid" ]]; then echo "$normalised" else die "For invalid subpath \"$str\", lib.path.subpath.normalise returned this result: \"$normalised\"" fi else if [[ -n "$valid" ]]; then die "For valid subpath \"$str\", lib.path.subpath.normalise failed" else if [[ "$debug" -ge 2 ]]; then echo >&2 "String \"$str\" is not a valid subpath" fi # Invalid and it correctly failed, we let the caller continue if they catch the exit code return 1 fi fi}
# Intermediate result populated by test_idempotency_realpath# and used in test_normalise_uniqueness## Contains a mapping from a normalised subpath to the realpath result it representsdeclare -A norm_to_real
test_idempotency_realpath() { if [[ "$debug" -ge 1 ]]; then echo >&2 "Checking idempotency of each result and making sure the realpath result isn't changed" fi
# Count invalid subpaths to display stats invalid=0 for str in "${strings[@]}"; do if ! result=$(normalise "$str"); then ((invalid++)) || true continue fi
# Check the law that it doesn't change the result of a realpath mkdir -p -- "$str" "$result" real_orig=$(realpath -- "$str") real_norm=$(realpath -- "$result")
if [[ "$real_orig" != "$real_norm" ]]; then die "realpath of the original string \"$str\" (\"$real_orig\") is not the same as realpath of the normalisation \"$result\" (\"$real_norm\")" fi
if [[ "$debug" -ge 2 ]]; then echo >&2 "String \"$str\" gets normalised to \"$result\" and file path \"$real_orig\"" fi norm_to_real["$result"]="$real_orig" done if [[ "$debug" -ge 1 ]]; then echo >&2 "$(bc <<< "scale=1; 100 / $count * $invalid")% of the total $count generated strings were invalid subpath strings, and were therefore ignored" fi}
test_normalise_uniqueness() { if [[ "$debug" -ge 1 ]]; then echo >&2 "Checking for the uniqueness law" fi
for norm_p in "${!norm_to_real[@]}"; do real_p=${norm_to_real["$norm_p"]} for norm_q in "${!norm_to_real[@]}"; do real_q=${norm_to_real["$norm_q"]} # Checks normalisation uniqueness law for each pair of values if [[ "$norm_p" != "$norm_q" && "$real_p" == "$real_q" ]]; then die "Normalisations \"$norm_p\" and \"$norm_q\" are different, but the realpath of them is the same: \"$real_p\"" fi done done}
test_idempotency_realpathtest_normalise_uniqueness
echo >&2 tests ok