Add fixes for heat deployed UDP_Replay and TRex 31/41131/3
authorMartin Banszel <martinx.banszel@intel.com>
Wed, 19 Jul 2017 19:35:02 +0000 (19:35 +0000)
committerRoss Brattain <ross.b.brattain@intel.com>
Wed, 6 Sep 2017 00:48:02 +0000 (17:48 -0700)
- Added a PROTOCOL_MAP to map the protocol names to codes -- the scapy
  requires the code, it fails if the proto is set e.g. to 'udp'
- ip addresses must be str, not unicode -- explicit conversion to str
  added
- removed unittest for setup_vnf_environment in test_tg_trex.py as
  it is the same function as already tested in test_sample_vnf.py
- traffic_profile refactored -- code repetition decreased, unittest
  adapted

Known issues:
- there is a an attempt to stop already stopped trex. It fires an
  exception that stop command is issued on the disconnected client.

Change-Id: I87e9029630f48b30e8f5b4f9d88ab3b25fd65f03
Signed-off-by: Martin Banszel <martinx.banszel@intel.com>
samples/vnf_samples/nsut/udp_replay/tc_heat_rfc2544_ipv4_1flow_64B_trex.yaml [new file with mode: 0644]
tests/unit/network_services/traffic_profile/test_traffic_profile.py
tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py
tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py
tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py
yardstick/network_services/helpers/samplevnf_helper.py
yardstick/network_services/nfvi/resource.py
yardstick/network_services/traffic_profile/traffic_profile.py
yardstick/network_services/vnf_generic/vnf/sample_vnf.py
yardstick/network_services/vnf_generic/vnf/tg_trex.py
yardstick/network_services/vnf_generic/vnf/udp_replay.py

diff --git a/samples/vnf_samples/nsut/udp_replay/tc_heat_rfc2544_ipv4_1flow_64B_trex.yaml b/samples/vnf_samples/nsut/udp_replay/tc_heat_rfc2544_ipv4_1flow_64B_trex.yaml
new file mode 100644 (file)
index 0000000..09a20c3
--- /dev/null
@@ -0,0 +1,79 @@
+# Copyright (c) 2016 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an AS IS BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+---
+schema: yardstick:task:0.1
+scenarios:
+- type: NSPerf
+  traffic_profile: ../../traffic_profiles/ipv4_throughput.yaml
+  topology: udp_replay-vnf-topology.yaml
+  nodes:
+    tg__1: trafficgen_1.yardstick
+    vnf__1: vnf.yardstick
+  options:
+    packetsize: 64
+    traffic_type: 4
+    vnf__1:
+       hw_csum: false
+    tg__1:
+       hw_csum: false
+    rfc2544:
+      allowed_drop_rate: 0.0001 - 0.0001
+  runner:
+    type: Iteration
+    iterations: 10
+    interval: 35
+  traffic_options:
+    flow: ../../traffic_profiles/ipv4_1flow_Packets.yaml
+    imix: ../../traffic_profiles/imix_voice.yaml
+context:
+  name: yardstick
+  image: yardstick-samplevnfs
+  user: ubuntu
+  nfvi_type: heat
+  flavor:
+    vcpus: 10
+    ram: 20480
+    disk: 4
+    extra_specs:
+      hw:cpu_sockets: 1
+      hw:cpu_cores: 10
+      hw:cpu_threads: 1
+  placement_groups:
+    pgrp1:
+      policy: "availability"
+
+  servers:
+    vnf:
+      floating_ip: true
+      placement: "pgrp1"
+    trafficgen_1:
+      floating_ip: true
+      placement: "pgrp1"
+
+  networks:
+    mgmt:
+      cidr: '10.0.1.0/24'
+    xe0:
+      cidr: '10.0.2.0/24'
+      vld_id: public
+      enable_dhcp: False
+      gateway_ip: null
+      port_security_enabled: False
+    xe1:
+      cidr: '10.0.3.0/24'
+      vld_id: private
+      enable_dhcp: False
+      gateway_ip: null
+      port_security_enabled: False
index 9a78c36..55e7d48 100644 (file)
@@ -29,8 +29,16 @@ stl_patch.start()
 
 if stl_patch:
     from yardstick.network_services.traffic_profile.base import TrafficProfile
-    from yardstick.network_services.traffic_profile.traffic_profile import \
-        TrexProfile
+    from yardstick.network_services.traffic_profile.traffic_profile import TrexProfile
+    from yardstick.network_services.traffic_profile.traffic_profile import SRC
+    from yardstick.network_services.traffic_profile.traffic_profile import DST
+    from yardstick.network_services.traffic_profile.traffic_profile import ETHERNET
+    from yardstick.network_services.traffic_profile.traffic_profile import IP
+    from yardstick.network_services.traffic_profile.traffic_profile import IPv6
+    from yardstick.network_services.traffic_profile.traffic_profile import UDP
+    from yardstick.network_services.traffic_profile.traffic_profile import SRC_PORT
+    from yardstick.network_services.traffic_profile.traffic_profile import DST_PORT
+    from yardstick.network_services.traffic_profile.traffic_profile import TYPE_OF_SERVICE
 
 
 class TestTrexProfile(unittest.TestCase):
@@ -44,6 +52,10 @@ class TestTrexProfile(unittest.TestCase):
             "flow_number": 10,
             "frame_size": 64}}
 
+    EXAMPLE_ETHERNET_ADDR = "00:00:00:00:00:01"
+    EXAMPLE_IP_ADDR = "10.0.0.1"
+    EXAMPLE_IPv6_ADDR = "0064:ff9b:0:0:0:0:9810:6414"
+
     PROFILE = {'description': 'Traffic profile to run RFC2544 latency',
                'name': 'rfc2544',
                'traffic_profile': {'traffic_type': 'RFC2544Profile',
@@ -129,87 +141,6 @@ class TestTrexProfile(unittest.TestCase):
             TrexProfile(TrafficProfile)
         self.assertEqual(None, trex_profile.execute({}))
 
-    def test_set_src_mac(self):
-        src_mac = "00:00:00:00:00:01"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_src_mac(src_mac))
-
-        src_mac = "00:00:00:00:00:01-00:00:00:00:00:02"
-        self.assertEqual(None, trex_profile.set_src_mac(src_mac))
-
-    def test_set_dst_mac(self):
-        dst_mac = "00:00:00:00:00:03"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_dst_mac(dst_mac))
-
-        dst_mac = "00:00:00:00:00:03-00:00:00:00:00:04"
-        self.assertEqual(None, trex_profile.set_dst_mac(dst_mac))
-
-    def test_set_src_ip4(self):
-        src_ipv4 = "152.16.100.20"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_src_ip4(src_ipv4))
-
-        src_ipv4 = "152.16.100.20-152.16.100.30"
-        self.assertEqual(None, trex_profile.set_src_ip4(src_ipv4))
-
-    def test_set_dst_ip4(self):
-        dst_ipv4 = "152.16.100.20"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_dst_ip4(dst_ipv4))
-
-        dst_ipv4 = "152.16.100.20-152.16.100.30"
-        self.assertEqual(None, trex_profile.set_dst_ip4(dst_ipv4))
-
-    def test_set_src_ip6(self):
-        src_ipv6 = "0064:ff9b:0:0:0:0:9810:6414"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_src_ip6(src_ipv6))
-
-        src_ipv6 = "0064:ff9b:0:0:0:0:9810:6414-0064:ff9b:0:0:0:0:9810:6420"
-        self.assertEqual(None, trex_profile.set_src_ip6(src_ipv6))
-
-    def test_set_dst_ip6(self):
-        dst_ipv6 = "0064:ff9b:0:0:0:0:9810:6414"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_dst_ip6(dst_ipv6))
-
-        dst_ipv6 = "0064:ff9b:0:0:0:0:9810:6414-0064:ff9b:0:0:0:0:9810:6420"
-        self.assertEqual(None, trex_profile.set_dst_ip6(dst_ipv6))
-
-    def test_dscp(self):
-        dscp = "0"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_dscp(dscp))
-
-        dscp = "0-1"
-        self.assertEqual(None, trex_profile.set_dscp(dscp))
-
-    def test_src_port(self):
-        port = "1234"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_src_port(port))
-
-        port = "1234-5678"
-        self.assertEqual(None, trex_profile.set_src_port(port))
-
-    def test_dst_port(self):
-        port = "1234"
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertEqual(None, trex_profile.set_dst_port(port))
-
-        port = "1234-5678"
-        self.assertEqual(None, trex_profile.set_dst_port(port))
-
     def test_qinq(self):
         qinq = {"S-VLAN": {"id": 128, "priority": 0, "cfi": 0},
                 "C-VLAN": {"id": 512, "priority": 0, "cfi": 0}}
@@ -222,36 +153,36 @@ class TestTrexProfile(unittest.TestCase):
                 "C-VLAN": {"id": "512-515", "priority": 0, "cfi": 0}}
         self.assertEqual(None, trex_profile.set_qinq(qinq))
 
-    def test_set_outer_l2_fields(self):
+    def test__set_outer_l2_fields(self):
         trex_profile = \
             TrexProfile(TrafficProfile)
         qinq = {"S-VLAN": {"id": 128, "priority": 0, "cfi": 0},
                 "C-VLAN": {"id": 512, "priority": 0, "cfi": 0}}
         outer_l2 = self.PROFILE['private']['ipv4']['outer_l2']
         outer_l2['QinQ'] = qinq
-        self.assertEqual(None, trex_profile.set_outer_l2_fields(outer_l2))
+        self.assertEqual(None, trex_profile._set_outer_l2_fields(outer_l2))
 
-    def test_set_outer_l3v4_fields(self):
+    def test__set_outer_l3v4_fields(self):
         trex_profile = \
             TrexProfile(TrafficProfile)
         outer_l3v4 = self.PROFILE['private']['ipv4']['outer_l3v4']
         outer_l3v4['proto'] = 'tcp'
-        self.assertEqual(None, trex_profile.set_outer_l3v4_fields(outer_l3v4))
+        self.assertEqual(None, trex_profile._set_outer_l3v4_fields(outer_l3v4))
 
-    def test_set_outer_l3v6_fields(self):
+    def test__set_outer_l3v6_fields(self):
         trex_profile = \
             TrexProfile(TrafficProfile)
         outer_l3v6 = self.PROFILE_v6['private']['ipv6']['outer_l3v4']
         outer_l3v6['proto'] = 'tcp'
         outer_l3v6['tc'] = 1
         outer_l3v6['hlim'] = 10
-        self.assertEqual(None, trex_profile.set_outer_l3v6_fields(outer_l3v6))
+        self.assertEqual(None, trex_profile._set_outer_l3v6_fields(outer_l3v6))
 
-    def test_set_outer_l4_fields(self):
+    def test__set_outer_l4_fields(self):
         trex_profile = \
             TrexProfile(TrafficProfile)
         outer_l4 = self.PROFILE['private']['ipv4']['outer_l4']
-        self.assertEqual(None, trex_profile.set_outer_l4_fields(outer_l4))
+        self.assertEqual(None, trex_profile._set_outer_l4_fields(outer_l4))
 
     def test_get_streams(self):
         trex_profile = \
