def test_network_switch_routes_packets_from_user_to_remote_destinations():
    """Validate packets from source to known destination are properly served.

    In this test we define a model with `NetworkService` (mock'ed),
    `NetworkSwitch` (being tested) and two network interfaces - eth and wifi
    (both mock'ed). `NetworkSwitch` defines two routes via these interfaces.

    Then we generate a couple of packets for the destination known to the
    switch and imitate they being received by the switch in `handle_message`.
    We make sure that these packets are being filled with source, sender
    and received addresses (taken from the switching table), SSNs are assigned
    and the packets are transmitted to the proper network interfaces.
    """
    sim, ns, eth, wifi = Mock(), Mock(), Mock(), Mock()
    switch = NetworkSwitch(sim)

    eth.address = 4
    eth_conn = Mock()
    eth.connections.set = Mock(return_value=eth_conn)
    wifi.address = 8
    wifi_conn = Mock()
    wifi.connections.set = Mock(return_value=wifi_conn)

    user_conn = switch.connections.set('user', ns, reverse=False)
    switch.connections.set('eth', eth, rname='network')
    switch.connections.set('wifi', wifi, rname='network')

    switch.table.add(10, connection='eth', next_hop=5)
    switch.table.add(20, connection='wifi', next_hop=13)

    pkt_1 = NetworkPacket(destination_address=10)
    pkt_2 = NetworkPacket(destination_address=20)

    switch.handle_message(pkt_1, connection=user_conn, sender=ns)
    sim.schedule.assert_called_with(0,
                                    eth.handle_message,
                                    args=(pkt_1, ),
                                    kwargs={
                                        'connection': eth_conn,
                                        'sender': switch,
                                    })
    assert pkt_1.receiver_address == 5  # = table[10].next_hop
    assert pkt_1.sender_address == 4  # = eth.address
    assert pkt_1.originator_address == 4  # = eth.address
    assert pkt_1.osn >= 0  # any value, but not None

    switch.handle_message(pkt_2, connection=user_conn, sender=ns)
    sim.schedule.assert_called_with(0,
                                    wifi.handle_message,
                                    args=(pkt_2, ),
                                    kwargs={
                                        'connection': wifi_conn,
                                        'sender': switch,
                                    })
    assert pkt_2.receiver_address == 13  # = table[20].next_hop
    assert pkt_2.sender_address == 8  # = wifi.address
    assert pkt_2.originator_address == 8  # = wifi.address
    assert pkt_2.osn >= 0  # = any value, but not None
Example #2
0
def test_wire_frame_implements_str():
    pkt_1 = NetworkPacket(data=AppData(100))
    pkt_2 = NetworkPacket(data=AppData(200))

    frame_1 = WireFrame(pkt_1, header_size=10, preamble=1, duration=2)
    assert str(frame_1) == f'WireFrame[D=2,HDR=10,PR=1 | {pkt_1}]'

    frame_2 = WireFrame(pkt_2)
    assert str(frame_2) == f'WireFrame[D=0,HDR=0,PR=0 | {pkt_2}]'
def test_network_packet_size():
    data = MagicMock()
    data.size = 100

    pkt1 = NetworkPacket(data=data)
    pkt2 = NetworkPacket()

    assert pkt1.size == 100
    assert pkt2.size == 0
