Skip to content

Commit

Permalink
Add remaining tests for nfc/clf/transport.py
Browse files Browse the repository at this point in the history
  • Loading branch information
nehpetsde committed Mar 29, 2017
1 parent a4f7ec5 commit e64076b
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 11 deletions.
8 changes: 4 additions & 4 deletions src/nfc/clf/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@
import re
import errno
import termios
import serial.tools.list_ports
from binascii import hexlify

try:
import usb1 as libusb
except ImportError:
except ImportError: # pragma: no cover
raise ImportError("missing usb1 module, try 'pip install libusb1'")

try:
import serial
except ImportError:
import serial.tools.list_ports
except ImportError: # pragma: no cover
raise ImportError("missing serial module, try 'pip install pyserial'")

import logging
Expand Down Expand Up @@ -220,7 +220,7 @@ def __init__(self, usb_bus, dev_adr):

def __del__(self):
self.close()
if self.context:
if self.context: # pragma: no branch
self.context.exit()

def open(self, usb_bus, dev_adr):
Expand Down
240 changes: 233 additions & 7 deletions tests/test_clf_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

import pytest
from pytest_mock import mocker # noqa: F401
from mock import call
from mock import call, MagicMock
import termios
import errno

import logging
logging.basicConfig(level=logging.DEBUG-1)
logging_level = logging.getLogger().getEffectiveLevel()
logging.getLogger("nfc.clf").setLevel(logging_level)
logging.getLogger("nfc.clf.transport").setLevel(logging_level)
# import logging
# logging.basicConfig(level=logging.DEBUG-1)
# logging_level = logging.getLogger().getEffectiveLevel()
# logging.getLogger("nfc.clf").setLevel(logging_level)
# logging.getLogger("nfc.clf.transport").setLevel(logging_level)