@@ -284,3 +215,40 @@ class TestTrexProfile(unittest.TestCase):
             TrexProfile(TrafficProfile)
         self.assertRaises(SystemExit, trex_profile._get_start_end_ipv6,
                           "1.1.1.3", "1.1.1.1")
+
+    def test__general_single_action_partial(self):
+        trex_profile = TrexProfile(TrafficProfile)
+
+        trex_profile._general_single_action_partial(ETHERNET)(SRC)(self.EXAMPLE_ETHERNET_ADDR)
+        self.assertEqual(self.EXAMPLE_ETHERNET_ADDR, trex_profile.ether_packet.src)
+
+        trex_profile._general_single_action_partial(IP)(DST)(self.EXAMPLE_IP_ADDR)
+        self.assertEqual(self.EXAMPLE_IP_ADDR, trex_profile.ip_packet.dst)
+
+        trex_profile._general_single_action_partial(IPv6)(DST)(self.EXAMPLE_IPv6_ADDR)
+        self.assertEqual(self.EXAMPLE_IPv6_ADDR, trex_profile.ip6_packet.dst)
+
+        trex_profile._general_single_action_partial(UDP)(SRC_PORT)(5060)
+        self.assertEqual(5060, trex_profile.udp_packet.sport)
+
+        trex_profile._general_single_action_partial(IP)(TYPE_OF_SERVICE)(0)
+        self.assertEqual(0, trex_profile.ip_packet.tos)
+
+    def test__set_proto_addr(self):
+        trex_profile = TrexProfile(TrafficProfile)
+
+        ether_range = "00:00:00:00:00:01-00:00:00:00:00:02"
+        ip_range = "1.1.1.2-1.1.1.10"
+        ipv6_range =  '0064:ff9b:0:0:0:0:9810:6414-0064:ff9b:0:0:0:0:9810:6420'
+
+        trex_profile._set_proto_addr(ETHERNET, SRC, ether_range)
+        trex_profile._set_proto_addr(ETHERNET, DST, ether_range)
+        trex_profile._set_proto_addr(IP, SRC, ip_range)
+        trex_profile._set_proto_addr(IP, DST, ip_range)
+        trex_profile._set_proto_addr(IPv6, SRC, ipv6_range)
+        trex_profile._set_proto_addr(IPv6, DST, ipv6_range)
+        trex_profile._set_proto_addr(UDP, SRC_PORT, "5060-5090")
+        trex_profile._set_proto_addr(UDP, DST_PORT, "5060")
+
+
+
index ad8c649..6f2a944 100644 (file)
@@ -21,9 +21,9 @@ import unittest
 import mock
 
 from tests.unit import STL_MOCKS
+SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
 
 
-SSH_HELPER = "yardstick.ssh.SSH"
 
 STLClient = mock.MagicMock()
 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
@@ -252,6 +252,8 @@ class TestTrexTrafficGenRFC(unittest.TestCase):
         trex_traffic_gen = TrexTrafficGenRFC('vnf1', self.VNFD_0)
         trex_traffic_gen._start_server = mock.Mock(return_value=0)
         trex_traffic_gen.resource_helper = mock.MagicMock()
+        trex_traffic_gen.setup_helper.setup_vnf_environment = mock.MagicMock()
+
         scenario_cfg = {
             "tc": "tc_baremetal_rfc2544_ipv4_1flow_64B",
             "topology": 'nsb_test_case.yaml',
@@ -286,6 +288,7 @@ class TestTrexTrafficGenRFC(unittest.TestCase):
 
         trex_traffic_gen = TrexTrafficGenRFC('vnf1', self.VNFD_0)
         trex_traffic_gen.resource_helper = mock.MagicMock()
+        trex_traffic_gen.setup_helper.setup_vnf_environment = mock.MagicMock()
         scenario_cfg = {
             "tc": "tc_baremetal_rfc2544_ipv4_1flow_64B",
             "nodes": [
index 65370df..9d1ce15 100644 (file)
@@ -20,6 +20,8 @@ from __future__ import absolute_import
 import unittest
 import mock
 
+SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
+
 from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
 from tests.unit import STL_MOCKS
 
@@ -112,16 +114,197 @@ class TestTrexTrafficGen(unittest.TestCase):
             "traffic_type": "FixedTraffic",
             "frame_rate": 100,  # pps
             "flow_number": 10,
-            "frame_size": 64}}
+            "frame_size": 64
+        },
+    }
+
+    SCENARIO_CFG = {
+        "options": {
+            "packetsize": 64,
+            "traffic_type": 4,
+            "rfc2544": {
+                "allowed_drop_rate": "0.8 - 1",
+            },
+            "vnf__1": {
+                "rules": "acl_1rule.yaml",
+                "vnf_config": {
+                    "lb_config": "SW",
+                    "lb_count": 1,
+                    "worker_config": "1C/1T",
+                    "worker_threads": 1,
+                }
+            }
+        },
+        "task_id": "a70bdf4a-8e67-47a3-9dc1-273c14506eb7",
+        "tc": "tc_ipv4_1Mflow_64B_packetsize",
+        "runner": {
+            "object": "NetworkServiceTestCase",
+            "interval": 35,
+            "output_filename": "/tmp/yardstick.out",
+            "runner_id": 74476, "duration": 400,
+            "type": "Duration"
+        },
+        "traffic_profile": "ipv4_throughput_acl.yaml",
+        "traffic_options": {
+            "flow": "ipv4_Packets_acl.yaml",
+            "imix": "imix_voice.yaml"
+        },
+        "type": "ISB",
+        "nodes": {
+            "tg__2": "trafficgen_2.yardstick",
+            "tg__1": "trafficgen_1.yardstick",
+            "vnf__1": "vnf.yardstick"
+        },
+        "topology": "udpreplay-tg-topology-baremetal.yaml"
+    }
+
+    CONTEXT_CFG = {
+        "nodes": {
+            "vnf__1": {
+                "vnfd-id-ref": "vnf__1",
+                "ip": "1.2.1.1",
+                "interfaces": {
+                    "xe0": {
+                        "local_iface_name": "ens786f0",
+                        "vld_id": "private",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:05:00.0",
+                        "local_ip": "152.16.100.19",
+                        "driver": "i40e",
+                        "dst_ip": "152.16.100.20",
+                        "local_mac": "00:00:00:00:00:02",
+                        "dst_mac": "00:00:00:00:00:04",
+                        "dpdk_port_num": 0
+                    },
+                    "xe1": {
+                        "local_iface_name": "ens786f1",
+                        "vld_id": "public",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:05:00.1",
+                        "local_ip": "152.16.40.19",
+                        "driver": "i40e",
+                        "dst_ip": "152.16.40.20",
+                        "local_mac": "00:00:00:00:00:01",
+                        "dst_mac": "00:00:00:00:00:03",
+                        "dpdk_port_num": 1
+                    }
+                },
+                "host": "1.2.1.1",
+                "user": "root",
+                "nd_route_tbl": [
+                    {
+                        "netmask": "112",
+                        "if": "xe0",
+                        "gateway": "0064:ff9b:0:0:0:0:9810:6414",
+                        "network": "0064:ff9b:0:0:0:0:9810:6414"
+                    },
+                    {
+                        "netmask": "112",
+                        "if": "xe1",
+                        "gateway": "0064:ff9b:0:0:0:0:9810:2814",
+                        "network": "0064:ff9b:0:0:0:0:9810:2814"
+                    }
+                ],
+                "password": "r00t",
+                "VNF model": "udp_replay.yaml",
+                "name": "vnf.yardstick",
+                "member-vnf-index": "2",
+                "routing_table": [
+                    {
+                        "netmask": "255.255.255.0",
+                        "if": "xe0",
+                        "gateway": "152.16.100.20",
+                        "network": "152.16.100.20"
+                    },
+                    {
+                        "netmask": "255.255.255.0",
+                        "if": "xe1",
+                        "gateway": "152.16.40.20",
+                        "network": "152.16.40.20"
+                    }
+                ],
+                "role": "vnf"
+            },
+            "trafficgen_2.yardstick": {
+                "member-vnf-index": "3",
+                "role": "TrafficGen",
+                "name": "trafficgen_2.yardstick",
+                "vnfd-id-ref": "tg__2",
+                "ip": "1.2.1.1",
+                "interfaces": {
+                    "xe0": {
+                        "local_iface_name": "ens513f0",
+                        "vld_id": "public",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:02:00.0",
+                        "local_ip": "152.16.40.20",
+                        "driver": "ixgbe",
+                        "dst_ip": "152.16.40.19",
+                        "local_mac": "00:00:00:00:00:03",
+                        "dst_mac": "00:00:00:00:00:01",
+                        "dpdk_port_num": 0
+                    },
+                    "xe1": {
+                        "local_iface_name": "ens513f1",
+                        "netmask": "255.255.255.0",
+                        "network": "202.16.100.0",
+                        "local_ip": "202.16.100.20",
+                        "driver": "ixgbe",
+                        "local_mac": "00:1e:67:d0:60:5d",
+                        "vpci": "0000:02:00.1",
+                        "dpdk_port_num": 1
+                    }
+                },
+                "password": "r00t",
+                "VNF model": "l3fwd_vnf.yaml",
+                "user": "root"
+            },
+            "trafficgen_1.yardstick": {
+                "member-vnf-index": "1",
+                "role": "TrafficGen",
+                "name": "trafficgen_1.yardstick",
+                "vnfd-id-ref": "tg__1",
+                "ip": "1.2.1.1",
+                "interfaces": {
+                    "xe0": {
+                        "local_iface_name": "ens785f0",
+                        "vld_id": "private",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:05:00.0",
+                        "local_ip": "152.16.100.20",
+                        "driver": "i40e",
+                        "dst_ip": "152.16.100.19",
+                        "local_mac": "00:00:00:00:00:04",
+                        "dst_mac": "00:00:00:00:00:02",
+                        "dpdk_port_num": 0
+                    },
+                    "xe1": {
+                        "local_ip": "152.16.100.21",
+                        "driver": "i40e",
+                        "vpci": "0000:05:00.1",
+                        "dpdk_port_num": 1,
+                        "local_iface_name": "ens785f1",
+                        "netmask": "255.255.255.0",
+                        "local_mac": "00:00:00:00:00:01"
+                    }
+                },
+                "password": "r00t",
+                "VNF model": "tg_rfc2544_tpl.yaml",
+                "user": "root"
+            }
+        }
+    }
+
+
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test___init__(self, ssh):
         mock_ssh(ssh)
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
         self.assertIsInstance(trex_traffic_gen.resource_helper, TrexResourceHelper)
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test_collect_kpi(self, ssh):
         mock_ssh(ssh)
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
@@ -130,14 +313,14 @@ class TestTrexTrafficGen(unittest.TestCase):
         result = trex_traffic_gen.collect_kpi()
         self.assertEqual({}, result)
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test_listen_traffic(self, ssh):
         mock_ssh(ssh)
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
         self.assertIsNone(trex_traffic_gen.listen_traffic({}))
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test_instantiate(self, ssh):
         mock_ssh(ssh)
 
