1 # Copyright (c) 2020 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Module defining ReceiveRateMeasurement class."""
17 class ReceiveRateMeasurement:
18 """Structure defining the result of single Rr measurement."""
21 self, duration, target_tr, transmit_count, loss_count,
22 approximated_duration=0.0, partial_transmit_count=0):
23 """Constructor, normalize primary and compute secondary quantities.
25 If approximated_duration is nonzero, it is stored.
26 If approximated_duration is zero, duration value is stored.
27 Either way, additional secondary quantities are computed
30 If there is zero transmit_count, fractions are set to zero.
32 In some cases, traffic generator does not attempt all the needed
33 transactions. In that case, nonzero partial_transmit_count
34 holds (an estimate of) count of the actually attempted transactions.
35 This is used to populate some secondary quantities.
37 TODO: Use None instead of zero?
39 :param duration: Measurement duration [s].
40 :param target_tr: Target transmit rate [pps].
41 If bidirectional traffic is measured, this is bidirectional rate.
42 :param transmit_count: Number of packets transmitted [1].
43 :param loss_count: Number of packets transmitted but not received [1].
44 :param approximated_duration: Estimate of the actual time of the trial.
45 :param partial_transmit_count: Estimate count of actually attempted
48 :type target_tr: float
49 :type transmit_count: int
51 :type approximated_duration: float
52 :type partial_transmit_count: int
54 self.duration = float(duration)
55 self.target_tr = float(target_tr)
56 self.transmit_count = int(transmit_count)
57 self.loss_count = int(loss_count)
58 self.receive_count = transmit_count - loss_count
59 self.transmit_rate = transmit_count / self.duration
60 self.loss_rate = loss_count / self.duration
61 self.receive_rate = self.receive_count / self.duration
62 self.loss_fraction = (
63 float(self.loss_count) / self.transmit_count
64 if self.transmit_count > 0 else 1.0
66 self.receive_fraction = (
67 float(self.receive_count) / self.transmit_count
68 if self.transmit_count > 0 else 0.0
70 self.approximated_duration = (
71 float(approximated_duration) if approximated_duration
74 self.approximated_receive_rate = (
75 self.receive_count / self.approximated_duration
76 if self.approximated_duration > 0.0 else 0.0
78 # If the traffic generator is unreliable and sends less packets,
79 # the absolute receive rate might be too low for next target.
80 self.partial_transmit_count = (
81 int(partial_transmit_count) if partial_transmit_count
82 else self.transmit_count
84 self.partial_receive_fraction = (
85 float(self.receive_count) / self.partial_transmit_count
86 if self.partial_transmit_count > 0 else 0.0
88 self.partial_receive_rate = (
89 self.target_tr * self.partial_receive_fraction
91 # We use relative packet ratios in order to support cases
92 # where target_tr is in transactions per second,
93 # but there are multiple packets per transaction.
94 self.relative_receive_rate = (
95 self.target_tr * self.receive_count / self.transmit_count
99 """Return string reporting input and loss fraction."""
100 return f"d={self.duration!s},Tr={self.target_tr!s}," \
101 f"Df={self.loss_fraction!s}"
104 """Return string evaluable as a constructor call."""
105 return f"ReceiveRateMeasurement(duration={self.duration!r}," \
106 f"target_tr={self.target_tr!r}," \
107 f"transmit_count={self.transmit_count!r}," \
108 f"loss_count={self.loss_count!r}," \
109 f"approximated_duration={self.approximated_duration!r}," \
110 f"partial_transmit_count={self.partial_transmit_count!r})"