#!/bin/bash function die { echo "$1" exit 1 } if [[ $# -ne 1 ]]; then die "$0 " fi PROG=$1 perl -c -w $PROG > /dev/null 2>&1 || die "$PROG contains contains syntax errors" # Check byte encoding OUTPUT=$(perl $PROG testdata/test_0?.txt | awk '{print $2}' | uniq | wc -l) if [[ "$OUTPUT" != "1" ]]; then die "$LINENO: Unexpected variation in high order nibble: $OUTPUT" fi OUTPUT=$(perl $PROG testdata/test_0?.txt testdata/test_0116a0.txt | awk '{print $3}' | sort -u | wc -l) if [[ "$OUTPUT" != "16" ]]; then die "$LINENO: Insufficient variation in low order nibble: $OUTPUT" fi OUTPUT=$(perl $PROG testdata/test_?0.txt | awk '{print $2}' | sort -u | wc -l) if [[ "$OUTPUT" != "16" ]]; then die "$LINENO: Insufficient variation in high order nibble: $OUTPUT" fi OUTPUT=$(perl $PROG testdata/test_?0.txt | awk '{print $3}' | uniq | wc -l) if [[ "$OUTPUT" != "1" ]]; then die "$LINENO: Unexpected variation in low order nibble: $OUTPUT" fi # Check that reading from stdin produces same output as reading from file OUTPUT1=$(perl $PROG testdata/test_00.txt | sed -e 's/\*.*//') OUTPUT2=$(perl $PROG < testdata/test_00.txt | sed -e 's/\*.*//') if [[ "$OUTPUT1" == "" ]]; then die "$LINENO: Unexpected empty digest" fi if [[ "$OUTPUT1" != "$OUTPUT2" ]]; then die "$LINENO: reading from stdin failed" fi # Check offset encoding OUTPUT=$(perl $PROG testdata/test_??.txt | awk '{print $1}' | uniq | wc -l) if [[ "$OUTPUT" != "1" ]]; then die "$LINENO: Unexpected variations in offsets: $OUTPUT" fi OUTPUT=$(perl $PROG testdata/test_01*.txt | awk '{print $1}' | sort -u | wc -l) if [[ "$OUTPUT" != "2" ]]; then die "$LINENO: Unexpected variations in offsets: $OUTPUT" fi # Check that all files are given unique digests OUTPUT1=$(perl $PROG testdata/test_*.txt | awk '{print $1 " " $2 " " $3}' | sort -u | wc -l) OUTPUT2=$(ls testdata/test_*.txt | wc -l) if [[ "$OUTPUT1" != "$OUTPUT2" ]]; then die "$LINENO: Digests are not unique: $OUTPUT1 vs $OUTPUT2" fi # Check that two byte encoding is used where needed OUTPUT=$(perl $PROG testdata/collision_* | grep -F collision_base.txt) if ! ( echo $OUTPUT | grep -qF " + " ); then die "$LINENO: Expected 2-tuple digest" fi OUTPUT=$(perl $PROG testdata/collision_base.txt testdata/collision_1* | grep -F collision_base.txt) if ( echo $OUTPUT | grep -qF " + " ); then die "$LINENO: Unexpected 2-tuple digest" fi # Check that same abbreviated digest is used for two different files # with the same MD5. OUTPUT1=$(perl $PROG testdata/test_10.txt | sed -e 's/\*.*//') OUTPUT2=$(perl $PROG testdata/collision_12.txt | sed -e 's/\*.*//') if [[ "$OUTPUT1" == "" ]]; then die "$LINENO: Unexpected empty digest" fi if [[ "$OUTPUT1" != "$OUTPUT2" ]]; then die "$LINENO: Digest mismatched for same-MD5 files" fi if ( echo $OUTPUT1 | grep -qF " + " ); then die "$LINENO: Unexpected multi-tuple digest" fi # Generate and check digest for a set of files TMPFILE=$(mktemp) if [[ "$TMPFILE" == "" ]]; then die "$LINENO: Error creating temporary file" fi if ! ( perl $PROG testdata/test_*.txt > $TMPFILE ); then rm -f $TMPFILE die "$LINENO: Failed to generate digest" fi if [[ ! -s $TMPFILE ]]; then rm -f $TMPFILE die "$LINENO: Generated empty digest" fi OUTPUT=$(perl $PROG -c $TMPFILE 2>&1 | grep -vF "OK") rm -f $TMPFILE if [[ "$OUTPUT" != "" ]]; then die "$LINENO: Failed to verify digest from file" fi # Verify that digest can be read from stdin OUTPUT=$(perl $PROG testdata/*.txt | perl $PROG -c 2>&1 | grep -vF "OK") if [[ "$OUTPUT" != "" ]]; then die "$LINENO: Failed to verify digest from stdin" fi OUTPUT=$(perl $PROG testdata/*.txt | perl $PROG -c - 2>&1 | grep -vF "OK") if [[ "$OUTPUT" != "" ]]; then die "$LINENO: Failed to verify digest from stdin" fi # Check that files with same digest are listed separately OUTPUT=$(perl $PROG testdata/test_10.txt testdata/collision_12.txt | wc -l) if [[ "$OUTPUT" != "2" ]]; then die "$LINENO: Expected two separate digest lines" fi # Check that file with the same digest uses only minimal encoding OUTPUT=$(perl $PROG testdata/test_10.txt testdata/collision_12.txt | sed -e 's/\*.*//' | uniq | wc -l) if [[ "$OUTPUT" != "1" ]]; then die "$LINENO: Expected a single digest variety" fi OUTPUT=$(perl $PROG testdata/test_10.txt testdata/collision_12.txt | sed -e 's/\*.*//' | uniq | wc | awk '{print $2}') if [[ "$OUTPUT" != "3" ]]; then die "$LINENO: Expected 3-word digest" fi # Check that digests are specific to each file OUTPUT1=$(perl $PROG testdata/test_0a.txt testdata/test_0b.txt | head -1 | sed -e 's/\*.*//') OUTPUT2=$(perl $PROG testdata/test_0a.txt testdata/test_0b.txt | tail -1 | sed -e 's/\*.*//') if [[ "$OUTPUT1" == "$OUTPUT2" ]]; then die "$LINENO: Expected different digests" fi OUTPUT=$(perl $PROG -c "$OUTPUT1" testdata/test_0a.txt 2>&1 | grep -F OK) if [[ "$OUTPUT" == "" ]]; then die "$LINENO: Failed to verify digest for test_0a.txt" fi OUTPUT=$(perl $PROG -c "$OUTPUT1" testdata/test_0b.txt 2>&1 | grep -F FAIL) if [[ "$OUTPUT" == "" ]]; then die "$LINENO: Failed to reject digest for test_0b.txt" fi OUTPUT=$(perl $PROG -c "$OUTPUT2" testdata/test_0a.txt 2>&1 | grep -F FAIL) if [[ "$OUTPUT" == "" ]]; then die "$LINENO: Failed to reject digest for test_0a.txt" fi OUTPUT=$(perl $PROG -c "$OUTPUT2" testdata/test_0b.txt 2>&1 | grep -F OK) if [[ "$OUTPUT" == "" ]]; then die "$LINENO: Failed to verify digest for test_0b.txt" fi # Check that directories are handled gracefully OUTPUT=$(perl $PROG testdata 2>&1 | grep -F "Error reading testdata") if [[ "$OUTPUT" == "" ]]; then die "$LINENO: Poor handling of directories" fi echo "$0: OK" exit 0