@@ -150,9 +333,11 @@ class TestTrexTrafficGen(unittest.TestCase):
         trex_traffic_gen._tg_process._is_alive = mock.Mock(return_value=1)
         trex_traffic_gen.ssh_helper = mock.MagicMock()
         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
-        self.assertIsNone(trex_traffic_gen.instantiate({}, {}))
+        trex_traffic_gen.setup_helper.setup_vnf_environment = mock.MagicMock()
 
-    @mock.patch("yardstick.ssh.SSH")
+        self.assertIsNone(trex_traffic_gen.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG))
+
+    @mock.patch(SSH_HELPER)
     def test_instantiate_error(self, ssh):
         mock_ssh(ssh, exec_result=(1, "", ""))
 
@@ -164,9 +349,10 @@ class TestTrexTrafficGen(unittest.TestCase):
         trex_traffic_gen._tg_process._is_alive = mock.Mock(return_value=0)
         trex_traffic_gen.ssh_helper = mock.MagicMock()
         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
-        self.assertIsNone(trex_traffic_gen.instantiate({}, {}))
+        trex_traffic_gen.setup_helper.setup_vnf_environment = mock.MagicMock()
+        self.assertIsNone(trex_traffic_gen.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG))
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test__start_server(self, ssh):
         mock_ssh(ssh)
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
@@ -175,7 +361,7 @@ class TestTrexTrafficGen(unittest.TestCase):
         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
         self.assertIsNone(trex_traffic_gen._start_server())
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test__traffic_runner(self, ssh):
         mock_ssh(ssh)
 
@@ -195,7 +381,7 @@ class TestTrexTrafficGen(unittest.TestCase):
         self.sut.resource_helper.QUEUE_WAIT_TIME = 0
         self.sut._traffic_runner(mock_traffic_profile)
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test__generate_trex_cfg(self, ssh):
         mock_ssh(ssh)
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
@@ -203,7 +389,7 @@ class TestTrexTrafficGen(unittest.TestCase):
         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
         self.assertIsNone(trex_traffic_gen.resource_helper.generate_cfg())
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test_run_traffic(self, ssh):
         mock_ssh(ssh)
 
@@ -221,21 +407,14 @@ class TestTrexTrafficGen(unittest.TestCase):
         self.sut._traffic_process.terminate()
         self.assertIsNotNone(result)
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test_scale(self, ssh):
         mock_ssh(ssh, exec_result=(1, "", ""))
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
         trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
         trex_traffic_gen.scale('')
 
-    @mock.patch("yardstick.ssh.SSH")
-    def test_setup_vnf_environment(self, ssh):
-        mock_ssh(ssh, exec_result=(1, "", ""))
-        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        trex_traffic_gen = TrexTrafficGen(NAME, vnfd)
-        self.assertIsNone(trex_traffic_gen.setup_helper.setup_vnf_environment())
-
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test_terminate(self, ssh):
         mock_ssh(ssh)
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
@@ -244,7 +423,7 @@ class TestTrexTrafficGen(unittest.TestCase):
         trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock()
         self.assertIsNone(trex_traffic_gen.terminate())
 
-    @mock.patch("yardstick.ssh.SSH")
+    @mock.patch(SSH_HELPER)
     def test__connect_client(self, ssh):
         mock_ssh(ssh)
         vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
index f0d75d5..c4ced30 100644 (file)
@@ -22,6 +22,7 @@ import mock
 import os
 
 from tests.unit import STL_MOCKS
+SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper'
 
 
 STLClient = mock.MagicMock()
@@ -30,269 +31,347 @@ stl_patch.start()
 
 if stl_patch:
     from yardstick.network_services.vnf_generic.vnf.udp_replay import UdpReplayApproxVnf
-    from yardstick.network_services.vnf_generic.vnf import udp_replay
+    from yardstick.network_services.vnf_generic.vnf.sample_vnf import ScenarioHelper
+
+from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh
 
 TEST_FILE_YAML = 'nsb_test_case.yaml'
 
 
-NAME = "tg__1"
+NAME = "vnf__1"
 
 
 @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Process")
