Пример #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_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)
Пример #3
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,
                                         })
Пример #4
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
Пример #5
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()
Пример #6
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
Пример #7
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
Пример #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() == ()
Пример #9
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
Пример #10
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
Пример #11
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, )
Пример #12
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, )
Пример #13
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
Пример #14
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()
Пример #15
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)
Пример #16
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,
                                         })
Пример #17
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
                                         })
Пример #18
0
def test_app_data_is_immutable():
    app_data = AppData(dest_addr=5, size=20, source_id=13, created_at=123)
    assert app_data.destination_address == 5
    assert app_data.size == 20
    assert app_data.source_id == 13
    assert app_data.created_at == 123
    with pytest.raises(AttributeError):
        app_data.destination_address = 11
    with pytest.raises(AttributeError):
        app_data.size = 21
    with pytest.raises(AttributeError):
        app_data.source_id = 26
    with pytest.raises(AttributeError):
        app_data.created_at = 234
Пример #19
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
Пример #20
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)
Пример #21
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)
Пример #22
0
def test_push_to_full_queue_without_service_drops_last_packet():
    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=1)
    queue.push(packets[0])

    # Check that num_dropped counter is 0 before overflow:
    assert queue.num_dropped == 0

    # Pushing a packet that will overflow the queue:
    queue.push(packets[1])
    assert queue.num_dropped == 1

    # Now check that only first packet is in the queue:
    assert not queue.empty()
    assert queue.full()
    assert len(queue) == 1
    assert queue.size() == 1
    assert queue.bitsize() == data_size[0]
    assert tuple(qp.packet for qp in queue.as_tuple()) == (packets[0], )
Пример #23
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()
Пример #24
0
def test_wired_interface_integration_serves_user_packet():
    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.03, 0.05)
    iface = WiredInterface(sim, 1, queue=queue, transceiver=transceiver)

    user_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')
    wire_conn.delay = 0.01

    user_pkt = NetworkPacket(data=AppData(size=100))

    transceiver_queue_conn = transceiver.connections['queue']
    queue_iface_conn = iface.connections['_queue'].reverse
    iface_transceiver_conn = iface.connections['_peer']

    # First of all, we need to force transceiver start, since no actual
    # simulation execution is performed:
    transceiver.start()

    # 1) Simulate like a new packet arrived from user, make sure that queue
    #    delivery was scheduled:
    iface.handle_message(user_pkt, connection=user_conn, sender=user)
    sim.schedule.assert_called_with(0,
                                    queue.handle_message,
                                    args=(user_pkt, ),
                                    kwargs={
                                        'connection': queue_iface_conn,
                                        'sender': iface,
                                    })
    sim.schedule.reset_mock()

    # 2) Force execution of queue packet delivery, make sure the packet arrives
    #    at the transceiver:
    queue.handle_message(user_pkt, queue_iface_conn, iface)
    sim.schedule.assert_called_with(0,
                                    transceiver.handle_message,
                                    args=(user_pkt, ),
                                    kwargs={
                                        'connection': transceiver_queue_conn,
                                        'sender': queue,
                                    })
    sim.schedule.reset_mock()

    # 3) Force packet handling at the transceiver and make sure it schedules
    #    packet delivery at its peer (iface itself):
    transceiver.handle_message(user_pkt,
                               connection=transceiver_queue_conn,
                               sender=queue)
    frame = transceiver.tx_frame
    sim.schedule.assert_any_call(0,
                                 iface.handle_message,
                                 args=(frame, ),
                                 kwargs={
                                     'connection': iface_transceiver_conn,
                                     'sender': transceiver,
                                 })
    assert frame.packet == user_pkt
    sim.schedule.reset_mock()

    # 4) Finally, force frame arrival at the interface and make sure it
    #    schedules frame reception at its peer after the channel delay:
    iface.handle_message(frame, iface_transceiver_conn, transceiver)
    sim.schedule.assert_called_with(wire_conn.delay,
                                    peer.handle_message,
                                    args=(frame, ),
                                    kwargs={
                                        'connection': wire_rev_conn,
                                        'sender': iface,
                                    })
Пример #25
0
def test_app_data_provides_str():
    app_data = AppData(dest_addr=1, size=250, source_id=2, created_at=10)
    assert str(app_data) == 'AppData{sid=2,dst=1,size=250,ct=10}'