def test_network_switch_ignores_old_messages():
    """Validate `NetworkSwitch` ignores messages with old SSN.
    """
    sim, ns, iface = Mock(), Mock(), Mock()
    switch = NetworkSwitch(sim)

    iface.address = 1
    iface_rev_conn = Mock()
    iface.connections.set = Mock(return_value=iface_rev_conn)

    ns_rev_conn = Mock()
    ns.connections.set = Mock(return_value=ns_rev_conn)

    switch.connections.set('user', ns, rname='network')
    iface_conn = switch.connections.set('iface', iface, rname='network')

    switch.table.add(10, connection='iface', next_hop=2)

    pkt_1 = NetworkPacket(destination_address=10, originator_address=13, osn=8)
    pkt_2 = NetworkPacket(destination_address=10, originator_address=13,
                          osn=8)  # the same SSN
    pkt_3 = NetworkPacket(destination_address=1, originator_address=13,
                          osn=5)  # older SSN, to sink
    pkt_4 = NetworkPacket(destination_address=1, originator_address=13,
                          osn=9)  # New one!
    pkt_5 = NetworkPacket(destination_address=10, originator_address=13,
                          osn=8)  # again old one

    switch.handle_message(pkt_1, connection=iface_conn, sender=iface)
    sim.schedule.assert_called_once_with(0,
                                         iface.handle_message,
                                         args=(pkt_1, ),
                                         kwargs={
                                             'connection': iface_rev_conn,
                                             'sender': switch,
                                         })
    sim.schedule.reset_mock()

    switch.handle_message(pkt_2, connection=iface_conn, sender=iface)
    sim.schedule.assert_not_called()

    switch.handle_message(pkt_3, connection=iface_conn, sender=iface)
    sim.schedule.assert_not_called()

    switch.handle_message(pkt_4, connection=iface_conn, sender=iface)
    sim.schedule.assert_called_once_with(0,
                                         ns.handle_message,
                                         args=(pkt_4, ),
                                         kwargs={
                                             'connection': ns_rev_conn,
                                             'sender': switch,
                                         })
    sim.schedule.reset_mock()

    switch.handle_message(pkt_5, connection=iface_conn, sender=iface)
    sim.schedule.assert_not_called()
def test_network_switch_sends_packets_with_its_interface_address_to_user():
    """Validate packet with destination matching one interface is routed up.

    We send three packets: one from 'eth', one from 'wifi' and one from 'user'.
    Make sure that in any case the packet is routed to user.
    """
    sim, ns, wifi, eth = Mock(), Mock(), Mock(), Mock()
    switch = NetworkSwitch(sim)

    ns_rev_conn = Mock()
    ns.connections.set = Mock(return_value=ns_rev_conn)

    eth.address = 1
    wifi.address = 2

    ns_conn = switch.connections.set('user', ns, rname='network')
    eth_conn = switch.connections.set('eth', eth, rname='network')
    wifi_conn = switch.connections.set('wifi', wifi, rname='network')

    pkt_1 = NetworkPacket(destination_address=2)
    pkt_2 = NetworkPacket(destination_address=2)
    pkt_3 = NetworkPacket(destination_address=2)

    # Sending the first packet from Ethernet interface:
    switch.handle_message(pkt_1, connection=eth_conn, sender=eth)
    sim.schedule.assert_called_once_with(0,
                                         ns.handle_message,
                                         args=(pkt_1, ),
                                         kwargs={
                                             'connection': ns_rev_conn,
                                             'sender': switch,
                                         })
    sim.schedule.reset_mock()

    # Sending another packet like from WiFi interface:
    switch.handle_message(pkt_2, connection=wifi_conn, sender=wifi)
    sim.schedule.assert_called_once_with(0,
                                         ns.handle_message,
                                         args=(pkt_2, ),
                                         kwargs={
                                             'connection': ns_rev_conn,
                                             'sender': switch,
                                         })
    sim.schedule.reset_mock()

    # Finally, send a packet from NetworkService (loopback-like behaviour):
    switch.handle_message(pkt_3, connection=ns_conn, sender=ns)
    sim.schedule.assert_called_once_with(0,
                                         ns.handle_message,
                                         args=(pkt_3, ),
                                         kwargs={
                                             'connection': ns_rev_conn,
                                             'sender': switch,
                                         })
    sim.schedule.reset_mock()
def test_network_packet_implements_str():
    data = MagicMock()
    data.__str__.return_value = 'AppData{sid=13}'
    pkt1 = NetworkPacket(destination_address=10,
                         originator_address=2,
                         sender_address=5,
                         receiver_address=6,
                         osn=4,
                         data=data)
    pkt2 = NetworkPacket(destination_address=5, data=data)
    pkt3 = NetworkPacket(destination_address=8)
    assert str(pkt1) == f'NetPkt{{DST=10,ORIGIN=2,SND=5,RCV=6,OSN=4 | {data}}}'
    assert str(pkt2) == f'NetPkt{{DST=5 | {data}}}'
    assert str(pkt3) == f'NetPkt{{DST=8}}'
