Files
dshash/tests/test.sh
2025-09-02 16:30:58 +12:00

319 lines
9.3 KiB
Bash
Executable File

#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
DSHASH_BIN="$PROJECT_DIR/dshash/dshash"
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
echo "Building dshash utility..."
cd "$PROJECT_DIR/dshash"
make clean > /dev/null 2>&1
make > /dev/null 2>&1
TOTAL_PASSED=0
TOTAL_FAILED=0
# =====================================
# SECTION 1: Library Unit Tests
# =====================================
echo ""
echo "=== Section 1: Library Unit Tests ==="
echo "Building test program..."
cd "$SCRIPT_DIR"
g++ -std=c++17 -o test_lib test_lib.cpp ../src/dshash.cpp -I../src
./test_lib
if [ $? -eq 0 ]; then
echo "✓ All library tests passed"
TOTAL_PASSED=$((TOTAL_PASSED + 7))
else
echo "✗ Library tests failed"
TOTAL_FAILED=$((TOTAL_FAILED + 1))
fi
# =====================================
# SECTION 2: Basic Utility Tests
# =====================================
echo ""
echo "=== Section 2: Basic Utility Tests ==="
FAILED=0
PASSED=0
run_test() {
local test_name="$1"
local expected="$2"
local actual="$3"
if [ "$expected" = "$actual" ]; then
echo "$test_name"
PASSED=$((PASSED + 1))
else
echo "$test_name"
echo " Expected: $expected"
echo " Got: $actual"
FAILED=$((FAILED + 1))
fi
}
echo -n "abc" > "$TEMP_DIR/test1.txt"
HASH=$($DSHASH_BIN "$TEMP_DIR/test1.txt")
run_test "Hash of 'abc'" "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" "$HASH"
echo -n "" > "$TEMP_DIR/empty.txt"
HASH=$($DSHASH_BIN "$TEMP_DIR/empty.txt")
run_test "Hash of empty file" "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" "$HASH"
echo -n "The quick brown fox jumps over the lazy dog" > "$TEMP_DIR/fox.txt"
HASH=$($DSHASH_BIN "$TEMP_DIR/fox.txt")
run_test "Hash of 'The quick brown fox...'" "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592" "$HASH"
mkdir -p "$TEMP_DIR/testdir/subdir"
echo -n "file1" > "$TEMP_DIR/testdir/file1.txt"
echo -n "file2" > "$TEMP_DIR/testdir/subdir/file2.txt"
HASH=$($DSHASH_BIN "$TEMP_DIR/testdir")
run_test "Hash of directory" "$(echo -n "$HASH" | grep -E '^[a-f0-9]{64}$' > /dev/null && echo 'valid')" "valid"
echo -n "test" > "$TEMP_DIR/verbose_test.txt"
OUTPUT=$($DSHASH_BIN -v "$TEMP_DIR/verbose_test.txt" 2>&1)
if echo "$OUTPUT" | grep -q "Processing file:"; then
run_test "Verbose mode" "works" "works"
else
run_test "Verbose mode" "works" "failed"
fi
mkdir -p "$TEMP_DIR/verbose_dir"
echo -n "test" > "$TEMP_DIR/verbose_dir/file.txt"
OUTPUT=$($DSHASH_BIN -v "$TEMP_DIR/verbose_dir" 2>&1)
if echo "$OUTPUT" | grep -q "Processing:"; then
run_test "Verbose mode for directory" "works" "works"
else
run_test "Verbose mode for directory" "works" "failed"
fi
TOTAL_PASSED=$((TOTAL_PASSED + PASSED))
TOTAL_FAILED=$((TOTAL_FAILED + FAILED))
# =====================================
# SECTION 3: System SHA256 Comparison
# =====================================
echo ""
echo "=== Section 3: System SHA256 Comparison ==="
FAILED=0
PASSED=0
compare_with_system() {
local test_name="$1"
local file_path="$2"
local our_hash=$($DSHASH_BIN "$file_path")
local system_hash=$(sha256sum "$file_path" | cut -d' ' -f1)
if [ "$our_hash" = "$system_hash" ]; then
echo "$test_name"
PASSED=$((PASSED + 1))
else
echo "$test_name"
echo " Our hash: $our_hash"
echo " System hash: $system_hash"
FAILED=$((FAILED + 1))
fi
}
# Test various file types
echo -n "a" > "$TEMP_DIR/single.txt"
compare_with_system "Single character" "$TEMP_DIR/single.txt"
printf "\x00\x01\x02\x03\xFF\xFE\xFD" > "$TEMP_DIR/binary.bin"
compare_with_system "Binary data" "$TEMP_DIR/binary.bin"
dd if=/dev/zero bs=1024 count=1024 2>/dev/null | tr '\0' 'A' > "$TEMP_DIR/large.txt"
compare_with_system "Large file (1MB)" "$TEMP_DIR/large.txt"
echo -n "!@#$%^&*()_+-=[]{}|;':\",./<>?" > "$TEMP_DIR/special.txt"
compare_with_system "Special characters" "$TEMP_DIR/special.txt"
echo -n "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" > "$TEMP_DIR/64bytes.txt"
compare_with_system "Exactly 64 bytes" "$TEMP_DIR/64bytes.txt"
echo -n "Hello 世界 🌍 Здравствуй мир" > "$TEMP_DIR/unicode.txt"
compare_with_system "Unicode text" "$TEMP_DIR/unicode.txt"
for i in {0..255}; do
printf "\\x$(printf %02x $i)"
done > "$TEMP_DIR/allbytes.bin"
compare_with_system "All byte values 0-255" "$TEMP_DIR/allbytes.bin"
TOTAL_PASSED=$((TOTAL_PASSED + PASSED))
TOTAL_FAILED=$((TOTAL_FAILED + FAILED))
# =====================================
# SECTION 4: NIST Test Vectors
# =====================================
echo ""
echo "=== Section 4: NIST Test Vectors ==="
FAILED=0
PASSED=0
# NIST test vectors
declare -a VECTORS=(
"|e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
"abc|ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq|248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
"a|ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
)
for vector in "${VECTORS[@]}"; do
IFS='|' read -r input expected <<< "$vector"
echo -n "$input" > "$TEMP_DIR/test.txt"
our_hash=$($DSHASH_BIN "$TEMP_DIR/test.txt")
if [ "$our_hash" = "$expected" ]; then
if [ -z "$input" ]; then
echo "✓ Empty string"
elif [ ${#input} -gt 20 ]; then
echo "✓ '${input:0:20}...'"
else
echo "✓ '$input'"
fi
PASSED=$((PASSED + 1))
else
echo "✗ Failed for input: '$input'"
echo " Expected: $expected"
echo " Got: $our_hash"
FAILED=$((FAILED + 1))
fi
done
# Special test: one million 'a' characters
perl -e 'print "a" x 1000000' > "$TEMP_DIR/million_a.txt"
our_hash=$($DSHASH_BIN "$TEMP_DIR/million_a.txt")
expected="cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
if [ "$our_hash" = "$expected" ]; then
echo "✓ One million 'a' characters"
PASSED=$((PASSED + 1))
else
echo "✗ One million 'a' characters"
FAILED=$((FAILED + 1))
fi
TOTAL_PASSED=$((TOTAL_PASSED + PASSED))
TOTAL_FAILED=$((TOTAL_FAILED + FAILED))
# =====================================
# SECTION 5: Stress Tests
# =====================================
echo ""
echo "=== Section 5: Stress Tests ==="
cd "$SCRIPT_DIR"
g++ -std=c++17 -O2 -o test_stress test_stress.cpp ../src/dshash.cpp -I../src 2>/dev/null
if ./test_stress > /dev/null 2>&1; then
echo "✓ All stress tests passed (8 tests)"
TOTAL_PASSED=$((TOTAL_PASSED + 8))
else
echo "✗ Stress tests failed"
TOTAL_FAILED=$((TOTAL_FAILED + 1))
fi
rm -f test_stress test_lib
# =====================================
# SECTION 6: Edge Cases
# =====================================
echo ""
echo "=== Section 6: Edge Cases ==="
FAILED=0
PASSED=0
# File with spaces in name
echo -n "test" > "$TEMP_DIR/file with spaces.txt"
OUR_HASH=$($DSHASH_BIN "$TEMP_DIR/file with spaces.txt")
SYSTEM_HASH=$(sha256sum "$TEMP_DIR/file with spaces.txt" | cut -d' ' -f1)
if [ "$OUR_HASH" = "$SYSTEM_HASH" ]; then
echo "✓ File with spaces in name"
PASSED=$((PASSED + 1))
else
echo "✗ File with spaces in name"
FAILED=$((FAILED + 1))
fi
# Symlink handling
echo -n "target" > "$TEMP_DIR/target.txt"
ln -s "$TEMP_DIR/target.txt" "$TEMP_DIR/link.txt"
OUR_HASH=$($DSHASH_BIN "$TEMP_DIR/link.txt")
SYSTEM_HASH=$(sha256sum "$TEMP_DIR/link.txt" | cut -d' ' -f1)
if [ "$OUR_HASH" = "$SYSTEM_HASH" ]; then
echo "✓ Symlink handling"
PASSED=$((PASSED + 1))
else
echo "✗ Symlink handling"
FAILED=$((FAILED + 1))
fi
# 55 bytes (padding edge case)
echo -n "0123456789abcdef0123456789abcdef0123456789abcdef0123456" > "$TEMP_DIR/55bytes.txt"
compare_with_system "55 bytes (padding edge)" "$TEMP_DIR/55bytes.txt"
# 56 bytes (padding edge case)
echo -n "0123456789abcdef0123456789abcdef0123456789abcdef01234567" > "$TEMP_DIR/56bytes.txt"
compare_with_system "56 bytes (padding edge)" "$TEMP_DIR/56bytes.txt"
TOTAL_PASSED=$((TOTAL_PASSED + PASSED))
TOTAL_FAILED=$((TOTAL_FAILED + FAILED))
# =====================================
# SECTION 7: Performance Test
# =====================================
echo ""
echo "=== Section 7: Performance Test ==="
# Create a 10MB file
dd if=/dev/urandom bs=1024 count=10240 of="$TEMP_DIR/10mb.bin" 2>/dev/null
# Time our implementation
START=$(date +%s%N)
OUR_HASH=$($DSHASH_BIN "$TEMP_DIR/10mb.bin")
END=$(date +%s%N)
OUR_TIME=$(( (END - START) / 1000000 ))
# Time system sha256sum
START=$(date +%s%N)
SYSTEM_HASH=$(sha256sum "$TEMP_DIR/10mb.bin" | cut -d' ' -f1)
END=$(date +%s%N)
SYSTEM_TIME=$(( (END - START) / 1000000 ))
if [ "$OUR_HASH" = "$SYSTEM_HASH" ]; then
echo "✓ 10MB file hash matches"
echo " Our time: ${OUR_TIME}ms"
echo " System time: ${SYSTEM_TIME}ms"
TOTAL_PASSED=$((TOTAL_PASSED + 1))
else
echo "✗ 10MB file hash mismatch"
TOTAL_FAILED=$((TOTAL_FAILED + 1))
fi
# =====================================
# FINAL SUMMARY
# =====================================
echo ""
echo "========================================="
echo "Test Results: $TOTAL_PASSED passed, $TOTAL_FAILED failed"
echo "========================================="
if [ $TOTAL_FAILED -eq 0 ]; then
echo "All tests passed!"
exit 0
else
echo "Some tests failed!"
exit 1
fi