b43030fe3d119dc5b94d90f7c0be12999ecfdbe8
[nfvbench.git] / nfvbench / traffic_gen / dummy.py
1 # Copyright 2016 Cisco Systems, Inc.  All rights reserved.
2 #
3 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
4 #    not use this file except in compliance with the License. You may obtain
5 #    a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #    Unless required by applicable law or agreed to in writing, software
10 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 #    License for the specific language governing permissions and limitations
13 #    under the License.
14
15 from traffic_base import AbstractTrafficGenerator
16 import traffic_utils as utils
17
18
19 class DummyTG(AbstractTrafficGenerator):
20     """Experimental dummy traffic generator.
21
22     This traffic generator will pretend to generate traffic and return fake data.
23     Useful for unit testing without actually generating any traffic.
24     """
25
26     def __init__(self, config):
27         AbstractTrafficGenerator.__init__(self, config)
28         self.port_handle = []
29         self.rates = []
30         self.l2_frame_size = 0
31         self.duration_sec = self.config.duration_sec
32         self.intf_speed = config.generator_config.intf_speed
33
34     def get_version(self):
35         return "0.1"
36
37     def init(self):
38         pass
39
40     def get_tx_pps_dropped_pps(self, tx_rate):
41         '''Get actual tx packets based on requested tx rate
42
43         :param tx_rate: requested TX rate with unit ('40%', '1Mbps', '1000pps')
44
45         :return: the actual TX pps and the dropped pps corresponding to the requested TX rate
46         '''
47         dr, tx = self.__get_dr_actual_tx(tx_rate)
48         actual_tx_bps = utils.load_to_bps(tx, self.intf_speed)
49         avg_packet_size = utils.get_average_packet_size(self.l2_frame_size)
50         tx_packets = utils.bps_to_pps(actual_tx_bps, avg_packet_size)
51
52         dropped = tx_packets * dr / 100
53         # print '===get_tx_pkts_dropped_pkts req tex=', tx_rate, 'dr=', dr,
54         # 'actual tx rate=', tx, 'actual tx pkts=', tx_packets, 'dropped=', dropped
55         return int(tx_packets), int(dropped)
56
57     def set_response_curve(self, lr_dr=0, ndr=100, max_actual_tx=100, max_11_tx=100):
58         '''Set traffic gen response characteristics
59
60         Specifies the drop rate curve and the actual TX curve
61         :param float lr_dr: The actual drop rate at TX line rate (in %, 0..100)
62         :param float ndr: The true NDR  (0 packet drop) in % (0..100) of line rate"
63         :param float max_actual_tx: highest actual TX when requested TX is 100%
64         :param float max_11_tx: highest requested TX that results in same actual TX
65         '''
66         self.target_ndr = ndr
67         if ndr < 100:
68             self.dr_slope = float(lr_dr) / (100 - ndr)
69         else:
70             self.dr_slope = 0
71         self.max_11_tx = max_11_tx
72         self.max_actual_tx = max_actual_tx
73         if max_11_tx < 100:
74             self.tx_slope = float(max_actual_tx - max_11_tx) / (100 - max_11_tx)
75         else:
76             self.tx_slope = 0
77
78     def __get_dr_actual_tx(self, requested_tx_rate):
79         '''Get drop rate at given requested tx rate
80         :param float requested_tx_rate: requested tx rate in % (0..100)
81         :return: the drop rate and actual tx rate at that requested_tx_rate in % (0..100)
82         '''
83         if requested_tx_rate <= self.max_11_tx:
84             actual_tx = requested_tx_rate
85         else:
86             actual_tx = self.max_11_tx + (requested_tx_rate - self.max_11_tx) * self.tx_slope
87         if actual_tx <= self.target_ndr:
88             dr = 0.0
89         else:
90             dr = (actual_tx - self.target_ndr) * self.dr_slope
91         return dr, actual_tx
92
93     def connect(self):
94         ports = list(self.config.generator_config.ports)
95         self.port_handle = ports
96
97     def is_arp_successful(self):
98         return True
99
100     def config_interface(self):
101         pass
102
103     def create_traffic(self, l2frame_size, rates, bidirectional, latency=True):
104         self.rates = [utils.to_rate_str(rate) for rate in rates]
105         self.l2_frame_size = l2frame_size
106
107     def clear_streamblock(self):
108         pass
109
110     def get_stats(self):
111         '''Get stats from current run.
112
113         The binary search mainly looks at 2 results to make the decision:
114             actual tx packets
115             actual rx dropped packets
116         From the Requested TX rate - we get the Actual TX rate and the RX drop rate
117         From the Run duration and actual TX rate - we get the actual total tx packets
118         From the Actual tx packets and RX drop rate - we get the RX dropped packets
119         '''
120         result = {}
121         total_tx_pps = 0
122
123         # use dummy values for all other result field as the goal is to
124         # test the ndr/pdr convergence code
125         for idx, ph in enumerate(self.port_handle):
126             requested_tx_rate = utils.get_load_from_rate(self.rates[idx])
127             tx_pps, dropped_pps = self.get_tx_pps_dropped_pps(requested_tx_rate)
128
129             # total packets sent per direction - used by binary search
130             total_pkts = tx_pps * self.duration_sec
131             dropped_pkts = dropped_pps * self.duration_sec
132             _, tx_pkt_rate = self.__get_dr_actual_tx(requested_tx_rate)
133             result[ph] = {
134                 'tx': {
135                     'total_pkts': total_pkts,
136                     'total_pkt_bytes': 100000,
137                     'pkt_rate': tx_pkt_rate,
138                     'pkt_bit_rate': 1000000
139                 },
140                 'rx': {
141                     # total packets received
142                     'total_pkts': total_pkts - dropped_pkts,
143                     'total_pkt_bytes': 100000,
144                     'pkt_rate': 100,
145                     'pkt_bit_rate': 1000000,
146                     'dropped_pkts': dropped_pkts
147                 }
148             }
149             result[ph]['rx']['max_delay_usec'] = 10.0
150             result[ph]['rx']['min_delay_usec'] = 1.0
151             result[ph]['rx']['avg_delay_usec'] = 2.0
152             total_tx_pps += tx_pps
153         # actual total tx rate in pps
154         result['total_tx_rate'] = total_tx_pps
155         return result
156
157     def clear_stats(self):
158         pass
159
160     def start_traffic(self):
161         pass
162
163     def stop_traffic(self):
164         pass
165
166     def cleanup(self):
167         pass