Source code for Tpdd_test

'''
Tpdd_test.py
Copyright 2016 - Gary Hammond email gfhammond@gmail.com

Unit tests for the Tpdd class

The unit tests require a physical TPDD to be connected to the serial port with
a disk in the drive. The disk will be formatted as part of the tests so make
sure that the disk is one that is ok to be wiped.

Optional attributes that can be used with the tests are:

* no-tpdd - For tests not requiring a TPDD to be connected.
* tpdd-off - For tests that check for correct behaviour when there is a lack of communication with a TPDD
* no-disk - For tests that check for correct behaviour when there is no disk in the drive
* disk - For disk operation tests.
* format - Used to disable the formatting of the disk by using -a '!format' on the command line

**If the test suite is run without specifying attributes, it will report failures!**

Example test run with the disk in a TPDD2 drive::

    nosetests -v .\Tpdd_test.py -a 'disk' -a 'tpdd2' -a 'format'

'''

from Tpdd import Tpdd
from nose import with_setup
from nose.tools import assert_equals, assert_not_equals, assert_in, assert_true, assert_false
from nose.plugins.attrib import attr
from unittest.case import SkipTest
import time
import operator

disk_in_drive               = False
drive_present               = False
uut                         = Tpdd('COM1')

result = uut.get_status()
if result[0] == uut.ERR_NO_CTS:
    drive_present = False
    disk_in_drive = False
elif result[0] == uut.OK:
    drive_present = True
    disk_in_drive = True
elif result[0] == uut.ERR_NO_DISK:
    drive_present = True
    disk_in_drive = False

###############################################################################
# Support functions
###############################################################################

def read_file(filename):
    '''
    Reads the contents of a local file.

    :param filename: The name of the file to read from.

    :returns: The data as read from the file if successful, otherwise an empty string.
    '''

    # Check to see if the file can be opened for reading.
    try:
        file = open(filename, 'r')
        # Read the data from the file
        try:
            _data = file.read()
            # Close the file
            try:
                file.close()
            except:
                print 'Error closing the file.'
                return ''
        except:
            print 'Unable to data from the file.'
            return ''
    except:
        print 'Error opening the file for reading.'
        return ''

    return _data

def write_file(filename, data):
    '''
    Writes data to a local file.

    :param filename: The name of the file to write to.

    :param data: The data to write to the file.

    :returns: True if successful, otherwise False.
    '''

    # Check to see if the file can be opened for writing.
    try:
        file = open(filename, 'wb')
        # Write the data to the file
        try:
            file.write(data)
            # Close the file
            try:
                file.close()
            except:
                print 'Error closing the file.'
                return False
        except:
            print 'Unable to write the data to the file.'
            return False
    except:
        print 'Error opening the file for writing.'
        return False

    return True

###############################################################################
# Test cases
###############################################################################

def uut_setup():
    pass

def uut_teardown():
    pass

#------------------------------------------------------------------------------
# Tests that do not require a TPDD
# Uses the 'no-tpdd' attribute
#------------------------------------------------------------------------------

