Exemplo n.º 1
0
        def __init__(self, arrival_mean, service_mean):
            # Parameters:
            self.arrival_mean = arrival_mean
            self.service_mean = service_mean

            # System state:
            self.queue_size = 0
            self.server_busy = False

            # Statistics:
            self.system_size_trace = Trace()
            self.server_busy_trace = Trace()
            self.service_intervals = Statistic()
            self.arrivals = Intervals()
            self.departures = Intervals()
Exemplo n.º 2
0
def test_intervals_creation_with_valid_data(timestamps):
    ints = Intervals(timestamps)
    _timestamps = asarray([0] + list(timestamps))
    assert not ints.empty
    assert len(ints) == len(timestamps)
    assert ints.as_tuple() == tuple(_timestamps[1:] - _timestamps[:-1])
    assert ints.last == timestamps[-1]
Exemplo n.º 3
0
def test_random_source_provides_statistics():
    """Validate that `RandomSource` provides statistics.
    """
    intervals = (10, 12, 15, 17)
    data_size = (123, 453, 245, 321)

    class TestModel(Model):
        def __init__(self, sim):
            super().__init__(sim)
            self.source = RandomSource(
                sim,
                source_id=34,
                dest_addr=13,
                data_size=Mock(side_effect=data_size),
                interval=Mock(side_effect=(intervals + (1000, ))),
            )
            self.network = DummyModel(sim, 'Network')
            self.source.connections['network'] = self.network

    ret = simulate(TestModel, stime_limit=sum(intervals))

    assert ret.data.source.arrival_intervals.as_tuple() == intervals
    assert ret.data.source.data_size_stat.as_tuple() == data_size

    # Also check that we can not replace statistics:
    with pytest.raises(AttributeError):
        from pydesim import Intervals
        ret.data.source.arrival_intervals = Intervals()
    with pytest.raises(AttributeError):
        from pydesim import Statistic
        ret.data.source.data_size_stat = Statistic()

    # Check that source records the number of packets being sent:
    assert ret.data.source.num_packets_sent == 4
Exemplo n.º 4
0
 def __init__(self, sim):
     super().__init__(sim)
     self.__source_delays_data = {}
     self.__source_delays = ReadOnlyDict(self.__source_delays_data)
     self.__arrival_intervals = Intervals()
     self.__data_size_stat = Statistic()
     self.__num_packets_received = 0
Exemplo n.º 5
0
 def __init__(self, sim, arrival_mean):
     super().__init__(sim)
     self.__arrival_mean = arrival_mean
     # Statistics:
     self.intervals = Intervals()
     # Initialize:
     self._schedule_next_arrival()
Exemplo n.º 6
0
def test_record_valid_data():
    ints = Intervals()
    assert ints.as_tuple() == ()

    ints.record(2)
    assert_almost_equal(ints.as_tuple(), (2, ))

    ints.record(3.4)
    assert_almost_equal(ints.as_tuple(), (2, 1.4))
Exemplo n.º 7
0
    def __init__(self, sim, arrival, index):
        super().__init__(sim)
        self.arrival = arrival
        self.index = index

        # Statistics:
        self.intervals = Intervals()
        self.num_generated = 0
        self.delays = Statistic()

        # Initialize:
        self._schedule_next_arrival()
Exemplo n.º 8
0
    def __init__(self, sim, service_time, index=0):
        super().__init__(sim)
        self.service_time = service_time
        self.packet = None
        self.index = index

        # Statistics:
        self.service_intervals = Statistic()
        self.busy_trace = Trace()
        self.busy_trace.record(self.sim.stime, 0)
        self.departure_intervals = Intervals()
        self.departure_intervals.record(sim.stime)
        self.num_served = 0
Exemplo n.º 9
0
 def __init__(self, sim, capacity, index=0):
     super().__init__(sim)
     self.__capacity = capacity
     self.packets = deque()
     self.index = index
     # Statistics:
     self.size_trace = Trace()
     self.size_trace.record(self.sim.stime, 0)
     self.num_dropped = 0
     self.arrival_intervals = Intervals()
     self.arrival_intervals.record(sim.stime)
     self.num_arrived = 0
     self.wait_intervals = Statistic()
