#!/bin/ksh
#
# Testdrive v1.04
# @(#)testdrive  {1.8 1/13/94 13:12:29}
#
# Jim Jagielski Jan 1994
#
# Usage: testdrive [ id ]
#
# where id is the SCSI id of the drive. If omitted then the environmental
# variable TAPE is used if defined else an error message is generated.
#
#
###############################################################################

PATH=/bin:/usr/bin

trap "cleanup 1" HUP INT QUIT

#
# Create the name of the device file from the SCSI id.
# You must use a nonrewinding device.
#

TAPENAME=/dev/rmt/tc

#
# Some misc stuff
#
MATCH[0]="match OK"
MATCH[1]="do NOT match"
MATCH[2]="couldn't be compared"

PASS[0]="pass"
PASS[1]="fail"

origdir=tc_orig$$
copydir=tc_copy$$


if [[ $# != 0 ]]; then
    TAPE=$TAPENAME$1n
else
    if [[ -z "$TAPE" ]]; then
	print "Error: No tape device specified"
	exit 1
    fi
fi

if [[ $(whoami) = root ]]; then
    print "You should not do this test as root because it could be dangerous if"
    print "something goes wrong and because it is a more severe test not to"
    print "use root anyway."
    exit 1
fi

if [[ ! -r $TAPE ]]; then
    print "Error: I can't read from '$TAPE'. Aborting drive test"
    exit 1
fi
if [[ ! -w $TAPE ]]; then
    print "Error: I can't write to '$TAPE'. Aborting drive test"
    exit 1
fi

#############################################################################
#
# Set up all the support functions
#
#############################################################################

function tdwt {
    print $1 | cpio -o 2>/dev/null | tcb > $TAPE
}

function tdrd {
    tcb < $TAPE | cpio -imu $1 2>/dev/null
}

function ttime {
    tdate=$(date '+%H:%M:%S')
    let hour=3600*${tdate%%:*}
    mmin=${tdate%:*}
    let min=60*${mmin#*:}
    let sec=${tdate##*:}
    let $1=hour+min+sec
}

function tsize {
    tblock=$(du -s $1)
    let $2=${tblock%%/*}
}

function cleanup {
    if [[ -n "$TAPE" ]]; then
	mt -f $TAPE rewind 2>/dev/null
    fi
    /bin/rm -rf /tmp/$origdir 2>/dev/null
    /bin/rm -rf /tmp/$copydir 2>/dev/null
    if [[ -n "$TD_TESTFILE" ]]; then
	/bin/rm -rf $TD_TESTFILE 2>/dev/null
    fi
    exit $1
}

function verify {
    cd /tmp/$copydir
    /bin/rm -f * 2>/dev/null
    tdrd $1
    print "done"
    copyfile=$1
    origfile=/tmp/$origdir/$1
    cmp -s $copyfile $origfile
    status=$?
    print -n "Files ${origfile##*/} written to tape and $copyfile "
    print "read from tape ${MATCH[status]}"
    /bin/rm -rf /tmp/$copydir/*
    return $status
}

function print_banner {
    print "===================================================================="
    print
    print "This is 'testdrive', a small shell script that will test the"
    print "functionality of 'tc' with your tape drive. Since not all tapes"
    print "support all 'mt' and 'tc' options, failure of the script does"
    print "not necessarily imply that 'tc' will not work with it. For"
    print "example, the Teac 150 will fail this test since it doesn't"
    print "support 'bsf' and acts strangely with 'eod'."
    print
    print "If 'testdrive' succeeds all it's read and write tests before it"
    print "starts testing EOD, then all should be well. For all it's tests,"
    print "'testdrive' will use a large ASCII file. The default for this"
    print "file is '/FILES' but that can be overridden by setting \$BIGFILE"
    print "before running 'testdrive'."
    print
    print "Device file to be used for drive test is '$TAPE'"
    sleep 10
}

function identify_tape {
    sync	# always do this when testing kernel software

    print "Now attempting to identify tape drive"
    print
    sleep 2
    mt -f $TAPE status 2>/dev/null
    case $? in
	0) :
	   ;;
	4) print "Error: Tape isn't loaded."
	   exit 1
	   ;;
	*) print "Error: Can't get status... "
	   exit 1
	   ;;
    esac
    sleep 5
    print
    print "Now rewinding drive"
    print
    mt -f $TAPE rewind
    if [[ $? != 0 ]]; then
	print "Error: Rewind failed. Aborting test of drive"
	exit 1
    fi
}

function ready_files {
    /bin/rm -rf /tmp/$origdir 2>/dev/null
    /bin/rm -rf /tmp/$copydir 2>/dev/null
    if ! mkdir /tmp/$copydir || ! mkdir /tmp/$origdir ; then
	print "Error: Can't create temporary directories in /tmp."
	print "Aborting test."
	cleanup 1
    fi

    FILES=/FILES

    #
    # First look to see if $BIGFILE is defined, if not, then
    # use /FILES as it
    #
    if [[ -z "$BIGFILE" ]]; then
	print "I see that \$BIGFILE isn't defined... I'll try to use '$FILES'"
	if [[ ! -r $FILES ]]; then
	    print "Error: Either '$FILES' doesn't exist or I can't read it!"
	    print "Aborting test."
	    cleanup 1
	fi
    else
	print "I see \$BIGFILE: $BIGFILE. I'll use that."
	FILES=$BIGFILE
    fi

    #
    # Make a copy of it in /tmp
    #
    TD_TESTFILE=/tmp/${FILES##*/}
    cp $FILES $TD_TESTFILE
    if [[ $? != 0 ]]; then
	print "Error: Can't copy the file '$FILES' to '$TD_TESTFILE'!"
	print "Aborting test."
	cleanup 1
    fi
    print
}

function bigtest {
    print "===================================================================="
    print "= Start of Large file write/read test..."
    print "===================================================================="
    print
    tsize $TD_TESTFILE size
    print "$TD_TESTFILE is $size blocks long."
    print
    print -n "Now copying $TD_TESTFILE to the tape drive for Write/Read test ... "
    cd ${TD_TESTFILE%/*}
    ttime time1
    tdwt ${TD_TESTFILE##*/}
    ttime time2
    if [[ $? != 0 ]]; then
	print
	print "Error: Copy of file to tape drive failed. Aborting test of drive"
	cleanup 1
    fi
    print "done"
    let speed='(size*30)'/'(time2-time1)'
    print
    print "Tape write speed was around $speed kB/minute"
    print

    print "Now rewinding drive"
    mt -f $TAPE rewind
    if [[ $? != 0 ]]; then
	print "Error: Rewind failed. Aborting test of drive"
	cleanup 1
    fi

    print -n "Now reading the file from the tape to check for errors ... "
    cd /tmp/$origdir
    ln -s $TD_TESTFILE
    ttime time1
    verify ${TD_TESTFILE##*/}
    ttime time2
    case $? in
	1) print
	   print
	   print "Error: File read from tape does not match file written to tape"
	   print "Cannot continue. Aborting test of drive"
	   cleanup 1
	   ;;
	2) print
	   print "Error: System error or script error. Cannot compare files"
	   print "Cannot continue. Aborting test of drive"
	   cleanup 1
	   ;;
    esac
    let speed='(size*30)'/'(time2-time1)'
    print
    print "Tape read (and verify) speed was around $speed kB/minute"
    print
    print "Large file write/read test completed"
}

function multtest {
    print "===================================================================="
    print "= Start of Multiple file write/read test..."
    print "===================================================================="
    print
    print "Now creating 6 temporary files"
    print

    /bin/rm -rf /tmp/$origdir
    /bin/rm -rf /tmp/$copydir
    mkdir /tmp/$origdir
    mkdir /tmp/$copydir
    let size=0
    for t in 1 2 3 4 5 6
    do
	print -n "  file ${t} ... "
	head -${t}${t}${t}${t} $TD_TESTFILE  > /tmp/$origdir/file$t
	tsize /tmp/$origdir/file$t fsize
	let size=size+fsize
	print "done"
    done

    cd /tmp/$origdir
    sync	# always do this when testing kernel software

    print
    print "Now writing several files to the drive for Multiple Write/Read test"
    print

    cd /tmp/$origdir
    ttime time1
    for t in 1 2 3 4 5 6
    do
	print -n "  writing file $t ... "
	tdwt file$t
	if [[ $? != 0 ]]; then
	    print
	    print "Error: Problem writing file to tape. Aborting test of drive"
	    cleanup 1
	fi
	print "done"
    done
    ttime time2

    let speed='(size*30)'/'(time2-time1)'
    print
    print "Tape write speed was around $speed kB/minute"
    print
    print "Now rewinding"
    print
    mt -f $TAPE rewind

    ttime time1
    for t in 1 2 3 4 5 6
    do
	print -n "  reading file $t ... "
	verify file$t
	if [[ $? != 0 ]]; then
	    print
	    print "Error: Problem reading file from tape. Aborting test of drive"
	    cleanup 1
	fi
    done
    ttime time2

    let speed='(size*30)'/'(time2-time1)'
    print
    print "Tape read (and verify) speed was around $speed kB/minute"
    print
    print "Multiple file write/read test completed"
}

function fsftest {
    print "===================================================================="
    print "= Start of 'fsf' write/read test..."
    print "===================================================================="
    print
    print "Testing the drive's ability to skip forward between files using the"
    print "'mt fsf' command"
    print

    error=0

    cd /tmp/$origdir
    print -n "Now seeking for file 4 ... "
    mt -f $TAPE fsf 3
    if [[ $? != 0 ]]; then
	print
	print "This device does not support fsf. Aborting fsf test"
	return 1
    fi
    verify file4
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 6 ... "
    mt -f $TAPE fsf 1
    verify file6
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 1 ... "
    mt -f $TAPE rewind
    verify file1
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 2 ... "
    mt -f $TAPE fsf 0
    verify file2
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 3 ... "
    mt -f $TAPE fsf 0
    verify file3
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 5 ... "
    mt -f $TAPE fsf 1
    verify file5
    if [[ $? != 0 ]]; then error=1; fi

    if [[ $error != 0 ]]; then
	print
	print "ALERT: Problem seen during 'fsf' test"
	fsfresult=1
    fi

    print
    print "'fsf' write/read test completed"
}

function eodtest {
    print "===================================================================="
    print "= Start of 'eod' write/read test..."
    print "===================================================================="
    print
    print "Testing the drive's ability to find the end of the recorded data"
    print "using the 'mt eod' command"
    print
    print "If 'testdrive' worked up to now but fails this test, don't"
    print "worry... "
    print

    cd /tmp/$origdir
    print -n "Now writing file 1 ... "
    tdwt file1
    print "done"

    print "Now rewinding"
    mt -f $TAPE rewind

    print "Now searching for EOD"
    mt -f $TAPE eod
    if [[ $? != 0 ]]; then
	print
	print "This device does not support eod. Aborting eod test"
	return 1	
    fi

    print -n "Now writing file 2 ... "
    tdwt file2
    print "done"

    print -n "Now writing file 3 ... "
    tdwt file3
    print "done"

    print "Now searching for EOD without rewinding first"
    # Some drives cannot do this but the driver takes care of it.
    mt -f $TAPE eod

    print -n "Now writing file 4 ... "
    tdwt file4
    print "done"

    print "Now rewinding"
    mt -f $TAPE rewind

    print "Now searching for EOD"
    mt -f $TAPE eod

    print "Now searching for EOD again while still at EOD"
    mt -f $TAPE eod

    print "Now searching for EOD for a third time"
    mt -f $TAPE eod

    print -n "Now writing file 5 ... "
    tdwt file5
    print "done"

    print "Now rewinding"
    mt -f $TAPE rewind

    print "Now searching for EOD"
    mt -f $TAPE eod

    print -n "Now writing file 6 ... "
    tdwt file6
    print "done"

    print "Now rewinding"
    print
    mt -f $TAPE rewind

    for t in 1 2 3 4 5 6
    do
	print -n "Now reading file $t ... "
	verify file$t
	if [[ $? != 0 ]]; then
	    print
	    print "ALERT: Problem seen during 'eod' test"
	    eodresult=1
	fi
    done

    print
    print "'eod' write/read test completed"
}

function bsftest {
#
# Test the file searching features of the "mt bsf" command. This script
# requires that the drive support the "mt fsf" and "mt eod" commands.
#

    print "===================================================================="
    print "= Start of 'bsf' write/read test..."
    print "===================================================================="
    print
    print "Testing the drive's ability to skip backwards between files using"
    print "the 'mt bsf' command"
    print

    error=0

    cd /tmp/$origdir
    print -n "Now seeking for EOD ... "
    mt -f $TAPE eod
    if [[ $? != 0 ]]; then error=1; fi
    print "done"

    print -n "Now seeking for file 4 ... "
    mt -f $TAPE bsf 4
    if [[ $? != 0 ]]; then
	print
	print "This device does not support bsf. Aborting bsf test"
	bsfresult=1
	return 1
    fi
    mt -f $TAPE fsf 1
    verify file4
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 1 ... "
    mt -f $TAPE rewind
    verify file1
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for EOD again ... "
    mt -f $TAPE eod
    if [[ $? != 0 ]]; then error=1; fi
    print "done"

    print -n "Now seeking for file 6 ... "
    mt -f $TAPE bsf 2
    mt -f $TAPE fsf 1
    verify file6
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 5 ... "
    mt -f $TAPE bsf 3
    mt -f $TAPE fsf 1
    verify file5
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 2 ... "
    mt -f $TAPE bsf 5
    mt -f $TAPE fsf 1
    verify file2
    if [[ $? != 0 ]]; then error=1; fi

    print -n "Now seeking for file 3 ... "
    mt -f $TAPE bsf 0
    mt -f $TAPE fsf 0
    verify file3
    if [[ $? != 0 ]]; then error=1; fi

    if [[ $error != 0 ]]; then
	print "ALERT: Problem seen during 'eod' test"
	bsfresult=1
    fi

    print
    print "'bsf' write/read test completed"
}

###############################################################################
#                                                                             #
#                      The actual start of testdrive                          #
#                                                                             #
###############################################################################

print_banner

identify_tape

#
# Set up some stuff for read and write tests
#
ready_files

#
# now do the various tests
#

bigresult=0
bigtest
print "Now rewinding"
mt -f $TAPE rewind

################################################################################
#
# Now create some temporary files and other stuff for the remaining tests, all
# of which use multiple files
#
################################################################################

multresult=0
multtest
print "Now rewinding"
mt -f $TAPE rewind

fsfresult=0
fsftest
print "Now rewinding"
mt -f $TAPE rewind

eodresult=0
eodtest
print "Now rewinding"
mt -f $TAPE rewind

bsfresult=0
bsftest
print "Now rewinding"
mt -f $TAPE rewind

print
print "All tests completed."
print
print "TEST RESULTS:"
print
print "Large file write/read      : ${PASS[bigresult]}"
print "Multiple file write/read   : ${PASS[multresult]}"
print "'fsf' write/read test      : ${PASS[fsfresult]}"
print "'eod' write/read test      : ${PASS[eodresult]}"
print "'bsf' write/read test      : ${PASS[bsfresult]}"
cleanup 0

################################################################################
