Пример #1
0
def test_network_switch_provides_table_read_only_property():
    sim = Mock()
    switch = NetworkSwitch(sim)
    assert isinstance(switch.table, SwitchTable)
    with pytest.raises(AttributeError):
        # noinspection PyPropertyAccess
        switch.table = SwitchTable()
Пример #2
0
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()
Пример #3
0
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()
Пример #4
0
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
Пример #5
0
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
Пример #6
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
Пример #7
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,
                                         })
Пример #8
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()