#!/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