Example #7
0
def test_wired_transceiver_raises_error_if_requested_tx_during_another_tx():
    sim, peer, queue = Mock(), Mock(), Mock()
    iface = WiredTransceiver(sim, bitrate=100)
    queue_conn = iface.connections.set('queue', queue, rname='iface')
    iface.connections.set('peer', peer, rname='peer')

    pkt_1 = NetworkPacket(data=AppData(size=10))
    pkt_2 = NetworkPacket(data=AppData(size=20))

    sim.stime = 0
    iface.start()
    iface.handle_message(pkt_1, sender=queue, connection=queue_conn)

    with pytest.raises(RuntimeError):
        iface.handle_message(pkt_2, sender=queue, connection=queue_conn)
Example #8
0
def test_pop_extracts_packets_in_correct_order():
    sim = Mock()
    sim.stime = 0
    data_size = [123, 412]
    packets = [NetworkPacket(data=AppData(0, sz, 0, 0)) for sz in data_size]

    queue = Queue(sim, capacity=2)
    queue.push(packets[0])
    queue.push(packets[1])

    assert queue.pop() == packets[0]
    assert not queue.empty()
    assert not queue.full()
    assert len(queue) == 1
    assert queue.size() == 1
    assert queue.bitsize() == data_size[1]
    assert tuple(qp.packet for qp in queue.as_tuple()) == (packets[1], )

    assert queue.pop() == packets[1]
    assert queue.empty()
    assert not queue.full()
    assert len(queue) == 0
    assert queue.size() == 0
    assert queue.bitsize() == 0
    assert queue.as_tuple() == ()
Example #9
0
def test_finite_queue_without_service_writes_statistics():
    sim = Mock()
    size = [123, 412, 230, 312]
    t0, t1, t2, t3, t4, t5 = 2, 7, 8, 10, 14, 19
    packets = [NetworkPacket(data=AppData(0, sz, 0, 0)) for sz in size]

    sim.stime = t0
    q = Queue(sim, capacity=2)

    # Run a sequence of operations:
    sim.stime = t1
    q.push(packets[0])  # stored after: packet[0]
    sim.stime = t2
    q.push(packets[1])  # stored after: packet[0], packet[1]
    sim.stime = t3
    q.push(packets[2])  # dropped due to overflow, stored: packet[0], packet[1]
    sim.stime = t4
    q.pop()  # stored after: packet[1]
    sim.stime = t5
    q.push(packets[3])  # stored after: packet[1], packet[3]

    assert tuple(qp.packet for qp in q.as_tuple()) == (packets[1], packets[3])
    assert q.size_trace.as_tuple() == ((t0, 0), (t1, 1), (t2, 2), (t4, 1), (t5,
                                                                            2))
    assert q.bitsize_trace.as_tuple() == (
        (t0, 0),
        (t1, size[0]),
        (t2, size[0] + size[1]),
        (t4, size[1]),
        (t5, size[1] + size[3]),
    )
    assert q.num_dropped == 1
