mirror of
https://github.com/JotaRandom/hfsutils.git
synced 2026-04-21 11:17:01 +00:00
i missed some stuff
This commit is contained in:
@@ -1,160 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Test script for mkfs.hfs functionality
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Testing mkfs.hfs functionality ==="
|
||||
echo
|
||||
|
||||
# Set paths
|
||||
MKFS_HFS="./build/standalone/mkfs.hfs"
|
||||
MKFS_HFS_PLUS="./build/standalone/mkfs.hfs+"
|
||||
MKFS_HFSPLUS="./build/standalone/mkfs.hfsplus"
|
||||
|
||||
# Test basic functionality
|
||||
echo "1. Testing basic functionality..."
|
||||
|
||||
# Test version
|
||||
echo " Testing version information:"
|
||||
$MKFS_HFS --version
|
||||
echo
|
||||
|
||||
# Test help
|
||||
echo " Testing help:"
|
||||
$MKFS_HFS --help | head -5
|
||||
echo
|
||||
|
||||
# Test different program names
|
||||
echo "2. Testing different program names..."
|
||||
echo " mkfs.hfs:"
|
||||
$MKFS_HFS --version | head -1
|
||||
|
||||
echo " mkfs.hfs+:"
|
||||
$MKFS_HFS_PLUS --version | head -1
|
||||
|
||||
echo " mkfs.hfsplus:"
|
||||
$MKFS_HFSPLUS --version | head -1
|
||||
echo
|
||||
|
||||
# Test formatting
|
||||
echo "3. Testing HFS formatting..."
|
||||
|
||||
# Create test images
|
||||
TEST_IMAGE1="/tmp/test_hfs1.img"
|
||||
TEST_IMAGE2="/tmp/test_hfs2.img"
|
||||
TEST_IMAGE3="/tmp/test_hfsplus.img"
|
||||
|
||||
echo " Creating basic HFS volume:"
|
||||
$MKFS_HFS -v -l "Test Volume" "$TEST_IMAGE1"
|
||||
|
||||
echo " Verifying HFS signature:"
|
||||
if hexdump -C "$TEST_IMAGE1" | head -1 | grep -q "4c 4b"; then
|
||||
echo " ✓ Boot block signature correct (LK)"
|
||||
else
|
||||
echo " ✗ Boot block signature incorrect"
|
||||
fi
|
||||
|
||||
if hexdump -C "$TEST_IMAGE1" | grep "42 44" | head -1 > /dev/null; then
|
||||
echo " ✓ MDB signature correct (BD)"
|
||||
else
|
||||
echo " ✗ MDB signature incorrect"
|
||||
fi
|
||||
|
||||
if hexdump -C "$TEST_IMAGE1" | grep -q "Test Volume"; then
|
||||
echo " ✓ Volume name correctly written"
|
||||
else
|
||||
echo " ✗ Volume name not found"
|
||||
fi
|
||||
|
||||
echo " Creating HFS+ volume:"
|
||||
rm -f "$TEST_IMAGE3" # Clean up first
|
||||
$MKFS_HFS_PLUS -v -l "HFS+ Test" "$TEST_IMAGE3"
|
||||
|
||||
echo " Verifying HFS+ signature:"
|
||||
if hexdump -C "$TEST_IMAGE3" | head -1 | grep -q "4c 4b"; then
|
||||
echo " ✓ Boot block signature correct (LK)"
|
||||
else
|
||||
echo " ✗ Boot block signature incorrect"
|
||||
fi
|
||||
|
||||
if hexdump -C "$TEST_IMAGE3" | grep "48 2b" | head -1 > /dev/null; then
|
||||
echo " ✓ HFS+ Volume Header signature correct (H+)"
|
||||
else
|
||||
echo " ✗ HFS+ Volume Header signature incorrect"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test error conditions
|
||||
echo "4. Testing error conditions..."
|
||||
|
||||
echo " Testing missing device argument:"
|
||||
if $MKFS_HFS 2>/dev/null; then
|
||||
echo " ✗ Should fail with missing device"
|
||||
else
|
||||
echo " ✓ Correctly rejects missing device"
|
||||
fi
|
||||
|
||||
echo " Testing volume name too long:"
|
||||
if $MKFS_HFS -l "This volume name is way too long for HFS specification" "$TEST_IMAGE2" 2>/dev/null; then
|
||||
echo " ✗ Should fail with long volume name"
|
||||
else
|
||||
echo " ✓ Correctly rejects long volume name"
|
||||
fi
|
||||
|
||||
echo " Testing existing file without force:"
|
||||
if $MKFS_HFS "$TEST_IMAGE1" 2>/dev/null; then
|
||||
echo " ✗ Should fail without force flag"
|
||||
else
|
||||
echo " ✓ Correctly requires force flag for existing file"
|
||||
fi
|
||||
|
||||
echo " Testing force flag:"
|
||||
$MKFS_HFS -f -l "Forced" "$TEST_IMAGE1"
|
||||
echo " ✓ Force flag works correctly"
|
||||
|
||||
echo
|
||||
|
||||
# Test different volume names
|
||||
echo "5. Testing volume name handling..."
|
||||
|
||||
echo " Single character name:"
|
||||
$MKFS_HFS -l "A" "$TEST_IMAGE2"
|
||||
echo " ✓ Single character name works"
|
||||
|
||||
echo " Maximum length name (27 chars):"
|
||||
$MKFS_HFS -f -l "abcdefghijklmnopqrstuvwxyz1" "$TEST_IMAGE2"
|
||||
echo " ✓ Maximum length name works"
|
||||
|
||||
echo " Name with spaces:"
|
||||
$MKFS_HFS -f -l "My Test Volume" "$TEST_IMAGE2"
|
||||
echo " ✓ Name with spaces works"
|
||||
|
||||
echo
|
||||
|
||||
# Performance test
|
||||
echo "6. Testing performance..."
|
||||
echo " Creating 1MB volume:"
|
||||
time $MKFS_HFS -f -l "Speed Test" "$TEST_IMAGE2" 2>/dev/null
|
||||
echo " ✓ Performance test completed"
|
||||
|
||||
echo
|
||||
|
||||
# Cleanup
|
||||
echo "7. Cleaning up..."
|
||||
rm -f "$TEST_IMAGE1" "$TEST_IMAGE2" "$TEST_IMAGE3"
|
||||
echo " ✓ Test files cleaned up"
|
||||
|
||||
echo
|
||||
echo "=== All tests completed successfully! ==="
|
||||
echo
|
||||
echo "Summary:"
|
||||
echo "✓ Basic functionality works"
|
||||
echo "✓ Program name detection works"
|
||||
echo "✓ HFS formatting creates correct structures"
|
||||
echo "✓ HFS+ formatting creates correct structures"
|
||||
echo "✓ Error handling works correctly"
|
||||
echo "✓ Volume name validation works"
|
||||
echo "✓ Performance is acceptable"
|
||||
echo
|
||||
echo "mkfs.hfs and mkfs.hfs+ are ready for basic testing!"
|
||||
@@ -1,434 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Comprehensive test suite for mkfs.hfs with realistic disk sizes
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() {
|
||||
echo -e "${BLUE}INFO:${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}SUCCESS:${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}WARNING:${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}ERROR:${NC} $1"
|
||||
}
|
||||
|
||||
# Set paths
|
||||
MKFS_HFS="./build/standalone/mkfs.hfs"
|
||||
MKFS_HFS_PLUS="./build/standalone/mkfs.hfs+"
|
||||
MKFS_HFSPLUS="./build/standalone/mkfs.hfsplus"
|
||||
|
||||
# Test images with historically accurate sizes
|
||||
FLOPPY_IMG="/tmp/test_floppy_1.44mb.img" # 1.44MB - Mac floppy disk
|
||||
INTRO_IMG="/tmp/test_intro_20mb.img" # 20MB - Introductory hard disk
|
||||
QUADRA_IMG="/tmp/test_quadra_80mb.img" # 80MB - Quadra hard disk
|
||||
|
||||
# Size constants (in bytes)
|
||||
FLOPPY_SIZE=$((1440 * 1024)) # 1.44MB
|
||||
INTRO_SIZE=$((20 * 1024 * 1024)) # 20MB
|
||||
QUADRA_SIZE=$((80 * 1024 * 1024)) # 80MB
|
||||
|
||||
echo "=== Comprehensive mkfs.hfs Test Suite ==="
|
||||
echo "Testing with historically accurate Mac disk sizes"
|
||||
echo
|
||||
|
||||
# Function to create disk image of specific size
|
||||
create_disk_image() {
|
||||
local image_path="$1"
|
||||
local size_bytes="$2"
|
||||
local description="$3"
|
||||
|
||||
log_info "Creating $description disk image: $image_path ($size_bytes bytes)"
|
||||
dd if=/dev/zero of="$image_path" bs=1024 count=$((size_bytes / 1024)) 2>/dev/null
|
||||
|
||||
if [[ ! -f "$image_path" ]]; then
|
||||
log_error "Failed to create disk image: $image_path"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local actual_size=$(stat -c%s "$image_path" 2>/dev/null || stat -f%z "$image_path" 2>/dev/null)
|
||||
log_success "Created $description: $actual_size bytes"
|
||||
}
|
||||
|
||||
# Function to verify HFS signature
|
||||
verify_hfs_signature() {
|
||||
local image_path="$1"
|
||||
local expected_fs="$2"
|
||||
|
||||
log_info "Verifying filesystem signatures in $image_path"
|
||||
|
||||
# Check boot blocks (LK signature)
|
||||
if hexdump -C "$image_path" | head -1 | grep -q "4c 4b"; then
|
||||
log_success "✓ Boot block signature correct (LK)"
|
||||
else
|
||||
log_error "✗ Boot block signature incorrect"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check filesystem signature
|
||||
if [[ "$expected_fs" == "HFS" ]]; then
|
||||
if hexdump -C "$image_path" | grep "42 44" | head -1 > /dev/null; then
|
||||
log_success "✓ HFS Master Directory Block signature correct (BD)"
|
||||
else
|
||||
log_error "✗ HFS MDB signature incorrect"
|
||||
return 1
|
||||
fi
|
||||
elif [[ "$expected_fs" == "HFS+" ]]; then
|
||||
if hexdump -C "$image_path" | grep "48 2b" | head -1 > /dev/null; then
|
||||
log_success "✓ HFS+ Volume Header signature correct (H+)"
|
||||
else
|
||||
log_error "✗ HFS+ Volume Header signature incorrect"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to analyze filesystem structure
|
||||
analyze_filesystem() {
|
||||
local image_path="$1"
|
||||
local fs_type="$2"
|
||||
|
||||
log_info "Analyzing $fs_type filesystem structure"
|
||||
|
||||
# Show first few blocks
|
||||
echo "First 32 bytes (boot block):"
|
||||
hexdump -C "$image_path" | head -2
|
||||
|
||||
echo
|
||||
echo "Volume header/MDB (offset 0x400):"
|
||||
hexdump -C "$image_path" -s 0x400 | head -4
|
||||
|
||||
# Check for volume name if HFS
|
||||
if [[ "$fs_type" == "HFS" ]]; then
|
||||
echo
|
||||
echo "Volume name area (offset 0x424):"
|
||||
hexdump -C "$image_path" -s 0x424 -n 32
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
# Function to test command-line options
|
||||
test_command_options() {
|
||||
local mkfs_cmd="$1"
|
||||
local test_img="$2"
|
||||
local fs_type="$3"
|
||||
|
||||
log_info "Testing command-line options for $fs_type"
|
||||
|
||||
# Test -v (verbose) option
|
||||
log_info "Testing -v (verbose) option"
|
||||
rm -f "$test_img"
|
||||
|
||||
# Create test image and check size before formatting
|
||||
dd if=/dev/zero of="$test_img" bs=1024 count=10240 2>/dev/null
|
||||
local size_before=$(stat -c%s "$test_img" 2>/dev/null || stat -f%z "$test_img" 2>/dev/null)
|
||||
log_info "File size before formatting: $size_before bytes"
|
||||
|
||||
if $mkfs_cmd -f -v -l "Verbose Test" "$test_img" | grep -q "successfully"; then
|
||||
log_success "✓ Verbose option works"
|
||||
|
||||
# Check size after formatting
|
||||
local size_after=$(stat -c%s "$test_img" 2>/dev/null || stat -f%z "$test_img" 2>/dev/null)
|
||||
log_info "File size after formatting: $size_after bytes"
|
||||
|
||||
if [[ "$size_before" -eq "$size_after" ]]; then
|
||||
log_success "✓ File size preserved during formatting"
|
||||
else
|
||||
log_error "✗ File size changed! Before: $size_before, After: $size_after"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "✗ Verbose option failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test -f (force) option
|
||||
log_info "Testing -f (force) option"
|
||||
local size_before_force=$(stat -c%s "$test_img" 2>/dev/null || stat -f%z "$test_img" 2>/dev/null)
|
||||
log_info "File size before force formatting: $size_before_force bytes"
|
||||
|
||||
if $mkfs_cmd -f -l "Force Test" "$test_img" >/dev/null 2>&1; then
|
||||
log_success "✓ Force option works"
|
||||
|
||||
# Check size after force formatting
|
||||
local size_after_force=$(stat -c%s "$test_img" 2>/dev/null || stat -f%z "$test_img" 2>/dev/null)
|
||||
log_info "File size after force formatting: $size_after_force bytes"
|
||||
|
||||
if [[ "$size_before_force" -eq "$size_after_force" ]]; then
|
||||
log_success "✓ File size preserved during force formatting"
|
||||
else
|
||||
log_error "✗ File size changed during force formatting! Before: $size_before_force, After: $size_after_force"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "✗ Force option failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test -l (label) option with various names
|
||||
log_info "Testing -l (label) option"
|
||||
|
||||
# Short name
|
||||
rm -f "$test_img"
|
||||
if $mkfs_cmd -l "A" "$test_img" >/dev/null 2>&1; then
|
||||
log_success "✓ Short label works"
|
||||
else
|
||||
log_error "✗ Short label failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Long name (27 chars - HFS limit)
|
||||
rm -f "$test_img"
|
||||
if $mkfs_cmd -l "abcdefghijklmnopqrstuvwxyz1" "$test_img" >/dev/null 2>&1; then
|
||||
log_success "✓ Maximum length label works"
|
||||
else
|
||||
log_error "✗ Maximum length label failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Name with spaces
|
||||
rm -f "$test_img"
|
||||
if $mkfs_cmd -l "Test Volume Name" "$test_img" >/dev/null 2>&1; then
|
||||
log_success "✓ Label with spaces works"
|
||||
else
|
||||
log_error "✗ Label with spaces failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test invalid options (should fail)
|
||||
log_info "Testing error conditions"
|
||||
|
||||
# Too long name (should fail)
|
||||
if $mkfs_cmd -l "This volume name is way too long for HFS specification" "$test_img" >/dev/null 2>&1; then
|
||||
log_error "✗ Should reject too long volume name"
|
||||
return 1
|
||||
else
|
||||
log_success "✓ Correctly rejects too long volume name"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup_test_images() {
|
||||
log_info "Cleaning up test images"
|
||||
rm -f "$FLOPPY_IMG" "$INTRO_IMG" "$QUADRA_IMG"
|
||||
log_success "Test images cleaned up"
|
||||
}
|
||||
|
||||
# Main test execution
|
||||
main() {
|
||||
echo "1. Creating test disk images..."
|
||||
|
||||
# Create historically accurate disk images
|
||||
create_disk_image "$FLOPPY_IMG" "$FLOPPY_SIZE" "1.44MB floppy disk"
|
||||
create_disk_image "$INTRO_IMG" "$INTRO_SIZE" "20MB introductory hard disk"
|
||||
create_disk_image "$QUADRA_IMG" "$QUADRA_SIZE" "80MB Quadra hard disk"
|
||||
|
||||
echo
|
||||
echo "2. Testing 1.44MB floppy disk with HFS..."
|
||||
|
||||
# Check size before formatting
|
||||
local floppy_size_before=$(stat -c%s "$FLOPPY_IMG" 2>/dev/null || stat -f%z "$FLOPPY_IMG" 2>/dev/null)
|
||||
log_info "Floppy size before formatting: $floppy_size_before bytes"
|
||||
|
||||
# Format floppy as HFS
|
||||
log_info "Formatting 1.44MB floppy as HFS"
|
||||
$MKFS_HFS -f -v -l "Floppy Disk" "$FLOPPY_IMG"
|
||||
|
||||
# Check size after formatting
|
||||
local floppy_size_after=$(stat -c%s "$FLOPPY_IMG" 2>/dev/null || stat -f%z "$FLOPPY_IMG" 2>/dev/null)
|
||||
log_info "Floppy size after formatting: $floppy_size_after bytes"
|
||||
|
||||
if [[ "$floppy_size_before" -eq "$floppy_size_after" ]]; then
|
||||
log_success "✓ Floppy disk size preserved during HFS formatting"
|
||||
else
|
||||
log_error "✗ Floppy disk size changed! Before: $floppy_size_before, After: $floppy_size_after"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify and analyze
|
||||
verify_hfs_signature "$FLOPPY_IMG" "HFS"
|
||||
analyze_filesystem "$FLOPPY_IMG" "HFS"
|
||||
|
||||
# Test command options on floppy
|
||||
test_command_options "$MKFS_HFS" "$FLOPPY_IMG" "HFS"
|
||||
|
||||
echo
|
||||
echo "3. Testing 20MB introductory disk with HFS..."
|
||||
|
||||
# Check size before formatting
|
||||
local intro_size_before=$(stat -c%s "$INTRO_IMG" 2>/dev/null || stat -f%z "$INTRO_IMG" 2>/dev/null)
|
||||
log_info "20MB disk size before HFS formatting: $intro_size_before bytes"
|
||||
|
||||
# Format 20MB disk as HFS
|
||||
log_info "Formatting 20MB disk as HFS"
|
||||
$MKFS_HFS -f -v -l "Intro Disk" "$INTRO_IMG"
|
||||
|
||||
# Check size after formatting
|
||||
local intro_size_after=$(stat -c%s "$INTRO_IMG" 2>/dev/null || stat -f%z "$INTRO_IMG" 2>/dev/null)
|
||||
log_info "20MB disk size after HFS formatting: $intro_size_after bytes"
|
||||
|
||||
if [[ "$intro_size_before" -eq "$intro_size_after" ]]; then
|
||||
log_success "✓ 20MB disk size preserved during HFS formatting"
|
||||
else
|
||||
log_error "✗ 20MB disk size changed! Before: $intro_size_before, After: $intro_size_after"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify and analyze
|
||||
verify_hfs_signature "$INTRO_IMG" "HFS"
|
||||
analyze_filesystem "$INTRO_IMG" "HFS"
|
||||
|
||||
echo
|
||||
echo "4. Testing 20MB introductory disk with HFS+..."
|
||||
|
||||
# Check size before formatting
|
||||
local intro_hfsplus_size_before=$(stat -c%s "$INTRO_IMG" 2>/dev/null || stat -f%z "$INTRO_IMG" 2>/dev/null)
|
||||
log_info "20MB disk size before HFS+ formatting: $intro_hfsplus_size_before bytes"
|
||||
|
||||
# Format 20MB disk as HFS+
|
||||
log_info "Formatting 20MB disk as HFS+"
|
||||
$MKFS_HFS_PLUS -f -v -l "Intro HFS+" "$INTRO_IMG"
|
||||
|
||||
# Check size after formatting
|
||||
local intro_hfsplus_size_after=$(stat -c%s "$INTRO_IMG" 2>/dev/null || stat -f%z "$INTRO_IMG" 2>/dev/null)
|
||||
log_info "20MB disk size after HFS+ formatting: $intro_hfsplus_size_after bytes"
|
||||
|
||||
if [[ "$intro_hfsplus_size_before" -eq "$intro_hfsplus_size_after" ]]; then
|
||||
log_success "✓ 20MB disk size preserved during HFS+ formatting"
|
||||
else
|
||||
log_error "✗ 20MB disk size changed! Before: $intro_hfsplus_size_before, After: $intro_hfsplus_size_after"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify and analyze
|
||||
verify_hfs_signature "$INTRO_IMG" "HFS+"
|
||||
analyze_filesystem "$INTRO_IMG" "HFS+"
|
||||
|
||||
# Test command options on HFS+
|
||||
test_command_options "$MKFS_HFS_PLUS" "$INTRO_IMG" "HFS+"
|
||||
|
||||
echo
|
||||
echo "5. Testing 80MB Quadra disk with HFS+..."
|
||||
|
||||
# Check size before formatting
|
||||
local quadra_size_before=$(stat -c%s "$QUADRA_IMG" 2>/dev/null || stat -f%z "$QUADRA_IMG" 2>/dev/null)
|
||||
log_info "80MB Quadra disk size before HFS+ formatting: $quadra_size_before bytes"
|
||||
|
||||
# Format 80MB disk as HFS+
|
||||
log_info "Formatting 80MB Quadra disk as HFS+"
|
||||
$MKFS_HFS_PLUS -f -v -l "Quadra Disk" "$QUADRA_IMG"
|
||||
|
||||
# Check size after formatting
|
||||
local quadra_size_after=$(stat -c%s "$QUADRA_IMG" 2>/dev/null || stat -f%z "$QUADRA_IMG" 2>/dev/null)
|
||||
log_info "80MB Quadra disk size after HFS+ formatting: $quadra_size_after bytes"
|
||||
|
||||
if [[ "$quadra_size_before" -eq "$quadra_size_after" ]]; then
|
||||
log_success "✓ 80MB Quadra disk size preserved during HFS+ formatting"
|
||||
else
|
||||
log_error "✗ 80MB Quadra disk size changed! Before: $quadra_size_before, After: $quadra_size_after"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify and analyze
|
||||
verify_hfs_signature "$QUADRA_IMG" "HFS+"
|
||||
analyze_filesystem "$QUADRA_IMG" "HFS+"
|
||||
|
||||
echo
|
||||
echo "6. Performance testing..."
|
||||
|
||||
# Performance test with different sizes
|
||||
log_info "Performance testing with different disk sizes"
|
||||
|
||||
echo "Floppy (1.44MB) format time:"
|
||||
time $MKFS_HFS -f -l "Perf Test" "$FLOPPY_IMG" 2>/dev/null
|
||||
|
||||
echo "20MB disk format time:"
|
||||
time $MKFS_HFS_PLUS -f -l "Perf Test" "$INTRO_IMG" 2>/dev/null
|
||||
|
||||
echo "80MB disk format time:"
|
||||
time $MKFS_HFS_PLUS -f -l "Perf Test" "$QUADRA_IMG" 2>/dev/null
|
||||
|
||||
echo
|
||||
echo "7. Block size analysis..."
|
||||
|
||||
# Analyze block sizes for different volume sizes
|
||||
log_info "Analyzing block size selection"
|
||||
|
||||
# Small volume (floppy) - should use 512-byte blocks
|
||||
$MKFS_HFS -v -f -l "Block Test" "$FLOPPY_IMG" | grep -i "block\|size" || true
|
||||
|
||||
# Medium volume (20MB) - should use 512-byte blocks
|
||||
$MKFS_HFS_PLUS -v -f -l "Block Test" "$INTRO_IMG" | grep -i "block\|size" || true
|
||||
|
||||
# Large volume (80MB) - should use 4096-byte blocks for HFS+
|
||||
$MKFS_HFS_PLUS -v -f -l "Block Test" "$QUADRA_IMG" | grep -i "block\|size" || true
|
||||
|
||||
echo
|
||||
echo "8. Compatibility testing..."
|
||||
|
||||
# Test different program names
|
||||
log_info "Testing program name variants"
|
||||
|
||||
echo "mkfs.hfs version:"
|
||||
$MKFS_HFS --version | head -1
|
||||
|
||||
echo "mkfs.hfs+ version:"
|
||||
$MKFS_HFS_PLUS --version | head -1
|
||||
|
||||
echo "mkfs.hfsplus version:"
|
||||
$MKFS_HFSPLUS --version | head -1
|
||||
|
||||
# Test help output
|
||||
log_info "Testing help output"
|
||||
$MKFS_HFS --help | head -5
|
||||
|
||||
echo
|
||||
echo "=== Comprehensive Test Results ==="
|
||||
|
||||
log_success "✓ 1.44MB floppy disk HFS formatting works correctly"
|
||||
log_success "✓ 20MB disk HFS formatting works correctly"
|
||||
log_success "✓ 20MB disk HFS+ formatting works correctly"
|
||||
log_success "✓ 80MB disk HFS+ formatting works correctly"
|
||||
log_success "✓ All command-line options work correctly"
|
||||
log_success "✓ Filesystem signatures are correct"
|
||||
log_success "✓ Performance is excellent across all sizes"
|
||||
log_success "✓ Block size selection is appropriate"
|
||||
log_success "✓ Program name variants work correctly"
|
||||
|
||||
echo
|
||||
echo "Summary:"
|
||||
echo "✓ HFS formatting: Tested on 1.44MB and 20MB volumes"
|
||||
echo "✓ HFS+ formatting: Tested on 20MB and 80MB volumes"
|
||||
echo "✓ Command options: All options (-v, -f, -l) work correctly"
|
||||
echo "✓ Error handling: Properly rejects invalid inputs"
|
||||
echo "✓ Signatures: Boot blocks (LK) and volume headers (BD/H+) correct"
|
||||
echo "✓ Performance: Fast formatting across all tested sizes"
|
||||
echo "✓ Compatibility: All program variants work correctly"
|
||||
|
||||
echo
|
||||
log_success "All comprehensive tests passed! mkfs.hfs is ready for production use."
|
||||
}
|
||||
|
||||
# Trap to ensure cleanup
|
||||
trap cleanup_test_images EXIT
|
||||
|
||||
# Run main test
|
||||
main "$@"
|
||||
@@ -1,205 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Test script for new command-line options in mkfs.hfs
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() {
|
||||
echo -e "${BLUE}INFO:${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}SUCCESS:${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}ERROR:${NC} $1"
|
||||
}
|
||||
|
||||
MKFS_HFS="./build/standalone/mkfs.hfs"
|
||||
|
||||
echo "=== Testing New Command-Line Options ==="
|
||||
echo
|
||||
|
||||
# Test 1: --license option
|
||||
log_info "Testing --license option"
|
||||
if $MKFS_HFS --license | grep -q "Copyright"; then
|
||||
log_success "✓ --license option works"
|
||||
else
|
||||
log_error "✗ --license option failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test 2: -t/--type option
|
||||
log_info "Testing -t/--type option"
|
||||
|
||||
# Test explicit HFS type
|
||||
rm -f /tmp/test_type_hfs.img
|
||||
if $MKFS_HFS -t hfs -v /tmp/test_type_hfs.img | grep -q "HFS volume"; then
|
||||
log_success "✓ -t hfs works"
|
||||
else
|
||||
log_error "✗ -t hfs failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test explicit HFS+ type
|
||||
rm -f /tmp/test_type_hfsplus.img
|
||||
if $MKFS_HFS -t hfs+ -v /tmp/test_type_hfsplus.img | grep -q "HFS+ volume"; then
|
||||
log_success "✓ -t hfs+ works"
|
||||
else
|
||||
log_error "✗ -t hfs+ failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test hfsplus alias
|
||||
rm -f /tmp/test_type_hfsplus2.img
|
||||
if $MKFS_HFS -t hfsplus -v /tmp/test_type_hfsplus2.img | grep -q "HFS+ volume"; then
|
||||
log_success "✓ -t hfsplus works"
|
||||
else
|
||||
log_error "✗ -t hfsplus failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test invalid type
|
||||
if $MKFS_HFS -t invalid /tmp/test_invalid_type.img 2>&1 | grep -q "invalid filesystem type"; then
|
||||
log_success "✓ Invalid type correctly rejected"
|
||||
else
|
||||
log_error "✗ Invalid type not rejected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test 3: -s/--size option
|
||||
log_info "Testing -s/--size option"
|
||||
|
||||
# Test size in bytes
|
||||
rm -f /tmp/test_size_bytes.img
|
||||
if $MKFS_HFS -s 1048576 -v /tmp/test_size_bytes.img | grep -q "created successfully"; then
|
||||
log_success "✓ Size in bytes works"
|
||||
else
|
||||
log_error "✗ Size in bytes failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test size with K suffix
|
||||
rm -f /tmp/test_size_k.img
|
||||
if $MKFS_HFS -s 1024K -v /tmp/test_size_k.img | grep -q "created successfully"; then
|
||||
log_success "✓ Size with K suffix works"
|
||||
else
|
||||
log_error "✗ Size with K suffix failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test size with M suffix
|
||||
rm -f /tmp/test_size_m.img
|
||||
if $MKFS_HFS -s 10M -v /tmp/test_size_m.img | grep -q "created successfully"; then
|
||||
log_success "✓ Size with M suffix works"
|
||||
else
|
||||
log_error "✗ Size with M suffix failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test size with G suffix
|
||||
rm -f /tmp/test_size_g.img
|
||||
if $MKFS_HFS -s 1G -v /tmp/test_size_g.img | grep -q "created successfully"; then
|
||||
log_success "✓ Size with G suffix works"
|
||||
else
|
||||
log_error "✗ Size with G suffix failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test minimum size validation
|
||||
if $MKFS_HFS -s 100K /tmp/test_small.img 2>&1 | grep -q "must be at least 800KB"; then
|
||||
log_success "✓ Minimum size validation works"
|
||||
else
|
||||
log_error "✗ Minimum size validation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test invalid size
|
||||
if $MKFS_HFS -s invalid /tmp/test_invalid_size.img 2>&1 | grep -q "invalid size"; then
|
||||
log_success "✓ Invalid size correctly rejected"
|
||||
else
|
||||
log_error "✗ Invalid size not rejected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test 4: Combined options
|
||||
log_info "Testing combined options"
|
||||
|
||||
rm -f /tmp/test_combined.img
|
||||
if $MKFS_HFS -t hfs+ -s 20M -l "Combined Test" -v /tmp/test_combined.img | grep -q "HFS+ volume 'Combined Test' created successfully"; then
|
||||
log_success "✓ Combined options work"
|
||||
else
|
||||
log_error "✗ Combined options failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test 5: Program name detection with explicit type override
|
||||
log_info "Testing program name detection with type override"
|
||||
|
||||
# Test mkfs.hfs+ with explicit HFS type (should use explicit type)
|
||||
rm -f /tmp/test_override.img
|
||||
if ./build/standalone/mkfs.hfs+ -t hfs -v /tmp/test_override.img | grep -q "HFS volume"; then
|
||||
log_success "✓ Explicit type overrides program name"
|
||||
else
|
||||
log_error "✗ Explicit type override failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test 6: File size preservation with new options
|
||||
log_info "Testing file size preservation with new options"
|
||||
|
||||
# Create a 5MB file and format it
|
||||
rm -f /tmp/test_preserve_size.img
|
||||
dd if=/dev/zero of=/tmp/test_preserve_size.img bs=1024 count=5120 2>/dev/null
|
||||
|
||||
size_before=$(stat -c%s /tmp/test_preserve_size.img 2>/dev/null || stat -f%z /tmp/test_preserve_size.img 2>/dev/null)
|
||||
log_info "File size before formatting: $size_before bytes"
|
||||
|
||||
$MKFS_HFS -f -t hfs+ -l "Size Test" -v /tmp/test_preserve_size.img >/dev/null
|
||||
|
||||
size_after=$(stat -c%s /tmp/test_preserve_size.img 2>/dev/null || stat -f%z /tmp/test_preserve_size.img 2>/dev/null)
|
||||
log_info "File size after formatting: $size_after bytes"
|
||||
|
||||
if [[ "$size_before" -eq "$size_after" ]]; then
|
||||
log_success "✓ File size preserved with new options"
|
||||
else
|
||||
log_error "✗ File size changed! Before: $size_before, After: $size_after"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Cleanup
|
||||
log_info "Cleaning up test files"
|
||||
rm -f /tmp/test_*.img
|
||||
|
||||
echo "=== All New Option Tests Passed! ==="
|
||||
echo
|
||||
echo "Summary of new features tested:"
|
||||
echo "✓ --license option displays license information"
|
||||
echo "✓ -t/--type option supports hfs, hfs+, hfsplus"
|
||||
echo "✓ -s/--size option supports bytes and K/M/G suffixes"
|
||||
echo "✓ Size validation enforces 800KB minimum"
|
||||
echo "✓ Invalid options are properly rejected"
|
||||
echo "✓ Combined options work together"
|
||||
echo "✓ Explicit type overrides program name detection"
|
||||
echo "✓ File sizes are preserved during formatting"
|
||||
echo
|
||||
log_success "mkfs.hfs command-line interface is fully compatible!"
|
||||
@@ -1,268 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Proper test methodology for mkfs.hfs following original hfsutils approach
|
||||
# Create disk images with dd, format with mkfs.hfs, verify with fsck.hfs
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() {
|
||||
echo -e "${BLUE}INFO:${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}SUCCESS:${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}WARNING:${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}ERROR:${NC} $1"
|
||||
}
|
||||
|
||||
MKFS_HFS="./build/standalone/mkfs.hfs"
|
||||
MKFS_HFS_PLUS="./build/standalone/mkfs.hfs+"
|
||||
MKFS_HFSPLUS="./build/standalone/mkfs.hfsplus"
|
||||
|
||||
echo "=== Proper mkfs.hfs Test Methodology ==="
|
||||
echo "Following original hfsutils test approach:"
|
||||
echo "1. Create disk images with dd"
|
||||
echo "2. Format with mkfs.hfs"
|
||||
echo "3. Verify with fsck.hfs (when available)"
|
||||
echo
|
||||
|
||||
# Function to create disk image with dd
|
||||
create_disk_image() {
|
||||
local image_path="$1"
|
||||
local size_kb="$2"
|
||||
local description="$3"
|
||||
|
||||
log_info "Creating $description: $image_path ($size_kb KB)"
|
||||
|
||||
# Use /dev/urandom for more realistic data (as suggested)
|
||||
if command -v /dev/urandom >/dev/null 2>&1; then
|
||||
dd if=/dev/urandom of="$image_path" bs=512 count=$((size_kb * 2)) 2>/dev/null
|
||||
else
|
||||
# Fallback to /dev/zero if /dev/urandom not available
|
||||
dd if=/dev/zero of="$image_path" bs=512 count=$((size_kb * 2)) 2>/dev/null
|
||||
fi
|
||||
|
||||
if [[ ! -f "$image_path" ]]; then
|
||||
log_error "Failed to create disk image: $image_path"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local actual_size=$(stat -c%s "$image_path" 2>/dev/null || stat -f%z "$image_path" 2>/dev/null)
|
||||
local expected_size=$((size_kb * 1024))
|
||||
|
||||
if [[ "$actual_size" -eq "$expected_size" ]]; then
|
||||
log_success "Created $description: $actual_size bytes"
|
||||
else
|
||||
log_warning "Size mismatch: expected $expected_size, got $actual_size"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to format and verify disk image
|
||||
format_and_verify() {
|
||||
local image_path="$1"
|
||||
local formatter="$2"
|
||||
local fs_type="$3"
|
||||
local volume_name="$4"
|
||||
local description="$5"
|
||||
|
||||
echo
|
||||
log_info "Testing $description"
|
||||
|
||||
# Check size before formatting
|
||||
local size_before=$(stat -c%s "$image_path" 2>/dev/null || stat -f%z "$image_path" 2>/dev/null)
|
||||
log_info "Size before formatting: $size_before bytes"
|
||||
|
||||
# Format the disk image
|
||||
log_info "Formatting with: $formatter -f -l \"$volume_name\" $image_path"
|
||||
if $formatter -f -l "$volume_name" "$image_path"; then
|
||||
log_success "Formatting completed"
|
||||
else
|
||||
log_error "Formatting failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check size after formatting
|
||||
local size_after=$(stat -c%s "$image_path" 2>/dev/null || stat -f%z "$image_path" 2>/dev/null)
|
||||
log_info "Size after formatting: $size_after bytes"
|
||||
|
||||
if [[ "$size_before" -eq "$size_after" ]]; then
|
||||
log_success "✓ File size preserved during formatting"
|
||||
else
|
||||
log_error "✗ File size changed! Before: $size_before, After: $size_after"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify filesystem signatures
|
||||
log_info "Verifying filesystem signatures"
|
||||
|
||||
# Check boot block signature (LK)
|
||||
if hexdump -C "$image_path" | head -1 | grep -q "4c 4b"; then
|
||||
log_success "✓ Boot block signature correct (LK)"
|
||||
else
|
||||
log_error "✗ Boot block signature incorrect"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check filesystem signature
|
||||
if [[ "$fs_type" == "HFS" ]]; then
|
||||
if hexdump -C "$image_path" | grep "42 44" | head -1 > /dev/null; then
|
||||
log_success "✓ HFS Master Directory Block signature correct (BD)"
|
||||
else
|
||||
log_error "✗ HFS MDB signature incorrect"
|
||||
return 1
|
||||
fi
|
||||
elif [[ "$fs_type" == "HFS+" ]]; then
|
||||
if hexdump -C "$image_path" | grep "48 2b" | head -1 > /dev/null; then
|
||||
log_success "✓ HFS+ Volume Header signature correct (H+)"
|
||||
else
|
||||
log_error "✗ HFS+ Volume Header signature incorrect"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# TODO: Verify with fsck.hfs when available
|
||||
# log_info "Verifying with fsck.hfs (when available)"
|
||||
# if command -v fsck.hfs >/dev/null 2>&1; then
|
||||
# if fsck.hfs "$image_path"; then
|
||||
# log_success "✓ fsck.hfs verification passed"
|
||||
# else
|
||||
# log_error "✗ fsck.hfs verification failed"
|
||||
# return 1
|
||||
# fi
|
||||
# else
|
||||
# log_warning "fsck.hfs not available yet"
|
||||
# fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Test images following original hfsutils test methodology
|
||||
FLOPPY_IMG="/tmp/test_floppy_1440k.img" # 1.44MB floppy
|
||||
INTRO_IMG="/tmp/test_intro_20mb.img" # 20MB introductory disk
|
||||
QUADRA_IMG="/tmp/test_quadra_80mb.img" # 80MB Quadra disk
|
||||
|
||||
# Cleanup function
|
||||
cleanup_test_images() {
|
||||
log_info "Cleaning up test images"
|
||||
rm -f "$FLOPPY_IMG" "$INTRO_IMG" "$QUADRA_IMG"
|
||||
log_success "Test images cleaned up"
|
||||
}
|
||||
|
||||
# Trap to ensure cleanup
|
||||
trap cleanup_test_images EXIT
|
||||
|
||||
echo "=== Test 1: 1.44MB Floppy Disk (HFS) ==="
|
||||
create_disk_image "$FLOPPY_IMG" 1440 "1.44MB floppy disk"
|
||||
format_and_verify "$FLOPPY_IMG" "$MKFS_HFS" "HFS" "Floppy Disk" "1.44MB floppy with HFS"
|
||||
|
||||
echo
|
||||
echo "=== Test 2: 20MB Introductory Disk (HFS) ==="
|
||||
create_disk_image "$INTRO_IMG" 20480 "20MB introductory disk"
|
||||
format_and_verify "$INTRO_IMG" "$MKFS_HFS" "HFS" "Intro Disk" "20MB disk with HFS"
|
||||
|
||||
echo
|
||||
echo "=== Test 3: 20MB Introductory Disk (HFS+) ==="
|
||||
# Reuse the same image, format as HFS+
|
||||
format_and_verify "$INTRO_IMG" "$MKFS_HFS_PLUS" "HFS+" "Intro HFS+" "20MB disk with HFS+"
|
||||
|
||||
echo
|
||||
echo "=== Test 4: 80MB Quadra Hard Disk (HFS+) ==="
|
||||
create_disk_image "$QUADRA_IMG" 81920 "80MB Quadra hard disk"
|
||||
format_and_verify "$QUADRA_IMG" "$MKFS_HFSPLUS" "HFS+" "Quadra HD" "80MB Quadra disk with HFS+"
|
||||
|
||||
echo
|
||||
echo "=== Test 5: Command-Line Options ==="
|
||||
|
||||
# Test verbose mode
|
||||
log_info "Testing verbose mode"
|
||||
create_disk_image "/tmp/test_verbose.img" 10240 "10MB test disk"
|
||||
if $MKFS_HFS -f -v -l "Verbose Test" /tmp/test_verbose.img | grep -q "created successfully"; then
|
||||
log_success "✓ Verbose mode works"
|
||||
else
|
||||
log_error "✗ Verbose mode failed"
|
||||
fi
|
||||
|
||||
# Test filesystem type selection
|
||||
log_info "Testing filesystem type selection"
|
||||
create_disk_image "/tmp/test_type.img" 10240 "10MB test disk"
|
||||
if $MKFS_HFS -f -t hfs+ -l "Type Test" /tmp/test_type.img | grep -q "HFS+"; then
|
||||
log_success "✓ Filesystem type selection works"
|
||||
else
|
||||
log_error "✗ Filesystem type selection failed"
|
||||
fi
|
||||
|
||||
# Test program name detection
|
||||
log_info "Testing program name detection"
|
||||
create_disk_image "/tmp/test_name.img" 10240 "10MB test disk"
|
||||
if $MKFS_HFS_PLUS -f -l "Name Test" /tmp/test_name.img | grep -q "HFS+"; then
|
||||
log_success "✓ Program name detection works"
|
||||
else
|
||||
log_error "✗ Program name detection failed"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== Test 6: Error Handling ==="
|
||||
|
||||
# Test missing device
|
||||
log_info "Testing missing device argument"
|
||||
if $MKFS_HFS 2>&1 | grep -q "missing device"; then
|
||||
log_success "✓ Missing device correctly detected"
|
||||
else
|
||||
log_error "✗ Missing device not detected"
|
||||
fi
|
||||
|
||||
# Test invalid filesystem type
|
||||
log_info "Testing invalid filesystem type"
|
||||
create_disk_image "/tmp/test_invalid.img" 1024 "1MB test disk"
|
||||
if $MKFS_HFS -t invalid /tmp/test_invalid.img 2>&1 | grep -q "invalid filesystem type"; then
|
||||
log_success "✓ Invalid filesystem type correctly rejected"
|
||||
else
|
||||
log_error "✗ Invalid filesystem type not rejected"
|
||||
fi
|
||||
|
||||
# Test volume name too long
|
||||
log_info "Testing volume name validation"
|
||||
if $MKFS_HFS -l "This volume name is way too long for HFS specification" /tmp/test_invalid.img 2>&1 | grep -q "too long"; then
|
||||
log_success "✓ Long volume name correctly rejected"
|
||||
else
|
||||
log_error "✗ Long volume name not rejected"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== Test Results Summary ==="
|
||||
log_success "✓ 1.44MB floppy disk (HFS) - Formatted and verified"
|
||||
log_success "✓ 20MB introductory disk (HFS) - Formatted and verified"
|
||||
log_success "✓ 20MB introductory disk (HFS+) - Formatted and verified"
|
||||
log_success "✓ 80MB Quadra disk (HFS+) - Formatted and verified"
|
||||
log_success "✓ Command-line options work correctly"
|
||||
log_success "✓ Error handling validates inputs"
|
||||
log_success "✓ File sizes preserved during formatting"
|
||||
log_success "✓ Filesystem signatures are correct"
|
||||
|
||||
echo
|
||||
echo "=== Methodology Verification ==="
|
||||
echo "✓ Used dd with /dev/urandom to create realistic disk images"
|
||||
echo "✓ Used proper block sizes (512 bytes) for dd"
|
||||
echo "✓ Formatted with mkfs.hfs -f [options] image_file"
|
||||
echo "✓ Verified filesystem signatures manually"
|
||||
echo "✓ Ready for fsck.hfs integration when available"
|
||||
|
||||
echo
|
||||
log_success "All tests passed using proper hfsutils methodology!"
|
||||
|
||||
# Cleanup temp files
|
||||
rm -f /tmp/test_*.img
|
||||
@@ -1,36 +0,0 @@
|
||||
#
|
||||
# hfsutils - tools for reading and writing Macintosh HFS volumes
|
||||
# Copyright (C) 1996-1998 Robert Leslie
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id: Makefile,v 1.5 1998/04/11 08:27:23 rob Exp $
|
||||
#
|
||||
|
||||
all :: test1 test2
|
||||
|
||||
clean ::
|
||||
rm -f gmon.* image.hfs core
|
||||
|
||||
depend ::
|
||||
|
||||
test1 :: ../hfssh ../hfs
|
||||
@echo; echo "source main.tcl; test1" | ../hfssh ../hfs
|
||||
|
||||
test2 :: ../hfssh ../hfs
|
||||
@echo; echo "source main.tcl; test2" | ../hfssh ../hfs
|
||||
|
||||
test3 :: ../hfssh ../hfs
|
||||
@echo; echo "source main.tcl; test3" | ../hfssh ../hfs
|
||||
@@ -1,346 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Generate Test Data for HFS Utilities
|
||||
# Creates various HFS images and sample files for testing
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Directories
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
DATA_DIR="$SCRIPT_DIR/data"
|
||||
TEMP_DIR="$SCRIPT_DIR/temp"
|
||||
|
||||
# Utility paths - using unified binary
|
||||
HFSUTIL="$PROJECT_ROOT/hfsutil"
|
||||
HFSCK="$PROJECT_ROOT/hfsck/hfsck"
|
||||
|
||||
# Create symlinks for compatibility if they don't exist
|
||||
if [ ! -L "$PROJECT_ROOT/hformat" ]; then
|
||||
ln -sf hfsutil "$PROJECT_ROOT/hformat"
|
||||
fi
|
||||
if [ ! -L "$PROJECT_ROOT/hmount" ]; then
|
||||
ln -sf hfsutil "$PROJECT_ROOT/hmount"
|
||||
fi
|
||||
if [ ! -L "$PROJECT_ROOT/humount" ]; then
|
||||
ln -sf hfsutil "$PROJECT_ROOT/humount"
|
||||
fi
|
||||
if [ ! -L "$PROJECT_ROOT/hcopy" ]; then
|
||||
ln -sf hfsutil "$PROJECT_ROOT/hcopy"
|
||||
fi
|
||||
if [ ! -L "$PROJECT_ROOT/hmkdir" ]; then
|
||||
ln -sf hfsutil "$PROJECT_ROOT/hmkdir"
|
||||
fi
|
||||
if [ ! -L "$PROJECT_ROOT/hls" ]; then
|
||||
ln -sf hfsutil "$PROJECT_ROOT/hls"
|
||||
fi
|
||||
|
||||
HFORMAT="$PROJECT_ROOT/hformat"
|
||||
HMOUNT="$PROJECT_ROOT/hmount"
|
||||
HUMOUNT="$PROJECT_ROOT/humount"
|
||||
HCOPY="$PROJECT_ROOT/hcopy"
|
||||
HMKDIR="$PROJECT_ROOT/hmkdir"
|
||||
HLS="$PROJECT_ROOT/hls"
|
||||
|
||||
log() {
|
||||
echo -e "${BLUE}[INFO]${NC} $*"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}[DONE]${NC} $*"
|
||||
}
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$DATA_DIR"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
|
||||
log "Generating test data in $DATA_DIR"
|
||||
|
||||
#==============================================================================
|
||||
# Sample Files for Testing
|
||||
#==============================================================================
|
||||
|
||||
log "Creating sample files..."
|
||||
|
||||
# Create various test files
|
||||
cd "$TEMP_DIR"
|
||||
|
||||
# Small text file
|
||||
cat > small_text.txt << 'EOF'
|
||||
This is a small text file for testing HFS utilities.
|
||||
It contains some basic ASCII text.
|
||||
Created by the HFS utilities test suite.
|
||||
|
||||
Line with special characters: !@#$%^&*()
|
||||
Line with numbers: 1234567890
|
||||
EOF
|
||||
|
||||
# Medium text file (around 8KB)
|
||||
{
|
||||
echo "This is a medium-sized text file for testing."
|
||||
echo "Generated on: $(date)"
|
||||
echo
|
||||
for i in {1..100}; do
|
||||
echo "Line $i: The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs."
|
||||
done
|
||||
} > medium_text.txt
|
||||
|
||||
# Large text file (around 64KB)
|
||||
{
|
||||
echo "This is a large text file for testing."
|
||||
echo "Generated on: $(date)"
|
||||
echo
|
||||
for i in {1..1000}; do
|
||||
echo "Line $i: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
|
||||
done
|
||||
} > large_text.txt
|
||||
|
||||
# Binary file (1KB of pseudo-random data)
|
||||
if command -v openssl >/dev/null; then
|
||||
openssl rand 1024 > binary_1k.dat
|
||||
else
|
||||
dd if=/dev/urandom of=binary_1k.dat bs=1024 count=1 2>/dev/null
|
||||
fi
|
||||
|
||||
# Binary file (16KB)
|
||||
if command -v openssl >/dev/null; then
|
||||
openssl rand 16384 > binary_16k.dat
|
||||
else
|
||||
dd if=/dev/urandom of=binary_16k.dat bs=16384 count=1 2>/dev/null
|
||||
fi
|
||||
|
||||
# Empty file
|
||||
touch empty_file.txt
|
||||
|
||||
# File with special characters in name
|
||||
echo "File with special characters" > "test file (with spaces & symbols).txt"
|
||||
|
||||
# Files with different extensions
|
||||
echo "C source file" > test.c
|
||||
echo "Header file" > test.h
|
||||
echo "Text document" > document.txt
|
||||
echo "README content" > README.md
|
||||
|
||||
success "Sample files created"
|
||||
|
||||
#==============================================================================
|
||||
# Test HFS Images
|
||||
#==============================================================================
|
||||
|
||||
cd "$DATA_DIR"
|
||||
|
||||
# Clean existing test images
|
||||
rm -f *.hfs *.img
|
||||
|
||||
log "Creating test HFS and HFS+ images..."
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 1. Small HFS image (1.44MB floppy disk size)
|
||||
#------------------------------------------------------------------------------
|
||||
log "Creating small HFS test image (1440KB)..."
|
||||
|
||||
# Create empty file first, then format it as HFS
|
||||
dd if=/dev/zero of=small_test.hfs bs=1024 count=1440 2>/dev/null
|
||||
"$HFORMAT" -l "Test Floppy" small_test.hfs
|
||||
"$HMOUNT" small_test.hfs
|
||||
|
||||
# Populate with basic files
|
||||
"$HCOPY" "$TEMP_DIR/small_text.txt" :readme.txt
|
||||
"$HCOPY" "$TEMP_DIR/test.c" :test.c
|
||||
"$HCOPY" "$TEMP_DIR/empty_file.txt" :empty.txt
|
||||
"$HMKDIR" :docs
|
||||
"$HCOPY" "$TEMP_DIR/medium_text.txt" :docs:manual.txt
|
||||
|
||||
"$HUMOUNT"
|
||||
success "Small HFS test image created: small_test.hfs"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 1b. Small HFS+ image (1.44MB floppy disk size)
|
||||
#------------------------------------------------------------------------------
|
||||
log "Creating small HFS+ test image (1440KB)..."
|
||||
|
||||
# Create empty file first, then format it as HFS+
|
||||
dd if=/dev/zero of=small_test_hfsplus.img bs=1024 count=1440 2>/dev/null
|
||||
"$HFORMAT" -t hfs+ -l "Test Floppy Plus" small_test_hfsplus.img
|
||||
|
||||
# Note: HFS+ volumes cannot be mounted with the old HFS library
|
||||
# This image is for testing HFS+ formatting and fsck functionality
|
||||
success "Small HFS+ test image created: small_test_hfsplus.img"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 2. Medium HFS image (10MB)
|
||||
#------------------------------------------------------------------------------
|
||||
log "Creating medium HFS test image (10MB)..."
|
||||
|
||||
# Create 10MB file
|
||||
dd if=/dev/zero of=medium_test.hfs bs=1024 count=10240 2>/dev/null
|
||||
"$HFORMAT" -l "Medium Test" medium_test.hfs
|
||||
"$HMOUNT" medium_test.hfs
|
||||
|
||||
# Create directory structure
|
||||
"$HMKDIR" :Documents
|
||||
"$HMKDIR" :Pictures
|
||||
"$HMKDIR" :Software
|
||||
"$HMKDIR" :Archives
|
||||
"$HMKDIR" :Documents:Projects
|
||||
"$HMKDIR" :Documents:Notes
|
||||
|
||||
# Populate with various files
|
||||
"$HCOPY" "$TEMP_DIR/small_text.txt" :Documents:readme.txt
|
||||
"$HCOPY" "$TEMP_DIR/medium_text.txt" :Documents:manual.txt
|
||||
"$HCOPY" "$TEMP_DIR/large_text.txt" :Documents:Notes:notes.txt
|
||||
"$HCOPY" "$TEMP_DIR/binary_1k.dat" :Archives:data1.bin
|
||||
"$HCOPY" "$TEMP_DIR/binary_16k.dat" :Archives:data16.bin
|
||||
"$HCOPY" "$TEMP_DIR/test.c" :Software:hello.c
|
||||
"$HCOPY" "$TEMP_DIR/test.h" :Software:hello.h
|
||||
|
||||
# File with special characters
|
||||
"$HCOPY" "$TEMP_DIR/test file (with spaces & symbols).txt" ":Documents:special file.txt"
|
||||
|
||||
"$HUMOUNT"
|
||||
success "Medium HFS test image created: medium_test.hfs"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 2b. Medium HFS+ image (10MB)
|
||||
#------------------------------------------------------------------------------
|
||||
log "Creating medium HFS+ test image (10MB)..."
|
||||
|
||||
# Create 10MB file and format as HFS+
|
||||
dd if=/dev/zero of=medium_test_hfsplus.img bs=1024 count=10240 2>/dev/null
|
||||
"$HFORMAT" -t hfs+ -l "Medium Test Plus" medium_test_hfsplus.img
|
||||
|
||||
# Note: HFS+ volumes cannot be mounted with the old HFS library
|
||||
# This image is for testing HFS+ formatting and fsck functionality
|
||||
success "Medium HFS+ test image created: medium_test_hfsplus.img"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 3. Empty images for testing
|
||||
#------------------------------------------------------------------------------
|
||||
log "Creating empty HFS test image (1440KB)..."
|
||||
|
||||
# Create empty file and format it as HFS
|
||||
dd if=/dev/zero of=empty_test.hfs bs=1024 count=1440 2>/dev/null
|
||||
"$HFORMAT" -l "Empty Test" empty_test.hfs
|
||||
success "Empty HFS test image created: empty_test.hfs"
|
||||
|
||||
log "Creating empty HFS+ test image (1440KB)..."
|
||||
|
||||
# Create empty file and format it as HFS+
|
||||
dd if=/dev/zero of=empty_test_hfsplus.img bs=1024 count=1440 2>/dev/null
|
||||
"$HFORMAT" -t hfs+ -l "Empty Test Plus" empty_test_hfsplus.img
|
||||
success "Empty HFS+ test image created: empty_test_hfsplus.img"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 4. Large image (50MB) for stress testing
|
||||
#------------------------------------------------------------------------------
|
||||
log "Creating large test image (50MB)..."
|
||||
|
||||
# Create 50MB file
|
||||
dd if=/dev/zero of=large_test.hfs bs=1024 count=51200 2>/dev/null
|
||||
"$HFORMAT" -l "Large Test Volume" large_test.hfs
|
||||
"$HMOUNT" large_test.hfs
|
||||
|
||||
# Create deeper directory structure
|
||||
for dir in System Applications Documents Music Pictures Movies; do
|
||||
"$HMKDIR" ":$dir"
|
||||
done
|
||||
|
||||
"$HMKDIR" :System:Configuration
|
||||
"$HMKDIR" :System:Logs
|
||||
"$HMKDIR" :Applications:Utilities
|
||||
"$HMKDIR" :Documents:Work
|
||||
"$HMKDIR" :Documents:Personal
|
||||
|
||||
# Add more files
|
||||
for i in {1..20}; do
|
||||
echo "Test file $i content for stress testing" > "$TEMP_DIR/test_file_$i.txt"
|
||||
"$HCOPY" "$TEMP_DIR/test_file_$i.txt" ":Documents:test_file_$i.txt"
|
||||
done
|
||||
|
||||
# Add some binary files
|
||||
"$HCOPY" "$TEMP_DIR/binary_1k.dat" :System:config.dat
|
||||
"$HCOPY" "$TEMP_DIR/binary_16k.dat" :Applications:app_data.bin
|
||||
|
||||
"$HUMOUNT"
|
||||
success "Large HFS test image created: large_test.hfs"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 4b. Large HFS+ image (50MB) for stress testing
|
||||
#------------------------------------------------------------------------------
|
||||
log "Creating large HFS+ test image (50MB)..."
|
||||
|
||||
# Create 50MB file and format as HFS+
|
||||
dd if=/dev/zero of=large_test_hfsplus.img bs=1024 count=51200 2>/dev/null
|
||||
"$HFORMAT" -t hfs+ -l "Large Test Plus" large_test_hfsplus.img
|
||||
|
||||
# Note: HFS+ volumes cannot be mounted with the old HFS library
|
||||
# This image is for testing HFS+ formatting and fsck functionality
|
||||
success "Large HFS+ test image created: large_test_hfsplus.img"
|
||||
|
||||
#==============================================================================
|
||||
# Test image with known corruption (for error testing)
|
||||
#==============================================================================
|
||||
log "Creating corrupted test image..."
|
||||
|
||||
# Start with a good image
|
||||
cp small_test.hfs corrupted_test.hfs
|
||||
|
||||
# Corrupt some bytes in the middle of the file (be careful not to corrupt critical structures)
|
||||
if command -v dd >/dev/null; then
|
||||
# Overwrite some bytes in the middle with zeros
|
||||
dd if=/dev/zero of=corrupted_test.hfs bs=1 seek=50000 count=100 conv=notrunc 2>/dev/null
|
||||
fi
|
||||
|
||||
success "Corrupted test image created: corrupted_test.hfs"
|
||||
|
||||
#==============================================================================
|
||||
# Create reference files for testing
|
||||
#==============================================================================
|
||||
log "Creating reference files..."
|
||||
|
||||
# Create expected output files for testing
|
||||
mkdir -p reference
|
||||
|
||||
# Expected directory listing for small_test.hfs
|
||||
cat > reference/small_test_ls.txt << 'EOF'
|
||||
d 0 0 Jan 1 1904 Jan 1 1904 docs
|
||||
f 0 56 Jan 1 1904 Jan 1 1904 empty.txt
|
||||
f 0 133 Jan 1 1904 Jan 1 1904 readme.txt
|
||||
f 0 13 Jan 1 1904 Jan 1 1904 test.c
|
||||
EOF
|
||||
|
||||
success "Reference files created"
|
||||
|
||||
#==============================================================================
|
||||
# Summary
|
||||
#==============================================================================
|
||||
echo
|
||||
log "Test data generation complete!"
|
||||
echo
|
||||
echo "Created HFS images:"
|
||||
ls -lh "$DATA_DIR"/*.hfs 2>/dev/null | while read -r line; do
|
||||
echo " $line"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Created HFS+ images:"
|
||||
ls -lh "$DATA_DIR"/*.img 2>/dev/null | while read -r line; do
|
||||
echo " $line"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Sample files available in: $TEMP_DIR"
|
||||
echo "Test images available in: $DATA_DIR"
|
||||
echo "Reference data available in: $DATA_DIR/reference"
|
||||
|
||||
# Cleanup temp directory
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
success "Test data ready for use"
|
||||
@@ -0,0 +1,253 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# validation.sh - Strict filesystem validation library
|
||||
# Zero tolerance for errors - ANY filesystem issue must fail
|
||||
#
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Counters
|
||||
TESTS_RUN=0
|
||||
TESTS_PASSED=0
|
||||
TESTS_FAILED=0
|
||||
|
||||
#
|
||||
# log_pass() - Log successful test
|
||||
#
|
||||
log_pass() {
|
||||
echo -e "${GREEN}✓ PASS${NC}: $1"
|
||||
((TESTS_PASSED++))
|
||||
}
|
||||
|
||||
#
|
||||
# log_fail() - Log failed test and EXIT
|
||||
#
|
||||
log_fail() {
|
||||
echo -e "${RED}✗ FAIL${NC}: $1"
|
||||
((TESTS_FAILED++))
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "TEST SUITE FAILED"
|
||||
echo "========================================="
|
||||
echo "Tests run: $TESTS_RUN"
|
||||
echo "Passed: $TESTS_PASSED"
|
||||
echo "Failed: $TESTS_FAILED"
|
||||
echo ""
|
||||
echo "A filesystem MUST be 100% correct."
|
||||
echo "Fix the issue before proceeding."
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# log_info() - Log informational message
|
||||
#
|
||||
log_info() {
|
||||
echo -e "${YELLOW}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
#
|
||||
# validate_filesystem() - CRITICAL validation with fsck
|
||||
# Returns: 0 if valid, calls log_fail if invalid
|
||||
#
|
||||
validate_filesystem() {
|
||||
local image="$1"
|
||||
local fs_type="$2" # "hfs" or "hfs+"
|
||||
|
||||
local fsck_cmd
|
||||
if [ "$fs_type" = "hfs" ]; then
|
||||
fsck_cmd="./build/standalone/fsck.hfs"
|
||||
else
|
||||
fsck_cmd="./build/standalone/fsck.hfs+"
|
||||
fi
|
||||
|
||||
if [ ! -f "$fsck_cmd" ]; then
|
||||
log_fail "fsck command not found: $fsck_cmd"
|
||||
fi
|
||||
|
||||
log_info "Validating $image with $fsck_cmd -n"
|
||||
|
||||
# Run fsck in read-only mode
|
||||
local output
|
||||
output=$($fsck_cmd -n "$image" 2>&1)
|
||||
local ret=$?
|
||||
|
||||
# Exit code 0 = no errors
|
||||
# Exit code 1 = errors corrected (shouldn't happen with -n)
|
||||
# Exit code 4 = errors found but not corrected
|
||||
# Anything else = critical failure
|
||||
|
||||
if [ $ret -eq 0 ]; then
|
||||
log_pass "Filesystem validation clean (exit code 0)"
|
||||
return 0
|
||||
else
|
||||
echo "fsck output:"
|
||||
echo "$output"
|
||||
log_fail "Filesystem validation FAILED (exit code $ret) - filesystem is CORRUPT"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# verify_exit_code() - Verify command exit code
|
||||
#
|
||||
verify_exit_code() {
|
||||
local actual=$1
|
||||
local expected=$2
|
||||
local operation="$3"
|
||||
|
||||
if [ $actual -ne $expected ]; then
|
||||
log_fail "$operation: Expected exit code $expected, got $actual"
|
||||
fi
|
||||
|
||||
log_pass "$operation: Exit code $expected (correct)"
|
||||
}
|
||||
|
||||
#
|
||||
# verify_file_exists() - Verify file exists and has minimum size
|
||||
#
|
||||
verify_file_exists() {
|
||||
local file="$1"
|
||||
local min_size="$2"
|
||||
|
||||
if [ ! -f "$file" ]; then
|
||||
log_fail "File does not exist: $file"
|
||||
fi
|
||||
|
||||
local size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
|
||||
if [ "$size" -lt "$min_size" ]; then
|
||||
log_fail "File too small: $file ($size bytes < $min_size bytes)"
|
||||
fi
|
||||
|
||||
log_pass "File exists with valid size: $file ($size bytes)"
|
||||
}
|
||||
|
||||
#
|
||||
# verify_signature() - Verify volume signature
|
||||
#
|
||||
verify_signature() {
|
||||
local image="$1"
|
||||
local fs_type="$2"
|
||||
local offset="$3" # Offset in bytes
|
||||
|
||||
local expected_sig
|
||||
if [ "$fs_type" = "hfs" ]; then
|
||||
expected_sig="4244" # BD in big-endian
|
||||
elif [ "$fs_type" = "hfs+" ]; then
|
||||
expected_sig="482b" # H+ in big-endian
|
||||
else
|
||||
log_fail "Unknown filesystem type: $fs_type"
|
||||
fi
|
||||
|
||||
# Read 2 bytes at offset
|
||||
local actual_sig=$(dd if="$image" bs=1 skip=$offset count=2 2>/dev/null | od -An -tx1 | tr -d ' \n')
|
||||
|
||||
if [ "$actual_sig" != "$expected_sig" ]; then
|
||||
log_fail "Invalid signature at offset $offset: got 0x$actual_sig, expected 0x$expected_sig"
|
||||
fi
|
||||
|
||||
log_pass "Valid $fs_type signature: 0x$actual_sig at offset $offset"
|
||||
}
|
||||
|
||||
#
|
||||
# verify_field_range() - Verify numeric field is in range
|
||||
#
|
||||
verify_field_range() {
|
||||
local field_name="$1"
|
||||
local actual="$2"
|
||||
local min="$3"
|
||||
local max="$4"
|
||||
|
||||
if [ "$actual" -lt "$min" ] || [ "$actual" -gt "$max" ]; then
|
||||
log_fail "$field_name out of range: $actual (expected $min-$max)"
|
||||
fi
|
||||
|
||||
log_pass "$field_name in valid range: $actual"
|
||||
}
|
||||
|
||||
#
|
||||
# run_test() - Run a test function with strict error handling
|
||||
#
|
||||
run_test() {
|
||||
local test_name="$1"
|
||||
shift
|
||||
local test_func="$@"
|
||||
|
||||
((TESTS_RUN++))
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Test #$TESTS_RUN: $test_name"
|
||||
echo "========================================="
|
||||
|
||||
# Run test in subshell to catch errors
|
||||
if $test_func; then
|
||||
log_pass "$test_name"
|
||||
return 0
|
||||
else
|
||||
log_fail "$test_name returned error"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# cleanup_test_files() - Clean up all test images
|
||||
#
|
||||
cleanup_test_files() {
|
||||
log_info "Cleaning up test files..."
|
||||
rm -f /tmp/test_*.img
|
||||
rm -f /tmp/hfs_test_*
|
||||
}
|
||||
|
||||
#
|
||||
# setup_test_env() - Set up test environment
|
||||
#
|
||||
setup_test_env() {
|
||||
log_info "Setting up test environment..."
|
||||
|
||||
# Verify build directory exists
|
||||
if [ ! -d "./build/standalone" ]; then
|
||||
log_fail "Build directory not found. Run ./build.sh first."
|
||||
fi
|
||||
|
||||
# Verify tools exist
|
||||
if [ ! -f "./build/standalone/mkfs.hfs" ]; then
|
||||
log_fail "mkfs.hfs not found. Run ./build.sh first."
|
||||
fi
|
||||
|
||||
if [ ! -f "./build/standalone/mkfs.hfs+" ]; then
|
||||
log_fail "mkfs.hfs+ not found. Run ./build.sh first."
|
||||
fi
|
||||
|
||||
# Note: fsck binaries are in build/standalone/fsck.hfs and fsck.hfs+
|
||||
if [ ! -f "./build/standalone/fsck.hfs" ]; then
|
||||
log_info "fsck.hfs not in standalone, checking for symlink..."
|
||||
# fsck might not be built yet, that's okay
|
||||
fi
|
||||
|
||||
if [ ! -f "./build/standalone/fsck.hfs+" ]; then
|
||||
log_info "fsck.hfs+ not in standalone, checking for symlink..."
|
||||
# fsck might not be built yet, that's okay
|
||||
fi
|
||||
|
||||
log_pass "Test environment ready"
|
||||
}
|
||||
|
||||
#
|
||||
# print_summary() - Print final test summary
|
||||
#
|
||||
print_summary() {
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "TEST SUITE COMPLETED SUCCESSFULLY"
|
||||
echo "========================================="
|
||||
echo "Total tests run: $TESTS_RUN"
|
||||
echo "Passed: $TESTS_PASSED"
|
||||
echo "Failed: $TESTS_FAILED"
|
||||
echo ""
|
||||
echo "✓ All filesystems are 100% valid"
|
||||
echo "✓ All structures conform to specifications"
|
||||
echo "✓ All repairs worked correctly"
|
||||
echo ""
|
||||
}
|
||||
-1344
File diff suppressed because it is too large
Load Diff
@@ -1,127 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Simple Integration Test for HFS Utilities
|
||||
# Demonstrates basic inter-utility workflows
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo "========================================="
|
||||
echo " Simple HFS Utilities Integration Test"
|
||||
echo "========================================="
|
||||
echo
|
||||
|
||||
# Change to test directory
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# Setup paths
|
||||
UTILS_DIR=".."
|
||||
TEST_IMG="test_integration.hfs"
|
||||
|
||||
echo "1. Creating HFS volume..."
|
||||
dd if=/dev/zero of="$TEST_IMG" bs=1024 count=2048 2>/dev/null
|
||||
$UTILS_DIR/hformat -l "Integration Test" "$TEST_IMG"
|
||||
echo -e "${GREEN}✓${NC} Volume created"
|
||||
|
||||
echo
|
||||
echo "2. Mounting volume..."
|
||||
$UTILS_DIR/hmount "$TEST_IMG"
|
||||
echo -e "${GREEN}✓${NC} Volume mounted"
|
||||
|
||||
echo
|
||||
echo "3. Creating directory structure..."
|
||||
$UTILS_DIR/hmkdir :Documents
|
||||
$UTILS_DIR/hmkdir :Documents:Projects
|
||||
$UTILS_DIR/hmkdir :Software
|
||||
echo -e "${GREEN}✓${NC} Directories created"
|
||||
|
||||
echo
|
||||
echo "4. Creating test files..."
|
||||
echo "Hello from HFS utilities!" > test_file.txt
|
||||
echo "Project documentation" > project.txt
|
||||
echo "#include <stdio.h>" > hello.c
|
||||
|
||||
echo
|
||||
echo "5. Copying files to volume..."
|
||||
$UTILS_DIR/hcopy test_file.txt :Documents:readme.txt
|
||||
$UTILS_DIR/hcopy project.txt :Documents:Projects:project.txt
|
||||
$UTILS_DIR/hcopy hello.c :Software:hello.c
|
||||
echo -e "${GREEN}✓${NC} Files copied to volume"
|
||||
|
||||
echo
|
||||
echo "6. Listing volume contents..."
|
||||
echo "Root directory:"
|
||||
$UTILS_DIR/hls
|
||||
echo
|
||||
echo "Documents directory:"
|
||||
$UTILS_DIR/hls :Documents
|
||||
echo
|
||||
echo "Documents/Projects directory:"
|
||||
$UTILS_DIR/hls :Documents:Projects
|
||||
echo -e "${GREEN}✓${NC} Directory listings shown"
|
||||
|
||||
echo
|
||||
echo "7. Testing navigation..."
|
||||
$UTILS_DIR/hcd :Documents
|
||||
echo "Current directory: $($UTILS_DIR/hpwd)"
|
||||
$UTILS_DIR/hcd :Projects
|
||||
echo "Current directory: $($UTILS_DIR/hpwd)"
|
||||
echo -e "${GREEN}✓${NC} Navigation works"
|
||||
|
||||
echo
|
||||
echo "8. Copying file back from volume..."
|
||||
# We're in Documents:Projects, go back to Documents first
|
||||
$UTILS_DIR/hcd ::
|
||||
$UTILS_DIR/hcopy readme.txt retrieved_file.txt
|
||||
if [ -f retrieved_file.txt ]; then
|
||||
echo "Retrieved content: $(cat retrieved_file.txt)"
|
||||
echo -e "${GREEN}✓${NC} File retrieved successfully"
|
||||
else
|
||||
echo -e "${RED}✗${NC} Failed to retrieve file"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "9. Testing file operations..."
|
||||
# Go back to root (omit argument to go to root)
|
||||
$UTILS_DIR/hcd
|
||||
# Now we should be at root
|
||||
$UTILS_DIR/hrename :Software:hello.c :Software:main.c
|
||||
echo "After rename:"
|
||||
$UTILS_DIR/hls :Software
|
||||
echo -e "${GREEN}✓${NC} File renamed"
|
||||
|
||||
echo
|
||||
echo "10. Testing deletion..."
|
||||
$UTILS_DIR/hdel :Software:main.c
|
||||
echo "After deletion:"
|
||||
$UTILS_DIR/hls :Software
|
||||
$UTILS_DIR/hrmdir :Software
|
||||
echo "After removing empty directory:"
|
||||
$UTILS_DIR/hls
|
||||
echo -e "${GREEN}✓${NC} Deletion works"
|
||||
|
||||
echo
|
||||
echo "11. Volume information..."
|
||||
$UTILS_DIR/hvol
|
||||
echo -e "${GREEN}✓${NC} Volume info displayed"
|
||||
|
||||
echo
|
||||
echo "12. Unmounting volume..."
|
||||
$UTILS_DIR/humount
|
||||
echo -e "${GREEN}✓${NC} Volume unmounted"
|
||||
|
||||
echo
|
||||
echo "13. Cleanup..."
|
||||
rm -f test_file.txt project.txt hello.c retrieved_file.txt "$TEST_IMG"
|
||||
echo -e "${GREEN}✓${NC} Cleanup complete"
|
||||
|
||||
echo
|
||||
echo "========================================="
|
||||
echo -e "${GREEN}All integration tests passed!${NC}"
|
||||
echo "========================================="
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test script to verify the build system works with different configurations
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Testing HFSUtils Build System ==="
|
||||
echo
|
||||
|
||||
# Test 1: Default build
|
||||
echo "Test 1: Default build"
|
||||
echo "make clean && make"
|
||||
echo
|
||||
|
||||
# Test 2: Custom compiler and flags
|
||||
echo "Test 2: Custom compiler and flags"
|
||||
echo "make clean && make CC=clang CFLAGS='-O3 -Wall'"
|
||||
echo
|
||||
|
||||
# Test 3: Custom prefix
|
||||
echo "Test 3: Custom prefix installation"
|
||||
echo "make install PREFIX=/opt/hfsutils"
|
||||
echo
|
||||
|
||||
# Test 4: DESTDIR staging
|
||||
echo "Test 4: DESTDIR staging installation"
|
||||
echo "make install DESTDIR=/tmp/hfsutils-staging"
|
||||
echo
|
||||
|
||||
# Test 5: Environment variables
|
||||
echo "Test 5: Environment variables"
|
||||
echo "export CC=gcc"
|
||||
echo "export CFLAGS='-g -O2 -march=native'"
|
||||
echo "export PREFIX=/usr/local"
|
||||
echo "./build.sh"
|
||||
echo
|
||||
|
||||
echo "=== Build System Features ==="
|
||||
echo "✓ DESTDIR support for package building"
|
||||
echo "✓ PREFIX support for custom installation paths"
|
||||
echo "✓ CC/CXX compiler selection"
|
||||
echo "✓ CFLAGS/CXXFLAGS/LDFLAGS support"
|
||||
echo "✓ Manual pages installation to \$MANDIR/man1/"
|
||||
echo "✓ Libraries installation to \$LIBDIR/"
|
||||
echo "✓ Headers installation to \$INCLUDEDIR/"
|
||||
echo "✓ hfsck installation to \$PREFIX/sbin/"
|
||||
echo
|
||||
|
||||
echo "=== Usage Examples ==="
|
||||
echo "# Standard installation:"
|
||||
echo "sudo make install"
|
||||
echo
|
||||
echo "# Custom prefix:"
|
||||
echo "make install PREFIX=/opt/hfsutils"
|
||||
echo
|
||||
echo "# Package building:"
|
||||
echo "make install DESTDIR=\$PWD/debian/tmp"
|
||||
echo
|
||||
echo "# Custom compiler:"
|
||||
echo "make CC=clang CFLAGS='-O3 -flto'"
|
||||
echo
|
||||
echo "# Environment-based build:"
|
||||
echo "export CC=gcc-11"
|
||||
echo "export CFLAGS='-O2 -g -fstack-protector-strong'"
|
||||
echo "./build.sh"
|
||||
echo
|
||||
@@ -1,198 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test Standard Exit Codes
|
||||
# Tests that fsck.hfs+ and mkfs.hfs+ return proper Unix/Linux/BSD exit codes
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
UTILS_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo "=== Standard Exit Codes Test ==="
|
||||
echo "Testing fsck.hfs+ and mkfs.hfs+ exit codes compliance"
|
||||
echo
|
||||
|
||||
# Check if utilities exist
|
||||
if [ ! -f "$UTILS_DIR/fsck.hfs+" ] && [ ! -f "$UTILS_DIR/hfsck/hfsck" ]; then
|
||||
echo -e "${RED}✗${NC} fsck.hfs+ not found. Please build first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$UTILS_DIR/mkfs.hfs+" ]; then
|
||||
echo -e "${RED}✗${NC} mkfs.hfs+ not found. Please build first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use the appropriate binaries
|
||||
if [ -f "$UTILS_DIR/fsck.hfs+" ]; then
|
||||
FSCK_HFSPLUS="$UTILS_DIR/fsck.hfs+"
|
||||
else
|
||||
FSCK_HFSPLUS="$UTILS_DIR/hfsck/hfsck"
|
||||
fi
|
||||
|
||||
MKFS_HFSPLUS="$UTILS_DIR/mkfs.hfs+"
|
||||
|
||||
echo "Using fsck binary: $FSCK_HFSPLUS"
|
||||
echo "Using mkfs binary: $MKFS_HFSPLUS"
|
||||
echo
|
||||
|
||||
# Test 1: fsck.hfs+ usage error (exit code 16)
|
||||
echo "=== Test 1: fsck.hfs+ Usage Error ==="
|
||||
echo "Testing fsck.hfs+ with invalid arguments..."
|
||||
|
||||
if $FSCK_HFSPLUS 2>/dev/null; then
|
||||
exit_code=$?
|
||||
else
|
||||
exit_code=$?
|
||||
fi
|
||||
|
||||
if [ $exit_code -eq 16 ]; then
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ returns correct usage error code (16)"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} fsck.hfs+ returned $exit_code, expected 16"
|
||||
fi
|
||||
|
||||
# Test 2: fsck.hfs+ operational error (exit code 8)
|
||||
echo
|
||||
echo "=== Test 2: fsck.hfs+ Operational Error ==="
|
||||
echo "Testing fsck.hfs+ with non-existent device..."
|
||||
|
||||
if $FSCK_HFSPLUS /dev/nonexistent 2>/dev/null; then
|
||||
exit_code=$?
|
||||
else
|
||||
exit_code=$?
|
||||
fi
|
||||
|
||||
if [ $exit_code -eq 8 ]; then
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ returns correct operational error code (8)"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} fsck.hfs+ returned $exit_code, expected 8"
|
||||
fi
|
||||
|
||||
# Test 3: mkfs.hfs+ usage error (exit code 2)
|
||||
echo
|
||||
echo "=== Test 3: mkfs.hfs+ Usage Error ==="
|
||||
echo "Testing mkfs.hfs+ with invalid arguments..."
|
||||
|
||||
if $MKFS_HFSPLUS 2>/dev/null; then
|
||||
exit_code=$?
|
||||
else
|
||||
exit_code=$?
|
||||
fi
|
||||
|
||||
if [ $exit_code -eq 2 ]; then
|
||||
echo -e "${GREEN}✓${NC} mkfs.hfs+ returns correct usage error code (2)"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} mkfs.hfs+ returned $exit_code, expected 2"
|
||||
fi
|
||||
|
||||
# Test 4: mkfs.hfs+ operational error (exit code 4)
|
||||
echo
|
||||
echo "=== Test 4: mkfs.hfs+ Operational Error ==="
|
||||
echo "Testing mkfs.hfs+ with non-existent device..."
|
||||
|
||||
if $MKFS_HFSPLUS /dev/nonexistent 2>/dev/null; then
|
||||
exit_code=$?
|
||||
else
|
||||
exit_code=$?
|
||||
fi
|
||||
|
||||
if [ $exit_code -eq 4 ]; then
|
||||
echo -e "${GREEN}✓${NC} mkfs.hfs+ returns correct operational error code (4)"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} mkfs.hfs+ returned $exit_code, expected 4"
|
||||
fi
|
||||
|
||||
# Test 5: fsck.hfs+ help/version (exit code 0)
|
||||
echo
|
||||
echo "=== Test 5: fsck.hfs+ Help/Version ==="
|
||||
echo "Testing fsck.hfs+ --version..."
|
||||
|
||||
if $FSCK_HFSPLUS --version >/dev/null 2>&1; then
|
||||
exit_code=$?
|
||||
else
|
||||
exit_code=$?
|
||||
fi
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ --version returns success code (0)"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} fsck.hfs+ --version returned $exit_code, expected 0"
|
||||
fi
|
||||
|
||||
# Test 6: mkfs.hfs+ help/version (exit code 0)
|
||||
echo
|
||||
echo "=== Test 6: mkfs.hfs+ Help/Version ==="
|
||||
echo "Testing mkfs.hfs+ --version..."
|
||||
|
||||
if $MKFS_HFSPLUS --version >/dev/null 2>&1; then
|
||||
exit_code=$?
|
||||
else
|
||||
exit_code=$?
|
||||
fi
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
echo -e "${GREEN}✓${NC} mkfs.hfs+ --version returns success code (0)"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} mkfs.hfs+ --version returned $exit_code, expected 0"
|
||||
fi
|
||||
|
||||
# Test 7: Create test image and check success codes
|
||||
echo
|
||||
echo "=== Test 7: Successful Operations ==="
|
||||
|
||||
# Create a test image
|
||||
TEST_IMAGE="$SCRIPT_DIR/test_exit_codes.img"
|
||||
rm -f "$TEST_IMAGE"
|
||||
|
||||
echo "Creating 5MB test image..."
|
||||
dd if=/dev/zero of="$TEST_IMAGE" bs=1M count=5 2>/dev/null
|
||||
|
||||
echo "Testing mkfs.hfs+ success..."
|
||||
if $MKFS_HFSPLUS -l "Exit Test" "$TEST_IMAGE" >/dev/null 2>&1; then
|
||||
exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
echo -e "${GREEN}✓${NC} mkfs.hfs+ returns success code (0) for valid operation"
|
||||
|
||||
# Test fsck on the created image
|
||||
echo "Testing fsck.hfs+ on created image..."
|
||||
if $FSCK_HFSPLUS -n "$TEST_IMAGE" >/dev/null 2>&1; then
|
||||
exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ returns success code (0) for clean filesystem"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} fsck.hfs+ returned $exit_code, expected 0"
|
||||
fi
|
||||
else
|
||||
exit_code=$?
|
||||
echo -e "${YELLOW}!${NC} fsck.hfs+ failed with exit code $exit_code"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} mkfs.hfs+ returned $exit_code, expected 0"
|
||||
fi
|
||||
else
|
||||
exit_code=$?
|
||||
echo -e "${YELLOW}!${NC} mkfs.hfs+ failed with exit code $exit_code"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
echo
|
||||
echo "=== Cleanup ==="
|
||||
rm -f "$TEST_IMAGE"
|
||||
echo "Test files cleaned up"
|
||||
|
||||
echo
|
||||
echo "=== Exit Codes Test Summary ==="
|
||||
echo -e "${GREEN}✓${NC} Standard Unix/Linux/BSD exit codes tested"
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ exit codes verified"
|
||||
echo -e "${GREEN}✓${NC} mkfs.hfs+ exit codes verified"
|
||||
echo
|
||||
echo "Standard Exit Codes Reference:"
|
||||
echo "fsck: 0=OK, 1=Corrected, 2=Reboot, 4=Uncorrected, 8=Operational, 16=Usage, 32=Cancelled, 128=Library"
|
||||
echo "mkfs: 0=Success, 1=General, 2=Usage, 4=Operational, 8=System"
|
||||
@@ -1,97 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test script for enhanced fsck.hfs functionality
|
||||
# Tests the enhanced HFS checking capabilities implemented in task 4.2
|
||||
|
||||
echo "=== Testing Enhanced fsck.hfs Functionality ==="
|
||||
|
||||
# Test 1: Help and version information
|
||||
echo "Test 1: Help and version information"
|
||||
echo "Running: ./build/standalone/fsck.hfs --help"
|
||||
./build/standalone/fsck.hfs --help > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Help option works correctly"
|
||||
else
|
||||
echo "✗ Help option failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running: ./build/standalone/fsck.hfs --version"
|
||||
./build/standalone/fsck.hfs --version > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Version option works correctly"
|
||||
else
|
||||
echo "✗ Version option failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 2: Error handling for missing device
|
||||
echo ""
|
||||
echo "Test 2: Error handling for missing device"
|
||||
echo "Running: ./build/standalone/fsck.hfs"
|
||||
./build/standalone/fsck.hfs > /dev/null 2>&1
|
||||
if [ $? -eq 16 ]; then # FSCK_USAGE_ERROR
|
||||
echo "✓ Correctly reports usage error for missing device"
|
||||
else
|
||||
echo "✗ Did not report correct error code for missing device"
|
||||
fi
|
||||
|
||||
# Test 3: Error handling for non-existent device
|
||||
echo ""
|
||||
echo "Test 3: Error handling for non-existent device"
|
||||
echo "Running: ./build/standalone/fsck.hfs /dev/nonexistent"
|
||||
./build/standalone/fsck.hfs /dev/nonexistent > /dev/null 2>&1
|
||||
if [ $? -eq 8 ]; then # FSCK_OPERATIONAL_ERROR
|
||||
echo "✓ Correctly reports operational error for non-existent device"
|
||||
else
|
||||
echo "✗ Did not report correct error code for non-existent device"
|
||||
fi
|
||||
|
||||
# Test 4: Verbose mode
|
||||
echo ""
|
||||
echo "Test 4: Verbose mode functionality"
|
||||
echo "Running: ./build/standalone/fsck.hfs -v /dev/nonexistent"
|
||||
output=$(./build/standalone/fsck.hfs -v /dev/nonexistent 2>&1)
|
||||
if echo "$output" | grep -q "Starting comprehensive HFS volume check"; then
|
||||
echo "✓ Verbose mode produces expected output"
|
||||
else
|
||||
echo "✗ Verbose mode does not produce expected output"
|
||||
fi
|
||||
|
||||
# Test 5: Command-line option parsing
|
||||
echo ""
|
||||
echo "Test 5: Command-line option parsing"
|
||||
echo "Running: ./build/standalone/fsck.hfs -n -v /dev/nonexistent"
|
||||
./build/standalone/fsck.hfs -n -v /dev/nonexistent > /dev/null 2>&1
|
||||
if [ $? -eq 8 ]; then # Should still be operational error
|
||||
echo "✓ Multiple options parsed correctly"
|
||||
else
|
||||
echo "✗ Multiple options not parsed correctly"
|
||||
fi
|
||||
|
||||
# Test 6: Program name detection
|
||||
echo ""
|
||||
echo "Test 6: Program name detection"
|
||||
if [ -f "./build/standalone/fsck.hfs+" ]; then
|
||||
echo "Running: ./build/standalone/fsck.hfs+ --version"
|
||||
./build/standalone/fsck.hfs+ --version > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ fsck.hfs+ variant works correctly"
|
||||
else
|
||||
echo "✗ fsck.hfs+ variant failed"
|
||||
fi
|
||||
else
|
||||
echo "! fsck.hfs+ not found, skipping test"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Enhanced fsck.hfs Functionality Tests Complete ==="
|
||||
echo "All basic functionality tests passed!"
|
||||
echo ""
|
||||
echo "Note: Full filesystem checking tests require actual HFS volumes."
|
||||
echo "The enhanced checking functions include:"
|
||||
echo "- Comprehensive Master Directory Block validation"
|
||||
echo "- Enhanced B-tree structure checking and repair"
|
||||
echo "- Allocation bitmap validation and repair"
|
||||
echo "- Catalog file consistency checking"
|
||||
echo "- Detailed verbose output with diagnostic information"
|
||||
@@ -1,754 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# HFS hcopy Directory Recursion Test Suite
|
||||
# Tests the recursive copy functionality for directories in hcopy
|
||||
# This addresses the feature request where hcopy :folder: ./dest -r should support
|
||||
# recursive copying of entire directory structures from HFS volumes to local filesystem
|
||||
#
|
||||
# Usage: ./test_hcopy_directory.sh
|
||||
#
|
||||
# This test suite can be run standalone or integrated into the main test suite.
|
||||
# It validates that hcopy -r flag works correctly for directory hierarchies.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Test configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
TEST_DATA_DIR="$SCRIPT_DIR/data"
|
||||
TEST_TEMP_DIR="$SCRIPT_DIR/temp_hcopy_test_$$"
|
||||
|
||||
# Utility paths
|
||||
HFSUTIL="${PROJECT_ROOT}/hfsutil"
|
||||
HCOPY="${PROJECT_ROOT}/hcopy"
|
||||
HMOUNT="${PROJECT_ROOT}/hmount"
|
||||
HUMOUNT="${PROJECT_ROOT}/humount"
|
||||
HLS="${PROJECT_ROOT}/hls"
|
||||
HMKDIR="${PROJECT_ROOT}/hmkdir"
|
||||
HDEL="${PROJECT_ROOT}/hdel"
|
||||
MKFS_HFS="${PROJECT_ROOT}/mkfs.hfs"
|
||||
|
||||
# Test counters
|
||||
TESTS_RUN=0
|
||||
TESTS_PASSED=0
|
||||
TESTS_FAILED=0
|
||||
FAILED_TESTS=()
|
||||
|
||||
#==============================================================================
|
||||
# Helper Functions
|
||||
#==============================================================================
|
||||
|
||||
log() {
|
||||
echo -e "${BLUE}[INFO]${NC} $*"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}[PASS]${NC} $*"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[FAIL]${NC} $*"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $*"
|
||||
}
|
||||
|
||||
# Test execution wrapper
|
||||
run_test() {
|
||||
local test_name="$1"
|
||||
local test_function="$2"
|
||||
|
||||
echo
|
||||
log "Running test: $test_name"
|
||||
TESTS_RUN=$((TESTS_RUN + 1))
|
||||
|
||||
if $test_function; then
|
||||
success "$test_name"
|
||||
TESTS_PASSED=$((TESTS_PASSED + 1))
|
||||
return 0
|
||||
else
|
||||
error "$test_name"
|
||||
TESTS_FAILED=$((TESTS_FAILED + 1))
|
||||
FAILED_TESTS+=("$test_name")
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if file exists
|
||||
assert_file_exists() {
|
||||
local file="$1"
|
||||
if [[ ! -f "$file" ]]; then
|
||||
error "File does not exist: $file"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Check if directory exists
|
||||
assert_dir_exists() {
|
||||
local dir="$1"
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
error "Directory does not exist: $dir"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Count files in directory recursively
|
||||
count_files_recursive() {
|
||||
local dir="$1"
|
||||
find "$dir" -type f 2>/dev/null | wc -l
|
||||
}
|
||||
|
||||
# Count directories recursively
|
||||
count_dirs_recursive() {
|
||||
local dir="$1"
|
||||
find "$dir" -type d 2>/dev/null | wc -l
|
||||
}
|
||||
|
||||
# Setup test environment
|
||||
setup_test_env() {
|
||||
log "Setting up test environment..."
|
||||
|
||||
# Create temp directory
|
||||
mkdir -p "$TEST_TEMP_DIR"
|
||||
|
||||
# Verify utilities exist
|
||||
for util in "$HFSUTIL" "$HCOPY" "$HMOUNT" "$HUMOUNT" "$HLS" "$HMKDIR" "$HDEL" "$MKFS_HFS"; do
|
||||
if [[ ! -x "$util" ]]; then
|
||||
local util_name=$(basename "$util")
|
||||
if [[ ! -L "$util" ]]; then
|
||||
error "Utility $(basename "$util") not found at $util"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
log "Test environment ready"
|
||||
log " Temp directory: $TEST_TEMP_DIR"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Cleanup test environment
|
||||
cleanup_test_env() {
|
||||
log "Cleaning up test environment..."
|
||||
|
||||
# Ensure no volume is mounted
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
|
||||
# Remove test directory
|
||||
rm -rf "$TEST_TEMP_DIR"
|
||||
|
||||
log "Cleanup complete"
|
||||
}
|
||||
|
||||
# Create a test HFS volume with a directory structure
|
||||
create_test_volume() {
|
||||
local volume_path="$1"
|
||||
local volume_name="${2:-TestVol}"
|
||||
|
||||
# Create the volume image
|
||||
dd if=/dev/zero of="$volume_path" bs=1M count=20 2>/dev/null
|
||||
|
||||
# Format as HFS+ (more stable than HFS)
|
||||
# Note: mkfs.hfs+ may segfault but creates valid filesystem
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/build/standalone/mkfs.hfs+ -f -l "$volume_name" "$volume_path" 2>/dev/null || true
|
||||
|
||||
# Final check - just check if file exists and has reasonable size
|
||||
if [ ! -f "$volume_path" ] || [ $(stat -c%s "$volume_path") -lt 1000000 ]; then
|
||||
error "Failed to create test volume file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Print test summary
|
||||
print_summary() {
|
||||
echo
|
||||
echo "========================================"
|
||||
echo " HFS hcopy Directory Test Summary"
|
||||
echo "========================================"
|
||||
echo "Tests run: $TESTS_RUN"
|
||||
echo "Tests passed: $TESTS_PASSED"
|
||||
echo "Tests failed: $TESTS_FAILED"
|
||||
|
||||
if [[ $TESTS_FAILED -gt 0 ]]; then
|
||||
echo
|
||||
echo "Failed tests:"
|
||||
for test in "${FAILED_TESTS[@]}"; do
|
||||
echo " - $test"
|
||||
done
|
||||
echo
|
||||
error "Some tests failed"
|
||||
return 1
|
||||
else
|
||||
echo
|
||||
success "All tests passed!"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# Basic Functionality Tests
|
||||
#==============================================================================
|
||||
|
||||
# Test that hcopy shows error for directory without -r flag
|
||||
test_hcopy_dir_without_recursion_flag() {
|
||||
log "Testing hcopy directory copy without -r flag (should fail)..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/test_no_recursion.hfs"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "No Recursion Test"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create a directory on the volume
|
||||
"$HMKDIR" ":TestDir" || {
|
||||
error "Failed to create test directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Try to copy directory without -r flag (should fail)
|
||||
if "$HCOPY" ":TestDir" "$TEST_TEMP_DIR/copy_result" 2>/dev/null; then
|
||||
error "hcopy should fail when copying directory without -r flag"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Correctly rejected directory copy without -r flag"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
# Test basic recursive directory copy
|
||||
test_hcopy_dir_with_recursion_flag() {
|
||||
log "Testing hcopy directory copy with -r flag..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/test_with_recursion.hfs"
|
||||
local local_copy_dir="$TEST_TEMP_DIR/copied_dir"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "With Recursion Test"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create test directory structure
|
||||
"$HMKDIR" ":SourceDir" || {
|
||||
error "Failed to create source directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy directory with -r flag
|
||||
if ! "$HCOPY" ":SourceDir" "$local_copy_dir" -r 2>/dev/null; then
|
||||
error "hcopy failed to copy directory with -r flag"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify directory was copied
|
||||
if ! assert_dir_exists "$local_copy_dir"; then
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Successfully copied directory with -r flag"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# Complex Directory Structure Tests
|
||||
#==============================================================================
|
||||
|
||||
# Test copying nested directories
|
||||
test_hcopy_nested_directories() {
|
||||
log "Testing hcopy with nested directory structures..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/test_nested.hfs"
|
||||
local local_copy_dir="$TEST_TEMP_DIR/nested_copy"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "Nested Test"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create nested directory structure on HFS volume
|
||||
"$HMKDIR" ":Level1" || {
|
||||
error "Failed to create Level1"
|
||||
return 1
|
||||
}
|
||||
|
||||
"$HMKDIR" ":Level1:Level2" || {
|
||||
error "Failed to create Level2"
|
||||
return 1
|
||||
}
|
||||
|
||||
"$HMKDIR" ":Level1:Level2:Level3" || {
|
||||
error "Failed to create Level3"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy entire nested structure
|
||||
if ! "$HCOPY" ":Level1" "$local_copy_dir" -r 2>/dev/null; then
|
||||
error "hcopy failed to copy nested directories"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify structure was copied
|
||||
if ! assert_dir_exists "$local_copy_dir"; then
|
||||
error "Root directory not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! assert_dir_exists "$local_copy_dir/Level2"; then
|
||||
error "Level2 directory not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! assert_dir_exists "$local_copy_dir/Level2/Level3"; then
|
||||
error "Level3 directory not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Successfully copied nested directories"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# Files in Directories Tests
|
||||
#==============================================================================
|
||||
|
||||
# Test copying directories with files
|
||||
test_hcopy_dir_with_files() {
|
||||
log "Testing hcopy directory copy with files..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/test_with_files.hfs"
|
||||
local local_copy_dir="$TEST_TEMP_DIR/dir_with_files"
|
||||
local temp_file1="$TEST_TEMP_DIR/file1.txt"
|
||||
local temp_file2="$TEST_TEMP_DIR/file2.txt"
|
||||
|
||||
# Create test files locally
|
||||
echo "Test file 1 content" > "$temp_file1"
|
||||
echo "Test file 2 content" > "$temp_file2"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "With Files Test"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create directory and add files
|
||||
"$HMKDIR" ":FileDir" || {
|
||||
error "Failed to create directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
"$HCOPY" "$temp_file1" ":FileDir:file1.txt" || {
|
||||
error "Failed to copy file1"
|
||||
return 1
|
||||
}
|
||||
|
||||
"$HCOPY" "$temp_file2" ":FileDir:file2.txt" || {
|
||||
error "Failed to copy file2"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy entire directory with files
|
||||
if ! "$HCOPY" ":FileDir" "$local_copy_dir" -r 2>/dev/null; then
|
||||
error "hcopy failed to copy directory with files"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify files were copied
|
||||
if ! assert_file_exists "$local_copy_dir/file1.txt"; then
|
||||
error "file1.txt not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! assert_file_exists "$local_copy_dir/file2.txt"; then
|
||||
error "file2.txt not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify file contents
|
||||
if ! grep -q "Test file 1 content" "$local_copy_dir/file1.txt"; then
|
||||
error "file1.txt content not preserved"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! grep -q "Test file 2 content" "$local_copy_dir/file2.txt"; then
|
||||
error "file2.txt content not preserved"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Successfully copied directory with files"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
# Test copying deeply nested directory with many files
|
||||
test_hcopy_complex_structure() {
|
||||
log "Testing hcopy with complex directory structure..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/test_complex.hfs"
|
||||
local local_copy_dir="$TEST_TEMP_DIR/complex_copy"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "Complex Test"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create complex structure
|
||||
"$HMKDIR" ":Project" || {
|
||||
error "Failed to create Project"
|
||||
return 1
|
||||
}
|
||||
|
||||
"$HMKDIR" ":Project:Source" || return 1
|
||||
"$HMKDIR" ":Project:Headers" || return 1
|
||||
"$HMKDIR" ":Project:Docs" || return 1
|
||||
"$HMKDIR" ":Project:Source:Modules" || return 1
|
||||
|
||||
# Create test files for each directory
|
||||
for dir in "Project" "Project:Source" "Project:Source:Modules" "Project:Headers" "Project:Docs"; do
|
||||
local temp_file="$TEST_TEMP_DIR/test_$(basename "$dir").txt"
|
||||
echo "Content for $dir" > "$temp_file"
|
||||
"$HCOPY" "$temp_file" ":${dir}:readme.txt" || {
|
||||
error "Failed to copy file to $dir"
|
||||
return 1
|
||||
}
|
||||
done
|
||||
|
||||
# Copy entire project structure
|
||||
if ! "$HCOPY" ":Project" "$local_copy_dir" -r 2>/dev/null; then
|
||||
error "hcopy failed to copy complex structure"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify structure
|
||||
for subdir in "Source" "Headers" "Docs" "Source/Modules"; do
|
||||
if ! assert_dir_exists "$local_copy_dir/$subdir"; then
|
||||
error "Subdirectory $subdir not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Verify files
|
||||
for file in "readme.txt" "Source/readme.txt" "Source/Modules/readme.txt" "Headers/readme.txt" "Docs/readme.txt"; do
|
||||
if ! assert_file_exists "$local_copy_dir/$file"; then
|
||||
error "File $file not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
log "Successfully copied complex directory structure"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# Edge Case Tests
|
||||
#==============================================================================
|
||||
|
||||
# Test copying empty directory
|
||||
test_hcopy_empty_directory() {
|
||||
log "Testing hcopy with empty directory..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/test_empty.hfs"
|
||||
local local_copy_dir="$TEST_TEMP_DIR/empty_copy"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "Empty Test"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create empty directory
|
||||
"$HMKDIR" ":EmptyDir" || {
|
||||
error "Failed to create empty directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy empty directory
|
||||
if ! "$HCOPY" ":EmptyDir" "$local_copy_dir" -r 2>/dev/null; then
|
||||
error "hcopy failed to copy empty directory"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify empty directory was created
|
||||
if ! assert_dir_exists "$local_copy_dir"; then
|
||||
error "Empty directory not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify it's actually empty
|
||||
local file_count=$(count_files_recursive "$local_copy_dir")
|
||||
if [ "$file_count" -ne 0 ]; then
|
||||
error "Directory should be empty but contains files"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Successfully copied empty directory"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
# Test directory with spaces in name
|
||||
test_hcopy_directory_with_spaces() {
|
||||
log "Testing hcopy with directory containing spaces..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/test_spaces.hfs"
|
||||
local local_copy_dir="$TEST_TEMP_DIR/dir with spaces copy"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "Spaces Test"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create directory with spaces
|
||||
"$HMKDIR" ":My Directory" || {
|
||||
error "Failed to create directory with spaces"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy directory
|
||||
if ! "$HCOPY" ":My Directory" "$local_copy_dir" -r 2>/dev/null; then
|
||||
error "hcopy failed to copy directory with spaces"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify directory was copied
|
||||
if ! assert_dir_exists "$local_copy_dir"; then
|
||||
error "Directory with spaces not copied"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Successfully copied directory with spaces in name"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# Real-World Scenario Tests
|
||||
#==============================================================================
|
||||
|
||||
# Test recovering a folder as described in the issue
|
||||
test_hcopy_recovery_scenario() {
|
||||
log "Testing recovery scenario from GitHub issue..."
|
||||
|
||||
local volume_path="$TEST_TEMP_DIR/legacy_recovery.hfs"
|
||||
local recovery_dir="$TEST_TEMP_DIR/recovered_macos"
|
||||
|
||||
# Create test volume
|
||||
if ! create_test_volume "$volume_path" "Legacy Recovery"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mount volume
|
||||
"$HMOUNT" "$volume_path" || {
|
||||
error "Failed to mount test volume"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Create a mock "Mac OS" directory structure
|
||||
"$HMKDIR" ":Mac OS" || {
|
||||
error "Failed to create Mac OS directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
"$HMKDIR" ":Mac OS:System" || return 1
|
||||
"$HMKDIR" ":Mac OS:Applications" || return 1
|
||||
"$HMKDIR" ":Mac OS:System:Extensions" || return 1
|
||||
|
||||
# Create some test files
|
||||
for i in {1..3}; do
|
||||
local temp_file="$TEST_TEMP_DIR/system_file_$i.bin"
|
||||
dd if=/dev/zero of="$temp_file" bs=1K count=$((i * 10)) 2>/dev/null
|
||||
"$HCOPY" "$temp_file" ":Mac OS:System:file_$i.bin" || return 1
|
||||
done
|
||||
|
||||
for i in {1..2}; do
|
||||
local temp_file="$TEST_TEMP_DIR/app_$i.bin"
|
||||
dd if=/dev/zero of="$temp_file" bs=1K count=$((i * 20)) 2>/dev/null
|
||||
"$HCOPY" "$temp_file" ":Mac OS:Applications:app_$i.bin" || return 1
|
||||
done
|
||||
|
||||
# Now attempt the recovery: copy :Mac OS: to ./recovered_macos -r
|
||||
# This is the exact scenario from the GitHub issue
|
||||
if ! "$HCOPY" ":Mac OS:" "$recovery_dir" -r 2>/dev/null; then
|
||||
error "Recovery failed: hcopy :Mac OS: ./recovered_macos -r"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify recovery structure
|
||||
if ! assert_dir_exists "$recovery_dir"; then
|
||||
error "Recovery directory not created"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! assert_dir_exists "$recovery_dir/System"; then
|
||||
error "System directory not recovered"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! assert_dir_exists "$recovery_dir/Applications"; then
|
||||
error "Applications directory not recovered"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! assert_dir_exists "$recovery_dir/System/Extensions"; then
|
||||
error "Extensions directory not recovered"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify files were recovered
|
||||
local recovered_files=$(count_files_recursive "$recovery_dir")
|
||||
if [ "$recovered_files" -eq 0 ]; then
|
||||
error "No files were recovered"
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Successfully recovered directory structure ($recovered_files files recovered)"
|
||||
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# Main Execution
|
||||
#==============================================================================
|
||||
|
||||
main() {
|
||||
echo "========================================"
|
||||
echo " HFS hcopy Directory Test Suite"
|
||||
echo "========================================"
|
||||
echo "Purpose: Test recursive directory copying with hcopy -r"
|
||||
echo "Issue: hcopy :folder: ./dest -r fails with EISDIR"
|
||||
echo
|
||||
|
||||
# Setup
|
||||
if ! setup_test_env; then
|
||||
error "Failed to setup test environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Trap cleanup
|
||||
trap cleanup_test_env EXIT
|
||||
|
||||
# Basic Functionality Tests
|
||||
echo
|
||||
echo "=== Basic Functionality Tests ==="
|
||||
run_test "Reject directory without -r flag" test_hcopy_dir_without_recursion_flag
|
||||
run_test "Accept directory with -r flag" test_hcopy_dir_with_recursion_flag
|
||||
|
||||
# Complex Directory Structure Tests
|
||||
echo
|
||||
echo "=== Complex Directory Structure Tests ==="
|
||||
run_test "Copy nested directories" test_hcopy_nested_directories
|
||||
run_test "Copy directory with files" test_hcopy_dir_with_files
|
||||
run_test "Copy complex structure" test_hcopy_complex_structure
|
||||
|
||||
# Edge Case Tests
|
||||
echo
|
||||
echo "=== Edge Case Tests ==="
|
||||
run_test "Copy empty directory" test_hcopy_empty_directory
|
||||
run_test "Copy directory with spaces" test_hcopy_directory_with_spaces
|
||||
|
||||
# Real-World Scenario Tests
|
||||
echo
|
||||
echo "=== Real-World Scenario Tests ==="
|
||||
run_test "Recovery scenario from GitHub issue" test_hcopy_recovery_scenario
|
||||
|
||||
# Print summary and exit
|
||||
print_summary
|
||||
}
|
||||
|
||||
# Run main function if script is executed directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
exit $?
|
||||
fi
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
TEST_DIR="test/temp_test_manual"
|
||||
mkdir -p "$TEST_DIR/source"
|
||||
echo 'test' > "$TEST_DIR/source/file.txt"
|
||||
dd if=/dev/zero of="$TEST_DIR/vol.hfs" bs=1M count=5 2>/dev/null
|
||||
./hformat -l Test "$TEST_DIR/vol.hfs"
|
||||
./hmount "$TEST_DIR/vol.hfs"
|
||||
./hcopy -R "$TEST_DIR/source" :
|
||||
EXIT_CODE=$?
|
||||
echo "Exit code: $EXIT_CODE"
|
||||
./hls :
|
||||
./humount
|
||||
rm -rf "$TEST_DIR"
|
||||
@@ -1,103 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " Test manual de hcopy -R (limpio)"
|
||||
echo "========================================="
|
||||
|
||||
# Limpiar y crear entorno
|
||||
rm -rf /tmp/test_rec
|
||||
mkdir -p /tmp/test_rec
|
||||
cd /tmp/test_rec
|
||||
|
||||
# Crear estructura de directorios
|
||||
echo "[1] Creando estructura de directorios de prueba..."
|
||||
mkdir -p source/nivel1/nivel2
|
||||
echo 'archivo raiz' > source/file_root.txt
|
||||
echo 'archivo nivel1' > source/nivel1/file1.txt
|
||||
echo 'archivo nivel2' > source/nivel1/nivel2/file2.txt
|
||||
|
||||
echo "Estructura creada:"
|
||||
find source -type f -o -type d | sort
|
||||
|
||||
# Crear volumen HFS
|
||||
echo ""
|
||||
echo "[2] Creando volumen HFS..."
|
||||
dd if=/dev/zero of=test.hfs bs=1M count=5 2>/dev/null
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hformat -l 'TestRec' test.hfs 2>&1 | head -n 3
|
||||
|
||||
# Montar volumen
|
||||
echo ""
|
||||
echo "[3] Montando volumen..."
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hmount test.hfs
|
||||
|
||||
# Verificar que está vacío
|
||||
echo ""
|
||||
echo "[4] Contenido inicial (debe estar vacío):"
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hls || echo "(vacío)"
|
||||
|
||||
# Test 1: Intentar copiar SIN -R (debe fallar)
|
||||
echo ""
|
||||
echo "[5] Test 1: Copiar directorio SIN -R (debe fallar con EISDIR)..."
|
||||
if /mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hcopy source :source 2>&1; then
|
||||
echo "❌ FALLÓ: Debería rechazar el directorio sin -R"
|
||||
exit 1
|
||||
else
|
||||
echo "✓ Correctamente rechazó el directorio sin -R"
|
||||
fi
|
||||
|
||||
# Test 2: Copiar CON -R (debe funcionar)
|
||||
echo ""
|
||||
echo "[6] Test 2: Copiar directorio CON -R (debe funcionar)..."
|
||||
if /mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hcopy -R source :source 2>&1; then
|
||||
echo "✓ hcopy -R ejecutado exitosamente"
|
||||
else
|
||||
echo "❌ FALLÓ: hcopy -R retornó error"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 3: Verificar estructura de directorios
|
||||
echo ""
|
||||
echo "[7] Test 3: Verificando estructura de directorios..."
|
||||
echo "Directorios en raíz:"
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hls
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:"
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hls :source
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:nivel1:"
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hls :source:nivel1
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:nivel1:nivel2:"
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hls :source:nivel1:nivel2
|
||||
|
||||
# Test 4: Verificar archivos
|
||||
echo ""
|
||||
echo "[8] Test 4: Verificando contenido de archivos..."
|
||||
|
||||
# Copiar de vuelta y verificar
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hcopy :source:file_root.txt /tmp/test_rec/verify_root.txt
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hcopy :source:nivel1:file1.txt /tmp/test_rec/verify_nivel1.txt
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil hcopy :source:nivel1:nivel2:file2.txt /tmp/test_rec/verify_nivel2.txt
|
||||
|
||||
echo "Contenido de file_root.txt:"
|
||||
cat /tmp/test_rec/verify_root.txt
|
||||
|
||||
echo "Contenido de file1.txt:"
|
||||
cat /tmp/test_rec/verify_nivel1.txt
|
||||
|
||||
echo "Contenido de file2.txt:"
|
||||
cat /tmp/test_rec/verify_nivel2.txt
|
||||
|
||||
# Limpiar
|
||||
echo ""
|
||||
echo "[9] Desmontando..."
|
||||
/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil humount
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " ✓ TODOS LOS TESTS PASARON"
|
||||
echo "========================================="
|
||||
@@ -1,144 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test hcopy recursive directory copying functionality
|
||||
# This test creates a directory structure on Unix and copies it to an HFS volume
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Utilities
|
||||
HFSUTIL="$PROJECT_ROOT/hfsutil"
|
||||
HMOUNT="$PROJECT_ROOT/hmount"
|
||||
HUMOUNT="$PROJECT_ROOT/humount"
|
||||
HCOPY="$PROJECT_ROOT/hcopy"
|
||||
HLS="$PROJECT_ROOT/hls"
|
||||
HMKDIR="$PROJECT_ROOT/hmkdir"
|
||||
HCD="$PROJECT_ROOT/hcd"
|
||||
HFORMAT="$PROJECT_ROOT/hformat"
|
||||
|
||||
# Test directory
|
||||
TEST_DIR="$SCRIPT_DIR/temp_recursive_test"
|
||||
TEST_VOLUME="$TEST_DIR/test_volume.hfs"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
pass() {
|
||||
echo -e "${GREEN}[PASS]${NC} $*"
|
||||
}
|
||||
|
||||
fail() {
|
||||
echo -e "${RED}[FAIL]${NC} $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $*"
|
||||
}
|
||||
|
||||
info() {
|
||||
echo "[INFO] $*"
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
"$HUMOUNT" 2>/dev/null || true
|
||||
rm -rf "$TEST_DIR"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "========================================"
|
||||
echo " hcopy Recursive Directory Test"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# Create test directory structure
|
||||
info "Creating test directory structure..."
|
||||
mkdir -p "$TEST_DIR"
|
||||
mkdir -p "$TEST_DIR/source/subdir1"
|
||||
mkdir -p "$TEST_DIR/source/subdir2/nested"
|
||||
echo "test file 1" > "$TEST_DIR/source/file1.txt"
|
||||
echo "test file 2" > "$TEST_DIR/source/subdir1/file2.txt"
|
||||
echo "test file 3" > "$TEST_DIR/source/subdir2/file3.txt"
|
||||
echo "nested file" > "$TEST_DIR/source/subdir2/nested/file4.txt"
|
||||
|
||||
# Create HFS volume
|
||||
info "Creating HFS volume..."
|
||||
dd if=/dev/zero of="$TEST_VOLUME" bs=1M count=5 2>/dev/null || fail "Failed to create volume file"
|
||||
"$HFORMAT" -l "RecursiveTest" "$TEST_VOLUME" >/dev/null 2>&1 || fail "Failed to format volume"
|
||||
|
||||
# Mount volume
|
||||
info "Mounting volume..."
|
||||
"$HMOUNT" "$TEST_VOLUME" || fail "Failed to mount volume"
|
||||
|
||||
# Test 1: Verify directory is rejected without -R flag
|
||||
info "Test 1: Directory without -R flag should fail..."
|
||||
if "$HCOPY" "$TEST_DIR/source" : 2>/dev/null; then
|
||||
fail "hcopy should reject directory without -R flag"
|
||||
else
|
||||
pass "Directory rejected without -R flag"
|
||||
fi
|
||||
|
||||
# Test 2: Copy directory with -R flag
|
||||
info "Test 2: Copy directory with -R flag..."
|
||||
if "$HCOPY" -R "$TEST_DIR/source" : 2>/dev/null; then
|
||||
pass "hcopy accepted directory with -R flag"
|
||||
else
|
||||
fail "hcopy failed with -R flag"
|
||||
fi
|
||||
|
||||
# Test 3: Verify directory was created
|
||||
info "Test 3: Verifying directory structure..."
|
||||
if "$HLS" :source >/dev/null 2>&1; then
|
||||
pass "Source directory created on HFS volume"
|
||||
else
|
||||
fail "Source directory not found on HFS volume"
|
||||
fi
|
||||
|
||||
# Test 4: Verify subdirectories
|
||||
if "$HLS" :source:subdir1 >/dev/null 2>&1; then
|
||||
pass "Subdirectory 1 created"
|
||||
else
|
||||
warn "Subdirectory 1 not found (may be expected if recursive copy not fully implemented)"
|
||||
fi
|
||||
|
||||
if "$HLS" :source:subdir2 >/dev/null 2>&1; then
|
||||
pass "Subdirectory 2 created"
|
||||
else
|
||||
warn "Subdirectory 2 not found"
|
||||
fi
|
||||
|
||||
if "$HLS" :source:subdir2:nested >/dev/null 2>&1; then
|
||||
pass "Nested subdirectory created"
|
||||
else
|
||||
warn "Nested subdirectory not found"
|
||||
fi
|
||||
|
||||
# Test 5: Verify files
|
||||
info "Test 4: Verifying files..."
|
||||
if "$HLS" :source | grep -q "file1.txt"; then
|
||||
pass "File1 found in root directory"
|
||||
else
|
||||
warn "File1 not found in root directory"
|
||||
fi
|
||||
|
||||
if "$HLS" :source:subdir1 | grep -q "file2.txt" 2>/dev/null; then
|
||||
pass "File2 found in subdir1"
|
||||
else
|
||||
warn "File2 not found in subdir1"
|
||||
fi
|
||||
|
||||
# Unmount
|
||||
info "Unmounting volume..."
|
||||
"$HUMOUNT" || warn "Failed to unmount cleanly"
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " Recursive copy test completed"
|
||||
echo "========================================"
|
||||
@@ -1,67 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Simple test for hcopy -R flag support
|
||||
# This tests that the flag parsing works correctly
|
||||
|
||||
set -e
|
||||
|
||||
HFSUTIL=$(cd "$(dirname "$0")" && pwd)/../hfsutil
|
||||
|
||||
if [ ! -f "$HFSUTIL" ]; then
|
||||
echo "ERROR: hfsutil not found at $HFSUTIL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Testing hcopy -R flag..."
|
||||
echo "=========================================="
|
||||
|
||||
# Test 1: Verify -R flag is recognized
|
||||
echo ""
|
||||
echo "Test 1: Verify -R flag is recognized in usage"
|
||||
OUTPUT=$($HFSUTIL hcopy 2>&1 || true)
|
||||
if echo "$OUTPUT" | grep -q "\-R"; then
|
||||
echo "[PASS] -R flag appears in hcopy usage message"
|
||||
else
|
||||
echo "[FAIL] -R flag not found in usage message"
|
||||
echo "Usage output:"
|
||||
echo "$OUTPUT"
|
||||
fi
|
||||
|
||||
# Test 2: Verify hcopy accepts the -R option without error (no volume needed)
|
||||
echo ""
|
||||
echo "Test 2: Verify hcopy accepts -R option"
|
||||
# This will fail because no files/volumes exist, but should fail with missing file error, not flag error
|
||||
OUTPUT=$($HFSUTIL hcopy -R nonexistent /tmp 2>&1 || true)
|
||||
if echo "$OUTPUT" | grep -qi "no such file\|not found"; then
|
||||
echo "[PASS] hcopy accepts -R flag and fails on missing file (expected)"
|
||||
elif echo "$OUTPUT" | grep -qi "invalid option\|unrecognized"; then
|
||||
echo "[FAIL] hcopy does not recognize -R flag"
|
||||
echo "Error output:"
|
||||
echo "$OUTPUT"
|
||||
else
|
||||
echo "[WARN] Unexpected error output:"
|
||||
echo "$OUTPUT"
|
||||
fi
|
||||
|
||||
# Test 3: Verify older hcopy behavior (reject directories without -R)
|
||||
echo ""
|
||||
echo "Test 3: Test directory rejection without -R"
|
||||
mkdir -p /tmp/test_hcopy_source
|
||||
echo "test file" > /tmp/test_hcopy_source/file.txt
|
||||
|
||||
# The command should fail with EISDIR when trying to copy directory without -R
|
||||
OUTPUT=$($HFSUTIL hcopy /tmp/test_hcopy_source /tmp 2>&1 || true)
|
||||
if echo "$OUTPUT" | grep -qi "is a directory"; then
|
||||
echo "[PASS] hcopy rejects directory without -R flag"
|
||||
elif echo "$OUTPUT" | grep -qi "eisdir"; then
|
||||
echo "[PASS] hcopy rejects directory (EISDIR error)"
|
||||
else
|
||||
# If no directory error, that's OK too - depends on where it fails
|
||||
echo "[INFO] No directory rejection error (may be expected): $OUTPUT"
|
||||
fi
|
||||
|
||||
rm -rf /tmp/test_hcopy_source
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Simple flag tests completed successfully!"
|
||||
@@ -1,182 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " Test de Integridad HFS"
|
||||
echo " Verificación contra herramientas del sistema"
|
||||
echo "========================================="
|
||||
|
||||
# Limpiar entorno
|
||||
rm -rf /tmp/test_integrity
|
||||
mkdir -p /tmp/test_integrity
|
||||
cd /tmp/test_integrity
|
||||
|
||||
HFSUTIL="/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil"
|
||||
|
||||
echo ""
|
||||
echo "[1] Creando archivos de prueba..."
|
||||
mkdir -p testdata/subdir
|
||||
echo "Contenido archivo 1" > testdata/file1.txt
|
||||
echo "Contenido archivo 2 en subdirectorio" > testdata/subdir/file2.txt
|
||||
dd if=/dev/urandom of=testdata/binary.bin bs=1024 count=10 2>/dev/null
|
||||
echo "Creados:"
|
||||
find testdata -type f
|
||||
|
||||
# Guardar checksums originales
|
||||
echo ""
|
||||
echo "[2] Calculando checksums de archivos originales..."
|
||||
md5sum testdata/file1.txt > checksums_original.txt
|
||||
md5sum testdata/subdir/file2.txt >> checksums_original.txt
|
||||
md5sum testdata/binary.bin >> checksums_original.txt
|
||||
echo "Checksums originales:"
|
||||
cat checksums_original.txt
|
||||
|
||||
echo ""
|
||||
echo "[3] Creando volumen HFS con hfsutil..."
|
||||
dd if=/dev/zero of=test.hfs bs=1M count=10 2>/dev/null
|
||||
$HFSUTIL hformat -l 'IntegrityTest' test.hfs 2>&1 | head -n 3
|
||||
|
||||
echo ""
|
||||
echo "[4] Copiando archivos con hfsutil..."
|
||||
$HFSUTIL hmount test.hfs
|
||||
$HFSUTIL hmkdir :testdata
|
||||
$HFSUTIL hmkdir :testdata:subdir
|
||||
$HFSUTIL hcopy -t testdata/file1.txt :testdata:file1.txt
|
||||
$HFSUTIL hcopy -t testdata/subdir/file2.txt :testdata:subdir:file2.txt
|
||||
$HFSUTIL hcopy -r testdata/binary.bin :testdata:binary.bin
|
||||
|
||||
echo ""
|
||||
echo "[5] Verificando con hfsutil hls..."
|
||||
$HFSUTIL hls :testdata
|
||||
$HFSUTIL hls :testdata:subdir
|
||||
|
||||
echo ""
|
||||
echo "[6] Copiando archivos DE VUELTA con hfsutil..."
|
||||
mkdir -p extracted_hfsutil
|
||||
$HFSUTIL hcopy -t :testdata:file1.txt extracted_hfsutil/file1.txt
|
||||
$HFSUTIL hcopy -t :testdata:subdir:file2.txt extracted_hfsutil/file2.txt
|
||||
$HFSUTIL hcopy -r :testdata:binary.bin extracted_hfsutil/binary.bin
|
||||
$HFSUTIL humount
|
||||
|
||||
echo ""
|
||||
echo "[7] Calculando checksums de archivos extraídos con hfsutil..."
|
||||
md5sum extracted_hfsutil/file1.txt > checksums_hfsutil.txt
|
||||
md5sum extracted_hfsutil/file2.txt >> checksums_hfsutil.txt
|
||||
md5sum extracted_hfsutil/binary.bin >> checksums_hfsutil.txt
|
||||
echo "Checksums extraídos:"
|
||||
cat checksums_hfsutil.txt
|
||||
|
||||
echo ""
|
||||
echo "[8] Comparando checksums (hfsutil roundtrip)..."
|
||||
if diff -u <(awk '{print $1}' checksums_original.txt | sort) <(awk '{print $1}' checksums_hfsutil.txt | sort); then
|
||||
echo "✓ Los checksums coinciden (hfsutil → HFS → hfsutil)"
|
||||
else
|
||||
echo "❌ Los checksums NO coinciden"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[9] Intentando montar con herramientas del kernel (si disponibles)..."
|
||||
|
||||
# Verificar si podemos usar mount nativo
|
||||
if command -v mount >/dev/null 2>&1 && [ -d /sys/module/hfs ]; then
|
||||
echo "Módulo HFS del kernel detectado, intentando mount nativo..."
|
||||
mkdir -p /tmp/test_integrity/mountpoint
|
||||
|
||||
# Intentar montar (probablemente requiera sudo)
|
||||
if sudo mount -t hfs -o loop test.hfs mountpoint 2>/dev/null; then
|
||||
echo "✓ Montado con mount del kernel"
|
||||
|
||||
echo ""
|
||||
echo "[10] Listando archivos con ls nativo..."
|
||||
ls -la mountpoint/
|
||||
ls -la mountpoint/testdata/ 2>/dev/null || echo "No se puede listar testdata"
|
||||
|
||||
echo ""
|
||||
echo "[11] Extrayendo archivos con cp nativo..."
|
||||
mkdir -p extracted_native
|
||||
if cp mountpoint/testdata/file1.txt extracted_native/ 2>/dev/null; then
|
||||
echo "✓ Archivo extraído con cp nativo"
|
||||
|
||||
echo ""
|
||||
echo "[12] Verificando checksum contra mount nativo..."
|
||||
md5sum extracted_native/file1.txt
|
||||
original_md5=$(md5sum testdata/file1.txt | awk '{print $1}')
|
||||
native_md5=$(md5sum extracted_native/file1.txt | awk '{print $1}')
|
||||
|
||||
if [ "$original_md5" = "$native_md5" ]; then
|
||||
echo "✓ Checksum coincide con mount nativo del kernel"
|
||||
else
|
||||
echo "❌ Checksum NO coincide con mount nativo"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "⚠ No se puede copiar archivos del mount nativo (permisos?)"
|
||||
fi
|
||||
|
||||
sudo umount mountpoint 2>/dev/null || true
|
||||
else
|
||||
echo "⚠ No se pudo montar con mount del kernel (requiere sudo o no compatible)"
|
||||
fi
|
||||
else
|
||||
echo "⚠ Módulo HFS del kernel no disponible, saltando test de mount nativo"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[13] Verificando estructura del volumen con hexdump..."
|
||||
echo "Signature del volumen HFS (debe ser 0x4244 'BD'):"
|
||||
hexdump -C test.hfs -s 1024 -n 2 | head -n 1
|
||||
|
||||
echo ""
|
||||
echo "[14] Buscando nombres de archivos en el volumen..."
|
||||
if strings test.hfs | grep -q "file1.txt"; then
|
||||
echo "✓ Encontrado 'file1.txt' en el volumen"
|
||||
else
|
||||
echo "⚠ No se encontró 'file1.txt' en el volumen (puede ser normal si está codificado)"
|
||||
fi
|
||||
|
||||
if strings test.hfs | grep -q "binary.bin"; then
|
||||
echo "✓ Encontrado 'binary.bin' en el volumen"
|
||||
else
|
||||
echo "⚠ No se encontró 'binary.bin' en el volumen"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[15] Verificando tamaño del volumen..."
|
||||
VOLUME_SIZE=$(stat -c%s test.hfs 2>/dev/null || stat -f%z test.hfs 2>/dev/null)
|
||||
echo "Tamaño del volumen: $VOLUME_SIZE bytes"
|
||||
|
||||
if [ "$VOLUME_SIZE" -eq $((10 * 1024 * 1024)) ]; then
|
||||
echo "✓ Tamaño correcto (10MB)"
|
||||
else
|
||||
echo "⚠ Tamaño inesperado"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[16] Test de escritura/lectura con hfsck..."
|
||||
if [ -f "/mnt/c/Users/Usuario/source/repos/hfsutils/hfsck/hfsck" ]; then
|
||||
echo "Ejecutando hfsck en el volumen..."
|
||||
if /mnt/c/Users/Usuario/source/repos/hfsutils/hfsck/hfsck -n test.hfs 2>&1 | head -n 20; then
|
||||
echo "✓ hfsck no reportó errores graves"
|
||||
else
|
||||
EXIT_CODE=$?
|
||||
if [ $EXIT_CODE -eq 8 ]; then
|
||||
echo "⚠ hfsck retornó código 8 (común en esta versión)"
|
||||
else
|
||||
echo "⚠ hfsck retornó código $EXIT_CODE"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "⚠ hfsck no disponible"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " ✓ TEST DE INTEGRIDAD COMPLETADO"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Resumen:"
|
||||
echo " - Archivos escritos con hfsutil: ✓"
|
||||
echo " - Archivos leídos con hfsutil: ✓"
|
||||
echo " - Checksums coinciden (roundtrip): ✓"
|
||||
echo " - Estructura HFS válida: ✓"
|
||||
@@ -1,163 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Test script to validate HFS/HFS+ specification conformance
|
||||
# Tests alternate header locations and Volume Header field values
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo "========================================="
|
||||
echo " HFS/HFS+ Specification Validation Test"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Cleanup
|
||||
cleanup() {
|
||||
rm -f test_hfs_spec.img test_hfsplus_spec.img
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Test 1: HFS Classic Volume
|
||||
echo -e "${BLUE}[TEST 1]${NC} HFS Classic Specification Conformance"
|
||||
echo "Creating 10MB HFS volume..."
|
||||
dd if=/dev/zero of=test_hfs_spec.img bs=1M count=10 2>/dev/null
|
||||
./build/standalone/mkfs.hfs -l "TestHFS" test_hfs_spec.img >/dev/null 2>&1
|
||||
|
||||
FILE_SIZE=$(stat -c%s test_hfs_spec.img)
|
||||
ALTERNATE_MDB_OFFSET=$((FILE_SIZE - 1024))
|
||||
|
||||
echo -e "${BLUE}[INFO]${NC} File size: $FILE_SIZE bytes"
|
||||
echo -e "${BLUE}[INFO]${NC} Alternate MDB should be at offset: $ALTERNATE_MDB_OFFSET (file_size - 1024)"
|
||||
|
||||
# Check primary MDB at offset 1024
|
||||
echo -e "${BLUE}[CHECK]${NC} Primary MDB signature at offset 1024..."
|
||||
PRIMARY_SIG=$(xxd -s 1024 -l 2 -p test_hfs_spec.img)
|
||||
if [ "$PRIMARY_SIG" = "4244" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} Primary MDB signature: 0x4244 ('BD')"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} Primary MDB signature: 0x$PRIMARY_SIG (expected 0x4244)"
|
||||
fi
|
||||
|
||||
# Check alternate MDB at file_size - 1024
|
||||
echo -e "${BLUE}[CHECK]${NC} Alternate MDB signature at offset $ALTERNATE_MDB_OFFSET..."
|
||||
ALT_SIG=$(xxd -s $ALTERNATE_MDB_OFFSET -l 2 -p test_hfs_spec.img)
|
||||
if [ "$ALT_SIG" = "4244" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} Alternate MDB signature: 0x4244 ('BD') at correct offset"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} Alternate MDB signature: 0x$ALT_SIG at offset $ALTERNATE_MDB_OFFSET (expected 0x4244)"
|
||||
fi
|
||||
|
||||
# Check drAtrb field (offset 1024 + 4 = 1028)
|
||||
echo -e "${BLUE}[CHECK]${NC} HFS drAtrb (attributes) at offset 1028..."
|
||||
DRATRB=$(xxd -s 1028 -l 2 -p test_hfs_spec.img)
|
||||
if [ "$DRATRB" = "0100" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} drAtrb: 0x0100 (unmounted bit set)"
|
||||
else
|
||||
echo -e "${YELLOW}[WARN]${NC} drAtrb: 0x$DRATRB (expected 0x0100)"
|
||||
fi
|
||||
|
||||
# Check drNxtCNID (offset 1024 + 84 = 1108)
|
||||
echo -e "${BLUE}[CHECK]${NC} HFS drNxtCNID (next catalog ID) at offset 1108..."
|
||||
DRNXTCNID=$(xxd -s 1108 -l 4 -p test_hfs_spec.img)
|
||||
if [ "$DRNXTCNID" = "00000010" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} drNxtCNID: 0x00000010 (16 decimal)"
|
||||
else
|
||||
echo -e "${YELLOW}[WARN]${NC} drNxtCNID: 0x$DRNXTCNID (expected 0x00000010)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Test 2: HFS+ Volume
|
||||
echo -e "${BLUE}[TEST 2]${NC} HFS+ Specification Conformance"
|
||||
echo "Creating 10MB HFS+ volume..."
|
||||
dd if=/dev/zero of=test_hfsplus_spec.img bs=1M count=10 2>/dev/null
|
||||
./build/standalone/mkfs.hfs+ -l "TestHFSPlus" test_hfsplus_spec.img >/dev/null 2>&1
|
||||
|
||||
FILE_SIZE=$(stat -c%s test_hfsplus_spec.img)
|
||||
ALTERNATE_VH_OFFSET=$((FILE_SIZE - 1024))
|
||||
|
||||
echo -e "${BLUE}[INFO]${NC} File size: $FILE_SIZE bytes"
|
||||
echo -e "${BLUE}[INFO]${NC} Alternate Volume Header should be at offset: $ALTERNATE_VH_OFFSET (file_size - 1024)"
|
||||
|
||||
# Check primary Volume Header at offset 1024
|
||||
echo -e "${BLUE}[CHECK]${NC} Primary Volume Header signature at offset 1024..."
|
||||
PRIMARY_SIG=$(xxd -s 1024 -l 2 -p test_hfsplus_spec.img)
|
||||
if [ "$PRIMARY_SIG" = "482b" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} Primary VH signature: 0x482B ('H+')"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} Primary VH signature: 0x$PRIMARY_SIG (expected 0x482B)"
|
||||
fi
|
||||
|
||||
# Check alternate Volume Header at file_size - 1024
|
||||
echo -e "${BLUE}[CHECK]${NC} Alternate Volume Header signature at offset $ALTERNATE_VH_OFFSET..."
|
||||
ALT_SIG=$(xxd -s $ALTERNATE_VH_OFFSET -l 2 -p test_hfsplus_spec.img)
|
||||
if [ "$ALT_SIG" = "482b" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} Alternate VH signature: 0x482B ('H+') at correct offset"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} Alternate VH signature: 0x$ALT_SIG at offset $ALTERNATE_VH_OFFSET (expected 0x482B)"
|
||||
fi
|
||||
|
||||
# Check attributes field (offset 1024 + 4 = 1028)
|
||||
echo -e "${BLUE}[CHECK]${NC} HFS+ attributes at offset 1028..."
|
||||
ATTRIBUTES=$(xxd -s 1028 -l 4 -p test_hfsplus_spec.img)
|
||||
if [ "$ATTRIBUTES" = "00000100" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} attributes: 0x00000100 (unmounted bit set)"
|
||||
elif [ "$ATTRIBUTES" = "00002100" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} attributes: 0x00002100 (unmounted + journaled bits set)"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} attributes: 0x$ATTRIBUTES (expected 0x00000100 or 0x00002100)"
|
||||
fi
|
||||
|
||||
# Check blockSize (offset 1024 + 40 = 1064)
|
||||
echo -e "${BLUE}[CHECK]${NC} HFS+ blockSize at offset 1064..."
|
||||
BLOCKSIZE=$(xxd -s 1064 -l 4 -p test_hfsplus_spec.img)
|
||||
echo -e "${BLUE}[INFO]${NC} blockSize: 0x$BLOCKSIZE"
|
||||
|
||||
# Check rsrcClumpSize (offset 1024 + 56 = 1080)
|
||||
echo -e "${BLUE}[CHECK]${NC} HFS+ rsrcClumpSize at offset 1080..."
|
||||
RSRC_CLUMP=$(xxd -s 1080 -l 4 -p test_hfsplus_spec.img)
|
||||
if [ "$RSRC_CLUMP" != "00000000" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} rsrcClumpSize: 0x$RSRC_CLUMP (non-zero)"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} rsrcClumpSize: 0x$RSRC_CLUMP (should be non-zero)"
|
||||
fi
|
||||
|
||||
# Check dataClumpSize (offset 1024 + 60 = 1084)
|
||||
echo -e "${BLUE}[CHECK]${NC} HFS+ dataClumpSize at offset 1084..."
|
||||
DATA_CLUMP=$(xxd -s 1084 -l 4 -p test_hfsplus_spec.img)
|
||||
if [ "$DATA_CLUMP" != "00000000" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} dataClumpSize: 0x$DATA_CLUMP (non-zero)"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} dataClumpSize: 0x$DATA_CLUMP (should be non-zero)"
|
||||
fi
|
||||
|
||||
# Check nextCatalogID (offset 1024 + 64 = 1088)
|
||||
echo -e "${BLUE}[CHECK]${NC} HFS+ nextCatalogID at offset 1088..."
|
||||
NEXT_CNID=$(xxd -s 1088 -l 4 -p test_hfsplus_spec.img)
|
||||
if [ "$NEXT_CNID" = "00000010" ]; then
|
||||
echo -e "${GREEN}[PASS]${NC} nextCatalogID: 0x00000010 (16 decimal)"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} nextCatalogID: 0x$NEXT_CNID (expected 0x00000010)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " Validation Summary"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Per Apple TN1150 and Wikipedia documentation:"
|
||||
echo " - Alternate headers MUST be at file_size - 1024 bytes"
|
||||
echo " - HFS signature: 0x4244 ('BD')"
|
||||
echo " - HFS+ signature: 0x482B ('H+') or 0x4858 ('HX' for HFSX)"
|
||||
echo " - nextCatalogID >= 16 (kHFSFirstUserCatalogNodeID)"
|
||||
echo " - attributes bit 8 set (0x0100 = kHFSVolumeUnmountedBit)"
|
||||
echo " - rsrcClumpSize and dataClumpSize must be non-zero"
|
||||
echo ""
|
||||
@@ -1,151 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Complete HFS+ Implementation Test Script
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== HFS+ Complete Implementation Test ==="
|
||||
echo
|
||||
|
||||
# Clean up any existing test files
|
||||
echo "Cleaning up previous test files..."
|
||||
rm -f test_hfs.img test_hfsplus.img test_mkfs.img test_comparison.img
|
||||
rm -f fsck.hfs+ mkfs.hfs+ mkfs.hfs
|
||||
|
||||
echo "Creating test images..."
|
||||
dd if=/dev/zero of=test_hfs.img bs=1M count=50 2>/dev/null
|
||||
dd if=/dev/zero of=test_hfsplus.img bs=1M count=50 2>/dev/null
|
||||
dd if=/dev/zero of=test_mkfs.img bs=1M count=50 2>/dev/null
|
||||
dd if=/dev/zero of=test_comparison.img bs=1M count=50 2>/dev/null
|
||||
|
||||
echo
|
||||
echo "=== Test 1: Traditional HFS Formatting ==="
|
||||
echo "Formatting with traditional HFS..."
|
||||
../hfsutil hformat -l "Traditional HFS" test_hfs.img
|
||||
|
||||
echo
|
||||
echo "=== Test 2: HFS+ Formatting with hformat ==="
|
||||
echo "Formatting with HFS+ using hformat -t hfs+..."
|
||||
../hfsutil hformat -t hfs+ -l "HFS Plus Volume" test_hfsplus.img
|
||||
|
||||
echo
|
||||
echo "=== Test 3: HFS+ Formatting with mkfs.hfs+ ==="
|
||||
echo "Creating mkfs.hfs+ symlink and testing..."
|
||||
ln -sf ../hfsutil mkfs.hfs+
|
||||
./mkfs.hfs+ -l "mkfs HFS Plus" test_mkfs.img
|
||||
|
||||
echo
|
||||
echo "=== Test 4: HFS Formatting with mkfs.hfs ==="
|
||||
echo "Creating mkfs.hfs symlink and testing..."
|
||||
ln -sf ../hfsutil mkfs.hfs
|
||||
./mkfs.hfs -l "mkfs HFS" test_comparison.img
|
||||
|
||||
echo
|
||||
echo "=== Test 5: Filesystem Detection ==="
|
||||
echo "Creating fsck.hfs+ symlink for testing..."
|
||||
ln -sf ../hfsck/hfsck fsck.hfs+
|
||||
|
||||
echo
|
||||
echo "Testing filesystem detection on each volume:"
|
||||
|
||||
echo "1. Traditional HFS volume:"
|
||||
if ../hfsck/hfsck --version 2>&1 | head -1; then
|
||||
echo " ✓ hfsck available"
|
||||
fi
|
||||
|
||||
echo "2. HFS+ volume (hformat):"
|
||||
if ./fsck.hfs+ --version 2>&1 | head -1; then
|
||||
echo " ✓ fsck.hfs+ available"
|
||||
fi
|
||||
|
||||
echo "3. HFS+ volume (mkfs.hfs+):"
|
||||
echo " ✓ Same as above"
|
||||
|
||||
echo "4. HFS volume (mkfs.hfs):"
|
||||
echo " ✓ Same as traditional HFS"
|
||||
|
||||
echo
|
||||
echo "=== Test 6: Volume Signature Verification ==="
|
||||
echo "Checking volume signatures with hexdump..."
|
||||
|
||||
echo "Traditional HFS (should show 'BD' at offset 0x400):"
|
||||
hexdump -C test_hfs.img | grep "00000400" | head -1
|
||||
|
||||
echo "HFS+ volume (hformat) (should show 'H+' at HFS+ header location):"
|
||||
hexdump -C test_hfsplus.img | grep "48 2b" | head -1
|
||||
|
||||
echo "HFS+ volume (mkfs.hfs+) (should show 'H+' at HFS+ header location):"
|
||||
hexdump -C test_mkfs.img | grep "48 2b" | head -1
|
||||
|
||||
echo "HFS volume (mkfs.hfs) (should show 'BD' at offset 0x400):"
|
||||
hexdump -C test_comparison.img | grep "00000400" | head -1
|
||||
|
||||
echo
|
||||
echo "=== Test 7: Program Name Detection ==="
|
||||
echo "Testing program name detection..."
|
||||
|
||||
echo "hformat with -t hfs+:"
|
||||
echo " ✓ Forces HFS+ formatting"
|
||||
|
||||
echo "mkfs.hfs+:"
|
||||
echo " ✓ Automatically uses HFS+ formatting"
|
||||
|
||||
echo "mkfs.hfs:"
|
||||
echo " ✓ Automatically uses HFS formatting"
|
||||
|
||||
echo "fsck.hfs+:"
|
||||
echo " ✓ Forces HFS+ checking"
|
||||
|
||||
echo
|
||||
echo "=== Test 8: Volume Information ==="
|
||||
echo "Displaying volume information..."
|
||||
|
||||
echo "File sizes:"
|
||||
ls -lh test_*.img
|
||||
|
||||
echo
|
||||
echo "Volume signatures (first few bytes of filesystem headers):"
|
||||
echo "HFS signature (BD = 0x4244):"
|
||||
echo "HFS+ signature (H+ = 0x482B):"
|
||||
|
||||
echo
|
||||
echo "=== Test Summary ==="
|
||||
echo "✓ Traditional HFS formatting working"
|
||||
echo "✓ HFS+ formatting implemented and working"
|
||||
echo "✓ Program name detection working (mkfs.hfs, mkfs.hfs+, fsck.hfs+)"
|
||||
echo "✓ Filesystem type selection working (-t option)"
|
||||
echo "✓ Volume signatures correctly written"
|
||||
echo "✓ Standard Unix filesystem utility conventions followed"
|
||||
echo "✓ Backward compatibility maintained"
|
||||
|
||||
echo
|
||||
echo "=== Implementation Status ==="
|
||||
echo "✓ HFS+ Volume Header creation"
|
||||
echo "✓ HFS+ Allocation file setup"
|
||||
echo "✓ HFS+ Extents overflow file setup"
|
||||
echo "✓ HFS+ Catalog file setup"
|
||||
echo "✓ HFS+ Attributes file placeholder"
|
||||
echo "✓ Proper endianness handling"
|
||||
echo "✓ Date validation and safe time handling"
|
||||
echo "✓ Block size optimization"
|
||||
echo "✓ Volume size calculation"
|
||||
|
||||
echo
|
||||
echo "=== Next Steps for Full HFS+ Support ==="
|
||||
echo "• Implement B-tree initialization for catalog and extents files"
|
||||
echo "• Add root directory creation in catalog"
|
||||
echo "• Implement allocation bitmap initialization"
|
||||
echo "• Add journal support (optional)"
|
||||
echo "• Implement Unicode filename support"
|
||||
echo "• Add extended attributes support"
|
||||
echo "• Implement HFS+ fsck functionality"
|
||||
|
||||
echo
|
||||
echo "=== Cleanup ==="
|
||||
echo "Removing test files..."
|
||||
rm -f test_hfs.img test_hfsplus.img test_mkfs.img test_comparison.img
|
||||
rm -f fsck.hfs+ mkfs.hfs+ mkfs.hfs
|
||||
|
||||
echo
|
||||
echo "HFS+ implementation test completed successfully!"
|
||||
echo "The framework is in place for full HFS+ support."
|
||||
@@ -1,159 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test HFS+ Journaling Support
|
||||
# Tests the journaling functionality in fsck.hfs+
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
UTILS_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo "=== HFS+ Journaling Support Test ==="
|
||||
echo "Testing fsck.hfs+ journaling functionality"
|
||||
echo
|
||||
|
||||
# Check if fsck.hfs+ exists
|
||||
if [ ! -f "$UTILS_DIR/fsck.hfs+" ] && [ ! -f "$UTILS_DIR/hfsck/hfsck" ]; then
|
||||
echo -e "${RED}✗${NC} fsck.hfs+ not found. Please build first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use the appropriate binary
|
||||
if [ -f "$UTILS_DIR/fsck.hfs+" ]; then
|
||||
FSCK_HFSPLUS="$UTILS_DIR/fsck.hfs+"
|
||||
else
|
||||
FSCK_HFSPLUS="$UTILS_DIR/hfsck/hfsck"
|
||||
fi
|
||||
|
||||
echo "Using fsck binary: $FSCK_HFSPLUS"
|
||||
echo
|
||||
|
||||
# Test 1: Version check with journaling support
|
||||
echo "=== Test 1: Version Check ==="
|
||||
echo "Checking if fsck.hfs+ reports journaling support..."
|
||||
|
||||
if $FSCK_HFSPLUS --version 2>&1 | grep -q "HFS+ filesystem checking"; then
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ version check passed"
|
||||
else
|
||||
echo -e "${RED}✗${NC} fsck.hfs+ version check failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 2: Help/Usage check
|
||||
echo
|
||||
echo "=== Test 2: Help Check ==="
|
||||
echo "Checking fsck.hfs+ help output..."
|
||||
|
||||
if $FSCK_HFSPLUS 2>&1 | grep -q "Usage:"; then
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ help output available"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} fsck.hfs+ help output not standard (may be normal)"
|
||||
fi
|
||||
|
||||
# Test 3: Invalid device handling
|
||||
echo
|
||||
echo "=== Test 3: Invalid Device Handling ==="
|
||||
echo "Testing fsck.hfs+ with non-existent device..."
|
||||
|
||||
if $FSCK_HFSPLUS /dev/nonexistent 2>/dev/null; then
|
||||
echo -e "${RED}✗${NC} fsck.hfs+ should fail with non-existent device"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ correctly handles non-existent device"
|
||||
fi
|
||||
|
||||
# Test 4: Create test image and check journaling detection
|
||||
echo
|
||||
echo "=== Test 4: HFS+ Image Creation and Journaling Detection ==="
|
||||
|
||||
# Create a test image
|
||||
TEST_IMAGE="$SCRIPT_DIR/test_journal.img"
|
||||
rm -f "$TEST_IMAGE"
|
||||
|
||||
echo "Creating 10MB test image..."
|
||||
dd if=/dev/zero of="$TEST_IMAGE" bs=1M count=10 2>/dev/null
|
||||
|
||||
# Try to format as HFS+ (this may not work without proper mkfs.hfs+)
|
||||
if [ -f "$UTILS_DIR/mkfs.hfs+" ]; then
|
||||
echo "Formatting as HFS+ with journaling..."
|
||||
if $UTILS_DIR/mkfs.hfs+ -l "Test Journal" "$TEST_IMAGE" 2>/dev/null; then
|
||||
echo -e "${GREEN}✓${NC} HFS+ image created successfully"
|
||||
|
||||
# Test fsck on the created image
|
||||
echo "Running fsck.hfs+ on created image..."
|
||||
if $FSCK_HFSPLUS -v "$TEST_IMAGE" 2>&1 | tee fsck_output.log; then
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ ran successfully on HFS+ image"
|
||||
|
||||
# Check if journaling was detected
|
||||
if grep -q "journal" fsck_output.log 2>/dev/null; then
|
||||
echo -e "${GREEN}✓${NC} Journaling support detected in output"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} No journaling messages (may be normal for new filesystem)"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} fsck.hfs+ had issues with created image (may be normal)"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} Could not create HFS+ image (mkfs.hfs+ may need improvement)"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} mkfs.hfs+ not available, skipping image creation test"
|
||||
fi
|
||||
|
||||
# Test 5: Log file creation
|
||||
echo
|
||||
echo "=== Test 5: Log File Creation ==="
|
||||
echo "Checking if hfsutils.log is created..."
|
||||
|
||||
# Run fsck to potentially create log
|
||||
$FSCK_HFSPLUS /dev/null 2>/dev/null || true
|
||||
|
||||
if [ -f "hfsutils.log" ]; then
|
||||
echo -e "${GREEN}✓${NC} hfsutils.log created successfully"
|
||||
echo "Log contents:"
|
||||
tail -5 hfsutils.log 2>/dev/null || echo " (empty or unreadable)"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} hfsutils.log not created (may be normal)"
|
||||
fi
|
||||
|
||||
# Test 6: Journaling code compilation check
|
||||
echo
|
||||
echo "=== Test 6: Journaling Code Integration ==="
|
||||
echo "Checking if journaling symbols are present in binary..."
|
||||
|
||||
if command -v nm >/dev/null 2>&1; then
|
||||
if nm "$FSCK_HFSPLUS" 2>/dev/null | grep -q journal; then
|
||||
echo -e "${GREEN}✓${NC} Journaling symbols found in binary"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} No journaling symbols found (may be stripped)"
|
||||
fi
|
||||
elif command -v strings >/dev/null 2>&1; then
|
||||
if strings "$FSCK_HFSPLUS" 2>/dev/null | grep -q journal; then
|
||||
echo -e "${GREEN}✓${NC} Journaling strings found in binary"
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} No journaling strings found"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} Cannot check binary symbols (nm/strings not available)"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
echo
|
||||
echo "=== Cleanup ==="
|
||||
rm -f "$TEST_IMAGE" fsck_output.log
|
||||
echo "Test files cleaned up"
|
||||
|
||||
echo
|
||||
echo "=== HFS+ Journaling Test Summary ==="
|
||||
echo -e "${GREEN}✓${NC} fsck.hfs+ journaling support test completed"
|
||||
echo -e "${GREEN}✓${NC} Basic functionality verified"
|
||||
echo -e "${GREEN}✓${NC} Error handling tested"
|
||||
echo
|
||||
echo "Note: Full journaling tests require actual HFS+ images with journals."
|
||||
echo "This test verifies that the journaling code is integrated and functional."
|
||||
@@ -1,165 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " Test Integridad de hcopy -R"
|
||||
echo " Verificación de copia recursiva"
|
||||
echo "========================================="
|
||||
|
||||
rm -rf /tmp/test_recursive_integrity
|
||||
mkdir -p /tmp/test_recursive_integrity
|
||||
cd /tmp/test_recursive_integrity
|
||||
|
||||
HFSUTIL="/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil"
|
||||
|
||||
echo ""
|
||||
echo "[1] Creando estructura de directorios compleja..."
|
||||
mkdir -p source/docs/manuals
|
||||
mkdir -p source/code/src
|
||||
mkdir -p source/data
|
||||
echo "Archivo raíz" > source/readme.txt
|
||||
echo "Manual 1" > source/docs/manual1.md
|
||||
echo "Manual 2" > source/docs/manuals/detailed.md
|
||||
echo "Código fuente" > source/code/src/main.c
|
||||
dd if=/dev/urandom of=source/data/binary.dat bs=512 count=5 2>/dev/null
|
||||
|
||||
echo "Estructura creada:"
|
||||
find source -type f | sort
|
||||
|
||||
echo ""
|
||||
echo "[2] Calculando checksums de todos los archivos..."
|
||||
find source -type f -exec md5sum {} \; | sort -k2 > checksums_original.txt
|
||||
echo "Total de archivos: $(wc -l < checksums_original.txt)"
|
||||
cat checksums_original.txt
|
||||
|
||||
echo ""
|
||||
echo "[3] Creando volumen HFS..."
|
||||
dd if=/dev/zero of=test.hfs bs=1M count=10 2>/dev/null
|
||||
$HFSUTIL hformat -l 'RecursiveTest' test.hfs 2>&1 | head -n 3
|
||||
|
||||
echo ""
|
||||
echo "[4] Copiando RECURSIVAMENTE con hcopy -R..."
|
||||
$HFSUTIL hmount test.hfs
|
||||
|
||||
if $HFSUTIL hcopy -R source :source 2>&1; then
|
||||
echo "✓ Copia recursiva exitosa"
|
||||
else
|
||||
echo "❌ Fallo en copia recursiva"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[5] Verificando estructura en HFS..."
|
||||
echo "Raíz del volumen:"
|
||||
$HFSUTIL hls
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:"
|
||||
$HFSUTIL hls :source
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:docs:"
|
||||
$HFSUTIL hls :source:docs
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:docs:manuals:"
|
||||
$HFSUTIL hls :source:docs:manuals
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:code:"
|
||||
$HFSUTIL hls :source:code
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:code:src:"
|
||||
$HFSUTIL hls :source:code:src
|
||||
|
||||
echo ""
|
||||
echo "Contenido de :source:data:"
|
||||
$HFSUTIL hls :source:data
|
||||
|
||||
echo ""
|
||||
echo "[6] Extrayendo archivo por archivo del HFS..."
|
||||
mkdir -p extracted
|
||||
$HFSUTIL hcopy -r :source:readme.txt extracted/readme.txt
|
||||
$HFSUTIL hcopy -r :source:docs:manual1.md extracted/manual1.md
|
||||
$HFSUTIL hcopy -r :source:docs:manuals:detailed.md extracted/detailed.md
|
||||
$HFSUTIL hcopy -r :source:code:src:main.c extracted/main.c
|
||||
$HFSUTIL hcopy -r :source:data:binary.dat extracted/binary.dat
|
||||
|
||||
echo ""
|
||||
echo "[7] Calculando checksums de archivos extraídos..."
|
||||
md5sum extracted/readme.txt > checksums_extracted.txt
|
||||
md5sum extracted/manual1.md >> checksums_extracted.txt
|
||||
md5sum extracted/detailed.md >> checksums_extracted.txt
|
||||
md5sum extracted/main.c >> checksums_extracted.txt
|
||||
md5sum extracted/binary.dat >> checksums_extracted.txt
|
||||
sort -k2 checksums_extracted.txt > checksums_extracted_sorted.txt
|
||||
|
||||
echo "Checksums extraídos:"
|
||||
cat checksums_extracted_sorted.txt
|
||||
|
||||
echo ""
|
||||
echo "[8] Comparando checksums de archivos binarios..."
|
||||
# Solo comparar el archivo binario (los de texto se convierten correctamente)
|
||||
ORIG_BIN=$(grep "binary.dat" checksums_original.txt | awk '{print $1}')
|
||||
EXTR_BIN=$(grep "binary.dat" checksums_extracted_sorted.txt | awk '{print $1}')
|
||||
|
||||
if [ "$ORIG_BIN" = "$EXTR_BIN" ]; then
|
||||
echo "✓ Checksum del archivo BINARIO coincide perfectamente: $ORIG_BIN"
|
||||
else
|
||||
echo "❌ Checksum binario NO coincide"
|
||||
echo "Original: $ORIG_BIN"
|
||||
echo "Extraído: $EXTR_BIN"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "NOTA: Los archivos de texto tienen checksums diferentes porque:"
|
||||
echo " - HFS usa line endings CR (Mac clásico) vs LF (Unix)"
|
||||
echo " - HFS usa charset MacRoman vs UTF-8"
|
||||
echo " - Esto es comportamiento CORRECTO de hfsutil"
|
||||
|
||||
echo ""
|
||||
echo "[9] Verificando que archivos de texto son legibles..."
|
||||
echo "Original readme.txt:"
|
||||
cat source/readme.txt
|
||||
echo ""
|
||||
echo "Extraído readme.txt:"
|
||||
cat extracted/readme.txt
|
||||
|
||||
echo ""
|
||||
echo "✓ Ambos archivos son legibles (conversión de charset funcionó)"
|
||||
|
||||
echo ""
|
||||
echo "[10] Verificando archivo binario bit a bit..."
|
||||
if cmp source/data/binary.dat extracted/binary.dat; then
|
||||
echo "✓ Archivo binario idéntico bit a bit"
|
||||
else
|
||||
echo "❌ Archivo binario difiere"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$HFSUTIL humount
|
||||
|
||||
echo ""
|
||||
echo "[11] Verificando integridad del volumen..."
|
||||
echo "Buscando nombres en el volumen raw:"
|
||||
for name in "readme.txt" "manual1.md" "detailed.md" "main.c" "binary.dat" "docs" "manuals" "code" "src" "data"; do
|
||||
if strings test.hfs | grep -q "$name"; then
|
||||
echo " ✓ Encontrado: $name"
|
||||
else
|
||||
echo " ⚠ No encontrado: $name (puede ser normal)"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " ✓ TEST DE INTEGRIDAD RECURSIVA EXITOSO"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Resumen:"
|
||||
echo " - Estructura de 3 niveles copiada: ✓"
|
||||
echo " - 5 archivos (4 texto, 1 binario): ✓"
|
||||
echo " - Archivo binario idéntico bit a bit: ✓"
|
||||
echo " - Archivos de texto convertidos correctamente: ✓"
|
||||
echo " - Conversión Unix→Mac charset funcionó: ✓"
|
||||
@@ -1,305 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "============================================================"
|
||||
echo " Test de Conformidad con Especificación HFS/HFS+"
|
||||
echo " Verificando estructuras según Inside Macintosh: Files"
|
||||
echo "============================================================"
|
||||
|
||||
MKFS_HFS="/mnt/c/Users/Usuario/source/repos/hfsutils/build/standalone/mkfs.hfs"
|
||||
MKFS_HFSPLUS="/mnt/c/Users/Usuario/source/repos/hfsutils/build/standalone/mkfs.hfs+"
|
||||
HFSUTIL="/mnt/c/Users/Usuario/source/repos/hfsutils/hfsutil"
|
||||
|
||||
rm -rf /tmp/mkfs_conformance_test
|
||||
mkdir -p /tmp/mkfs_conformance_test
|
||||
cd /tmp/mkfs_conformance_test
|
||||
|
||||
# Función para leer bytes en hex
|
||||
read_hex_bytes() {
|
||||
local file=$1
|
||||
local offset=$2
|
||||
local count=$3
|
||||
dd if="$file" bs=1 skip=$offset count=$count 2>/dev/null | od -An -tx1 | tr -d ' \n'
|
||||
}
|
||||
|
||||
# Función para leer uint16 big-endian
|
||||
read_uint16() {
|
||||
local file=$1
|
||||
local offset=$2
|
||||
local hex=$(read_hex_bytes "$file" $offset 2)
|
||||
echo $((16#$hex))
|
||||
}
|
||||
|
||||
# Función para leer uint32 big-endian
|
||||
read_uint32() {
|
||||
local file=$1
|
||||
local offset=$2
|
||||
local hex=$(read_hex_bytes "$file" $offset 4)
|
||||
echo $((16#$hex))
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "========== TEST 1: mkfs.hfs (HFS clásico) =========="
|
||||
echo ""
|
||||
|
||||
dd if=/dev/zero of=test_hfs.img bs=1M count=10 2>/dev/null
|
||||
$MKFS_HFS -l "TestVolume" test_hfs.img 2>&1 | head -n 10
|
||||
|
||||
echo ""
|
||||
echo "[1] Verificando Boot Blocks (bloques 0-1, 1024 bytes)..."
|
||||
BOOT_SIG=$(read_hex_bytes test_hfs.img 0 2)
|
||||
echo " Boot signature: 0x$BOOT_SIG (debe ser 0x4C4B o 0x0000)"
|
||||
|
||||
echo ""
|
||||
echo "[2] Verificando Master Directory Block (MDB) en bloque 2 (offset 1024)..."
|
||||
|
||||
# Offset 1024 = inicio del MDB
|
||||
MDB_OFFSET=1024
|
||||
|
||||
# drSigWord (offset +0): HFS signature
|
||||
SIG=$(read_hex_bytes test_hfs.img $MDB_OFFSET 2)
|
||||
echo " drSigWord (signature): 0x$SIG"
|
||||
if [ "$SIG" = "4244" ]; then
|
||||
echo " ✓ Signature correcta (0x4244 = 'BD' para HFS)"
|
||||
else
|
||||
echo " ❌ Signature incorrecta (esperado 0x4244)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# drCrDate (offset +2): Creation date (segundos desde 1904)
|
||||
CR_DATE=$(read_uint32 test_hfs.img $((MDB_OFFSET + 2)))
|
||||
echo " drCrDate (creation): $CR_DATE segundos desde 1904-01-01"
|
||||
if [ $CR_DATE -gt 0 ]; then
|
||||
echo " ✓ Fecha de creación válida"
|
||||
else
|
||||
echo " ❌ Fecha de creación inválida"
|
||||
fi
|
||||
|
||||
# drLsMod (offset +6): Last modified date
|
||||
MOD_DATE=$(read_uint32 test_hfs.img $((MDB_OFFSET + 6)))
|
||||
echo " drLsMod (last modified): $MOD_DATE"
|
||||
echo " ✓ Fecha de modificación válida"
|
||||
|
||||
# drAtrb (offset +10): Volume attributes
|
||||
ATTR=$(read_uint16 test_hfs.img $((MDB_OFFSET + 10)))
|
||||
echo " drAtrb (attributes): 0x$(printf '%04X' $ATTR)"
|
||||
if [ $(($ATTR & 0x0100)) -ne 0 ]; then
|
||||
echo " ✓ Bit 8 set (unmounted cleanly)"
|
||||
else
|
||||
echo " ⚠ Volume not marked as unmounted cleanly"
|
||||
fi
|
||||
|
||||
# drNmFls (offset +12): Number of files in root
|
||||
NUM_FILES=$(read_uint16 test_hfs.img $((MDB_OFFSET + 12)))
|
||||
echo " drNmFls (files in root): $NUM_FILES"
|
||||
echo " ✓ Debería ser 0 para volumen vacío"
|
||||
|
||||
# drVBMSt (offset +14): Volume bitmap start block
|
||||
VBMST=$(read_uint16 test_hfs.img $((MDB_OFFSET + 14)))
|
||||
echo " drVBMSt (bitmap start): block $VBMST"
|
||||
if [ $VBMST -eq 3 ]; then
|
||||
echo " ✓ Bitmap start correcto (block 3)"
|
||||
else
|
||||
echo " ❌ Bitmap start incorrecto (esperado 3)"
|
||||
fi
|
||||
|
||||
# drNmAlBlks (offset +18): Number of allocation blocks
|
||||
NUM_ALLOC=$(read_uint16 test_hfs.img $((MDB_OFFSET + 18)))
|
||||
echo " drNmAlBlks (allocation blocks): $NUM_ALLOC"
|
||||
echo " ✓ Total de bloques de asignación"
|
||||
|
||||
# drAlBlkSiz (offset +20): Allocation block size
|
||||
ALLOC_SIZE=$(read_uint32 test_hfs.img $((MDB_OFFSET + 20)))
|
||||
echo " drAlBlkSiz (block size): $ALLOC_SIZE bytes"
|
||||
if [ $ALLOC_SIZE -gt 0 ] && [ $(($ALLOC_SIZE % 512)) -eq 0 ]; then
|
||||
echo " ✓ Tamaño de bloque válido (múltiplo de 512)"
|
||||
else
|
||||
echo " ❌ Tamaño de bloque inválido"
|
||||
fi
|
||||
|
||||
# drNxtCNID (offset +30): Next catalog node ID
|
||||
NEXT_CNID=$(read_uint32 test_hfs.img $((MDB_OFFSET + 30)))
|
||||
echo " drNxtCNID (next CNID): $NEXT_CNID"
|
||||
if [ $NEXT_CNID -eq 16 ]; then
|
||||
echo " ✓ Next CNID correcto (16 según spec)"
|
||||
else
|
||||
echo " ⚠ Next CNID = $NEXT_CNID (spec dice 16)"
|
||||
fi
|
||||
|
||||
# drFreeBks (offset +34): Free allocation blocks
|
||||
FREE_BLKS=$(read_uint16 test_hfs.img $((MDB_OFFSET + 34)))
|
||||
echo " drFreeBks (free blocks): $FREE_BLKS"
|
||||
echo " ✓ Bloques libres reportados"
|
||||
|
||||
# drVN (offset +36): Volume name (Pascal string)
|
||||
NAME_LEN=$(read_hex_bytes test_hfs.img $((MDB_OFFSET + 36)) 1)
|
||||
NAME_LEN=$((16#$NAME_LEN))
|
||||
echo " drVN (volume name length): $NAME_LEN bytes"
|
||||
if [ $NAME_LEN -gt 0 ] && [ $NAME_LEN -le 27 ]; then
|
||||
NAME=$(dd if=test_hfs.img bs=1 skip=$((MDB_OFFSET + 37)) count=$NAME_LEN 2>/dev/null)
|
||||
echo " drVN (volume name): '$NAME'"
|
||||
echo " ✓ Nombre de volumen válido"
|
||||
else
|
||||
echo " ❌ Longitud de nombre inválida"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[3] Verificando Alternate MDB (último bloque del volumen)..."
|
||||
FILE_SIZE=$(stat -c%s test_hfs.img 2>/dev/null || stat -f%z test_hfs.img 2>/dev/null)
|
||||
ALT_MDB_OFFSET=$((FILE_SIZE - 1024))
|
||||
ALT_SIG=$(read_hex_bytes test_hfs.img $ALT_MDB_OFFSET 2)
|
||||
echo " Alternate MDB signature: 0x$ALT_SIG"
|
||||
if [ "$ALT_SIG" = "4244" ]; then
|
||||
echo " ✓ Alternate MDB presente y válido"
|
||||
else
|
||||
echo " ❌ Alternate MDB no encontrado o inválido"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[4] Verificando Volume Bitmap (bloque 3)..."
|
||||
BITMAP_OFFSET=$((3 * 512))
|
||||
BITMAP_BYTE=$(read_hex_bytes test_hfs.img $BITMAP_OFFSET 1)
|
||||
echo " Primer byte del bitmap: 0x$BITMAP_BYTE"
|
||||
echo " (bits marcan bloques asignados a archivos del sistema)"
|
||||
|
||||
echo ""
|
||||
echo "========== TEST 2: mkfs.hfs+ (HFS Plus/Extended) =========="
|
||||
echo ""
|
||||
|
||||
dd if=/dev/zero of=test_hfsplus.img bs=1M count=10 2>/dev/null
|
||||
$MKFS_HFSPLUS -l "TestHFSPlus" test_hfsplus.img 2>&1 | head -n 10
|
||||
|
||||
echo ""
|
||||
echo "[1] Verificando HFS+ Volume Header (bloque 2, offset 1024)..."
|
||||
|
||||
VH_OFFSET=1024
|
||||
|
||||
# Signature (offset +0): 'H+' or 'HX'
|
||||
VH_SIG=$(read_hex_bytes test_hfsplus.img $VH_OFFSET 2)
|
||||
echo " signature: 0x$VH_SIG"
|
||||
if [ "$VH_SIG" = "482b" ]; then
|
||||
echo " ✓ Signature correcta (0x482B = 'H+' para HFS+)"
|
||||
elif [ "$VH_SIG" = "4858" ]; then
|
||||
echo " ✓ Signature correcta (0x4858 = 'HX' para HFSX)"
|
||||
else
|
||||
echo " ❌ Signature incorrecta (esperado 0x482B o 0x4858)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# version (offset +2)
|
||||
VERSION=$(read_uint16 test_hfsplus.img $((VH_OFFSET + 2)))
|
||||
echo " version: $VERSION"
|
||||
if [ $VERSION -eq 4 ] || [ $VERSION -eq 5 ]; then
|
||||
echo " ✓ Versión válida (4=HFS+, 5=HFSX)"
|
||||
else
|
||||
echo " ⚠ Versión inesperada: $VERSION"
|
||||
fi
|
||||
|
||||
# attributes (offset +4)
|
||||
VH_ATTR=$(read_uint32 test_hfsplus.img $((VH_OFFSET + 4)))
|
||||
echo " attributes: 0x$(printf '%08X' $VH_ATTR)"
|
||||
if [ $(($VH_ATTR & 0x00000100)) -ne 0 ]; then
|
||||
echo " ✓ kHFSVolumeUnmountedBit set"
|
||||
fi
|
||||
|
||||
# blockSize (offset +40)
|
||||
BLOCK_SIZE=$(read_uint32 test_hfsplus.img $((VH_OFFSET + 40)))
|
||||
echo " blockSize: $BLOCK_SIZE bytes"
|
||||
if [ $BLOCK_SIZE -gt 0 ] && [ $(($BLOCK_SIZE % 512)) -eq 0 ]; then
|
||||
echo " ✓ Tamaño de bloque válido"
|
||||
else
|
||||
echo " ❌ Tamaño de bloque inválido"
|
||||
fi
|
||||
|
||||
# totalBlocks (offset +44)
|
||||
TOTAL_BLOCKS=$(read_uint32 test_hfsplus.img $((VH_OFFSET + 44)))
|
||||
echo " totalBlocks: $TOTAL_BLOCKS"
|
||||
echo " ✓ Total de bloques en el volumen"
|
||||
|
||||
# freeBlocks (offset +48)
|
||||
FREE_BLOCKS=$(read_uint32 test_hfsplus.img $((VH_OFFSET + 48)))
|
||||
echo " freeBlocks: $FREE_BLOCKS"
|
||||
echo " ✓ Bloques libres reportados"
|
||||
|
||||
# nextCatalogID (offset +56)
|
||||
NEXT_CAT_ID=$(read_uint32 test_hfsplus.img $((VH_OFFSET + 56)))
|
||||
echo " nextCatalogID: $NEXT_CAT_ID"
|
||||
if [ $NEXT_CAT_ID -ge 16 ]; then
|
||||
echo " ✓ Next catalog ID válido (>= 16)"
|
||||
else
|
||||
echo " ❌ Next catalog ID inválido"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[2] Verificando Alternate Volume Header (último bloque)..."
|
||||
FILE_SIZE=$(stat -c%s test_hfsplus.img 2>/dev/null || stat -f%z test_hfsplus.img 2>/dev/null)
|
||||
ALT_VH_OFFSET=$((FILE_SIZE - 1024))
|
||||
ALT_VH_SIG=$(read_hex_bytes test_hfsplus.img $ALT_VH_OFFSET 2)
|
||||
echo " Alternate VH signature: 0x$ALT_VH_SIG"
|
||||
if [ "$ALT_VH_SIG" = "482b" ] || [ "$ALT_VH_SIG" = "4858" ]; then
|
||||
echo " ✓ Alternate Volume Header presente y válido"
|
||||
else
|
||||
echo " ❌ Alternate Volume Header no encontrado"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========== TEST 3: hformat (hfsutil) =========="
|
||||
echo ""
|
||||
|
||||
dd if=/dev/zero of=test_hformat.img bs=1M count=10 2>/dev/null
|
||||
$HFSUTIL hformat -l "HFSUtilTest" test_hformat.img 2>&1 | head -n 5
|
||||
|
||||
echo ""
|
||||
echo "[1] Verificando volumen creado por hformat..."
|
||||
|
||||
MDB_OFFSET=1024
|
||||
SIG=$(read_hex_bytes test_hformat.img $MDB_OFFSET 2)
|
||||
echo " Signature: 0x$SIG"
|
||||
if [ "$SIG" = "4244" ]; then
|
||||
echo " ✓ hformat crea volúmenes HFS válidos"
|
||||
else
|
||||
echo " ❌ Signature incorrecta"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NAME_LEN=$(read_hex_bytes test_hformat.img $((MDB_OFFSET + 36)) 1)
|
||||
NAME_LEN=$((16#$NAME_LEN))
|
||||
NAME=$(dd if=test_hformat.img bs=1 skip=$((MDB_OFFSET + 37)) count=$NAME_LEN 2>/dev/null)
|
||||
echo " Volume name: '$NAME'"
|
||||
echo " ✓ Nombre de volumen correcto"
|
||||
|
||||
echo ""
|
||||
echo "========== TEST 4: Compatibilidad entre herramientas =========="
|
||||
echo ""
|
||||
|
||||
echo "[1] Montando volumen mkfs.hfs con hfsutil..."
|
||||
if $HFSUTIL hmount test_hfs.img 2>&1; then
|
||||
echo " ✓ hfsutil puede montar volúmenes de mkfs.hfs"
|
||||
$HFSUTIL hvol
|
||||
$HFSUTIL humount
|
||||
else
|
||||
echo " ❌ hfsutil no puede montar volúmenes de mkfs.hfs"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[2] Montando volumen hformat con hfsutil..."
|
||||
if $HFSUTIL hmount test_hformat.img 2>&1; then
|
||||
echo " ✓ hfsutil puede montar sus propios volúmenes"
|
||||
$HFSUTIL humount
|
||||
else
|
||||
echo " ❌ hfsutil no puede montar sus propios volúmenes"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "============================================================"
|
||||
echo " ✓ TESTS DE CONFORMIDAD COMPLETADOS"
|
||||
echo "============================================================"
|
||||
echo ""
|
||||
echo "Resumen:"
|
||||
echo " - mkfs.hfs crea MDB conforme a spec: ✓"
|
||||
echo " - Signature HFS correcta (0x4244): ✓"
|
||||
echo " - Campos MDB según Inside Macintosh: ✓"
|
||||
echo " - mkfs.hfs+ crea Volume Header HFS+: ✓"
|
||||
echo " - Signature HFS+ correcta (0x482B): ✓"
|
||||
echo " - hformat compatible con especificación: ✓"
|
||||
echo " - Volúmenes intercambiables entre herramientas: ✓"
|
||||
@@ -1,163 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Validation script to check build system functionality
|
||||
# This script verifies that all variables are properly passed through the build system
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== HFSUtils Build System Validation ==="
|
||||
echo
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Test function
|
||||
test_variable() {
|
||||
local var_name="$1"
|
||||
local expected="$2"
|
||||
local actual="$3"
|
||||
|
||||
if [ "$actual" = "$expected" ]; then
|
||||
echo -e "${GREEN}✓${NC} $var_name: $actual"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗${NC} $var_name: expected '$expected', got '$actual'"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Test 1: Check Makefile variable defaults
|
||||
echo "Test 1: Checking Makefile variable defaults"
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Extract defaults from Makefile
|
||||
PREFIX_DEFAULT=$(grep "^PREFIX ?=" Makefile | cut -d'=' -f2 | tr -d ' ')
|
||||
CC_DEFAULT=$(grep "^CC ?=" Makefile | cut -d'=' -f2 | tr -d ' ')
|
||||
CFLAGS_DEFAULT=$(grep "^CFLAGS ?=" Makefile | cut -d'=' -f2 | tr -d ' ')
|
||||
|
||||
test_variable "PREFIX" "/usr/local" "$PREFIX_DEFAULT"
|
||||
test_variable "CC" "gcc" "$CC_DEFAULT"
|
||||
test_variable "CFLAGS" "-g-O2" "$CFLAGS_DEFAULT"
|
||||
|
||||
echo
|
||||
|
||||
# Test 2: Check build.sh variable handling
|
||||
echo "Test 2: Checking build.sh variable handling"
|
||||
echo "-------------------------------------------"
|
||||
|
||||
# Check if build.sh properly handles environment variables
|
||||
if grep -q 'export CC="${CC:-gcc}"' build.sh; then
|
||||
echo -e "${GREEN}✓${NC} build.sh handles CC variable"
|
||||
else
|
||||
echo -e "${RED}✗${NC} build.sh missing CC variable handling"
|
||||
fi
|
||||
|
||||
if grep -q 'export CFLAGS="${CFLAGS:--g -O2}"' build.sh; then
|
||||
echo -e "${GREEN}✓${NC} build.sh handles CFLAGS variable"
|
||||
else
|
||||
echo -e "${RED}✗${NC} build.sh missing CFLAGS variable handling"
|
||||
fi
|
||||
|
||||
if grep -q 'export PREFIX="${PREFIX:-/usr/local}"' build.sh; then
|
||||
echo -e "${GREEN}✓${NC} build.sh handles PREFIX variable"
|
||||
else
|
||||
echo -e "${RED}✗${NC} build.sh missing PREFIX variable handling"
|
||||
fi
|
||||
|
||||
if grep -q 'export DESTDIR="${DESTDIR:-}"' build.sh; then
|
||||
echo -e "${GREEN}✓${NC} build.sh handles DESTDIR variable"
|
||||
else
|
||||
echo -e "${RED}✗${NC} build.sh missing DESTDIR variable handling"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test 3: Check library Makefiles
|
||||
echo "Test 3: Checking library Makefiles"
|
||||
echo "----------------------------------"
|
||||
|
||||
for lib in libhfs librsrc hfsck; do
|
||||
if [ -f "$lib/Makefile" ]; then
|
||||
if grep -q "PREFIX ?=" "$lib/Makefile"; then
|
||||
echo -e "${GREEN}✓${NC} $lib/Makefile supports PREFIX"
|
||||
else
|
||||
echo -e "${RED}✗${NC} $lib/Makefile missing PREFIX support"
|
||||
fi
|
||||
|
||||
if grep -q "DESTDIR ?=" "$lib/Makefile"; then
|
||||
echo -e "${GREEN}✓${NC} $lib/Makefile supports DESTDIR"
|
||||
else
|
||||
echo -e "${RED}✗${NC} $lib/Makefile missing DESTDIR support"
|
||||
fi
|
||||
|
||||
if grep -q "CC ?=" "$lib/Makefile"; then
|
||||
echo -e "${GREEN}✓${NC} $lib/Makefile supports CC"
|
||||
else
|
||||
echo -e "${RED}✗${NC} $lib/Makefile missing CC support"
|
||||
fi
|
||||
|
||||
if grep -q "CFLAGS ?=" "$lib/Makefile"; then
|
||||
echo -e "${GREEN}✓${NC} $lib/Makefile supports CFLAGS"
|
||||
else
|
||||
echo -e "${RED}✗${NC} $lib/Makefile missing CFLAGS support"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}!${NC} $lib/Makefile not found"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
# Test 4: Check manual page installation
|
||||
echo "Test 4: Checking manual page installation"
|
||||
echo "-----------------------------------------"
|
||||
|
||||
if [ -d "doc/man" ]; then
|
||||
man_count=$(find doc/man -name "*.1" | wc -l)
|
||||
echo -e "${GREEN}✓${NC} Found $man_count manual pages in doc/man/"
|
||||
|
||||
if grep -q "doc/man/\*.1" Makefile; then
|
||||
echo -e "${GREEN}✓${NC} Makefile includes manual page installation"
|
||||
else
|
||||
echo -e "${RED}✗${NC} Makefile missing manual page installation"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗${NC} doc/man directory not found"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Test 5: Check installation targets
|
||||
echo "Test 5: Checking installation targets"
|
||||
echo "-------------------------------------"
|
||||
|
||||
targets=("install" "install-libs" "install-symlinks")
|
||||
for target in "${targets[@]}"; do
|
||||
if grep -q "^$target:" Makefile; then
|
||||
echo -e "${GREEN}✓${NC} Target '$target' exists"
|
||||
else
|
||||
echo -e "${RED}✗${NC} Target '$target' missing"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
# Summary
|
||||
echo "=== Validation Summary ==="
|
||||
echo "Build system features implemented:"
|
||||
echo "• DESTDIR support for package building"
|
||||
echo "• PREFIX support for custom installation paths"
|
||||
echo "• CC/CXX compiler selection"
|
||||
echo "• CFLAGS/CXXFLAGS/LDFLAGS support"
|
||||
echo "• Manual pages installation"
|
||||
echo "• Library installation with headers"
|
||||
echo "• Proper variable propagation to sub-makefiles"
|
||||
echo
|
||||
echo "Usage examples:"
|
||||
echo " make install PREFIX=/opt/hfsutils"
|
||||
echo " make install DESTDIR=/tmp/staging"
|
||||
echo " make CC=clang CFLAGS='-O3 -march=native'"
|
||||
echo " CC=gcc-11 CFLAGS='-O2 -g' ./build.sh"
|
||||
@@ -1,62 +0,0 @@
|
||||
# HFS/HFS+ Utilities Test Suite
|
||||
|
||||
This directory contains tests for the HFS/HFS+ filesystem utilities.
|
||||
|
||||
## Test Structure
|
||||
|
||||
```
|
||||
tests/
|
||||
├── unit/ # Unit tests for individual components
|
||||
├── integration/ # Integration tests for complete workflows
|
||||
├── fixtures/ # Test data and sample filesystems
|
||||
├── scripts/ # Test automation scripts
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Unit Tests
|
||||
```bash
|
||||
make test-unit
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
```bash
|
||||
make test-integration
|
||||
```
|
||||
|
||||
### All Tests
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
## Test Categories
|
||||
|
||||
### Unit Tests
|
||||
- `unit/mkfs/` - Tests for mkfs.hfs and mkfs.hfs+ functionality
|
||||
- `unit/fsck/` - Tests for fsck.hfs and fsck.hfs+ functionality
|
||||
- `unit/shared/` - Tests for shared utility functions
|
||||
|
||||
### Integration Tests
|
||||
- `integration/mkfs/` - End-to-end mkfs testing
|
||||
- `integration/fsck/` - End-to-end fsck testing
|
||||
- `integration/workflows/` - Complete filesystem workflows
|
||||
|
||||
### Test Fixtures
|
||||
- `fixtures/images/` - Sample HFS/HFS+ filesystem images
|
||||
- `fixtures/data/` - Test data files
|
||||
- `fixtures/configs/` - Test configuration files
|
||||
|
||||
## Test Requirements
|
||||
|
||||
- Linux system with loop device support
|
||||
- Root privileges for some tests (filesystem creation/mounting)
|
||||
- At least 100MB free disk space for test images
|
||||
|
||||
## Writing Tests
|
||||
|
||||
Tests should follow these conventions:
|
||||
- Use descriptive test names
|
||||
- Include both positive and negative test cases
|
||||
- Clean up resources after test completion
|
||||
- Document expected behavior and edge cases
|
||||
@@ -1,153 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# test_mkfs_basic.sh - Basic integration tests for mkfs.hfs and mkfs.hfs+
|
||||
# Copyright (C) 2025 Pablo Lezaeta
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Test configuration
|
||||
TEST_DIR="$(dirname "$0")"
|
||||
ROOT_DIR="$TEST_DIR/../../.."
|
||||
BUILD_DIR="$ROOT_DIR/build/standalone"
|
||||
TEST_IMAGE_DIR="/tmp/hfs_test_$$"
|
||||
TEST_IMAGE_SIZE="10M"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
log_info "Cleaning up test files..."
|
||||
rm -rf "$TEST_IMAGE_DIR"
|
||||
}
|
||||
|
||||
# Set up cleanup trap
|
||||
trap cleanup EXIT
|
||||
|
||||
# Check if utilities exist
|
||||
check_utilities() {
|
||||
log_info "Checking for required utilities..."
|
||||
|
||||
if [ ! -f "$BUILD_DIR/mkfs.hfs" ]; then
|
||||
log_error "mkfs.hfs not found. Please build first with 'make mkfs.hfs'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$BUILD_DIR/mkfs.hfs+" ]; then
|
||||
log_error "mkfs.hfs+ not found. Please build first with 'make mkfs.hfs'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All utilities found"
|
||||
}
|
||||
|
||||
# Test mkfs.hfs basic functionality
|
||||
test_mkfs_hfs() {
|
||||
log_info "Testing mkfs.hfs basic functionality..."
|
||||
|
||||
local test_image="$TEST_IMAGE_DIR/test_hfs.img"
|
||||
|
||||
# Create test image file
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
|
||||
# Test basic mkfs.hfs
|
||||
log_info "Creating HFS filesystem..."
|
||||
"$BUILD_DIR/mkfs.hfs" -v -l "TestHFS" "$test_image"
|
||||
|
||||
# Verify the image was created and has reasonable size
|
||||
if [ ! -f "$test_image" ]; then
|
||||
log_error "Test image was not created"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local size=$(stat -c%s "$test_image")
|
||||
if [ "$size" -lt 1000000 ]; then
|
||||
log_error "Test image seems too small: $size bytes"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "mkfs.hfs basic test passed"
|
||||
}
|
||||
|
||||
# Test mkfs.hfs+ basic functionality
|
||||
test_mkfs_hfsplus() {
|
||||
log_info "Testing mkfs.hfs+ basic functionality..."
|
||||
|
||||
local test_image="$TEST_IMAGE_DIR/test_hfsplus.img"
|
||||
|
||||
# Create test image file
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
|
||||
# Test basic mkfs.hfs+
|
||||
log_info "Creating HFS+ filesystem..."
|
||||
"$BUILD_DIR/mkfs.hfs+" -v -l "TestHFSPlus" "$test_image"
|
||||
|
||||
# Verify the image was created and has reasonable size
|
||||
if [ ! -f "$test_image" ]; then
|
||||
log_error "Test image was not created"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local size=$(stat -c%s "$test_image")
|
||||
if [ "$size" -lt 1000000 ]; then
|
||||
log_error "Test image seems too small: $size bytes"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "mkfs.hfs+ basic test passed"
|
||||
}
|
||||
|
||||
# Test command-line options
|
||||
test_command_line_options() {
|
||||
log_info "Testing command-line options..."
|
||||
|
||||
# Test version option
|
||||
"$BUILD_DIR/mkfs.hfs" -V > /dev/null
|
||||
"$BUILD_DIR/mkfs.hfs+" -V > /dev/null
|
||||
|
||||
# Test help option
|
||||
"$BUILD_DIR/mkfs.hfs" -h > /dev/null
|
||||
"$BUILD_DIR/mkfs.hfs+" -h > /dev/null
|
||||
|
||||
# Test license option
|
||||
"$BUILD_DIR/mkfs.hfs" --license > /dev/null
|
||||
"$BUILD_DIR/mkfs.hfs+" --license > /dev/null
|
||||
|
||||
log_info "Command-line options test passed"
|
||||
}
|
||||
|
||||
# Main test execution
|
||||
main() {
|
||||
log_info "Starting mkfs integration tests..."
|
||||
|
||||
# Create test directory
|
||||
mkdir -p "$TEST_IMAGE_DIR"
|
||||
|
||||
# Run tests
|
||||
check_utilities
|
||||
test_command_line_options
|
||||
test_mkfs_hfs
|
||||
test_mkfs_hfsplus
|
||||
|
||||
log_info "All mkfs integration tests passed!"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -1,230 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# test_mkfs_cli_compatibility.sh - Test command-line interface compatibility with hformat
|
||||
# Copyright (C) 2025 Pablo Lezaeta
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Test configuration
|
||||
TEST_DIR="$(dirname "$0")"
|
||||
ROOT_DIR="$TEST_DIR/../../.."
|
||||
BUILD_DIR="$ROOT_DIR/build/standalone"
|
||||
TEST_IMAGE_DIR="/tmp/hfs_cli_test_$$"
|
||||
TEST_IMAGE_SIZE="10M"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
log_info "Cleaning up test files..."
|
||||
rm -rf "$TEST_IMAGE_DIR"
|
||||
}
|
||||
|
||||
# Set up cleanup trap
|
||||
trap cleanup EXIT
|
||||
|
||||
# Test proper mkfs behavior (no -s or -t options)
|
||||
test_proper_mkfs_behavior() {
|
||||
log_info "Testing proper mkfs behavior..."
|
||||
|
||||
local test_image="$TEST_IMAGE_DIR/mkfs_proper.img"
|
||||
|
||||
# Create test image file
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
|
||||
# Test -f (force) option
|
||||
log_info "Testing -f (force) option..."
|
||||
"$BUILD_DIR/mkfs.hfs" -f -l "ForceTest" "$test_image"
|
||||
|
||||
# Test -l (label) option
|
||||
log_info "Testing -l (label) option..."
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs" -l "TestLabel" "$test_image"
|
||||
|
||||
# Test -v (verbose) option
|
||||
log_info "Testing -v (verbose) option..."
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs" -v -l "VerboseTest" "$test_image" | grep -q "formatting"
|
||||
|
||||
# Test that mkfs.hfs+ works with HFS+ only
|
||||
log_info "Testing mkfs.hfs+ creates HFS+ only..."
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs+" -v -l "HFSPlusTest" "$test_image" 2>&1 | grep -q "HFS+ filesystem"
|
||||
|
||||
log_info "Proper mkfs behavior tests passed"
|
||||
}
|
||||
|
||||
# Test that inappropriate options are rejected
|
||||
test_inappropriate_options_rejected() {
|
||||
log_info "Testing that inappropriate options are rejected..."
|
||||
|
||||
# Test that -t option is rejected by mkfs.hfs
|
||||
log_info "Testing -t option rejection by mkfs.hfs..."
|
||||
if "$BUILD_DIR/mkfs.hfs" -t hfs /dev/null 2>/dev/null; then
|
||||
log_error "mkfs.hfs should reject -t option"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test that -s option is rejected by mkfs.hfs
|
||||
log_info "Testing -s option rejection by mkfs.hfs..."
|
||||
if "$BUILD_DIR/mkfs.hfs" -s 1024 /dev/null 2>/dev/null; then
|
||||
log_error "mkfs.hfs should reject -s option"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test that -t option is rejected by mkfs.hfs+
|
||||
log_info "Testing -t option rejection by mkfs.hfs+..."
|
||||
if "$BUILD_DIR/mkfs.hfs+" -t hfs+ /dev/null 2>/dev/null; then
|
||||
log_error "mkfs.hfs+ should reject -t option"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test that -s option is rejected by mkfs.hfs+
|
||||
log_info "Testing -s option rejection by mkfs.hfs+..."
|
||||
if "$BUILD_DIR/mkfs.hfs+" -s 1024 /dev/null 2>/dev/null; then
|
||||
log_error "mkfs.hfs+ should reject -s option"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Inappropriate options rejection tests passed"
|
||||
}
|
||||
|
||||
# Test separate tool behavior
|
||||
test_separate_tool_behavior() {
|
||||
log_info "Testing separate tool behavior..."
|
||||
|
||||
local test_image="$TEST_IMAGE_DIR/separate_tools.img"
|
||||
|
||||
# Test mkfs.hfs creates HFS only
|
||||
log_info "Testing mkfs.hfs creates HFS only..."
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs" -v "$test_image" | grep -q "HFS filesystem" && \
|
||||
! "$BUILD_DIR/mkfs.hfs" -v "$test_image" | grep -q "HFS+ filesystem"
|
||||
|
||||
# Test mkfs.hfs+ creates HFS+ only
|
||||
log_info "Testing mkfs.hfs+ creates HFS+ only..."
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs+" -v "$test_image" 2>&1 | grep -q "HFS+ filesystem"
|
||||
|
||||
log_info "Separate tool behavior tests passed"
|
||||
}
|
||||
|
||||
# Test error handling
|
||||
test_error_handling() {
|
||||
log_info "Testing error handling..."
|
||||
|
||||
# Test missing device argument
|
||||
if "$BUILD_DIR/mkfs.hfs" 2>/dev/null; then
|
||||
log_error "Should have failed with missing device argument"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test invalid volume name (too long for HFS)
|
||||
local long_name="123456789012345678901234567890" # 30 chars, too long for HFS
|
||||
if "$BUILD_DIR/mkfs.hfs" -l "$long_name" /dev/null 2>/dev/null; then
|
||||
log_error "Should have failed with volume name too long for HFS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test invalid volume name (too long for HFS+)
|
||||
local very_long_name=$(printf 'A%.0s' {1..260}) # 260 chars, too long for HFS+
|
||||
if "$BUILD_DIR/mkfs.hfs+" -l "$very_long_name" /dev/null 2>/dev/null; then
|
||||
log_error "Should have failed with volume name too long for HFS+"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Error handling tests passed"
|
||||
}
|
||||
|
||||
# Test volume label validation
|
||||
test_volume_label_validation() {
|
||||
log_info "Testing volume label validation..."
|
||||
|
||||
local test_image="$TEST_IMAGE_DIR/label_test.img"
|
||||
|
||||
# Create test image file
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
|
||||
# Test valid HFS label (27 chars max)
|
||||
"$BUILD_DIR/mkfs.hfs" -l "ValidHFSLabel" "$test_image"
|
||||
|
||||
# Test valid HFS+ label (255 chars max)
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs+" -l "ValidHFSPlusLabel" "$test_image"
|
||||
|
||||
log_info "Volume label validation tests passed"
|
||||
}
|
||||
|
||||
# Test proper mkfs behavior with partitions
|
||||
test_partition_handling() {
|
||||
log_info "Testing partition handling..."
|
||||
|
||||
local test_image="$TEST_IMAGE_DIR/partition_test.img"
|
||||
|
||||
# Test basic formatting without partition number
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs" -f -l "BasicTest" "$test_image"
|
||||
|
||||
# Test with partition number 0 (whole device)
|
||||
dd if=/dev/zero of="$test_image" bs=1M count=10 2>/dev/null
|
||||
"$BUILD_DIR/mkfs.hfs" -l "PartTest" "$test_image" 0
|
||||
|
||||
log_info "Partition handling tests passed"
|
||||
}
|
||||
|
||||
# Check if utilities exist
|
||||
check_utilities() {
|
||||
log_info "Checking for required utilities..."
|
||||
|
||||
if [ ! -f "$BUILD_DIR/mkfs.hfs" ]; then
|
||||
log_error "mkfs.hfs not found. Please build first with 'make mkfs.hfs'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$BUILD_DIR/mkfs.hfs+" ]; then
|
||||
log_error "mkfs.hfs+ not found. Please build first with 'make mkfs.hfs'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "All utilities found"
|
||||
}
|
||||
|
||||
# Main test execution
|
||||
main() {
|
||||
log_info "Starting mkfs command-line interface compatibility tests..."
|
||||
|
||||
# Create test directory
|
||||
mkdir -p "$TEST_IMAGE_DIR"
|
||||
|
||||
# Run tests
|
||||
check_utilities
|
||||
test_proper_mkfs_behavior
|
||||
test_inappropriate_options_rejected
|
||||
test_separate_tool_behavior
|
||||
test_error_handling
|
||||
test_volume_label_validation
|
||||
test_partition_handling
|
||||
|
||||
log_info "All mkfs CLI compatibility tests passed!"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* test_mkfs_common.c - Unit tests for mkfs common functionality
|
||||
* Copyright (C) 2025 Pablo Lezaeta
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../../../src/mkfs/mkfs_common.h"
|
||||
|
||||
/* Test parse_size_common function */
|
||||
void test_parse_size_common(void)
|
||||
{
|
||||
printf("Testing parse_size_common...\n");
|
||||
|
||||
/* Test basic numbers */
|
||||
assert(parse_size_common("1024") == 1024);
|
||||
assert(parse_size_common("0") == -1); /* Invalid */
|
||||
assert(parse_size_common("-1") == -1); /* Invalid */
|
||||
|
||||
/* Test K suffix */
|
||||
assert(parse_size_common("1K") == 1024);
|
||||
assert(parse_size_common("1k") == 1024);
|
||||
assert(parse_size_common("10K") == 10240);
|
||||
|
||||
/* Test M suffix */
|
||||
assert(parse_size_common("1M") == 1024 * 1024);
|
||||
assert(parse_size_common("1m") == 1024 * 1024);
|
||||
assert(parse_size_common("5M") == 5 * 1024 * 1024);
|
||||
|
||||
/* Test G suffix */
|
||||
assert(parse_size_common("1G") == 1024LL * 1024 * 1024);
|
||||
assert(parse_size_common("1g") == 1024LL * 1024 * 1024);
|
||||
|
||||
/* Test invalid inputs */
|
||||
assert(parse_size_common(NULL) == -1);
|
||||
assert(parse_size_common("") == -1);
|
||||
assert(parse_size_common("abc") == -1);
|
||||
assert(parse_size_common("1X") == -1); /* Invalid suffix */
|
||||
assert(parse_size_common("1KB") == -1); /* Extra characters */
|
||||
|
||||
printf("parse_size_common tests passed\n");
|
||||
}
|
||||
|
||||
/* Test volume name validation */
|
||||
void test_validate_volume_names(void)
|
||||
{
|
||||
printf("Testing volume name validation...\n");
|
||||
|
||||
/* Test HFS volume names */
|
||||
assert(validate_volume_name_hfs("Test") == 0);
|
||||
assert(validate_volume_name_hfs("A") == 0);
|
||||
assert(validate_volume_name_hfs("1234567890123456789012345678") == -1); /* Too long */
|
||||
assert(validate_volume_name_hfs("Test:Name") == -1); /* Contains colon */
|
||||
assert(validate_volume_name_hfs("") == -1); /* Empty */
|
||||
assert(validate_volume_name_hfs(NULL) == 0); /* NULL is OK */
|
||||
|
||||
/* Test HFS+ volume names */
|
||||
assert(validate_volume_name_hfsplus("Test") == 0);
|
||||
assert(validate_volume_name_hfsplus("A") == 0);
|
||||
/* Create a 256-character string */
|
||||
char long_name[257];
|
||||
memset(long_name, 'A', 256);
|
||||
long_name[256] = '\0';
|
||||
assert(validate_volume_name_hfsplus(long_name) == -1); /* Too long */
|
||||
assert(validate_volume_name_hfsplus("Test:Name") == -1); /* Contains colon */
|
||||
assert(validate_volume_name_hfsplus("") == -1); /* Empty */
|
||||
assert(validate_volume_name_hfsplus(NULL) == 0); /* NULL is OK */
|
||||
|
||||
printf("Volume name validation tests passed\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Running mkfs common functionality tests...\n\n");
|
||||
|
||||
test_parse_size_common();
|
||||
test_validate_volume_names();
|
||||
|
||||
printf("\nAll tests passed!\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user