-class TestAclApproxVnf(unittest.TestCase):
-    VNFD = {'vnfd:vnfd-catalog':
-            {'vnfd':
-             [{'short-name': 'VpeVnf',
-               'vdu':
-               [{'routing_table':
-                 [{'network': '152.16.100.20',
-                   'netmask': '255.255.255.0',
-                   'gateway': '152.16.100.20',
-                   'if': 'xe0'},
-                  {'network': '152.16.40.20',
-                   'netmask': '255.255.255.0',
-                   'gateway': '152.16.40.20',
-                   'if': 'xe1'}],
-                 'description': 'VPE approximation using DPDK',
-                 'name': 'vpevnf-baremetal',
-                 'nd_route_tbl':
-                 [{'network': '0064:ff9b:0:0:0:0:9810:6414',
-                   'netmask': '112',
-                   'gateway': '0064:ff9b:0:0:0:0:9810:6414',
-                   'if': 'xe0'},
-                  {'network': '0064:ff9b:0:0:0:0:9810:2814',
-                   'netmask': '112',
-                   'gateway': '0064:ff9b:0:0:0:0:9810:2814',
-                   'if': 'xe1'}],
-                 'id': 'vpevnf-baremetal',
-                 'external-interface':
-                 [{'virtual-interface':
-                   {'dst_mac': '00:00:00:00:00:04',
-                    'vpci': '0000:05:00.0',
-                    'local_ip': '152.16.100.19',
-                    'type': 'PCI-PASSTHROUGH',
-                    'netmask': '255.255.255.0',
-                    'dpdk_port_num': '0',
-                    'bandwidth': '10 Gbps',
-                    'driver': "i40e",
-                    'dst_ip': '152.16.100.20',
-                    'local_iface_name': 'xe0',
-                    'local_mac': '00:00:00:00:00:02'},
-                   'vnfd-connection-point-ref': 'xe0',
-                   'name': 'xe0'},
-                  {'virtual-interface':
-                   {'dst_mac': '00:00:00:00:00:03',
-                    'vpci': '0000:05:00.1',
-                    'local_ip': '152.16.40.19',
-                    'type': 'PCI-PASSTHROUGH',
-                    'driver': "i40e",
-                    'netmask': '255.255.255.0',
-                    'dpdk_port_num': '1',
-                    'bandwidth': '10 Gbps',
-                    'dst_ip': '152.16.40.20',
-                    'local_iface_name': 'xe1',
-                    'local_mac': '00:00:00:00:00:01'},
-                   'vnfd-connection-point-ref': 'xe1',
-                   'name': 'xe1'}]}],
-               'description': 'Vpe approximation using DPDK',
-               'mgmt-interface':
-                   {'vdu-id': 'vpevnf-baremetal',
-                    'host': '1.2.1.1',
-                    'password': 'r00t',
-                    'user': 'root',
-                    'ip': '1.2.1.1'},
-               'benchmark':
-                   {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']},
-               'connection-point': [{'type': 'VPORT', 'name': 'xe0'},
-                                    {'type': 'VPORT', 'name': 'xe1'}],
-               'id': 'UdpReplayApproxVnf', 'name': 'VPEVnfSsh'}]}}
-
-    scenario_cfg = {'options': {'packetsize': 64, 'traffic_type': 4,
-                                'rfc2544': {'allowed_drop_rate': '0.8 - 1'},
-                                'vnf__1': {'rules': 'acl_1rule.yaml',
-                                           'vnf_config': {'lb_config': 'SW',
-                                                          'lb_count': 1,
-                                                          'worker_config':
-                                                          '1C/1T',
-                                                          'worker_threads': 1}}
-                                },
-                    'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
-                    'tc': 'tc_ipv4_1Mflow_64B_packetsize',
-                    'runner': {'object': 'NetworkServiceTestCase',
-                               'interval': 35,
-                               'output_filename': '/tmp/yardstick.out',
-                               'runner_id': 74476, 'duration': 400,
-                               'type': 'Duration'},
-                    'traffic_profile': 'ipv4_throughput_acl.yaml',
-                    'traffic_options': {'flow': 'ipv4_Packets_acl.yaml',
-                                        'imix': 'imix_voice.yaml'},
-                    'type': 'ISB',
-                    'nodes': {'tg__2': 'trafficgen_2.yardstick',
-                              'tg__1': 'trafficgen_1.yardstick',
-                              'vnf__1': 'vnf.yardstick'},
-                    'topology': 'vpe-tg-topology-baremetal.yaml'}
-
-    context_cfg = {'nodes': {'trafficgen_2.yardstick':
-                             {'member-vnf-index': '3',
-                              'role': 'TrafficGen',
-                              'name': 'trafficgen_2.yardstick',
-                              'vnfd-id-ref': 'tg__2',
-                              'ip': '1.2.1.1',
-                              'interfaces':
-                              {'xe0': {'local_iface_name': 'ens513f0',
-                                       'vld_id': 'public',
-                                       'netmask': '255.255.255.0',
-                                       'local_ip': '152.16.40.20',
-                                       'dst_mac': '00:00:00:00:00:01',
-                                       'local_mac': '00:00:00:00:00:03',
-                                       'dst_ip': '152.16.40.19',
-                                       'driver': 'ixgbe',
-                                       'vpci': '0000:02:00.0',
-                                       'dpdk_port_num': 0},
-                               'xe1': {'local_iface_name': 'ens513f1',
-                                       'netmask': '255.255.255.0',
-                                       'network': '202.16.100.0',
-                                       'local_ip': '202.16.100.20',
-                                       'local_mac': '00:1e:67:d0:60:5d',
-                                       'driver': 'ixgbe',
-                                       'vpci': '0000:02:00.1',
-                                       'dpdk_port_num': 1}},
-                              'password': 'r00t',
-                              'VNF model': 'l3fwd_vnf.yaml',
-                              'user': 'root'},
-                             'trafficgen_1.yardstick':
-                             {'member-vnf-index': '1',
-                              'role': 'TrafficGen',
-                              'name': 'trafficgen_1.yardstick',
-                              'vnfd-id-ref': 'tg__1',
-                              'ip': '1.2.1.1',
-                              'interfaces':
-                              {'xe0': {'local_iface_name': 'ens785f0',
-                                       'vld_id': 'private',
-                                       'netmask': '255.255.255.0',
-                                       'local_ip': '152.16.100.20',
-                                       'dst_mac': '00:00:00:00:00:02',
-                                       'local_mac': '00:00:00:00:00:04',
-                                       'dst_ip': '152.16.100.19',
-                                       'driver': 'i40e',
-                                       'vpci': '0000:05:00.0',
-                                       'dpdk_port_num': 0},
-                               'xe1': {'local_iface_name': 'ens785f1',
-                                       'netmask': '255.255.255.0',
-                                       'local_ip': '152.16.100.21',
-                                       'local_mac': '00:00:00:00:00:01',
-                                       'driver': 'i40e',
-                                       'vpci': '0000:05:00.1',
-                                       'dpdk_port_num': 1}},
-                              'password': 'r00t',
-                              'VNF model': 'tg_rfc2544_tpl.yaml',
-                              'user': 'root'},
-                             'vnf__1':
-                             {'name': 'vnf.yardstick',
-                              'vnfd-id-ref': 'vnf__1',
-                              'ip': '1.2.1.1',
-                              'interfaces':
-                              {'xe0': {'local_iface_name': 'ens786f0',
-                                       'vld_id': 'private',
-                                       'netmask': '255.255.255.0',
-                                       'local_ip': '152.16.100.19',
-                                       'dst_mac': '00:00:00:00:00:04',
-                                       'local_mac': '00:00:00:00:00:02',
-                                       'dst_ip': '152.16.100.20',
-                                       'driver': 'i40e',
-                                       'vpci': '0000:05:00.0',
-                                       'dpdk_port_num': 0},
-                               'xe1': {'local_iface_name': 'ens786f1',
-                                       'vld_id': 'public',
-                                       'netmask': '255.255.255.0',
-                                       'local_ip': '152.16.40.19',
-                                       'dst_mac': '00:00:00:00:00:03',
-                                       'local_mac': '00:00:00:00:00:01',
-                                       'dst_ip': '152.16.40.20',
-                                       'driver': 'i40e',
-                                       'vpci': '0000:05:00.1',
-                                       'dpdk_port_num': 1}},
-                              'routing_table':
-                              [{'netmask': '255.255.255.0',
-                                'gateway': '152.16.100.20',
-                                'network': '152.16.100.20',
-                                'if': 'xe0'},
-                               {'netmask': '255.255.255.0',
-                                'gateway': '152.16.40.20',
-                                'network': '152.16.40.20',
-                                'if': 'xe1'}],
-                              'member-vnf-index': '2',
-                              'host': '1.2.1.1',
-                              'role': 'vnf',
-                              'user': 'root',
-                              'nd_route_tbl':
-                              [{'netmask': '112',
-                                'gateway': '0064:ff9b:0:0:0:0:9810:6414',
-                                'network': '0064:ff9b:0:0:0:0:9810:6414',
-                                'if': 'xe0'},
-                               {'netmask': '112',
-                                'gateway': '0064:ff9b:0:0:0:0:9810:2814',
-                                'network': '0064:ff9b:0:0:0:0:9810:2814',
-                                'if': 'xe1'}],
-                              'password': 'r00t',
-                              'VNF model': 'udp_replay.yaml'}}}
-
-    def test___init__(self, mock_process):
-        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-        self.assertIsNone(udp_approx_vnf._vnf_process)
+class TestUdpReplayApproxVnf(unittest.TestCase):
+
+    VNFD_0 = {
+        'short-name': 'UdpReplayVnf',
+        'vdu': [
+            {
+                'description': 'UDPReplay approximation using DPDK',
+                'routing_table': [
+                    {
+                        'netmask': '255.255.255.0',
+                        'if': 'xe0',
+                        'network': '152.16.100.20',
+                        'gateway': '152.16.100.20',
+                    },
+                    {
+                        'netmask': '255.255.255.0',
+                        'if': 'xe1',
+                        'network': '152.16.40.20',
+                        'gateway': '152.16.40.20',
+                    }
+                ],
+                'external-interface': [
+                    {
+                        'virtual-interface': {
+                            'dst_mac': '00:00:00:00:00:04',
+                            'driver': 'i40e',
+                            'local_iface_name': 'xe0',
+                            'bandwidth': '10 Gbps',
+                            'local_ip': '152.16.100.19',
+                            'local_mac': '00:00:00:00:00:02',
+                            'vpci': '0000:05:00.0',
+                            'dpdk_port_num': '0',
+                            'netmask': '255.255.255.0',
+                            'dst_ip': '152.16.100.20',
+                            'type': 'PCI-PASSTHROUGH',
+                        },
+                        'vnfd-connection-point-ref': 'xe0',
+                        'name': 'xe0',
+                    },
+                    {
+                        'virtual-interface': {
+                            'dst_mac': '00:00:00:00:00:03',
+                            'driver': 'i40e',
+                            'local_iface_name': 'xe1',
+                            'bandwidth': '10 Gbps',
+                            'local_ip': '152.16.40.19',
+                            'local_mac': '00:00:00:00:00:01',
+                            'vpci': '0000:05:00.1',
+                            'dpdk_port_num': '1',
+                            'netmask': '255.255.255.0',
+                            'dst_ip': '152.16.40.20',
+                            'type': 'PCI-PASSTHROUGH',
+                        },
+                        'vnfd-connection-point-ref': 'xe1',
+                        'name': 'xe1',
+                    }
+                ],
+                'nd_route_tbl': [
+                    {
+                        'netmask': '112',
+                        'if': 'xe0',
+                        'network': '0064:ff9b:0:0:0:0:9810:6414',
+                        'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+                    },
+                    {
+                        'netmask': '112',
+                        'if': 'xe1',
+                        'network': '0064:ff9b:0:0:0:0:9810:2814',
+                        'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+                    }
+                ],
+                'id': 'udpreplayvnf-baremetal',
+                'name': 'udpreplayvnf-baremetal',
+            }
+        ],
+        'description': 'UDPReplay approximation using DPDK',
+        'name': 'VPEVnfSsh',
+        'mgmt-interface': {
+            'vdu-id': 'udpreplay-baremetal',
+            'host': '1.2.1.1',
+            'password': 'r00t',
+            'user': 'root',
+            'ip': '1.2.1.1',
+        },
+        'benchmark': {
+            'kpi': [
+                'packets_in',
+                'packets_fwd',
+                'packets_dropped',
+            ]
+        },
+        'connection-point': [
+            {
+                'type': 'VPORT',
+                'name': 'xe0',
+            },
+            {
+                'type': 'VPORT',
+                'name': 'xe1',
+            }
+        ],
+        'id': 'UdpReplayApproxVnf',
+    }
+
+    SCENARIO_CFG = {
+        "options": {
+            "packetsize": 64,
+            "traffic_type": 4,
+            "rfc2544": {
+                "allowed_drop_rate": "0.8 - 1",
+            },
+            "vnf__1": {
+                "rules": "acl_1rule.yaml",
+                "vnf_config": {
+                    "lb_config": "SW",
+                    "lb_count": 1,
+                    "worker_config": "1C/1T",
+                    "worker_threads": 1,
+                },
+                "hw_csum": "false",
+            }
+        },
+        "task_id": "a70bdf4a-8e67-47a3-9dc1-273c14506eb7",
+        "tc": "tc_ipv4_1Mflow_64B_packetsize",
+        "runner": {
+            "object": "NetworkServiceTestCase",
+            "interval": 35,
+            "output_filename": "/tmp/yardstick.out",
+            "runner_id": 74476, "duration": 400,
+            "type": "Duration"
+        },
+        "traffic_profile": "ipv4_throughput_acl.yaml",
+        "traffic_options": {
+            "flow": "ipv4_Packets_acl.yaml",
+            "imix": "imix_voice.yaml"
+        },
+        "type": "ISB",
+        "nodes": {
+            "tg__2": "trafficgen_2.yardstick",
+            "tg__1": "trafficgen_1.yardstick",
+            "vnf__1": "vnf.yardstick"
+        },
+        "topology": "udpreplay-tg-topology-baremetal.yaml"
+    }
+
+    CONTEXT_CFG = {
+        "nodes": {
+            "vnf__1": {
+                "vnfd-id-ref": "vnf__1",
+                "ip": "1.2.1.1",
+                "interfaces": {
+                    "xe0": {
+                        "local_iface_name": "ens786f0",
+                        "vld_id": "private",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:05:00.0",
+                        "local_ip": "152.16.100.19",
+                        "driver": "i40e",
+                        "dst_ip": "152.16.100.20",
+                        "local_mac": "00:00:00:00:00:02",
+                        "dst_mac": "00:00:00:00:00:04",
+                        "dpdk_port_num": 0
+                    },
+                    "xe1": {
+                        "local_iface_name": "ens786f1",
+                        "vld_id": "public",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:05:00.1",
+                        "local_ip": "152.16.40.19",
+                        "driver": "i40e",
+                        "dst_ip": "152.16.40.20",
+                        "local_mac": "00:00:00:00:00:01",
+                        "dst_mac": "00:00:00:00:00:03",
+                        "dpdk_port_num": 1
+                    }
+                },
+                "host": "1.2.1.1",
+                "user": "root",
+                "nd_route_tbl": [
+                    {
+                        "netmask": "112",
+                        "if": "xe0",
+                        "gateway": "0064:ff9b:0:0:0:0:9810:6414",
+                        "network": "0064:ff9b:0:0:0:0:9810:6414"
+                    },
+                    {
+                        "netmask": "112",
+                        "if": "xe1",
+                        "gateway": "0064:ff9b:0:0:0:0:9810:2814",
+                        "network": "0064:ff9b:0:0:0:0:9810:2814"
+                    }
+                ],
+                "password": "r00t",
+                "VNF model": "udp_replay.yaml",
+                "name": "vnf.yardstick",
+                "member-vnf-index": "2",
+                "routing_table": [
+                    {
+                        "netmask": "255.255.255.0",
+                        "if": "xe0",
+                        "gateway": "152.16.100.20",
+                        "network": "152.16.100.20"
+                    },
+                    {
+                        "netmask": "255.255.255.0",
+                        "if": "xe1",
+                        "gateway": "152.16.40.20",
+                        "network": "152.16.40.20"
+                    }
+                ],
+                "role": "vnf"
+            },
+            "trafficgen_2.yardstick": {
+                "member-vnf-index": "3",
+                "role": "TrafficGen",
+                "name": "trafficgen_2.yardstick",
+                "vnfd-id-ref": "tg__2",
+                "ip": "1.2.1.1",
+                "interfaces": {
+                    "xe0": {
+                        "local_iface_name": "ens513f0",
+                        "vld_id": "public",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:02:00.0",
+                        "local_ip": "152.16.40.20",
+                        "driver": "ixgbe",
+                        "dst_ip": "152.16.40.19",
+                        "local_mac": "00:00:00:00:00:03",
+                        "dst_mac": "00:00:00:00:00:01",
+                        "dpdk_port_num": 0
+                    },
+                    "xe1": {
+                        "local_iface_name": "ens513f1",
+                        "netmask": "255.255.255.0",
+                        "network": "202.16.100.0",
+                        "local_ip": "202.16.100.20",
+                        "driver": "ixgbe",
+                        "local_mac": "00:1e:67:d0:60:5d",
+                        "vpci": "0000:02:00.1",
+                        "dpdk_port_num": 1
+                    }
+                },
+                "password": "r00t",
+                "VNF model": "l3fwd_vnf.yaml",
+                "user": "root"
+            },
+            "trafficgen_1.yardstick": {
+                "member-vnf-index": "1",
+                "role": "TrafficGen",
+                "name": "trafficgen_1.yardstick",
+                "vnfd-id-ref": "tg__1",
+                "ip": "1.2.1.1",
+                "interfaces": {
+                    "xe0": {
+                        "local_iface_name": "ens785f0",
+                        "vld_id": "private",
+                        "netmask": "255.255.255.0",
+                        "vpci": "0000:05:00.0",
+                        "local_ip": "152.16.100.20",
+                        "driver": "i40e",
+                        "dst_ip": "152.16.100.19",
+                        "local_mac": "00:00:00:00:00:04",
+                        "dst_mac": "00:00:00:00:00:02",
+                        "dpdk_port_num": 0
+                    },
+                    "xe1": {
+                        "local_ip": "152.16.100.21",
+                        "driver": "i40e",
+                        "vpci": "0000:05:00.1",
+                        "dpdk_port_num": 1,
+                        "local_iface_name": "ens785f1",
+                        "netmask": "255.255.255.0",
+                        "local_mac": "00:00:00:00:00:01"
+                    }
+                },
+                "password": "r00t",
+                "VNF model": "tg_rfc2544_tpl.yaml",
+                "user": "root"
+            }
+        }
+    }
+
+    def test___init__(self, _):
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        self.assertIsNone(udp_replay_approx_vnf._vnf_process)
 
     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
-    def test_collect_kpi(self, mock_time, mock_process):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, "", ""))
-            ssh.from_node.return_value = ssh_mock
-            vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-            result = "stats\r\r\n\r\nUDP_Replay stats:\r\n--------------\r\n" \
-                "Port\t\tRx Packet\t\tTx Packet\t\tRx Pkt Drop\t\tTx Pkt Drop \r\n"\
-                "0\t\t7374156\t\t7374136\t\t\t0\t\t\t0\r\n" \
-                "1\t\t7374316\t\t7374315\t\t\t0\t\t\t0\r\n\r\nReplay>\r\r\nReplay>"
-            udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-            udp_approx_vnf.q_in = mock.MagicMock()
-            udp_approx_vnf.q_out = mock.MagicMock()
-            udp_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
-            udp_approx_vnf.all_ports = [0, 1]
-            udp_approx_vnf.interfaces = vnfd["vdu"][0]['external-interface']
-            udp_approx_vnf.get_stats = mock.Mock(return_value=result)
-            result = {'collect_stats': {}, 'packets_dropped': 0,
-                      'packets_fwd': 14748451, 'packets_in': 14748472}
-            self.assertEqual(result, udp_approx_vnf.collect_kpi())
+    @mock.patch(SSH_HELPER)
+    def test_collect_kpi(self, ssh, mock_time, _):
+        mock_ssh(ssh)
+
+        vnfd = self.VNFD_0
+        result = "stats\r\r\n\r\nUDP_Replay stats:\r\n--------------\r\n" \
+                 "Port\t\tRx Packet\t\tTx Packet\t\tRx Pkt Drop\t\tTx Pkt Drop \r\n"\
+                 "0\t\t7374156\t\t7374136\t\t\t0\t\t\t0\r\n" \
+                 "1\t\t7374316\t\t7374315\t\t\t0\t\t\t0\r\n\r\nReplay>\r\r\nReplay>"
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
+        udp_replay_approx_vnf.q_in = mock.MagicMock()
+        udp_replay_approx_vnf.q_out = mock.MagicMock()
+        udp_replay_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
+        udp_replay_approx_vnf.all_ports = [0, 1]
+        udp_replay_approx_vnf.get_stats = mock.Mock(return_value=result)
+        result = {'collect_stats': {}, 'packets_dropped': 0,
+                  'packets_fwd': 14748451, 'packets_in': 14748472}
+        self.assertEqual(result, udp_replay_approx_vnf.collect_kpi())
 
     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
-    def test_vnf_execute_command(self, mock_time, mock_process):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, "", ""))
-            ssh.from_node.return_value = ssh_mock
-            vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-            udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-            cmd = "quit"
-            self.assertEqual("", udp_approx_vnf.vnf_execute(cmd))
-
-    def test_get_stats(self, mock_process):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, "", ""))
-            ssh.from_node.return_value = ssh_mock
-            vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-            udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-            udp_approx_vnf.q_in = mock.MagicMock()
-            udp_approx_vnf.q_out = mock.MagicMock()
-            udp_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
-            mock_result = \
-                "CG-NAPT(.*\n)*Received 100, Missed 0, Dropped 0,Translated 100,ingress"
-            udp_approx_vnf.vnf_execute = mock.Mock(return_value=mock_result)
-            self.assertEqual(mock_result,
-                             udp_approx_vnf.get_stats())
+    @mock.patch(SSH_HELPER)
+    def test_vnf_execute_command(self, ssh, mock_time, _):
+        mock_ssh(ssh)
+
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        cmd = "quit"
+        self.assertEqual("", udp_replay_approx_vnf.vnf_execute(cmd))
+
+    @mock.patch(SSH_HELPER)
+    def test_get_stats(self, ssh, _):
+        mock_ssh(ssh)
+
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        udp_replay_approx_vnf.q_in = mock.MagicMock()
+        udp_replay_approx_vnf.q_out = mock.MagicMock()
+        udp_replay_approx_vnf.q_out.qsize = mock.Mock(return_value=0)
+        mock_result = \
+            "CG-NAPT(.*\n)*Received 100, Missed 0, Dropped 0,Translated 100,ingress"
+
+        udp_replay_approx_vnf.vnf_execute = mock.Mock(return_value=mock_result)
+
+        self.assertEqual(mock_result,
+                         udp_replay_approx_vnf.get_stats())
 
     def _get_file_abspath(self, filename):
         curr_path = os.path.dirname(os.path.abspath(__file__))