@attr('no-tpdd')
@attr('disk')
[docs]def test_checksum(): ''' Test that the checksum method returns a valid checksum ''' _test_data = [[0x00], [0xff], [0x01, 0x59], [0xfe, 0x2a, 0xb9], [0xde, 0xad, 0xbe, 0xef], [0x5a, 0x5a, 0x01, 0x00, 0x66], [0x29, 0xa2] + [0x20 for number in xrange(24)] + [0x46, 0x03], [0x17 for number in xrange(132)]] for _data in _test_data: _sum = 0 for _x in _data: _sum += _x _checksum = operator.xor((_sum % 256), 255) _result = uut.checksum(_data) assert_equals(_result, _checksum)
@attr('no-tpdd') @attr('disk')
[docs]def test_parse_invalid_filename(): ''' Tests various invalid filenames ''' _invalid_filename = ['a.do', '0ab.do', ':abc.do', 'abcdef', '1:abcd', '0:abcdef.', '2:123456.do', '0:abcdefg.123', '1:abcdef.1234', '1234567.do'] for _item in _invalid_filename: _result = uut.parse_filename(_item) print _result assert_equals(_result[0], uut.FAIL)
@attr('no-tpdd') @attr('disk')
[docs]def test_parse_valid_filename(): ''' Tests various valid filenames ''' _valid_filename = [['0:a.do', '0:a .do'], ['0:ab.do', '0:ab .do'], ['0:abc.do', '0:abc .do'], ['0:ABCD.DO', '0:ABCD .DO'], ['0:abcde.do', '0:abcde .do'], ['0:abcdef.do', '0:abcdef.do'], ['1:a.do', '1:a .do'], ['1:ab.do', '1:ab .do'], ['1:abc.do', '1:abc .do'], ['1:abcd.do', '1:abcd .do'], ['1:abcde.do', '1:abcde .do'], ['1:abcdef.do', '1:abcdef.do'], ['0:abc123.a', '0:abc123.a'], ['0:abc123.ab', '0:abc123.ab'], ['0:abc123.abc', '0:abc123.abc']] for _item in _valid_filename: _result = uut.parse_filename(_item[0]) print _result assert_equals(_result[1], _item[1])
@attr('no-tpdd') @attr('disk')
[docs]def test_parse_invalid_return_code_item(): ''' Test valid return codes ''' _invalid_codes = [[chr(0x13), chr(0x01), chr(0x00), chr(0x00)], [chr(0x12), chr(0x04), chr(0x30), chr(0x34)], [chr(0x12)], [chr(0x12), chr(0x01)], [chr(0x12), chr(0x01), chr(0x00)]] for _item in _invalid_codes: _result = uut.parse_return_code(_item) print _result assert_equals(_result[0], 0xff)
@attr('no-tpdd') @attr('disk')
[docs]def test_parse_valid_return_code_item(): ''' Test valid return code items. The last test item is an invalid code however the format of the return message is valid. ''' _valid_codes = [[chr(0x12), chr(0x01), chr(0x00), chr(0x00)], [chr(0x12), chr(0x01), chr(0x30), chr(0x34)], [chr(0x12), chr(0x01), chr(0xff), chr(0xaa)], [chr(0x12), chr(0x01), chr(0x5f), chr(0xaa)]] for _item in _valid_codes: _result = uut.parse_return_code(_item) print _result assert_equals(_result[0], ord(_item[2]))
@attr('no-tpdd') @attr('disk')
[docs]def test_return_code_item_invalid(): ''' Test invalid return code descriptions ''' _invalid_codes = [0x01, 0x5f, 0xaa, 1, 'test'] for _item in _invalid_codes: _result = uut.return_code_item(_item) print _result assert_equals(_result[1], uut.ERR_CODE_INVALID_TEXT)
@attr('no-tpdd') @attr('disk')
[docs]def test_return_code_item_valid(): ''' Test valid return code descriptions ''' _valid_codes = [[0x00, 'normal (no error)'], [0x40, 'no start mark'], [0xff, 'writing data to disk drive failed']] for _item in _valid_codes: _result = uut.return_code_item(_item[0]) print _result assert_equals(_result[1], _item[1])
#------------------------------------------------------------------------------ # TPDD off Tests # Uses the 'tpdd-off' attribute #------------------------------------------------------------------------------ @attr('tpdd-off')
[docs]def test_status_no_drive(): ''' Test for a valid status with the drive not powered on ''' try: if not drive_present: _result = uut.get_status() else: raise SkipTest() except: print 'Unexpected error' raise SkipTest() assert_equals(_result[0], uut.ERR_NO_CTS) assert_equals(_result[1], uut.return_code_item(uut.ERR_NO_CTS)[1])
#------------------------------------------------------------------------------ # No disk tests # Uses the 'no-disk' attribute #------------------------------------------------------------------------------ @attr('no-disk')
[docs]def test_status_no_disk(): ''' Test for a 'no disk' or 'disk change' error with no disk in the drive ''' _result = uut.get_status() assert_in(_result[0], (uut.ERR_NO_DISK, uut.ERR_DISK_CHANGE)) assert_in(_result[1], (uut.return_code_item(uut.ERR_NO_DISK)[1], uut.return_code_item(uut.ERR_DISK_CHANGE)[1]))
#------------------------------------------------------------------------------ # Disk tests # Uses the 'disk' attribute. # Use the following attributes in addition to the 'disk' attribute where required: # - 'format' attribute for the disk formatting # - 'tpdd2' attribute for tests specific to a tpdd2 #------------------------------------------------------------------------------ @attr('disk')
[docs]def test_status_valid(): ''' Test for a valid status with the disk in the drive ''' _result = uut.get_status() assert_equals(_result[0], uut.OK) assert_equals(_result[1], uut.return_code_item(uut.OK)[1])
@attr('format')
[docs]def test_format(): ''' Formats the disk in the drive and checks for errors ''' _result = uut.format_disk() assert_equals(_result[0], uut.OK) assert_equals(_result[1], uut.return_code_item(uut.OK)[1])
@attr('disk')
[docs]def test_dir_empty_disk_bank_0(): ''' Check to see if any empty disk reports the correct number of bytes ''' uut.set_bank('0') _result = uut.get_dir()[1] assert_in(_result, (['101120 bytes free'], ['202240 bytes free']))
@attr('tpdd2')
[docs]def test_dir_empty_disk_bank_1(): ''' Check that an empty disks reports the correct number of bytes on bank 1 ''' uut.set_bank('1') _result = uut.get_dir()[1] assert_equals(_result, ['202240 bytes free'])
@attr('disk')
[docs]def test_copy_file_to_bank_0(): ''' Copies a file to the TPDD ''' _data = read_file('testfile.txt') _result = uut.save_file('0:TEMP0.DO', _data) assert_equals(_result[0], uut.OK)
@attr('tpdd2')
[docs]def test_copy_file_to_bank_1(): ''' If the disk is a TPDD 2 disk do the test again on the second bank ''' _data = read_file('testfile.txt') _result = uut.save_file('1:TEMP1.DO', _data) assert_equals(_result[0], uut.OK)
@attr('disk')
[docs]def test_copy_file_from_bank_0(): ''' Copies a file from the TPDD ''' _result0 = uut.load_file('0:TEMP0.DO') if _result0[0] == uut.OK: _result1 = write_file('temp0.txt', _result0[1]) assert_equals(_result0[0], uut.OK) assert_true(_result1)
@attr('tpdd2')
[docs]def test_copy_file_from_bank_1(): ''' If the disk is a TPDD 2 disk do the test again on the second bank ''' _result0 = uut.load_file('1:TEMP1.DO') if _result0[0] == uut.OK: _result1 = write_file('temp1.txt', _result0[1]) assert_equals(_result0[0], uut.OK) assert_true(_result1)
@attr('disk')
[docs]def test_file_exists_bank_0(): ''' Checks the file exists method ''' _result = uut.file_exists('0:TEMP0.DO') assert_true(_result)
@attr('tpdd2')
[docs]def test_file_exists_bank_1(): ''' If the disk is a TPDD 2 disk do the test again on the second bank ''' _result = uut.file_exists('1:TEMP1.DO') assert_true(_result)
@attr('disk')
[docs]def test_file_not_exists_bank_0(): ''' Checks the file exists method with non-existent files ''' filenames = ['0:NOFILE.DO', ':TEMP0.DO', 'TEMP0.DO', '2:temp1.DO'] for item in filenames: _result = uut.file_exists(item) assert_false(_result)
@attr('tpdd2')
[docs]def test_file_not_exists_bank_1(): ''' If the disk is a TPDD 2 disk do the test again on the second bank ''' _result = uut.file_exists('1:NOFILE.DO') assert_false(_result)
@attr('disk')
[docs]def test_rename_valid_file_bank_0(): ''' Checks the file rename method with valid filenames ''' _result = uut.rename_file('0:TEMP0.DO', '0:TEMP2.DO') assert_equals(_result[0], uut.OK)
@attr('tpdd2')
[docs]def test_rename_valid_file_bank_1(): ''' If the disk is a TPDD 2 disk do the test again on the second bank ''' _result = uut.rename_file('1:TEMP1.DO', '1:TEMP3.DO') assert_equals(_result[0], uut.OK)
@attr('disk')
[docs]def test_rename_invalid_file_bank_0(): ''' Checks the file rename method with invalid filenames ''' filenames = [['0:TEMP0.DO', 'TEMP0.DO'], ['0:TEMP0.DO', ':TEMP0.DO'], ['0:TEMP0.DO', '1:TEMP0.DO'], ['0:TEMP0.DO', '0:TEMP000.DO'], [':TEMP0.DO', '0:TEMP0.DO'], ['TEMP0.DO', '0:TEMP0.DO'], ['0:TEMP000.DO', '0:TEMP0.DO'], ['0:TEMP0.DO', '0:TEMP0.DO']] for item in filenames: _result = uut.rename_file(item[0], item[1]) assert_not_equals(_result[0], uut.OK)
@attr('tpdd2')
[docs]def test_rename_invalid_file_bank_1(): ''' If the disk is a TPDD 2 disk do the test again on the second bank ''' filenames = [['1:TEMP0.DO', 'TEMP0.DO'], ['1:TEMP0.DO', ':TEMP0.DO'], ['1:TEMP0.DO', '0:TEMP0.DO'], ['1:TEMP0.DO', '1:TEMP000.DO'], [':TEMP0.DO', '1:TEMP0.DO'], ['TEMP0.DO', '1:TEMP0.DO'], ['1:TEMP000.DO', '1:TEMP0.DO'], ['1:TEMP0.DO', '1:TEMP0.DO']] for item in filenames: _result = uut.rename_file(item[0], item[1]) assert_not_equals(_result[0], uut.OK)
@attr('disk')
[docs]def test_delete_file_from_bank_0(): ''' deletes a file from the TPDD ''' _result = uut.delete_file('0:TEMP2.DO') assert_equals(_result[0], uut.OK)
@attr('tpdd2')
[docs]def test_delete_file_from_bank_1(): ''' If the disk is a TPDD 2 disk do the test again on the second bank ''' _result = uut.delete_file('1:TEMP3.DO') assert_equals(_result[0], uut.OK)