diff options
13 files changed, 660 insertions, 17 deletions
diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex_scale-up.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex_scale-up.yaml new file mode 100644 index 000000000..eaeee7103 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex_scale-up.yaml @@ -0,0 +1,89 @@ +# Copyright (c) 2016-2018 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. +{% set mem = mem or 20480 %} +{% set vcpus = vcpus or 10 %} +{% set vports = vports or 2 %} +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: ../../traffic_profiles/ipv4_throughput-scale-up.yaml + extra_args: + vports: {{ vports }} + topology: vfw-tg-topology-scale-up.yaml + nodes: + tg__0: tg_0.yardstick + vnf__0: vnf_0.yardstick + options: + framesize: + uplink: {64B: 100} + downlink: {64B: 100} + flow: + src_ip: [ +{% for vport in range(0,vports,2|int) %} + {'tg__0': 'xe{{vport}}'}, +{% endfor %} ] + dst_ip: [ +{% for vport in range(1,vports,2|int) %} + {'tg__0': 'xe{{vport}}'}, +{% endfor %} ] + count: 1 + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', file: vfw_vnf_pipeline_cores_{{vcpus}}_ports_{{vports}}_lb_1_sw.conf } + runner: + type: Iteration + iterations: 10 + interval: 35 +context: + # put node context first, so we don't HEAT deploy if node has errors + name: yardstick + image: yardstick-samplevnfs + flavor: + vcpus: {{ vcpus }} + ram: {{ mem }} + disk: 6 + extra_specs: + hw:cpu_sockets: 1 + hw:cpu_cores: {{ vcpus }} + hw:cpu_threads: 1 + user: ubuntu + placement_groups: + pgrp1: + policy: "availability" + servers: + tg_0: + floating_ip: true + placement: "pgrp1" + vnf_0: + floating_ip: true + placement: "pgrp1" + networks: + mgmt: + cidr: '10.0.1.0/24' +{% for vport in range(1,vports,2|int) %} + uplink_{{loop.index0}}: + cidr: '10.1.{{vport}}.0/24' + gateway_ip: 'null' + port_security_enabled: False + enable_dhcp: 'false' + downlink_{{loop.index0}}: + cidr: '10.1.{{vport+1}}.0/24' + gateway_ip: 'null' + port_security_enabled: False + enable_dhcp: 'false' +{% endfor %} diff --git a/samples/vnf_samples/nsut/vfw/vfw-tg-topology-scale-up.yaml b/samples/vnf_samples/nsut/vfw/vfw-tg-topology-scale-up.yaml new file mode 100644 index 000000000..d4bf8d6d1 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/vfw-tg-topology-scale-up.yaml @@ -0,0 +1,52 @@ +# Copyright (c) 2016-2018 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. +--- +{% set vports = get(extra_args, 'vports', '2') %} +nsd:nsd-catalog: + nsd: + - id: 3tg-topology + name: 3tg-topology + short-name: 3tg-topology + description: 3tg-topology + constituent-vnfd: + - member-vnf-index: '1' + vnfd-id-ref: tg__0 + VNF model: ../../vnf_descriptors/tg_rfc2544_tpl.yaml #VNF type + - member-vnf-index: '2' + vnfd-id-ref: vnf__0 + VNF model: ../../vnf_descriptors/vfw_vnf.yaml #VNF type + + vld: +{% for vport in range(0,vports,2|int) %} + - id: uplink_{{loop.index0}} + name: tg__0 to vnf__0 link {{vport + 1}} + type: ELAN + vnfd-connection-point-ref: + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe{{vport}} + vnfd-id-ref: tg__0 + - member-vnf-index-ref: '2' + vnfd-connection-point-ref: xe{{vport}} + vnfd-id-ref: vnf__0 + - id: downlink_{{loop.index0}} + name: vnf__0 to tg__0 link {{vport + 2}} + type: ELAN + vnfd-connection-point-ref: + - member-vnf-index-ref: '2' + vnfd-connection-point-ref: xe{{vport+1}} + vnfd-id-ref: vnf__0 + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe{{vport+1}} + vnfd-id-ref: tg__0 +{% endfor %} diff --git a/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_4_ports_2_lb_1_sw.conf b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_4_ports_2_lb_1_sw.conf new file mode 100644 index 000000000..b31d0546c --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_4_ports_2_lb_1_sw.conf @@ -0,0 +1,52 @@ +[PIPELINE0] +type = MASTER +core = 0 + +[PIPELINE1] +type = ARPICMP +core = 0 +pktq_in = SWQ0 +pktq_out = SWQ1 +pktq_in_prv = RXQ1.0 +prv_to_pub_map = (1,0) + +[PIPELINE2] +type = TXRX +core = 1 +pipeline_txrx_type = RXRX +dest_if_offset = 176 +pktq_in = RXQ1.0 RXQ0.0 +pktq_out = SWQ2 SWQ3 SWQ0 + +[PIPELINE3] +type = LOADB +core = 2 +pktq_in = SWQ2 SWQ3 +pktq_out = SWQ4 SWQ5 +outport_offset = 136 +n_vnf_threads = 1 +n_lb_tuples = 5 +loadb_debug = 0 +lib_arp_debug = 0 +prv_que_handler = (0,) + +[PIPELINE4] +type = VFW +core = 3 +pktq_in = SWQ4 SWQ5 +pktq_out = SWQ6 SWQ7 +n_rules = 10 +prv_que_handler = (0) +n_flows = 2000000 +traffic_type = 4 +pkt_type = ipv4 +tcp_be_liberal = 0 + +[PIPELINE5] +type = TXRX +core = 1 +pipeline_txrx_type = TXTX +dest_if_offset = 176 +pktq_in = SWQ6 SWQ7 SWQ1 +pktq_out = TXQ1.0 TXQ0.0 + diff --git a/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_4_ports_4_lb_1_sw.conf b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_4_ports_4_lb_1_sw.conf new file mode 100644 index 000000000..3bf8dc68b --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_4_ports_4_lb_1_sw.conf @@ -0,0 +1,52 @@ + +[PIPELINE0] +type = MASTER +core = 0 + +[PIPELINE1] +type = ARPICMP +core = 0 +pktq_in = SWQ0 +pktq_out = SWQ1 +pktq_in_prv = RXQ2.0 RXQ3.0 +prv_to_pub_map = (2,0)(3,1) + +[PIPELINE2] +type = TXRX +core = 1 +pipeline_txrx_type = RXRX +dest_if_offset = 176 +pktq_in = RXQ2.0 RXQ0.0 RXQ3.0 RXQ1.0 +pktq_out = SWQ2 SWQ3 SWQ4 SWQ5 SWQ0 + +[PIPELINE3] +type = LOADB +core = 2 +pktq_in = SWQ2 SWQ3 SWQ4 SWQ5 +pktq_out = SWQ6 SWQ7 SWQ8 SWQ9 +outport_offset = 136 +n_vnf_threads = 1 +n_lb_tuples = 5 +loadb_debug = 0 +lib_arp_debug = 0 +prv_que_handler = (0,2,) + +[PIPELINE4] +type = VFW +core = 3 +pktq_in = SWQ6 SWQ7 SWQ8 SWQ9 +pktq_out = SWQ10 SWQ11 SWQ12 SWQ13 +n_rules = 10 +prv_que_handler = (0) +n_flows = 2000000 +traffic_type = 4 +pkt_type = ipv4 +tcp_be_liberal = 0 + +[PIPELINE5] +type = TXRX +core = 1 +pipeline_txrx_type = TXTX +dest_if_offset = 176 +pktq_in = SWQ10 SWQ11 SWQ12 SWQ13 SWQ1 +pktq_out = TXQ2.0 TXQ0.0 TXQ3.0 TXQ1.0 diff --git a/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_6_ports_6_lb_1_sw.conf b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_6_ports_6_lb_1_sw.conf new file mode 100644 index 000000000..1d55d8855 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_6_ports_6_lb_1_sw.conf @@ -0,0 +1,51 @@ +[PIPELINE0] +type = MASTER +core = 0 + +[PIPELINE1] +type = ARPICMP +core = 0 +pktq_in = SWQ0 +pktq_out = SWQ1 +pktq_in_prv = RXQ5.0 RXQ3.0 RXQ4.0 +prv_to_pub_map = (5,2)(3,0)(4,1) + +[PIPELINE2] +type = TXRX +core = 1 +pipeline_txrx_type = RXRX +dest_if_offset = 176 +pktq_in = RXQ5.0 RXQ2.0 RXQ3.0 RXQ0.0 RXQ4.0 RXQ1.0 +pktq_out = SWQ2 SWQ3 SWQ4 SWQ5 SWQ6 SWQ7 SWQ0 + +[PIPELINE3] +type = LOADB +core = 2 +pktq_in = SWQ2 SWQ3 SWQ4 SWQ5 SWQ6 SWQ7 +pktq_out = SWQ8 SWQ9 SWQ10 SWQ11 SWQ12 SWQ13 +outport_offset = 136 +n_vnf_threads = 1 +n_lb_tuples = 5 +loadb_debug = 0 +lib_arp_debug = 0 +prv_que_handler = (0,2,4,) + +[PIPELINE4] +type = VFW +core = 3 +pktq_in = SWQ8 SWQ9 SWQ10 SWQ11 SWQ12 SWQ13 +pktq_out = SWQ14 SWQ15 SWQ16 SWQ17 SWQ18 SWQ19 +n_rules = 10 +prv_que_handler = (0) +n_flows = 2000000 +traffic_type = 4 +pkt_type = ipv4 +tcp_be_liberal = 0 + +[PIPELINE5] +type = TXRX +core = 1 +pipeline_txrx_type = TXTX +dest_if_offset = 176 +pktq_in = SWQ14 SWQ15 SWQ16 SWQ17 SWQ18 SWQ19 SWQ1 +pktq_out = TXQ5.0 TXQ2.0 TXQ3.0 TXQ0.0 TXQ4.0 TXQ1.0 diff --git a/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_6_ports_8_lb_1_sw.conf b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_6_ports_8_lb_1_sw.conf new file mode 100644 index 000000000..8434fee34 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_6_ports_8_lb_1_sw.conf @@ -0,0 +1,52 @@ +[PIPELINE0] +type = MASTER +core = 0 + +[PIPELINE1] +type = ARPICMP +core = 0 +pktq_in = SWQ0 +pktq_out = SWQ1 +pktq_in_prv = RXQ6.0 RXQ7.0 RXQ4.0 RXQ5.0 +prv_to_pub_map = (6,2)(7,3)(4,0)(5,1) + +[PIPELINE2] +type = TXRX +core = 1 +pipeline_txrx_type = RXRX +dest_if_offset = 176 +pktq_in = RXQ6.0 RXQ2.0 RXQ7.0 RXQ3.0 RXQ4.0 RXQ0.0 RXQ5.0 RXQ1.0 +pktq_out = SWQ2 SWQ3 SWQ4 SWQ5 SWQ6 SWQ7 SWQ8 SWQ9 SWQ0 + +[PIPELINE3] +type = LOADB +core = 2 +pktq_in = SWQ2 SWQ3 SWQ4 SWQ5 SWQ6 SWQ7 SWQ8 SWQ9 +pktq_out = SWQ10 SWQ11 SWQ12 SWQ13 SWQ14 SWQ15 SWQ16 SWQ17 +outport_offset = 136 +n_vnf_threads = 1 +n_lb_tuples = 5 +loadb_debug = 0 +lib_arp_debug = 0 +prv_que_handler = (0,2,4,6,) + +[PIPELINE4] +type = VFW +core = 3 +pktq_in = SWQ10 SWQ11 SWQ12 SWQ13 SWQ14 SWQ15 SWQ16 SWQ17 +pktq_out = SWQ18 SWQ19 SWQ20 SWQ21 SWQ22 SWQ23 SWQ24 SWQ25 +n_rules = 10 +prv_que_handler = (0) +n_flows = 2000000 +traffic_type = 4 +pkt_type = ipv4 +tcp_be_liberal = 0 + +[PIPELINE5] +type = TXRX +core = 1 +pipeline_txrx_type = TXTX +dest_if_offset = 176 +pktq_in = SWQ18 SWQ19 SWQ20 SWQ21 SWQ22 SWQ23 SWQ24 SWQ25 SWQ1 +pktq_out = TXQ6.0 TXQ2.0 TXQ7.0 TXQ3.0 TXQ4.0 TXQ0.0 TXQ5.0 TXQ1.0 + diff --git a/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_8_ports_10_lb_1_sw.conf b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_8_ports_10_lb_1_sw.conf new file mode 100644 index 000000000..51d97e0f8 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/vfw_vnf_pipeline_cores_8_ports_10_lb_1_sw.conf @@ -0,0 +1,52 @@ +[PIPELINE0] +type = MASTER +core = 0 + +[PIPELINE1] +type = ARPICMP +core = 0 +pktq_in = SWQ0 +pktq_out = SWQ1 +pktq_in_prv = RXQ7.0 RXQ8.0 RXQ5.0 RXQ6.0 RXQ9.0 +prv_to_pub_map = (7,2)(8,3)(5,0)(6,1)(9,4) + +[PIPELINE2] +type = TXRX +core = 1 +pipeline_txrx_type = RXRX +dest_if_offset = 176 +pktq_in = RXQ7.0 RXQ2.0 RXQ8.0 RXQ3.0 RXQ5.0 RXQ0.0 RXQ6.0 RXQ1.0 RXQ9.0 RXQ4.0 +pktq_out = SWQ2 SWQ3 SWQ4 SWQ5 SWQ6 SWQ7 SWQ8 SWQ9 SWQ10 SWQ11 SWQ0 + +[PIPELINE3] +type = LOADB +core = 2 +pktq_in = SWQ2 SWQ3 SWQ4 SWQ5 SWQ6 SWQ7 SWQ8 SWQ9 SWQ10 SWQ11 +pktq_out = SWQ12 SWQ13 SWQ14 SWQ15 SWQ16 SWQ17 SWQ18 SWQ19 SWQ20 SWQ21 +outport_offset = 136 +n_vnf_threads = 1 +n_lb_tuples = 5 +loadb_debug = 0 +lib_arp_debug = 0 +prv_que_handler = (0,2,4,6,8,) + +[PIPELINE4] +type = VFW +core = 3 +pktq_in = SWQ12 SWQ13 SWQ14 SWQ15 SWQ16 SWQ17 SWQ18 SWQ19 SWQ20 SWQ21 +pktq_out = SWQ22 SWQ23 SWQ24 SWQ25 SWQ26 SWQ27 SWQ28 SWQ29 SWQ30 SWQ31 +n_rules = 10 +prv_que_handler = (0) +n_flows = 2000000 +traffic_type = 4 +pkt_type = ipv4 +tcp_be_liberal = 0 + +[PIPELINE5] +type = TXRX +core = 1 +pipeline_txrx_type = TXTX +dest_if_offset = 176 +pktq_in = SWQ22 SWQ23 SWQ24 SWQ25 SWQ26 SWQ27 SWQ28 SWQ29 SWQ30 SWQ31 SWQ1 +pktq_out = TXQ7.0 TXQ2.0 TXQ8.0 TXQ3.0 TXQ5.0 TXQ0.0 TXQ6.0 TXQ1.0 TXQ9.0 TXQ4.0 + diff --git a/samples/vnf_samples/traffic_profiles/ipv4_throughput-scale-up.yaml b/samples/vnf_samples/traffic_profiles/ipv4_throughput-scale-up.yaml new file mode 100644 index 000000000..d2cc18c15 --- /dev/null +++ b/samples/vnf_samples/traffic_profiles/ipv4_throughput-scale-up.yaml @@ -0,0 +1,102 @@ +# Copyright (c) 2016-2018 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. + +# flow definition for ACL tests - 1K flows - ipv4 only +# +# the number of flows defines the widest range of parameters +# for example if srcip_range=1.0.0.1-1.0.0.255 and dst_ip_range=10.0.0.1-10.0.1.255 +# and it should define only 16 flows +# +# there is assumption that packets generated will have a random sequences of following addresses pairs +# in the packets +# 1. src=1.x.x.x(x.x.x =random from 1..255) dst=10.x.x.x (random from 1..512) +# 2. src=1.x.x.x(x.x.x =random from 1..255) dst=10.x.x.x (random from 1..512) +# ... +# 512. src=1.x.x.x(x.x.x =random from 1..255) dst=10.x.x.x (random from 1..512) +# +# not all combination should be filled +# Any other field with random range will be added to flow definition +# +# the example.yaml provides all possibilities for traffic generation +# +# the profile defines a public and private side to make limited traffic correlation +# between private and public side same way as it is made by IXIA solution. +# +{% set vports = get(extra_args, 'vports', '2') %} +--- +schema: "nsb:traffic_profile:0.1" + +# This file is a template, it will be filled with values from tc.yaml before passing to the traffic generator + +name: rfc2544 +description: Traffic profile to run RFC2544 latency +traffic_profile: + traffic_type: RFC2544Profile # defines traffic behavior - constant or look for highest possible throughput + frame_rate: 100 # pc of linerate + # that specifies a range (e.g. ipv4 address, port) +{% set count = 0 %} +{% for vport in range(vports|int) %} +uplink_{{vport}}: + ipv4: + id: {{count + 1 }} + outer_l2: + framesize: + 64B: "{{ get(imix, 'imix.uplink.64B', '0') }}" + 128B: "{{ get(imix, 'imix.uplink.128B', '0') }}" + 256B: "{{ get(imix, 'imix.uplink.256B', '0') }}" + 373b: "{{ get(imix, 'imix.uplink.373B', '0') }}" + 512B: "{{ get(imix, 'imix.uplink.512B', '0') }}" + 570B: "{{ get(imix, 'imix.uplink.570B', '0') }}" + 1400B: "{{ get(imix, 'imix.uplink.1400B', '0') }}" + 1500B: "{{ get(imix, 'imix.uplink.1500B', '0') }}" + 1518B: "{{ get(imix, 'imix.uplink.1518B', '0') }}" + outer_l3v4: + proto: "udp" + srcip4: "{{ get(flow, 'flow.src_ip_{{vport}}', '1.1.1.1-1.1.255.255') }}" + dstip4: "{{ get(flow, 'flow.dst_ip_{{vport}}', '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_port_{{vport}}', '1234-4321') }}" + dstport: "{{ get(flow, 'flow.dst_port_{{vport}}', '2001-4001') }}" + count: "{{ get(flow, 'flow.count', '1') }}" +downlink_{{vport}}: + ipv4: + id: {{count + 2}} + outer_l2: + framesize: + 64B: "{{ get(imix, 'imix.downlink.64B', '0') }}" + 128B: "{{ get(imix, 'imix.downlink.128B', '0') }}" + 256B: "{{ get(imix, 'imix.downlink.256B', '0') }}" + 373b: "{{ get(imix, 'imix.downlink.373B', '0') }}" + 512B: "{{ get(imix, 'imix.downlink.512B', '0') }}" + 570B: "{{ get(imix, 'imix.downlink.570B', '0') }}" + 1400B: "{{ get(imix, 'imix.downlink.1400B', '0') }}" + 1500B: "{{ get(imix, 'imix.downlink.1500B', '0') }}" + 1518B: "{{ get(imix, 'imix.downlink.1518B', '0') }}" + + outer_l3v4: + proto: "udp" + srcip4: "{{ get(flow, 'flow.dst_ip_{{vport}}', '90.90.1.1-90.90.255.255') }}" + dstip4: "{{ get(flow, 'flow.src_ip_{{vport}}', '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_port_{{vport}}', '1234-4321') }}" + dstport: "{{ get(flow, 'flow.src_port_{{vport}}', '2001-4001') }}" + count: "{{ get(flow, 'flow.count', '1') }}" +{% set count = count + 2 %} +{% endfor %}
\ No newline at end of file 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 18a8ab85d..f8f8eb604 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 @@ -549,7 +549,8 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.open') @mock.patch.object(utils, 'find_relative_file') @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig') - def test_build_config(self, mock_multi_port_config_class, mock_find, *args): + @mock.patch.object(utils, 'open_relative_file') + def test_build_config(self, mock_open_rf, mock_multi_port_config_class, mock_find, *args): mock_multi_port_config = mock_multi_port_config_class() vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() @@ -566,6 +567,20 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): self.assertGreaterEqual(mock_multi_port_config.generate_config.call_count, 1) self.assertGreaterEqual(mock_multi_port_config.generate_script.call_count, 1) + scenario_helper.vnf_cfg = {'file': 'fake_file'} + dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) + mock_open_rf.side_effect = mock.mock_open(read_data='fake_data') + dpdk_setup_helper.PIPELINE_COMMAND = expected = 'pipeline command' + + result = dpdk_setup_helper.build_config() + + mock_open_rf.assert_called_once() + self.assertEqual(result, expected) + self.assertGreaterEqual(ssh_helper.upload_config_file.call_count, 2) + self.assertGreaterEqual(mock_find.call_count, 1) + self.assertGreaterEqual(mock_multi_port_config.generate_config.call_count, 1) + self.assertGreaterEqual(mock_multi_port_config.generate_script.call_count, 1) + def test__build_pipeline_kwargs(self): vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py index c43dabfd4..45c151b59 100644 --- a/yardstick/benchmark/scenarios/networking/vnf_generic.py +++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py @@ -28,7 +28,6 @@ from yardstick.benchmark.scenarios import base as scenario_base from yardstick.common.constants import LOG_DIR from yardstick.common.process import terminate_children from yardstick.common import utils -from yardstick.common.yaml_loader import yaml_load from yardstick.network_services.collector.subscriber import Collector from yardstick.network_services.vnf_generic import vnfdgen from yardstick.network_services.vnf_generic.vnf.base import GenericVNF @@ -100,12 +99,7 @@ class NetworkServiceTestCase(scenario_base.Scenario): self.scenario_cfg = scenario_cfg self.context_cfg = context_cfg - # fixme: create schema to validate all fields have been provided - with utils.open_relative_file(scenario_cfg["topology"], - scenario_cfg['task_path']) as stream: - topology_yaml = yaml_load(stream) - - self.topology = topology_yaml["nsd:nsd-catalog"]["nsd"][0] + self._render_topology() self.vnfs = [] self.collector = None self.traffic_profile = None @@ -184,6 +178,12 @@ class NetworkServiceTestCase(scenario_base.Scenario): with utils.open_relative_file(profile, path) as infile: return infile.read() + def _get_topology(self): + topology = self.scenario_cfg["topology"] + path = self.scenario_cfg["task_path"] + with utils.open_relative_file(topology, path) as infile: + return infile.read() + def _fill_traffic_profile(self): tprofile = self._get_traffic_profile() extra_args = self.scenario_cfg.get('extra_args', {}) @@ -198,6 +198,15 @@ class NetworkServiceTestCase(scenario_base.Scenario): traffic_vnfd = vnfdgen.generate_vnfd(tprofile, tprofile_data) self.traffic_profile = tprofile_base.TrafficProfile.get(traffic_vnfd) + def _render_topology(self): + topology = self._get_topology() + topology_args = self.scenario_cfg.get('extra_args', {}) + topolgy_data = { + 'extra_args': topology_args + } + topology_yaml = vnfdgen.generate_vnfd(topology, topolgy_data) + self.topology = topology_yaml["nsd:nsd-catalog"]["nsd"][0] + def _find_vnf_name_from_id(self, vnf_id): return next((vnfd["vnfd-id-ref"] for vnfd in self.topology["constituent-vnfd"] diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py index a6b1d0792..d6249a874 100644 --- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py @@ -174,6 +174,7 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): vnf_cfg = self.scenario_helper.vnf_cfg task_path = self.scenario_helper.task_path + config_file = vnf_cfg.get('file') lb_count = vnf_cfg.get('lb_count', 3) lb_config = vnf_cfg.get('lb_config', 'SW') worker_config = vnf_cfg.get('worker_config', '1C/1T') @@ -202,12 +203,20 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): self.socket) multiport.generate_config() - with open(self.CFG_CONFIG) as handle: - new_config = handle.read() - - new_config = self._update_traffic_type(new_config, traffic_options) - new_config = self._update_packet_type(new_config, traffic_options) - + if config_file: + with utils.open_relative_file(config_file, task_path) as infile: + new_config = ['[EAL]'] + vpci = [] + for port in self.vnfd_helper.port_pairs.all_ports: + interface = self.vnfd_helper.find_interface(name=port) + vpci.append(interface['virtual-interface']["vpci"]) + new_config.extend('w = {0}'.format(item) for item in vpci) + new_config = '\n'.join(new_config) + '\n' + infile.read() + else: + with open(self.CFG_CONFIG) as handle: + new_config = handle.read() + new_config = self._update_traffic_type(new_config, traffic_options) + new_config = self._update_packet_type(new_config, traffic_options) self.ssh_helper.upload_config_file(config_basename, new_config) self.ssh_helper.upload_config_file(script_basename, multiport.generate_script(self.vnfd_helper)) diff --git a/yardstick/tests/functional/benchmark/scenarios/networking/test_vnf_generic.py b/yardstick/tests/functional/benchmark/scenarios/networking/test_vnf_generic.py index da75e3a7e..38f1a978d 100644 --- a/yardstick/tests/functional/benchmark/scenarios/networking/test_vnf_generic.py +++ b/yardstick/tests/functional/benchmark/scenarios/networking/test_vnf_generic.py @@ -17,7 +17,6 @@ import sys import mock import unittest -import yaml from yardstick import tests as y_tests from yardstick.common import utils @@ -53,6 +52,24 @@ uplink_{{vport}}: {% endfor %} """ +TOPOLOGY_PROFILE = """ +{% set vports = get(extra_args, 'vports', 2) %} +nsd:nsd-catalog: + nsd: + - id: 3tg-topology + vld: +{% for vport in range(0,vports,2|int) %} + - id: uplink_{{loop.index0}} + name: tg__0 to vnf__0 link {{vport + 1}} + vnfd-connection-point-ref: + - vnfd-connection-point-ref: xe{{vport}} + - id: downlink_{{loop.index0}} + name: vnf__0 to tg__0 link {{vport + 2}} + vnfd-connection-point-ref: + - vnfd-connection-point-ref: xe{{vport+1}} +{% endfor %} +""" + class VnfGenericTestCase(unittest.TestCase): def setUp(self): @@ -61,11 +78,13 @@ class VnfGenericTestCase(unittest.TestCase): 'traffic_profile': 'fake_fprofile_path'} context_cfg = {} topology_yaml = {'nsd:nsd-catalog': {'nsd': [mock.Mock()]}} - with mock.patch.object(yaml, 'load', return_value=topology_yaml), \ - mock.patch.object(utils, 'open_relative_file'): + + with mock.patch.object(utils, 'open_relative_file') as mock_open_path: + mock_open_path.side_effect = mock.mock_open(read_data=str(topology_yaml)) self.ns_testcase = vnf_generic.NetworkServiceTestCase(scenario_cfg, context_cfg) self.ns_testcase._get_traffic_profile = mock.Mock() + self.ns_testcase._get_topology = mock.Mock() def test__fill_traffic_profile_no_args(self): traffic_profile = copy.deepcopy(TRAFFIC_PROFILE_1) @@ -108,3 +127,69 @@ class VnfGenericTestCase(unittest.TestCase): config = self.ns_testcase.traffic_profile.params self.assertEqual({'ipv4': '192.168.0.0'}, config['uplink_0']) self.assertNotIn('uplink_1', config) + + def test__render_topology_with_args(self): + topology_profile = copy.deepcopy(TOPOLOGY_PROFILE) + self.ns_testcase._get_topology.return_value = topology_profile + self.ns_testcase.scenario_cfg['extra_args'] = {'vports': 6} + + self.ns_testcase._render_topology() + topology = self.ns_testcase.topology + self.assertEqual("3tg-topology", topology['id']) + vld = self.ns_testcase.topology['vld'] + self.assertEqual(len(vld), 6) + for index, vport in enumerate(range(0, 6, 2)): + self.assertEqual('uplink_{}'.format(index), vld[vport]['id']) + self.assertEqual('tg__0 to vnf__0 link {}'.format(vport + 1), vld[vport]['name']) + self.assertEqual('xe{}'.format(vport), + vld[vport]['vnfd-connection-point-ref'][0] + ['vnfd-connection-point-ref']) + + self.assertEqual('downlink_{}'.format(index), vld[vport + 1]['id']) + self.assertEqual('vnf__0 to tg__0 link {}'.format(vport + 2), vld[vport + 1]['name']) + self.assertEqual('xe{}'.format(vport + 1), + vld[vport + 1]['vnfd-connection-point-ref'][0] + ['vnfd-connection-point-ref']) + + def test__render_topology_incorrect_args(self): + topology_profile = copy.deepcopy(TOPOLOGY_PROFILE) + self.ns_testcase._get_topology.return_value = topology_profile + self.ns_testcase.scenario_cfg['extra_args'] = {'fake_vports': 5} + + self.ns_testcase._render_topology() + + topology = self.ns_testcase.topology + self.assertEqual("3tg-topology", topology['id']) + vld = self.ns_testcase.topology['vld'] + self.assertEqual(len(vld), 2) + + self.assertEqual('uplink_0', vld[0]['id']) + self.assertEqual('tg__0 to vnf__0 link 1', vld[0]['name']) + self.assertEqual('xe0', + vld[0]['vnfd-connection-point-ref'][0]['vnfd-connection-point-ref']) + + self.assertEqual('downlink_0', vld[1]['id']) + self.assertEqual('vnf__0 to tg__0 link 2', vld[1]['name']) + self.assertEqual('xe1', + vld[1]['vnfd-connection-point-ref'][0]['vnfd-connection-point-ref']) + + def test__render_topology_no_args(self): + topology_profile = copy.deepcopy(TOPOLOGY_PROFILE) + self.ns_testcase._get_topology.return_value = topology_profile + + self.ns_testcase._render_topology() + + topology = self.ns_testcase.topology + self.assertEqual("3tg-topology", topology['id']) + vld = self.ns_testcase.topology['vld'] + self.assertEqual(len(vld), 2) + + self.assertEqual('uplink_0', vld[0]['id']) + self.assertEqual('tg__0 to vnf__0 link 1', vld[0]['name']) + self.assertEqual('xe0', + vld[0]['vnfd-connection-point-ref'][0]['vnfd-connection-point-ref']) + + self.assertEqual('downlink_0', vld[1]['id']) + self.assertEqual('vnf__0 to tg__0 link 2', vld[1]['name']) + self.assertEqual('xe1', + vld[1]['vnfd-connection-point-ref'][0]['vnfd-connection-point-ref']) diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py index 022e66ff1..83db6ae01 100644 --- a/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py @@ -645,6 +645,29 @@ class TestNetworkServiceTestCase(unittest.TestCase): ) mock_tprofile_get.assert_called_once_with(fake_vnfd) + @mock.patch.object(utils, 'open_relative_file') + def test__get_topology(self, mock_open_path): + self.s.scenario_cfg['topology'] = 'fake_topology' + self.s.scenario_cfg['task_path'] = 'fake_path' + mock_open_path.side_effect = mock.mock_open(read_data='fake_data') + self.assertEqual('fake_data', self.s._get_topology()) + mock_open_path.assert_called_once_with('fake_topology', 'fake_path') + + @mock.patch.object(vnfdgen, 'generate_vnfd') + def test__render_topology(self, mock_generate): + fake_topology = 'fake_topology' + mock_generate.return_value = {'nsd:nsd-catalog': {'nsd': ['fake_nsd']}} + with mock.patch.object(self.s, '_get_topology', + return_value=fake_topology) as mock_get_topology: + self.s._render_topology() + mock_get_topology.assert_called_once() + + mock_generate.assert_called_once_with( + fake_topology, + {'extra_args': {'arg1': 'value1', 'arg2': 'value2'}} + ) + self.assertEqual(self.s.topology, 'fake_nsd') + def test_teardown(self): vnf = mock.Mock(autospec=GenericVNF) vnf.terminate = mock.Mock(return_value=True) |