Exemplo n.º 10
0
def test_controlled_source_provides_statistics():
    """Validate that `ControlledSource` provides statistics.
    """
    intervals = (10, 12, 15, 17)
    data_size = (123, 453, 245, 321)

    class SourceController(Model):
        def __init__(self, sim, src):
            super().__init__(sim)
            self.iterator = iter(intervals)
            self.src = src
            self.sim.schedule(next(self.iterator), self.handle_timeout)

        def handle_timeout(self):
            self.src.get_next()
            try:
                interval = next(self.iterator)
            except StopIteration:
                pass
            else:
                self.sim.schedule(interval, self.handle_timeout)

    class TestModel(Model):
        def __init__(self, sim):
            super().__init__(sim)
            self.source = ControlledSource(
                sim,
                source_id=34,
                dest_addr=13,
                data_size=Mock(side_effect=data_size),
            )
            self.network = DummyModel(sim, 'Network')
            self.source.connections['network'] = self.network
            self.controller = SourceController(sim, self.source)

    ret = simulate(TestModel, stime_limit=sum(intervals))

    assert ret.data.source.data_size_stat.as_tuple() == data_size
    assert ret.data.source.arrival_intervals.as_tuple() == intervals

    # Also check that we can not replace statistics:
    with pytest.raises(AttributeError):
        from pydesim import Intervals
        ret.data.source.arrival_intervals = Intervals()
    with pytest.raises(AttributeError):
        from pydesim import Statistic
        ret.data.source.data_size_stat = Statistic()

    # Check that source records the number of packets being sent:
    assert ret.data.source.num_packets_sent == 4
Exemplo n.º 11
0
    def __init__(self, sim, data_size, source_id, dest_addr):
        """Constructor.

        :param sim: `pydesim.Simulator` object;
        :param data_size: callable without arguments, iterable or constant;
            represents application data size distribution;
        :param source_id: this source ID (more like IP address, not MAC)
        :param dest_addr: destination MAC address.
        """
        super().__init__(sim)
        self.__data_size = data_size
        self.__source_id = source_id
        self.__dest_addr = dest_addr

        # Attempt to build iterators for data size and intervals:
        try:
            self.__data_size_iter = iter(self.__data_size)
        except TypeError:
            self.__data_size_iter = None

        # Statistics:
        self.__arrival_intervals = Intervals()
        self.__data_size_stat = Statistic()
        self.__num_packets_sent = 0
Exemplo n.º 12
0
def test_as_list(timestamps):
    ints = Intervals(timestamps)
    _timestamps = asarray([0] + list(timestamps))
    assert ints.as_list() == list(_timestamps[1:] - _timestamps[:-1])
Exemplo n.º 13
0
def test_statistic(data):
    ints = Intervals(data)
    stats = ints.statistic()
    assert_almost_equal(stats.as_tuple(), ints.as_tuple())
Exemplo n.º 14
0
def test_record_in_past_raises_error():
    ints = Intervals([10])
    with pytest.raises(ValueError) as excinfo:
        ints.record(9.9)
    assert 'prohibited timestamps from past' in str(excinfo.value).lower()
Exemplo n.º 15
0
def test_record_illegal_types_raises_error(value):
    ints = Intervals()
    with pytest.raises(TypeError) as excinfo:
        ints.record(value)
    assert 'only numeric values expected' in str(excinfo.value).lower()
Exemplo n.º 16
0
def test_data_of_illegal_types_causes_type_error(timestamps):
    with pytest.raises(TypeError) as excinfo:
        Intervals(timestamps)
    assert 'only numeric values expected' in str(excinfo.value).lower()
Exemplo n.º 17
0
 def __init__(self, sim):
     super().__init__(sim)
     # Statistics:
     self.arrival_intervals = Intervals()
     self.arrival_intervals.record(self.sim.stime)
