319 lines
9.3 KiB
Bash
Executable File
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 |