Esempio n. 1
0
def test_backend_version_check() -> None:
    """Test that an exception is raised if the arduino reports an unsupported version."""
    with pytest.raises(CommunicationError):
        SBArduinoHardwareBackend("COM0", SBArduinoSerialOldVersion1)
    with pytest.raises(CommunicationError):
        SBArduinoHardwareBackend("COM0", SBArduinoSerialOldVersion2)
    SBArduinoHardwareBackend("COM0", SBArduinoSerialNewVersion1)
    SBArduinoHardwareBackend("COM0", SBArduinoSerialNewVersion2)
    SBArduinoHardwareBackend("COM0", SBArduinoSerialNewVersion3)
Esempio n. 2
0
def test_ultrasound_distance_timeout() -> None:
    """Test that None is returned upon a timeout occurring."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()

    serial.append_received_data(b"> 0\n")
    metres = backend.get_ultrasound_distance(3, 4)
    serial.check_sent_data(b"U 3 4\n")
    assert metres is None

    serial.check_all_received_data_consumed()
Esempio n. 3
0
def test_backend_initialisation_serial() -> None:
    """Test commands/responses are sent/received during initialisation."""
    backend = make_backend()
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()
    serial.check_all_received_data_consumed()

    with pytest.raises(CommunicationError):
        SBArduinoHardwareBackend("COM0",
                                 SBArduinoSerialBootFail)  # type: ignore
    with pytest.raises(CommunicationError):
        SBArduinoHardwareBackend("COM0", SBArduinoSerialNoBoot)  # type: ignore
Esempio n. 4
0
def test_backend_handles_serial_exeption() -> None:
    """Test that an exception is raised when a SerialException happens."""
    check_for_communication_error(
        SBArduinoHardwareBackend(
            "COM0",
            SBArduinoSerialTimeout,  # type: ignore
        ))
    check_for_communication_error(
        SBArduinoHardwareBackend(
            "COM0",
            SBArduinoSerialException,  # type: ignore
        ))
Esempio n. 5
0
def test_ultrasound_pulse_on_same_pin() -> None:
    """Test same pin for trigger and echo."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()

    serial.append_received_data(b"> 2345\n")
    duration = backend.get_ultrasound_pulse(3, 3)
    serial.check_sent_data(b"T 3 3\n")
    assert duration == timedelta(microseconds=2345)

    # Check backend updated its view of what modes the pins are in now.
    assert backend.get_gpio_pin_mode(3) is GPIOPinMode.DIGITAL_INPUT

    serial.check_all_received_data_consumed()
Esempio n. 6
0
def test_ultrasound_distance_on_same_pin() -> None:
    """Test same pin for trigger and echo."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()

    serial.append_received_data(b"> 1230\n")
    metres = backend.get_ultrasound_distance(3, 3)
    serial.check_sent_data(b"U 3 3\n")
    assert metres is not None
    assert isclose(metres, 1.23)

    # Check backend updated its view of what modes the pins are in now.
    assert backend.get_gpio_pin_mode(3) is GPIOPinMode.DIGITAL_INPUT

    serial.check_all_received_data_consumed()
Esempio n. 7
0
def test_backend_handles_unrecognised_response() -> None:
    """Test that an exception is raised when an unrecognised response is received."""
    check_for_communication_error(
        SBArduinoHardwareBackend(
            "COM0",
            SBArduinoSerialErrorResponse,  # type: ignore
        ))
Esempio n. 8
0
def test_backend_initialisation() -> None:
    """Test that we can initialise a SBArduinoHardwareBackend."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    assert type(backend) is SBArduinoHardwareBackend
    assert type(backend._serial) is SBArduinoSerial
    assert all(pin.mode is GPIOPinMode.DIGITAL_INPUT
               for pin in backend._digital_pins.values())
    assert all(pin.state is False for pin in backend._digital_pins.values())
Esempio n. 9
0
def test_backend_read_digital_state_requires_pin_mode() -> None:
    """Check that pin must be in DIGITAL_INPUT* mode for read digital state to work."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_OUTPUT)
    assert backend.get_gpio_pin_mode(2) is not GPIOPinMode.DIGITAL_INPUT
    with pytest.raises(ValueError):
        backend.read_gpio_pin_digital_state(2)
Esempio n. 10
0
def test_backend_input_modes() -> None:
    """Check that the correct commands are send when setting pins to input modes."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_INPUT)
    serial.check_sent_data(b"W 2 Z\n")
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_INPUT_PULLUP)
    serial.check_sent_data(b"W 2 P\n")
    with pytest.raises(NotSupportedByHardwareError):
        backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_INPUT_PULLDOWN)
    serial.check_all_received_data_consumed()
