Ejemplo n.º 1
0
def test_hash_frame():
    """
    Test that _hash_frame returns a consistent result regardless of digipeaters
    """
    hash1 = APRSInterface._hash_frame(
        APRSMessageFrame(destination='VK4BWI-2',
                         source='VK4MSL-10',
                         addressee='VK4BWI-2',
                         message=b'testing',
                         msgid=123,
                         repeaters=['WIDE2-1', 'WIDE1-1']))

    hash2 = APRSInterface._hash_frame(
        APRSMessageFrame(destination='VK4BWI-2',
                         source='VK4MSL-10',
                         addressee='VK4BWI-2',
                         message=b'testing',
                         msgid=123,
                         repeaters=['VK4RZB*', 'WIDE1-1']))

    hash3 = APRSInterface._hash_frame(
        APRSMessageFrame(destination='VK4BWI-2',
                         source='VK4MSL-10',
                         addressee='VK4BWI-2',
                         message=b'testing',
                         msgid=123,
                         repeaters=['VK4RZB*', 'VK4RZA*']))

    # These should all be the same
    eq_(hash1, hash2)
    eq_(hash1, hash3)
Ejemplo n.º 2
0
def test_hash_frame_mismatch_payload():
    """
    Test that _hash_frame returns different hashes for mismatching source
    """
    hash1 = APRSInterface._hash_frame(
            APRSMessageFrame(
                destination='VK4BWI-2',
                source='VK4MSL-10',
                addressee='VK4BWI-2',
                message=b'testing 1',
                msgid=123,
                repeaters=['WIDE2-1','WIDE1-1']
            )
    )

    hash2 = APRSInterface._hash_frame(
            APRSMessageFrame(
                destination='VK4BWI-2',
                source='VK4MSL-10',
                addressee='VK4BWI-2',
                message=b'testing 2',
                msgid=123,
                repeaters=['WIDE2-1','WIDE1-1']
            )
    )

    # These should not be the same
    assert hash1 != hash2
Ejemplo n.º 3
0
def test_message_frame_malformed_delim():
    """
    Test the message frame decoder will reject malformed message delimiter
    """
    try:
        APRSMessageFrame.decode(None, ':123456789xThis is not valid', None)
    except ValueError as e:
        eq_(str(e), "Not a message frame: ':123456789xThis is not valid'")
Ejemplo n.º 4
0
def test_message_frame_malformed_start():
    """
    Test the message frame decoder will reject malformed start of message.
    """
    try:
        APRSMessageFrame.decode(None, 'x123456789:This is not valid', None)
    except ValueError as e:
        eq_(str(e), "Not a message frame: 'x123456789:This is not valid'")
Ejemplo n.º 5
0
def test_message_frame_copy():
    """
    Test we can copy a message frame
    """
    msg = APRSMessageFrame(destination='APRS',
                           source='VK4MSL',
                           addressee='TEST',
                           message='Station under test',
                           msgid=12345)
    msgcopy = msg.copy()
    assert msg is not msgcopy

    eq_(to_hex(bytes(msgcopy)), to_hex(bytes(msg)))
Ejemplo n.º 6
0
def test_test_or_add_frame_expired():
    """
    Test that _test_or_add_frame returns False for expired repeats
    """
    frame = APRSMessageFrame(
                destination='VK4BWI-2',
                source='VK4MSL-10',
                addressee='VK4BWI-2',
                message=b'testing',
                msgid=123,
                repeaters=['WIDE2-1','WIDE1-1']
    )
    framedigest = APRSInterface._hash_frame(frame)

    ax25int = DummyAX25Interface()
    aprsint = APRSInterface(ax25int, 'VK4MSL-10')
    # Inject the frame expiry
    expiry_time = aprsint._loop.time() - 1
    aprsint._msg_expiry[framedigest] = expiry_time

    # Try it out
    res = aprsint._test_or_add_frame(frame)

    # We should get 'False' as the response
    eq_(res, False)

    # The expiry time should be at least 25 seconds.
    eq_(len(aprsint._msg_expiry), 1)
    assert_greater(aprsint._msg_expiry.get(framedigest, 0),
            ax25int._loop.time() + 25)

    # A clean-up should have been scheduled.
    eq_(len(ax25int._loop.calls), 1)
    (_, callfunc) = ax25int._loop.calls.pop(0)
    eq_(callfunc, aprsint._schedule_dedup_cleanup)
Ejemplo n.º 7
0
def test_test_or_add_frame_repeat():
    """
    Test that _test_or_add_frame returns True for un-expired repeats
    """
    frame = APRSMessageFrame(
                destination='VK4BWI-2',
                source='VK4MSL-10',
                addressee='VK4BWI-2',
                message=b'testing',
                msgid=123,
                repeaters=['WIDE2-1','WIDE1-1']
    )
    framedigest = APRSInterface._hash_frame(frame)

    ax25int = DummyAX25Interface()
    aprsint = APRSInterface(ax25int, 'VK4MSL-10')
    # Inject the frame expiry
    expiry_time = aprsint._loop.time() + 1
    aprsint._msg_expiry[framedigest] = expiry_time

    # Try it out
    res = aprsint._test_or_add_frame(frame)

    # We should get 'False' as the response
    eq_(res, True)

    # Expiry should not have changed
    eq_(len(aprsint._msg_expiry), 1)
    eq_(aprsint._msg_expiry[framedigest], expiry_time)

    # Nothing further should be done.
    eq_(len(ax25int._loop.calls), 0)
