def test_on_receive_pass_to_router(): """ Test _on_receive passes the message to the base APRSRouter class. """ # Create a frame frame = AX25UnnumberedInformationFrame( destination='VK4BWI-2', source='VK4MSL-10', pid=0xf0, payload=b':VK4BWI-2 :testing{123', repeaters=['WIDE2-1','WIDE1-1'] ) # Create our interface ax25int = DummyAX25Interface() aprsint = APRSInterface(ax25int, 'VK4MSL-10') # Now pass the frame in as if it were just received aprsint._on_receive(frame) # There should be two calls made, one to our deduplication clean-up, the # other to our superclass eq_(len(ax25int._loop.calls), 2) (_, callfunc) = ax25int._loop.calls.pop(0) eq_(callfunc, aprsint._schedule_dedup_cleanup) (_, callfunc) = ax25int._loop.calls.pop(0) assert isinstance(callfunc, partial) eq_(callfunc.func, super(APRSInterface, aprsint)._on_receive)
def test_on_receive_addressed(): """ Test _on_receive of message addressed to station. """ # Create a frame frame = AX25UnnumberedInformationFrame( destination='APZAIO', source='VK4BWI-2', pid=0xf0, payload=b':VK4MSL-10:testing{123', repeaters=['WIDE2-1','WIDE1-1'] ) # Create our interface ax25int = DummyAX25Interface() aprsint = APRSInterface(ax25int, 'VK4MSL-10') # Now pass the frame in as if it were just received aprsint._on_receive(frame) # There should be three calls made, one to our deduplication clean-up, the # other to our superclass, the third to our received_address_msg signal. eq_(len(ax25int._loop.calls), 3) (_, callfunc) = ax25int._loop.calls.pop(0) eq_(callfunc, aprsint._schedule_dedup_cleanup) (_, callfunc) = ax25int._loop.calls.pop(0) assert isinstance(callfunc, partial) eq_(callfunc.func, super(APRSInterface, aprsint)._on_receive) (_, callfunc) = ax25int._loop.calls.pop(0) assert isinstance(callfunc, partial) eq_(callfunc.func, aprsint.received_addressed_msg.emit)
def test_on_receive_dup(): """ Test _on_receive ignores duplicate frames. """ # Create a frame and hash it frame = AX25UnnumberedInformationFrame( destination='VK4BWI-2', source='VK4MSL-10', pid=0xf0, payload=b':VK4BWI-2 :testing{123', repeaters=['WIDE2-1','WIDE1-1'] ) framedigest = APRSInterface._hash_frame(frame) # Create our interface ax25int = DummyAX25Interface() aprsint = APRSInterface(ax25int, 'VK4MSL-10') # Inject the hash now = aprsint._loop.time() aprsint._msg_expiry.update({ framedigest: now + 3 }) # Now pass the frame in as if it were just received aprsint._on_receive(frame) # There should be no calls made eq_(len(ax25int._loop.calls), 0)
def test_on_receive_exception(): """ Test _on_receive swallows exceptions. """ # Create a frame frame = AX25UnnumberedInformationFrame( destination='VK4BWI-2', source='VK4MSL-10', pid=0xf0, payload=b':VK4BWI-2 :testing{123', repeaters=['WIDE2-1','WIDE1-1'] ) # Create our interface ax25int = DummyAX25Interface() aprsint = APRSInterface(ax25int, 'VK4MSL-10') # Stub the _test_or_add_frame so it returns false aprsint._test_or_add_frame = lambda *a : False # Stub the IOLoop's call_soon so it fails calls = [] def stub(*args): calls.append(args) raise RuntimeError('Oopsie') aprsint._loop.call_soon = stub # Now pass the frame in as if it were just received aprsint._on_receive(frame) # We should have called call_soon, but the exception should have been # caught and logged. eq_(len(calls), 1)
def test_on_receive_unsol_ackrej(): """ Test _on_receive of unsolicited ACK/REJ addressed to station. """ # Create a frame frame = AX25UnnumberedInformationFrame( destination='APZAIO', source='VK4BWI-2', pid=0xf0, payload=b':VK4MSL-10:ack123', repeaters=['WIDE2-1','WIDE1-1'] ) # Create our interface ax25int = DummyAX25Interface() aprsint = APRSInterface(ax25int, 'VK4MSL-10') # Now pass the frame in as if it were just received aprsint._on_receive(frame) # There should be two calls made, one to our deduplication clean-up, the # other to our superclass. We don't pass the message out otherwise. eq_(len(ax25int._loop.calls), 2) (_, callfunc) = ax25int._loop.calls.pop(0) eq_(callfunc, aprsint._schedule_dedup_cleanup) (_, callfunc) = ax25int._loop.calls.pop(0) assert isinstance(callfunc, partial) eq_(callfunc.func, super(APRSInterface, aprsint)._on_receive)
def test_on_receive_notframe(): """ Test _on_receive ignores non-APRS-frames. """ # Create a frame class DummyFrame(AX25UnnumberedInformationFrame): def __init__(self, *args, **kwargs): self.addressee_calls = 0 super(DummyFrame, self).__init__(*args, **kwargs) @property def addressee(self): self.addressee_calls += 1 return AX25Address.decode('N0CALL') frame = DummyFrame(destination='VK4BWI-2', source='VK4MSL-10', pid=0xf0, payload=b'this is not an APRS message', repeaters=['WIDE2-1', 'WIDE1-1']) # Create our interface ax25int = DummyAX25Interface() aprsint = APRSInterface(ax25int, 'VK4MSL-10') # Stub the _test_or_add_frame so it returns false aprsint._test_or_add_frame = lambda *a: False # Now pass the frame in as if it were just received aprsint._on_receive(frame) # The addressee property should not be touched eq_(frame.addressee_calls, 0)
def test_on_receive_sol_replyack(): """ Test _on_receive of solicited reply-ack addressed to station. """ # Create a frame frame = AX25UnnumberedInformationFrame( destination='APZAIO', source='VK4BWI-2', pid=0xf0, payload=b':VK4MSL-10:testing{356}123', repeaters=['WIDE2-1','WIDE1-1'] ) # Create our interface ax25int = DummyAX25Interface() aprsint = APRSInterface(ax25int, 'VK4MSL-10') # Inject a message handler for the message ID handler = DummyMessageHandler() aprsint._pending_msg['123'] = handler # Now pass the frame in as if it were just received aprsint._on_receive(frame) # There should be four calls made, one to our deduplication clean-up, the # second to our superclass, the third to the handler's _on_response method # and finally the incoming message should be emitted like a normal message. eq_(len(ax25int._loop.calls), 4) (_, callfunc) = ax25int._loop.calls.pop(0) eq_(callfunc, aprsint._schedule_dedup_cleanup) (_, callfunc) = ax25int._loop.calls.pop(0) assert isinstance(callfunc, partial) eq_(callfunc.func, super(APRSInterface, aprsint)._on_receive) (_, callfunc, msg) = ax25int._loop.calls.pop(0) eq_(callfunc, handler._on_response) eq_(bytes(frame), bytes(msg)) # The message should also have been treated as a new incoming message. (_, callfunc) = ax25int._loop.calls.pop(0) assert isinstance(callfunc, partial) eq_(callfunc.func, aprsint.received_addressed_msg.emit)