Skip to content

Commit a0d94e1

Browse files
committed
Add algorithm-specific test cases
1 parent 0eef9cb commit a0d94e1

5 files changed

Lines changed: 792 additions & 0 deletions

File tree

test/README_ALGORITHM_TESTS.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Algorithm-Specific Test Suites
2+
3+
This directory contains individual test scripts for validating otezip's compression algorithm implementations against system binaries and reference implementations.
4+
5+
## Test Scripts
6+
7+
### test-deflate.sh
8+
Tests the DEFLATE compression algorithm implementation against gzip (system deflate reference).
9+
10+
**Tests:**
11+
- `test_otezip_deflate_extraction()` - Round-trip compression/decompression with otezip
12+
- `test_otezip_deflate_system_unzip()` - Compatibility with system unzip
13+
- `test_compression_ratio()` - Compression ratio comparison with gzip
14+
- `test_corner_cases()` - Empty files, single bytes, etc.
15+
- `test_method_field()` - Verify ZIP method field (0x0008)
16+
17+
**Run:** `bash test/test-deflate.sh`
18+
19+
### test-zstd.sh
20+
Tests the ZSTD compression algorithm implementation against the system zstd binary.
21+
22+
**Tests:**
23+
- `test_otezip_zstd_extraction()` - Round-trip compression/decompression
24+
- `test_compression_comparison()` - Ratio comparison with system zstd
25+
- `test_interop_decompress()` - Interoperability checks
26+
- `test_compression_levels()` - Compression level testing
27+
- `test_corner_cases()` - Empty, single byte, 5MB random file
28+
- `test_method_field()` - Verify ZIP method field (0x005D/93)
29+
30+
**Run:** `bash test/test-zstd.sh`
31+
32+
### test-lzma.sh
33+
Tests the LZMA compression algorithm implementation against xz (LZMA reference).
34+
35+
**Tests:**
36+
- `test_otezip_lzma_extraction()` - Round-trip compression/decompression
37+
- `test_7z_lzma_extraction()` - Compatibility with 7z-created LZMA archives
38+
- `test_compression_comparison()` - Ratio comparison with system xz
39+
- `test_random_data()` - Incompressible data handling
40+
- `test_corner_cases()` - Empty, single byte, 1MB random file
41+
- `test_mixed_content()` - Multiple file types in one archive
42+
- `test_method_field()` - Verify ZIP method field (0x000E/14)
43+
44+
**Run:** `bash test/test-lzma.sh`
45+
46+
## Method IDs
47+
48+
- STORE: 0
49+
- DEFLATE: 8
50+
- LZMA: 14
51+
- ZSTD: 93
52+
- Brotli: 97
53+
- LZFSE: 100
54+
55+
## System Requirements
56+
57+
- gzip (for DEFLATE comparison)
58+
- zstd (for ZSTD comparison)
59+
- xz (for LZMA/xz comparison)
60+
- 7z (optional, for LZMA 7z compatibility tests)
61+
- unzip (for standard ZIP extraction compatibility)
62+
63+
Install on macOS:
64+
```
65+
brew install zstd xz
66+
# gzip comes with system
67+
```
68+
69+
## Test Coverage
70+
71+
These tests ensure that otezip's compression implementations:
72+
73+
1. **Correctly compress and decompress files** - Round-trip integrity tests
74+
2. **Produce valid ZIP archives** - Compatible with system unzip
75+
3. **Match compression ratios** - Comparable to reference implementations
76+
4. **Handle edge cases** - Empty files, single bytes, various sizes
77+
5. **Maintain format compatibility** - Proper ZIP method field encoding
78+
6. **Interoperate with other tools** - Extract files created by 7z, etc.
79+
80+
## Known Issues
81+
82+
- Some large repetitive files (>100KB) with deflate have extraction issues
83+
- Very large LZMA files (>10MB) with 7z have compatibility issues
84+
- Compression ratio calculations in scripts may have minor parsing issues on macOS
85+
86+
## Integration with Main Test Suite
87+
88+
The main test suite (`test.sh`) tests all algorithms together. These individual scripts provide deeper, algorithm-specific validation and debugging capabilities.

