Skip to content

Commit 633b56f

Browse files
committed
Generate htree image for testing
1 parent 803c69d commit 633b56f

4 files changed

Lines changed: 107 additions & 50 deletions

File tree

.github/workflows/build.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ jobs:
4747
test32.ext4.tmp
4848
test64.ext4
4949
test64.ext4.tmp
50+
test_htree.ext4
5051
if-no-files-found: error
5152
test:
5253
name: Test on ${{ matrix.os }} python ${{ matrix.python }}

_test_image.sh

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,59 @@
11
#!/bin/bash
22
set -e
33

4+
if ! command -v chronic &>/dev/null; then
5+
chronic() {
6+
"$@"
7+
}
8+
fi
9+
10+
mkimage() {
11+
name="$1"
12+
shift
13+
dir="$1"
14+
shift
15+
size="$1"
16+
shift
17+
18+
echo "[test] Making image $name < $dir..."
19+
chronic dd if=/dev/zero of="$name".ext4.tmp count="$size" bs=1048576
20+
chronic mkfs.ext4 -g 1024 "$@" "$name".ext4.tmp -d "$dir"
21+
echo -n F >"$name".ext4
22+
cat "$name".ext4.tmp >>"$name".ext4
23+
}
24+
425
tmp_dir=$(mktemp -d)
26+
# shellcheck disable=SC2064
527
trap "rm -r \"$tmp_dir\"" EXIT
6-
echo "hello world" > "$tmp_dir"/test.txt
7-
for i in {1..1000};do
8-
echo "hello world" >> "$tmp_dir"/test.txt
9-
done
10-
for i in {1..100};do
11-
echo "hello world$i" > "$tmp_dir"/test$i.txt
12-
for j in {1..20};do
13-
setfattr -n user.name$j -v value${i}_$j "$tmp_dir"/test$i.txt
28+
echo "[test] Using temporary directory: $tmp_dir"
29+
echo "[test] Generating files..."
30+
echo "hello world" >"$tmp_dir"/test.txt
31+
for i in {1..1000}; do
32+
echo "echo "hello world" >>'$tmp_dir/test.txt'"
33+
done | xargs -P "$(nproc)" -I {} bash -c '{}'
34+
for i in {1..100}; do
35+
echo "echo 'hello world$i' >'$tmp_dir/test$i.txt'"
36+
done | xargs -P "$(nproc)" -I {} bash -c '{}'
37+
for i in {1..100}; do
38+
for j in {1..20}; do
39+
echo "setfattr -n 'user.name$j' -v 'value${i}_$j' '$tmp_dir/test$i.txt'"
1440
done
15-
done
16-
dd if=/dev/zero of=test32.ext4.tmp count=20 bs=1048576
17-
dd if=/dev/zero of=test64.ext4.tmp count=20 bs=1048576
18-
mkfs.ext4 -g 1024 -O 64bit test64.ext4.tmp -d "$tmp_dir"
19-
mkfs.ext4 -g 1024 -O ^64bit test32.ext4.tmp -d "$tmp_dir"
20-
echo -n F > test32.ext4
21-
cat test32.ext4.tmp >> test32.ext4
22-
echo -n F > test64.ext4
23-
cat test64.ext4.tmp >> test64.ext4
41+
done | xargs -P "$(nproc)" -I {} bash -c '{}'
42+
43+
mkimage test32 "$tmp_dir" 20 -O ^64bit
44+
mkimage test64 "$tmp_dir" 20 -O 64bit
45+
46+
rm -f "$tmp_dir"/test*.txt
47+
echo "[test] Generating files..."
48+
49+
echo "[test] Making image $name..."
50+
chronic dd if=/dev/zero of=test_htree.ext4 count=20 bs=1048576
51+
chronic mkfs.ext4 -g 1024 -b 1024 -N 25000 -O 64bit,dir_index test_htree.ext4
52+
sudo mount -t ext4 test_htree.ext4 "$tmp_dir"
53+
# shellcheck disable=SC2064
54+
trap "sudo umount;rmdir \"$tmp_dir\"" EXIT
55+
printf '%s\n' "$tmp_dir"/{1..20000} | xargs sudo touch
56+
sudo umount "$tmp_dir"
57+
# shellcheck disable=SC2064
58+
trap "rmdir \"$tmp_dir\"" EXIT
59+
chronic e2fsck -Dy test_htree.ext4

test.py

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import ext4
66

7+
from io import BufferedReader
78
from typing import cast
89
from typing import Callable
910
from typing import Any
@@ -41,6 +42,38 @@ def _assert(source: str, debug: Callable[[], Any] | None = None): # pyright: ig
4142
print(f" {debug()}")
4243

4344