@@ -300,111 +379,115 @@ class TestAclApproxVnf(unittest.TestCase):
         return file_path
 
     @mock.patch('yardstick.network_services.vnf_generic.vnf.udp_replay.open')
-    def test__build_pipeline_kwargs(self, mock_open, mock_process):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh.from_node.return_value = ssh_mock
-            vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-            udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-            udp_approx_vnf._build_config = mock.MagicMock()
-            udp_approx_vnf.queue_wrapper = mock.MagicMock()
-            udp_approx_vnf.nfvi_type = "baremetal"
-            udp_approx_vnf.bound_pci = []
-            udp_approx_vnf.all_ports = [0, 1]
-            udp_approx_vnf.ssh_helper = mock.MagicMock(
-                **{"provision_tool.return_value": "tool_path"})
-            udp_approx_vnf.vnf_cfg = {'lb_config': 'SW',
-                                      'lb_count': 1,
-                                      'worker_config': '1C/1T',
-                                      'worker_threads': 1}
-            udp_approx_vnf.options = {'traffic_type': '4',
-                                      'topology': 'nsb_test_case.yaml'}
-
-            udp_approx_vnf._build_pipeline_kwargs()
-            self.assertEqual(udp_approx_vnf.pipeline_kwargs, {
-                'config': '(0, 0, 1)(1, 0, 2)',
-                'cpu_mask_hex': '0x6',
-                'hw_csum': '',
-                'ports_len_hex': '0x3',
-                'tool_path': 'tool_path',
-                'whitelist': ''
-            })
-
-    @mock.patch("yardstick.network_services.vnf_generic.vnf.udp_replay.hex")
-    @mock.patch("yardstick.network_services.vnf_generic.vnf.udp_replay.eval")
+    @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
+    @mock.patch(SSH_HELPER)
+    def test__build_config(self, ssh, mock_context, *_):
+        mock_ssh(ssh)
+
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        udp_replay_approx_vnf.queue_wrapper = mock.MagicMock()
+        udp_replay_approx_vnf.nfvi_context = mock_context
+        udp_replay_approx_vnf.nfvi_context.attrs = {'nfvi_type': 'baremetal'}
+        udp_replay_approx_vnf.setup_helper.bound_pci = []
+        udp_replay_approx_vnf.all_ports = [0, 1]
+        udp_replay_approx_vnf.ssh_helper.provision_tool = mock.MagicMock(return_value="tool_path")
+        udp_replay_approx_vnf.scenario_helper = ScenarioHelper(name='vnf__1')
+        udp_replay_approx_vnf.scenario_helper.scenario_cfg = self.SCENARIO_CFG
+
+        cmd_line = udp_replay_approx_vnf._build_config()
+
+        expected = "sudo tool_path -c 0x7 -n 4 -w  --  -p 0x3 --config='(0, 0, 1)(1, 0, 2)'"
+        self.assertEqual(cmd_line, expected)
+
     @mock.patch('yardstick.network_services.vnf_generic.vnf.udp_replay.open')
-    def test_run_udp_replay(self, mock_open, eval, hex, mock_process):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, "", ""))
-            ssh_mock.run = \
-                mock.Mock(return_value=(0, "", ""))
-            ssh.from_node.return_value = ssh_mock
-            vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-            udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-            udp_approx_vnf._build_config = mock.MagicMock()
-            udp_approx_vnf.queue_wrapper = mock.MagicMock()
-            udp_approx_vnf.ssh_helper = mock.MagicMock()
-            udp_approx_vnf.ssh_helper.run = mock.MagicMock()
-            udp_approx_vnf.vnf_cfg = {'lb_config': 'SW',
-                                      'lb_count': 1,
-                                      'worker_config': '1C/1T',
-                                      'worker_threads': 1}
-            udp_approx_vnf.options = {'traffic_type': '4',
-                                      'topology': 'nsb_test_case.yaml'}
-
-            udp_approx_vnf._run()
-            udp_approx_vnf.ssh_helper.run.assert_called_once()
+    @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
+    @mock.patch(SSH_HELPER)
+    def test__build_pipeline_kwargs(self, ssh, mock_context, *_):
+        mock_ssh(ssh)
+
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        udp_replay_approx_vnf._build_config = mock.MagicMock()
+        udp_replay_approx_vnf.queue_wrapper = mock.MagicMock()
+        udp_replay_approx_vnf.nfvi_context = mock_context
+        udp_replay_approx_vnf.nfvi_context.attrs = {'nfvi_type': 'baremetal'}
+        udp_replay_approx_vnf.setup_helper.bound_pci = []
+        udp_replay_approx_vnf.all_ports = [0, 1]
+        udp_replay_approx_vnf.ssh_helper.provision_tool = mock.MagicMock(return_value="tool_path")
+        udp_replay_approx_vnf.scenario_helper = ScenarioHelper(name='vnf__1')
+        udp_replay_approx_vnf.scenario_helper.scenario_cfg = self.SCENARIO_CFG
+
+        udp_replay_approx_vnf._build_pipeline_kwargs()
+
+        self.assertEqual(udp_replay_approx_vnf.pipeline_kwargs, {
+            'config': '(0, 0, 1)(1, 0, 2)',
+            'cpu_mask_hex': '0x7',
+            'hw_csum': '',
+            'ports_len_hex': '0x3',
+            'tool_path': 'tool_path',
+            'whitelist': ''
+        })
+
+    @mock.patch(SSH_HELPER)
+    def test_run_udp_replay(self, ssh, _):
+        mock_ssh(ssh)
+
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        udp_replay_approx_vnf._build_config = mock.MagicMock()
+        udp_replay_approx_vnf.queue_wrapper = mock.MagicMock()
+
+        udp_replay_approx_vnf._run()
+
+        udp_replay_approx_vnf.ssh_helper.run.assert_called_once()
 
     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
