示例#1
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}]'
示例#2
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
示例#3
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
示例#4
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
示例#5
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()
示例#6
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
                                         })
示例#7
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)
示例#8
0
def test_wired_interface_integration_receives_frame():
    sim, user, peer = Mock(), Mock(), Mock()
    sim.stime = 10

    from pycsmaca.simulations.modules.queues import Queue
    queue = Queue(sim)
    transceiver = WiredTransceiver(sim, 1000, 22, 0.1, 0.05)
    iface = WiredInterface(sim, 0, queue=queue, transceiver=transceiver)

    user_rev_conn = Mock()
    user.connections.set = Mock(return_value=user_rev_conn)
    iface.connections.set('user', user, rname='iface')

    wire_rev_conn = Mock()
    peer.connections.set = Mock(return_value=wire_rev_conn)
    wire_conn = iface.connections.set('wire', peer, rname='wire')

    packet = NetworkPacket(data=AppData(size=242))
    duration = (packet.size + transceiver.header_size
                ) / transceiver.bitrate + transceiver.preamble
    frame = WireFrame(packet, duration, transceiver.header_size,
                      transceiver.preamble)

    transceiver_peer_conn = iface.connections['_peer'].reverse
    _receiver_conn = iface.connections['_receiver']

    # 1) Simulate like a frame came from the peer:
    iface.handle_message(frame, connection=wire_conn, sender=peer)
    sim.schedule.assert_called_with(0,
                                    transceiver.handle_message,
                                    args=(frame, ),
                                    kwargs={
                                        'connection': transceiver_peer_conn,
                                        'sender': iface,
                                    })
    sim.schedule.reset_mock()

    # 2) Execute transceiver frame reception start, update time and
    #    execute transceiver frame reception end. Then make sure that
    #    packet was scheduled for sending up to the interface via 'up':
    transceiver.handle_message(frame, transceiver_peer_conn, iface)
    sim.schedule.assert_called_with(duration,
                                    transceiver.handle_rx_end,
                                    args=(frame, ))
    sim.schedule.reset_mock()
    sim.stime += duration
    transceiver.handle_rx_end(frame)
    sim.schedule.assert_called_with(0,
                                    iface.handle_message,
                                    args=(packet, ),
                                    kwargs={
                                        'connection': _receiver_conn,
                                        'sender': transceiver,
                                    })
    sim.schedule.reset_mock()

    # 3) Execute interface packet reception, make sure it is delivered to user:
    iface.handle_message(packet, _receiver_conn, transceiver)
    sim.schedule.assert_called_with(0,
                                    user.handle_message,
                                    args=(packet, ),
                                    kwargs={
                                        'connection': user_rev_conn,
                                        'sender': iface,
                                    })
    sim.schedule.reset_mock()
示例#9
0
def test_wired_transceiver_is_full_duplex(bitrate, header_size, preamble,
                                          size):
    sim, peer, queue, switch = Mock(), Mock(), Mock(), Mock()
    sim.stime = 0

    eth = WiredTransceiver(sim,
                           header_size=header_size,
                           bitrate=bitrate,
                           preamble=preamble,
                           ifs=0)

    peer_conn = eth.connections.set('peer', peer, reverse=False)
    queue_conn = eth.connections.set('queue', queue, reverse=False)
    eth.connections.set('up', switch, reverse=False)

    inp_pkt = NetworkPacket(data=AppData(size=size))
    out_pkt_1 = NetworkPacket(data=AppData(size=size))
    out_pkt_2 = NetworkPacket(data=AppData(size=size))
    duration = (header_size + size) / bitrate + preamble
    frame = WireFrame(inp_pkt,
                      duration=duration,
                      header_size=header_size,
                      preamble=preamble)

    # 1) Transceiver starts transmitting `out_pkt_1`:
    sim.stime = 0
    eth.start()
    eth.handle_message(out_pkt_1, queue_conn, queue)
    assert eth.tx_busy
    assert eth.rx_ready
    sim.schedule.assert_any_call(duration, eth.handle_tx_end)
    sim.schedule.assert_any_call(0, peer.handle_message, args=ANY, kwargs=ANY)
    sim.schedule.reset_mock()

    # 2) Then, after 2/3 of the packet was transmitted, a packet arrives:
    sim.stime = 2 * duration / 3
    eth.handle_message(frame, peer_conn, peer)
    assert eth.tx_busy
    assert eth.rx_busy
    sim.schedule.assert_called_with(duration,
                                    eth.handle_rx_end,
                                    args=(frame, ))
    sim.schedule.reset_mock()

    # 3) After duration, call handle_tx_end and handle_ifs_end:
    sim.stime = duration
    eth.handle_tx_end()
    eth.handle_ifs_end()
    assert eth.tx_ready
    assert eth.rx_busy
    sim.schedule.reset_mock()

    # 4) After another 1/3 duration start new TX (during RX this time):
    sim.stime = 4 / 3 * duration
    eth.handle_message(out_pkt_2, queue_conn, queue)
    assert eth.tx_busy
    assert eth.rx_busy
    sim.schedule.assert_any_call(duration, eth.handle_tx_end)
    sim.schedule.assert_any_call(0, peer.handle_message, args=ANY, kwargs=ANY)
    sim.schedule.reset_mock()

    # 5) After 5/3 duration, RX ends, but TX still goes on:
    sim.stime = 5 / 3 * duration
    eth.handle_rx_end(frame)
    assert eth.tx_busy
    assert eth.rx_ready
    sim.schedule.assert_called_with(0,
                                    switch.handle_message,
                                    args=ANY,
                                    kwargs=ANY)