Пример #26
0
def test_queue_with_several_services_finds_right_connections():
    sim, blue, red, green = Mock(), Mock(), Mock(), Mock()
    sim.stime = 0

    blue_rev_conn = Mock()
    blue.connections.set = Mock(return_value=blue_rev_conn)
    red_rev_conn = Mock()
    red.connections.set = Mock(return_value=red_rev_conn)
    green_rev_conn = Mock()
    green.connections.set = Mock(return_value=green_rev_conn)

    queue = Queue(sim=sim)
    queue.connections.set('blue', blue, rname='queue')
    queue.connections.set('red', red, rname='queue')
    queue.connections.set('green', green, rname='queue')

    # First, we fill the queue:
    pkt_1 = NetworkPacket(data=AppData(size=100))
    pkt_2 = NetworkPacket(data=AppData(size=200))
    pkt_3 = NetworkPacket(data=AppData(size=300))

    # Now, while queue is empty, two services request data:
    sim.stime = 0.5
    queue.get_next(green)
    sim.stime = 1.0
    queue.get_next(blue)

    # At some moment, a packet arrives. It should be passed to the module that
    # first requested the packet:
    sim.stime = 2
    queue.push(pkt_1)
    sim.schedule.assert_called_once_with(0,
                                         green.handle_message,
                                         args=(pkt_1, ),
                                         kwargs={
                                             'connection': green_rev_conn,
                                             'sender': queue,
                                         })
    assert queue.as_tuple() == ()
    sim.schedule.reset_mock()

    # At the next moment, another packet arrives and is being passed to the
    # module that requested data after the first one:
    sim.stime = 5
    queue.push(pkt_2)
    sim.schedule.assert_called_once_with(0,
                                         blue.handle_message,
                                         args=(pkt_2, ),
                                         kwargs={
                                             'connection': blue_rev_conn,
                                             'sender': queue,
                                         })
    assert queue.as_tuple() == ()
    sim.schedule.reset_mock()

    # Now another packet arrives, and it should be stored since both requests
    # were fulfilled previously:
    sim.stime = 10
    queue.push(pkt_3)
    assert tuple(qp.packet for qp in queue.as_tuple()) == (pkt_3, )
    sim.schedule.assert_not_called()

    # Finally, the another module requests a packet, and it is immediately
    # delivered to it:
    sim.stime = 19
    queue.get_next(red)
    sim.schedule.assert_called_once_with(0,
                                         red.handle_message,
                                         args=(pkt_3, ),
                                         kwargs={
                                             'connection': red_rev_conn,
                                             'sender': queue,
                                         })
Пример #27
0
def test_app_data_supports_default_values():
    app_data = AppData()
    assert app_data.destination_address == 0
    assert app_data.size == 0
    assert app_data.source_id == 0
    assert app_data.created_at == 0
Пример #28
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)
Пример #29
0
def test_wired_transceiver_packet_from_queue_transmission(
        bitrate, header_size, preamble, ifs):
    sim = Mock()
    iface = WiredTransceiver(
        sim,
        bitrate=bitrate,
        header_size=header_size,
        preamble=preamble,
        ifs=ifs,
    )

    # Now we connect the transceiver with a queue and start it. Make sure
    # that the queue is connected via 'queue' link, and after start `get_next()`
    # is called.
    queue = Mock()
    queue_rev_conn = Mock()
    queue.connections.set = Mock(return_value=queue_rev_conn)

    queue_conn = iface.connections.set('queue', queue, rname='iface')
    queue.get_next.assert_not_called()

    iface.start()  # start of the transceiver causes `get_next()` call

    queue.get_next.assert_called_once_with(iface)
    queue.get_next.reset_mock()
    assert iface.started and iface.tx_ready and not iface.tx_busy

    #
    # After being started, transceiver expects a `NetworkPacket` in its
    # handle_message() call. We connect another mock to the transceiver via
    # 'peer' connection and make sure that after the call that `send()` was
    # called on that peer connection.
    #
    # Since `WireFrame` objects are expected to be used in connections
    # between peers, we patch them.
    #
    peer = Mock()
    peer_rev_conn = Mock()
    peer.connections.set = Mock(return_value=peer_rev_conn)

    iface.connections.set('peer', peer, rname='peer')
    packet = NetworkPacket(data=AppData(size=500))
    duration = (packet.size + header_size) / bitrate + preamble

    with patch(WIRE_FRAME_CLASS) as WireFrameMock:
        frame_kwargs = {
            'packet': packet,
            'header_size': header_size,
            'duration': duration,
            'preamble': preamble,
        }
        frame_instance = Mock()
        frame_instance.duration = duration
        frame_instance.size = header_size + packet.size
        WireFrameMock.return_value = frame_instance

        sim.stime = 0
        iface.handle_message(packet, sender=queue, connection=queue_conn)
        sim.schedule.assert_any_call(0,
                                     peer.handle_message,
                                     args=(frame_instance, ),
                                     kwargs={
                                         'connection': peer_rev_conn,
                                         'sender': iface,
                                     })
        WireFrameMock.assert_called_once_with(**frame_kwargs)

        # Also check that wired transceiver scheduled a timeout:
        sim.schedule.assert_any_call(duration, iface.handle_tx_end)

        # .. and that now transceiver is busy:
        assert iface.started and not iface.tx_ready and iface.tx_busy
        sim.schedule.reset_mock()

    # Now we imitate `handle_tx_end()` call, make sure that after that the
    # transceiver is not yet ready, but schedules `handle_ifs_end()`:
    sim.stime = duration
    iface.handle_tx_end()
    sim.schedule.assert_called_once_with(ifs, iface.handle_ifs_end)
    assert iface.started and not iface.tx_ready and iface.tx_busy

    # After the IFS waiting finished, transceiver is expected to call
    # `queue.get_next(iface)` and be ready for new packets:
    sim.stime += ifs
    iface.handle_ifs_end()
    queue.get_next.assert_called_once_with(iface)
    assert iface.started and iface.tx_ready and not iface.tx_busy