Esempio n. 11
0
def test_backend_read_analogue() -> None:
    """Test that we can read the digital state of a pin."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()

    readings = [212, 535, 662, 385]
    for i, expected_reading in enumerate(readings):
        # "read analogue" command reads all four pins at once.
        identifier = 14 + i
        for j, reading in enumerate(readings):
            serial.append_received_data(f"> a{j} {reading}".encode("utf-8"),
                                        newline=True)
        expected_voltage = (expected_reading / 1024.0) * 5.0
        measured_voltage = backend.read_gpio_pin_analogue_value(identifier)
        assert isclose(measured_voltage, expected_voltage)
        serial.check_sent_data(b"A\n")

    serial.check_all_received_data_consumed()
Esempio n. 12
0
def test_backend_write_digital_state() -> None:
    """Test that we can write the digital state of a pin."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()
    # This should put the pin into the most recent (or default) output state.
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_OUTPUT)
    serial.check_sent_data(b"W 2 L\n")
    backend.write_gpio_pin_digital_state(2, True)
    serial.check_sent_data(b"W 2 H\n")
    backend.write_gpio_pin_digital_state(2, False)
    serial.check_sent_data(b"W 2 L\n")
    serial.check_all_received_data_consumed()
Esempio n. 13
0
def test_backend_get_set_pin_mode() -> None:
    """Test that we can get and set pin modes."""
    pin = 2
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    assert backend.get_gpio_pin_mode(pin) is GPIOPinMode.DIGITAL_INPUT
    backend.set_gpio_pin_mode(pin, GPIOPinMode.DIGITAL_OUTPUT)
    assert backend.get_gpio_pin_mode(pin) is GPIOPinMode.DIGITAL_OUTPUT
Esempio n. 14
0
def test_backend_handles_comment_response() -> None:
    """Test that comments in the Arduino's response are ignored."""
    backends: List[SBArduinoHardwareBackend] = [
        make_backend(),  # Normal
        SBArduinoHardwareBackend(  # Comment
            "COM0",
            SBArduinoSerialCommentResponse,  # type: ignore
        ),
    ]
    results: List[bool] = []
    for backend in backends:
        cast(SBArduinoSerial,
             backend._serial).append_received_data(b"> H", newline=True)
        results.append(backend.read_gpio_pin_digital_state(2))

    assert results[0] is results[1]
Esempio n. 15
0
def test_backend_read_digital_state() -> None:
    """Test that we can read the digital state of a pin."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()

    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_INPUT)
    serial.check_sent_data(b"W 2 Z\n")

    serial.append_received_data(b"> H", newline=True)
    assert backend.read_gpio_pin_digital_state(2) is True
    serial.check_sent_data(b"R 2\n")

    serial.append_received_data(b"> L", newline=True)
    assert backend.read_gpio_pin_digital_state(2) is False
    serial.check_sent_data(b"R 2\n")

    serial.append_received_data(b"> X", newline=True)  # invalid
    with pytest.raises(CommunicationError):
        backend.read_gpio_pin_digital_state(2)
    serial.check_sent_data(b"R 2\n")

    serial.check_all_received_data_consumed()
Esempio n. 16
0
def test_ultrasound_pulse() -> None:
    """Test that we can read an ultrasound pulse time."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()

    serial.append_received_data(b"> 2345\n")
    duration = backend.get_ultrasound_pulse(3, 4)
    serial.check_sent_data(b"T 3 4\n")
    assert duration == timedelta(microseconds=2345)

    # Check backend updated its view of what modes the pins are in now.
    assert backend.get_gpio_pin_mode(3) is GPIOPinMode.DIGITAL_OUTPUT
    assert backend.get_gpio_pin_digital_state(3) is False
    assert backend.get_gpio_pin_mode(4) is GPIOPinMode.DIGITAL_INPUT

    serial.check_all_received_data_consumed()
Esempio n. 17
0
def test_ultrasound_distance() -> None:
    """Test that we can read an ultrasound distance."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()

    serial.append_received_data(b"> 1230\n")
    metres = backend.get_ultrasound_distance(3, 4)
    serial.check_sent_data(b"U 3 4\n")
    assert metres is not None
    assert isclose(metres, 1.23)

    # Check backend updated its view of what modes the pins are in now.
    assert backend.get_gpio_pin_mode(3) is GPIOPinMode.DIGITAL_OUTPUT
    assert backend.get_gpio_pin_digital_state(3) is False
    assert backend.get_gpio_pin_mode(4) is GPIOPinMode.DIGITAL_INPUT

    serial.check_all_received_data_consumed()
Esempio n. 18
0
def test_backend_initialisation_serial() -> None:
    """Test commands/responses are sent/received during initialisation."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()
    serial.check_all_received_data_consumed()