-    def test_instantiate(self, Context, mock_process):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, "", ""))
-            ssh.from_node.return_value = ssh_mock
-            vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-            udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-            self.scenario_cfg['vnf_options'] = {'cgnapt': {'cfg': "",
-                                                           'rules': ""}}
-            udp_approx_vnf._run_udp_replay = mock.Mock(return_value=0)
-            udp_approx_vnf._parse_rule_file = mock.Mock(return_value={})
-            udp_approx_vnf.deploy_udp_replay_vnf = mock.Mock(return_value=1)
-            udp_approx_vnf.q_out.put("Replay>")
-            udp_approx_vnf.get_my_ports = mock.Mock(return_value=[0, 1])
-            udp_replay.WAIT_TIME = 3
-            udp_approx_vnf.get_nfvi_type = mock.Mock(return_value="baremetal")
-
-            udp_approx_vnf._vnf_process = mock.MagicMock()
-            udp_approx_vnf._vnf_process.is_alive = \
-                mock.Mock(return_value=1)
-            self.assertIsNone(udp_approx_vnf.instantiate(self.scenario_cfg,
-                                                         self.context_cfg))
-
-    def test_scale(self, mock_process):
-        vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-        udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
+    @mock.patch(SSH_HELPER)
+    def test_instantiate(self, ssh, *_):
+        mock_ssh(ssh)
+
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        udp_replay_approx_vnf.q_out.put("Replay>")
+        udp_replay_approx_vnf.WAIT_TIME = 0
+        udp_replay_approx_vnf.setup_helper.setup_vnf_environment = mock.Mock()
+
+        self.assertIsNone(udp_replay_approx_vnf.instantiate(self.SCENARIO_CFG,
+                                                     self.CONTEXT_CFG))
+
+        udp_replay_approx_vnf._vnf_process.is_alive = mock.Mock(return_value=1)
+        udp_replay_approx_vnf._vnf_process.exitcode = 0
+
+        self.assertEquals(udp_replay_approx_vnf.wait_for_instantiate(), 0)
+
+    @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context")
+    @mock.patch('yardstick.ssh.SSH')
+    @mock.patch(SSH_HELPER)
+    def test_instantiate_panic(self, ssh, resource_ssh, *_):
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        udp_replay_approx_vnf.WAIT_TIME = 0
+        udp_replay_approx_vnf.q_out.put("some text PANIC some text")
+        udp_replay_approx_vnf.setup_helper.setup_vnf_environment = mock.Mock()
+
+        self.assertIsNone(udp_replay_approx_vnf.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG))
+        with self.assertRaises(RuntimeError):
+            udp_replay_approx_vnf.wait_for_instantiate()
+
+    def test_scale(self, _):
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
         flavor = ""
-        self.assertRaises(NotImplementedError, udp_approx_vnf.scale, flavor)
+
+        self.assertRaises(NotImplementedError, udp_replay_approx_vnf.scale, flavor)
 
     @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time")
-    def test_terminate(self, mock_time, mock_process):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, "", ""))
-            ssh.from_node.return_value = ssh_mock
-            vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
-            udp_approx_vnf = UdpReplayApproxVnf(NAME, vnfd)
-            udp_approx_vnf._vnf_process = mock.MagicMock()
-            udp_approx_vnf._vnf_process.terminate = mock.Mock()
-            udp_approx_vnf.used_drivers = {"01:01.0": "i40e",
-                                           "01:01.1": "i40e"}
-            udp_approx_vnf.execute_command = mock.Mock()
-            udp_approx_vnf.ssh_helper = ssh_mock
-            udp_approx_vnf.dpdk_nic_bind = "dpdk_nic_bind.py"
-            self.assertEqual(None, udp_approx_vnf.terminate())
+    @mock.patch(SSH_HELPER)
+    def test_terminate(self, ssh, mock_time, _):
+        mock_ssh(ssh)
+
+        udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0)
+        udp_replay_approx_vnf._vnf_process = mock.MagicMock()
+        udp_replay_approx_vnf._vnf_process.terminate = mock.Mock()
+        udp_replay_approx_vnf.used_drivers = {"01:01.0": "i40e",
+                                       "01:01.1": "i40e"}
+        udp_replay_approx_vnf.dpdk_nic_bind = "dpdk_nic_bind.py"
+        self.assertEqual(None, udp_replay_approx_vnf.terminate())
 
 if __name__ == '__main__':
     unittest.main()
index dfc5cb9..9d89d41 100644 (file)
@@ -229,10 +229,15 @@ class MultiPortConfig(object):
     @staticmethod
     def get_port_pairs(interfaces):
         port_pair_list = []
-        networks = defaultdict(list)
+        networks = {}
         for private_intf in interfaces:
             vintf = private_intf['virtual-interface']
-            networks[vintf['vld_id']].append(vintf)
+            try:
+                vld_id = vintf['vld_id']
+            except KeyError:
+                pass
+            else:
+                networks.setdefault(vld_id, []).append(vintf)
 
         for name, net in networks.items():
             # partition returns a tuple
index f0ae676..055fdba 100644 (file)
@@ -203,6 +203,7 @@ class ResourceProfile(object):
         self._provide_config_file(bin_path, 'collectd.conf', kwargs)
 
     def _start_collectd(self, connection, bin_path):
+        LOG.debug("Starting collectd to collect NFVi stats")
         connection.execute('sudo pkill -9 collectd')
         bin_path = get_nsb_option("bin_path")
         collectd_path = os.path.join(bin_path, "collectd", "collectd")
index 7bbe892..4c6595d 100644 (file)
@@ -33,203 +33,86 @@ from trex_stl_lib.trex_stl_packet_builder_scapy import STLScVmRaw
 from trex_stl_lib.trex_stl_packet_builder_scapy import STLVmFixIpv4
 from trex_stl_lib import api as Pkt
 
+SRC = 'src'
+DST = 'dst'
+ETHERNET = 'Ethernet'
+IP = 'IP'
+IPv6 = 'IPv6'
+UDP = 'UDP'
+DSCP = 'DSCP'
+SRC_PORT = 'sport'
+DST_PORT = 'dport'
+TYPE_OF_SERVICE = 'tos'
+
 
 class TrexProfile(TrafficProfile):
     """ This class handles Trex Traffic profile generation and execution """
 
-    def __init__(self, yaml_data):
-        super(TrexProfile, self).__init__(yaml_data)
-        self.flows = 100
-        self.pps = 100
-        self.pg_id = 0
-        self.first_run = True
-        self.streams = 1
-        self.profile_data = []
-        self.profile = None
-        self.base_pkt = None
-        self.fsize = None
-        self.trex_vm = None
-        self.vms = []
-        self.rate = None
-        self.ip_packet = None
-        self.ip6_packet = None
-        self.udp_packet = None
-        self.udp_dport = ''
-        self.udp_sport = ''
-        self.qinq_packet = None
-        self.qinq = False
-        self.vm_flow_vars = []
-        self.packets = []
-        self.ether_packet = []
-
-    def execute(self, traffic_generator):
-        """ Generate the stream and run traffic on the given ports """
-        pass
-
-    def _set_ether_fields(self, **kwargs):
-        """ set ethernet protocol fields """
-        if not self.ether_packet:
-            self.ether_packet = Pkt.Ether()
-            for key, value in six.iteritems(kwargs):
-                setattr(self.ether_packet, key, value)
-
-    def _set_ip_fields(self, **kwargs):
-        """ set l3 ipv4 protocol fields """
-
-        if not self.ip_packet:
-            self.ip_packet = Pkt.IP()
-        for key in kwargs:
-            setattr(self.ip_packet, key, kwargs[key])
-
-    def _set_ip6_fields(self, **kwargs):
-        """ set l3 ipv6 protocol fields """
-        if not self.ip6_packet:
-            self.ip6_packet = Pkt.IPv6()
-        for key in kwargs:
-            setattr(self.ip6_packet, key, kwargs[key])
-
-    def _set_udp_fields(self, **kwargs):
-        """ set l4 udp ports fields """
-        if not self.udp_packet:
-            self.udp_packet = Pkt.UDP()
-        for key in kwargs:
-            setattr(self.udp_packet, key, kwargs[key])
-
-    def set_src_mac(self, src_mac):
-        """ set source mac address fields """
-        src_macs = src_mac.split('-')
-        min_value = src_macs[0]
-        if len(src_macs) == 1:
-            src_mac = min_value
-            self._set_ether_fields(src=src_mac)
-        else:
-            stl_vm_flow_var = STLVmFlowVar(name="mac_src",
+    PROTO_MAP = {
+        ETHERNET: ('ether_packet', Pkt.Ether),
+        IP: ('ip_packet', Pkt.IP),
+        IPv6: ('ip6_packet', Pkt.IPv6),
+        UDP: ('udp_packet', Pkt.UDP),
+    }
+
+    def _general_single_action_partial(self, protocol):
+        def f(field):
+            def partial(value):
+                kwargs = {
+                    field: value
+                }
+                self._set_proto_fields(protocol, **kwargs)
+            return partial
+        return f
+
+    def _ethernet_range_action_partial(self, direction, _):
+        def partial(min_value, max_value):
+            stl_vm_flow_var = STLVmFlowVar(name="mac_{}".format(direction),
                                            min_value=1,
                                            max_value=30,
                                            size=4,
                                            op='inc',
                                            step=1)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_src',
-                                                pkt_offset='Ether.src')
+            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_{}'.format(direction),
+                                                pkt_offset='Ether.{}'.format(direction))
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
+        return partial
 
-    def set_dst_mac(self, dst_mac):
-        """ set destination mac address fields """
-        dst_macs = dst_mac.split('-')
-        min_value = dst_macs[0]
-        if len(dst_macs) == 1:
-            dst_mac = min_value
-            self._set_ether_fields(dst=dst_mac)
-        else:
-            stl_vm_flow_var = STLVmFlowVar(name="mac_dst",
-                                           min_value=1,
-                                           max_value=30,
-                                           size=4,
-                                           op='inc',
-                                           step=1)
-            self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_dst',
-                                                pkt_offset='Ether.dst')
-            self.vm_flow_vars.append(stl_vm_wr_flow_var)
-
-    def set_src_ip4(self, src_ip4, count=1):
-        """ set source ipv4 address fields """
-        src_ips = src_ip4.split('-')
-        min_value = src_ips[0]
-        max_value = src_ips[1] if len(src_ips) == 2 else src_ips[0]
-        if len(src_ips) == 1:
-            src_ip4 = min_value
-            self._set_ip_fields(src=src_ip4)
-        else:
-            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="ip4_src",
+    def _ip_range_action_partial(self, direction, count=1):
+        def partial(min_value, max_value):
+            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="ip4_{}".format(direction),
                                                            min_value=min_value,
                                                            max_value=max_value,
                                                            size=4,
                                                            limit=int(count),
                                                            seed=0x1235)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip4_src',
-                                                pkt_offset='IP.src')
+            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip4_{}'.format(direction),
+                                                pkt_offset='IP.{}'.format(direction))
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
             stl_vm_fix_ipv4 = STLVmFixIpv4(offset="IP")
             self.vm_flow_vars.append(stl_vm_fix_ipv4)
