2024-05-28 19:43:04 +03:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
2014-07-16 17:02:05 +03:00
|
|
|
source common.sh
|
|
|
|
|
2024-06-16 13:51:46 +03:00
|
|
|
TODO_NixOS
|
|
|
|
|
2014-07-16 17:02:05 +03:00
|
|
|
clearStore
|
|
|
|
|
2024-09-05 17:41:15 +03:00
|
|
|
# Check that NARs with duplicate directory entries are rejected.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < duplicate.nar | grepQuiet "NAR directory is not sorted"
|
2014-07-16 17:02:05 +03:00
|
|
|
|
2024-09-05 17:48:43 +03:00
|
|
|
# Check that nix-store --restore fails if the output already exists.
|
2024-09-05 23:21:53 +03:00
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < duplicate.nar | grepQuiet "path '.*/out' already exists"
|
2024-09-05 17:48:43 +03:00
|
|
|
|
2024-09-05 17:54:12 +03:00
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
echo foo > "$TEST_ROOT/out"
|
2024-09-05 23:21:53 +03:00
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < duplicate.nar | grepQuiet "File exists"
|
2024-09-05 17:54:12 +03:00
|
|
|
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
ln -s "$TEST_ROOT/out2" "$TEST_ROOT/out"
|
2024-09-05 23:21:53 +03:00
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < duplicate.nar | grepQuiet "File exists"
|
2024-09-05 17:54:12 +03:00
|
|
|
|
|
|
|
mkdir -p "$TEST_ROOT/out2"
|
2024-09-05 23:21:53 +03:00
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < duplicate.nar | grepQuiet "path '.*/out' already exists"
|
2024-09-05 17:54:12 +03:00
|
|
|
|
2024-09-06 17:28:09 +03:00
|
|
|
# The same, but for a regular file.
|
|
|
|
nix-store --dump ./nars.sh > "$TEST_ROOT/tmp.nar"
|
|
|
|
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
mkdir -p "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
ln -s "$TEST_ROOT/out2" "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
|
|
|
mkdir -p "$TEST_ROOT/out2"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
2024-09-09 15:11:35 +03:00
|
|
|
# The same, but for a symlink.
|
2024-09-06 17:28:09 +03:00
|
|
|
ln -sfn foo "$TEST_ROOT/symlink"
|
|
|
|
nix-store --dump "$TEST_ROOT/symlink" > "$TEST_ROOT/tmp.nar"
|
|
|
|
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar"
|
|
|
|
[[ -L "$TEST_ROOT/out" ]]
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
mkdir -p "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
ln -s "$TEST_ROOT/out2" "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
|
|
|
mkdir -p "$TEST_ROOT/out2"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < "$TEST_ROOT/tmp.nar" | grepQuiet "File exists"
|
|
|
|
|
2014-07-16 17:02:05 +03:00
|
|
|
# Check whether restoring and dumping a NAR that contains case
|
|
|
|
# collisions is round-tripping, even on a case-insensitive system.
|
2024-09-05 17:41:15 +03:00
|
|
|
rm -rf "$TEST_ROOT/case"
|
|
|
|
opts=("--option" "use-case-hack" "true")
|
2024-06-04 00:51:07 +03:00
|
|
|
nix-store "${opts[@]}" --restore "$TEST_ROOT/case" < case.nar
|
2024-09-12 18:25:25 +03:00
|
|
|
[[ -e "$TEST_ROOT/case/xt_CONNMARK.h" ]]
|
|
|
|
[[ -e "$TEST_ROOT/case/xt_CONNmark.h~nix~case~hack~1" ]]
|
|
|
|
[[ -e "$TEST_ROOT/case/xt_connmark.h~nix~case~hack~2" ]]
|
|
|
|
[[ -e "$TEST_ROOT/case/x/FOO" ]]
|
|
|
|
[[ -d "$TEST_ROOT/case/x/Foo~nix~case~hack~1" ]]
|
|
|
|
[[ -e "$TEST_ROOT/case/x/foo~nix~case~hack~2/a~nix~case~hack~1/foo" ]]
|
2024-06-04 00:51:07 +03:00
|
|
|
nix-store "${opts[@]}" --dump "$TEST_ROOT/case" > "$TEST_ROOT/case.nar"
|
|
|
|
cmp case.nar "$TEST_ROOT/case.nar"
|
|
|
|
[ "$(nix-hash "${opts[@]}" --type sha256 "$TEST_ROOT/case")" = "$(nix-hash --flat --type sha256 case.nar)" ]
|
2014-07-16 17:02:05 +03:00
|
|
|
|
|
|
|
# Check whether we detect true collisions (e.g. those remaining after
|
|
|
|
# removal of the suffix).
|
|
|
|
touch "$TEST_ROOT/case/xt_CONNMARK.h~nix~case~hack~3"
|
2024-06-04 00:51:07 +03:00
|
|
|
(! nix-store "${opts[@]}" --dump "$TEST_ROOT/case" > /dev/null)
|
2024-09-05 20:26:10 +03:00
|
|
|
|
|
|
|
# Detect NARs that have a directory entry that after case-hacking
|
|
|
|
# collides with another entry (e.g. a directory containing 'Test',
|
|
|
|
# 'Test~nix~case~hack~1' and 'test').
|
|
|
|
rm -rf "$TEST_ROOT/case"
|
|
|
|
expectStderr 1 nix-store "${opts[@]}" --restore "$TEST_ROOT/case" < case-collision.nar | grepQuiet "NAR contains file name 'test' that collides with case-hacked file name 'Test~nix~case~hack~1'"
|
2024-09-05 21:37:26 +03:00
|
|
|
|
2024-09-26 19:17:31 +03:00
|
|
|
# Deserializing a NAR that contains file names that Unicode-normalize to the
|
|
|
|
# same name should fail on macOS and specific Linux setups (typically ZFS with
|
|
|
|
# `utf8only` enabled and `normalization` set to anything else than `none`). The
|
|
|
|
# deserialization should succeed on most Linux, where file names aren't
|
|
|
|
# unicode-normalized.
|
|
|
|
#
|
|
|
|
# We test that:
|
|
|
|
#
|
|
|
|
# 1. It either succeeds or fails with "already exists" error.
|
|
|
|
# 2. Nix has the same behavior with respect to unicode normalization than
|
|
|
|
# $TEST_ROOT's filesystem (when using basic Unix commands)
|
2024-09-05 21:37:26 +03:00
|
|
|
rm -rf "$TEST_ROOT/out"
|
2024-09-26 19:17:31 +03:00
|
|
|
set +e
|
|
|
|
unicodeTestOut=$(nix-store --restore "$TEST_ROOT/out" < unnormalized.nar 2>&1)
|
|
|
|
unicodeTestCode=$?
|
|
|
|
set -e
|
|
|
|
|
2024-10-07 15:54:35 +03:00
|
|
|
touch "$TEST_ROOT/unicode-â" # non-canonical version
|
|
|
|
touch "$TEST_ROOT/unicode-â"
|
|
|
|
|
2024-09-26 19:17:31 +03:00
|
|
|
touchFilesCount=$(find "$TEST_ROOT" -maxdepth 1 -name "unicode-*" -type f | wc -l)
|
|
|
|
|
|
|
|
if (( unicodeTestCode == 1 )); then
|
|
|
|
# If the command failed (MacOS or ZFS + normalization), checks that it failed
|
|
|
|
# with the expected "already exists" error, and that this is the same
|
|
|
|
# behavior as `touch`
|
|
|
|
echo "$unicodeTestOut" | grepQuiet "path '.*/out/â' already exists"
|
|
|
|
|
|
|
|
(( touchFilesCount == 1 ))
|
|
|
|
elif (( unicodeTestCode == 0 )); then
|
|
|
|
# If the command succeeded, check that both files are present, and that this
|
|
|
|
# is the same behavior as `touch`
|
2024-09-05 21:37:26 +03:00
|
|
|
[[ -e $TEST_ROOT/out/â ]]
|
|
|
|
[[ -e $TEST_ROOT/out/â ]]
|
2024-09-26 19:17:31 +03:00
|
|
|
|
|
|
|
(( touchFilesCount == 2 ))
|
|
|
|
else
|
|
|
|
# if the return code is neither 0 or 1, fail the test.
|
|
|
|
echo "NAR deserialization of files with the same Unicode normalization failed with unexpected return code $unicodeTestCode" >&2
|
|
|
|
exit 1
|
2024-09-05 21:37:26 +03:00
|
|
|
fi
|
2024-09-12 15:58:33 +03:00
|
|
|
|
2024-09-26 19:17:31 +03:00
|
|
|
rm -f "$TEST_ROOT/unicode-*"
|
|
|
|
|
2024-09-12 15:58:33 +03:00
|
|
|
# Unpacking a NAR with a NUL character in a file name should fail.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
2024-11-03 08:02:43 +02:00
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < nul-character.nar | grepQuiet "NAR contains invalid file name 'f"
|
2024-09-12 15:58:33 +03:00
|
|
|
|
|
|
|
# Likewise for a '.' filename.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < dot.nar | grepQuiet "NAR contains invalid file name '.'"
|
|
|
|
|
|
|
|
# Likewise for a '..' filename.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < dotdot.nar | grepQuiet "NAR contains invalid file name '..'"
|
|
|
|
|
|
|
|
# Likewise for a filename containing a slash.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < slash.nar | grepQuiet "NAR contains invalid file name 'x/y'"
|
|
|
|
|
|
|
|
# Likewise for an empty filename.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < empty.nar | grepQuiet "NAR contains invalid file name ''"
|
2024-09-12 16:57:46 +03:00
|
|
|
|
|
|
|
# Test that the 'executable' field cannot come before the 'contents' field.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < executable-after-contents.nar | grepQuiet "expected tag ')', got 'executable'"
|
|
|
|
|
|
|
|
# Test that the 'name' field cannot come before the 'node' field in a directory entry.
|
|
|
|
rm -rf "$TEST_ROOT/out"
|
|
|
|
expectStderr 1 nix-store --restore "$TEST_ROOT/out" < name-after-node.nar | grepQuiet "expected tag 'name'"
|