Esempio n. 19
0
def test_backend_firmware_version() -> None:
    """Test that the firmware version is parsed correctly."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    assert backend.firmware_version == SBArduinoSerial.firmware_version
Esempio n. 20
0
def check_for_communication_error(backend: SBArduinoHardwareBackend) -> None:
    """Check that performing an operation on the backend raises a CommunicationError."""
    with pytest.raises(CommunicationError):
        backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_INPUT)
Esempio n. 21
0
def test_backend_handles_failure() -> None:
    """Test that an exception is raised when a failure response is received."""
    with pytest.raises(CommunicationError):
        SBArduinoHardwareBackend("COM0", SBArduinoSerialFailureResponse)
Esempio n. 22
0
def make_backend() -> SBArduinoHardwareBackend:
    """Instantiate an SBArduinoHardwareBackend  with some default arguments."""
    return SBArduinoHardwareBackend("COM0", SBArduinoSerial)  # type: ignore
Esempio n. 23
0
def test_backend_analogue_pin_modes() -> None:
    """Test that only certain modes are valid on digital pins."""
    pin = 14
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    with pytest.raises(NotSupportedByHardwareError):
        backend.set_gpio_pin_mode(pin, GPIOPinMode.DIGITAL_INPUT)
    with pytest.raises(NotSupportedByHardwareError):
        backend.set_gpio_pin_mode(pin, GPIOPinMode.DIGITAL_INPUT_PULLUP)
    with pytest.raises(NotSupportedByHardwareError):
        backend.set_gpio_pin_mode(pin, GPIOPinMode.DIGITAL_INPUT_PULLDOWN)
    with pytest.raises(NotSupportedByHardwareError):
        backend.set_gpio_pin_mode(pin, GPIOPinMode.DIGITAL_OUTPUT)
    backend.set_gpio_pin_mode(pin, GPIOPinMode.ANALOGUE_INPUT)
    with pytest.raises(NotSupportedByHardwareError):
        backend.set_gpio_pin_mode(pin, GPIOPinMode.ANALOGUE_OUTPUT)
    with pytest.raises(NotSupportedByHardwareError):
        backend.set_gpio_pin_mode(pin, GPIOPinMode.PWM_OUTPUT)
Esempio n. 24
0
def test_backend_digital_state_persists() -> None:
    """Test switching to a different mode and then back to output."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    serial = cast(SBArduinoSerial, backend._serial)
    serial.check_data_sent_by_constructor()
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_OUTPUT)
    serial.check_sent_data(b"W 2 L\n")
    backend.write_gpio_pin_digital_state(2, True)
    serial.check_sent_data(b"W 2 H\n")
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_INPUT)
    serial.check_sent_data(b"W 2 Z\n")
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_OUTPUT)
    serial.check_sent_data(b"W 2 H\n")
    backend.write_gpio_pin_digital_state(2, False)
    serial.check_sent_data(b"W 2 L\n")
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_INPUT)
    serial.check_sent_data(b"W 2 Z\n")
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_OUTPUT)
    serial.check_sent_data(b"W 2 L\n")
    serial.check_all_received_data_consumed()
Esempio n. 25
0
def test_backend_read_analogue_requires_analogue_pin() -> None:
    """Check that pins 2-13 are not supported by read analogue."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    with pytest.raises(NotSupportedByHardwareError):
        backend.read_gpio_pin_analogue_value(13)
Esempio n. 26
0
def test_backend_get_digital_state() -> None:
    """Test that we can read back the digital state of a pin."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    # This should put the pin into the most recent (or default) output state.
    backend.set_gpio_pin_mode(2, GPIOPinMode.DIGITAL_OUTPUT)
    assert backend.get_gpio_pin_digital_state(2) is False
    backend.write_gpio_pin_digital_state(2, True)
    assert backend.get_gpio_pin_digital_state(2) is True
    backend.write_gpio_pin_digital_state(2, False)
    assert backend.get_gpio_pin_digital_state(2) is False
Esempio n. 27
0
def test_backend_read_digital_state_requires_digital_pin() -> None:
    """Check that pins 14-19 are not supported by read digital state."""
    backend = SBArduinoHardwareBackend("COM0", SBArduinoSerial)
    with pytest.raises(NotSupportedByHardwareError):
        backend.read_gpio_pin_digital_state(14)