+        return partial
 
-    def set_dst_ip4(self, dst_ip4, count=1):
-        """ set destination ipv4 address fields """
-        dst_ips = dst_ip4.split('-')
-        min_value = dst_ips[0]
-        max_value = dst_ips[1] if len(dst_ips) == 2 else dst_ips[0]
-        if len(dst_ips) == 1:
-            dst_ip4 = min_value
-            self._set_ip_fields(dst=dst_ip4)
-        else:
-            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="dst_ip4",
-                                                           min_value=min_value,
-                                                           max_value=max_value,
-                                                           size=4,
-                                                           limit=int(count),
-                                                           seed=0x1235)
-            self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='dst_ip4',
-                                                pkt_offset='IP.dst')
-            self.vm_flow_vars.append(stl_vm_wr_flow_var)
-            stl_vm_fix_ipv4 = STLVmFixIpv4(offset="IP")
-            self.vm_flow_vars.append(stl_vm_fix_ipv4)
-
-    def set_src_ip6(self, src_ip6):
-        """ set source ipv6 address fields """
-        src_ips = src_ip6.split('-')
-        min_value = src_ips[0]
-        max_value = src_ips[1] if len(src_ips) == 2 else src_ips[0]
-        src_ip6 = min_value
-        self._set_ip6_fields(src=src_ip6)
-        if len(src_ips) == 2:
-            min_value, max_value = \
-                self._get_start_end_ipv6(min_value, max_value)
-            stl_vm_flow_var = STLVmFlowVar(name="ip6_src",
+    def _ip6_range_action_partial(self, direction, _):
+        def partial(min_value, max_value):
+            min_value, max_value = self._get_start_end_ipv6(min_value, max_value)
+            stl_vm_flow_var = STLVmFlowVar(name="ip6_{}".format(direction),
                                            min_value=min_value,
                                            max_value=max_value,
                                            size=8,
                                            op='random',
                                            step=1)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip6_src',
-                                                pkt_offset='IPv6.src',
+            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip6_{}'.format(direction),
+                                                pkt_offset='IPv6.{}'.format(direction),
                                                 offset_fixup=8)
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
+        return partial
 
-    def set_dst_ip6(self, dst_ip6):
-        """ set destination ipv6 address fields """
-        dst_ips = dst_ip6.split('-')
-        min_value = dst_ips[0]
-        max_value = dst_ips[1] if len(dst_ips) == 2 else dst_ips[0]
-        dst_ip6 = min_value
-        self._set_ip6_fields(dst=dst_ip6)
-        if len(dst_ips) == 2:
-            min_value, max_value = \
-                self._get_start_end_ipv6(min_value, max_value)
-            stl_vm_flow_var = STLVmFlowVar(name="dst_ip6",
-                                           min_value=min_value,
-                                           max_value=max_value,
-                                           size=8,
-                                           op='random',
-                                           step=1)
-            self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='dst_ip6',
-                                                pkt_offset='IPv6.dst',
-                                                offset_fixup=8)
-            self.vm_flow_vars.append(stl_vm_wr_flow_var)
-
-    def set_dscp(self, dscp):
-        """ set dscp for trex """
-        dscps = str(dscp).split('-')
-        min_value = int(dscps[0])
-        max_value = int(dscps[1]) if len(dscps) == 2 else int(dscps[0])
-        if len(dscps) == 1:
-            dscp = min_value
-            self._set_ip_fields(tos=dscp)
-        else:
+    def _dscp_range_action_partial(self, *_):
+        def partial(min_value, max_value):
             stl_vm_flow_var = STLVmFlowVar(name="dscp",
                                            min_value=min_value,
                                            max_value=max_value,
@@ -241,54 +124,110 @@ class TrexProfile(TrafficProfile):
                                                 pkt_offset='IP.tos')
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
 
-    def set_src_port(self, src_port, count=1):
-        """ set packet source port """
-        src_ports = str(src_port).split('-')
-        min_value = int(src_ports[0])
-        if len(src_ports) == 1:
-            max_value = int(src_ports[0])
-            src_port = min_value
-            self._set_udp_fields(sport=src_port)
-        else:
-            max_value = int(src_ports[1])
-            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="port_src",
+    def _udp_range_action_partial(self, field, count=1):
+        def partial(min_value, max_value):
+            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="port_{}".format(field),
                                                            min_value=min_value,
                                                            max_value=max_value,
                                                            size=2,
                                                            limit=int(count),
                                                            seed=0x1235)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_src',
+            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_{}'.format(field),
                                                 pkt_offset=self.udp_sport)
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
+        return partial
 
-    def set_dst_port(self, dst_port, count=1):
-        """ set packet destnation port """
-        dst_ports = str(dst_port).split('-')
-        min_value = int(dst_ports[0])
-        if len(dst_ports) == 1:
-            max_value = int(dst_ports[0])
-            dst_port = min_value
-            self._set_udp_fields(dport=dst_port)
+    def __init__(self, yaml_data):
+        super(TrexProfile, self).__init__(yaml_data)
+        self.flows = 100
+        self.pps = 100
+        self.pg_id = 0
+        self.first_run = True
+        self.streams = 1
+        self.profile_data = []
+        self.profile = None
+        self.base_pkt = None
+        self.fsize = None
+        self.trex_vm = None
+        self.vms = []
+        self.rate = None
+        self.ether_packet = None
+        self.ip_packet = None
+        self.ip6_packet = None
+        self.udp_packet = None
+        self.udp_dport = ''
+        self.udp_sport = ''
+        self.qinq_packet = None
+        self.qinq = False
+        self.vm_flow_vars = []
+        self.packets = []
+
+        self._map_proto_actions = {
+            # the tuple is (single value function, range value function, if the values should be
+            # converted to integer).
+            ETHERNET: (self._general_single_action_partial(ETHERNET),
+                       self._ethernet_range_action_partial,
+                       False,
+                       ),
+            IP: (self._general_single_action_partial(IP),
+                 self._ip_range_action_partial,
+                 False,
+                 ),
+            IPv6: (self._general_single_action_partial(IPv6),
+                   self._ip6_range_action_partial,
+                   False,
+                   ),
+            DSCP: (self._general_single_action_partial(IP),
+                   self._dscp_range_action_partial,
+                   True,
+                   ),
+            UDP: (self._general_single_action_partial(UDP),
+                  self._udp_range_action_partial,
+                  True,
+                  ),
+        }
+
+    def execute(self, traffic_generator):
+        """ Generate the stream and run traffic on the given ports """
+        pass
+
+    def _call_on_range(self, range, single_action, range_action, count=1, to_int=False):
+        def convert_to_int(val):
+            return int(val) if to_int else val
+
+        range_iter = iter(str(range).split('-'))
+        min_value = convert_to_int(next(range_iter))
+        try:
+            max_value = convert_to_int(next(range_iter))
+        except StopIteration:
+            single_action(min_value)
         else:
-            max_value = int(dst_ports[1])
-            stl_vm_flow_var = \
-                STLVmFlowVarRepeatableRandom(name="port_dst",
-                                             min_value=min_value,
-                                             max_value=max_value,
-                                             size=2,
-                                             limit=int(count),
-                                             seed=0x1235)
-            self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_dst',
-                                                pkt_offset=self.udp_dport)
-            self.vm_flow_vars.append(stl_vm_wr_flow_var)
+            range_action(min_value=min_value, max_value=max_value)
+
+    def _set_proto_addr(self, protocol, field, address, count=1):
+        single_action, range_action, to_int = self._map_proto_actions[protocol]
+        self._call_on_range(address,
+                            single_action(field),
+                            range_action(field, count),
+                            to_int=to_int,
+                            )
+
+    def _set_proto_fields(self, protocol, **kwargs):
+        _attr_name, _class = self.PROTO_MAP[protocol]
+
+        if not getattr(self, _attr_name):
+            setattr(self, _attr_name, _class())
+
+        _attr = getattr(self, _attr_name)
+        for key, value in six.iteritems(kwargs):
+            setattr(_attr, key, value)
 
     def set_svlan_cvlan(self, svlan, cvlan):
         """ set svlan & cvlan """
         self.qinq = True
         ether_params = {'type': 0x8100}
-        self._set_ether_fields(**ether_params)
+        self._set_proto_fields(ETHERNET, **ether_params)
         svlans = str(svlan['id']).split('-')
         svlan_min = int(svlans[0])
         svlan_max = int(svlans[1]) if len(svlans) == 2 else int(svlans[0])
@@ -309,42 +248,42 @@ class TrexProfile(TrafficProfile):
         """ set qinq in packet """
         self.set_svlan_cvlan(qinq['S-VLAN'], qinq['C-VLAN'])
 
-    def set_outer_l2_fields(self, outer_l2):
+    def _set_outer_l2_fields(self, outer_l2):
         """ setup outer l2 fields from traffic profile """
         ether_params = {'type': 0x800}
-        self._set_ether_fields(**ether_params)
+        self._set_proto_fields(ETHERNET, **ether_params)
         if 'srcmac' in outer_l2:
-            self.set_src_mac(outer_l2['srcmac'])
+            self._set_proto_addr(ETHERNET, SRC, outer_l2['srcmac'])
         if 'dstmac' in outer_l2:
-            self.set_dst_mac(outer_l2['dstmac'])
+            self._set_proto_addr(ETHERNET, DST, outer_l2['dstmac'])
         if 'QinQ' in outer_l2:
             self.set_qinq(outer_l2['QinQ'])
 
-    def set_outer_l3v4_fields(self, outer_l3v4):
+    def _set_outer_l3v4_fields(self, outer_l3v4):
         """ setup outer l3v4 fields from traffic profile """
         ip_params = {}
         if 'proto' in outer_l3v4:
-            ip_params['proto'] = outer_l3v4['proto']
+            ip_params['proto'] = socket.getprotobyname(outer_l3v4['proto'])
             if outer_l3v4['proto'] == 'tcp':
                 self.udp_packet = Pkt.TCP()
                 self.udp_dport = 'TCP.dport'
                 self.udp_sport = 'TCP.sport'
                 tcp_params = {'flags': '', 'window': 0}
-                self._set_udp_fields(**tcp_params)
+                self._set_proto_fields(UDP, **tcp_params)
         if 'ttl' in outer_l3v4:
             ip_params['ttl'] = outer_l3v4['ttl']
-        self._set_ip_fields(**ip_params)
+        self._set_proto_fields(IP, **ip_params)
         if 'dscp' in outer_l3v4:
-            self.set_dscp(outer_l3v4['dscp'])
+            self._set_proto_addr(DSCP, TYPE_OF_SERVICE, outer_l3v4['dscp'])
         if 'srcip4' in outer_l3v4:
-            self.set_src_ip4(outer_l3v4['srcip4'], outer_l3v4['count'])
+            self._set_proto_addr(IP, SRC, outer_l3v4['srcip4'], outer_l3v4['count'])
         if 'dstip4' in outer_l3v4:
