1 # Copyright (c) 2019 Viosoft Corporation
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
17 from trex_stl_lib.trex_stl_exceptions import STLError
19 from yardstick.common.utils import safe_cast
20 from yardstick.network_services.vnf_generic.vnf.sample_vnf import \
22 from yardstick.network_services.vnf_generic.vnf.sample_vnf import \
24 from yardstick.network_services.vnf_generic.vnf.tg_trex import \
25 TrexDpdkVnfSetupEnvHelper
26 from yardstick.network_services.vnf_generic.vnf.tg_trex import \
29 LOGGING = logging.getLogger(__name__)
32 class TrexVppResourceHelper(TrexResourceHelper):
34 def __init__(self, setup_helper, rfc_helper_type=None):
35 super(TrexVppResourceHelper, self).__init__(setup_helper)
37 if rfc_helper_type is None:
38 rfc_helper_type = Rfc2544ResourceHelper
40 self.rfc2544_helper = rfc_helper_type(self.scenario_helper)
46 def generate_samples(self, stats=None, ports=None, port_pg_id=None,
50 stats = self.get_stats(ports)
51 for pname in (intf['name'] for intf in self.vnfd_helper.interfaces):
52 port_num = self.vnfd_helper.port_num(pname)
53 port_stats = stats.get(port_num, {})
55 'rx_throughput_fps': float(port_stats.get('rx_pps', 0.0)),
56 'tx_throughput_fps': float(port_stats.get('tx_pps', 0.0)),
57 'rx_throughput_bps': float(port_stats.get('rx_bps', 0.0)),
58 'tx_throughput_bps': float(port_stats.get('tx_bps', 0.0)),
59 'in_packets': int(port_stats.get('ipackets', 0)),
60 'out_packets': int(port_stats.get('opackets', 0)),
64 pg_id_list = port_pg_id.get_pg_ids(port_num)
65 samples[pname]['latency'] = {}
66 for pg_id in pg_id_list:
67 latency_global = stats.get('latency', {})
68 pg_latency = latency_global.get(pg_id, {}).get('latency')
70 t_min = safe_cast(pg_latency.get("total_min", 0.0), float,
72 t_avg = safe_cast(pg_latency.get("average", 0.0), float,
74 t_max = safe_cast(pg_latency.get("total_max", 0.0), float,
82 samples[pname]['latency'][pg_id] = latency
86 def _run_traffic_once(self, traffic_profile):
87 self.client_started.value = 1
88 traffic_profile.execute_traffic(self)
91 def run_traffic(self, traffic_profile):
92 self._queue.cancel_join_thread()
93 traffic_profile.init_queue(self._queue)
94 super(TrexVppResourceHelper, self).run_traffic(traffic_profile)
97 def fmt_latency(lat_min, lat_avg, lat_max):
98 t_min = int(round(safe_cast(lat_min, float, -1.0)))
99 t_avg = int(round(safe_cast(lat_avg, float, -1.0)))
100 t_max = int(round(safe_cast(lat_max, float, -1.0)))
102 return "/".join(str(tmp) for tmp in (t_min, t_avg, t_max))
104 def send_traffic_on_tg(self, ports, port_pg_id, duration, rate,
107 # Choose rate and start traffic:
108 self.client.start(ports=ports, mult=rate, duration=duration)
111 self.client.wait_on_traffic(ports=ports, timeout=duration + 20)
112 except STLError as err:
113 self.client.stop(ports)
114 LOGGING.error("TRex stateless timeout error: %s", err)
116 if self.client.get_warnings():
117 for warning in self.client.get_warnings():
118 LOGGING.warning(warning)
120 # Read the stats after the test
121 stats = self.client.get_stats()
126 packets_in.append(stats[port]["ipackets"])
127 packets_out.append(stats[port]["opackets"])
131 pg_id_list = port_pg_id.get_pg_ids(port)
132 for pg_id in pg_id_list:
133 latency_global = stats.get('latency', {})
134 pg_latency = latency_global.get(pg_id, {}).get(
136 lat = self.fmt_latency(
137 str(pg_latency.get("total_min")),
138 str(pg_latency.get("average")),
139 str(pg_latency.get("total_max")))
141 "latencyStream%s(usec)=%s", pg_id, lat)
142 self.latency.append(lat)
144 self.sent = sum(packets_out)
145 total_rcvd = sum(packets_in)
146 self.loss = self.sent - total_rcvd
147 LOGGING.info("rate=%s, totalReceived=%s, totalSent=%s,"
148 " frameLoss=%s", rate, total_rcvd, self.sent,
151 except STLError as err:
152 LOGGING.error("TRex stateless runtime error: %s", err)
153 raise RuntimeError('TRex stateless runtime error')
156 class TrexTrafficGenVpp(SampleVNFTrafficGen):
160 def __init__(self, name, vnfd, setup_env_helper_type=None,
161 resource_helper_type=None):
162 if setup_env_helper_type is None:
163 setup_env_helper_type = TrexDpdkVnfSetupEnvHelper
164 if resource_helper_type is None:
165 resource_helper_type = TrexVppResourceHelper
167 super(TrexTrafficGenVpp, self).__init__(
168 name, vnfd, setup_env_helper_type, resource_helper_type)
170 def _check_status(self):
171 return self.resource_helper.check_status()
173 def _start_server(self):
174 super(TrexTrafficGenVpp, self)._start_server()
175 self.resource_helper.start()
177 def wait_for_instantiate(self):
178 return self._wait_for_process()