Example #10
0
def test_wired_transceiver_sends_data_up_when_rx_completed():
    sim, sender, switch = Mock(), Mock(), Mock()
    sim.stime = 0
    iface = WiredTransceiver(sim)
    sim.schedule.reset_mock()  # clear sim.schedule(0, iface.start) call

    pkt = NetworkPacket(data=AppData(size=100))
    frame = WireFrame(pkt, duration=0.5, header_size=20, preamble=0.01)

    switch_rev_conn = Mock()
    switch.connections.set = Mock(return_value=switch_rev_conn)
    iface.connections.set('up', switch, rname='iface')
    sender_conn = iface.connections.set('peer', sender, rname='peer')

    assert iface.rx_ready and not iface.rx_busy

    iface.handle_message(frame, sender=sender, connection=sender_conn)
    assert not iface.rx_ready and iface.rx_busy
    sim.schedule.assert_called_once_with(
        frame.duration,
        iface.handle_rx_end,
        args=(frame, ),
    )
    sim.schedule.reset_mock()

    sim.stime += frame.duration
    iface.handle_rx_end(frame)
    sim.schedule.assert_called_once_with(0,
                                         switch.handle_message,
                                         args=(pkt, ),
                                         kwargs={
                                             'sender': iface,
                                             'connection': switch_rev_conn,
                                         })
    assert iface.rx_ready and not iface.rx_busy
Example #11
0
def test_saturated_queue_not_requests_source_when_not_empty_after_get_next():
    sim, source, switch, service = Mock(), Mock(), Mock(), Mock()
    sim.stime = 0

    service_rev_conn = Mock()
    service.connections.set = Mock(return_value=service_rev_conn)

    queue = SaturatedQueue(sim=sim, source=source)
    queue.connections.set('output', service, rname='queue')
    queue.connections.set('input', switch, reverse=False)

    pkt = NetworkPacket(data=AppData(size=100))
    queue.push(pkt)

    assert queue.size() == 1
    queue.get_next(service)

    # Validate that packet was passed to the service, but source.get_next()
    # not called:
    sim.schedule.assert_called_once_with(0,
                                         service.handle_message,
                                         args=(pkt, ),
                                         kwargs={
                                             'connection': service_rev_conn,
                                             'sender': queue,
                                         })
    source.get_next.assert_not_called()

    # However, after the queue became empty, it will call source:
    queue.get_next(service)
    source.get_next.assert_called_once()
Example #12
0
def test_saturated_queue_requests_source_packet_when_empty_after_get_next():
    sim, source, switch, service = Mock(), Mock(), Mock(), Mock()
    sim.stime = 0

    service_rev_conn = Mock()
    service.connections.set = Mock(return_value=service_rev_conn)

    queue = SaturatedQueue(sim=sim, source=source)
    queue.connections.set('output', service, rname='queue')
    queue.connections.set('input', switch, reverse=False)

    # Requesting the next packet from the queue:
    queue.get_next(service)

    source.get_next.assert_called_once()

    # Assume that packet was generated by source, went through all layers
    # and arrived from the switch. Make sure that this packet will be
    # delivered to the service:
    pkt = NetworkPacket(data=AppData(size=100))
    queue.handle_message(pkt)
    sim.schedule.assert_called_once_with(0,
                                         service.handle_message,
                                         args=(pkt, ),
                                         kwargs={
                                             'connection': service_rev_conn,
                                             'sender': queue,
                                         })
Example #13
0
def test_queue_with_service_passes_new_packet_directly_after_get_next_call():
    sim, service = Mock(), Mock()
    sim.stime = 0

    service_rev_conn = Mock()
    service.connections.set = Mock(return_value=service_rev_conn)

    queue = Queue(sim=sim)
    queue.connections.set('service', service, rname='queue')
    queue.get_next(service=service)

    packet = NetworkPacket(data=AppData(size=100))
    sim.stime = 13
    queue.push(packet)

    # Check that the message was delivered to the service:
    sim.schedule.assert_called_once_with(0,
                                         service.handle_message,
                                         args=(packet, ),
                                         kwargs={
                                             'connection': service_rev_conn,
                                             'sender': queue,
                                         })

    # Check that queue is still empty:
    assert queue.as_tuple() == ()

    # Also make sure that size updates were not written:
    assert queue.size_trace.as_tuple() == ((0, 0), )
    assert queue.bitsize_trace.as_tuple() == ((0, 0), )
    assert queue.num_dropped == 0