45+
def test_magic_error(f: BufferedReader):
46+
global FAILED
47+
try:
48+
print("check MagicError: ", end="")
49+
_ = ext4.Volume(f, offset=0)
50+
FAILED = True # pyright: ignore[reportConstantRedefinition]
51+
print("fail")
52+
print(" MagicError not raised")
53+
except ext4.struct.MagicError:
54+
print("pass")
55+
56+
except Exception as e:
57+
FAILED = True # pyright: ignore[reportConstantRedefinition]
58+
print("fail")
59+
print(" ", end="")
60+
print(e)
61+
62+
63+
def test_root_inode(volume: ext4.Volume):
64+
global FAILED
65+
try:
66+
print("Validate root inode: ", end="")
67+
volume.root.validate()
68+
print("pass")
69+
70+
except ext4.struct.ChecksumError as e:
71+
FAILED = True # pyright: ignore[reportConstantRedefinition]
72+
print("fail")
73+
print(" ", end="")
74+
print(e)
75+
76+
4477
print("check ext4.Volume stream validation: ", end="")
4578
try:
4679
_ = ext4.Volume(1) # pyright: ignore[reportArgumentType]
@@ -64,37 +97,17 @@ def _assert(source: str, debug: Callable[[], Any] | None = None): # pyright: ig
6497
test_path_tuple(b"/test/test", (b"test", b"test"))
6598

6699
for img_file in ("test32.ext4", "test64.ext4"):
100+
print(f"Testing image: {img_file}")
67101
offset = os.path.getsize(img_file) - os.path.getsize(f"{img_file}.tmp")
68-
_assert("offset > 0")
69-
with open(img_file, "rb") as f:
70-
try:
71-
print("check MagicError: ", end="")
72-
_ = ext4.Volume(f, offset=0)
73-
FAILED = True # pyright: ignore[reportConstantRedefinition]
74-
print("fail")
75-
print(" MagicError not raised")
76-
except ext4.struct.MagicError:
77-
print("pass")
78-
79-
except Exception as e:
80-
FAILED = True # pyright: ignore[reportConstantRedefinition]
81-
print("fail")
82-
print(" ", end="")
83-
print(e)
84-
85-
# Extract specific file
86-
volume = ext4.Volume(f, offset=offset)
102+
_assert("offset > 0", lambda: offset)
103+
if offset < 0:
104+
continue
87105

88-
try:
89-
print("Validate root inode: ", end="")
90-
volume.root.validate()
91-
print("pass")
106+
with open(img_file, "rb") as f:
107+
test_magic_error(f)
92108

93-
except ext4.struct.ChecksumError as e:
94-
FAILED = True # pyright: ignore[reportConstantRedefinition]
95-
print("fail")
96-
print(" ", end="")
97-
print(e)
109+
volume = ext4.Volume(f, offset=offset)
110+
test_root_inode(volume)
98111

99112
inode = cast(ext4.File, volume.inode_at("/test.txt"))
100113
_assert("isinstance(inode, ext4.File)")
@@ -124,5 +137,12 @@ def _assert(source: str, debug: Callable[[], Any] | None = None): # pyright: ig
124137
_ = b.seek(0)
125138
_assert(f"b.read({x}) == {data[:x]}", lambda: b.seek(0) == 0 and b.read(x))
126139

140+
img_file = "test_htree.ext4"
141+
print(f"Testing image: {img_file}")
142+
with open(img_file, "rb") as f:
143+
volume = ext4.Volume(f)
144+
_assert("volume.root.is_htree")
145+
test_root_inode(volume)
146+
127147
if FAILED:
128148
sys.exit(1)

test.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#!/bin/bash
22
set -e
3-
if ! [ -d .venv ];then
3+
if ! [ -d .venv ]; then
44
python -m venv .venv
55
fi
66
if [ -f .venv/Scripts/activate ]; then
7-
. .venv/Scripts/activate
7+
source .venv/Scripts/activate
88
elif [ -f .venv/bin/activate ]; then
9-
. .venv/bin/activate
9+
source .venv/bin/activate
1010
else
1111
echo "venv missing"
1212
exit 1
@@ -15,8 +15,8 @@ python -m pip install wheel
1515
python -m pip install \
1616
--extra-index-url=https://wheels.eeems.codes/ \
1717
-r requirements.txt
18-
if ! [ -f test32.ext4 ] || ! [ -f test32.ext4.tmp ] || ! [ -f test64.ext4 ] || ! [ -f test64.ext4.tmp ] ;then
18+
if [ ! -f test32.ext4 ] || [ ! -f test32.ext4.tmp ] || [ ! -f test64.ext4 ] || [ ! -f test64.ext4.tmp ] || [ ! -f test_htree.ext4 ]; then
1919
./_test_image.sh
20-
trap "rm -f test{32,64}.ext4{,.tmp}" EXIT
20+
trap "rm -f test{32,64,_htree}.ext4{,.tmp}" EXIT
2121
fi
2222
python test.py

0 commit comments

Comments
 (0)