Exemplo n.º 18
0
def test_intervals_accept_only_timestamps_in_future():
    with pytest.raises(ValueError) as excinfo:
        Intervals([1, 2, 1.9, 3])
    assert 'timestamps must be ascending' in str(excinfo.value).lower()
Exemplo n.º 19
0
def test_intervals_copy_list_content_instead_of_pointer():
    data = [1, 2]
    ints = Intervals(data)
    ints.record(3)
    assert ints.as_tuple() == (1, 1, 1)
    assert data == [1, 2]
Exemplo n.º 20
0
def test_sink_module_records_statistics():
    """Validate that `Sink` module records various statistics.

    In this test we check that `Sink` module records end-to-end delays per
    SourceID, inter-arrival intervals and packet sizes (last two statistics
    are recorded without splitting by SourceID). It also records the number of
    received packets.

    To do this, we define a sample simulation with dummy network layer, two
    sources and one sink. Each source generates three messages within given
    intervals and with given sizes.
    """
    delays = [(5, 2, 234), (10, 3, 135)]
    intervals = [(10, 10, 200), (20, 400, 80)]
    sizes = [(1234, 1625, 1452), (2534, 2124, 2664)]
    sids = [23, 14]

    class DummyNetwork(Model):
        def __init__(self, sim):
            super().__init__(sim)

        def handle_message(self, app_data, **kwargs):
            self.connections['sink'].send(app_data)

    class TestModel(Model):
        def __init__(self, sim):
            super().__init__(sim)
            self.sink = Sink(sim)
            for ds, inter, sid, delay in zip(sizes, intervals, sids, delays):
                network = DummyNetwork(sim)
                source = RandomSource(sim, ds, inter, sid, 5)
                source.connections['network'] = network
                network.connections['sink'] = self.sink
                network.connections['sink'].delay = Mock(side_effect=delay)

    ret = simulate(TestModel)
    sink = ret.data.sink

    assert isinstance(sink.source_delays[sids[0]], Statistic)
    assert sink.source_delays[sids[0]].as_tuple() == delays[0]
    assert sink.source_delays[sids[1]].as_tuple() == delays[1]

    # To check `Sink` stores arrival intervals and packet sizes, we estimate
    # expected arrival times (received_at) and along with it order packet
    # sizes by their arrival time:
    indices = [0, 0]
    gen_times = [cumsum(ints) for ints in intervals]
    n = len(intervals[0])
    received_at, received_sizes = [], []
    while any(i < n for i in indices):
        next_arrivals = [(gen_times[i][j] + delays[i][j]) if j < n else inf
                         for i, j in enumerate(indices)]
        i = int(argmin(next_arrivals))
        received_at.append(next_arrivals[i])
        received_sizes.append(sizes[i][indices[i]])
        indices[i] += 1

    # Since received_at stores arrival timestamps, compute arrival intervals:
    v = asarray(received_at)
    arrival_intervals = [v[0]] + list(v[1:] - v[:-1])

    # Check that recorded data match the expected:
    assert isinstance(sink.arrival_intervals, Intervals)
    assert sink.arrival_intervals.as_tuple() == tuple(arrival_intervals)
    assert isinstance(sink.data_size_stat, Statistic)
    assert sink.data_size_stat.as_tuple() == tuple(received_sizes)
    assert sink.num_packets_received == len(received_sizes)

    # Check that statistics can not be overwritten:
    with pytest.raises(AttributeError):
        sink.arrival_intervals = Intervals()
    with pytest.raises(AttributeError):
        sink.data_size_stat = Statistic()
    with pytest.raises(TypeError):
        sink.source_delays[sids[0]] = Statistic()
Exemplo n.º 21
0
def test_empty_intervals_instantiation():
    ints = Intervals()
    assert ints.empty
    assert len(ints) == 0
    assert ints.as_tuple() == ()
    assert ints.last == 0
Exemplo n.º 22
0
 def __init__(self, sim):
     super().__init__(sim)
     # Statistics:
     self.departures = Intervals()
     self.departures.record(self.sim.stime)