Example #14
0
def test_wire_frame_init_and_properties():
    pkt_1 = NetworkPacket(data=AppData(100))
    pkt_2 = NetworkPacket(data=AppData(200))

    frame_1 = WireFrame(pkt_1, header_size=10, preamble=0.2, duration=1.5)
    assert frame_1.packet == pkt_1
    assert frame_1.duration == 1.5
    assert frame_1.header_size == 10
    assert frame_1.preamble == 0.2
    assert frame_1.size == 10 + pkt_1.size

    frame_2 = WireFrame(packet=pkt_2)
    assert frame_2.packet == pkt_2
    assert frame_2.duration == 0
    assert frame_2.header_size == 0
    assert frame_2.preamble == 0
    assert frame_2.size == 0
def test_network_switch_forwards_packets_received_from_network_interfaces():
    """Validate packet with destination matching one interface is routed up.

    We send three packets: one from 'eth', one from 'wifi' and one from 'user'.
    Make sure that in any case the packet is routed to user.
    """
    sim, ns, wifi, eth = Mock(), Mock(), Mock(), Mock()
    switch = NetworkSwitch(sim)

    eth.address = 1
    eth_rev_conn = Mock()
    eth.connections.set = Mock(return_value=eth_rev_conn)

    wifi.address = 20
    wifi_rev_conn = Mock()
    wifi.connections.set = Mock(return_value=wifi_rev_conn)

    switch.connections.set('user', ns, reverse=False)
    switch.connections.set('eth', eth, rname='network')
    wifi_conn = switch.connections.set('wifi', wifi, rname='network')

    switch.table.add(10, connection='eth', next_hop=2)
    switch.table.add(30, connection='wifi', next_hop=23)

    pkt_1 = NetworkPacket(destination_address=10, originator_address=5, osn=8)
    pkt_2 = NetworkPacket(destination_address=30, originator_address=17, osn=4)

    switch.handle_message(pkt_1, connection=wifi, sender=wifi_conn)
    sim.schedule.assert_called_once_with(0,
                                         eth.handle_message,
                                         args=(pkt_1, ),
                                         kwargs={
                                             'connection': eth_rev_conn,
                                             'sender': switch,
                                         })
    sim.schedule.reset_mock()

    switch.handle_message(pkt_2, connection=wifi, sender=wifi_conn)
    sim.schedule.assert_called_once_with(0,
                                         wifi.handle_message,
                                         args=(pkt_2, ),
                                         kwargs={
                                             'connection': wifi_rev_conn,
                                             'sender': switch,
                                         })
Example #16
0
def test_queue_accepts_packets_on_handle_message_call():
    sim, producer = Mock(), Mock()
    sim.stime = 0

    queue = Queue(sim=sim)
    conn = queue.connections.set('input', producer, reverse=False)

    pkt = NetworkPacket(data=AppData(size=123))

    queue.handle_message(pkt, sender=producer, connection=conn)
    assert tuple(qp.packet for qp in queue.as_tuple()) == (pkt, )
Example #17
0
def test_queue_with_service_passes_single_stored_packet_after_get_next_call():
    t0, t1, t2, t3, t4 = 0, 13, 19, 22, 29
    size = [100, 200, 300]
    sim, service = Mock(), Mock()
    sim.stime = t0

    service_rev_conn = Mock()
    service.connections.set = Mock(return_value=service_rev_conn)

    queue = Queue(sim=sim)
    queue.connections.set('service', service, rname='queue')

    packets = [NetworkPacket(data=AppData(size=sz)) for sz in size]
    sim.stime = t1
    queue.push(packets[0])
    sim.stime = t2
    queue.push(packets[1])

    # Check that queue is updated, since no `get_next()` call was performed:
    assert tuple(qp.packet for qp in queue.as_tuple()) == tuple(packets[0:2])
    sim.schedule.assert_not_called()

    # Check that after `get_next()` request the message is passed:
    sim.stime = t3
    queue.get_next(service=service)
    assert tuple(qp.packet for qp in queue.as_tuple()) == (packets[1], )
    sim.schedule.assert_called_once_with(0,
                                         service.handle_message,
                                         args=(packets[0], ),
                                         kwargs={
                                             'connection': service_rev_conn,
                                             'sender': queue,
                                         })

    sim.stime = t4
    queue.push(packets[2])
    assert tuple(qp.packet for qp in queue.as_tuple()) == tuple(packets[1:3])

    # Also make sure that size updates were written:
    assert queue.size_trace.as_tuple() == (
        (t0, 0),
        (t1, 1),
        (t2, 2),
        (t3, 1),
        (t4, 2),
    )
    assert queue.bitsize_trace.as_tuple() == (
        (t0, 0),
        (t1, size[0]),
        (t2, size[0] + size[1]),
        (t3, size[1]),
        (t4, size[1] + size[2]),
    )
    assert queue.num_dropped == 0