-            self.set_dst_ip4(outer_l3v4['dstip4'], outer_l3v4['count'])
+            self._set_proto_addr(IP, DST, outer_l3v4['dstip4'], outer_l3v4['count'])
 
-    def set_outer_l3v6_fields(self, outer_l3v6):
+    def _set_outer_l3v6_fields(self, outer_l3v6):
         """ setup outer l3v6 fields from traffic profile """
         ether_params = {'type': 0x86dd}
-        self._set_ether_fields(**ether_params)
+        self._set_proto_fields(ETHERNET, **ether_params)
         ip6_params = {}
         if 'proto' in outer_l3v6:
             ip6_params['proto'] = outer_l3v6['proto']
@@ -353,25 +292,25 @@ class TrexProfile(TrafficProfile):
                 self.udp_dport = 'TCP.dport'
                 self.udp_sport = 'TCP.sport'
                 tcp_params = {'flags': '', 'window': 0}
-                self._set_udp_fields(**tcp_params)
+                self._set_proto_fields(UDP, **tcp_params)
         if 'ttl' in outer_l3v6:
             ip6_params['ttl'] = outer_l3v6['ttl']
         if 'tc' in outer_l3v6:
             ip6_params['tc'] = outer_l3v6['tc']
         if 'hlim' in outer_l3v6:
             ip6_params['hlim'] = outer_l3v6['hlim']
-        self._set_ip6_fields(**ip6_params)
+        self._set_proto_fields(IPv6, **ip6_params)
         if 'srcip6' in outer_l3v6:
-            self.set_src_ip6(outer_l3v6['srcip6'])
+            self._set_proto_addr(IPv6, SRC, outer_l3v6['srcip6'])
         if 'dstip6' in outer_l3v6:
-            self.set_dst_ip6(outer_l3v6['dstip6'])
+            self._set_proto_addr(IPv6, DST, outer_l3v6['dstip6'])
 
-    def set_outer_l4_fields(self, outer_l4):
+    def _set_outer_l4_fields(self, outer_l4):
         """ setup outer l4 fields from traffic profile """
         if 'srcport' in outer_l4:
-            self.set_src_port(outer_l4['srcport'], outer_l4['count'])
+            self._set_proto_addr(UDP, SRC_PORT, outer_l4['srcport'], outer_l4['count'])
         if 'dstport' in outer_l4:
-            self.set_dst_port(outer_l4['dstport'], outer_l4['count'])
+            self._set_proto_addr(UDP, DST_PORT, outer_l4['dstport'], outer_l4['count'])
 
     def generate_imix_data(self, packet_definition):
         """ generate packet size for a given traffic profile """
@@ -434,13 +373,13 @@ class TrexProfile(TrafficProfile):
         outer_l3v6 = packet_definition.get('outer_l3v6', None)
         outer_l4 = packet_definition.get('outer_l4', None)
         if outer_l2:
-            self.set_outer_l2_fields(outer_l2)
+            self._set_outer_l2_fields(outer_l2)
         if outer_l3v4:
-            self.set_outer_l3v4_fields(outer_l3v4)
+            self._set_outer_l3v4_fields(outer_l3v4)
         if outer_l3v6:
-            self.set_outer_l3v6_fields(outer_l3v6)
+            self._set_outer_l3v6_fields(outer_l3v6)
         if outer_l4:
-            self.set_outer_l4_fields(outer_l4)
+            self._set_outer_l4_fields(outer_l4)
         self.trex_vm = STLScVmRaw(self.vm_flow_vars)
 
     def generate_packets(self):
index 9a7d399..1b2533a 100644 (file)
@@ -680,19 +680,19 @@ class ScenarioHelper(object):
 
     @property
     def task_path(self):
-        return self.scenario_cfg["task_path"]
+        return self.scenario_cfg['task_path']
 
     @property
     def nodes(self):
-        return self.scenario_cfg['nodes']
+        return self.scenario_cfg.get('nodes')
 
     @property
     def all_options(self):
-        return self.scenario_cfg["options"]
+        return self.scenario_cfg.get('options', {})
 
     @property
     def options(self):
-        return self.all_options[self.name]
+        return self.all_options.get(self.name, {})
 
     @property
     def vnf_cfg(self):
@@ -742,7 +742,6 @@ class SampleVNF(GenericVNF):
         self.q_out = Queue()
         self.queue_wrapper = None
         self.run_kwargs = {}
-        self.scenario_cfg = None
         self.tg_port_pairs = None
         self.used_drivers = {}
         self.vnf_port_pairs = None
@@ -937,7 +936,6 @@ class SampleVNFTrafficGen(GenericTrafficGen):
     def instantiate(self, scenario_cfg, context_cfg):
         self.scenario_helper.scenario_cfg = scenario_cfg
         self.resource_helper.generate_cfg()
-        self.setup_helper.setup_vnf_environment()
         self.resource_helper.setup()
 
         LOG.info("Starting %s server...", self.APP_NAME)
index 616b331..1fe790f 100644 (file)
@@ -25,10 +25,19 @@ from yardstick.common.utils import mac_address_to_hex_list
 from yardstick.network_services.utils import get_nsb_option
 from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen
 from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
+from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
 
 LOG = logging.getLogger(__name__)
 
 
+class TrexDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
+    APP_NAME = "t-rex-64"
+    CFG_CONFIG = ""
+    CFG_SCRIPT = ""
+    PIPELINE_COMMAND = ""
+    VNF_TYPE = "TG"
+
+
 class TrexResourceHelper(ClientResourceHelper):
 
     CONF_FILE = '/tmp/trex_cfg.yaml'
@@ -36,16 +45,14 @@ class TrexResourceHelper(ClientResourceHelper):
     RESOURCE_WORD = 'trex'
     RUN_DURATION = 0
 
-    SYNC_PORT = 4500
-    ASYNC_PORT = 4501
+    ASYNC_PORT = 4500
+    SYNC_PORT = 4501
 
     def generate_cfg(self):
         ext_intf = self.vnfd_helper.interfaces
         vpci_list = []
         port_list = []
         trex_cfg = {
-            'port_limit': 0,
-            'version': '2',
             'interfaces': vpci_list,
             'port_info': port_list,
             "port_limit": len(ext_intf),
@@ -79,6 +86,7 @@ class TrexResourceHelper(ClientResourceHelper):
     DISABLE_DEPLOY = True
 
     def setup(self):
+        super(TrexResourceHelper, self).setup()
         if self.DISABLE_DEPLOY:
             return
 
@@ -130,6 +138,9 @@ class TrexTrafficGen(SampleVNFTrafficGen):
         if resource_helper_type is None:
             resource_helper_type = TrexResourceHelper
 
+        if setup_env_helper_type is None:
+            setup_env_helper_type = TrexDpdkVnfSetupEnvHelper
+
         super(TrexTrafficGen, self).__init__(name, vnfd, setup_env_helper_type,
                                              resource_helper_type)
 
index 6e206f2..a9bc204 100644 (file)
@@ -16,6 +16,8 @@ from __future__ import absolute_import
 import logging
 
 from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF
+from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
+from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
 
 LOG = logging.getLogger(__name__)
 
@@ -27,38 +29,65 @@ REPLAY_PIPELINE_COMMAND = (
 # {tool_path} -p {ports_len_hex} -f {cfg_file} -s {script}'
 
 
+class UdpReplaySetupEnvHelper(DpdkVnfSetupEnvHelper):
+
+    APP_NAME = "UDP_Replay"
+
+
+class UdpReplayResourceHelper(ClientResourceHelper):
+    pass
+
+
 class UdpReplayApproxVnf(SampleVNF):
 
     APP_NAME = "UDP_Replay"
     APP_WORD = "UDP_Replay"
-    PIPELINE_COMMAND = REPLAY_PIPELINE_COMMAND
     VNF_PROMPT = 'Replay>'
 
-    CSUM_MAP = {
-        'baremetal': '',
-        'sriov': '',
-    }
+    VNF_TYPE = 'UdpReplay'
+
+    HW_OFFLOADING_NFVI_TYPES = {'baremetal', 'sriov'}
+
+    PIPELINE_COMMAND = REPLAY_PIPELINE_COMMAND
+
+    def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None):
+        if resource_helper_type is None:
+            resource_helper_type = UdpReplayResourceHelper
+
+        if setup_env_helper_type is None:
+            setup_env_helper_type = UdpReplaySetupEnvHelper
+
+        super(UdpReplayApproxVnf, self).__init__(name, vnfd, setup_env_helper_type,
+                                                 resource_helper_type)
+
+    def _start_server(self):
+        super(UdpReplayApproxVnf, self)._start_server()
+        self.resource_helper.start()
 
     def scale(self, flavor=""):
         """ scale vnfbased on flavor input """
         raise NotImplementedError
 
-    def _build_config(self):
-        pass
-
     def _deploy(self):
         self.generate_port_pairs()
         super(UdpReplayApproxVnf, self)._deploy()
 
     def _build_pipeline_kwargs(self):
-        tool_path = self.ssh_helper.provision_tool(self.APP_NAME)
-        ports_mask = 2 ** len(self.all_ports) - 1
+        all_ports = [i for i, _ in enumerate(self.vnfd_helper.interfaces)]
+        number_of_ports = len(all_ports)
+
+        tool_path = self.ssh_helper.provision_tool(tool_file=self.APP_NAME)
+        ports_mask = 2 ** number_of_ports - 1
         ports_mask_hex = hex(ports_mask)
-        cpu_mask_hex = hex(ports_mask * 2)
-        hw_csum = self.CSUM_MAP.get(self.nfvi_type, "--no-hw-csum")
-        config_value = "".join(str((port, 0, port + 1)) for port in self.all_ports)
+        cpu_mask_hex = hex(2 ** (number_of_ports + 1) - 1)
+        hw_csum = ""
+        if (not self.scenario_helper.options.get('hw_csum', False) or
+                self.nfvi_context.attrs.get('nfvi_type') not in self.HW_OFFLOADING_NFVI_TYPES):
+            hw_csum = '--no-hw-csum'
+
+        config_value = "".join(str((port, 0, port + 1)) for port in all_ports)
 
-        whitelist = " -w ".join(self.bound_pci)
+        whitelist = " -w ".join(self.setup_helper.bound_pci)
         self.pipeline_kwargs = {
             'ports_len_hex': ports_mask_hex,
             'tool_path': tool_path,
@@ -68,13 +97,19 @@ class UdpReplayApproxVnf(SampleVNF):
             'config': config_value,
         }
 
+    def _build_config(self):
+        self._build_pipeline_kwargs()
+        return self.PIPELINE_COMMAND.format(**self.pipeline_kwargs)
+
     def collect_kpi(self):
         def get_sum(offset):
             return sum(int(i) for i in split_stats[offset::5])
 
+        number_of_ports = len(self.vnfd_helper.interfaces)
+
         stats = self.get_stats()
         stats_words = stats.split()
-        split_stats = stats_words[stats_words.index('0'):][:len(self.all_ports) * 5]
+        split_stats = stats_words[stats_words.index('0'):][:number_of_ports * 5]
         result = {
             "packets_in": get_sum(1),
             "packets_fwd": get_sum(2),