Files
erofs-freebsd-out-tree/tests/prepare_g1_fixtures.sh
T
2026-08-13 10:44:59 +02:00

197 lines
7.1 KiB
Bash
Executable File

#!/bin/sh
set -eu
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
output=${1:?usage: prepare_g1_fixtures.sh OUTPUT}
source_dir="$output/source"
base_dir="$output/base"
image_dir="$output/images"
expected_dir="$output/expected"
for tool in mkfs.erofs fsck.erofs dump.erofs python3 sha256sum stat; do
command -v "$tool" >/dev/null 2>&1 || {
echo "missing tool: $tool" >&2
exit 1
}
done
test "$(id -u)" -eq 0 || {
echo "root is required to create device-node fixtures" >&2
exit 1
}
test ! -e "$output" || {
echo "output already exists: $output" >&2
exit 1
}
mkdir -p \
"$source_dir/compact/dir" \
"$source_dir/compact/dotdir" \
"$source_dir/extended" \
"$source_dir/flat/very/long/path/to/a/deeply/nested/deterministic/target/directory" \
"$source_dir/inline" \
"$base_dir" "$expected_dir"
SOURCE_DIR="$source_dir" EXPECTED_DIR="$expected_dir" python3 <<'PY'
from pathlib import Path
import os
source = Path(os.environ["SOURCE_DIR"])
expected = Path(os.environ["EXPECTED_DIR"])
def write_pattern(path: Path, size: int, seed: int) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("wb") as out:
offset = 0
while offset < size:
count = min(65536, size - offset)
out.write(bytes(
(((offset + index) * 131 + seed) ^ ((offset + index) >> 5)) & 0xff
for index in range(count)
))
offset += count
compact = source / "compact"
(compact / "root.txt").write_text("repo22 G1 root payload\n", encoding="ascii")
write_pattern(compact / "testfile.txt", 65537, 1)
(compact / "small.txt").write_text("compact inode payload\n", encoding="ascii")
(compact / "single.txt").write_text("single-link payload\n", encoding="ascii")
(compact / "hard-a.txt").write_text("hard-link payload\n", encoding="ascii")
(compact / "dotdir" / "child.txt").write_text("dot directory child\n", encoding="ascii")
(compact / "invalid-target.txt").write_text("invalid nid target\n", encoding="ascii")
(compact / "special-target.txt").write_text("special target\n", encoding="ascii")
extended = source / "extended"
write_pattern(extended / "large-file.bin", 2 * 1024 * 1024 + 731, 2)
(extended / "huge-sparse.dat").write_bytes(b"x")
(extended / "oversize.dat").write_bytes(b"x")
flat = source / "flat"
(flat / "small.txt").write_text("flat plain small payload\n", encoding="ascii")
write_pattern(flat / "medium.dat", 100 * 1024 + 17, 3)
write_pattern(flat / "large.bin", 10 * 1024 * 1024 + 31, 4)
write_pattern(flat / "data.txt", 256 * 1024 + 19, 5)
write_pattern(flat / "random-test.bin", 1024 * 1024, 6)
write_pattern(flat / "huge-data.bin", 100 * 1024 * 1024 + 257, 7)
(flat / "very" / "long" / "path" / "to" / "a" / "deeply" / "nested" /
"deterministic" / "target" / "directory" / "file.txt").write_text(
"long symlink target payload\n", encoding="ascii"
)
inline = source / "inline"
(inline / "tiny.txt").write_text("inline data\n", encoding="ascii")
(inline / "empty.txt").write_bytes(b"")
(inline / "inline.txt").write_bytes(b"inline-tail-payload-0123456789\n")
write_pattern(inline / "tailpacked.dat", 5000, 8)
write_pattern(inline / "file-4095.dat", 4095, 9)
write_pattern(inline / "file-4096.dat", 4096, 10)
write_pattern(inline / "file-4097.dat", 4097, 11)
(inline / "target.txt").write_text("short symlink target payload\n", encoding="ascii")
for source_path, offset, length, output_name in (
(flat / "medium.dat", 10 * 4096, 5 * 4096, "medium-10-5.bin"),
(flat / "random-test.bin", 0, 10 * 1024, "random-start.bin"),
(flat / "random-test.bin", 500 * 1024, 10 * 1024, "random-mid.bin"),
(flat / "random-test.bin", 1000 * 1024, 24 * 1024, "random-end.bin"),
(flat / "huge-data.bin", 50 * 1024 * 1024, 5 * 1024 * 1024,
"huge-sample.bin"),
):
with source_path.open("rb") as handle:
handle.seek(offset)
data = handle.read(length)
if len(data) != length:
raise RuntimeError(f"short expected range from {source_path}")
(expected / output_name).write_bytes(data)
(expected / "large-hole-zero-64k.bin").write_bytes(bytes(65536))
(expected / "large-hole-description.txt").write_text(
"path=/huge-sparse.dat size=4294971393 content=all-zero\n", encoding="ascii"
)
PY
ln "$source_dir/compact/testfile.txt" "$source_dir/compact/dir/testfile.txt"
ln "$source_dir/compact/hard-a.txt" "$source_dir/compact/hard-b.txt"
ln -s special-target.txt "$source_dir/compact/special-link"
mknod "$source_dir/compact/char-large" c 2748 344865
mknod "$source_dir/compact/block-large" b 2748 344865
mkfifo "$source_dir/compact/fifo"
ln -s target.txt "$source_dir/inline/link1"
ln -s /nonexistent/repo22-g1-target "$source_dir/inline/brokenlink"
ln -s very/long/path/to/a/deeply/nested/deterministic/target/directory/file.txt \
"$source_dir/flat/longlink"
find "$source_dir" -exec touch -h -t 197001010000.00 {} +
build_image()
{
uuid=$1
image=$2
source=$3
shift 3
mkfs.erofs -d0 -x-1 -T0 --all-time --all-root --workers=1 \
-U "$uuid" "$@" "$base_dir/$image" "$source_dir/$source"
}
build_image 31000000-0000-0000-0000-000000000001 \
compact.erofs compact -E force-inode-compact
build_image 31000000-0000-0000-0000-000000000002 \
extended.erofs extended -E force-inode-extended
build_image 31000000-0000-0000-0000-000000000003 \
flat.erofs flat -E noinline_data,force-inode-compact
build_image 31000000-0000-0000-0000-000000000004 \
inline.erofs inline -E force-inode-compact
python3 "$script_dir/g1_fixtures.py" \
--compact "$base_dir/compact.erofs" \
--extended "$base_dir/extended.erofs" \
--flat "$base_dir/flat.erofs" \
--inline "$base_dir/inline.erofs" \
--output "$image_dir"
for image in compact.erofs extended.erofs flat.erofs inline.erofs \
compact-nlink1.erofs inline-zero.erofs extended-large-hole.erofs; do
fsck.erofs "$image_dir/$image" >/dev/null
done
printf '%s\n' \
'48-bit fixtures are field/CRC checked by g1_fixtures.py;' \
'production fsck.erofs 1.8.6 does not recognize incompat feature 0x80.'
dump.erofs --cat --path=/small.txt "$image_dir/compact.erofs" |
cmp - "$source_dir/compact/small.txt"
dump.erofs --cat --path=/large-file.bin "$image_dir/extended.erofs" |
cmp - "$source_dir/extended/large-file.bin"
dump.erofs --cat --path=/medium.dat "$image_dir/flat.erofs" |
cmp - "$source_dir/flat/medium.dat"
dump.erofs --cat --path=/tailpacked.dat "$image_dir/inline.erofs" |
cmp - "$source_dir/inline/tailpacked.dat"
(
cd "$output"
find source expected -type f -print0 | sort -z | xargs -0 sha256sum
) > "$output/SOURCE-SHA256SUMS"
(
cd "$output"
find source -type l -print | sort | while IFS= read -r path; do
printf '%s -> %s\n' "$path" "$(readlink "$path")"
done
find source -type p -printf '%p type=fifo\n'
for kind in block:b char:c; do
label=${kind%:*}
type=${kind#*:}
find source -type "$type" -print | sort | while IFS= read -r path; do
set -- $(stat -c '%t %T' "$path")
printf '%s type=%s major=%d minor=%d\n' \
"$path" "$label" "$((0x$1))" "$((0x$2))"
done
done
) > "$output/SOURCE-METADATA"
(
cd "$output"
sha256sum SOURCE-METADATA
) > "$output/SOURCE-METADATA.sha256"
cat "$image_dir/fixture-evidence.txt"
cat "$output/SOURCE-SHA256SUMS"
cat "$output/SOURCE-METADATA"
cat "$image_dir/IMAGE-SHA256SUMS"