def test_network_switch_increments_ssn_for_successive_packets_from_same_src():
    """Validate when two packets come from 'user' to same dest, SSN increments.
    """
    sim, ns, eth = Mock(), Mock(), Mock()
    switch = NetworkSwitch(sim)

    eth.address = 1
    eth_conn = Mock()
    eth.connections.set = Mock(return_value=eth_conn)

    user_conn = switch.connections.set('user', ns, reverse=False)
    switch.connections.set('eth', eth, rname='network')

    switch.table.add(5, connection='eth', next_hop=2)
    switch.table.add(10, connection='eth', next_hop=3)

    pkt_1 = NetworkPacket(destination_address=5)
    pkt_2 = NetworkPacket(destination_address=10)

    switch.handle_message(pkt_1, connection=user_conn, sender=ns)
    switch.handle_message(pkt_2, connection=user_conn, sender=ns)

    assert pkt_2.osn > pkt_1.osn
def test_network_packet_creation():
    data = Mock()
    packet = NetworkPacket(destination_address=10,
                           originator_address=2,
                           sender_address=5,
                           receiver_address=6,
                           osn=32,
                           data=data)
    assert packet.destination_address == 10
    assert packet.originator_address == 2
    assert packet.sender_address == 5
    assert packet.receiver_address == 6
    assert packet.osn == 32
    assert packet.data == data
Example #20
0
def test_wired_transceiver_ignores_frames_not_from_peer():
    sim, sender, switch = Mock(), Mock(), Mock()
    sim.stime = 0
    iface = WiredTransceiver(sim)
    sim.schedule.reset_mock()  # clear sim.schedule(0, iface.start) call

    pkt = NetworkPacket(data=AppData(size=100))
    frame = WireFrame(pkt, duration=0.5, header_size=20, preamble=0.01)

    iface.connections.set('up', switch, reverse=False)
    sender_conn = iface.connections.set('wrong_name', sender, reverse=False)

    iface.handle_message(frame, sender=sender, connection=sender_conn)
    sim.schedule.assert_not_called()
    assert iface.rx_ready
Example #21
0
def test_push_to_empty_queue_without_service_correctly_updates_content():
    sim = Mock()
    sim.stime = 0

    queue = Queue(sim, capacity=2)
    data_size = 123
    packet = NetworkPacket(data=AppData(0, data_size, 0, 0))

    queue.push(packet)
    assert not queue.empty()
    assert not queue.full()
    assert len(queue) == 1
    assert queue.size() == 1
    assert queue.bitsize() == data_size
    assert tuple(qp.packet for qp in queue.as_tuple()) == (packet, )
Example #22
0
def test_wired_transceiver_drops_received_message_if_not_connected_to_switch():
    sim, sender = Mock(), Mock()
    sim.stime = 0

    iface = WiredTransceiver(sim)
    sender_conn = iface.connections.set('peer', sender, rname='peer')

    pkt = NetworkPacket(data=AppData(size=100))
    frame = WireFrame(pkt, duration=0.5, header_size=20, preamble=0.01)

    iface.handle_message(frame, sender=sender, connection=sender_conn)
    sim.stime += frame.duration

    sim.schedule.reset_mock()
    iface.handle_rx_end(frame)
    sim.schedule.assert_not_called()