test/test-deflate.sh

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
#!/bin/sh
2+
3+
# Test DEFLATE compression algorithm against system gzip implementation
4+
# This script compares otezip's deflate with gzip to ensure compatibility
5+
6+
D=tmp_deflate
7+
MZ=$(pwd)/../otezip
8+
if [ ! -x "${MZ}" ]; then
9+
make -C .. >/dev/null 2>&1
10+
fi
11+
12+
init() {
13+
rm -rf "$D" && mkdir -p "$D" && cd "$D"
14+
15+
# Create test files
16+
printf "hello world\n" > test1.txt
17+
dd if=/dev/urandom of=test_binary.bin bs=1k count=10 2>/dev/null
18+
19+
# Create a repetitive file (should compress well)
20+
python3 -c "print('A' * 5000)" > test_repetitive.txt 2>/dev/null || \
21+
perl -e 'print "A" x 5000' > test_repetitive.txt 2>/dev/null || \
22+
(i=0; while [ $i -lt 5000 ]; do printf "A"; i=$((i+1)); done) > test_repetitive.txt
23+
24+
echo "[DEFLATE] Test files created:"
25+
ls -la
26+
}
27+
28+
fini() {
29+
cd ..
30+
rm -rf "$D"
31+
}
32+
33+
error() {
34+
echo "ERROR: $@" >&2
35+
exit 1
36+
}
37+
38+
# Test 1: Create ZIP with otezip deflate, extract and verify with system
39+
test_otezip_deflate_extraction() {
40+
init
41+
echo "[TEST 1] otezip deflate creation + otezip extraction"
42+
43+
$MZ -c archive.zip test1.txt test_binary.bin test_repetitive.txt -z deflate || \
44+
error "otezip creation failed"
45+
46+
echo "[+] Created archive with otezip (deflate)"
47+
$MZ -l archive.zip
48+
49+
mkdir -p extract_otezip
50+
cd extract_otezip
51+
$MZ -x ../archive.zip > /dev/null || error "otezip extraction failed"
52+
53+
# Verify extracted files match originals
54+
cmp -s test1.txt ../test1.txt || error "test1.txt mismatch after otezip extract"
55+
cmp -s test_binary.bin ../test_binary.bin || error "test_binary.bin mismatch after otezip extract"
56+
cmp -s test_repetitive.txt ../test_repetitive.txt || error "test_repetitive.txt mismatch after otezip extract"
57+
58+
echo "[+] All files extracted correctly by otezip"
59+
cd ..
60+
61+
fini
62+
echo "[PASS] Test 1: otezip deflate round-trip"
63+
}
64+
65+
# Test 2: Create ZIP with otezip deflate, verify with system unzip
66+
test_otezip_deflate_system_unzip() {
67+
init
68+
echo "[TEST 2] otezip deflate creation + system unzip extraction"
69+
70+
$MZ -c archive.zip test1.txt test_binary.bin test_repetitive.txt -z deflate || \
71+
error "otezip creation failed"
72+
73+
echo "[+] Created archive with otezip (deflate)"
74+
$MZ -l archive.zip
75+
76+
mkdir -p extract_unzip
77+
cd extract_unzip
78+
unzip -q ../archive.zip || error "system unzip extraction failed"
79+
80+
# Verify extracted files match originals
81+
cmp -s test1.txt ../test1.txt || error "test1.txt mismatch after system unzip"
82+
cmp -s test_binary.bin ../test_binary.bin || error "test_binary.bin mismatch after system unzip"
83+
cmp -s test_repetitive.txt ../test_repetitive.txt || error "test_repetitive.txt mismatch after system unzip"
84+
85+
echo "[+] All files extracted correctly by system unzip"
86+
cd ..
87+
88+
fini
89+
echo "[PASS] Test 2: otezip deflate compatible with system unzip"
90+
}
91+
92+
# Test 3: Compare compression ratio with gzip
93+
test_compression_ratio() {
94+
init
95+
echo "[TEST 3] Compression ratio comparison with gzip"
96+
97+
original_size=$(wc -c < test_repetitive.txt)
98+
echo "[*] Original repetitive file size: $original_size bytes"
99+
100+
# otezip deflate compression
101+
$MZ -c archive_otezip.zip test_repetitive.txt -z deflate || \
102+
error "otezip creation failed"
103+
104+
# Get the compressed size from the ZIP local header
105+
otezip_compressed=$(unzip -l archive_otezip.zip | grep test_repetitive | awk '{print $4}')
106+
otezip_zip_size=$(wc -c < archive_otezip.zip)
107+
echo "[*] otezip ZIP file size: $otezip_zip_size bytes (compressed: $otezip_compressed bytes)"
108+
109+
# gzip compression for comparison
110+
gzip -k test_repetitive.txt
111+
gzip_size=$(wc -c < test_repetitive.txt.gz)
112+
echo "[*] gzip file size: $gzip_size bytes"
113+
114+
# Calculate compression ratios
115+
echo "[*] Compression ratios:"
116+
echo " otezip deflate: $(echo "scale=2; $original_size / $otezip_compressed" | bc)x"
117+
echo " gzip deflate: $(echo "scale=2; $original_size / $gzip_size" | bc)x"
118+
119+
fini
120+
echo "[PASS] Test 3: Compression ratio comparison"
121+
}
122+
123+
# Test 4: Corner cases
124+
test_corner_cases() {
125+
init
126+
echo "[TEST 4] DEFLATE corner cases"
127+
128+
# Empty file
129+
: > empty.txt
130+
$MZ -c archive.zip empty.txt -z deflate || error "failed on empty file"
131+
mkdir -p extract && cd extract
132+
$MZ -x ../archive.zip > /dev/null || error "extraction of empty failed"
133+
[ -f empty.txt ] || error "empty.txt not extracted"
134+
[ ! -s empty.txt ] || error "empty.txt should be empty"
135+
cd .. && rm -rf extract
136+
echo "[+] Empty file handling: OK"
137+
138+
# Single byte
139+
printf "X" > single.bin
140+
$MZ -c archive.zip single.bin -z deflate || error "failed on single byte"
141+
mkdir -p extract && cd extract
142+
$MZ -x ../archive.zip > /dev/null || error "extraction of single byte failed"
143+
cmp -s single.bin ../single.bin || error "single byte mismatch"
144+
cd .. && rm -rf extract
145+
echo "[+] Single byte handling: OK"
146+
147+
fini
148+
echo "[PASS] Test 4: DEFLATE corner cases"
149+
}
150+
151+
# Test 5: Verify internal compression method field
152+
test_method_field() {
153+
init
154+
echo "[TEST 5] Verify DEFLATE method field in ZIP"
155+
156+
$MZ -c archive.zip test1.txt -z deflate || error "otezip creation failed"
157+
158+
# Method 8 is DEFLATE (0x08 in hex)
159+
# Check local file header compression method
160+
method=$(xxd -p archive.zip | head -c 200 | grep -o '0800' | head -1)
161+
if [ -n "$method" ]; then
162+
echo "[+] DEFLATE method field (0x0008) found in archive"
163+
else
164+
echo "[!] Warning: Could not verify DEFLATE method field, but archive works"
165+
fi
166+
167+
fini
168+
echo "[PASS] Test 5: Method field verification"
169+
}
170+
171+
# Run all tests
172+
echo "=================================================="
173+
echo "DEFLATE Compression Algorithm Test Suite"
174+
echo "Testing otezip against gzip/system unzip"
175+
echo "=================================================="
176+
177+
test_otezip_deflate_extraction || exit 1
178+
test_otezip_deflate_system_unzip || exit 1
179+
test_compression_ratio
180+
test_corner_cases || exit 1
181+
test_method_field || exit 1
182+
183+
echo ""
184+
echo "=================================================="
185+
echo "All DEFLATE tests passed!"
186+
echo "=================================================="

0 commit comments

Comments
 (0)