diff options
author | Ross Brattain <ross.b.brattain@intel.com> | 2017-09-15 20:49:52 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@opnfv.org> | 2017-09-15 20:49:52 +0000 |
commit | 3016786696b9e5a26b364cb5bd4cb5676420fe58 (patch) | |
tree | 0ca209f5bf0f00e36e856ffecd21184921265077 | |
parent | 38eb33a092e903b9854267d3e36496c919517103 (diff) | |
parent | be6e7ed6f053a4a697af939fa0ddcd5dce54c0c8 (diff) |
Merge "NSB: fix port topology"
75 files changed, 2360 insertions, 1688 deletions
diff --git a/samples/vnf_samples/nsut/acl/acl-tg-topology-3node.yaml b/samples/vnf_samples/nsut/acl/acl-tg-topology-3node.yaml index f8c01daff..36cb2e88b 100644 --- a/samples/vnf_samples/nsut/acl/acl-tg-topology-3node.yaml +++ b/samples/vnf_samples/nsut/acl/acl-tg-topology-3node.yaml @@ -40,7 +40,16 @@ nsd:nsd-catalog: - member-vnf-index-ref: '2' vnfd-connection-point-ref: xe0 vnfd-id-ref: vnf__1 - + - id: private_2 + name: tg__1 to vnf__1 link 2 + type: ELAN + vnfd-connection-point-ref: + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe1 + vnfd-id-ref: tg__1 + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe1 + vnfd-id-ref: tg__1 - id: public_1 name: vnf__1 to tg__2 link 2 type: ELAN diff --git a/samples/vnf_samples/nsut/acl/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml b/samples/vnf_samples/nsut/acl/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml index aea127a08..1261aa0c8 100644 --- a/samples/vnf_samples/nsut/acl/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml +++ b/samples/vnf_samples/nsut/acl/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml @@ -33,7 +33,7 @@ scenarios: traffic_type: 4 rfc2544: allowed_drop_rate: 0.0001 - 0.0001 - corelated_traffic: true + correlated_traffic: true vnf__1: rules: acl_1rule.yaml vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} diff --git a/samples/vnf_samples/nsut/cgnapt/cgnapt-vnf-topology-3node.yaml b/samples/vnf_samples/nsut/cgnapt/cgnapt-vnf-topology-3node.yaml index 24407dc88..7b681b52a 100644 --- a/samples/vnf_samples/nsut/cgnapt/cgnapt-vnf-topology-3node.yaml +++ b/samples/vnf_samples/nsut/cgnapt/cgnapt-vnf-topology-3node.yaml @@ -40,7 +40,16 @@ nsd:nsd-catalog: - member-vnf-index-ref: '2' vnfd-connection-point-ref: xe0 vnfd-id-ref: vnf__1 - + - id: private_2 + name: tg__1 to vnf__1 link 2 + type: ELAN + vnfd-connection-point-ref: + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe1 + vnfd-id-ref: tg__1 + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe1 + vnfd-id-ref: tg__1 - id: public_1 name: vnf__1 to tg__2 link 2 type: ELAN diff --git a/samples/vnf_samples/nsut/cgnapt/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml b/samples/vnf_samples/nsut/cgnapt/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml index 38549f0a1..f110ab233 100644 --- a/samples/vnf_samples/nsut/cgnapt/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml +++ b/samples/vnf_samples/nsut/cgnapt/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml @@ -28,19 +28,19 @@ scenarios: public: {64B: 100} flow: src_ip: [{'tg__1': 'xe0'}] - dst_ip: [{'tg__2': 'xe0'} + dst_ip: [{'tg__2': 'xe0'}] count: 1 traffic_type: 4 rfc2544: allowed_drop_rate: 0.0001 - 0.0001 - corelated_traffic: true + correlated_traffic: true vnf__1: vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} napt: 'dynamic' nfvi_enable: True runner: type: Iteration - iterations: 10 + iterations: 14 interval: 35 context: type: Node diff --git a/samples/vnf_samples/nsut/ping/tc_ping_heat_context.yaml b/samples/vnf_samples/nsut/ping/tc_ping_heat_context.yaml index 394523ffa..d6f096b55 100644 --- a/samples/vnf_samples/nsut/ping/tc_ping_heat_context.yaml +++ b/samples/vnf_samples/nsut/ping/tc_ping_heat_context.yaml @@ -31,7 +31,7 @@ scenarios: context: name: yardstick - image: yardstick-image + image: yardstick-samplevnfs flavor: yardstick-flavor user: ubuntu diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml index cadc4289c..6a55bfb77 100644 --- a/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml +++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_trex_corelated_traffic.yaml @@ -33,7 +33,7 @@ scenarios: traffic_type: 4 rfc2544: allowed_drop_rate: 0.0001 - 0.0001 - corelated_traffic: true + correlated_traffic: true vnf__1: rules: acl_1rule.yaml vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} diff --git a/samples/vnf_samples/nsut/vpe/tc_baremetal_http_ipv4_ixload.yaml b/samples/vnf_samples/nsut/vpe/tc_baremetal_http_ipv4_ixload.yaml index 4dd6d8148..a40179390 100644 --- a/samples/vnf_samples/nsut/vpe/tc_baremetal_http_ipv4_ixload.yaml +++ b/samples/vnf_samples/nsut/vpe/tc_baremetal_http_ipv4_ixload.yaml @@ -31,8 +31,8 @@ scenarios: count: 1 traffic_type: 4 vnf__1: - cfg: vpe_config nfvi_enable: True + vnf_config: vpe_config runner: type: Duration duration: 4 diff --git a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_1518B.yaml b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_1518B.yaml index 8029ba3de..bff9743e0 100644 --- a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_1518B.yaml +++ b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_1518B.yaml @@ -33,8 +33,8 @@ scenarios: rfc2544: allowed_drop_rate: 0.0001 - 0.0001 vnf__1: - cfg: vpe_config nfvi_enable: True + vnf_config: vpe_config runner: type: Iteration iterations: 10 diff --git a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B.yaml b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B.yaml index d393aa763..50874ac5c 100644 --- a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B.yaml +++ b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B.yaml @@ -33,8 +33,8 @@ scenarios: rfc2544: allowed_drop_rate: 0.0001 - 0.0001 vnf__1: - cfg: vpe_config nfvi_enable: True + vnf_config: vpe_config runner: type: Iteration iterations: 10 diff --git a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_ixia.yaml b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_ixia.yaml index f33d86911..394d07861 100644 --- a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_ixia.yaml +++ b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_ixia.yaml @@ -33,8 +33,8 @@ scenarios: rfc2544: allowed_drop_rate: 0.0001 - 0.0001 vnf__1: - cfg: vpe_config nfvi_enable: True + vnf_config: vpe_config runner: type: Iteration iterations: 10 diff --git a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml index 91099fd95..972d58bdf 100644 --- a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml +++ b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_64B_trex_corelated_traffic.yaml @@ -33,10 +33,10 @@ scenarios: traffic_type: 4 rfc2544: allowed_drop_rate: 0.0001 - 0.0001 - corelated_traffic: true + correlated_traffic: true vnf__1: - cfg: vpe_config nfvi_enable: True + vnf_config: vpe_config runner: type: Iteration iterations: 10 diff --git a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_IMIX.yaml b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_IMIX.yaml index e237dca94..092f068c9 100644 --- a/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_IMIX.yaml +++ b/samples/vnf_samples/nsut/vpe/tc_baremetal_rfc2544_ipv4_1flow_IMIX.yaml @@ -34,8 +34,8 @@ scenarios: rfc2544: allowed_drop_rate: 0.0001 - 0.0001 vnf__1: - cfg: vpe_config nfvi_enable: True + vnf_config: vpe_config runner: type: Iteration iterations: 10 diff --git a/samples/vnf_samples/traffic_profiles/ipv4_throughput.yaml b/samples/vnf_samples/traffic_profiles/ipv4_throughput.yaml index 98624b108..6e0c693a5 100644 --- a/samples/vnf_samples/traffic_profiles/ipv4_throughput.yaml +++ b/samples/vnf_samples/traffic_profiles/ipv4_throughput.yaml @@ -61,14 +61,14 @@ private_1: outer_l3v4: proto: "udp" - srcip4: "{{get(flow, 'flow.src_ip0', '1.1.1.1-1.1.255.255') }}" - dstip4: "{{get(flow, 'flow.dst_ip0', '90.90.1.1-90.90.255.255') }}" + srcip4: "{{get(flow, 'flow.src_ip_0', '1.1.1.1-1.1.255.255') }}" + dstip4: "{{get(flow, 'flow.dst_ip_0', '90.90.1.1-90.90.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 0 outer_l4: - srcport: "{{get(flow, 'flow.src_port0', '1234-4321') }}" - dstport: "{{get(flow, 'flow.dst_port0', '2001-4001') }}" + srcport: "{{get(flow, 'flow.src_port_0', '1234-4321') }}" + dstport: "{{get(flow, 'flow.dst_port_0', '2001-4001') }}" count: "{{get(flow, 'flow.count', '1') }}" public_1: ipv4: @@ -86,12 +86,12 @@ public_1: outer_l3v4: proto: "udp" - srcip4: "{{get(flow, 'flow.dst_ip0', '90.90.1.1-90.90.255.255') }}" - dstip4: "{{get(flow, 'flow.src_ip0', '1.1.1.1-1.1.255.255') }}" + srcip4: "{{get(flow, 'flow.dst_ip_0', '90.90.1.1-90.90.255.255') }}" + dstip4: "{{get(flow, 'flow.src_ip_0', '1.1.1.1-1.1.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 0 outer_l4: - srcport: "{{get(flow, 'flow.dst_port0', '1234-4321') }}" - dstport: "{{get(flow, 'flow.src_port0', '2001-4001') }}" + srcport: "{{get(flow, 'flow.dst_port_0', '1234-4321') }}" + dstport: "{{get(flow, 'flow.src_port_0', '2001-4001') }}" count: "{{get(flow, 'flow.count', '1') }}" diff --git a/samples/vnf_samples/traffic_profiles/ipv4_throughput_cgnapt.yaml b/samples/vnf_samples/traffic_profiles/ipv4_throughput_cgnapt.yaml index 0758cf3a8..df04a93e5 100644 --- a/samples/vnf_samples/traffic_profiles/ipv4_throughput_cgnapt.yaml +++ b/samples/vnf_samples/traffic_profiles/ipv4_throughput_cgnapt.yaml @@ -61,14 +61,14 @@ private_1: outer_l3v4: proto: "udp" - srcip4: "{{get(flow, 'flow.src_ip0', '10.0.2.1-10.0.2.255') }}" - dstip4: "{{get(flow, 'flow.dst_ip0', '10.0.3.1-10.0.3.255') }}" + srcip4: "{{get(flow, 'flow.src_ip_0', '10.0.2.1-10.0.2.255') }}" + dstip4: "{{get(flow, 'flow.dst_ip_0', '10.0.3.1-10.0.3.255') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 0 outer_l4: - srcport: "{{get(flow, 'flow.src_port0', '1234-4321') }}" - dstport: "{{get(flow, 'flow.dst_port0', '2001-4001') }}" + srcport: "{{get(flow, 'flow.src_port_0', '1234-4321') }}" + dstport: "{{get(flow, 'flow.dst_port_0', '2001-4001') }}" count: "{{get(flow, 'flow.count', '1') }}" public_1: ipv4: @@ -86,12 +86,12 @@ public_1: outer_l3v4: proto: "udp" - srcip4: "{{get(flow, 'flow.dst_ip0', '10.0.3.1-10.0.3.255') }}" - dstip4: "{{get(flow, 'flow.public_ip0', '10.0.2.1-10.0.2.255') }}" + srcip4: "{{get(flow, 'flow.dst_ip_0', '10.0.3.1-10.0.3.255') }}" + dstip4: "{{get(flow, 'flow.public_ip_0', '10.0.2.1-10.0.2.255') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 0 outer_l4: - srcport: "{{get(flow, 'flow.dst_port0', '1234-4321') }}" - dstport: "{{get(flow, 'flow.src_port0', '2001-4001') }}" + srcport: "{{get(flow, 'flow.dst_port_0', '1234-4321') }}" + dstport: "{{get(flow, 'flow.src_port_0', '2001-4001') }}" count: "{{get(flow, 'flow.count', '1') }}" diff --git a/samples/vnf_samples/traffic_profiles/ipv4_throughput_vpe.yaml b/samples/vnf_samples/traffic_profiles/ipv4_throughput_vpe.yaml index 233457eba..da9bc40da 100644 --- a/samples/vnf_samples/traffic_profiles/ipv4_throughput_vpe.yaml +++ b/samples/vnf_samples/traffic_profiles/ipv4_throughput_vpe.yaml @@ -71,14 +71,16 @@ private_1: outer_l3v4: proto: "tcp" - srcip4: "{{get(flow, 'flow.src_ip0', '192.168.0.0-192.168.255.255') }}" - dstip4: "{{get(flow, 'flow.dst_ip0', '192.16.0.0-192.16.0.31') }}" + srcip4: "{{get(flow, 'flow.src_ip_0', '192.168.0.0-192.168.255.255') }}" + dstip4: "{{get(flow, 'flow.dst_ip_0', '192.16.0.0-192.16.0.31') }}" + count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 32 outer_l4: - srcport: "{{get(flow, 'flow.src_port0', '0') }}" - dstport: "{{get(flow, 'flow.dst_port0', '0') }}" + srcport: "{{get(flow, 'flow.src_port_0', '0') }}" + dstport: "{{get(flow, 'flow.dst_port_0', '0') }}" + count: "{{get(flow, 'flow.count', '1') }}" public_1: ipv4: outer_l2: @@ -93,14 +95,16 @@ public_1: outer_l3v4: proto: "tcp" - srcip4: "{{get(flow, 'flow.dst_ip0', '192.16.0.0-192.16.0.31') }}" - dstip4: "{{get(flow, 'flow.src_ip0', '192.168.0.0-192.168.255.255') }}" + srcip4: "{{get(flow, 'flow.dst_ip_0', '192.16.0.0-192.16.0.31') }}" + dstip4: "{{get(flow, 'flow.src_ip_0', '192.168.0.0-192.168.255.255') }}" + count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 32 outer_l4: - srcport: "{{get(flow, 'flow.dst_port0', '0') }}" - dstport: "{{get(flow, 'flow.src_port0', '0') }}" + srcport: "{{get(flow, 'flow.dst_port_0', '0') }}" + dstport: "{{get(flow, 'flow.src_port_0', '0') }}" + count: "{{get(flow, 'flow.count', '1') }}" private_2: ipv4: outer_l2: @@ -129,12 +133,14 @@ private_2: proto: "tcp" srcip4: "{{get(flow, 'flow.src_ip1', '192.168.0.0-192.168.255.255') }}" dstip4: "{{get(flow, 'flow.dst_ip1', '192.16.0.0-192.16.0.31') }}" + count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 32 outer_l4: srcport: "{{get(flow, 'flow.src_port1', '0') }}" dstport: "{{get(flow, 'flow.dst_port1', '0') }}" + count: "{{get(flow, 'flow.count', '1') }}" public_2: ipv4: outer_l2: @@ -151,9 +157,11 @@ public_2: proto: "tcp" srcip4: "{{get(flow, 'flow.dst_ip1', '192.16.0.0-192.16.0.31') }}" dstip4: "{{get(flow, 'flow.src_ip1', '192.168.0.0-192.168.255.255') }}" + count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 32 outer_l4: srcport: "{{get(flow, 'flow.dst_port1', '0') }}" dstport: "{{get(flow, 'flow.src_port1', '0') }}" + count: "{{get(flow, 'flow.count', '1') }}" diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml index c53b4fad4..a008eb353 100644 --- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml +++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml @@ -47,14 +47,14 @@ private_1: outer_l3v4: proto: "udp" - srcip4: "{{get(flow, 'flow.src_ip0', '1.1.1.1-1.15.255.255') }}" - dstip4: "{{get(flow, 'flow.dst_ip0', '90.90.1.1-90.105.255.255') }}" + srcip4: "{{get(flow, 'flow.src_ip_0', '1.1.1.1-1.15.255.255') }}" + dstip4: "{{get(flow, 'flow.dst_ip_0', '90.90.1.1-90.105.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 0 outer_l4: - srcport: "{{get(flow, 'flow.src_port0', '1234') }}" - dstport: "{{get(flow, 'flow.dst_port0', '2001') }}" + srcport: "{{get(flow, 'flow.src_port_0', '1234') }}" + dstport: "{{get(flow, 'flow.dst_port_0', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" public_1: ipv4: @@ -72,14 +72,14 @@ public_1: outer_l3v4: proto: "udp" - srcip4: "{{get(flow, 'flow.dst_ip0', '1.1.1.1-1.15.255.255') }}" - dstip4: "{{get(flow, 'flow.src_ip0', '90.90.1.1-90.105.255.255') }}" + srcip4: "{{get(flow, 'flow.dst_ip_0', '1.1.1.1-1.15.255.255') }}" + dstip4: "{{get(flow, 'flow.src_ip_0', '90.90.1.1-90.105.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 0 outer_l4: - srcport: "{{get(flow, 'flow.src_port0', '1234') }}" - dstport: "{{get(flow, 'flow.dst_port0', '2001') }}" + srcport: "{{get(flow, 'flow.src_port_0', '1234') }}" + dstport: "{{get(flow, 'flow.dst_port_0', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" private_2: ipv4: diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml index 7468dbdb1..7ca2f1043 100644 --- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml +++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml @@ -68,15 +68,15 @@ private_1: outer_l3v4: proto: "tcp" - srcip4: "{{get(flow, 'flow.src_ip0', '192.168.0.0-192.168.255.255') }}" - dstip4: "{{get(flow, 'flow.dst_ip0', '192.16.0.0-192.16.0.31') }}" + srcip4: "{{get(flow, 'flow.src_ip_0', '192.168.0.0-192.168.255.255') }}" + dstip4: "{{get(flow, 'flow.dst_ip_0', '192.16.0.0-192.16.0.31') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 32 outer_l4: - srcport: "{{get(flow, 'flow.src_port0', '0') }}" - dstport: "{{get(flow, 'flow.dst_port0', '0') }}" + srcport: "{{get(flow, 'flow.src_port_0', '0') }}" + dstport: "{{get(flow, 'flow.dst_port_0', '0') }}" count: "{{get(flow, 'flow.count', '1') }}" public_1: ipv4: @@ -92,15 +92,15 @@ public_1: outer_l3v4: proto: "tcp" - srcip4: "{{get(flow, 'flow.dst_ip0', '192.16.0.0-192.16.0.31') }}" - dstip4: "{{get(flow, 'flow.src_ip0', '192.168.0.0-192.168.255.255') }}" + srcip4: "{{get(flow, 'flow.dst_ip_0', '192.16.0.0-192.16.0.31') }}" + dstip4: "{{get(flow, 'flow.src_ip_0', '192.168.0.0-192.168.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" ttl: 32 dscp: 32 outer_l4: - srcport: "{{get(flow, 'flow.dst_port0', '0') }}" - dstport: "{{get(flow, 'flow.src_port0', '0') }}" + srcport: "{{get(flow, 'flow.dst_port_0', '0') }}" + dstport: "{{get(flow, 'flow.src_port_0', '0') }}" count: "{{get(flow, 'flow.count', '1') }}" private_2: ipv4: diff --git a/samples/vnf_samples/vnf_descriptors/acl_vnf.yaml b/samples/vnf_samples/vnf_descriptors/acl_vnf.yaml index b38e6b8ae..62188b84a 100644 --- a/samples/vnf_samples/vnf_descriptors/acl_vnf.yaml +++ b/samples/vnf_samples/vnf_descriptors/acl_vnf.yaml @@ -32,11 +32,6 @@ vnfd:vnfd-catalog: {% if key_filename is defined %} key_filename: '{{key_filename}}' # Value filled by vnfdgen {% endif %} - connection-point: - - name: xe0 - type: VPORT - - name: xe1 - type: VPORT vdu: - id: aclvnf-baremetal name: aclvnf-baremetal @@ -44,37 +39,6 @@ vnfd:vnfd-catalog: vm-flavor: vcpu-count: '4' memory-mb: '4096' - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe0.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe0.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe0.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe0.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 - - name: xe1 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe1.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe1.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe1.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe1.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe1.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe1.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe1.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe1.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe1.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe1 routing_table: {{ routing_table }} nd_route_tbl: {{ nd_route_tbl }} benchmark: diff --git a/samples/vnf_samples/vnf_descriptors/cgnapt_vnf.yaml b/samples/vnf_samples/vnf_descriptors/cgnapt_vnf.yaml index b42fb4d4e..da774cce5 100644 --- a/samples/vnf_samples/vnf_descriptors/cgnapt_vnf.yaml +++ b/samples/vnf_samples/vnf_descriptors/cgnapt_vnf.yaml @@ -34,42 +34,10 @@ vnfd:vnfd-catalog: {% if key_filename is defined %} key_filename: '{{key_filename}}' # Value filled by vnfdgen {% endif %} - connection-point: - - name: xe0 - type: VPORT - - name: xe1 - type: VPORT vdu: - id: cgnaptvnf-baremetal name: cgnaptvnf-baremetal description: CGNAPT approximation using DPDK - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe0.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe0.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 - - name: xe1 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe1.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe1.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe1.local_ip }}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe1.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe1.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe1.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe1.dst_mac }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe1 routing_table: {{ routing_table }} nd_route_tbl: {{ nd_route_tbl }} benchmark: diff --git a/samples/vnf_samples/vnf_descriptors/prox_vnf-1.yaml b/samples/vnf_samples/vnf_descriptors/prox_vnf-1.yaml index 76eaad8e1..3b3739fc5 100644 --- a/samples/vnf_samples/vnf_descriptors/prox_vnf-1.yaml +++ b/samples/vnf_samples/vnf_descriptors/prox_vnf-1.yaml @@ -42,22 +42,6 @@ vnfd:vnfd-catalog: vm-flavor: vcpu-count: '4' memory-mb: '4096' - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe0.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe0.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe0.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe0.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 routing_table: {{ routing_table }} nd_route_tbl: {{ nd_route_tbl }} benchmark: diff --git a/samples/vnf_samples/vnf_descriptors/prox_vnf-2.yaml b/samples/vnf_samples/vnf_descriptors/prox_vnf-2.yaml index b02690e74..75c16ba5a 100644 --- a/samples/vnf_samples/vnf_descriptors/prox_vnf-2.yaml +++ b/samples/vnf_samples/vnf_descriptors/prox_vnf-2.yaml @@ -44,37 +44,6 @@ vnfd:vnfd-catalog: vm-flavor: vcpu-count: '4' memory-mb: '4096' - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe0.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe0.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe0.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe0.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 - - name: xe1 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe1.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe1.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe1.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe1.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe1.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe1.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe1.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe1.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe1.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe1 routing_table: {{ routing_table }} nd_route_tbl: {{ nd_route_tbl }} benchmark: diff --git a/samples/vnf_samples/vnf_descriptors/prox_vnf-4.yaml b/samples/vnf_samples/vnf_descriptors/prox_vnf-4.yaml index 0f8aa55c2..75c16ba5a 100644 --- a/samples/vnf_samples/vnf_descriptors/prox_vnf-4.yaml +++ b/samples/vnf_samples/vnf_descriptors/prox_vnf-4.yaml @@ -44,67 +44,6 @@ vnfd:vnfd-catalog: vm-flavor: vcpu-count: '4' memory-mb: '4096' - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe0.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe0.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe0.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe0.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 - - name: xe1 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe1.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe1.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe1.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe1.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe1.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe1.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe1.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe1.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe1.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe1 - - name: xe2 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe2.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe2.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe2.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe2.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe2.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe2.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe2.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe2.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe2.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe2 - - name: xe3 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe3.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe3.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe3.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe3.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe3.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe3.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe3.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe3.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe3.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe3 routing_table: {{ routing_table }} nd_route_tbl: {{ nd_route_tbl }} benchmark: diff --git a/samples/vnf_samples/vnf_descriptors/tg_rfc2544_tpl.yaml b/samples/vnf_samples/vnf_descriptors/tg_rfc2544_tpl.yaml index dee3dd760..d94ddfe4c 100644 --- a/samples/vnf_samples/vnf_descriptors/tg_rfc2544_tpl.yaml +++ b/samples/vnf_samples/vnf_descriptors/tg_rfc2544_tpl.yaml @@ -32,41 +32,10 @@ vnfd:vnfd-catalog: {% if key_filename is defined %} key_filename: '{{key_filename}}' # Value filled by vnfdgen {% endif %} - connection-point: - - name: xe0 - type: VPORT - - name: xe1 - type: VPORT vdu: - id: trexgen-baremetal name: trexgen-baremetal description: TRex stateless traffic verifier - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - local_iface_name: '{{ interfaces.xe0.local_iface_name }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe0.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 - - name: xe1 - virtual-interface: - type: PCI-PASSTHROUGH - vpci: '{{ interfaces.xe1.vpci }}' # Value filled by vnfdgen - local_iface_name: '{{ interfaces.xe1.local_iface_name }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe1.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe1.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe1.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe1.local_mac }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe1.dst_mac }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe1 benchmark: kpi: diff --git a/samples/vnf_samples/vnf_descriptors/udp_replay_vnf.yaml b/samples/vnf_samples/vnf_descriptors/udp_replay_vnf.yaml index 33c07a6f4..659807d88 100644 --- a/samples/vnf_samples/vnf_descriptors/udp_replay_vnf.yaml +++ b/samples/vnf_samples/vnf_descriptors/udp_replay_vnf.yaml @@ -35,42 +35,10 @@ vnfd:vnfd-catalog: {% if key_filename is defined %} key_filename: '{{key_filename}}' # Value filled by vnfdgen {% endif %} - connection-point: - - name: xe0 - type: VPORT - - name: xe1 - type: VPORT vdu: - id: udp_replayvnf-baremetal name: udp_replayvnf-baremetal description: UdpReplayVnf approximation using DPDK - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe0.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe0.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 - - name: xe1 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe1.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe1.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe1.local_ip }}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe1.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe1.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe1.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe1.dst_mac }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe1 benchmark: kpi: - packets_in diff --git a/samples/vnf_samples/vnf_descriptors/vfw_vnf.yaml b/samples/vnf_samples/vnf_descriptors/vfw_vnf.yaml index 1c272e66d..035c7336e 100644 --- a/samples/vnf_samples/vnf_descriptors/vfw_vnf.yaml +++ b/samples/vnf_samples/vnf_descriptors/vfw_vnf.yaml @@ -32,11 +32,6 @@ vnfd:vnfd-catalog: {% if key_filename is defined %} key_filename: '{{key_filename}}' # Value filled by vnfdgen {% endif %} - connection-point: - - name: xe0 - type: VPORT - - name: xe1 - type: VPORT vdu: - id: aclvnf-baremetal name: aclvnf-baremetal @@ -44,37 +39,6 @@ vnfd:vnfd-catalog: vm-flavor: vcpu-count: '4' memory-mb: '4096' - external-interface: - - name: xe0 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe0.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe0.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe0.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe0.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe0.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe0.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe0.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe0.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe0.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe0 - - name: xe1 - virtual-interface: - type: PCI-PASSTHROUGH - # Substitution variables MUST be quoted. Otherwise Python can misinterpet them. - vpci: '{{ interfaces.xe1.vpci }}' # Value filled by vnfdgen - dpdk_port_num: '{{ interfaces.xe1.dpdk_port_num }}' # Value filled by vnfdgen - local_ip: '{{ interfaces.xe1.local_ip }}' # Value filled by vnfdgen - driver: '{{ interfaces.xe1.driver}}' # Value filled by vnfdgen - dst_ip: '{{ interfaces.xe1.dst_ip }}' # Value filled by vnfdgen - local_mac: '{{ interfaces.xe1.local_mac }}' # Value filled by vnfdgen - netmask: '{{ interfaces.xe1.netmask }}' # Value filled by vnfdgen - dst_mac: '{{ interfaces.xe1.dst_mac }}' # Value filled by vnfdgen - vld_id: '{{ interfaces.xe1.vld_id }}' # Value filled by vnfdgen - bandwidth: 10 Gbps - vnfd-connection-point-ref: xe1 routing_table: {{ routing_table }} nd_route_tbl: {{ nd_route_tbl }} benchmark: diff --git a/tests/unit/benchmark/contexts/test_heat.py b/tests/unit/benchmark/contexts/test_heat.py index 582d9ab99..d1b5855f9 100644 --- a/tests/unit/benchmark/contexts/test_heat.py +++ b/tests/unit/benchmark/contexts/test_heat.py @@ -182,11 +182,17 @@ class HeatContextTestCase(unittest.TestCase): u'd-mac_address': u'00:10', u'd-device_id': u'dev43', u'd-network_id': u'net987', + u'e': u'40.30.20.15', + u'e-subnet_id': 2, + u'e-mac_address': u'00:10', + u'e-device_id': u'dev43', + u'e-network_id': u'net987', } server = mock.MagicMock() server.ports = OrderedDict([ - ('a', {'stack_name': 'b', 'port': 'port_a'}), - ('c', {'stack_name': 'd', 'port': 'port_c'}), + ('a', [{'stack_name': 'b', 'port': 'port_a'}]), + ('c', [{'stack_name': 'd', 'port': 'port_c'}, + {'stack_name': 'e', 'port': 'port_f'}]), ]) expected = { @@ -205,7 +211,7 @@ class HeatContextTestCase(unittest.TestCase): } self.test_context.add_server_port(server) self.assertEqual(server.private_ip, '10.20.30.45') - self.assertEqual(len(server.interfaces), 2) + self.assertEqual(len(server.interfaces), 3) self.assertDictEqual(server.interfaces['port_a'], expected) @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate') diff --git a/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py b/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py index 58244b8f5..8aa9a8c8b 100644 --- a/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py +++ b/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py @@ -24,6 +24,8 @@ import errno import unittest import mock +from copy import deepcopy + from tests.unit import STL_MOCKS from yardstick.benchmark.scenarios.networking.vnf_generic import \ SshManager, NetworkServiceTestCase, IncorrectConfig, \ @@ -365,6 +367,24 @@ class TestNetworkServiceTestCase(unittest.TestCase): result = '152.16.100.2-152.16.100.254' self.assertEqual(result, self.s._get_ip_flow_range({"tg__1": 'xe0'})) + @mock.patch('yardstick.benchmark.scenarios.networking.vnf_generic.ipaddress') + def test__get_ip_flow_range_no_node_data(self, mock_ipaddress): + scenario_cfg = deepcopy(self.scenario_cfg) + scenario_cfg["traffic_options"]["flow"] = \ + self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") + + mock_ipaddress.ip_network.return_value = ipaddr = mock.Mock() + ipaddr.hosts.return_value = [] + + expected = '0.0.0.0' + result = self.s._get_ip_flow_range({"tg__2": 'xe0'}) + self.assertEqual(result, expected) + + def test__get_ip_flow_range_no_nodes(self): + expected = '0.0.0.0' + result = self.s._get_ip_flow_range({}) + self.assertEqual(result, expected) + def test___get_traffic_flow(self): self.scenario_cfg["traffic_options"]["flow"] = \ self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") @@ -653,12 +673,6 @@ class TestNetworkServiceTestCase(unittest.TestCase): res = NetworkServiceTestCase.parse_netdev_info(output) assert res == self.SAMPLE_VM_NETDEVS - def test_sort_dpdk_port_num(self): - netdevs = self.SAMPLE_NETDEVS.copy() - NetworkServiceTestCase._sort_dpdk_port_num(netdevs) - assert netdevs['lan']['dpdk_port_num'] == 0 - assert netdevs['enp11s0']['dpdk_port_num'] == 1 - def test_probe_missing_values(self): netdevs = self.SAMPLE_NETDEVS.copy() network = {'local_mac': '0a:de:ad:be:ef:f5'} diff --git a/tests/unit/network_services/helpers/test_dpdkbindnic_helper.py b/tests/unit/network_services/helpers/test_dpdkbindnic_helper.py new file mode 100644 index 000000000..dbd8396c8 --- /dev/null +++ b/tests/unit/network_services/helpers/test_dpdkbindnic_helper.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python + +# Copyright (c) 2016-2017 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. + +import mock +import unittest +from yardstick.network_services.helpers.dpdknicbind_helper import DpdkBindHelper +from yardstick.network_services.helpers.dpdknicbind_helper import DpdkBindHelperException +from yardstick.network_services.helpers.dpdknicbind_helper import NETWORK_KERNEL +from yardstick.network_services.helpers.dpdknicbind_helper import NETWORK_DPDK +from yardstick.network_services.helpers.dpdknicbind_helper import CRYPTO_KERNEL +from yardstick.network_services.helpers.dpdknicbind_helper import CRYPTO_DPDK +from yardstick.network_services.helpers.dpdknicbind_helper import NETWORK_OTHER +from yardstick.network_services.helpers.dpdknicbind_helper import CRYPTO_OTHER + +pass + + +class MyTestDpdkBindHelper(unittest.TestCase): + EXAMPLE_OUTPUT = """ + +Network devices using DPDK-compatible driver +============================================ +0000:00:04.0 'Virtio network device' drv=igb_uio unused= +0000:00:05.0 'Virtio network device' drv=igb_uio unused= + +Network devices using kernel driver +=================================== +0000:00:03.0 'Virtio network device' if=ens3 drv=virtio-pci unused=igb_uio *Active* + +Other network devices +===================== +<none> + +Crypto devices using DPDK-compatible driver +=========================================== +<none> + +Crypto devices using kernel driver +================================== +<none> + +Other crypto devices +==================== +<none> +""" + + PARSED_EXAMPLE = { + NETWORK_DPDK: [ + {'active': False, + 'dev_type': 'Virtio network device', + 'driver': 'igb_uio', + 'iface': None, + 'unused': '', + 'vpci': '0000:00:04.0', + }, + {'active': False, + 'dev_type': 'Virtio network device', + 'driver': 'igb_uio', + 'iface': None, + 'unused': '', + 'vpci': '0000:00:05.0', + } + ], + NETWORK_KERNEL: [ + {'active': True, + 'dev_type': 'Virtio network device', + 'driver': 'virtio-pci', + 'iface': 'ens3', + 'unused': 'igb_uio', + 'vpci': '0000:00:03.0', + } + ], + CRYPTO_KERNEL: [], + CRYPTO_DPDK: [], + NETWORK_OTHER: [], + CRYPTO_OTHER: [], + } + + CLEAN_STATUS = { + NETWORK_KERNEL: [], + NETWORK_DPDK: [], + CRYPTO_KERNEL: [], + CRYPTO_DPDK: [], + NETWORK_OTHER: [], + CRYPTO_OTHER: [], + } + + ONE_INPUT_LINE = ("0000:00:03.0 'Virtio network device' if=ens3 " + "drv=virtio-pci unused=igb_uio *Active*") + + ONE_INPUT_LINE_PARSED = [{ + 'vpci': '0000:00:03.0', + 'dev_type': 'Virtio network device', + 'iface': 'ens3', + 'driver': 'virtio-pci', + 'unused': 'igb_uio', + 'active': True, + }] + + def test___init__(self): + conn = mock.Mock() + conn.provision_tool = mock.Mock(return_value='path_to_tool') + + dpdk_bind_helper = DpdkBindHelper(conn) + + self.assertEquals(conn, dpdk_bind_helper.ssh_helper) + self.assertEquals(self.CLEAN_STATUS, dpdk_bind_helper.dpdk_status) + self.assertIsNone(dpdk_bind_helper.status_nic_row_re) + self.assertIsNone(dpdk_bind_helper._dpdk_nic_bind_attr) + self.assertIsNone(dpdk_bind_helper._status_cmd_attr) + + def test__dpdk_execute(self): + conn = mock.Mock() + conn.execute = mock.Mock(return_value=(0, 'output', 'error')) + conn.provision_tool = mock.Mock(return_value='tool_path') + dpdk_bind_helper = DpdkBindHelper(conn) + self.assertEquals((0, 'output', 'error'), dpdk_bind_helper._dpdk_execute('command')) + + def test__dpdk_execute_failure(self): + conn = mock.Mock() + conn.execute = mock.Mock(return_value=(1, 'output', 'error')) + conn.provision_tool = mock.Mock(return_value='tool_path') + dpdk_bind_helper = DpdkBindHelper(conn) + with self.assertRaises(DpdkBindHelperException): + dpdk_bind_helper._dpdk_execute('command') + + def test__addline(self): + conn = mock.Mock() + + dpdk_bind_helper = DpdkBindHelper(conn) + + dpdk_bind_helper._addline(NETWORK_KERNEL, self.ONE_INPUT_LINE) + + self.assertIsNotNone(dpdk_bind_helper.dpdk_status) + self.assertEquals(self.ONE_INPUT_LINE_PARSED, dpdk_bind_helper.dpdk_status[NETWORK_KERNEL]) + + def test__switch_active_dict_by_header(self): + line = "Crypto devices using DPDK-compatible driver" + olddict = 'olddict' + self.assertEqual(CRYPTO_DPDK, DpdkBindHelper._switch_active_dict(line, olddict)) + + def test__switch_active_dict_by_header_empty(self): + line = "<none>" + olddict = 'olddict' + self.assertEqual(olddict, DpdkBindHelper._switch_active_dict(line, olddict)) + + def test_parse_dpdk_status_output(self): + conn = mock.Mock() + + dpdk_bind_helper = DpdkBindHelper(conn) + + dpdk_bind_helper.parse_dpdk_status_output(self.EXAMPLE_OUTPUT) + + self.maxDiff = None + self.assertEquals(self.PARSED_EXAMPLE, dpdk_bind_helper.dpdk_status) + + def test_read_status(self): + conn = mock.Mock() + conn.execute = mock.Mock(return_value=(0, self.EXAMPLE_OUTPUT, '')) + conn.provision_tool = mock.Mock(return_value='path_to_tool') + + dpdk_bind_helper = DpdkBindHelper(conn) + + self.assertEquals(self.PARSED_EXAMPLE, dpdk_bind_helper.read_status()) + + def test__get_bound_pci_addresses(self): + conn = mock.Mock() + + dpdk_bind_helper = DpdkBindHelper(conn) + + dpdk_bind_helper.parse_dpdk_status_output(self.EXAMPLE_OUTPUT) + + self.assertEquals(['0000:00:04.0', '0000:00:05.0'], + dpdk_bind_helper._get_bound_pci_addresses(NETWORK_DPDK)) + self.assertEquals(['0000:00:03.0'], + dpdk_bind_helper._get_bound_pci_addresses(NETWORK_KERNEL)) + + def test_interface_driver_map(self): + conn = mock.Mock() + + dpdk_bind_helper = DpdkBindHelper(conn) + + dpdk_bind_helper.parse_dpdk_status_output(self.EXAMPLE_OUTPUT) + + self.assertEquals({'0000:00:04.0': 'igb_uio', + '0000:00:03.0': 'virtio-pci', + '0000:00:05.0': 'igb_uio', + }, + dpdk_bind_helper.interface_driver_map) + + def test_bind(self): + conn = mock.Mock() + conn.execute = mock.Mock(return_value=(0, '', '')) + conn.provision_tool = mock.Mock(return_value='/opt/nsb_bin/dpdk_nic_bind.py') + + dpdk_bind_helper = DpdkBindHelper(conn) + dpdk_bind_helper.read_status = mock.Mock() + + dpdk_bind_helper.bind(['0000:00:03.0', '0000:00:04.0'], 'my_driver') + + conn.execute.assert_called_with('sudo /opt/nsb_bin/dpdk_nic_bind.py --force ' + '-b my_driver 0000:00:03.0 0000:00:04.0') + dpdk_bind_helper.read_status.assert_called_once() + + def test_rebind_drivers(self): + conn = mock.Mock() + + dpdk_bind_helper = DpdkBindHelper(conn) + + dpdk_bind_helper.bind = mock.Mock() + dpdk_bind_helper.used_drivers = { + '0000:05:00.0': 'd1', + '0000:05:01.0': 'd3', + } + + dpdk_bind_helper.rebind_drivers() + + dpdk_bind_helper.bind.assert_any_call('0000:05:00.0', 'd1', True) + dpdk_bind_helper.bind.assert_any_call('0000:05:01.0', 'd3', True) + + def test_save_used_drivers(self): + conn = mock.Mock() + dpdk_bind_helper = DpdkBindHelper(conn) + dpdk_bind_helper.dpdk_status = self.PARSED_EXAMPLE + + dpdk_bind_helper.save_used_drivers() + + expected = { + '0000:00:04.0': 'igb_uio', + '0000:00:05.0': 'igb_uio', + '0000:00:03.0': 'virtio-pci', + } + + self.assertEqual(expected, dpdk_bind_helper.used_drivers) diff --git a/tests/unit/network_services/helpers/test_samplevnf_helper.py b/tests/unit/network_services/helpers/test_samplevnf_helper.py index 608f31747..3d3f6dc28 100644 --- a/tests/unit/network_services/helpers/test_samplevnf_helper.py +++ b/tests/unit/network_services/helpers/test_samplevnf_helper.py @@ -18,91 +18,152 @@ from __future__ import absolute_import from __future__ import division -import os import unittest import mock -from yardstick.network_services.helpers.samplevnf_helper import MultiPortConfig +from yardstick.network_services.helpers.samplevnf_helper import MultiPortConfig, PortPairs +from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper + + +class TestPortPairs(unittest.TestCase): + def test_port_pairs_list(self): + vnfd = TestMultiPortConfig.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + interfaces = vnfd['vdu'][0]['external-interface'] + port_pairs = PortPairs(interfaces) + self.assertEqual(port_pairs.port_pair_list, [("xe0", "xe1")]) + + def test_valid_networks(self): + vnfd = TestMultiPortConfig.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + interfaces = vnfd['vdu'][0]['external-interface'] + port_pairs = PortPairs(interfaces) + self.assertEqual(port_pairs.valid_networks, [("private_0", "public_0")]) + + def test_all_ports(self): + vnfd = TestMultiPortConfig.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + interfaces = vnfd['vdu'][0]['external-interface'] + port_pairs = PortPairs(interfaces) + self.assertEqual(set(port_pairs.all_ports), {"xe0", "xe1"}) + + def test_priv_ports(self): + vnfd = TestMultiPortConfig.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + interfaces = vnfd['vdu'][0]['external-interface'] + port_pairs = PortPairs(interfaces) + self.assertEqual(port_pairs.priv_ports, ["xe0"]) + + def test_pub_ports(self): + vnfd = TestMultiPortConfig.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + interfaces = vnfd['vdu'][0]['external-interface'] + port_pairs = PortPairs(interfaces) + self.assertEqual(port_pairs.pub_ports, ["xe1"]) class TestMultiPortConfig(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', - 'ifname': 'xe0', - 'local_iface_name': 'eth0', - 'local_mac': '00:00:00:00:00:02', - 'vld_id': 'private_1', - }, - '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', - 'ifname': 'xe1', - 'local_iface_name': 'eth1', - 'local_mac': '00:00:00:00:00:01', - 'vld_id': 'public_1', - }, - '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': 'AclApproxVnf', 'name': 'VPEVnfSsh'}]}} + + VNFD_0 = {'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', + 'ifname': 'xe0', + 'local_iface_name': 'eth0', + 'local_mac': '00:00:00:00:00:02', + 'vld_id': 'private_0', + }, + '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', + 'ifname': 'xe1', + 'local_iface_name': 'eth1', + 'local_mac': '00:00:00:00:00:01', + 'vld_id': 'public_0', + }, + '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': 'AclApproxVnf', 'name': 'VPEVnfSsh'} + + VNFD = { + 'vnfd:vnfd-catalog': { + 'vnfd': [ + VNFD_0, + ] + } + } + + def test_validate_ip_and_prefixlen(self): + ip_addr, prefix_len = MultiPortConfig.validate_ip_and_prefixlen('10.20.30.40', '16') + self.assertEqual(ip_addr, '10.20.30.40') + self.assertEqual(prefix_len, 16) + + ip_addr, prefix_len = MultiPortConfig.validate_ip_and_prefixlen('::1', '40') + self.assertEqual(ip_addr, '0000:0000:0000:0000:0000:0000:0000:0001') + self.assertEqual(prefix_len, 40) + + def test_validate_ip_and_prefixlen_negative(self): + with self.assertRaises(AttributeError): + MultiPortConfig.validate_ip_and_prefixlen('', '') + + with self.assertRaises(AttributeError): + MultiPortConfig.validate_ip_and_prefixlen('10.20.30.400', '16') + + with self.assertRaises(AttributeError): + MultiPortConfig.validate_ip_and_prefixlen('10.20.30.40', '33') + + with self.assertRaises(AttributeError): + MultiPortConfig.validate_ip_and_prefixlen('::1', '129') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.open') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.os') @@ -111,11 +172,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) self.assertEqual(0, opnfv_vnf.swq) mock_os.path = mock.MagicMock() mock_os.path.isfile = mock.Mock(return_value=False) - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) self.assertEqual(0, opnfv_vnf.swq) @mock.patch('yardstick.network_services.helpers.samplevnf_helper.open') @@ -125,7 +187,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -139,7 +202,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = VnfdHelper(self.VNFD_0) + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -148,7 +212,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] self.assertIsNotNone(opnfv_vnf.generate_script(self.VNFD)) opnfv_vnf.lb_config = 'HW' self.assertIsNotNone(opnfv_vnf.generate_script(self.VNFD)) @@ -160,12 +224,13 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 opnfv_vnf.update_write_parser = mock.MagicMock() - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.vnf_type = 'ACL' opnfv_vnf.generate_link_config = mock.Mock() opnfv_vnf.generate_arp_config = mock.Mock() @@ -181,7 +246,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -190,7 +256,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'ACL' opnfv_vnf.get_ports_gateway = mock.Mock(return_value=u'1.1.1.1') @@ -212,7 +278,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -221,7 +288,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.get_ports_gateway = mock.Mock(return_value=u'1.1.1.1') @@ -239,7 +306,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -248,7 +316,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.get_ports_gateway = mock.Mock(return_value=u'1.1.1.1') @@ -268,7 +336,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -277,7 +346,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.get_ports_gateway = mock.Mock(return_value=u'1.1.1.1') @@ -297,7 +366,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -306,7 +376,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.txrx_pipeline = '' @@ -323,7 +393,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -332,7 +403,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.txrx_pipeline = '' @@ -349,7 +420,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -358,7 +430,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.txrx_pipeline = '' @@ -375,7 +447,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -384,7 +457,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.txrx_pipeline = '' @@ -401,7 +474,9 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -410,7 +485,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.get_port_pairs = mock.Mock() opnfv_vnf.vnf_type = 'VFW' opnfv_vnf.txrx_pipeline = '' @@ -418,7 +493,11 @@ class TestMultiPortConfig(unittest.TestCase): opnfv_vnf.get_ports_gateway6 = mock.Mock() opnfv_vnf.vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] opnfv_vnf.interfaces = opnfv_vnf.vnfd['vdu'][0]['external-interface'] - self.assertIsNotNone(opnfv_vnf.generate_link_config()) + opnfv_vnf.all_ports = ['32', '1', '987'] + opnfv_vnf.validate_ip_and_prefixlen = mock.Mock(return_value=('10.20.30.40', 16)) + + result = opnfv_vnf.generate_link_config() + self.assertEqual(len(result.splitlines()), 9) @mock.patch('yardstick.network_services.helpers.samplevnf_helper.open') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.os') @@ -427,7 +506,8 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.get_config_tpl_data = mock.MagicMock() opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 @@ -436,7 +516,7 @@ class TestMultiPortConfig(unittest.TestCase): mock.Mock(return_value={'link_config': 0, 'arp_config': '', 'arp_config6': '', 'actions': '', 'rules': ''}) - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.get_ports_gateway6 = mock.Mock() @@ -459,10 +539,11 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -482,10 +563,11 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -505,10 +587,11 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -533,10 +616,11 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -556,10 +640,11 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -581,10 +666,11 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -614,10 +700,11 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -649,10 +736,10 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = VnfdHelper(self.VNFD_0) + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -666,10 +753,12 @@ class TestMultiPortConfig(unittest.TestCase): opnfv_vnf.worker_config = '1t' opnfv_vnf.start_core = 0 opnfv_vnf.lb_count = 1 + opnfv_vnf._port_pairs = PortPairs(vnfd_mock.interfaces) + opnfv_vnf.port_pair_list = opnfv_vnf._port_pairs.port_pair_list result = opnfv_vnf.generate_lb_to_port_pair_mapping() self.assertEqual(None, result) result = opnfv_vnf.set_priv_to_pub_mapping() - self.assertEqual('(0, 1)', result) + self.assertEqual('(0,1)', result) @mock.patch('yardstick.network_services.helpers.samplevnf_helper.open') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.os') @@ -680,11 +769,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = VnfdHelper(self.VNFD_0) + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -702,6 +792,43 @@ class TestMultiPortConfig(unittest.TestCase): self.assertEqual(None, result) @mock.patch('yardstick.network_services.helpers.samplevnf_helper.open') + @mock.patch('yardstick.network_services.helpers.samplevnf_helper.ConfigParser') + def test_generate_arp_route_tbl(self, *_): + topology_file = mock.Mock() + config_tpl = mock.Mock() + tmp_file = mock.Mock() + vnfd_mock = mock.MagicMock() + vnfd_mock.port_num.side_effect = ['32', '1', '987'] + vnfd_mock.find_interface.side_effect = [ + { + 'virtual-interface': { + 'dst_ip': '10.20.30.40', + 'netmask': '20', + }, + }, + { + 'virtual-interface': { + 'dst_ip': '10.200.30.40', + 'netmask': '24', + }, + }, + { + 'virtual-interface': { + 'dst_ip': '10.20.3.40', + 'netmask': '8', + }, + }, + ] + + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) + opnfv_vnf.all_ports = [3, 2, 5] + + expected = '(0a141000,fffff000,32,0a141e28) (0ac81e00,ffffff00,1,0ac81e28) ' \ + '(0a000000,ff000000,987,0a140328)' + result = opnfv_vnf.generate_arp_route_tbl() + self.assertEqual(result, expected) + + @mock.patch('yardstick.network_services.helpers.samplevnf_helper.open') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.os') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.ConfigParser') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.OrderedDict') @@ -710,11 +837,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -754,11 +882,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -795,11 +924,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -848,11 +978,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -884,11 +1015,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -932,11 +1064,12 @@ class TestMultiPortConfig(unittest.TestCase): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = VnfdHelper(self.VNFD_0) + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() @@ -982,7 +1115,7 @@ class TestMultiPortConfig(unittest.TestCase): opnfv_vnf.loadb_tpl = mock.MagicMock() opnfv_vnf.vnf_type = 'CGNAPT' opnfv_vnf.update_timer = mock.Mock() - opnfv_vnf.port_pair_list = [[[0], [1], [2]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1"), ("xe0", "xe2")] opnfv_vnf.lb_to_port_pair_mapping = [0, 1] opnfv_vnf.generate_arpicmp_data = mock.Mock() result = opnfv_vnf.generate_config_data() @@ -992,66 +1125,17 @@ class TestMultiPortConfig(unittest.TestCase): @mock.patch('yardstick.network_services.helpers.samplevnf_helper.os') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.ConfigParser') @mock.patch('yardstick.network_services.helpers.samplevnf_helper.OrderedDict') - def test_get_port_pairs(self, mock_open, mock_os, ConfigParser, - OrderedDict): - topology_file = mock.Mock() - config_tpl = mock.Mock() - tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) - opnfv_vnf.socket = 0 - opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] - opnfv_vnf.txrx_pipeline = '' - opnfv_vnf.rules = '' - opnfv_vnf.write_parser = mock.MagicMock() - opnfv_vnf.read_parser = mock.MagicMock() - opnfv_vnf.read_parser.sections = mock.Mock(return_value=['MASTER']) - opnfv_vnf.read_parser.has_option = mock.Mock(return_value=[]) - opnfv_vnf.write_parser.set = mock.Mock() - opnfv_vnf.write_parser.add_section = mock.Mock() - opnfv_vnf.read_parser.items = mock.MagicMock() - opnfv_vnf.pipeline_counter = 0 - opnfv_vnf.worker_config = '1t' - opnfv_vnf.start_core = 0 - opnfv_vnf.lb_count = 1 - opnfv_vnf.vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - opnfv_vnf.interfaces = opnfv_vnf.vnfd['vdu'][0]['external-interface'] - opnfv_vnf.lb_to_port_pair_mapping = [0, 1] - opnfv_vnf.lb_index = 1 - opnfv_vnf.ports_len = 1 - opnfv_vnf.pktq_out = ['1', '2'] - opnfv_vnf.prv_que_handler = 0 - opnfv_vnf.init_write_parser_template = mock.Mock() - opnfv_vnf.arpicmp_tpl = mock.MagicMock() - opnfv_vnf.txrx_tpl = mock.MagicMock() - opnfv_vnf.loadb_tpl = mock.MagicMock() - opnfv_vnf.vnf_tpl = {'public_ip_port_range': '98164810 (1,65535)', - 'vnf_set': '(2,4,5)'} - opnfv_vnf.generate_vnf_data = mock.Mock(return_value={}) - opnfv_vnf.update_write_parser = mock.Mock() - - curr_path = os.path.dirname(os.path.abspath(__file__)) - opnfv_vnf.topology_file = \ - os.path.join(curr_path, 'acl_vnf_topology_ixia.yaml') - opnfv_vnf.lb_count = 10 - result = opnfv_vnf.get_port_pairs(opnfv_vnf.interfaces) - self.assertEqual(result[0], [('xe0', 'xe1')]) - - @mock.patch('yardstick.network_services.helpers.samplevnf_helper.open') - @mock.patch('yardstick.network_services.helpers.samplevnf_helper.os') - @mock.patch('yardstick.network_services.helpers.samplevnf_helper.ConfigParser') - @mock.patch('yardstick.network_services.helpers.samplevnf_helper.OrderedDict') def test_init_eal(self, mock_open, mock_os, ConfigParser, OrderedDict): topology_file = mock.Mock() config_tpl = mock.Mock() tmp_file = mock.Mock() - opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file) + vnfd_mock = mock.MagicMock() + opnfv_vnf = MultiPortConfig(topology_file, config_tpl, tmp_file, vnfd_mock) opnfv_vnf.socket = 0 opnfv_vnf.start_core = 0 - opnfv_vnf.port_pair_list = [[[0], [1]]] - opnfv_vnf.port_pairs = [[[0], [1]]] + opnfv_vnf.port_pair_list = [("xe0", "xe1")] + opnfv_vnf.port_pairs = [("xe0", "xe1")] opnfv_vnf.txrx_pipeline = '' opnfv_vnf.rules = '' opnfv_vnf.write_parser = mock.MagicMock() diff --git a/tests/unit/network_services/libs/ixia_libs/test_IxNet.py b/tests/unit/network_services/libs/ixia_libs/test_IxNet.py index 7fe83406a..ea2f9c3d9 100644 --- a/tests/unit/network_services/libs/ixia_libs/test_IxNet.py +++ b/tests/unit/network_services/libs/ixia_libs/test_IxNet.py @@ -268,7 +268,7 @@ class TestIxNextgen(unittest.TestCase): def test_add_ip_header_v4(self): static_traffic_params = { - "private_1": { + "private_0": { "id": 1, "bidir": "False", "duration": 60, @@ -308,7 +308,7 @@ class TestIxNextgen(unittest.TestCase): }, "traffic_type": "continuous" }, - "public_1": { + "public_0": { "id": 2, "bidir": "False", "duration": 60, @@ -366,7 +366,7 @@ class TestIxNextgen(unittest.TestCase): def test_add_ip_header_v4_nothing_to_do(self): static_traffic_params = { - "private_1": { + "private_0": { "id": 1, "bidir": "False", "duration": 60, @@ -406,7 +406,7 @@ class TestIxNextgen(unittest.TestCase): }, "traffic_type": "continuous" }, - "public_1": { + "public_0": { "id": 2, "bidir": "False", "duration": 60, @@ -464,7 +464,7 @@ class TestIxNextgen(unittest.TestCase): def test_add_ip_header_v6(self): static_traffic_profile = { - "private_1": { + "private_0": { "id": 1, "bidir": "False", "duration": 60, @@ -497,7 +497,7 @@ class TestIxNextgen(unittest.TestCase): }, "traffic_type": "continuous" }, - "public_1": { + "public_0": { "id": 2, "bidir": "False", "duration": 60, @@ -547,7 +547,7 @@ class TestIxNextgen(unittest.TestCase): def test_add_ip_header_v6_nothing_to_do(self): static_traffic_params = { - "private_1": { + "private_0": { "id": 1, "bidir": "False", "duration": 60, @@ -579,7 +579,7 @@ class TestIxNextgen(unittest.TestCase): }, "traffic_type": "continuous" }, - "public_1": { + "public_0": { "id": 2, "bidir": "False", "duration": 60, @@ -684,7 +684,7 @@ class TestIxNextgen(unittest.TestCase): def test_ix_update_ether(self): static_traffic_params = { - "private_1": { + "private_0": { "id": 1, "bidir": "False", "duration": 60, @@ -723,7 +723,7 @@ class TestIxNextgen(unittest.TestCase): }, "traffic_type": "continuous" }, - "public_1": { + "public_0": { "id": 2, "bidir": "False", "duration": 60, @@ -787,7 +787,7 @@ class TestIxNextgen(unittest.TestCase): def test_ix_update_ether_nothing_to_do(self): static_traffic_params = { - "private_1": { + "private_0": { "id": 1, "bidir": "False", "duration": 60, @@ -820,7 +820,7 @@ class TestIxNextgen(unittest.TestCase): }, "traffic_type": "continuous" }, - "public_1": { + "public_0": { "id": 2, "bidir": "False", "duration": 60, diff --git a/tests/unit/network_services/nfvi/test_resource.py b/tests/unit/network_services/nfvi/test_resource.py index 21beba882..1c2c1f3e2 100644 --- a/tests/unit/network_services/nfvi/test_resource.py +++ b/tests/unit/network_services/nfvi/test_resource.py @@ -54,7 +54,7 @@ class TestResourceProfile(unittest.TestCase): 'local_ip': '172.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '172.16.100.20', 'local_mac': '3c:fd:fe:a1:2b:80'}, @@ -66,7 +66,7 @@ class TestResourceProfile(unittest.TestCase): 'local_ip': '172.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '172.16.40.20', 'local_mac': '3c:fd:fe:a1:2b:81'}, diff --git a/tests/unit/network_services/traffic_profile/test_base.py b/tests/unit/network_services/traffic_profile/test_base.py index 72b097b52..290610361 100644 --- a/tests/unit/network_services/traffic_profile/test_base.py +++ b/tests/unit/network_services/traffic_profile/test_base.py @@ -48,7 +48,7 @@ class TestTrafficProfile(unittest.TestCase): def test_execute(self): traffic_profile = TrafficProfile(self.TRAFFIC_PROFILE) - self.assertRaises(NotImplementedError, traffic_profile.execute, {}) + self.assertRaises(NotImplementedError, traffic_profile.execute_traffic, {}) def test_get(self): traffic_profile = TrafficProfile(self.TRAFFIC_PROFILE) diff --git a/tests/unit/network_services/traffic_profile/test_fixed.py b/tests/unit/network_services/traffic_profile/test_fixed.py index 84843178e..eb182a2fb 100644 --- a/tests/unit/network_services/traffic_profile/test_fixed.py +++ b/tests/unit/network_services/traffic_profile/test_fixed.py @@ -74,7 +74,7 @@ class TestFixedProfile(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', 'local_mac': '00:00:00:00:00:01'}, @@ -86,7 +86,7 @@ class TestFixedProfile(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_mac': '00:00:00:00:00:02'}, diff --git a/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py b/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py index 846bfa307..656623624 100644 --- a/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py +++ b/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py @@ -20,6 +20,8 @@ from __future__ import division import unittest import mock +from copy import deepcopy + from tests.unit import STL_MOCKS STLClient = mock.MagicMock() @@ -35,6 +37,7 @@ if stl_patch: class TestIXIARFC2544Profile(unittest.TestCase): + TRAFFIC_PROFILE = { "schema": "isb:traffic_profile:0.1", "name": "fixed", @@ -43,7 +46,9 @@ class TestIXIARFC2544Profile(unittest.TestCase): "traffic_type": "FixedTraffic", "frame_rate": 100, # pps "flow_number": 10, - "frame_size": 64}} + "frame_size": 64, + }, + } PROFILE = {'description': 'Traffic profile to run RFC2544 latency', 'name': 'rfc2544', @@ -178,7 +183,6 @@ class TestIXIARFC2544Profile(unittest.TestCase): self.PROFILE, mac, xfile="tmp", static_traffic=STATIC_TRAFFIC) - @mock.patch("yardstick.network_services.traffic_profile.ixia_rfc2544.open") def test_get_ixia_traffic_profile(self, mock_open): traffic_generator = mock.Mock(autospec=TrexProfile) @@ -435,11 +439,19 @@ class TestIXIARFC2544Profile(unittest.TestCase): profile_data, mac, static_traffic=STATIC_TRAFFIC) self.assertIsNotNone(result) + def test__get_ixia_traffic_profile_default_args(self): + r_f_c2544_profile = IXIARFC2544Profile(self.TRAFFIC_PROFILE) + + expected = {} + result = r_f_c2544_profile._get_ixia_traffic_profile({}) + self.assertDictEqual(result, expected) + def test__ixia_traffic_generate(self): traffic_generator = mock.Mock(autospec=TrexProfile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [-1] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = \ mock.Mock(return_value=True) traffic = {"public": {'iload': 10}, @@ -451,12 +463,12 @@ class TestIXIARFC2544Profile(unittest.TestCase): traffic, ixia_obj) self.assertIsNone(result) - def test_execute(self): traffic_generator = mock.Mock(autospec=TrexProfile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [-1] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = \ mock.Mock(return_value=True) r_f_c2544_profile = IXIARFC2544Profile(self.TRAFFIC_PROFILE) @@ -470,14 +482,40 @@ class TestIXIARFC2544Profile(unittest.TestCase): r_f_c2544_profile.get_multiplier = mock.Mock() r_f_c2544_profile._ixia_traffic_generate = mock.Mock() ixia_obj = mock.MagicMock() - self.assertEqual(None, r_f_c2544_profile.execute(traffic_generator, - ixia_obj)) + self.assertEqual(None, r_f_c2544_profile.execute_traffic(traffic_generator, ixia_obj)) + + def test_update_traffic_profile(self): + traffic_generator = mock.Mock(autospec=TrexProfile) + traffic_generator.networks = { + "private_0": ["xe0"], # private, one value for intfs + "public_0": ["xe1", "xe2"], # public, two values for intfs + "public_1": ["xe3"], # not in TRAFFIC PROFILE + "tenant_0": ["xe4"], # not public or private + } + + ports_expected = [8, 3, 5] + traffic_generator.vnfd_helper.port_num.side_effect = ports_expected + traffic_generator.client.return_value = True + + traffic_profile = deepcopy(self.TRAFFIC_PROFILE) + traffic_profile.update({ + "private_0": ["xe0"], + "public_0": ["xe1", "xe2"], + }) + + r_f_c2544_profile = IXIARFC2544Profile(traffic_profile) + r_f_c2544_profile.full_profile = {} + r_f_c2544_profile.get_streams = mock.Mock() + + self.assertIsNone(r_f_c2544_profile.update_traffic_profile(traffic_generator)) + self.assertEqual(r_f_c2544_profile.ports, ports_expected) def test_get_drop_percentage(self): traffic_generator = mock.Mock(autospec=TrexProfile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [0] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = \ mock.Mock(return_value=True) r_f_c2544_profile = IXIARFC2544Profile(self.TRAFFIC_PROFILE) @@ -584,9 +622,10 @@ class TestIXIARFC2544Profile(unittest.TestCase): def test_start_ixia_latency(self): traffic_generator = mock.Mock(autospec=TrexProfile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [0] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = \ mock.Mock(return_value=True) r_f_c2544_profile = IXIARFC2544Profile(self.TRAFFIC_PROFILE) diff --git a/tests/unit/network_services/traffic_profile/test_rfc2544.py b/tests/unit/network_services/traffic_profile/test_rfc2544.py index aef0b93de..b63a805f3 100644 --- a/tests/unit/network_services/traffic_profile/test_rfc2544.py +++ b/tests/unit/network_services/traffic_profile/test_rfc2544.py @@ -50,7 +50,7 @@ class TestRFC2544Profile(unittest.TestCase): 'name': 'rfc2544', 'traffic_profile': {'traffic_type': 'RFC2544Profile', 'frame_rate': 100}, - 'public_1': {'ipv4': + 'public_0': {'ipv4': {'outer_l2': {'framesize': {'64B': '100', '1518B': '0', '128B': '0', '1400B': '0', @@ -62,7 +62,7 @@ class TestRFC2544Profile(unittest.TestCase): 'dscp': 0, 'ttl': 32, 'count': 1}, 'outer_l4': {'srcport': '2001', 'dsrport': '1234', 'count': 1}}}, - 'private_1': {'ipv4': + 'private_0': {'ipv4': {'outer_l2': {'framesize': {'64B': '100', '1518B': '0', '128B': '0', '1400B': '0', @@ -82,27 +82,29 @@ class TestRFC2544Profile(unittest.TestCase): def test_execute(self): traffic_generator = mock.Mock(autospec=TrexProfile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [-1] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = \ mock.Mock(return_value=True) r_f_c2544_profile = RFC2544Profile(self.TRAFFIC_PROFILE) r_f_c2544_profile.params = self.PROFILE r_f_c2544_profile.first_run = True - self.assertEqual(None, r_f_c2544_profile.execute(traffic_generator)) + self.assertEqual(None, r_f_c2544_profile.execute_traffic(traffic_generator)) def test_get_drop_percentage(self): traffic_generator = mock.Mock(autospec=TrexProfile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [0] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = mock.Mock(return_value=True) r_f_c2544_profile = RFC2544Profile(self.TRAFFIC_PROFILE) r_f_c2544_profile.params = self.PROFILE r_f_c2544_profile.register_generator(traffic_generator) - self.assertIsNone(r_f_c2544_profile.execute(traffic_generator)) + self.assertIsNone(r_f_c2544_profile.execute_traffic(traffic_generator)) samples = {} for ifname in range(1): @@ -140,15 +142,16 @@ class TestRFC2544Profile(unittest.TestCase): def test_get_drop_percentage_update(self): traffic_generator = mock.Mock(autospec=RFC2544Profile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [0] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = mock.Mock(return_value=True) r_f_c2544_profile = RFC2544Profile(self.TRAFFIC_PROFILE) r_f_c2544_profile.params = self.PROFILE r_f_c2544_profile.register_generator(traffic_generator) - self.assertIsNone(r_f_c2544_profile.execute()) + self.assertIsNone(r_f_c2544_profile.execute_traffic()) samples = {} for ifname in range(1): @@ -187,14 +190,15 @@ class TestRFC2544Profile(unittest.TestCase): def test_get_drop_percentage_div_zero(self): traffic_generator = mock.Mock(autospec=TrexProfile) - traffic_generator.my_ports = [0, 1] - traffic_generator.priv_ports = [0] - traffic_generator.pub_ports = [1] + traffic_generator.networks = { + "private_0": ["xe0"], + "public_0": ["xe1"], + } traffic_generator.client = \ mock.Mock(return_value=True) r_f_c2544_profile = RFC2544Profile(self.TRAFFIC_PROFILE) r_f_c2544_profile.params = self.PROFILE - self.assertEqual(None, r_f_c2544_profile.execute(traffic_generator)) + self.assertEqual(None, r_f_c2544_profile.execute_traffic(traffic_generator)) samples = {} for ifname in range(1): name = "xe{}".format(ifname) diff --git a/tests/unit/network_services/traffic_profile/test_traffic_profile.py b/tests/unit/network_services/traffic_profile/test_traffic_profile.py index 55e7d483a..e0b0ce85c 100644 --- a/tests/unit/network_services/traffic_profile/test_traffic_profile.py +++ b/tests/unit/network_services/traffic_profile/test_traffic_profile.py @@ -136,11 +136,6 @@ class TestTrexProfile(unittest.TestCase): TrexProfile(TrafficProfile) self.assertEqual(trex_profile.pps, 100) - def test_execute(self): - trex_profile = \ - TrexProfile(TrafficProfile) - self.assertEqual(None, trex_profile.execute({})) - def test_qinq(self): qinq = {"S-VLAN": {"id": 128, "priority": 0, "cfi": 0}, "C-VLAN": {"id": 512, "priority": 0, "cfi": 0}} @@ -239,7 +234,7 @@ class TestTrexProfile(unittest.TestCase): 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' + 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) @@ -249,6 +244,3 @@ class TestTrexProfile(unittest.TestCase): 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") - - - diff --git a/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py index 2e83353cd..f47da3729 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py @@ -75,7 +75,7 @@ class TestAclApproxVnf(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': '152.16.100.20', @@ -90,7 +90,7 @@ class TestAclApproxVnf(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', diff --git a/tests/unit/network_services/vnf_generic/vnf/test_base.py b/tests/unit/network_services/vnf_generic/vnf/test_base.py index e1c69e7b3..478ce186b 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_base.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_base.py @@ -150,7 +150,7 @@ class TestGenericVNF(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', 'local_mac': '00:00:00:00:00:01' @@ -165,7 +165,7 @@ class TestGenericVNF(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_mac': '00:00:00:00:00:02' diff --git a/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py index e5503697a..c21beabfc 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py @@ -21,6 +21,8 @@ import os import unittest import mock +from copy import deepcopy + from tests.unit import STL_MOCKS from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh @@ -66,15 +68,22 @@ link 1 up """ header = "This is a header" - out = CgnaptApproxSetupEnvHelper._update_cgnat_script_file(header, sample.splitlines(), "") + out = CgnaptApproxSetupEnvHelper._update_cgnat_script_file(header, sample.splitlines()) self.assertNotIn("This is a header", out) - def test__get_cgnapt_confgi(self): + def test__get_cgnapt_config(self): + vnfd_helper = mock.Mock() + vnfd_helper.port_pairs.priv_ports = [{"name": 'a'}, {"name": "b"}, {"name": "c"}] + + helper = CgnaptApproxSetupEnvHelper(vnfd_helper, mock.Mock(), mock.Mock()) + helper._get_ports_gateway = mock.Mock(side_effect=[3, 5, 2]) + result = helper._get_cgnapt_config([{"name": 'a'}, {}, {"name": "b"}, {}, {"name": "c"}]) + self.assertEqual(result, [3, 5, 2]) - c = CgnaptApproxSetupEnvHelper(mock.MagicMock(), mock.MagicMock(), mock.MagicMock()) - c._get_ports_gateway = mock.Mock(return_value=3) - ret = c._get_cgnapt_config([{"name": 'a'}, {}, {"name": "b"}, {}, {"name": "c"}]) - self.assertEqual(ret, [3, 3, 3]) + def test_scale(self): + helper = CgnaptApproxSetupEnvHelper(mock.Mock(), mock.Mock(), mock.Mock()) + with self.assertRaises(NotImplementedError): + helper.scale() @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Process") @@ -111,7 +120,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': '152.16.100.20', @@ -126,7 +135,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', @@ -146,31 +155,48 @@ class TestCgnaptApproxVnf(unittest.TestCase): {'type': 'VPORT', 'name': 'xe1'}], 'id': 'CgnaptApproxVnf', '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', - 'task_path': '/tmp', - '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'} + SCENARIO_CFG = { + 'options': { + 'packetsize': 64, + 'traffic_type': 4, + 'rfc2544': { + 'allowed_drop_rate': '0.8 - 1', + }, + 'vnf__1': { + 'napt': 'dynamic', + 'vnf_config': { + 'lb_config': 'SW', + 'lb_count': 1, + 'worker_config': + '1C/1T', + 'worker_threads': 1, + }, + }, + }, + 'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7', + 'task_path': '/tmp', + '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': {'tg__2': {'member-vnf-index': '3', @@ -277,14 +303,16 @@ class TestCgnaptApproxVnf(unittest.TestCase): 'password': 'r00t', 'VNF model': 'cgnapt_vnf.yaml'}}} + def setUp(self): + self.scenario_cfg = deepcopy(self.SCENARIO_CFG) + def test___init__(self, mock_process): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd) self.assertIsNone(cgnapt_approx_vnf._vnf_process) - @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_collect_kpi(self, ssh, mock_time, mock_process): + def test_collect_kpi(self, ssh, mock_process): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -296,9 +324,8 @@ class TestCgnaptApproxVnf(unittest.TestCase): result = {'packets_dropped': 0, 'packets_fwd': 0, 'packets_in': 0} self.assertEqual(result, cgnapt_approx_vnf.collect_kpi()) - @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_vnf_execute_command(self, ssh, mock_time, mock_process): + def test_vnf_execute_command(self, ssh, mock_process): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -386,9 +413,24 @@ class TestCgnaptApproxVnf(unittest.TestCase): self.assertEqual(None, cgnapt_approx_vnf.terminate()) @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") - @mock.patch("yardstick.network_services.vnf_generic.vnf.cgnapt_vnf.time") @mock.patch(SSH_HELPER) - def test__vnf_up_post(self, ssh, mock_time, mock_cgnapt_time, mock_process): + def test__vnf_up_post(self, ssh, mock_time, mock_process): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + self.scenario_cfg['options'][name]['napt'] = 'static' + + cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd) + cgnapt_approx_vnf._vnf_process = mock.MagicMock() + cgnapt_approx_vnf._vnf_process.terminate = mock.Mock() + cgnapt_approx_vnf.vnf_execute = mock.MagicMock() + cgnapt_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg + cgnapt_approx_vnf._resource_collect_stop = mock.Mock() + cgnapt_approx_vnf._vnf_up_post() + + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") + @mock.patch(SSH_HELPER) + def test__vnf_up_post_short(self, ssh, mock_time, mock_process): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -399,7 +441,6 @@ class TestCgnaptApproxVnf(unittest.TestCase): cgnapt_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg cgnapt_approx_vnf._resource_collect_stop = mock.Mock() cgnapt_approx_vnf._vnf_up_post() - cgnapt_approx_vnf.vnf_execute.assert_called_once() if __name__ == '__main__': diff --git a/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py b/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py index cba3d449f..821c10f64 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py @@ -17,6 +17,7 @@ from __future__ import absolute_import +import copy import os import socket import unittest @@ -25,6 +26,7 @@ from contextlib import contextmanager import mock from tests.unit import STL_MOCKS +from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper STLClient = mock.MagicMock() stl_patch = mock.patch.dict("sys.modules", STL_MOCKS) @@ -634,6 +636,111 @@ class TestProxSocketHelper(unittest.TestCase): class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): + + VNFD0 = { + 'short-name': 'ProxVnf', + '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': 'PROX approximation using DPDK', + 'name': 'proxvnf-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': 'proxvnf-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', + 'vld_id': 'private_0', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'driver': "i40e", + 'dst_ip': '152.16.100.19', + 'local_iface_name': 'xe0', + 'local_mac': '00:00:00:00:00:02', + 'ifname': 'xe0', + }, + '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', + 'vld_id': 'public_0', + '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', + 'ifname': 'xe1', + }, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1', + }, + ], + }, + ], + 'description': 'PROX approximation using DPDK', + 'mgmt-interface': { + 'vdu-id': 'proxvnf-baremetal', + 'host': '1.2.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.2.1.1', + }, + 'benchmark': { + 'kpi': [ + 'packets_in', + 'packets_fwd', + 'packets_dropped', + ], + }, + 'id': 'ProxApproxVnf', + 'name': 'ProxVnf', + } + + VNFD = { + 'vnfd:vnfd-catalog': { + 'vnfd': [ + VNFD0, + ], + }, + } + def test__replace_quoted_with_value(self): # empty string input_str = '' @@ -751,33 +858,6 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): result = ProxDpdkVnfSetupEnvHelper.write_prox_config(input_data) self.assertEqual(result, expected) - def test_rebind_drivers(self): - def find_drivers(*args, **kwargs): - setup_helper.used_drivers = used_drivers - - used_drivers = { - 'a': (1, 'b'), - 'c': (2, 'd'), - } - - vnfd_helper = mock.MagicMock() - ssh_helper = mock.MagicMock() - scenario_helper = mock.MagicMock() - setup_helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - setup_helper._find_used_drivers = mock_find = mock.MagicMock(side_effect=find_drivers) - - setup_helper.rebind_drivers() - self.assertEqual(mock_find.call_count, 1) - self.assertEqual(ssh_helper.execute.call_count, 2) - self.assertIn('--force', ssh_helper.execute.call_args[0][0]) - - mock_find.reset_mock() - ssh_helper.execute.reset_mock() - setup_helper.rebind_drivers(False) - self.assertEqual(mock_find.call_count, 0) - self.assertEqual(ssh_helper.execute.call_count, 2) - self.assertNotIn('--force', ssh_helper.execute.call_args[0][0]) - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file') def test_build_config_file_no_additional_file(self, mock_find_path): vnf1 = { @@ -931,8 +1011,7 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): mock_parser_type.side_effect = init - vnfd_helper = mock.MagicMock() - vnfd_helper.interfaces = [] + vnfd_helper = VnfdHelper(self.VNFD0) ssh_helper = mock.MagicMock() scenario_helper = mock.MagicMock() @@ -946,23 +1025,6 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): helper.additional_files = {"ipv4.lua": "/tmp/ipv4.lua"} helper.remote_prox_file_name = 'remote' - vnfd_helper.interfaces = [ - { - 'virtual-interface': { - 'dst_mac': '00:00:00:de:ad:88', - }, - }, - { - 'virtual-interface': { - 'dst_mac': '00:00:00:de:ad:ee', - }, - }, - { - 'virtual-interface': { - 'dst_mac': '00:00:00:de:ad:ff', - }, - }, - ] sections_data = [ [ 'lua', @@ -975,7 +1037,7 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): [ ['ip', ''], ['mac', 'foo'], - ['dst mac', '@@2'], + ['dst mac', '@@1'], ['tx port', '1'], ], ], @@ -1004,7 +1066,7 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): [ ['ip', ''], ['mac', 'hardware'], - ['dst mac', '00:00:00:de:ad:ff'], + ['dst mac', '00:00:00:00:00:03'], ['tx port', '1'], ], ], @@ -1012,7 +1074,7 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): 'port 2', [ ['ip', ''], - ['$sut_mac0', '00 00 00 de ad 88'], + ['$sut_mac0', '00 00 00 00 00 04'], ['tx port', '0'], ['single', '@'], ['user_table', 'dofile("/tmp/ipv4.lua")'], @@ -1079,48 +1141,26 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): helper.generate_prox_config_file('a/b') def test_generate_prox_lua_file(self): - vnfd_helper = mock.MagicMock() - vnfd_helper.interfaces = [] + vnfd_helper = VnfdHelper(self.VNFD0) ssh_helper = mock.MagicMock() scenario_helper = mock.MagicMock() helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) helper.LUA_PARAMETER_NAME = 'sut' - expected = '' - result = helper.generate_prox_lua_file() - self.assertEqual(result, expected) - - vnfd_helper.interfaces = [ - { - 'local_ip': '10.20.30.40', - 'dst_ip': '10.11.12.13', - 'virtual-interface': { - 'dpdk_port_num': 3, - }, - }, - { - 'local_ip': '10.20.30.45', - 'dst_ip': '10.11.12.19', - 'virtual-interface': { - 'dpdk_port_num': 7, - }, - }, + expected = [ + 'sut_hex_ip_port_0:"98 10 64 13"', + 'sut_ip_port_0:"152.16.100.19"', + 'gen_hex_ip_port_0:"98 10 64 13"', + 'gen_ip_port_0:"152.16.100.19"', + + 'sut_hex_ip_port_1:"98 10 28 13"', + 'sut_ip_port_1:"152.16.40.19"', + 'gen_hex_ip_port_1:"98 10 28 14"', + 'gen_ip_port_1:"152.16.40.20"', ] - - expected = os.linesep.join([ - 'sut_hex_ip_port_3:"0a 14 1e 28"', - 'sut_ip_port_3:"10.20.30.40"', - 'gen_hex_ip_port_3:"0a 0b 0c 0d"', - 'gen_ip_port_3:"10.11.12.13"', - - 'sut_hex_ip_port_7:"0a 14 1e 2d"', - 'sut_ip_port_7:"10.20.30.45"', - 'gen_hex_ip_port_7:"0a 0b 0c 13"', - 'gen_ip_port_7:"10.11.12.19"', - ]) result = helper.generate_prox_lua_file() - self.assertEqual(result, expected) + self.assertListEqual(result.splitlines(), expected) def test_upload_prox_lua(self): def identity(*args): @@ -1198,6 +1238,111 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): class TestProxResourceHelper(unittest.TestCase): + + VNFD0 = { + 'short-name': 'ProxVnf', + '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': 'PROX approximation using DPDK', + 'name': 'proxvnf-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': 'proxvnf-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', + 'vld_id': 'private_0', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'driver': "i40e", + 'dst_ip': '152.16.100.19', + 'local_iface_name': 'xe0', + 'local_mac': '00:00:00:00:00:02', + 'ifname': 'xe0', + }, + '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', + 'vld_id': 'public_0', + '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', + 'ifname': 'xe1', + }, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1', + }, + ], + }, + ], + 'description': 'PROX approximation using DPDK', + 'mgmt-interface': { + 'vdu-id': 'proxvnf-baremetal', + 'host': '1.2.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.2.1.1', + }, + 'benchmark': { + 'kpi': [ + 'packets_in', + 'packets_fwd', + 'packets_dropped', + ], + }, + 'id': 'ProxApproxVnf', + 'name': 'ProxVnf', + } + + VNFD = { + 'vnfd:vnfd-catalog': { + 'vnfd': [ + VNFD0, + ], + }, + } + def test_line_rate_to_pps(self): expected = 0.25 * 1e8 result = ProxResourceHelper.line_rate_to_pps(180, 4) @@ -1603,8 +1748,30 @@ class TestProxResourceHelper(unittest.TestCase): def measure(*args, **kwargs): yield stats + bad_vnfd = copy.deepcopy(self.VNFD0) + bad_vnfd['vdu'][0]['external-interface'].append({ + 'virtual-interface': { + 'dst_mac': '00:00:00:00:00:05', + 'vpci': '0000:06:00.0', + 'local_ip': '152.16.100.20', + 'type': 'PCI-PASSTHROUGH', + 'vld_id': 'private_1', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'driver': "i40e", + 'dst_ip': '152.16.100.20', + 'local_iface_name': 'xe2', + 'local_mac': '00:00:00:00:00:07', + 'ifname': 'xe2', + }, + 'vnfd-connection-point-ref': 'xe2', + 'name': 'xe2', + }) + + bad_vnfd_helper = VnfdHelper(bad_vnfd) setup_helper = mock.MagicMock() - setup_helper.vnfd_helper.interfaces = [] + setup_helper.vnfd_helper = bad_vnfd_helper stats = { 'delta': TotStatsTuple(6, 7, 8, 9), @@ -1622,25 +1789,21 @@ class TestProxResourceHelper(unittest.TestCase): with self.assertRaises(AssertionError): helper.run_test(980, 15, 45) - setup_helper.vnfd_helper.interfaces = [ - {'name': 'a', 'virtual-interface': {'vpci': 'z'}}, - {'name': 'b', 'virtual-interface': {'vpci': 'y'}}, - {'name': 'c', 'virtual-interface': {'vpci': 'x'}}, - {'name': 'd', 'virtual-interface': {'vpci': 'w'}}, - ] + vnfd_helper = VnfdHelper(self.VNFD0) + setup_helper.vnfd_helper = vnfd_helper + helper = ProxResourceHelper(setup_helper) + helper.client = client + helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8]) helper._test_cores = [3, 4] - expected_test_data = ProxTestDataTuple(0.0, 2.0, 6, 7, 8, [3.3, 3.6, 3.8], 6, 7, 1.3e7) + expected_test_data = ProxTestDataTuple(0.0, 2.0, 6, 7, 8, [3.3, 3.6, 3.8], 6, 7, 6.5e6) expected_port_samples = { - 'a': {'in_packets': 6, 'out_packets': 7}, - 'b': {'in_packets': 6, 'out_packets': 7}, - 'c': {'in_packets': 6, 'out_packets': 7}, - 'd': {'in_packets': 6, 'out_packets': 7}, + 'xe0': {'in_packets': 6, 'out_packets': 7}, + 'xe1': {'in_packets': 6, 'out_packets': 7}, } test_data, port_samples = helper.run_test(230, 60, 65) - self.assertEqual(test_data, expected_test_data, '\n'.join(str(x) for x in test_data)) - self.assertEqual(port_samples, expected_port_samples, - '\n'.join(str(x) for x in port_samples)) + self.assertTupleEqual(test_data, expected_test_data) + self.assertDictEqual(port_samples, expected_port_samples) def test_get_latency(self): setup_helper = mock.MagicMock() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py index 4b115f2d6..2e83cafc1 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py @@ -87,7 +87,7 @@ class TestProxApproxVnf(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'vld_id': '', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': '152.16.100.20', @@ -106,7 +106,7 @@ class TestProxApproxVnf(unittest.TestCase): 'vld_id': '', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', diff --git a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py index 983c21e61..fa733489c 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py @@ -98,10 +98,12 @@ class TestVnfSshHelper(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', - 'local_mac': '00:00:00:00:00:01' + 'local_mac': '00:00:00:00:00:01', + 'vld_id': 'private_0', + 'ifname': 'xe0', }, 'vnfd-connection-point-ref': 'xe0', 'name': 'xe0' @@ -113,10 +115,12 @@ class TestVnfSshHelper(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', - 'local_mac': '00:00:00:00:00:02' + 'local_mac': '00:00:00:00:00:02', + 'vld_id': 'public_0', + 'ifname': 'xe1', }, 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1' @@ -292,10 +296,12 @@ class TestSetupEnvHelper(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', - 'local_mac': '00:00:00:00:00:01' + 'local_mac': '00:00:00:00:00:01', + 'vld_id': 'private_0', + 'ifname': 'xe0', }, 'vnfd-connection-point-ref': 'xe0', 'name': 'xe0' @@ -307,10 +313,12 @@ class TestSetupEnvHelper(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', - 'local_mac': '00:00:00:00:00:02' + 'local_mac': '00:00:00:00:00:02', + 'vld_id': 'public_0', + 'ifname': 'xe1', }, 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1' @@ -414,12 +422,11 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): 'virtual-interface': { 'dst_mac': '00:00:00:00:00:03', 'vpci': '0000:05:00.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'driver': 'i40e', 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', 'local_mac': '00:00:00:00:00:01', @@ -433,12 +440,11 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): 'virtual-interface': { 'dst_mac': '00:00:00:00:00:04', 'vpci': '0000:05:00.1', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'driver': 'ixgbe', 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_mac': '00:00:00:00:00:02', @@ -549,7 +555,8 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): call_args_iter = (args[0][0] for args in ssh_helper.execute.call_args_list) self.assertIsNone(result) self.assertEqual(ssh_helper.execute.call_count, 3) - for expect_start, expect_in, arg0 in zip(expect_start_list, expect_in_list, call_args_iter): + for expect_start, expect_in, arg0 in zip(expect_start_list, expect_in_list, + call_args_iter): self.assertTrue(arg0.startswith(expect_start)) self.assertIn(expect_in, arg0) @@ -566,19 +573,11 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): call_args_iter = (args[0][0] for args in ssh_helper.execute.call_args_list) self.assertIsNone(result) self.assertEqual(ssh_helper.execute.call_count, 3) - for expect_start, expect_in, arg0 in zip(expect_start_list, expect_in_list, call_args_iter): + for expect_start, expect_in, arg0 in zip(expect_start_list, expect_in_list, + call_args_iter): self.assertTrue(arg0.startswith(expect_start)) self.assertIn(expect_in, arg0) - def test__get_dpdk_port_num(self): - vnfd_helper = VnfdHelper(self.VNFD_0) - ssh_helper = mock.Mock() - scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - expected = '0' - result = dpdk_setup_helper._get_dpdk_port_num('xe0') - self.assertEqual(result, expected) - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.open') @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.find_relative_file') @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig') @@ -590,7 +589,6 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): scenario_helper.vnf_cfg = {} scenario_helper.all_options = {} dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - dpdk_setup_helper.all_ports = [] dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command' result = dpdk_setup_helper.build_config() @@ -614,7 +612,7 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): expected = { 'cfg_file': 'config', 'script': 'script', - 'ports_len_hex': '0xf', + 'port_mask_hex': '0x3', 'tool_path': 'tool_path', } dpdk_setup_helper._build_pipeline_kwargs() @@ -725,73 +723,24 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): result = dpdk_setup_helper._validate_cpu_cfg() self.assertEqual(result, expected) - def test__find_used_drivers(self): - vnfd_helper = VnfdHelper(self.VNFD_0) - ssh_helper = mock.Mock() - stdout = ''' -00:01.2 foo drv=name1 -00:01.4 drv foo=name2 -00:02.2 drv=name3 -00:02.3 drv=name4 -''' - ssh_helper.execute.return_value = 0, stdout, '' - scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - dpdk_setup_helper.used_drivers = None - dpdk_setup_helper._dpdk_nic_bind = '' - dpdk_setup_helper.bound_pci = [ - 'pci 00:01.2', - 'pci 00:02.3', - ] + @mock.patch('yardstick.ssh.SSH') + def test_setup_vnf_environment(self, _): + def execute(cmd, *args, **kwargs): + if cmd.startswith('which '): + return exec_failure + return exec_success - expected = { - '00:01.2': (0, 'name1'), - '00:02.3': (2, 'name4'), - } - dpdk_setup_helper._find_used_drivers() - self.assertEqual(dpdk_setup_helper.used_drivers, expected) + exec_success = (0, 'good output', '') + exec_failure = (1, 'bad output', 'error output') - def test_dpdk_nic_bind(self): vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() - ssh_helper.provision_tool.return_value = nic_bind = object() - scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) + ssh_helper.execute = execute - self.assertIsNone(dpdk_setup_helper._dpdk_nic_bind) - self.assertIs(dpdk_setup_helper.dpdk_nic_bind, nic_bind) - self.assertIs(dpdk_setup_helper.dpdk_nic_bind, nic_bind) - self.assertEqual(ssh_helper.provision_tool.call_count, 1) + dpdk_vnf_setup_env_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, mock.Mock()) + dpdk_vnf_setup_env_helper._validate_cpu_cfg = mock.Mock(return_value=[]) - # ensure provision tool is not called a second time - self.assertIs(dpdk_setup_helper.dpdk_nic_bind, nic_bind) - self.assertEqual(ssh_helper.provision_tool.call_count, 1) - - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') - @mock.patch('yardstick.ssh.SSH') - def test_setup_vnf_environment(self, _, mock_time): - cores = ['3', '4'] - - vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0)) - ssh_helper = mock.Mock() - ssh_helper.execute.return_value = 1, 'bad output', 'error output' - ssh_helper.join_bin_path.return_value = 'joined_path' - ssh_helper.provision_tool.return_value = 'provision string' - scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - dpdk_setup_helper._setup_hugepages = mock.Mock() - dpdk_setup_helper._validate_cpu_cfg = mock.Mock(return_value=cores) - dpdk_setup_helper._find_used_drivers = mock.Mock() - dpdk_setup_helper.used_drivers = { - '0000:05:00.0': (1, ''), - '0000:05:01.0': (3, ''), - } - - result = dpdk_setup_helper.setup_vnf_environment() - self.assertIsInstance(result, ResourceProfile) - self.assertEqual(result.cores, cores) - self.assertEqual(vnfd_helper.interfaces[0]['dpdk_port_num'], 1) - self.assertNotIn('dpdk_port_num', vnfd_helper.interfaces[1]) + self.assertIsInstance(dpdk_vnf_setup_env_helper.setup_vnf_environment(), ResourceProfile) def test__setup_dpdk_early_success(self): vnfd_helper = VnfdHelper(self.VNFD_0) @@ -851,83 +800,146 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): self.assertIsInstance(result, ResourceProfile) self.assertEqual(dpdk_setup_helper.socket, 1) - def test__bind_dpdk_unforced(self): - vnfd_helper = VnfdHelper(self.VNFD_0) - ssh_helper = mock.Mock() - scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - - dpdk_setup_helper._bind_dpdk('x', 'y', force=False) - self.assertNotIn('--force', ssh_helper.execute.call_args_list[0][0][0]) - - def test__detect_and_bind_dpdk_short(self): - vnfd_helper = VnfdHelper(self.VNFD_0) - ssh_helper = mock.Mock() - ssh_helper.execute.return_value = 0, 'output', '' - scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - - self.assertIsNone(dpdk_setup_helper._detect_and_bind_dpdk('a', 'b')) - self.assertEqual(ssh_helper.execute.call_count, 1) - - def test__detect_and_bind_dpdk_fail_to_bind(self): - vnfd_helper = VnfdHelper(self.VNFD_0) + def test__detect_and_bind_drivers(self): + vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0)) ssh_helper = mock.Mock() - ssh_helper.execute.return_value = 1, 'bad output', 'error output' + # ssh_helper.execute = mock.Mock(return_value = (0, 'text', '')) + # ssh_helper.execute.return_value = 0, 'output', '' scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - dpdk_setup_helper._bind_dpdk = mock.Mock() - - self.assertIsNone(dpdk_setup_helper._detect_and_bind_dpdk('a', 'b')) - self.assertEqual(ssh_helper.execute.call_count, 2) + rv = ['0000:05:00.1', '0000:05:00.0'] - def test__detect_and_bind_dpdk(self): - vnfd_helper = VnfdHelper(self.VNFD_0) - ssh_helper = mock.Mock() - ssh_helper.execute.side_effect = iter([ - (1, 'bad output', 'error output'), - (0, 'output', ''), - ]) - scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - dpdk_setup_helper._bind_dpdk = mock.Mock() - - self.assertEqual(dpdk_setup_helper._detect_and_bind_dpdk('a', 'b'), 'output') - self.assertEqual(ssh_helper.execute.call_count, 2) + dpdk_setup_helper.dpdk_bind_helper._get_bound_pci_addresses = mock.Mock(return_value=rv) + dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock() + dpdk_setup_helper.dpdk_bind_helper.read_status = mock.Mock() - def test__bind_kernel_devices(self): - bind_iter = iter([ - None, - 'output', - ]) + self.assertIsNone(dpdk_setup_helper._detect_and_bind_drivers()) - vnfd_helper = VnfdHelper(self.VNFD_0) - ssh_helper = mock.Mock() - scenario_helper = mock.Mock() - dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - dpdk_setup_helper._detect_and_bind_dpdk = mock.Mock(side_effect=bind_iter) - - self.assertIsNone(dpdk_setup_helper._bind_kernel_devices()) + intf_0 = vnfd_helper.vdu[0]['external-interface'][0]['virtual-interface'] + intf_1 = vnfd_helper.vdu[0]['external-interface'][1]['virtual-interface'] + self.assertEquals(0, intf_0['dpdk_port_num']) + self.assertEquals(1, intf_1['dpdk_port_num']) def test_tear_down(self): vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - dpdk_setup_helper._dpdk_nic_bind = 'a' - dpdk_setup_helper.used_drivers = { - '0000:05:00.0': (1, 'd1'), - '0000:05:01.0': (3, 'd3'), + dpdk_setup_helper.dpdk_bind_helper.bind = mock.Mock() + dpdk_setup_helper.dpdk_bind_helper.used_drivers = { + '0000:05:00.0': 'd1', + '0000:05:01.0': 'd3', } self.assertIsNone(dpdk_setup_helper.tear_down()) + dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call('0000:05:00.0', 'd1', True) + dpdk_setup_helper.dpdk_bind_helper.bind.assert_any_call('0000:05:01.0', 'd3', True) class TestResourceHelper(unittest.TestCase): + VNFD_0 = { + '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:03', + 'vpci': '0000:05:00.0', + 'driver': 'i40e', + 'local_ip': '152.16.100.19', + 'type': 'PCI-PASSTHROUGH', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.100.20', + 'local_mac': '00:00:00:00:00:01' + }, + 'vnfd-connection-point-ref': 'xe0', + 'name': 'xe0' + }, + { + 'virtual-interface': { + 'dst_mac': '00:00:00:00:00:04', + 'vpci': '0000:05:00.1', + 'driver': 'ixgbe', + 'local_ip': '152.16.40.19', + 'type': 'PCI-PASSTHROUGH', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 1, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.40.20', + 'local_mac': '00:00:00:00:00:02' + }, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1' + }, + ], + }, + ], + 'description': 'Vpe approximation using DPDK', + 'mgmt-interface': { + 'vdu-id': 'vpevnf-baremetal', + 'host': '1.1.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.1.1.1' + }, + 'benchmark': { + 'kpi': [ + 'packets_in', + 'packets_fwd', + 'packets_dropped', + ], + }, + 'connection-point': [ + { + 'type': 'VPORT', + 'name': 'xe0', + }, + { + 'type': 'VPORT', + 'name': 'xe1', + }, + ], + 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh' + } + def test_setup(self): resource = object() - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -938,7 +950,7 @@ class TestResourceHelper(unittest.TestCase): self.assertIs(resource_helper.resource, resource) def test_generate_cfg(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -947,7 +959,7 @@ class TestResourceHelper(unittest.TestCase): self.assertIsNone(resource_helper.generate_cfg()) def test_stop_collect(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -957,7 +969,7 @@ class TestResourceHelper(unittest.TestCase): self.assertIsNone(resource_helper.stop_collect()) def test_stop_collect_none(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -966,6 +978,7 @@ class TestResourceHelper(unittest.TestCase): self.assertIsNone(resource_helper.stop_collect()) + class TestClientResourceHelper(unittest.TestCase): VNFD_0 = { @@ -1012,10 +1025,12 @@ class TestClientResourceHelper(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', - 'local_mac': '00:00:00:00:00:01' + 'local_mac': '00:00:00:00:00:01', + 'vld_id': 'private_0', + 'ifname': 'xe0', }, 'vnfd-connection-point-ref': 'xe0', 'name': 'xe0' @@ -1028,10 +1043,12 @@ class TestClientResourceHelper(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', - 'local_mac': '00:00:00:00:00:02' + 'local_mac': '00:00:00:00:00:02', + 'vld_id': 'public_0', + 'ifname': 'xe1', }, 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1' @@ -1044,7 +1061,7 @@ class TestClientResourceHelper(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 2, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.30', 'local_mac': '00:00:00:00:00:11' @@ -1095,7 +1112,7 @@ class TestClientResourceHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError', new_callable=lambda: MockError) def test_get_stats_not_connected(self, mock_state_error, mock_logger): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -1151,16 +1168,9 @@ class TestClientResourceHelper(unittest.TestCase): "in_packets": 0, "out_packets": 48791, }, - 'xe2': { - "rx_throughput_fps": 0.0, - "tx_throughput_fps": 0.0, - "rx_throughput_mbps": 0.0, - "tx_throughput_mbps": 0.0, - "in_packets": 0, - "out_packets": 0, - }, } - result = client_resource_helper.generate_samples() + ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports) + result = client_resource_helper.generate_samples(ports) self.assertDictEqual(result, expected) def test_generate_samples_with_key(self): @@ -1211,7 +1221,8 @@ class TestClientResourceHelper(unittest.TestCase): "out_packets": 48791, }, } - result = client_resource_helper.generate_samples('key_name') + ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports) + result = client_resource_helper.generate_samples(ports, 'key_name') self.assertDictEqual(result, expected) def test_generate_samples_with_key_and_default(self): @@ -1261,11 +1272,12 @@ class TestClientResourceHelper(unittest.TestCase): "out_packets": 48791, }, } - result = client_resource_helper.generate_samples('key_name', 'default') + ports = vnfd_helper.port_nums(vnfd_helper.port_pairs.all_ports) + result = client_resource_helper.generate_samples(ports, 'key_name', 'default') self.assertDictEqual(result, expected) def test_clear_stats(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -1276,7 +1288,7 @@ class TestClientResourceHelper(unittest.TestCase): self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1) def test_clear_stats_of_ports(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -1287,7 +1299,7 @@ class TestClientResourceHelper(unittest.TestCase): self.assertEqual(client_resource_helper.client.clear_stats.call_count, 1) def test_start(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -1298,7 +1310,7 @@ class TestClientResourceHelper(unittest.TestCase): self.assertEqual(client_resource_helper.client.start.call_count, 1) def test_start_ports(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -1309,7 +1321,7 @@ class TestClientResourceHelper(unittest.TestCase): self.assertEqual(client_resource_helper.client.start.call_count, 1) def test_collect_kpi_with_queue(self): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -1332,7 +1344,7 @@ class TestClientResourceHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError', new_callable=lambda: MockError) def test__connect_with_failures(self, mock_error, mock_logger, mock_time): - vnfd_helper = VnfdHelper({}) + vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) @@ -1667,7 +1679,7 @@ class TestSampleVnf(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', 'local_mac': '00:00:00:00:00:01' @@ -1682,7 +1694,7 @@ class TestSampleVnf(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_mac': '00:00:00:00:00:02' @@ -1757,7 +1769,6 @@ class TestSampleVnf(unittest.TestCase): class MySetupEnvHelper(SetupEnvHelper): pass - class MyResourceHelper(ResourceHelper): pass @@ -1895,6 +1906,16 @@ class TestSampleVnf(unittest.TestCase): self.assertEqual(sample_vnf.wait_for_instantiate(), 0) + def test__build_ports(self): + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + sample_vnf = SampleVNF('vnf1', vnfd) + + self.assertIsNone(sample_vnf._build_ports()) + self.assertIsNotNone(sample_vnf.networks) + self.assertIsNotNone(sample_vnf.priv_ports) + self.assertIsNotNone(sample_vnf.pub_ports) + self.assertIsNotNone(sample_vnf.my_ports) + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") def test_vnf_execute_with_queue_data(self, mock_time): queue_size_list = [ @@ -2022,7 +2043,7 @@ class TestSampleVNFTrafficGen(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.100.20', 'local_mac': '00:00:00:00:00:01' @@ -2038,7 +2059,7 @@ class TestSampleVNFTrafficGen(unittest.TestCase): 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_mac': '00:00:00:00:00:02' @@ -2046,22 +2067,6 @@ class TestSampleVNFTrafficGen(unittest.TestCase): 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1' }, - { - 'virtual-interface': { - 'dst_mac': '00:00:00:00:00:13', - 'vpci': '0000:05:00.2', - 'driver': 'ixgbe', - 'local_ip': '152.16.40.19', - 'type': 'PCI-PASSTHROUGH', - 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', - 'bandwidth': '10 Gbps', - 'dst_ip': '152.16.40.30', - 'local_mac': '00:00:00:00:00:11' - }, - 'vnfd-connection-point-ref': 'xe2', - 'name': 'xe2' - }, ], }, ], @@ -2174,7 +2179,7 @@ class TestSampleVNFTrafficGen(unittest.TestCase): mock_traffic_profile = mock.Mock(autospec=TrafficProfile) mock_traffic_profile.get_traffic_definition.return_value = "64" - mock_traffic_profile.execute.return_value = "64" + mock_traffic_profile.execute_traffic.return_value = "64" mock_traffic_profile.params = self.TRAFFIC_PROFILE sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_ixload.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_ixload.py index c65c0ab0a..e6e4b882e 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_ixload.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_ixload.py @@ -70,7 +70,7 @@ class TestIxLoadTrafficGen(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': '152.16.100.20', @@ -85,7 +85,7 @@ class TestIxLoadTrafficGen(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py index 45bbfaea3..c1b2d27eb 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py @@ -20,6 +20,7 @@ from __future__ import absolute_import import unittest import mock from multiprocessing import Queue +import multiprocessing from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh from tests.unit import STL_MOCKS @@ -31,11 +32,40 @@ stl_patch = mock.patch.dict("sys.modules", STL_MOCKS) stl_patch.start() if stl_patch: - from yardstick.network_services.vnf_generic.vnf.tg_ping import PingParser, PingTrafficGen - from yardstick.network_services.traffic_profile.base import TrafficProfile + from yardstick.network_services.vnf_generic.vnf.tg_ping import PingParser + from yardstick.network_services.vnf_generic.vnf.tg_ping import PingTrafficGen + from yardstick.network_services.vnf_generic.vnf.tg_ping import PingResourceHelper + from yardstick.network_services.vnf_generic.vnf.tg_ping import PingSetupEnvHelper from yardstick.network_services.vnf_generic.vnf.sample_vnf import VnfSshHelper +class TestPingResourceHelper(unittest.TestCase): + def test___init__(self): + setup_helper = mock.Mock() + helper = PingResourceHelper(setup_helper) + + self.assertIsInstance(helper._queue, multiprocessing.queues.Queue) + self.assertIsInstance(helper._parser, PingParser) + + def test_run_traffic(self): + setup_helper = mock.Mock() + traffic_profile = mock.Mock() + traffic_profile.params = { + 'traffic_profile': { + 'frame_size': 64, + }, + } + + helper = PingResourceHelper(setup_helper) + helper.cmd_kwargs = {'target_ip': '10.0.0.2', + 'local_ip': '10.0.0.1', + 'local_if_name': 'eth0', + } + helper.ssh_helper = mock.Mock() + helper.run_traffic(traffic_profile) + helper.ssh_helper.run.called_with('ping-s 64 10.0.0.2') + + class TestPingParser(unittest.TestCase): def test___init__(self): q_out = Queue() @@ -69,7 +99,6 @@ class TestPingParser(unittest.TestCase): class TestPingTrafficGen(unittest.TestCase): - VNFD_0_EXT_IF_0 = { 'virtual-interface': { 'dst_mac': '00:00:00:00:00:04', @@ -77,7 +106,6 @@ class TestPingTrafficGen(unittest.TestCase): 'local_ip': u'152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': u'152.16.100.20', @@ -96,14 +124,13 @@ class TestPingTrafficGen(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', 'bandwidth': '10 Gbps', 'dst_ip': u'152.16.40.20', 'local_iface_name': 'xe1', 'local_mac': '00:00:00:00:00:01', }, - 'vnfd-connection-point-ref': 'xe1', - 'name': 'xe1', + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1', } VNFD_0_EXT_IF_LIST = [ @@ -151,7 +178,7 @@ class TestPingTrafficGen(unittest.TestCase): ], 'description': 'Vpe approximation using DPDK', 'mgmt-interface': { - 'vdu-id': 'vpevnf-baremetal', + 'vdu-id': 'vpevnf-baremetal', 'host': '1.1.1.1', 'password': 'r00t', 'user': 'root', @@ -198,11 +225,20 @@ class TestPingTrafficGen(unittest.TestCase): }, } + CMD_KWARGS = { + 'target_ip': u'152.16.100.20', + 'local_ip': u'152.16.100.19', + 'local_if_name': u'xe0', + } + @mock.patch("yardstick.ssh.SSH") def test___init__(self, ssh): ssh.from_node.return_value.execute.return_value = 0, "success", "" ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) - self.assertIsNotNone(ping_traffic_gen._queue) + + self.assertIsInstance(ping_traffic_gen.setup_helper, PingSetupEnvHelper) + self.assertIsInstance(ping_traffic_gen.resource_helper, PingResourceHelper) + self.assertEquals(ping_traffic_gen._result, {}) @mock.patch("yardstick.ssh.SSH") def test__bind_device_kernel_with_failure(self, ssh): @@ -234,35 +270,23 @@ class TestPingTrafficGen(unittest.TestCase): mock_ssh(ssh, spec=VnfSshHelper, exec_result=(0, "success", "")) ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) ping_traffic_gen.setup_helper.ssh_helper = mock.MagicMock( - **{"execute.return_value": (0, "", "")}) + **{"execute.return_value": (0, "success", "")}) self.assertIsInstance(ping_traffic_gen.ssh_helper, mock.Mock) self.assertEqual(ping_traffic_gen._result, {}) + self.assertIsNone(ping_traffic_gen.instantiate({}, {})) + + self.assertEqual( + ping_traffic_gen.vnfd_helper.interfaces[0]['virtual-interface']['local_iface_name'], + 'success') + self.assertEqual(self.CMD_KWARGS, ping_traffic_gen.resource_helper.cmd_kwargs) self.assertIsNotNone(ping_traffic_gen._result) @mock.patch("yardstick.ssh.SSH") def test_listen_traffic(self, ssh): - ssh.from_node.return_value.execute.return_value = 0, "success", "" ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) self.assertIsNone(ping_traffic_gen.listen_traffic({})) - @mock.patch(SSH_HELPER) - def test_run_traffic_process(self, ssh): - mock_ssh(ssh) - - mock_traffic_profile = mock.Mock(autospec=TrafficProfile) - mock_traffic_profile.get_traffic_definition.return_value = "64" - mock_traffic_profile.params = self.TRAFFIC_PROFILE - - ssh.from_node.return_value.execute.return_value = 0, "success", "" - ssh.from_node.return_value.run.return_value = 0, "success", "" - - sut = PingTrafficGen('vnf1', self.VNFD_0) - sut._traffic_runner(mock_traffic_profile) - sut.ssh_helper.run.assert_called_with( - "ping -s 64 152.16.100.20", - stdout=sut._parser, keep_stdin_open=True, pty=True) - @mock.patch("yardstick.ssh.SSH") def test_scale_negative(self, ssh): ssh.from_node.return_value.execute.return_value = 0, "success", "" @@ -277,4 +301,4 @@ class TestPingTrafficGen(unittest.TestCase): ssh.from_node.return_value.run.return_value = 0, "success", "" ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) - self.assertIsNone(ping_traffic_gen.terminate())
\ No newline at end of file + self.assertIsNone(ping_traffic_gen.terminate()) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py index a12abb625..d1f24700a 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py @@ -80,7 +80,7 @@ class TestProxTrafficGen(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'vld_id': '', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': '152.16.100.20', @@ -99,7 +99,7 @@ class TestProxTrafficGen(unittest.TestCase): 'vld_id': '', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', @@ -349,8 +349,10 @@ class TestProxTrafficGen(unittest.TestCase): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] prox_traffic_gen = ProxTrafficGen(NAME, vnfd) - prox_traffic_gen.ssh_helper = mock.MagicMock( + ssh_helper = mock.MagicMock( **{"execute.return_value": (0, "", ""), "bin_path": ""}) + prox_traffic_gen.ssh_helper = ssh_helper + prox_traffic_gen.setup_helper.dpdk_bind_helper.ssh_helper = ssh_helper prox_traffic_gen.setup_helper._setup_resources = mock.MagicMock() prox_traffic_gen.setup_hugepages = mock.MagicMock() prox_traffic_gen.generate_prox_config_file = mock.MagicMock() @@ -384,7 +386,7 @@ class TestProxTrafficGen(unittest.TestCase): mock_traffic_profile = mock.Mock(autospec=TrafficProfile) mock_traffic_profile.get_traffic_definition.return_value = "64" - mock_traffic_profile.execute.return_value = "64" + mock_traffic_profile.execute_traffic.return_value = "64" mock_traffic_profile.params = self.TRAFFIC_PROFILE vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py index 3c5ccefce..0e303dc3b 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py @@ -23,7 +23,6 @@ import mock from tests.unit import STL_MOCKS - STLClient = mock.MagicMock() stl_patch = mock.patch.dict("sys.modules", STL_MOCKS) stl_patch.start() @@ -36,13 +35,11 @@ if stl_patch: TEST_FILE_YAML = 'nsb_test_case.yaml' - NAME = "tg__1" @mock.patch("yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.IxNextgen") class TestIxiaResourceHelper(unittest.TestCase): - def test___init___with_custom_rfc_helper(self, mock_ix_nextgen): class MyRfcHelper(IxiaRfc2544Helper): pass @@ -63,71 +60,71 @@ class TestIxiaResourceHelper(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.IxNextgen") class TestIXIATrafficGen(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.1.1.1', - 'password': 'r00t', - 'user': 'root', - 'ip': '1.1.1.1'}, - 'benchmark': - {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']}, - 'connection-point': [{'type': 'VPORT', 'name': 'xe0'}, - {'type': 'VPORT', 'name': 'xe1'}], - 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}} + {'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.1.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.1.1.1'}, + 'benchmark': + {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']}, + 'connection-point': [{'type': 'VPORT', 'name': 'xe0'}, + {'type': 'VPORT', 'name': 'xe1'}], + 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}} TRAFFIC_PROFILE = { "schema": "isb:traffic_profile:0.1", @@ -140,12 +137,12 @@ class TestIXIATrafficGen(unittest.TestCase): "frame_size": 64}} TC_YAML = {'scenarios': [{'tc_options': - {'rfc2544': {'allowed_drop_rate': '0.8 - 1'}}, + {'rfc2544': {'allowed_drop_rate': '0.8 - 1'}}, 'runner': {'duration': 400, 'interval': 35, 'type': 'Duration'}, 'traffic_options': - {'flow': 'ipv4_1flow_Packets_vpe.yaml', - 'imix': 'imix_voice.yaml'}, + {'flow': 'ipv4_1flow_Packets_vpe.yaml', + 'imix': 'imix_voice.yaml'}, 'vnf_options': {'vpe': {'cfg': 'vpe_config'}}, 'traffic_profile': 'ipv4_throughput_vpe.yaml', 'type': 'NSPerf', @@ -195,7 +192,7 @@ class TestIXIATrafficGen(unittest.TestCase): 'vnf_config': {'lb_config': 'SW', 'lb_count': 1, 'worker_config': - '1C/1T', + '1C/1T', 'worker_threads': 1}} }}) ixnet_traffic_gen.topology = "" @@ -255,6 +252,7 @@ class TestIXIATrafficGen(unittest.TestCase): mock_traffic_profile = mock.Mock(autospec=TrafficProfile) mock_traffic_profile.get_traffic_definition.return_value = "64" mock_traffic_profile.params = self.TRAFFIC_PROFILE + mock_traffic_profile.ports = [0, 1] mock_ssh_instance = mock.Mock(autospec=mock_ssh.SSH) mock_ssh_instance.execute.return_value = 0, "", "" @@ -306,11 +304,10 @@ class TestIXIATrafficGen(unittest.TestCase): }, ] - mock_traffic_profile.execute.return_value = ['Completed', samples] + mock_traffic_profile.execute_traffic.return_value = ['Completed', samples] mock_traffic_profile.get_drop_percentage.return_value = ['Completed', samples] sut = IxiaTrafficGen(name, vnfd) - sut.tg_port_pairs = [[[0], [1]]] sut.vnf_port_pairs = [[[0], [1]]] sut.tc_file_name = self._get_file_abspath(TEST_FILE_YAML) sut.topology = "" @@ -349,7 +346,8 @@ class TestIXIATrafficGen(unittest.TestCase): 'task_path': '/path/to/task' } - with mock.patch('yardstick.benchmark.scenarios.networking.vnf_generic.open', create=True) as mock_open: + with mock.patch('yardstick.benchmark.scenarios.networking.vnf_generic.open', + create=True) as mock_open: mock_open.return_value = mock.MagicMock() result = sut._traffic_runner(mock_traffic_profile) self.assertIsNone(result) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py index 6f2a9445f..0fe0c3d45 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py @@ -24,7 +24,6 @@ from tests.unit import STL_MOCKS SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' - STLClient = mock.MagicMock() stl_patch = mock.patch.dict("sys.modules", STL_MOCKS) stl_patch.start() @@ -101,8 +100,8 @@ class TestTrexTrafficGenRFC(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'vld_id': 'private_1', - 'dpdk_port_num': '0', + 'vld_id': 'private_0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': '152.16.100.20', @@ -121,8 +120,8 @@ class TestTrexTrafficGenRFC(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'driver': "i40e", 'netmask': '255.255.255.0', - 'vld_id': 'public_1', - 'dpdk_port_num': '1', + 'vld_id': 'public_0', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py index 9d1ce1520..4fd4c4c43 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py @@ -25,7 +25,6 @@ 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 - NAME = 'vnf_1' STLClient = mock.MagicMock() @@ -34,77 +33,77 @@ stl_patch.start() if stl_patch: from yardstick.network_services.vnf_generic.vnf.tg_trex import \ - TrexTrafficGen, TrexResourceHelper + TrexTrafficGen, TrexResourceHelper from yardstick.network_services.traffic_profile.base import TrafficProfile class TestTrexTrafficGen(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.1.1.1', - 'password': 'r00t', - 'user': 'root', - 'ip': '1.1.1.1'}, - 'benchmark': - {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']}, - 'connection-point': [{'type': 'VPORT', 'name': 'xe0'}, - {'type': 'VPORT', 'name': 'xe1'}], - 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}} + {'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.1.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.1.1.1'}, + 'benchmark': + {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']}, + 'connection-point': [{'type': 'VPORT', 'name': 'xe0'}, + {'type': 'VPORT', 'name': 'xe1'}], + 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}} TRAFFIC_PROFILE = { "schema": "isb:traffic_profile:0.1", @@ -295,8 +294,6 @@ class TestTrexTrafficGen(unittest.TestCase): } } - - @mock.patch(SSH_HELPER) def test___init__(self, ssh): mock_ssh(ssh) @@ -367,7 +364,7 @@ class TestTrexTrafficGen(unittest.TestCase): mock_traffic_profile = mock.Mock(autospec=TrafficProfile) mock_traffic_profile.get_traffic_definition.return_value = "64" - mock_traffic_profile.execute.return_value = "64" + mock_traffic_profile.execute_traffic.return_value = "64" mock_traffic_profile.params = self.TRAFFIC_PROFILE vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -432,5 +429,6 @@ class TestTrexTrafficGen(unittest.TestCase): client.connect = mock.Mock(return_value=0) self.assertIsNotNone(trex_traffic_gen.resource_helper._connect(client)) + if __name__ == '__main__': unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py b/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py index c4ced30fe..95bc08b17 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py @@ -31,6 +31,7 @@ stl_patch.start() if stl_patch: from yardstick.network_services.vnf_generic.vnf.udp_replay import UdpReplayApproxVnf + from yardstick.network_services.nfvi.resource import ResourceProfile from yardstick.network_services.vnf_generic.vnf.sample_vnf import ScenarioHelper from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh @@ -73,10 +74,12 @@ class TestUdpReplayApproxVnf(unittest.TestCase): 'local_ip': '152.16.100.19', 'local_mac': '00:00:00:00:00:02', 'vpci': '0000:05:00.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'netmask': '255.255.255.0', 'dst_ip': '152.16.100.20', 'type': 'PCI-PASSTHROUGH', + 'vld_id': 'private_0', + 'ifname': 'xe0', }, 'vnfd-connection-point-ref': 'xe0', 'name': 'xe0', @@ -90,10 +93,12 @@ class TestUdpReplayApproxVnf(unittest.TestCase): 'local_ip': '152.16.40.19', 'local_mac': '00:00:00:00:00:01', 'vpci': '0000:05:00.1', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'netmask': '255.255.255.0', 'dst_ip': '152.16.40.20', 'type': 'PCI-PASSTHROUGH', + 'vld_id': 'public_0', + 'ifname': 'xe1', }, 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1', @@ -342,21 +347,12 @@ class TestUdpReplayApproxVnf(unittest.TestCase): 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.all_ports = ["xe0", "xe1"] 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") - @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) @@ -378,7 +374,6 @@ class TestUdpReplayApproxVnf(unittest.TestCase): file_path = os.path.join(curr_path, filename) return file_path - @mock.patch('yardstick.network_services.vnf_generic.vnf.udp_replay.open') @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch(SSH_HELPER) def test__build_config(self, ssh, mock_context, *_): @@ -389,14 +384,14 @@ class TestUdpReplayApproxVnf(unittest.TestCase): 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)'" + expected = \ + "sudo tool_path --log-level=5 -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') @@ -404,14 +399,11 @@ class TestUdpReplayApproxVnf(unittest.TestCase): @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.setup_helper.bound_pci = ['0000:00:0.1', '0000:00:0.3'] + udp_replay_approx_vnf.all_ports = ["xe0", "xe1"] 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 @@ -419,12 +411,12 @@ class TestUdpReplayApproxVnf(unittest.TestCase): udp_replay_approx_vnf._build_pipeline_kwargs() self.assertEqual(udp_replay_approx_vnf.pipeline_kwargs, { - 'config': '(0, 0, 1)(1, 0, 2)', + 'config': '(0,0,1),(1,0,2)', 'cpu_mask_hex': '0x7', 'hw_csum': '', - 'ports_len_hex': '0x3', + 'port_mask_hex': '0x3', 'tool_path': 'tool_path', - 'whitelist': '' + 'whitelist': '0000:00:0.1 -w 0000:00:0.3' }) @mock.patch(SSH_HELPER) @@ -444,13 +436,14 @@ class TestUdpReplayApproxVnf(unittest.TestCase): def test_instantiate(self, ssh, *_): mock_ssh(ssh) + resource = mock.Mock(autospec=ResourceProfile) + 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)) + 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 @@ -484,8 +477,7 @@ class TestUdpReplayApproxVnf(unittest.TestCase): 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.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()) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py index c3d53ff03..38cc1774a 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py @@ -73,7 +73,7 @@ class TestFWApproxVnf(unittest.TestCase): 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', 'netmask': '255.255.255.0', - 'dpdk_port_num': '0', + 'dpdk_port_num': 0, 'bandwidth': '10 Gbps', 'driver': "i40e", 'dst_ip': '152.16.100.20', @@ -88,7 +88,7 @@ class TestFWApproxVnf(unittest.TestCase): 'type': 'PCI-PASSTHROUGH', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + 'dpdk_port_num': 1, 'bandwidth': '10 Gbps', 'dst_ip': '152.16.40.20', 'local_iface_name': 'xe1', diff --git a/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py index ffd0d539b..e210aa0e4 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py @@ -36,8 +36,8 @@ stl_patch.start() if stl_patch: from yardstick.network_services.vnf_generic.vnf.vpe_vnf import ConfigCreate from yardstick.network_services.nfvi.resource import ResourceProfile - from yardstick.network_services.vnf_generic.vnf import vpe_vnf - from yardstick.network_services.vnf_generic.vnf.vpe_vnf import VpeApproxVnf + from yardstick.network_services.vnf_generic.vnf.vpe_vnf import \ + VpeApproxVnf, VpeApproxSetupEnvHelper from tests.unit.network_services.vnf_generic.vnf.test_base import FileAbsPath from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh @@ -185,14 +185,15 @@ class TestVpeApproxVnf(unittest.TestCase): 'vpci': '0000:05:00.0', 'local_ip': '152.16.100.19', 'type': 'PCI-PASSTHROUGH', - 'vld_id': '', 'netmask': '255.255.255.0', - 'dpdk_port_num': '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', + 'vld_id': 'private_0', + 'ifname': 'xe0', }, 'vnfd-connection-point-ref': 'xe0', 'name': 'xe0', @@ -203,14 +204,15 @@ class TestVpeApproxVnf(unittest.TestCase): 'vpci': '0000:05:00.1', 'local_ip': '152.16.40.19', 'type': 'PCI-PASSTHROUGH', - 'vld_id': '', 'driver': "i40e", 'netmask': '255.255.255.0', - 'dpdk_port_num': '1', + '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', + 'vld_id': 'public_0', + 'ifname': 'xe1', }, 'vnfd-connection-point-ref': 'xe1', 'name': 'xe1', @@ -258,7 +260,7 @@ class TestVpeApproxVnf(unittest.TestCase): SCENARIO_CFG = { 'options': { 'packetsize': 64, - 'traffic_type': 4 , + 'traffic_type': 4, 'rfc2544': { 'allowed_drop_rate': '0.8 - 1', }, @@ -499,6 +501,40 @@ class TestVpeApproxVnf(unittest.TestCase): vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0) vpe_approx_vnf.tc_file_name = get_file_abspath(TEST_FILE_YAML) + vpe_approx_vnf.vnf_cfg = { + 'lb_config': 'SW', + 'lb_count': 1, + 'worker_config': '1C/1T', + 'worker_threads': 1, + } + vpe_approx_vnf.scenario_helper.scenario_cfg = { + 'options': { + NAME: { + 'traffic_type': '4', + 'topology': 'nsb_test_case.yaml', + 'vnf_config': 'vpe_config', + } + } + } + vpe_approx_vnf.topology = "nsb_test_case.yaml" + vpe_approx_vnf.nfvi_type = "baremetal" + vpe_approx_vnf._provide_config_file = mock.Mock() + vpe_approx_vnf._build_config = mock.MagicMock() + + self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock) + self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock) + self.assertIsNone(vpe_approx_vnf._run()) + + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig") + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") + @mock.patch("yardstick.network_services.vnf_generic.vnf.vpe_vnf.ConfigCreate") + @mock.patch("yardstick.network_services.vnf_generic.vnf.vpe_vnf.open") + @mock.patch(SSH_HELPER) + def test_build_config(self, mock_mul, mock_context, mock_config, mock_open, ssh, _): + mock_ssh(ssh) + vpe_approx_vnf = VpeApproxSetupEnvHelper(mock.MagicMock(), + mock.MagicMock, mock.MagicMock) + vpe_approx_vnf.tc_file_name = get_file_abspath(TEST_FILE_YAML) vpe_approx_vnf.generate_port_pairs = mock.Mock() vpe_approx_vnf.tg_port_pairs = [[[0], [1]]] vpe_approx_vnf.vnf_port_pairs = [[[0], [1]]] @@ -513,6 +549,7 @@ class TestVpeApproxVnf(unittest.TestCase): NAME: { 'traffic_type': '4', 'topology': 'nsb_test_case.yaml', + 'vnf_config': 'vpe_config', } } } @@ -520,8 +557,12 @@ class TestVpeApproxVnf(unittest.TestCase): vpe_approx_vnf.nfvi_type = "baremetal" vpe_approx_vnf._provide_config_file = mock.Mock() - self.assertIsInstance(vpe_approx_vnf.ssh_helper, mock.Mock) - self.assertIsNone(vpe_approx_vnf._run()) + vpe_approx_vnf.ssh_helper = mock.MagicMock() + vpe_approx_vnf.scenario_helper = mock.MagicMock() + vpe_approx_vnf.ssh_helper.bin_path = mock.Mock() + vpe_approx_vnf.ssh_helper.upload_config_file = mock.MagicMock() + self.assertIsNone(vpe_approx_vnf._build_vnf_ports()) + self.assertIsNotNone(vpe_approx_vnf.build_config()) @mock.patch(SSH_HELPER) def test_wait_for_instantiate(self, ssh, _): diff --git a/yardstick/benchmark/contexts/heat.py b/yardstick/benchmark/contexts/heat.py index d2309cc10..c7586abf4 100644 --- a/yardstick/benchmark/contexts/heat.py +++ b/yardstick/benchmark/contexts/heat.py @@ -83,9 +83,14 @@ class HeatContext(Context): external_network = os.environ.get("EXTERNAL_NETWORK", "net04_ext") have_external_network = any(net.get("external_network") for net in networks.values()) - if sorted_networks and not have_external_network: - # no external net defined, assign it to first network using os.environ - sorted_networks[0][1]["external_network"] = external_network + if not have_external_network: + # try looking for mgmt network first + try: + networks['mgmt']["external_network"] = external_network + except KeyError: + if sorted_networks: + # otherwise assign it to first network using os.environ + sorted_networks[0][1]["external_network"] = external_network return sorted_networks @@ -328,16 +333,21 @@ class HeatContext(Context): LOG.info("Deploying context '%s' DONE", self.name) def add_server_port(self, server): - # TODO(hafe) can only handle one internal network for now - # use private ip from first port - private_port = next(iter(server.ports.values())) + # use private ip from first port in first network + try: + private_port = next(iter(server.ports.values()))[0] + except IndexError: + LOG.exception("Unable to find first private port in %s", server.ports) + raise server.private_ip = self.stack.outputs[private_port["stack_name"]] server.interfaces = {} - for network_name, port in server.ports.items(): - # port['port'] is either port name from mapping or default network_name - server.interfaces[port['port']] = self.make_interface_dict(network_name, port['port'], - port['stack_name'], - self.stack.outputs) + for network_name, ports in server.ports.items(): + for port in ports: + # port['port'] is either port name from mapping or default network_name + server.interfaces[port['port']] = self.make_interface_dict(network_name, + port['port'], + port['stack_name'], + self.stack.outputs) def make_interface_dict(self, network_name, port, stack_name, outputs): private_ip = outputs[stack_name] diff --git a/yardstick/benchmark/contexts/model.py b/yardstick/benchmark/contexts/model.py index da2b74e1c..facfab892 100644 --- a/yardstick/benchmark/contexts/model.py +++ b/yardstick/benchmark/contexts/model.py @@ -11,9 +11,15 @@ """ from __future__ import absolute_import + +import six +import logging from six.moves import range +LOG = logging.getLogger(__name__) + + class Object(object): """Base class for classes in the logical model Contains common attributes and methods @@ -257,44 +263,51 @@ class Server(Object): # pragma: no cover # if explicit mapping skip unused networks if self.network_ports: try: - port = self.network_ports[network.name] + ports = self.network_ports[network.name] except KeyError: # no port for this network continue + else: + if isinstance(ports, six.string_types): + if ports.startswith('-'): + LOG.warning("possible YAML error, port name starts with - '%s", ports) + ports = [ports] # otherwise add a port for every network with port name as network name else: - port = network.name - port_name = "{0}-{1}-port".format(server_name, port) - self.ports[network.name] = {"stack_name": port_name, "port": port} - # we can't use secgroups if port_security_enabled is False - if network.port_security_enabled is False: - sec_group_id = None - else: - # if port_security_enabled is None we still need to add to secgroup - sec_group_id = self.secgroup_name - # don't refactor to pass in network object, that causes JSON - # circular ref encode errors - template.add_port(port_name, network.stack_name, network.subnet_stack_name, - network.vnic_type, sec_group_id=sec_group_id, - provider=network.provider, - allowed_address_pairs=network.allowed_address_pairs) - port_name_list.append(port_name) - - if self.floating_ip: - external_network = self.floating_ip["external_network"] - if network.has_route_to(external_network): - self.floating_ip["stack_name"] = server_name + "-fip" - template.add_floating_ip(self.floating_ip["stack_name"], - external_network, - port_name, - network.router.stack_if_name, - sec_group_id) - self.floating_ip_assoc["stack_name"] = \ - server_name + "-fip-assoc" - template.add_floating_ip_association( - self.floating_ip_assoc["stack_name"], - self.floating_ip["stack_name"], - port_name) + ports = [network.name] + for port in ports: + port_name = "{0}-{1}-port".format(server_name, port) + self.ports.setdefault(network.name, []).append( + {"stack_name": port_name, "port": port}) + # we can't use secgroups if port_security_enabled is False + if network.port_security_enabled is False: + sec_group_id = None + else: + # if port_security_enabled is None we still need to add to secgroup + sec_group_id = self.secgroup_name + # don't refactor to pass in network object, that causes JSON + # circular ref encode errors + template.add_port(port_name, network.stack_name, network.subnet_stack_name, + network.vnic_type, sec_group_id=sec_group_id, + provider=network.provider, + allowed_address_pairs=network.allowed_address_pairs) + port_name_list.append(port_name) + + if self.floating_ip: + external_network = self.floating_ip["external_network"] + if network.has_route_to(external_network): + self.floating_ip["stack_name"] = server_name + "-fip" + template.add_floating_ip(self.floating_ip["stack_name"], + external_network, + port_name, + network.router.stack_if_name, + sec_group_id) + self.floating_ip_assoc["stack_name"] = \ + server_name + "-fip-assoc" + template.add_floating_ip_association( + self.floating_ip_assoc["stack_name"], + self.floating_ip["stack_name"], + port_name) if self.flavor: if isinstance(self.flavor, dict): self.flavor["name"] = \ diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py index 0e6ceab6e..ada92121b 100644 --- a/yardstick/benchmark/scenarios/networking/vnf_generic.py +++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py @@ -25,7 +25,6 @@ import re from itertools import chain import six -from operator import itemgetter from collections import defaultdict from yardstick.benchmark.scenarios import base @@ -134,6 +133,7 @@ class NetworkServiceTestCase(base.Scenario): self.vnfs = [] self.collector = None self.traffic_profile = None + self.node_netdevs = {} def _get_ip_flow_range(self, ip_start_range): @@ -168,15 +168,17 @@ class NetworkServiceTestCase(base.Scenario): def _get_traffic_flow(self): flow = {} try: + # TODO: should be .0 or .1 so we can use list + # but this also roughly matches private_0, public_0 fflow = self.scenario_cfg["options"]["flow"] for index, src in enumerate(fflow.get("src_ip", [])): - flow["src_ip{}".format(index)] = self._get_ip_flow_range(src) + flow["src_ip_{}".format(index)] = self._get_ip_flow_range(src) for index, dst in enumerate(fflow.get("dst_ip", [])): - flow["dst_ip{}".format(index)] = self._get_ip_flow_range(dst) + flow["dst_ip_{}".format(index)] = self._get_ip_flow_range(dst) - for index, publicip in enumerate(fflow.get("publicip", [])): - flow["public_ip{}".format(index)] = publicip + for index, publicip in enumerate(fflow.get("public_ip", [])): + flow["public_ip_{}".format(index)] = publicip flow["count"] = fflow["count"] except KeyError: @@ -263,7 +265,6 @@ class NetworkServiceTestCase(base.Scenario): node0_if["node_name"] = node0_name node1_if["node_name"] = node1_name - vld_networks = self.get_vld_networks(self.context_cfg["networks"]) node0_if["vld_id"] = vld["id"] node1_if["vld_id"] = vld["id"] @@ -276,6 +277,7 @@ class NetworkServiceTestCase(base.Scenario): node1_if["peer_ifname"] = node0_if_name # just load the network + vld_networks = self.get_vld_networks(self.context_cfg["networks"]) node0_if["network"] = vld_networks.get(vld["id"], {}) node1_if["network"] = vld_networks.get(vld["id"], {}) @@ -325,16 +327,15 @@ class NetworkServiceTestCase(base.Scenario): vnfd = self._find_vnfd_from_vnf_idx(vnf_idx) self.context_cfg["nodes"][vnf_name].update(vnfd) - @staticmethod - def _sort_dpdk_port_num(netdevs): - # dpdk_port_num is PCI BUS ID ordering, lowest first - s = sorted(netdevs.values(), key=itemgetter('pci_bus_id')) - for dpdk_port_num, netdev in enumerate(s): - netdev['dpdk_port_num'] = dpdk_port_num + def _probe_netdevs(self, node, node_dict, timeout=120): + try: + return self.node_netdevs[node] + except KeyError: + pass - def _probe_netdevs(self, node, node_dict): - cmd = "PATH=$PATH:/sbin:/usr/sbin ip addr show" netdevs = {} + cmd = "PATH=$PATH:/sbin:/usr/sbin ip addr show" + with SshManager(node_dict) as conn: if conn: exit_status = conn.execute(cmd)[0] @@ -346,6 +347,8 @@ class NetworkServiceTestCase(base.Scenario): raise IncorrectSetup( "Cannot find netdev info in sysfs" % node) netdevs = node_dict['netdevs'] = self.parse_netdev_info(stdout) + + self.node_netdevs[node] = netdevs return netdevs @classmethod @@ -458,10 +461,22 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \ (expected_name, classes_found)) @staticmethod - def update_interfaces_from_node(vnfd, node): - for intf in vnfd["vdu"][0]["external-interface"]: - node_intf = node['interfaces'][intf['name']] - intf['virtual-interface'].update(node_intf) + def create_interfaces_from_node(vnfd, node): + ext_intfs = vnfd["vdu"][0]["external-interface"] = [] + # have to sort so xe0 goes first + for intf_name, intf in sorted(node['interfaces'].items()): + if intf.get('vld_id'): + # force dpkd_port_num to int so we can do reverse lookup + try: + intf['dpdk_port_num'] = int(intf['dpdk_port_num']) + except KeyError: + pass + ext_intf = { + "name": intf_name, + "virtual-interface": intf, + "vnfd-connection-point-ref": intf_name, + } + ext_intfs.append(ext_intf) def load_vnf_models(self, scenario_cfg=None, context_cfg=None): """ Create VNF objects based on YAML descriptors @@ -491,7 +506,7 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \ vnfd = vnfdgen.generate_vnfd(vnf_model, node) # TODO: here add extra context_cfg["nodes"] regardless of template vnfd = vnfd["vnfd:vnfd-catalog"]["vnfd"][0] - self.update_interfaces_from_node(vnfd, node) + self.create_interfaces_from_node(vnfd, node) vnf_impl = self.get_vnf_impl(vnfd['id']) vnf_instance = vnf_impl(node_name, vnfd) vnfs.append(vnf_instance) diff --git a/yardstick/network_services/helpers/dpdknicbind_helper.py b/yardstick/network_services/helpers/dpdknicbind_helper.py new file mode 100644 index 000000000..605d08d38 --- /dev/null +++ b/yardstick/network_services/helpers/dpdknicbind_helper.py @@ -0,0 +1,145 @@ +# Copyright (c) 2016-2017 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. +import re +import itertools + +NETWORK_KERNEL = 'network_kernel' +NETWORK_DPDK = 'network_dpdk' +NETWORK_OTHER = 'network_other' +CRYPTO_KERNEL = 'crypto_kernel' +CRYPTO_DPDK = 'crypto_dpdk' +CRYPTO_OTHER = 'crypto_other' + + +class DpdkBindHelperException(Exception): + pass + + +class DpdkBindHelper(object): + DPDK_STATUS_CMD = "{dpdk_nic_bind} --status" + DPDK_BIND_CMD = "sudo {dpdk_nic_bind} {force} -b {driver} {vpci}" + + NIC_ROW_RE = re.compile("([^ ]+) '([^']+)' (?:if=([^ ]+) )?drv=([^ ]+) " + "unused=([^ ]*)(?: (\*Active\*))?") + SKIP_RE = re.compile('(====|<none>|^$)') + NIC_ROW_FIELDS = ['vpci', 'dev_type', 'iface', 'driver', 'unused', 'active'] + + HEADER_DICT_PAIRS = [ + (re.compile('^Network.*DPDK.*$'), NETWORK_DPDK), + (re.compile('^Network.*kernel.*$'), NETWORK_KERNEL), + (re.compile('^Other network.*$'), NETWORK_OTHER), + (re.compile('^Crypto.*DPDK.*$'), CRYPTO_DPDK), + (re.compile('^Crypto.*kernel$'), CRYPTO_KERNEL), + (re.compile('^Other crypto.*$'), CRYPTO_OTHER), + ] + + def clean_status(self): + self.dpdk_status = { + NETWORK_KERNEL: [], + NETWORK_DPDK: [], + CRYPTO_KERNEL: [], + CRYPTO_DPDK: [], + NETWORK_OTHER: [], + CRYPTO_OTHER: [], + } + + def __init__(self, ssh_helper): + self.dpdk_status = None + self.status_nic_row_re = None + self._dpdk_nic_bind_attr = None + self._status_cmd_attr = None + + self.ssh_helper = ssh_helper + self.clean_status() + + def _dpdk_execute(self, *args, **kwargs): + res = self.ssh_helper.execute(*args, **kwargs) + if res[0] != 0: + raise DpdkBindHelperException('{} command failed with rc={}'.format( + self._dpdk_nic_bind, res[0])) + return res + + @property + def _dpdk_nic_bind(self): + if self._dpdk_nic_bind_attr is None: + self._dpdk_nic_bind_attr = self.ssh_helper.provision_tool(tool_file="dpdk-devbind.py") + return self._dpdk_nic_bind_attr + + @property + def _status_cmd(self): + if self._status_cmd_attr is None: + self._status_cmd_attr = self.DPDK_STATUS_CMD.format(dpdk_nic_bind=self._dpdk_nic_bind) + return self._status_cmd_attr + + def _addline(self, active_list, line): + if active_list is None: + return + res = self.NIC_ROW_RE.match(line) + if res is None: + return + new_data = {k: v for k, v in zip(self.NIC_ROW_FIELDS, res.groups())} + new_data['active'] = bool(new_data['active']) + self.dpdk_status[active_list].append(new_data) + + @classmethod + def _switch_active_dict(cls, a_row, active_dict): + for regexp, a_dict in cls.HEADER_DICT_PAIRS: + if regexp.match(a_row): + return a_dict + return active_dict + + def parse_dpdk_status_output(self, input): + active_dict = None + self.clean_status() + for a_row in input.splitlines(): + if self.SKIP_RE.match(a_row): + continue + active_dict = self._switch_active_dict(a_row, active_dict) + self._addline(active_dict, a_row) + return self.dpdk_status + + def _get_bound_pci_addresses(self, active_dict): + return [iface['vpci'] for iface in self.dpdk_status[active_dict]] + + @property + def dpdk_bound_pci_addresses(self): + return self._get_bound_pci_addresses(NETWORK_DPDK) + + @property + def kernel_bound_pci_addresses(self): + return self._get_bound_pci_addresses(NETWORK_KERNEL) + + @property + def interface_driver_map(self): + return {interface['vpci']: interface['driver'] + for interface in itertools.chain(*self.dpdk_status.values())} + + def read_status(self): + return self.parse_dpdk_status_output(self._dpdk_execute(self._status_cmd)[1]) + + def bind(self, pci, driver, force=True): + cmd = self.DPDK_BIND_CMD.format(dpdk_nic_bind=self._dpdk_nic_bind, + driver=driver, + vpci=' '.join(list(pci)), + force='--force' if force else '') + self._dpdk_execute(cmd) + # update the inner status dict + self.read_status() + + def save_used_drivers(self): + self.used_drivers = self.interface_driver_map + + def rebind_drivers(self, force=True): + for vpci, driver in self.used_drivers.items(): + self.bind(vpci, driver, force) diff --git a/yardstick/network_services/helpers/samplevnf_helper.py b/yardstick/network_services/helpers/samplevnf_helper.py index 9d89d4188..7054b9232 100644 --- a/yardstick/network_services/helpers/samplevnf_helper.py +++ b/yardstick/network_services/helpers/samplevnf_helper.py @@ -19,7 +19,7 @@ import logging import os import sys from collections import OrderedDict, defaultdict -from itertools import chain +from itertools import chain, repeat import six from six.moves.configparser import ConfigParser @@ -62,6 +62,97 @@ SCRIPT_TPL = """ """ +class PortPairs(object): + + PUBLIC = "public" + PRIVATE = "private" + + def __init__(self, interfaces): + super(PortPairs, self).__init__() + self.interfaces = interfaces + self._all_ports = None + self._priv_ports = None + self._pub_ports = None + self._networks = None + self._port_pair_list = None + self._valid_networks = None + + @property + def networks(self): + if self._networks is None: + self._networks = {} + for intf in self.interfaces: + vintf = intf['virtual-interface'] + try: + vld_id = vintf['vld_id'] + except KeyError: + # probably unused port? + LOG.warning("intf without vld_id, %s", vintf) + else: + self._networks.setdefault(vld_id, []).append(vintf["ifname"]) + return self._networks + + @classmethod + def get_public_id(cls, vld_id): + # partition returns a tuple + parts = list(vld_id.partition(cls.PRIVATE)) + if parts[0]: + # 'private' was not in or not leftmost in the string + return + parts[1] = cls.PUBLIC + public_id = ''.join(parts) + return public_id + + @property + # this only works for vnfs that have both private and public visible + def valid_networks(self): + if self._valid_networks is None: + self._valid_networks = [] + for vld_id in self.networks: + public_id = self.get_public_id(vld_id) + if public_id in self.networks: + self._valid_networks.append((vld_id, public_id)) + return self._valid_networks + + @property + def all_ports(self): + if self._all_ports is None: + self._all_ports = sorted(set(self.priv_ports + self.pub_ports)) + return self._all_ports + + @property + def priv_ports(self): + if self._priv_ports is None: + intfs = chain.from_iterable( + intfs for vld_id, intfs in self.networks.items() if + vld_id.startswith(self.PRIVATE)) + self._priv_ports = sorted(set(intfs)) + return self._priv_ports + + @property + def pub_ports(self): + if self._pub_ports is None: + intfs = chain.from_iterable( + intfs for vld_id, intfs in self.networks.items() if vld_id.startswith(self.PUBLIC)) + self._pub_ports = sorted(set(intfs)) + return self._pub_ports + + @property + def port_pair_list(self): + if self._port_pair_list is None: + self._port_pair_list = [] + + for priv, pub in self.valid_networks: + for private_intf in self.networks[priv]: + # only VNFs have private, public peers + peer_intfs = self.networks.get(pub, []) + if peer_intfs: + for public_intf in peer_intfs: + port_pair = private_intf, public_intf + self._port_pair_list.append(port_pair) + return self._port_pair_list + + class MultiPortConfig(object): HW_LB = "HW" @@ -108,7 +199,7 @@ class MultiPortConfig(object): ip_addr = cls.make_ip_addr(ip_addr, prefixlen) return ip_addr.ip.exploded, ip_addr.network.prefixlen - def __init__(self, topology_file, config_tpl, tmp_file, interfaces=None, + def __init__(self, topology_file, config_tpl, tmp_file, vnfd_helper, vnf_type='CGNAT', lb_count=2, worker_threads=3, worker_config='1C/1T', lb_config='SW', socket=0): @@ -118,8 +209,7 @@ class MultiPortConfig(object): self.worker_threads = self.get_worker_threads(worker_threads) self.vnf_type = vnf_type self.pipe_line = 0 - self.interfaces = interfaces if interfaces else {} - self.networks = {} + self.vnfd_helper = vnfd_helper self.write_parser = ConfigParser() self.read_parser = ConfigParser() self.read_parser.read(config_tpl) @@ -138,6 +228,8 @@ class MultiPortConfig(object): self.start_core = "" self.pipeline_counter = "" self.txrx_pipeline = "" + self._port_pairs = None + self.all_ports = [] self.port_pair_list = [] self.lb_to_port_pair_mapping = {} self.init_eal() @@ -145,12 +237,11 @@ class MultiPortConfig(object): self.lb_index = None self.mul = 0 self.port_pairs = [] - self.port_pair_list = [] self.ports_len = 0 self.prv_que_handler = None self.vnfd = None self.rules = None - self.pktq_out = '' + self.pktq_out = [] @staticmethod def gen_core(core): @@ -160,18 +251,19 @@ class MultiPortConfig(object): return str(core) def make_port_pairs_iter(self, operand, iterable): - return (operand(x[-1], y) for y in iterable for x in chain(*self.port_pairs)) + return (operand(self.vnfd_helper.port_num(x), y) for y in iterable for x in + chain.from_iterable(self.port_pairs)) def make_range_port_pairs_iter(self, operand, start, end): return self.make_port_pairs_iter(operand, range(start, end)) def init_eal(self): - vpci = [v['virtual-interface']["vpci"] for v in self.interfaces] + lines = ['[EAL]\n'] + vpci = (v['virtual-interface']["vpci"] for v in self.vnfd_helper.interfaces) + lines.extend('w = {0}\n'.format(item) for item in vpci) + lines.append('\n') with open(self.tmp_file, 'w') as fh: - fh.write('[EAL]\n') - for item in vpci: - fh.write('w = {0}\n'.format(item)) - fh.write('\n') + fh.writelines(lines) def update_timer(self): timer_tpl = self.get_config_tpl_data('TIMER') @@ -226,40 +318,6 @@ class MultiPortConfig(object): except ValueError: self.start_core = int(self.start_core[:-1]) + 1 - @staticmethod - def get_port_pairs(interfaces): - port_pair_list = [] - networks = {} - for private_intf in interfaces: - vintf = private_intf['virtual-interface'] - 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 - parts = list(name.partition('private')) - if parts[0]: - # 'private' was not in or not leftmost in the string - continue - parts[1] = 'public' - public_id = ''.join(parts) - for private_intf in net: - try: - public_peer_intfs = networks[public_id] - except KeyError: - LOG.warning("private network without peer %s, %s not found", name, public_id) - continue - - for public_intf in public_peer_intfs: - port_pair = private_intf["ifname"], public_intf["ifname"] - port_pair_list.append(port_pair) - - return port_pair_list, networks - def get_lb_count(self): self.lb_count = int(min(len(self.port_pair_list), self.lb_count)) @@ -267,50 +325,51 @@ class MultiPortConfig(object): self.lb_to_port_pair_mapping = defaultdict(int) port_pair_count = len(self.port_pair_list) lb_pair_count = int(port_pair_count / self.lb_count) - for i in range(self.lb_count): - self.lb_to_port_pair_mapping[i + 1] = lb_pair_count - for i in range(port_pair_count % self.lb_count): - self.lb_to_port_pair_mapping[i + 1] += 1 + extra = port_pair_count % self.lb_count + extra_iter = repeat(lb_pair_count + 1, extra) + norm_iter = repeat(lb_pair_count, port_pair_count - extra) + new_values = {i: v for i, v in enumerate(chain(extra_iter, norm_iter), 1)} + self.lb_to_port_pair_mapping.update(new_values) def set_priv_to_pub_mapping(self): - return "".join(str(y) for y in [(int(x[0][-1]), int(x[1][-1])) for x in - self.port_pair_list]) + port_nums = [tuple(self.vnfd_helper.port_nums(x)) for x in self.port_pair_list] + return "".join(str(y).replace(" ", "") for y in + port_nums) def set_priv_que_handler(self): # iterated twice, can't be generator - priv_to_pub_map = [(int(x[0][-1]), int(x[1][-1])) for x in self.port_pairs] + priv_to_pub_map = [tuple(self.vnfd_helper.port_nums(x)) for x in self.port_pairs] # must be list to use .index() port_list = list(chain.from_iterable(priv_to_pub_map)) priv_ports = (x[0] for x in priv_to_pub_map) self.prv_que_handler = '({})'.format( - ",".join((str(port_list.index(x)) for x in priv_ports))) + "".join(("{},".format(port_list.index(x)) for x in priv_ports))) def generate_arp_route_tbl(self): - arp_config = [] arp_route_tbl_tmpl = "({port0_dst_ip_hex},{port0_netmask_hex},{port_num}," \ "{next_hop_ip_hex})" - for port_pair in self.port_pair_list: - for port in port_pair: - port_num = int(port[-1]) - interface = self.interfaces[port_num] - # We must use the dst because we are on the VNF and we need to - # reach the TG. - dst_port0_ip = \ - ipaddress.ip_interface(six.text_type( - "%s/%s" % (interface["virtual-interface"]["dst_ip"], - interface["virtual-interface"]["netmask"]))) - arp_vars = { - "port0_dst_ip_hex": ip_to_hex(dst_port0_ip.network.network_address.exploded), - "port0_netmask_hex": ip_to_hex(dst_port0_ip.network.netmask.exploded), - # this is the port num that contains port0 subnet and next_hop_ip_hex - "port_num": port_num, - # next hop is dst in this case - # must be within subnet - "next_hop_ip_hex": ip_to_hex(dst_port0_ip.ip.exploded), - } - arp_config.append(arp_route_tbl_tmpl.format(**arp_vars)) - - return ' '.join(arp_config) + + def build_arp_config(port): + dpdk_port_num = self.vnfd_helper.port_num(port) + interface = self.vnfd_helper.find_interface(name=port)["virtual-interface"] + # We must use the dst because we are on the VNF and we need to + # reach the TG. + dst_port0_ip = ipaddress.ip_interface(six.text_type( + "%s/%s" % (interface["dst_ip"], interface["netmask"]))) + + arp_vars = { + "port0_dst_ip_hex": ip_to_hex(dst_port0_ip.network.network_address.exploded), + "port0_netmask_hex": ip_to_hex(dst_port0_ip.network.netmask.exploded), + # this is the port num that contains port0 subnet and next_hop_ip_hex + # this is LINKID which should be based on DPDK port number + "port_num": dpdk_port_num, + # next hop is dst in this case + # must be within subnet + "next_hop_ip_hex": ip_to_hex(dst_port0_ip.ip.exploded), + } + return arp_route_tbl_tmpl.format(**arp_vars) + + return ' '.join(build_arp_config(port) for port in self.all_ports) def generate_arpicmp_data(self): swq_in_str = self.make_range_str('SWQ{}', self.swq, offset=self.lb_count) @@ -318,9 +377,11 @@ class MultiPortConfig(object): swq_out_str = self.make_range_str('SWQ{}', self.swq, offset=self.lb_count) self.swq += self.lb_count # ports_mac_list is disabled for some reason - # mac_iter = (self.interfaces[int(x[-1])]['virtual-interface']['local_mac'] - # for port_pair in self.port_pair_list for x in port_pair) - pktq_in_iter = ('RXQ{}'.format(float(x[0][-1])) for x in self.port_pair_list) + + # mac_iter = (self.vnfd_helper.find_interface(name=port)['virtual-interface']['local_mac'] + # for port in self.all_ports) + pktq_in_iter = ('RXQ{}.0'.format(self.vnfd_helper.port_num(x[0])) for x in + self.port_pair_list) arpicmp_data = { 'core': self.gen_core(self.start_core), @@ -505,7 +566,10 @@ class MultiPortConfig(object): self.vnf_tpl = self.get_config_tpl_data(self.vnf_type) def generate_config(self): - self.port_pair_list, self.networks = self.get_port_pairs(self.interfaces) + self._port_pairs = PortPairs(self.vnfd_helper.interfaces) + self.port_pair_list = self._port_pairs.port_pair_list + self.all_ports = self._port_pairs.all_ports + self.get_lb_count() self.generate_lb_to_port_pair_mapping() self.generate_config_data() @@ -514,18 +578,16 @@ class MultiPortConfig(object): self.write_parser.write(tfh) def generate_link_config(self): + def build_args(port): + # lookup interface by name + virtual_interface = self.vnfd_helper.find_interface(name=port)["virtual-interface"] + local_ip = virtual_interface["local_ip"] + netmask = virtual_interface["netmask"] + port_num = self.vnfd_helper.port_num(port) + port_ip, prefix_len = self.validate_ip_and_prefixlen(local_ip, netmask) + return LINK_CONFIG_TEMPLATE.format(port_num, port_ip, prefix_len) - link_configs = [] - for port_pair in self.port_pair_list: - for port in port_pair: - port = port[-1] - virtual_interface = self.interfaces[int(port)]["virtual-interface"] - local_ip = virtual_interface["local_ip"] - netmask = virtual_interface["netmask"] - port_ip, prefix_len = self.validate_ip_and_prefixlen(local_ip, netmask) - link_configs.append(LINK_CONFIG_TEMPLATE.format(port, port_ip, prefix_len)) - - return ''.join(link_configs) + return ''.join(build_args(port) for port in self.all_ports) def get_route_data(self, src_key, data_key, port): route_list = self.vnfd['vdu'][0].get(src_key, []) @@ -548,37 +610,38 @@ class MultiPortConfig(object): def generate_arp_config(self): arp_config = [] - for port_pair in self.port_pair_list: - for port in port_pair: - # ignore gateway, always use TG IP - # gateway = self.get_ports_gateway(port) - dst_mac = self.interfaces[int(port[-1])]["virtual-interface"]["dst_mac"] - dst_ip = self.interfaces[int(port[-1])]["virtual-interface"]["dst_ip"] - # arp_config.append((port[-1], gateway, dst_mac, self.txrx_pipeline)) - # so dst_mac is the TG dest mac, so we need TG dest IP. - arp_config.append((port[-1], dst_ip, dst_mac, self.txrx_pipeline)) + for port in self.all_ports: + # ignore gateway, always use TG IP + # gateway = self.get_ports_gateway(port) + vintf = self.vnfd_helper.find_interface(name=port)["virtual-interface"] + dst_mac = vintf["dst_mac"] + dst_ip = vintf["dst_ip"] + # arp_config.append( + # (self.vnfd_helper.port_num(port), gateway, dst_mac, self.txrx_pipeline)) + # so dst_mac is the TG dest mac, so we need TG dest IP. + # should be dpdk_port_num + arp_config.append( + (self.vnfd_helper.port_num(port), dst_ip, dst_mac, self.txrx_pipeline)) return '\n'.join(('p {3} arpadd {0} {1} {2}'.format(*values) for values in arp_config)) def generate_arp_config6(self): arp_config6 = [] - for port_pair in self.port_pair_list: - for port in port_pair: - # ignore gateway, always use TG IP - # gateway6 = self.get_ports_gateway6(port) - dst_mac6 = self.interfaces[int(port[-1])]["virtual-interface"]["dst_mac"] - dst_ip6 = self.interfaces[int(port[-1])]["virtual-interface"]["dst_ip"] - # arp_config6.append((port[-1], gateway6, dst_mac6, self.txrx_pipeline)) - arp_config6.append((port[-1], dst_ip6, dst_mac6, self.txrx_pipeline)) + for port in self.all_ports: + # ignore gateway, always use TG IP + # gateway6 = self.get_ports_gateway6(port) + vintf = self.vnfd_helper.find_interface(name=port)["virtual-interface"] + dst_mac6 = vintf["dst_mac"] + dst_ip6 = vintf["dst_ip"] + # arp_config6.append( + # (self.vnfd_helper.port_num(port), gateway6, dst_mac6, self.txrx_pipeline)) + arp_config6.append( + (self.vnfd_helper.port_num(port), dst_ip6, dst_mac6, self.txrx_pipeline)) return '\n'.join(('p {3} arpadd {0} {1} {2}'.format(*values) for values in arp_config6)) def generate_action_config(self): - port_list = [] - for port_pair in self.port_pair_list: - for port in port_pair: - port_list.append(port[-1]) - + port_list = (self.vnfd_helper.port_num(p) for p in self.all_ports) if self.vnf_type == "VFW": template = FW_ACTION_TEMPLATE else: @@ -589,8 +652,9 @@ class MultiPortConfig(object): def get_ip_from_port(self, port): # we can't use gateway because in OpenStack gateways interfer with floating ip routing # return self.make_ip_addr(self.get_ports_gateway(port), self.get_netmask_gateway(port)) - ip = self.interfaces[port]["virtual-interface"]["local_ip"] - netmask = self.interfaces[port]["virtual-interface"]["netmask"] + vintf = self.vnfd_helper.find_interface(name=port)["virtual-interface"] + ip = vintf["local_ip"] + netmask = vintf["netmask"] return self.make_ip_addr(ip, netmask) def get_network_and_prefixlen_from_ip_of_port(self, port): @@ -607,12 +671,12 @@ class MultiPortConfig(object): new_rules = [] new_ipv6_rules = [] pattern = 'p {0} add {1} {2} {3} {4} {5} 0 65535 0 65535 0 0 {6}' - for port_pair in self.port_pair_list: - src_port = int(port_pair[0][-1]) - dst_port = int(port_pair[1][-1]) + for src_intf, dst_intf in self.port_pair_list: + src_port = self.vnfd_helper.port_num(src_intf) + dst_port = self.vnfd_helper.port_num(dst_intf) - src_net, src_prefix_len = self.get_network_and_prefixlen_from_ip_of_port(src_port) - dst_net, dst_prefix_len = self.get_network_and_prefixlen_from_ip_of_port(dst_port) + src_net, src_prefix_len = self.get_network_and_prefixlen_from_ip_of_port(src_intf) + dst_net, dst_prefix_len = self.get_network_and_prefixlen_from_ip_of_port(dst_intf) # ignore entires with empty values if all((src_net, src_prefix_len, dst_net, dst_prefix_len)): new_rules.append((cmd, self.txrx_pipeline, src_net, src_prefix_len, @@ -637,7 +701,8 @@ class MultiPortConfig(object): return ''.join([rules_config, new_rules_config, acl_apply]) def generate_script_data(self): - self.port_pair_list, self.networks = self.get_port_pairs(self.interfaces) + self._port_pairs = PortPairs(self.vnfd_helper.interfaces) + self.port_pair_list = self._port_pairs.port_pair_list self.get_lb_count() script_data = { 'link_config': self.generate_link_config(), @@ -675,5 +740,5 @@ set_hash_input_set {0} ipv6-udp src-ipv6 udp-src-port add set_hash_input_set {1} ipv6-udp dst-ipv6 udp-dst-port add """ for port_pair in self.port_pair_list: - script += hwlb_tpl.format(port_pair[0][-1], port_pair[1][-1]) + script += hwlb_tpl.format(*(self.vnfd_helper.port_nums(port_pair))) return script diff --git a/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py b/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py index 38831ee86..1ec00e5bc 100644 --- a/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py +++ b/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py @@ -113,10 +113,10 @@ class IxNextgen(object): } MODE_SEEDS_MAP = { - 0: ('private_1', ['256', '2048']), + 0: ('private_0', ['256', '2048']), } - MODE_SEEDS_DEFAULT = 'public_1', ['2048', '256'] + MODE_SEEDS_DEFAULT = 'public_0', ['2048', '256'] @staticmethod def find_view_obj(view_name, views): diff --git a/yardstick/network_services/nfvi/resource.py b/yardstick/network_services/nfvi/resource.py index 055fdba7e..fa32a4dcf 100644 --- a/yardstick/network_services/nfvi/resource.py +++ b/yardstick/network_services/nfvi/resource.py @@ -21,11 +21,11 @@ import os import os.path import re import multiprocessing -from collections import Sequence from oslo_config import cfg from yardstick import ssh +from yardstick.common.utils import validate_non_string_sequence from yardstick.network_services.nfvi.collectd import AmqpConsumer from yardstick.network_services.utils import get_nsb_option @@ -45,16 +45,14 @@ class ResourceProfile(object): def __init__(self, mgmt, interfaces=None, cores=None): self.enable = True - self.connection = None - self.cores = cores if isinstance(cores, Sequence) else [] + self.cores = validate_non_string_sequence(cores, default=[]) self._queue = multiprocessing.Queue() self.amqp_client = None - self.interfaces = interfaces if isinstance(interfaces, Sequence) else [] + self.interfaces = validate_non_string_sequence(interfaces, default=[]) # why the host or ip? self.vnfip = mgmt.get("host", mgmt["ip"]) self.connection = ssh.SSH.from_node(mgmt, overrides={"ip": self.vnfip}) - self.connection.wait() def check_if_sa_running(self, process): @@ -111,7 +109,7 @@ class ResourceProfile(object): @classmethod def parse_intel_pmu_stats(cls, key, value): - return {''.join(key): value.split(":")[1]} + return {''.join(str(v) for v in key): value.split(":")[1]} def parse_collectd_result(self, metrics, core_list): """ convert collectd data into json""" @@ -234,7 +232,7 @@ class ResourceProfile(object): connection.execute("sudo rabbitmqctl delete_user guest") connection.execute("sudo rabbitmqctl add_user admin admin") connection.execute("sudo rabbitmqctl authenticate_user admin admin") - connection.execute("sudo rabbitmqctl set_permissions -p / admin \".*\" \".*\" \".*\"") + connection.execute("sudo rabbitmqctl set_permissions -p / admin '.*' '.*' '.*'") LOG.debug("Start collectd service.....") connection.execute("sudo %s" % collectd_path) diff --git a/yardstick/network_services/traffic_profile/base.py b/yardstick/network_services/traffic_profile/base.py index 906498586..611792b94 100644 --- a/yardstick/network_services/traffic_profile/base.py +++ b/yardstick/network_services/traffic_profile/base.py @@ -44,7 +44,7 @@ class TrafficProfile(object): # IMIX = {"10K": 0.1, "100M": 0.5} self.params = tp_config - def execute(self, traffic_generator): + def execute_traffic(self, traffic_generator): """ This methods defines the behavior of the traffic generator. It will be called in a loop until the traffic generator exits. diff --git a/yardstick/network_services/traffic_profile/ixia_rfc2544.py b/yardstick/network_services/traffic_profile/ixia_rfc2544.py index ddb41f3c0..049a81a65 100644 --- a/yardstick/network_services/traffic_profile/ixia_rfc2544.py +++ b/yardstick/network_services/traffic_profile/ixia_rfc2544.py @@ -23,11 +23,17 @@ LOG = logging.getLogger(__name__) class IXIARFC2544Profile(TrexProfile): - def _get_ixia_traffic_profile(self, profile_data, mac={}, - xfile=None, static_traffic={}): + + def _get_ixia_traffic_profile(self, profile_data, mac=None, xfile=None, static_traffic=None): + if mac is None: + mac = {} + + if static_traffic is None: + static_traffic = {} + result = {} if xfile: - with open(xfile, 'r') as stream: + with open(xfile) as stream: try: static_traffic = json.load(stream) except Exception as exc: @@ -73,7 +79,7 @@ class IXIARFC2544Profile(TrexProfile): def _ixia_traffic_generate(self, traffic_generator, traffic, ixia_obj): for key, value in traffic.items(): if "public" in key or "private" in key: - traffic[key]["iload"] = str(self.rate) + value["iload"] = str(self.rate) ixia_obj.ix_update_frame(traffic) ixia_obj.ix_update_ether(traffic) ixia_obj.add_ip_header(traffic, 4) @@ -81,19 +87,27 @@ class IXIARFC2544Profile(TrexProfile): self.tmp_drop = 0 self.tmp_throughput = 0 - def update_traffic_profile(self): - self.profile = 'private_1' - for key, value in self.params.items(): - if "private" in key or "public" in key: - self.profile_data = self.params[key] + def update_traffic_profile(self, traffic_generator): + def port_generator(): + for vld_id, intfs in sorted(traffic_generator.networks.items()): + if not vld_id.startswith(("private", "public")): + continue + profile_data = self.params.get(vld_id) + if not profile_data: + continue + self.profile_data = profile_data self.get_streams(self.profile_data) - self.full_profile.update({key: self.profile_data}) + self.full_profile.update({vld_id: self.profile_data}) + for intf in intfs: + yield traffic_generator.vnfd_helper.port_num(intf) + + self.ports = [port for port in port_generator()] - def execute(self, traffic_generator, ixia_obj, mac={}, xfile=None): + def execute_traffic(self, traffic_generator, ixia_obj, mac={}, xfile=None): if self.first_run: self.full_profile = {} self.pg_id = 0 - self.update_traffic_profile() + self.update_traffic_profile(traffic_generator) traffic = \ self._get_ixia_traffic_profile(self.full_profile, mac, xfile) self.max_rate = self.rate @@ -108,7 +122,7 @@ class IXIARFC2544Profile(TrexProfile): def start_ixia_latency(self, traffic_generator, ixia_obj, mac={}, xfile=None): - self.update_traffic_profile() + self.update_traffic_profile(traffic_generator) traffic = \ self._get_ixia_traffic_profile(self.full_profile, mac, xfile) self._ixia_traffic_generate(traffic_generator, traffic, diff --git a/yardstick/network_services/traffic_profile/rfc2544.py b/yardstick/network_services/traffic_profile/rfc2544.py index a3b803673..6a0ecaf99 100644 --- a/yardstick/network_services/traffic_profile/rfc2544.py +++ b/yardstick/network_services/traffic_profile/rfc2544.py @@ -43,7 +43,7 @@ class RFC2544Profile(TrexProfile): def register_generator(self, generator): self.generator = generator - def execute(self, traffic_generator=None): + def execute_traffic(self, traffic_generator=None): """ Generate the stream and run traffic on the given ports """ if traffic_generator is not None and self.generator is None: self.generator = traffic_generator @@ -52,21 +52,18 @@ class RFC2544Profile(TrexProfile): return self.ports = [] - priv_ports = self.generator.priv_ports - pub_ports = self.generator.pub_ports - # start from 1 for private_1, public_1, etc. - for index, (priv_port, pub_port) in enumerate(zip(priv_ports, pub_ports), 1): - profile_data = self.params.get('private_{}'.format(index), '') - self.ports.append(priv_port) - # pass profile_data directly, don't use self.profile_data - self.generator.client.add_streams(self.get_streams(profile_data), ports=priv_port) - profile_data = self.params.get('public_{}'.format(index), '') + for vld_id, intfs in sorted(self.generator.networks.items()): + profile_data = self.params.get(vld_id) + # no profile for this port + if not profile_data: + continue # correlated traffic doesn't use public traffic? - if not profile_data or self.generator.rfc2544_helper.correlated_traffic: + if vld_id.startswith("public") and self.generator.rfc2544_helper.correlated_traffic: continue - # just get the pub_port - self.ports.append(pub_port) - self.generator.client.add_streams(self.get_streams(profile_data), ports=pub_port) + for intf in intfs: + port = self.generator.vnfd_helper.port_num(intf) + self.ports.append(port) + self.generator.client.add_streams(self.get_streams(profile_data), ports=port) self.max_rate = self.rate self.min_rate = 0 @@ -86,7 +83,7 @@ class RFC2544Profile(TrexProfile): if generator is None: generator = self.generator run_duration = self.generator.RUN_DURATION - samples = self.generator.generate_samples() + samples = self.generator.generate_samples(self.ports) in_packets = sum([value['in_packets'] for value in samples.values()]) out_packets = sum([value['out_packets'] for value in samples.values()]) @@ -135,8 +132,8 @@ class RFC2544Profile(TrexProfile): # TODO(esm): why don't we discard results that are out of tolerance? self.min_rate = self.rate - generator.clear_client_stats() - generator.start_client(mult=self.get_multiplier(), + generator.clear_client_stats(self.ports) + generator.start_client(self.ports, mult=self.get_multiplier(), duration=run_duration, force=True) # if correlated traffic update the Throughput diff --git a/yardstick/network_services/traffic_profile/traffic_profile.py b/yardstick/network_services/traffic_profile/traffic_profile.py index 4c6595d94..894126c09 100644 --- a/yardstick/network_services/traffic_profile/traffic_profile.py +++ b/yardstick/network_services/traffic_profile/traffic_profile.py @@ -188,9 +188,9 @@ class TrexProfile(TrafficProfile): ), } - def execute(self, traffic_generator): + def execute_traffic(self, traffic_generator): """ Generate the stream and run traffic on the given ports """ - pass + raise NotImplementedError() def _call_on_range(self, range, single_action, range_action, count=1, to_int=False): def convert_to_int(val): diff --git a/yardstick/network_services/vnf_generic/vnf/acl_vnf.py b/yardstick/network_services/vnf_generic/vnf/acl_vnf.py index 5f3c8a0cd..3ba38dec2 100644 --- a/yardstick/network_services/vnf_generic/vnf/acl_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/acl_vnf.py @@ -24,7 +24,7 @@ LOG = logging.getLogger(__name__) # ACL should work the same on all systems, we can provide the binary ACL_PIPELINE_COMMAND = \ - 'sudo {tool_path} -p {ports_len_hex} -f {cfg_file} -s {script}' + 'sudo {tool_path} -p {port_mask_hex} -f {cfg_file} -s {script}' ACL_COLLECT_KPI = r"""\ ACL TOTAL:[^p]+pkts_processed"?:\s(\d+),[^p]+pkts_drop"?:\s(\d+),[^p]+pkts_received"?:\s(\d+),""" diff --git a/yardstick/network_services/vnf_generic/vnf/base.py b/yardstick/network_services/vnf_generic/vnf/base.py index 955f9f03d..e32e5fb50 100644 --- a/yardstick/network_services/vnf_generic/vnf/base.py +++ b/yardstick/network_services/vnf_generic/vnf/base.py @@ -16,6 +16,8 @@ from __future__ import absolute_import import logging +from yardstick.network_services.helpers.samplevnf_helper import PortPairs + LOG = logging.getLogger(__name__) @@ -59,6 +61,10 @@ class QueueFileWrapper(object): class VnfdHelper(dict): + def __init__(self, *args, **kwargs): + super(VnfdHelper, self).__init__(*args, **kwargs) + self.port_pairs = PortPairs(self['vdu'][0]['external-interface']) + @property def mgmt_interface(self): return self["mgmt-interface"] @@ -92,6 +98,28 @@ class VnfdHelper(dict): if interface[key] == value: return interface + # hide dpdk_port_num key so we can abstract + def find_interface_by_port(self, port): + for interface in self.interfaces: + virtual_intf = interface["virtual-interface"] + # we have to convert to int to compare + if int(virtual_intf['dpdk_port_num']) == port: + return interface + + def port_num(self, name): + # we need interface name -> DPDK port num (PMD ID) -> LINK ID + # LINK ID -> PMD ID is governed by the port mask + """ + + :rtype: int + :type name: str + """ + intf = self.find_interface(name=name) + return int(intf["virtual-interface"]["dpdk_port_num"]) + + def port_nums(self, intfs): + return [self.port_num(i) for i in intfs] + class VNFObject(object): diff --git a/yardstick/network_services/vnf_generic/vnf/cgnapt_vnf.py b/yardstick/network_services/vnf_generic/vnf/cgnapt_vnf.py index f9980b165..45ef757b3 100644 --- a/yardstick/network_services/vnf_generic/vnf/cgnapt_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/cgnapt_vnf.py @@ -13,16 +13,14 @@ # limitations under the License. from __future__ import absolute_import -import time import logging -from six.moves import zip from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF, DpdkVnfSetupEnvHelper LOG = logging.getLogger(__name__) # CGNAPT should work the same on all systems, we can provide the binary -CGNAPT_PIPELINE_COMMAND = 'sudo {tool_path} -p {ports_len_hex} -f {cfg_file} -s {script}' +CGNAPT_PIPELINE_COMMAND = 'sudo {tool_path} -p {port_mask_hex} -f {cfg_file} -s {script}' WAIT_FOR_STATIC_NAPT = 4 CGNAPT_COLLECT_KPI = """\ @@ -55,7 +53,7 @@ class CgnaptApproxSetupEnvHelper(DpdkVnfSetupEnvHelper): yield '.'.join(ip_parts) @staticmethod - def _update_cgnat_script_file(ip_pipeline_cfg, mcpi, vnf_str): + def _update_cgnat_script_file(ip_pipeline_cfg, mcpi): pipeline_config_str = str(ip_pipeline_cfg) input_cmds = '\n'.join(mcpi) icmp_flag = 'link 0 down' in input_cmds @@ -67,16 +65,13 @@ class CgnaptApproxSetupEnvHelper(DpdkVnfSetupEnvHelper): raise NotImplementedError def _get_cgnapt_config(self, interfaces=None): + # TODO: static CGNAPT is broken, don't use it if interfaces is None: interfaces = self.vnfd_helper.interfaces - gateway_ips = [] - # fixme: Get private port and gateway from port list - priv_ports = interfaces[::2] - for interface in priv_ports: - gateway_ips.append(self._get_ports_gateway(interface["name"])) - return gateway_ips + priv_ports = self.vnfd_helper.port_pairs.priv_ports + return [self._get_ports_gateway(intf["name"]) for intf in priv_ports] class CgnaptApproxVnf(SampleVNF): @@ -103,21 +98,23 @@ class CgnaptApproxVnf(SampleVNF): if self.scenario_helper.options.get('napt', 'static') != 'static': return - ip_iter = self.setup_helper._generate_ip_from_pool("152.16.40.10") - gw_ips = self.setup_helper._get_cgnapt_config() - if self.scenario_helper.vnf_cfg.get("lb_config", "SW") == 'HW': - pipeline = self.setup_helper.HW_DEFAULT_CORE - offset = 3 - else: - pipeline = self.setup_helper.SW_DEFAULT_CORE - 1 - offset = 0 - - worker_threads = int(self.scenario_helper.vnf_cfg["worker_threads"]) - cmd_template = "p {0} entry addm {1} 1 {2} 1 0 32 65535 65535 65535" - for gw, ip in zip(gw_ips, ip_iter): - cmd = cmd_template.format(pipeline, gw, ip) - pipeline += worker_threads - pipeline += offset - self.vnf_execute(cmd) - - time.sleep(WAIT_FOR_STATIC_NAPT) + # ip_iter = self.setup_helper._generate_ip_from_pool("152.16.40.10") + # gw_ips = self.setup_helper._get_cgnapt_config() + # if self.scenario_helper.vnf_cfg.get("lb_config", "SW") == 'HW': + # pipeline = self.setup_helper.HW_DEFAULT_CORE + # offset = 3 + # else: + # pipeline = self.setup_helper.SW_DEFAULT_CORE - 1 + # offset = 0 + # + # worker_threads = int(self.scenario_helper.vnf_cfg["worker_threads"]) + # # p <pipeline id> entry addm <prv_ipv4/6> prvport> <pub_ip> <pub_port> <phy_port> <ttl> + # # <no_of_entries> <end_prv_port> <end_pub_port> + # cmd_template = "p {0} entry addm {1} 1 {2} 1 0 32 65535 65535 65535" + # for gw, ip in zip(gw_ips, ip_iter): + # cmd = cmd_template.format(pipeline, gw, ip) + # pipeline += worker_threads + # pipeline += offset + # self.vnf_execute(cmd) + # + # time.sleep(WAIT_FOR_STATIC_NAPT) diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py index d6ec271c9..00ab6c24c 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py @@ -639,9 +639,10 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): prox_config.parse() # Ensure MAC is set "hardware" - ext_intf = self.vnfd_helper.interfaces - # we are using enumeration to map logical port numbers to interfaces - for port_num, intf in enumerate(ext_intf): + all_ports = self.vnfd_helper.port_pairs.all_ports + # use dpdk port number + for port_name in all_ports: + port_num = self.vnfd_helper.port_num(port_name) port_section_name = "port {}".format(port_num) for section_name, section in sections: if port_section_name != section_name: @@ -659,13 +660,15 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): if item_val.startswith("@@dst_mac"): tx_port_iter = re.finditer(r'\d+', item_val) tx_port_no = int(next(tx_port_iter).group(0)) - mac = ext_intf[tx_port_no]["virtual-interface"]["dst_mac"] + intf = self.vnfd_helper.find_interface_by_port(tx_port_no) + mac = intf["virtual-interface"]["dst_mac"] section_data[1] = mac.replace(":", " ", 6) if item_key == "dst mac" and item_val.startswith("@@"): tx_port_iter = re.finditer(r'\d+', item_val) tx_port_no = int(next(tx_port_iter).group(0)) - mac = ext_intf[tx_port_no]["virtual-interface"]["dst_mac"] + intf = self.vnfd_helper.find_interface_by_port(tx_port_no) + mac = intf["virtual-interface"]["dst_mac"] section_data[1] = mac # if addition file specified in prox config @@ -714,13 +717,15 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): def generate_prox_lua_file(self): p = OrderedDict() - ext_intf = self.vnfd_helper.interfaces + all_ports = self.vnfd_helper.port_pairs.all_ports lua_param = self.LUA_PARAMETER_NAME - for intf in ext_intf: + for port_name in all_ports: peer = self.LUA_PARAMETER_PEER[lua_param] - port_num = intf["virtual-interface"]["dpdk_port_num"] - local_ip = intf["local_ip"] - dst_ip = intf["dst_ip"] + port_num = self.vnfd_helper.port_num(port_name) + intf = self.vnfd_helper.find_interface(name=port_name) + vintf = intf['virtual-interface'] + local_ip = vintf["local_ip"] + dst_ip = vintf["dst_ip"] local_ip_hex = ip_to_hex(local_ip, separator=' ') dst_ip_hex = ip_to_hex(dst_ip, separator=' ') p.update([ @@ -880,7 +885,7 @@ class ProxResourceHelper(ClientResourceHelper): self._run_traffic_once(traffic_profile) def _run_traffic_once(self, traffic_profile): - traffic_profile.execute(self) + traffic_profile.execute_traffic(self) if traffic_profile.done: self._queue.put({'done': True}) LOG.debug("tg_prox done") @@ -922,12 +927,11 @@ class ProxResourceHelper(ClientResourceHelper): self.sut.stop_all() def run_test(self, pkt_size, duration, value, tolerated_loss=0.0): - # type: (object, object, object, object) -> object # do this assert in init? unless we expect interface count to # change from one run to another run... - interfaces = self.vnfd_helper.interfaces - interface_count = len(interfaces) - assert interface_count in {1, 2, 4}, \ + ports = self.vnfd_helper.port_pairs.all_ports + port_count = len(ports) + assert port_count in {1, 2, 4}, \ "Invalid number of ports: 1, 2 or 4 ports only supported at this time" with self.traffic_context(pkt_size, value): @@ -942,15 +946,18 @@ class ProxResourceHelper(ClientResourceHelper): latency = self.get_latency() deltas = data['delta'] - rx_total, tx_total = self.sut.port_stats(range(interface_count))[6:8] - pps = value / 100.0 * self.line_rate_to_pps(pkt_size, interface_count) + rx_total, tx_total = self.sut.port_stats(range(port_count))[6:8] + pps = value / 100.0 * self.line_rate_to_pps(pkt_size, port_count) samples = {} # we are currently using enumeration to map logical port num to interface - for index, iface in enumerate(interfaces): - port_rx_total, port_tx_total = self.sut.port_stats([index])[6:8] - samples[iface["name"]] = {"in_packets": port_rx_total, - "out_packets": port_tx_total} + for port_name in ports: + port = self.vnfd_helper.port_num(port_name) + port_rx_total, port_tx_total = self.sut.port_stats([port])[6:8] + samples[port_name] = { + "in_packets": port_rx_total, + "out_packets": port_tx_total, + } result = ProxTestDataTuple(tolerated_loss, tsc_hz, deltas.rx, deltas.tx, deltas.tsc, latency, rx_total, tx_total, pps) diff --git a/yardstick/network_services/vnf_generic/vnf/prox_vnf.py b/yardstick/network_services/vnf_generic/vnf/prox_vnf.py index cb09b43f6..bef7c5a33 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_vnf.py @@ -51,9 +51,7 @@ class ProxApproxVnf(SampleVNF): try: return self.resource_helper.execute(cmd, *args, **kwargs) except OSError as e: - if ignore_errors and e.errno in {errno.EPIPE, errno.ESHUTDOWN}: - pass - else: + if not ignore_errors or e.errno not in {errno.EPIPE, errno.ESHUTDOWN}: raise def collect_kpi(self): @@ -66,11 +64,12 @@ class ProxApproxVnf(SampleVNF): } return result - if len(self.vnfd_helper.interfaces) not in {1, 2, 4}: + intf_count = len(self.vnfd_helper.interfaces) + if intf_count not in {1, 2, 4}: raise RuntimeError("Failed ..Invalid no of ports .. " "1, 2 or 4 ports only supported at this time") - port_stats = self.vnf_execute('port_stats', range(len(self.vnfd_helper.interfaces))) + port_stats = self.vnf_execute('port_stats', range(intf_count)) try: rx_total = port_stats[6] tx_total = port_stats[7] @@ -90,7 +89,7 @@ class ProxApproxVnf(SampleVNF): def _tear_down(self): # this should be standardized for all VNFs or removed - self.setup_helper.rebind_drivers() + self.setup_helper.tear_down() def terminate(self): # try to quit with socket commands diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py index 1b2533aad..96e703060 100644 --- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py @@ -30,7 +30,9 @@ from six.moves import cStringIO from yardstick.benchmark.contexts.base import Context from yardstick.benchmark.scenarios.networking.vnf_generic import find_relative_file from yardstick.network_services.helpers.cpu import CpuSysCores +from yardstick.network_services.helpers.samplevnf_helper import PortPairs from yardstick.network_services.helpers.samplevnf_helper import MultiPortConfig +from yardstick.network_services.helpers.dpdknicbind_helper import DpdkBindHelper from yardstick.network_services.nfvi.resource import ResourceProfile from yardstick.network_services.vnf_generic.vnf.base import GenericVNF from yardstick.network_services.vnf_generic.vnf.base import QueueFileWrapper @@ -126,15 +128,11 @@ class SetupEnvHelper(object): class DpdkVnfSetupEnvHelper(SetupEnvHelper): APP_NAME = 'DpdkVnf' - DPDK_BIND_CMD = "sudo {dpdk_nic_bind} {force} -b {driver} {vpci}" - DPDK_UNBIND_CMD = "sudo {dpdk_nic_bind} --force -b {driver} {vpci}" FIND_NET_CMD = "find /sys/class/net -lname '*{}*' -printf '%f'" HW_DEFAULT_CORE = 3 SW_DEFAULT_CORE = 2 - DPDK_STATUS_DRIVER_RE = re.compile(r"(\d{2}:\d{2}\.\d).*drv=([-\w]+)") - @staticmethod def _update_packet_type(ip_pipeline_cfg, traffic_options): match_str = 'pkt_type = ipv4' @@ -165,15 +163,9 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): super(DpdkVnfSetupEnvHelper, self).__init__(vnfd_helper, ssh_helper, scenario_helper) self.all_ports = None self.bound_pci = None - self._dpdk_nic_bind = None self.socket = None self.used_drivers = None - - @property - def dpdk_nic_bind(self): - if self._dpdk_nic_bind is None: - self._dpdk_nic_bind = self.ssh_helper.provision_tool(tool_file="dpdk-devbind.py") - return self._dpdk_nic_bind + self.dpdk_bind_helper = DpdkBindHelper(ssh_helper) def _setup_hugepages(self): cmd = "awk '/Hugepagesize/ { print $2$3 }' < /proc/meminfo" @@ -190,10 +182,6 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): self.ssh_helper.execute("echo %s | sudo tee %s" % (pages, memory_path)) - def _get_dpdk_port_num(self, name): - interface = self.vnfd_helper.find_interface(name=name) - return interface['virtual-interface']['dpdk_port_num'] - def build_config(self): vnf_cfg = self.scenario_helper.vnf_cfg task_path = self.scenario_helper.task_path @@ -216,7 +204,7 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): multiport = MultiPortConfig(self.scenario_helper.topology, config_tpl_cfg, config_basename, - self.vnfd_helper.interfaces, + self.vnfd_helper, self.VNF_TYPE, lb_count, worker_threads, @@ -234,7 +222,6 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): self.ssh_helper.upload_config_file(config_basename, new_config) self.ssh_helper.upload_config_file(script_basename, multiport.generate_script(self.vnfd_helper)) - self.all_ports = multiport.port_pair_list LOG.info("Provision and start the %s", self.APP_NAME) self._build_pipeline_kwargs() @@ -242,11 +229,19 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): def _build_pipeline_kwargs(self): tool_path = self.ssh_helper.provision_tool(tool_file=self.APP_NAME) - ports_len_hex = hex(2 ** (len(self.all_ports) + 1) - 1) + # count the number of actual ports in the list of pairs + # remove duplicate ports + # this is really a mapping from LINK ID to DPDK PMD ID + # e.g. 0x110 maps LINK0 -> PMD_ID_1, LINK1 -> PMD_ID_2 + # 0x1010 maps LINK0 -> PMD_ID_1, LINK1 -> PMD_ID_3 + ports = self.vnfd_helper.port_pairs.all_ports + port_nums = self.vnfd_helper.port_nums(ports) + # create mask from all the dpdk port numbers + ports_mask_hex = hex(sum(2 ** num for num in port_nums)) self.pipeline_kwargs = { 'cfg_file': self.CFG_CONFIG, 'script': self.CFG_SCRIPT, - 'ports_len_hex': ports_len_hex, + 'port_mask_hex': ports_mask_hex, 'tool_path': tool_path, } @@ -285,17 +280,6 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): def _validate_cpu_cfg(self): return self._get_cpu_sibling_list() - def _find_used_drivers(self): - cmd = "{0} -s".format(self.dpdk_nic_bind) - rc, dpdk_status, _ = self.ssh_helper.execute(cmd) - - self.used_drivers = { - vpci: (index, driver) - for index, (vpci, driver) - in enumerate(self.DPDK_STATUS_DRIVER_RE.findall(dpdk_status)) - if any(b.endswith(vpci) for b in self.bound_pci) - } - def setup_vnf_environment(self): self._setup_dpdk() resource = self._setup_resources() @@ -341,65 +325,31 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): def _detect_and_bind_drivers(self): interfaces = self.vnfd_helper.interfaces - self._find_used_drivers() - for vpci, (index, _) in self.used_drivers.items(): - try: - intf1 = next(v for v in interfaces if vpci == v['virtual-interface']['vpci']) - except StopIteration: - pass - else: - intf1['dpdk_port_num'] = index - - for vpci in self.bound_pci: - self._bind_dpdk('igb_uio', vpci) - time.sleep(2) - - # debug dump after binding - self.ssh_helper.execute("sudo {} -s".format(self.dpdk_nic_bind)) + self.dpdk_bind_helper.read_status() + self.dpdk_bind_helper.save_used_drivers() - def rebind_drivers(self, force=True): - if not self.used_drivers: - self._find_used_drivers() - for vpci, (_, driver) in self.used_drivers.items(): - self._bind_dpdk(driver, vpci, force) + self.dpdk_bind_helper.bind(self.bound_pci, 'igb_uio') - def _bind_dpdk(self, driver, vpci, force=True): - if force: - force = '--force ' - else: - force = '' - cmd = self.DPDK_BIND_CMD.format(force=force, - dpdk_nic_bind=self.dpdk_nic_bind, - driver=driver, - vpci=vpci) - self.ssh_helper.execute(cmd) + sorted_dpdk_pci_addresses = sorted(self.dpdk_bind_helper.dpdk_bound_pci_addresses) + for dpdk_port_num, vpci in enumerate(sorted_dpdk_pci_addresses): + try: + intf = next(v for v in interfaces + if vpci == v['virtual-interface']['vpci']) + # force to int + intf['virtual-interface']['dpdk_port_num'] = int(dpdk_port_num) + except: + pass + time.sleep(2) - def _detect_and_bind_dpdk(self, vpci, driver): + def get_local_iface_name_by_vpci(self, vpci): find_net_cmd = self.FIND_NET_CMD.format(vpci) - exit_status, _, _ = self.ssh_helper.execute(find_net_cmd) - if exit_status == 0: - # already bound - return None - self._bind_dpdk(driver, vpci) exit_status, stdout, _ = self.ssh_helper.execute(find_net_cmd) - if exit_status != 0: - # failed to bind - return None - return stdout - - def _bind_kernel_devices(self): - # only used by PingSetupEnvHelper? - for intf in self.vnfd_helper.interfaces: - vi = intf["virtual-interface"] - stdout = self._detect_and_bind_dpdk(vi["vpci"], vi["driver"]) - if stdout is not None: - vi["local_iface_name"] = posixpath.basename(stdout) + if exit_status == 0: + return stdout + return None def tear_down(self): - for vpci, (_, driver) in self.used_drivers.items(): - self.ssh_helper.execute(self.DPDK_UNBIND_CMD.format(dpdk_nic_bind=self.dpdk_nic_bind, - driver=driver, - vpci=vpci)) + self.dpdk_bind_helper.rebind_drivers() class ResourceHelper(object): @@ -458,14 +408,17 @@ class ClientResourceHelper(ResourceHelper): self.client = None self.client_started = Value('i', 0) - self.my_ports = None + self.all_ports = None self._queue = Queue() self._result = {} self._terminated = Value('i', 0) self._vpci_ascending = None def _build_ports(self): - self.my_ports = [0, 1] + self.networks = self.vnfd_helper.port_pairs.networks + self.priv_ports = self.vnfd_helper.port_nums(self.vnfd_helper.port_pairs.priv_ports) + self.pub_ports = self.vnfd_helper.port_nums(self.vnfd_helper.port_pairs.pub_ports) + self.all_ports = self.vnfd_helper.port_nums(self.vnfd_helper.port_pairs.all_ports) def get_stats(self, *args, **kwargs): try: @@ -474,8 +427,9 @@ class ClientResourceHelper(ResourceHelper): LOG.exception("TRex client not connected") return {} - def generate_samples(self, key=None, default=None): - last_result = self.get_stats(self.my_ports) + def generate_samples(self, ports, key=None, default=None): + # needs to be used ports + last_result = self.get_stats(ports) key_value = last_result.get(key, default) if not isinstance(last_result, Mapping): # added for mock unit test @@ -483,27 +437,29 @@ class ClientResourceHelper(ResourceHelper): return {} samples = {} - for vpci_idx, vpci in enumerate(self._vpci_ascending): - name = self.vnfd_helper.find_virtual_interface(vpci=vpci)["name"] - # fixme: VNFDs KPIs values needs to be mapped to TRex structure - xe_value = last_result.get(vpci_idx, {}) - samples[name] = { - "rx_throughput_fps": float(xe_value.get("rx_pps", 0.0)), - "tx_throughput_fps": float(xe_value.get("tx_pps", 0.0)), - "rx_throughput_mbps": float(xe_value.get("rx_bps", 0.0)), - "tx_throughput_mbps": float(xe_value.get("tx_bps", 0.0)), - "in_packets": int(xe_value.get("ipackets", 0)), - "out_packets": int(xe_value.get("opackets", 0)), - } - if key: - samples[name][key] = key_value + # recalculate port for interface and see if it matches ports provided + for intf in self.vnfd_helper.interfaces: + name = intf["name"] + port = self.vnfd_helper.port_num(name) + if port in ports: + xe_value = last_result.get(port, {}) + samples[name] = { + "rx_throughput_fps": float(xe_value.get("rx_pps", 0.0)), + "tx_throughput_fps": float(xe_value.get("tx_pps", 0.0)), + "rx_throughput_mbps": float(xe_value.get("rx_bps", 0.0)), + "tx_throughput_mbps": float(xe_value.get("tx_bps", 0.0)), + "in_packets": int(xe_value.get("ipackets", 0)), + "out_packets": int(xe_value.get("opackets", 0)), + } + if key: + samples[name][key] = key_value return samples def _run_traffic_once(self, traffic_profile): - traffic_profile.execute(self) + traffic_profile.execute_traffic(self) self.client_started.value = 1 time.sleep(self.RUN_DURATION) - samples = self.generate_samples() + samples = self.generate_samples(traffic_profile.ports) time.sleep(self.QUEUE_WAIT_TIME) self._queue.put(samples) @@ -513,14 +469,14 @@ class ClientResourceHelper(ResourceHelper): try: self._build_ports() self.client = self._connect() - self.client.reset(ports=self.my_ports) - self.client.remove_all_streams(self.my_ports) # remove all streams + self.client.reset(ports=self.all_ports) + self.client.remove_all_streams(self.all_ports) # remove all streams traffic_profile.register_generator(self) while self._terminated.value == 0: self._run_traffic_once(traffic_profile) - self.client.stop(self.my_ports) + self.client.stop(self.all_ports) self.client.disconnect() self._terminated.value = 0 except STLError: @@ -534,12 +490,12 @@ class ClientResourceHelper(ResourceHelper): def clear_stats(self, ports=None): if ports is None: - ports = self.my_ports + ports = self.all_ports self.client.clear_stats(ports=ports) def start(self, ports=None, *args, **kwargs): if ports is None: - ports = self.my_ports + ports = self.all_ports self.client.start(ports=ports, *args, **kwargs) def collect_kpi(self): @@ -730,7 +686,6 @@ class SampleVNF(GenericVNF): self.resource_helper = resource_helper_type(self.setup_helper) - self.all_ports = None self.context_cfg = None self.nfvi_context = None self.pipeline_kwargs = {} @@ -742,11 +697,17 @@ class SampleVNF(GenericVNF): self.q_out = Queue() self.queue_wrapper = None self.run_kwargs = {} - self.tg_port_pairs = None self.used_drivers = {} self.vnf_port_pairs = None self._vnf_process = None + def _build_ports(self): + self._port_pairs = PortPairs(self.vnfd_helper.interfaces) + self.networks = self._port_pairs.networks + self.priv_ports = self.vnfd_helper.port_nums(self._port_pairs.priv_ports) + self.pub_ports = self.vnfd_helper.port_nums(self._port_pairs.pub_ports) + self.my_ports = self.vnfd_helper.port_nums(self._port_pairs.all_ports) + def _get_route_data(self, route_index, route_type): route_iter = iter(self.vnfd_helper.vdu0.get('nd_route_tbl', [])) for _ in range(route_index): @@ -825,6 +786,8 @@ class SampleVNF(GenericVNF): LOG.info("Waiting for %s VNF to start.. ", self.APP_NAME) time.sleep(1) + # put newline to force new prompt? + self.q_in.put("\r\n") def _build_run_kwargs(self): self.run_kwargs = { @@ -925,7 +888,6 @@ class SampleVNFTrafficGen(GenericTrafficGen): self.runs_traffic = True self.traffic_finished = False - self.tg_port_pairs = None self._tg_process = None self._traffic_process = None diff --git a/yardstick/network_services/vnf_generic/vnf/tg_ping.py b/yardstick/network_services/vnf_generic/vnf/tg_ping.py index e65296287..9cd9f2574 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_ping.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_ping.py @@ -23,6 +23,7 @@ from ipaddress import IPv4Interface from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen 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__) @@ -59,7 +60,38 @@ class PingParser(object): class PingSetupEnvHelper(DpdkVnfSetupEnvHelper): def setup_vnf_environment(self): - self._bind_kernel_devices() + for intf in self.vnfd_helper.interfaces: + vi = intf['virtual-interface'] + vi['local_iface_name'] = self.get_local_iface_name_by_vpci(vi['vpci']) + + +class PingResourceHelper(ClientResourceHelper): + + def __init__(self, setup_helper): + super(PingResourceHelper, self).__init__(setup_helper) + self._queue = Queue() + self._parser = PingParser(self._queue) + + def run_traffic(self, traffic_profile): + # drop the connection in order to force a new one + self.ssh_helper.drop_connection() + + self.client_started.value = 1 + cmd_list = [ + "sudo ip addr flush {local_if_name}", + "sudo ip addr add {local_ip}/24 dev {local_if_name}", + "sudo ip link set {local_if_name} up", + ] + + self.cmd_kwargs['packet_size'] = traffic_profile.params['traffic_profile']['frame_size'] + + for cmd in cmd_list: + self.ssh_helper.execute(cmd.format(**self.cmd_kwargs)) + + ping_cmd = "nohup ping -s {packet_size} {target_ip}&" + self.ssh_helper.run(ping_cmd.format(**self.cmd_kwargs), + stdout=self._parser, + keep_stdin_open=True, pty=True) class PingTrafficGen(SampleVNFTrafficGen): @@ -69,16 +101,17 @@ class PingTrafficGen(SampleVNFTrafficGen): """ TG_NAME = 'Ping' + APP_NAME = 'Ping' RUN_WAIT = 4 def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None): if setup_env_helper_type is None: setup_env_helper_type = PingSetupEnvHelper + if resource_helper_type is None: + resource_helper_type = PingResourceHelper super(PingTrafficGen, self).__init__(name, vnfd, setup_env_helper_type, resource_helper_type) - self._queue = Queue() - self._parser = PingParser(self._queue) self._result = {} def scale(self, flavor=""): @@ -89,12 +122,23 @@ class PingTrafficGen(SampleVNFTrafficGen): return self._tg_process.is_alive() def instantiate(self, scenario_cfg, context_cfg): + self._start_server() self._result = { "packets_received": 0, "rtt": 0, } + intf = self.vnfd_helper.interfaces[0]["virtual-interface"] + self.resource_helper.cmd_kwargs = { + 'target_ip': IPv4Interface(intf["dst_ip"]).ip.exploded, + 'local_ip': IPv4Interface(intf["local_ip"]).ip.exploded, + 'local_if_name': intf["local_iface_name"].split('/')[0], + } + self.setup_helper.setup_vnf_environment() + def wait_for_instantiate(self): + pass + def listen_traffic(self, traffic_profile): """ Not needed for ping @@ -102,27 +146,3 @@ class PingTrafficGen(SampleVNFTrafficGen): :return: """ pass - - def _traffic_runner(self, traffic_profile): - intf = self.vnfd_helper.interfaces[0]["virtual-interface"] - profile = traffic_profile.params["traffic_profile"] - cmd_kwargs = { - 'target_ip': IPv4Interface(intf["dst_ip"]).ip.exploded, - 'local_ip': IPv4Interface(intf["local_ip"]).ip.exploded, - 'local_if_name': intf["local_iface_name"].split('/')[0], - 'packet_size': profile["frame_size"], - } - - cmd_list = [ - "sudo ip addr flush {local_if_name}", - "sudo ip addr add {local_ip}/24 dev {local_if_name}", - "sudo ip link set {local_if_name} up", - ] - - for cmd in cmd_list: - self.ssh_helper.execute(cmd.format(**cmd_kwargs)) - - ping_cmd = "ping -s {packet_size} {target_ip}" - self.ssh_helper.run(ping_cmd.format(**cmd_kwargs), - stdout=self._parser, - keep_stdin_open=True, pty=True) diff --git a/yardstick/network_services/vnf_generic/vnf/tg_prox.py b/yardstick/network_services/vnf_generic/vnf/tg_prox.py index c266f2c0f..40eda753f 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_prox.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_prox.py @@ -56,7 +56,6 @@ class ProxTrafficGen(SampleVNFTrafficGen): self.runs_traffic = True self.traffic_finished = False - self.tg_port_pairs = None self._tg_process = None self._traffic_process = None diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py index a52416dd9..93e496969 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py @@ -58,19 +58,12 @@ class IxiaResourceHelper(ClientResourceHelper): rfc_helper_type = IxiaRfc2544Helper self.rfc_helper = rfc_helper_type(self.scenario_helper) - self.tg_port_pairs = [] self.priv_ports = None self.pub_ports = None def _connect(self, client=None): self.client._connect(self.vnfd_helper) - def _build_ports(self): - # self.generate_port_pairs(self.topology) - self.priv_ports = [int(x[0][2:]) for x in self.tg_port_pairs] - self.pub_ports = [int(x[1][2:]) for x in self.tg_port_pairs] - self.my_ports = list(set(self.priv_ports).union(set(self.pub_ports))) - def get_stats(self, *args, **kwargs): return self.client.ix_get_statistics() @@ -79,33 +72,37 @@ class IxiaResourceHelper(ClientResourceHelper): if self.client and self.client.ixnet: self.client.ix_stop_traffic() - def generate_samples(self, key=None, default=None): + def generate_samples(self, ports, key=None, default=None): stats = self.get_stats() last_result = stats[1] latency = stats[0] samples = {} - for vpci_idx, interface in enumerate(self.vnfd_helper.interfaces): + for interface in self.vnfd_helper.interfaces: try: - name = "xe{0}".format(vpci_idx) - samples[name] = { - "rx_throughput_kps": float(last_result["Rx_Rate_Kbps"][vpci_idx]), - "tx_throughput_kps": float(last_result["Tx_Rate_Kbps"][vpci_idx]), - "rx_throughput_mbps": float(last_result["Rx_Rate_Mbps"][vpci_idx]), - "tx_throughput_mbps": float(last_result["Tx_Rate_Mbps"][vpci_idx]), - "in_packets": int(last_result["Valid_Frames_Rx"][vpci_idx]), - "out_packets": int(last_result["Frames_Tx"][vpci_idx]), - "RxThroughput": int(last_result["Valid_Frames_Rx"][vpci_idx]) / 30, - "TxThroughput": int(last_result["Frames_Tx"][vpci_idx]) / 30, - } - if key: - avg_latency = latency["Store-Forward_Avg_latency_ns"][vpci_idx] - min_latency = latency["Store-Forward_Min_latency_ns"][vpci_idx] - max_latency = latency["Store-Forward_Max_latency_ns"][vpci_idx] - samples[name][key] = \ - {"Store-Forward_Avg_latency_ns": avg_latency, - "Store-Forward_Min_latency_ns": min_latency, - "Store-Forward_Max_latency_ns": max_latency} + name = interface["name"] + # this is not DPDK port num, but this is whatever number we gave + # when we selected ports and programmed the profile + port = self.vnfd_helper.port_num(name) + if port in ports: + samples[name] = { + "rx_throughput_kps": float(last_result["Rx_Rate_Kbps"][port]), + "tx_throughput_kps": float(last_result["Tx_Rate_Kbps"][port]), + "rx_throughput_mbps": float(last_result["Rx_Rate_Mbps"][port]), + "tx_throughput_mbps": float(last_result["Tx_Rate_Mbps"][port]), + "in_packets": int(last_result["Valid_Frames_Rx"][port]), + "out_packets": int(last_result["Frames_Tx"][port]), + "RxThroughput": int(last_result["Valid_Frames_Rx"][port]) / 30, + "TxThroughput": int(last_result["Frames_Tx"][port]) / 30, + } + if key: + avg_latency = latency["Store-Forward_Avg_latency_ns"][port] + min_latency = latency["Store-Forward_Min_latency_ns"][port] + max_latency = latency["Store-Forward_Max_latency_ns"][port] + samples[name][key] = \ + {"Store-Forward_Avg_latency_ns": avg_latency, + "Store-Forward_Min_latency_ns": min_latency, + "Store-Forward_Max_latency_ns": max_latency} except IndexError: pass @@ -132,6 +129,7 @@ class IxiaResourceHelper(ClientResourceHelper): self.client.ix_assign_ports() mac = {} + # TODO: shouldn't this index map to port number we used to generate the profile for index, interface in enumerate(self.vnfd_helper.interfaces, 1): virt_intf = interface["virtual-interface"] mac.update({ @@ -145,11 +143,11 @@ class IxiaResourceHelper(ClientResourceHelper): self.scenario_helper.scenario_cfg["task_path"]) # Generate ixia traffic config... while not self._terminated.value: - traffic_profile.execute(self, self.client, mac, ixia_file) + traffic_profile.execute_traffic(self, self.client, mac, ixia_file) self.client_started.value = 1 time.sleep(WAIT_FOR_TRAFFIC) self.client.ix_stop_traffic() - samples = self.generate_samples() + samples = self.generate_samples(traffic_profile.ports) self._queue.put(samples) status, samples = traffic_profile.get_drop_percentage(self, samples, min_tol, max_tol, self.client, mac, @@ -167,11 +165,11 @@ class IxiaResourceHelper(ClientResourceHelper): self._terminated.value = 1 return - traffic_profile.execute(self, self.client, mac, ixia_file) + traffic_profile.execute_traffic(self, self.client, mac, ixia_file) for _ in range(5): time.sleep(self.LATENCY_TIME_SLEEP) self.client.ix_stop_traffic() - samples = self.generate_samples('latency', {}) + samples = self.generate_samples(traffic_profile.ports, 'latency', {}) self._queue.put(samples) traffic_profile.start_ixia_latency(self, self.client, mac, ixia_file) if self._terminated.value: @@ -197,7 +195,6 @@ class IxiaTrafficGen(SampleVNFTrafficGen): resource_helper_type) self._ixia_traffic_gen = None self.ixia_file_name = '' - self.tg_port_pairs = [] self.vnf_port_pairs = [] def _check_status(self): diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py index 15c9c0e1d..4e9f4bdc1 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py @@ -18,9 +18,7 @@ from __future__ import print_function import time import logging from collections import Mapping -from itertools import chain -from yardstick.network_services.helpers.samplevnf_helper import MultiPortConfig from yardstick.network_services.vnf_generic.vnf.tg_trex import TrexTrafficGen from yardstick.network_services.vnf_generic.vnf.sample_vnf import Rfc2544ResourceHelper from yardstick.network_services.vnf_generic.vnf.tg_trex import TrexResourceHelper @@ -47,23 +45,15 @@ class TrexRfcResourceHelper(TrexResourceHelper): rfc_helper_type = TrexRfc2544ResourceHelper self.rfc2544_helper = rfc_helper_type(self.scenario_helper) - # self.tg_port_pairs = [] - - def _build_ports(self): - self.tg_port_pairs, self.networks = MultiPortConfig.get_port_pairs( - self.vnfd_helper.interfaces) - self.priv_ports = [int(x[0][2:]) for x in self.tg_port_pairs] - self.pub_ports = [int(x[1][2:]) for x in self.tg_port_pairs] - self.my_ports = list(set(chain(self.priv_ports, self.pub_ports))) def _run_traffic_once(self, traffic_profile): if self._terminated.value: return - traffic_profile.execute(self) + traffic_profile.execute_traffic(self) self.client_started.value = 1 time.sleep(self.RUN_DURATION) - self.client.stop(self.my_ports) + self.client.stop(traffic_profile.ports) time.sleep(self.WAIT_TIME) samples = traffic_profile.get_drop_percentage(self) self._queue.put(samples) @@ -71,30 +61,30 @@ class TrexRfcResourceHelper(TrexResourceHelper): if not self.rfc2544_helper.is_done(): return - self.client.stop(self.my_ports) - self.client.reset(ports=self.my_ports) - self.client.remove_all_streams(self.my_ports) - traffic_profile.execute_latency(samples=samples) + self.client.stop(traffic_profile.ports) + self.client.reset(ports=traffic_profile.ports) + self.client.remove_all_streams(traffic_profile.ports) + traffic_profile.execute_traffic_latency(samples=samples) multiplier = traffic_profile.calculate_pps(samples)[1] for _ in range(5): time.sleep(self.LATENCY_TIME_SLEEP) - self.client.stop(self.my_ports) + self.client.stop(traffic_profile.ports) time.sleep(self.WAIT_TIME) - last_res = self.client.get_stats(self.my_ports) + last_res = self.client.get_stats(traffic_profile.ports) if not isinstance(last_res, Mapping): self._terminated.value = 1 continue - self.generate_samples('latency', {}) + self.generate_samples(traffic_profile.ports, 'latency', {}) self._queue.put(samples) self.client.start(mult=str(multiplier), - ports=self.my_ports, + ports=traffic_profile.ports, duration=120, force=True) - def start_client(self, mult, duration, force=True): - self.client.start(ports=self.my_ports, mult=mult, duration=duration, force=force) + def start_client(self, ports, mult=None, duration=None, force=True): + self.client.start(ports=ports, mult=mult, duration=duration, force=force) - def clear_client_stats(self): - self.client.clear_stats(ports=self.my_ports) + def clear_client_stats(self, ports): + self.client.clear_stats(ports=ports) def collect_kpi(self): self.rfc2544_helper.iteration.value += 1 diff --git a/yardstick/network_services/vnf_generic/vnf/udp_replay.py b/yardstick/network_services/vnf_generic/vnf/udp_replay.py index a9bc204d5..88773387e 100644 --- a/yardstick/network_services/vnf_generic/vnf/udp_replay.py +++ b/yardstick/network_services/vnf_generic/vnf/udp_replay.py @@ -19,14 +19,22 @@ 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__) # UDP_Replay should work the same on all systems, we can provide the binary + +# we can't match the prompt regexp due to extra noise +# yardstick.ssh ssh.py:302 DEBUG stdout: UDP_Replay: lcore 0 has nothing to do +# eplUDP_Replay: -- lcoreid=1 portid=0 rxqueueid=0 +# ay> +# +# try decreasing log level to RTE_LOG_NOTICE (5) REPLAY_PIPELINE_COMMAND = ( - """sudo {tool_path} -c {cpu_mask_hex} -n 4 -w {whitelist} -- """ - """{hw_csum} -p {ports_len_hex} --config='{config}'""" + """sudo {tool_path} --log-level=5 -c {cpu_mask_hex} -n 4 -w {whitelist} -- """ + """{hw_csum} -p {port_mask_hex} --config='{config}'""" ) -# {tool_path} -p {ports_len_hex} -f {cfg_file} -s {script}' +# {tool_path} -p {port_mask_hex} -f {cfg_file} -s {script}' class UdpReplaySetupEnvHelper(DpdkVnfSetupEnvHelper): @@ -42,7 +50,8 @@ class UdpReplayApproxVnf(SampleVNF): APP_NAME = "UDP_Replay" APP_WORD = "UDP_Replay" - VNF_PROMPT = 'Replay>' + # buffering issue? + VNF_PROMPT = 'eplay>' VNF_TYPE = 'UdpReplay' @@ -60,36 +69,30 @@ class UdpReplayApproxVnf(SampleVNF): 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 _deploy(self): - self.generate_port_pairs() - super(UdpReplayApproxVnf, self)._deploy() - def _build_pipeline_kwargs(self): - all_ports = [i for i, _ in enumerate(self.vnfd_helper.interfaces)] - number_of_ports = len(all_ports) + ports = self.vnfd_helper.port_pairs.all_ports + number_of_ports = len(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) + port_nums = self.vnfd_helper.port_nums(ports) + ports_mask_hex = hex(sum(2 ** num for num in port_nums)) + # one core extra for master 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) + # tuples of (FLD_PORT, FLD_QUEUE, FLD_LCORE) + # [--config (port,queue,lcore)[,(port,queue,lcore]]" + # start with lcore = 1 since we use lcore=0 for master + config_value = ",".join( + str((self.vnfd_helper.port_num(port), 0, core)).replace(" ", "") for core, port in + enumerate(self.vnfd_helper.port_pairs.all_ports, 1)) whitelist = " -w ".join(self.setup_helper.bound_pci) self.pipeline_kwargs = { - 'ports_len_hex': ports_mask_hex, + 'port_mask_hex': ports_mask_hex, 'tool_path': tool_path, 'hw_csum': hw_csum, 'whitelist': whitelist, @@ -105,7 +108,7 @@ class UdpReplayApproxVnf(SampleVNF): def get_sum(offset): return sum(int(i) for i in split_stats[offset::5]) - number_of_ports = len(self.vnfd_helper.interfaces) + number_of_ports = len(self.vnfd_helper.port_pairs.all_ports) stats = self.get_stats() stats_words = stats.split() diff --git a/yardstick/network_services/vnf_generic/vnf/vfw_vnf.py b/yardstick/network_services/vnf_generic/vnf/vfw_vnf.py index 32a08c7bd..6c95648ce 100644 --- a/yardstick/network_services/vnf_generic/vnf/vfw_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/vfw_vnf.py @@ -22,7 +22,7 @@ from yardstick.network_services.yang_model import YangModel LOG = logging.getLogger(__name__) # vFW should work the same on all systems, we can provide the binary -FW_PIPELINE_COMMAND = """sudo {tool_path} -p {ports_len_hex} -f {cfg_file} -s {script}""" +FW_PIPELINE_COMMAND = """sudo {tool_path} -p {port_mask_hex} -f {cfg_file} -s {script}""" FW_COLLECT_KPI = (r"""VFW TOTAL:[^p]+pkts_received"?:\s(\d+),[^p]+pkts_fw_forwarded"?:\s(\d+),""" r"""[^p]+pkts_drop_fw"?:\s(\d+),\s""") diff --git a/yardstick/network_services/vnf_generic/vnf/vpe_vnf.py b/yardstick/network_services/vnf_generic/vnf/vpe_vnf.py index 310ab67cb..72c1514f1 100644 --- a/yardstick/network_services/vnf_generic/vnf/vpe_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/vpe_vnf.py @@ -15,6 +15,8 @@ from __future__ import absolute_import from __future__ import print_function + + import os import logging import re @@ -22,17 +24,17 @@ import posixpath from six.moves import configparser, zip +from yardstick.network_services.helpers.samplevnf_helper import PortPairs from yardstick.network_services.pipeline import PipelineRules from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF, DpdkVnfSetupEnvHelper LOG = logging.getLogger(__name__) -VPE_PIPELINE_COMMAND = """sudo {tool_path} -p {ports_len_hex} -f {cfg_file} -s {script}""" +VPE_PIPELINE_COMMAND = """sudo {tool_path} -p {port_mask_hex} -f {cfg_file} -s {script}""" VPE_COLLECT_KPI = """\ Pkts in:\s(\d+)\r\n\ -\tPkts dropped by Pkts in:\s(\d+)\r\n\ -\tPkts dropped by AH:\s(\d+)\r\n\\ +\tPkts dropped by AH:\s(\d+)\r\n\ \tPkts dropped by other:\s(\d+)\ """ @@ -92,24 +94,23 @@ class ConfigCreate(object): pktq = "SWQ{0}{1}".format(self.sw_q, sink) return pktq - def vpe_upstream(self, vnf_cfg, intf): + def vpe_upstream(self, vnf_cfg, index=0): parser = configparser.ConfigParser() parser.read(os.path.join(vnf_cfg, 'vpe_upstream')) + for pipeline in parser.sections(): for k, v in parser.items(pipeline): if k == "pktq_in": - index = intf['index'] if "RXQ" in v: - value = "RXQ{0}.0".format(index) + value = "RXQ{0}.0".format(self.priv_ports[index]) else: value = self.get_sink_swq(parser, pipeline, k, index) parser.set(pipeline, k, value) elif k == "pktq_out": - index = intf['peer_intf']['index'] if "TXQ" in v: - value = "TXQ{0}.0".format(index) + value = "TXQ{0}.0".format(self.pub_ports[index]) else: self.sw_q += 1 value = self.get_sink_swq(parser, pipeline, k, index) @@ -123,21 +124,19 @@ class ConfigCreate(object): self.n_pipeline += 1 return parser - def vpe_downstream(self, vnf_cfg, intf): + def vpe_downstream(self, vnf_cfg, index): parser = configparser.ConfigParser() parser.read(os.path.join(vnf_cfg, 'vpe_downstream')) for pipeline in parser.sections(): for k, v in parser.items(pipeline): - index = intf['dpdk_port_num'] - peer_index = intf['peer_intf']['dpdk_port_num'] if k == "pktq_in": if "RXQ" not in v: value = self.get_sink_swq(parser, pipeline, k, index) elif "TM" in v: - value = "RXQ{0}.0 TM{1}".format(peer_index, index) + value = "RXQ{0}.0 TM{1}".format(self.pub_ports[index], index) else: - value = "RXQ{0}.0".format(peer_index) + value = "RXQ{0}.0".format(self.pub_ports[index]) parser.set(pipeline, k, value) @@ -146,9 +145,9 @@ class ConfigCreate(object): self.sw_q += 1 value = self.get_sink_swq(parser, pipeline, k, index) elif "TM" in v: - value = "TXQ{0}.0 TM{1}".format(peer_index, index) + value = "TXQ{0}.0 TM{1}".format(self.priv_ports[index], index) else: - value = "TXQ{0}.0".format(peer_index) + value = "TXQ{0}.0".format(self.priv_ports[index]) parser.set(pipeline, k, value) @@ -166,10 +165,10 @@ class ConfigCreate(object): config = self.vpe_initialize(config) config = self.vpe_rxq(config) config.write(cfg_file) - for index, priv_port in enumerate(self.priv_ports): - config = self.vpe_upstream(vnf_cfg, priv_port) + for index in range(0, len(self.priv_ports)): + config = self.vpe_upstream(vnf_cfg, index) config.write(cfg_file) - config = self.vpe_downstream(vnf_cfg, priv_port) + config = self.vpe_downstream(vnf_cfg, index) config = self.vpe_tmq(config, index) config.write(cfg_file) @@ -199,36 +198,41 @@ class ConfigCreate(object): return rules.get_string() + def generate_tm_cfg(self, vnf_cfg, index=0): + vnf_cfg = os.path.join(vnf_cfg, "full_tm_profile_10G.cfg") + if os.path.exists(vnf_cfg): + return open(vnf_cfg).read() + class VpeApproxSetupEnvHelper(DpdkVnfSetupEnvHelper): + APP_NAME = 'vPE_vnf' CFG_CONFIG = "/tmp/vpe_config" CFG_SCRIPT = "/tmp/vpe_script" + TM_CONFIG = "/tmp/full_tm_profile_10G.cfg" CORES = ['0', '1', '2', '3', '4', '5'] PIPELINE_COMMAND = VPE_PIPELINE_COMMAND + def _build_vnf_ports(self): + self._port_pairs = PortPairs(self.vnfd_helper.interfaces) + self.priv_ports = self._port_pairs.priv_ports + self.pub_ports = self._port_pairs.pub_ports + self.all_ports = self._port_pairs.all_ports + def build_config(self): vpe_vars = { "bin_path": self.ssh_helper.bin_path, "socket": self.socket, } - all_ports = [] - priv_ports = [] - pub_ports = [] - for interface in self.vnfd_helper.interfaces: - all_ports.append(interface['name']) - vld_id = interface['virtual-interface']['vld_id'] - if vld_id.startswith('private'): - priv_ports.append(interface) - elif vld_id.startswith('public'): - pub_ports.append(interface) - - vpe_conf = ConfigCreate(priv_ports, pub_ports, self.socket) + self._build_vnf_ports() + vpe_conf = ConfigCreate(self.vnfd_helper.port_pairs.priv_ports, + self.vnfd_helper.port_pairs.pub_ports, self.socket) vpe_conf.create_vpe_config(self.scenario_helper.vnf_cfg) config_basename = posixpath.basename(self.CFG_CONFIG) script_basename = posixpath.basename(self.CFG_SCRIPT) + tm_basename = posixpath.basename(self.TM_CONFIG) with open(self.CFG_CONFIG) as handle: vpe_config = handle.read() @@ -237,6 +241,15 @@ class VpeApproxSetupEnvHelper(DpdkVnfSetupEnvHelper): vpe_script = vpe_conf.generate_vpe_script(self.vnfd_helper.interfaces) self.ssh_helper.upload_config_file(script_basename, vpe_script.format(**vpe_vars)) + tm_config = vpe_conf.generate_tm_cfg(self.scenario_helper.vnf_cfg) + self.ssh_helper.upload_config_file(tm_basename, tm_config) + + LOG.info("Provision and start the %s", self.APP_NAME) + LOG.info(self.CFG_CONFIG) + LOG.info(self.CFG_SCRIPT) + self._build_pipeline_kwargs() + return self.PIPELINE_COMMAND.format(**self.pipeline_kwargs) + class VpeApproxVnf(SampleVNF): """ This class handles vPE VNF model-driver definitions """ |