Example #23
0
def test_push_up_to_full_queue_without_service_correctly_updates_content():
    sim = Mock()
    sim.stime = 0
    data_size = [123, 412]
    packets = [NetworkPacket(data=AppData(0, sz, 0, 0)) for sz in data_size]

    queue = Queue(sim, capacity=2)
    queue.push(packets[0])
    queue.push(packets[1])

    assert not queue.empty()
    assert queue.full()
    assert len(queue) == 2
    assert queue.size() == 2
    assert queue.bitsize() == sum(data_size)
    assert tuple(qp.packet for qp in queue.as_tuple()) == tuple(packets)
Example #24
0
def test_wired_interface_forwards_packets_after_rx_end_to_user():
    sim, queue, transceiver, user = Mock(), Mock(), Mock(), Mock()
    iface = WiredInterface(sim, 13, queue, transceiver)

    user_conn = iface.connections.set('user', user, rname='iface')

    int_receiver_conn = iface.connections['_receiver']
    pkt = NetworkPacket(data=AppData(size=100))

    iface.handle_message(pkt, connection=int_receiver_conn, sender=transceiver)

    sim.schedule.assert_called_once_with(0,
                                         user.handle_message,
                                         args=(pkt, ),
                                         kwargs={
                                             'connection': user_conn.reverse,
                                             'sender': iface,
                                         })
Example #25
0
def test_wired_interface_forwards_frames_from_wire_to_transceiver():
    sim, queue, transceiver, peer = Mock(), Mock(), Mock(), Mock()
    iface = WiredInterface(sim, 13, queue, transceiver)

    peer_conn = iface.connections.set('wire', peer, rname='wire')
    frame = WireFrame(NetworkPacket(data=AppData(size=100)))
    iface.handle_message(frame, connection=peer_conn, sender=peer)

    int_peer_conn = iface.connections['_peer']

    sim.schedule.assert_called_once_with(0,
                                         transceiver.handle_message,
                                         args=(frame, ),
                                         kwargs={
                                             'connection':
                                             int_peer_conn.reverse,
                                             'sender': iface
                                         })
def test_network_switch_ignores_packets_to_unknown_destinations():
    """Validate `NetworkSwitch` ignores messages without source not from 'user'.
    """
    sim, ns, eth = Mock(), Mock(), Mock()
    switch = NetworkSwitch(sim)

    eth.address = 1
    eth_conn = Mock()
    eth.connections.set = Mock(return_value=eth_conn)

    user_conn = switch.connections.set('invalid', ns, reverse=False)
    switch.connections.set('eth', eth, rname='network')

    switch.table.add(10, connection='eth', next_hop=2)

    pkt = NetworkPacket(destination_address=13)

    switch.handle_message(pkt, connection=user_conn, sender=ns)
    sim.schedule.assert_not_called()
Example #27
0
def test_infinite_queue_stores_many_enough_packets():
    n = 50
    packets = [
        NetworkPacket(data=AppData(0, uniform(0, 1000), 0, 0))
        for _ in range(n)
    ]
    times = list(cumsum(uniform(0, 20, n)))

    sim = Mock()
    sim.stime = 0

    queue = Queue(sim)

    for pkt, t in zip(packets, times):
        sim.stime = t
        queue.push(pkt)

    assert queue.size() == n
    assert len(queue.size_trace) == n + 1
    assert queue.num_dropped == 0