Ejemplo n.º 8
0
def test_transmit_exception():
    """
    Test that transmit swallows exceptions.
    """
    ax25int = DummyAX25Interface()

    # Stub the transmit so it fails
    calls = []
    def stub(*args):
        calls.append(args)
        raise RuntimeError('Oopsie')
    ax25int.transmit = stub

    aprsint = APRSInterface(ax25int, 'VK4MSL-10')
    aprsint.transmit(
            APRSMessageFrame(
                destination='VK4BWI-2',
                source='VK4MSL-10',
                addressee='VK4BWI-2',
                message=b'testing',
                msgid=123
            )
    )

    # Transmit should have been called
    eq_(len(calls), 1)
Ejemplo n.º 9
0
def test_message_frame_get_msg():
    """
    Test the message frame will return the message enclosed
    """
    msg = APRSMessageFrame(destination='APRS',
                           source='VK4MSL',
                           addressee='TEST',
                           message='Station under test',
                           msgid=12345)
    eq_(msg.message, 'Station under test')
Ejemplo n.º 10
0
def test_message_encode_noreplyack():
    """
    Test we can encode without reply-ack.
    """
    msg = APRSMessageFrame(destination='APRS',
                           source='VK4MSL',
                           addressee='VK4BWI',
                           message='Test without "reply-ack" capability',
                           msgid='321')
    eq_(msg.payload, b':VK4BWI   :Test without "reply-ack" capability{321')
Ejemplo n.º 11
0
def test_message_encode_replyack_capable():
    """
    Test we can encode a reply-ack flag.
    """
    msg = APRSMessageFrame(destination='APRS',
                           source='VK4MSL',
                           addressee='VK4BWI',
                           message='Test announcing "reply-ack" capability',
                           msgid='321',
                           replyack=True)
    eq_(msg.payload, b':VK4BWI   :Test announcing "reply-ack" capability{321}')
Ejemplo n.º 12
0
def test_message_frame_bad_msgid():
    """
    Test the message frame constructor rejects too-big message IDs
    """
    try:
        APRSMessageFrame(destination='APRS',
                         source='VK4MSL',
                         addressee='BREAK',
                         message='Break this!',
                         msgid=123456)
    except ValueError as e:
        eq_(str(e), "message ID '123456' too long")
Ejemplo n.º 13
0
def test_message_encode_replyack_reply():
    """
    Test we can encode a reply-ack reply.
    """
    msg = APRSMessageFrame(destination='APRS',
                           source='VK4MSL',
                           addressee='VK4BWI',
                           message='Test reply using "reply-ack" capability',
                           msgid='321',
                           replyack='567')
    eq_(msg.payload,
        b':VK4BWI   :Test reply using "reply-ack" capability{321}567')
Ejemplo n.º 14
0
def test_send_response_oneshot():
    """
    Test that send_response ignores one-shot messages.
    """
    ax25int = DummyAX25Interface()
    aprsint = APRSInterface(ax25int, 'VK4MSL-10')
    aprsint.send_response(
        APRSMessageFrame(destination='VK4BWI-2',
                         source='VK4MSL-10',
                         addressee='VK4BWI-2',
                         message=b'testing',
                         msgid=None))

    # Nothing should be sent
    eq_(len(ax25int.transmitted), 0)
Ejemplo n.º 15
0
def test_send_message_replyack_notreplyack():
    """
    Test that send_message in confirmable mode generates a message handler.
    """
    ax25int = DummyAX25Interface()
    aprsint = APRSInterface(ax25int, 'VK4MSL-10')
    replymsg = APRSMessageFrame(destination='APRS',
                                source='VK4MDL-7',
                                addressee='VK4MSL-7',
                                message='Hello',
                                msgid='123',
                                replyack=False)
    try:
        aprsint.send_message('VK4MDL-7',
                             'Hi',
                             oneshot=False,
                             replyack=replymsg)
    except ValueError as e:
        eq_(str(e), 'replyack is not a reply-ack message')
Ejemplo n.º 16
0
def test_send_response_rej():
    """
    Test that send_response with ack=False sends rejection.
    """
    ax25int = DummyAX25Interface()
    aprsint = APRSInterface(ax25int, 'VK4MSL-10')
    aprsint.send_response(APRSMessageFrame(destination='VK4BWI-2',
                                           source='VK4MSL-10',
                                           addressee='VK4BWI-2',
                                           message=b'testing',
                                           msgid=123),
                          ack=False)

    # The APRS message handler will have tried sending the message
    eq_(len(ax25int.transmitted), 1)
    frame = ax25int.transmitted.pop(0)

    # Frame is a APRS message rejection frame
    assert isinstance(frame, APRSMessageFrame)
    eq_(frame.payload, b':VK4MSL-10:rej123')
Ejemplo n.º 17
0
def test_send_message_replyack():
    """
    Test that send_message with a replyack message sets replyack.
    """
    ax25int = DummyAX25Interface()
    aprsint = APRSInterface(ax25int, 'VK4MSL-10')
    replymsg = APRSMessageFrame(
            destination='APRS',
            source='VK4MDL-7',
            addressee='VK4MSL-7',
            message='Hello',
            msgid='123',
            replyack=True
    )
    res = aprsint.send_message(
            'VK4MDL-7', 'Hi', oneshot=False, replyack=replymsg
    )

    # We got back a handler class
    assert isinstance(res, APRSMessageHandler)

    # That message handler should be registered with the interface
    eq_(len(aprsint._pending_msg), 1)
    assert res.msgid in aprsint._pending_msg
    assert_is(aprsint._pending_msg[res.msgid], res)

    # The APRS message handler will have tried sending the message
    eq_(len(ax25int.transmitted), 1)
    frame = ax25int.transmitted.pop(0)

    # Frame is a APRS message frame
    assert isinstance(frame, APRSMessageFrame)

    # Frame has reply-ACK set
    eq_(frame.replyack, '123')

    # Message handler is in 'SEND' state
    eq_(res.state, APRSMessageHandler.HandlerState.SEND)