def HEX(s):
Expand Down Expand Up @@ -60,7 +60,7 @@ class TestTTY(object):
(['COM3'], '', False)),
('com:X', [('COM1',), ('COM2',), ('COM3',)], [],
None),
('comport', [('COM1',), ('COM2',), ('COM3',)], [],
('com_', [('COM1',), ('COM2',), ('COM3',)], [],
None),
('', [('COM1',), ('COM2',), ('COM3',)], [],
None),
Expand Down Expand Up @@ -168,3 +168,229 @@ def test_close(self, serial, tty):
serial.return_value.close.assert_called_with()
assert tty.tty is None
tty.close()


class TestUSB(object):
class Endpoint(object):
def __init__(self, addr, attr, maxp=64):
self.addr, self.attr, self.maxp = addr, attr, maxp

def getAddress(self):
return self.addr

def getAttributes(self):
return self.attr

def getMaxPacketSize(self):
return self.maxp

class Settings(object):
def __init__(self, endpoints):
self.endpoints = endpoints

def iterEndpoints(self):
return iter(self.endpoints)

class Device(object):
def __init__(self, vid, pid, bus, dev, settings=None):
self.vid, self.pid, self.bus, self.dev = vid, pid, bus, dev
self.settings = settings

def iterSettings(self):
return iter(self.settings)

def getVendorID(self):
return self.vid

def getProductID(self):
return self.pid

def getBusNumber(self):
return self.bus

def getDeviceAddress(self):
return self.dev

def getManufacturer(self):
return 'Vendor'

def getProduct(self):
return 'Product'

def open(self):
return MagicMock(spec=nfc.clf.transport.libusb.USBDeviceHandle)

@pytest.fixture() # noqa: F811
def usb_context(self, mocker):
libusb = 'nfc.clf.transport.libusb'
return mocker.patch(libusb + '.USBContext', autospec=True)

@pytest.mark.parametrize("path, devices, found", [
('tty', [], None),
('usb_', [], None),
('usb', [Device(1, 2, 3, 4), Device(5, 6, 7, 8)],
[(1, 2, 3, 4), (5, 6, 7, 8)]),
('usb:0001', [Device(1, 2, 3, 4), Device(1, 6, 7, 8)],
[(1, 2, 3, 4), (1, 6, 7, 8)]),
('usb:0001:0002', [Device(1, 2, 3, 4), Device(1, 6, 7, 8)],
[(1, 2, 3, 4)]),
('usb:003', [Device(1, 2, 3, 4), Device(5, 6, 3, 8)],
[(1, 2, 3, 4), (5, 6, 3, 8)]),
('usb:003:004', [Device(1, 2, 3, 4), Device(5, 6, 3, 8)],
[(1, 2, 3, 4)]),
])
def test_find(self, usb_context, path, devices, found):
usb_context_enter = usb_context.return_value.__enter__
usb_context_enter.return_value.getDeviceList.return_value = devices
if not found == IOError:
assert nfc.clf.transport.USB.find(path) == found
else:
with pytest.raises(IOError):
nfc.clf.transport.USB.find(path)

@pytest.mark.parametrize("vid, pid, bus, dev, settings", [
(0x1000, 0x2000, 1, 2, []),
(0x1000, 0x2000, 2, 1, []),
(0x1000, 0x2000, 1, 2,
[Settings([Endpoint(0x0004, 0x0001), Endpoint(0x0084, 0x0002)])]),
(0x1000, 0x2000, 1, 2,
[Settings([Endpoint(0x0004, 0x0002), Endpoint(0x0084, 0x0001)])]),
])
def test_init_fail_attr(self, usb_context, vid, pid, bus, dev, settings):
usb_context.return_value.getDeviceList.return_value = [
self.Device(vid, pid, bus, dev, settings)
]
with pytest.raises(IOError) as excinfo:
nfc.clf.transport.USB(1, 2)
assert excinfo.value.errno == errno.ENODEV

def test_init_fail_name(self, usb_context):
device = self.Device(0x1000, 0x2000, 1, 2, [
self.Settings([
self.Endpoint(0x0004, 0x0002),
self.Endpoint(0x0084, 0x0002),
])
])
device.getManufacturer = MagicMock()
device.getManufacturer.side_effect = [
nfc.clf.transport.libusb.USBErrorIO
]
usb_context.return_value.getDeviceList.return_value = [device]
usb = nfc.clf.transport.USB(1, 2)
assert usb.manufacturer_name is None
assert usb.product_name is None

def test_init_fail_open(self, usb_context):
device = self.Device(0x1000, 0x2000, 1, 2, [
self.Settings([
self.Endpoint(0x0004, 0x0002),
self.Endpoint(0x0084, 0x0002),
])
])
device.open = MagicMock()
device.open.side_effect = [
nfc.clf.transport.libusb.USBErrorAccess,
nfc.clf.transport.libusb.USBErrorBusy,
nfc.clf.transport.libusb.USBErrorNoDevice,
]
usb_context.return_value.getDeviceList.return_value = [device]

with pytest.raises(IOError) as excinfo:
nfc.clf.transport.USB(1, 2)
assert excinfo.value.errno == errno.EACCES

with pytest.raises(IOError) as excinfo:
nfc.clf.transport.USB(1, 2)
assert excinfo.value.errno == errno.EBUSY

with pytest.raises(IOError) as excinfo:
nfc.clf.transport.USB(1, 2)
assert excinfo.value.errno == errno.ENODEV

@pytest.fixture() # noqa: F811
def usb(self, usb_context):
usb_context.return_value.getDeviceList.return_value = [
self.Device(0x1000, 0x2000, 1, 2, [
self.Settings([
self.Endpoint(0x0004, 0x0002),
self.Endpoint(0x0084, 0x0002),
self.Endpoint(0x1004, 0x0002),
self.Endpoint(0x1084, 0x0002),
])
])
]
usb = nfc.clf.transport.USB(1, 2)
return usb

def test_manufacturer_name(self, usb):
assert usb.manufacturer_name == "Vendor"

def test_product_name(self, usb):
assert usb.product_name == "Product"

def test_read(self, usb):
usb.usb_dev.bulkRead.side_effect = [
b'12',
b'34',
nfc.clf.transport.libusb.USBErrorTimeout,
nfc.clf.transport.libusb.USBErrorNoDevice,
nfc.clf.transport.libusb.USBError,
b'',
]
assert usb.read() == b'12'
usb.usb_dev.bulkRead.assert_called_with(0x84, 300, 0)

assert usb.read(100) == b'34'
usb.usb_dev.bulkRead.assert_called_with(0x84, 300, 100)

with pytest.raises(IOError) as excinfo:
usb.read()
assert excinfo.value.errno == errno.ETIMEDOUT

with pytest.raises(IOError) as excinfo:
usb.read()
assert excinfo.value.errno == errno.ENODEV

with pytest.raises(IOError) as excinfo:
usb.read()
assert excinfo.value.errno == errno.EIO

with pytest.raises(IOError) as excinfo:
usb.read()
assert excinfo.value.errno == errno.EIO

usb.usb_inp = None
assert usb.read() is None

def test_write(self, usb):
usb.write(b'12')
usb.usb_dev.bulkWrite.assert_called_with(0x04, b'12', 0)

usb.write(b'12', 100)
usb.usb_dev.bulkWrite.assert_called_with(0x04, b'12', 100)

usb.write(64 * b'1', 100)
usb.usb_dev.bulkWrite.assert_has_calls([
call(0x04, 64 * b'1', 100),
call(0x04, b'', 100),
])

usb.usb_dev.bulkWrite.side_effect = [
nfc.clf.transport.libusb.USBErrorTimeout,
nfc.clf.transport.libusb.USBErrorNoDevice,
nfc.clf.transport.libusb.USBError,
]
with pytest.raises(IOError) as excinfo:
usb.write(b'12')
assert excinfo.value.errno == errno.ETIMEDOUT

with pytest.raises(IOError) as excinfo:
usb.write(b'12')
assert excinfo.value.errno == errno.ENODEV

with pytest.raises(IOError) as excinfo:
usb.write(b'12')
assert excinfo.value.errno == errno.EIO

usb.usb_out = None
assert usb.write(b'12') is None

0 comments on commit e64076b

Please sign in to comment.