Example #28
0
def test_wired_transceiver_records_tx_statistics(bitrate, data_sizes,
                                                 header_size, preamble,
                                                 intervals, ifs):
    sim, receiver, queue = Mock(), Mock(), Mock()
    sim.stime = 0

    iface = WiredTransceiver(sim, bitrate, header_size, preamble, ifs)
    iface.connections.set('peer', receiver, rname='peer')
    queue_conn = iface.connections.set('queue', queue, reverse=False)

    packets = [NetworkPacket(data=AppData(size=sz)) for sz in data_sizes]
    frame_sizes = [sz + header_size for sz in data_sizes]
    durations = [(sz + header_size) / bitrate + preamble for sz in data_sizes]
    t, timestamps = 0, []
    for interval, duration in zip(intervals, durations):
        t_arrival = t + interval
        t_departure = t_arrival + duration + ifs
        timestamps.append((t_arrival, t_departure))
        t = t_departure

    # Simulating transmit sequence
    for (t_arrival, t_departure), packet in zip(timestamps, packets):
        sim.stime = t_arrival
        iface.handle_message(packet, sender=queue, connection=queue_conn)

        sim.stime = t_departure - ifs
        iface.handle_tx_end()

        sim.stime = t_departure
        iface.handle_ifs_end()

    # Check TX statistics:
    expected_busy_trace = [(0, 0)]
    for t_arrival, t_departure in timestamps:
        expected_busy_trace.append((t_arrival, 1))
        expected_busy_trace.append((t_departure, 0))

    assert iface.num_transmitted_packets == len(packets)
    assert iface.num_transmitted_bits == sum(sz for sz in frame_sizes)
    assert iface.tx_busy_trace.as_tuple() == tuple(expected_busy_trace)
def test_network_switch_updates_addresses_when_forwarding_packet():
    """Validate sender and receiver addresses are upon forwarding.
    """
    sim, ns, wifi, eth = Mock(), Mock(), Mock(), Mock()
    switch = NetworkSwitch(sim)

    eth.address = 7
    wifi.address = 199
    wifi_rev_conn = Mock()
    wifi.connections.set = Mock(return_value=wifi_rev_conn)

    switch.connections.set('user', ns, reverse=False)
    switch.connections.set('wifi', wifi, rname='network')
    eth_conn = switch.connections.set('eth', eth, reverse=False)

    switch.table.add(230, 'wifi', 205)

    pkt = NetworkPacket(destination_address=230,
                        originator_address=5,
                        sender_address=6,
                        receiver_address=7,
                        osn=8)

    switch.handle_message(pkt, connection=eth_conn, sender=eth)
    sim.schedule.assert_called_once_with(0,
                                         wifi.handle_message,
                                         args=(pkt, ),
                                         kwargs={
                                             'connection': wifi_rev_conn,
                                             'sender': switch,
                                         })

    # These fields are expected to be updated
    assert pkt.sender_address == 199
    assert pkt.receiver_address == 205

    # These fields should be kept:
    assert pkt.osn == 8
    assert pkt.originator_address == 5
    assert pkt.destination_address == 230
Example #30
0
def test_wired_transceiver_records_rx_statistics(bitrate, data_sizes,
                                                 header_size, preamble,
                                                 intervals):
    sim, sender = Mock(), Mock()
    sim.stime = 0

    iface = WiredTransceiver(sim, bitrate, header_size, preamble)
    sender_conn = iface.connections.set('peer', sender, rname='peer')

    packets = [NetworkPacket(data=AppData(size=sz)) for sz in data_sizes]
    durations = [(sz + header_size) / bitrate + preamble for sz in data_sizes]
    frames = [
        WireFrame(pkt, dt, header_size, preamble)
        for pkt, dt in zip(packets, durations)
    ]
    t, timestamps = 0, []
    for interval, duration in zip(intervals, durations):
        t_arrival = t + interval
        t_departure = t_arrival + duration
        t = t_departure
        timestamps.append((t_arrival, t_departure))

    # Simulating receive sequence
    for (t_arrival, t_departure), frame in zip(timestamps, frames):
        sim.stime = t_arrival
        iface.handle_message(frame, sender=sender, connection=sender_conn)

        sim.stime = t_departure
        iface.handle_rx_end(frame)

    # Check RX statistics:
    expected_busy_trace = [(0, 0)]
    for t_arrival, t_departure in timestamps:
        expected_busy_trace.append((t_arrival, 1))
        expected_busy_trace.append((t_departure, 0))

    assert iface.num_received_frames == len(frames)
    assert iface.num_received_bits == sum(frame.size for frame in frames)
    assert iface.rx_busy_trace.as_tuple() == tuple(expected_busy_trace)