From ba4e9e6e47bd10ecc803bab920178ea973c2fa86 Mon Sep 17 00:00:00 2001 From: Emma Foley Date: Wed, 29 Nov 2017 22:56:21 +0000 Subject: Move tests: unit/benchmark * Fix pylint errors * Add TODOs Some errors are ignored locally, as they were a symptom of other problems. These issues have been flagged with a TODO, and should be fixed later. Change-Id: I30eb4b0aafe0575d0cddbc946108291f21a98ed8 Jira: YARDSTICK-837 Signed-off-by: Emma Foley Signed-off-by: Ross Brattain --- .../benchmark/scenarios/networking/__init__.py | 0 .../benchmark/scenarios/networking/imix_voice.yaml | 41 ++ .../scenarios/networking/iperf3_sample_output.json | 1 + .../networking/iperf3_sample_output_udp.json | 1 + .../networking/ipv4_1flow_Packets_vpe.yaml | 18 + .../scenarios/networking/ipv4_throughput_vpe.yaml | 101 +++ .../networking/netperf_sample_output.json | 1 + .../networking/netutilization_sample_output1.txt | 9 + .../networking/netutilization_sample_output2.txt | 13 + .../benchmark/scenarios/networking/test_iperf3.py | 202 ++++++ .../benchmark/scenarios/networking/test_netperf.py | 130 ++++ .../scenarios/networking/test_netperf_node.py | 130 ++++ .../scenarios/networking/test_netutilization.py | 227 ++++++ .../scenarios/networking/test_networkcapacity.py | 61 ++ .../benchmark/scenarios/networking/test_nstat.py | 113 +++ .../benchmark/scenarios/networking/test_ping.py | 101 +++ .../benchmark/scenarios/networking/test_ping6.py | 125 ++++ .../benchmark/scenarios/networking/test_pktgen.py | 675 +++++++++++++++++ .../scenarios/networking/test_pktgen_dpdk.py | 186 +++++ .../networking/test_pktgen_dpdk_throughput.py | 202 ++++++ .../benchmark/scenarios/networking/test_sfc.py | 77 ++ .../scenarios/networking/test_vnf_generic.py | 798 +++++++++++++++++++++ .../benchmark/scenarios/networking/test_vsperf.py | 136 ++++ .../scenarios/networking/test_vsperf_dpdk.py | 221 ++++++ .../scenarios/networking/tg_trex_tpl.yaml | 75 ++ .../scenarios/networking/vpe_vnf_topology.yaml | 50 ++ 26 files changed, 3694 insertions(+) create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/__init__.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/imix_voice.yaml create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output.json create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output_udp.json create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/ipv4_1flow_Packets_vpe.yaml create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/ipv4_throughput_vpe.yaml create mode 100755 yardstick/tests/unit/benchmark/scenarios/networking/netperf_sample_output.json create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output1.txt create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output2.txt create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_iperf3.py create mode 100755 yardstick/tests/unit/benchmark/scenarios/networking/test_netperf.py create mode 100755 yardstick/tests/unit/benchmark/scenarios/networking/test_netperf_node.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_netutilization.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_networkcapacity.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_nstat.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_ping.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_ping6.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk_throughput.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_sfc.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/tg_trex_tpl.yaml create mode 100644 yardstick/tests/unit/benchmark/scenarios/networking/vpe_vnf_topology.yaml (limited to 'yardstick/tests/unit/benchmark/scenarios/networking') diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/__init__.py b/yardstick/tests/unit/benchmark/scenarios/networking/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/imix_voice.yaml b/yardstick/tests/unit/benchmark/scenarios/networking/imix_voice.yaml new file mode 100644 index 000000000..b8f8e5358 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/imix_voice.yaml @@ -0,0 +1,41 @@ +# 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. + +#imix definition for voice traffic +# +# it is a typical case for testing the synthetic VNF performance. +# +#percentage of the packets can be less than 100% +#the traffic in downstream and upstream direction could be different + +schema: "nsb:imix:0.1" + +imix: + private: + imix_small: 100 #ipv4 case - 72B should be 0 ipv6 case - 84B + imix_128B: 0 + imix_256B: 0 + imix_373B: 0 + imix_570B: 0 + imix_1400B: 0 + imix_1500B: 0 + + public: + imix_small: 100 #ipv4 case - 72B ipv6 - 84B + imix_128B: 0 + imix_256B: 0 + imix_373B: 0 + imix_570B: 0 + imix_1400B: 0 + imix_1500B: 0 diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output.json b/yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output.json new file mode 100644 index 000000000..b56009ba1 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output.json @@ -0,0 +1 @@ +{"start": {"connecting_to": {"host": "172.16.0.252", "port": 5201}, "timestamp": {"timesecs": 1436254758, "time": "Tue, 07 Jul 2015 07:39:18 GMT"}, "test_start": {"protocol": "TCP", "num_streams": 1, "omit": 0, "bytes": 0, "blksize": 131072, "duration": 10, "blocks": 0, "reverse": 0}, "system_info": "Linux client 3.13.0-55-generic #94-Ubuntu SMP Thu Jun 18 00:27:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux\n", "version": "iperf 3.0.7", "connected": [{"local_host": "10.0.1.2", "local_port": 37633, "remote_host": "172.16.0.252", "socket": 4, "remote_port": 5201}], "cookie": "client.1436254758.606879.1fb328dc230", "tcp_mss_default": 1448}, "intervals": [{"sum": {"end": 1.00068, "seconds": 1.00068, "bytes": 16996624, "bits_per_second": 135881000.0, "start": 0, "retransmits": 0, "omitted": false}, "streams": [{"end": 1.00068, "socket": 4, "seconds": 1.00068, "bytes": 16996624, "bits_per_second": 135881000.0, "start": 0, "retransmits": 0, "omitted": false, "snd_cwnd": 451776}]}, {"sum": {"end": 2.00048, "seconds": 0.999804, "bytes": 20010192, "bits_per_second": 160113000.0, "start": 1.00068, "retransmits": 0, "omitted": false}, "streams": [{"end": 2.00048, "socket": 4, "seconds": 0.999804, "bytes": 20010192, "bits_per_second": 160113000.0, "start": 1.00068, "retransmits": 0, "omitted": false, "snd_cwnd": 713864}]}, {"sum": {"end": 3.00083, "seconds": 1.00035, "bytes": 18330464, "bits_per_second": 146592000.0, "start": 2.00048, "retransmits": 0, "omitted": false}, "streams": [{"end": 3.00083, "socket": 4, "seconds": 1.00035, "bytes": 18330464, "bits_per_second": 146592000.0, "start": 2.00048, "retransmits": 0, "omitted": false, "snd_cwnd": 768888}]}, {"sum": {"end": 4.00707, "seconds": 1.00624, "bytes": 19658376, "bits_per_second": 156292000.0, "start": 3.00083, "retransmits": 0, "omitted": false}, "streams": [{"end": 4.00707, "socket": 4, "seconds": 1.00624, "bytes": 19658376, "bits_per_second": 156292000.0, "start": 3.00083, "retransmits": 0, "omitted": false, "snd_cwnd": 812328}]}, {"sum": {"end": 5.00104, "seconds": 0.993972, "bytes": 15709072, "bits_per_second": 126435000.0, "start": 4.00707, "retransmits": 0, "omitted": false}, "streams": [{"end": 5.00104, "socket": 4, "seconds": 0.993972, "bytes": 15709072, "bits_per_second": 126435000.0, "start": 4.00707, "retransmits": 0, "omitted": false, "snd_cwnd": 849976}]}, {"sum": {"end": 6.00049, "seconds": 0.999443, "bytes": 19616288, "bits_per_second": 157018000.0, "start": 5.00104, "retransmits": 53, "omitted": false}, "streams": [{"end": 6.00049, "socket": 4, "seconds": 0.999443, "bytes": 19616288, "bits_per_second": 157018000.0, "start": 5.00104, "retransmits": 53, "omitted": false, "snd_cwnd": 641464}]}, {"sum": {"end": 7.00085, "seconds": 1.00036, "bytes": 22250480, "bits_per_second": 177939000.0, "start": 6.00049, "retransmits": 0, "omitted": false}, "streams": [{"end": 7.00085, "socket": 4, "seconds": 1.00036, "bytes": 22250480, "bits_per_second": 177939000.0, "start": 6.00049, "retransmits": 0, "omitted": false, "snd_cwnd": 706624}]}, {"sum": {"end": 8.00476, "seconds": 1.00391, "bytes": 22282240, "bits_per_second": 177564000.0, "start": 7.00085, "retransmits": 0, "omitted": false}, "streams": [{"end": 8.00476, "socket": 4, "seconds": 1.00391, "bytes": 22282240, "bits_per_second": 177564000.0, "start": 7.00085, "retransmits": 0, "omitted": false, "snd_cwnd": 761648}]}, {"sum": {"end": 9.0016, "seconds": 0.996847, "bytes": 19657680, "bits_per_second": 157759000.0, "start": 8.00476, "retransmits": 28, "omitted": false}, "streams": [{"end": 9.0016, "socket": 4, "seconds": 0.996847, "bytes": 19657680, "bits_per_second": 157759000.0, "start": 8.00476, "retransmits": 28, "omitted": false, "snd_cwnd": 570512}]}, {"sum": {"end": 10.0112, "seconds": 1.00955, "bytes": 20932520, "bits_per_second": 165876000.0, "start": 9.0016, "retransmits": 0, "omitted": false}, "streams": [{"end": 10.0112, "socket": 4, "seconds": 1.00955, "bytes": 20932520, "bits_per_second": 165876000.0, "start": 9.0016, "retransmits": 0, "omitted": false, "snd_cwnd": 615400}]}], "end": {"sum_received": {"seconds": 10.0112, "start": 0, "end": 10.0112, "bytes": 193366712, "bits_per_second": 154521000.0}, "streams": [{"sender": {"end": 10.0112, "socket": 4, "seconds": 10.0112, "bytes": 195443936, "bits_per_second": 156181000.0, "start": 0, "retransmits": 81}, "receiver": {"end": 10.0112, "socket": 4, "seconds": 10.0112, "bytes": 193366712, "bits_per_second": 154521000.0, "start": 0}}], "sum_sent": {"end": 10.0112, "seconds": 10.0112, "bytes": 195443936, "bits_per_second": 156181000.0, "start": 0, "retransmits": 81}, "cpu_utilization_percent": {"remote_user": 1.10295, "remote_system": 40.0403, "host_user": 2.41785, "remote_total": 41.1438, "host_system": 5.09548, "host_total": 7.51411}}} \ No newline at end of file diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output_udp.json b/yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output_udp.json new file mode 100644 index 000000000..8173c8f64 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/iperf3_sample_output_udp.json @@ -0,0 +1 @@ +{"start":{"connected":[{"socket":4, "local_host":"10.0.1.2", "local_port":46384, "remote_host":"172.16.9.195", "remote_port":5201}], "version":"iperf 3.0.7", "system_info":"Linux zeus 3.13.0-61-generic #100-Ubuntu SMP Wed Jul 29 11:21:34 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux\n", "timestamp":{"time":"Tue, 29 Sep 2015 01:48:23 GMT", "timesecs":1443491303}, "connecting_to":{"host":"172.16.9.195", "port":5201}, "cookie":"zeus.1443491303.539703.3479129b58a5b", "test_start":{"protocol":"UDP", "num_streams":1, "blksize":8192, "omit":0, "duration":10, "bytes":0, "blocks":0, "reverse":0}}, "intervals":[{"streams":[{"socket":4, "start":0, "end":1.00022, "seconds":1.00022, "bytes":2252800, "bits_per_second":1.80184e+07, "packets":275, "omitted":false}], "sum":{"start":0, "end":1.00022, "seconds":1.00022, "bytes":2252800, "bits_per_second":1.80184e+07, "packets":275, "omitted":false}}, {"streams":[{"socket":4, "start":1.00022, "end":2.00022, "seconds":0.999993, "bytes":2498560, "bits_per_second":1.99886e+07, "packets":305, "omitted":false}], "sum":{"start":1.00022, "end":2.00022, "seconds":0.999993, "bytes":2498560, "bits_per_second":1.99886e+07, "packets":305, "omitted":false}}, {"streams":[{"socket":4, "start":2.00022, "end":3.00022, "seconds":1, "bytes":2506752, "bits_per_second":2.0054e+07, "packets":306, "omitted":false}], "sum":{"start":2.00022, "end":3.00022, "seconds":1, "bytes":2506752, "bits_per_second":2.0054e+07, "packets":306, "omitted":false}}, {"streams":[{"socket":4, "start":3.00022, "end":4.00022, "seconds":1, "bytes":2498560, "bits_per_second":19988480, "packets":305, "omitted":false}], "sum":{"start":3.00022, "end":4.00022, "seconds":1, "bytes":2498560, "bits_per_second":19988480, "packets":305, "omitted":false}}, {"streams":[{"socket":4, "start":4.00022, "end":5.0002, "seconds":0.999977, "bytes":2498560, "bits_per_second":1.99889e+07, "packets":305, "omitted":false}], "sum":{"start":4.00022, "end":5.0002, "seconds":0.999977, "bytes":2498560, "bits_per_second":1.99889e+07, "packets":305, "omitted":false}}, {"streams":[{"socket":4, "start":5.0002, "end":6.00024, "seconds":1.00004, "bytes":2498560, "bits_per_second":1.99877e+07, "packets":305, "omitted":false}], "sum":{"start":5.0002, "end":6.00024, "seconds":1.00004, "bytes":2498560, "bits_per_second":1.99877e+07, "packets":305, "omitted":false}}, {"streams":[{"socket":4, "start":6.00024, "end":7.00023, "seconds":0.999998, "bytes":2498560, "bits_per_second":1.99885e+07, "packets":305, "omitted":false}], "sum":{"start":6.00024, "end":7.00023, "seconds":0.999998, "bytes":2498560, "bits_per_second":1.99885e+07, "packets":305, "omitted":false}}, {"streams":[{"socket":4, "start":7.00023, "end":8.00023, "seconds":0.999999, "bytes":2506752, "bits_per_second":2.0054e+07, "packets":306, "omitted":false}], "sum":{"start":7.00023, "end":8.00023, "seconds":0.999999, "bytes":2506752, "bits_per_second":2.0054e+07, "packets":306, "omitted":false}}, {"streams":[{"socket":4, "start":8.00023, "end":9.00018, "seconds":0.999945, "bytes":2498560, "bits_per_second":1.99896e+07, "packets":305, "omitted":false}], "sum":{"start":8.00023, "end":9.00018, "seconds":0.999945, "bytes":2498560, "bits_per_second":1.99896e+07, "packets":305, "omitted":false}}, {"streams":[{"socket":4, "start":9.00018, "end":10.0002, "seconds":1.00004, "bytes":2498560, "bits_per_second":1.99876e+07, "packets":305, "omitted":false}], "sum":{"start":9.00018, "end":10.0002, "seconds":1.00004, "bytes":2498560, "bits_per_second":1.99876e+07, "packets":305, "omitted":false}}], "end":{"streams":[{"udp":{"socket":4, "start":0, "end":10.0002, "seconds":10.0002, "bytes":24756224, "bits_per_second":1.98045e+07, "jitter_ms":0.0113579, "lost_packets":0, "packets":3022, "lost_percent":0}}], "sum":{"start":0, "end":10.0002, "seconds":10.0002, "bytes":24756224, "bits_per_second":1.98045e+07, "jitter_ms":0.0113579, "lost_packets":0, "packets":3022, "lost_percent":0}, "cpu_utilization_percent":{"host_total":0.647561, "host_user":0.146468, "host_system":0.501083, "remote_total":0.31751, "remote_user":0, "remote_system":0.31751}}} diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/ipv4_1flow_Packets_vpe.yaml b/yardstick/tests/unit/benchmark/scenarios/networking/ipv4_1flow_Packets_vpe.yaml new file mode 100644 index 000000000..f3046f463 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/ipv4_1flow_Packets_vpe.yaml @@ -0,0 +1,18 @@ +# 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. + +flow: + srcip4_range: '152.16.0.20' + dstip4_range: '152.40.0.20' + count: 1 diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/ipv4_throughput_vpe.yaml b/yardstick/tests/unit/benchmark/scenarios/networking/ipv4_throughput_vpe.yaml new file mode 100644 index 000000000..2123e4705 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/ipv4_throughput_vpe.yaml @@ -0,0 +1,101 @@ +# 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. + +# 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. +# +schema: "isb: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) + + +private: + ipv4: + outer_l2: + framesize: + 64B: "{{ get(imix, 'imix.uplink.imix_small', '0') }}" + 128B: "{{ get(imix, 'imix.uplink.imix_128B', '0') }}" + 256B: "{{ get(imix, 'imix.uplink.imix_256B', '0') }}" + 373b: "{{ get(imix, 'imix.uplink.imix_373B', '0') }}" + 570B: "{{get(imix, 'imix.uplink.imix_570B', '0') }}" + 1400B: "{{get(imix, 'imix.uplink.imix_1400B', '0') }}" + 1518B: "{{get(imix, 'imix.uplink.imix_1500B', '0') }}" + + QinQ: + S-VLAN: + id: 128 + priority: 0 + cfi: 0 + C-VLAN: + id: 512 + priority: 0 + cfi: 0 + + outer_l3v4: + proto: "tcp" + srcip4: "{{get(flow, 'flow.srcip4_range', '192.168.0.0-192.168.255.255') }}" + dstip4: "{{get(flow, 'flow.dstip4_range', '192.16.0.0-192.16.0.31') }}" + ttl: 32 + dscp: 32 + + outer_l4: + srcport: "{{get(flow, 'flow.srcport_range', '0') }}" + dstport: "{{get(flow, 'flow.dstport_range', '0') }}" +public: + ipv4: + outer_l2: + framesize: + 64B: "{{ get(imix, 'imix.uplink.imix_small', '0') }}" + 128B: "{{ get(imix, 'imix.uplink.imix_128B', '0') }}" + 256B: "{{ get(imix, 'imix.uplink.imix_256B', '0') }}" + 373b: "{{ get(imix, 'imix.uplink.imix_373B', '0') }}" + 570B: "{{get(imix, 'imix.uplink.imix_570B', '0') }}" + 1400B: "{{get(imix, 'imix.uplink.imix_1400B', '0') }}" + 1518B: "{{get(imix, 'imix.uplink.imix_1500B', '0') }}" + + outer_l3v4: + proto: "tcp" + srcip4: "{{get(flow, 'flow.dstip4_range', '192.16.0.0-192.16.0.31') }}" + dstip4: "{{get(flow, 'flow.srcip4_range', '192.168.0.0-192.168.255.255') }}" + ttl: 32 + dscp: 32 + + outer_l4: + srcport: "{{get(flow, 'flow.dstport_range', '0') }}" + dstport: "{{get(flow, 'flow.srcport_range', '0') }}" diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/netperf_sample_output.json b/yardstick/tests/unit/benchmark/scenarios/networking/netperf_sample_output.json new file mode 100755 index 000000000..bba76cfa5 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/netperf_sample_output.json @@ -0,0 +1 @@ +{"mean_latency":"9.49","troughput":"823.77","troughput_unit":"10^6bits/s"} \ No newline at end of file diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output1.txt b/yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output1.txt new file mode 100644 index 000000000..f90457cb3 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output1.txt @@ -0,0 +1,9 @@ +Linux 3.19.0-25-generic (huawei-pod4) 07/19/2016 _x86_64_ (1 CPU) + +02:01:50 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil +02:01:51 PM eth0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +02:01:51 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil +Average: eth0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output2.txt b/yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output2.txt new file mode 100644 index 000000000..417613ec1 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/netutilization_sample_output2.txt @@ -0,0 +1,13 @@ +Linux 3.19.0-25-generic (huawei-pod4) 07/19/2016 _x86_64_ (1 CPU) + +02:01:50 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil +02:01:51 PM eth0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +02:01:51 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +02:01:52 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil +02:01:53 PM eth0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +02:01:53 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil +Average: eth0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_iperf3.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_iperf3.py new file mode 100644 index 000000000..4d3745230 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_iperf3.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for yardstick.benchmark.scenarios.networking.iperf3.Iperf + +from __future__ import absolute_import + +import os +import unittest + +import mock +from oslo_serialization import jsonutils + +from yardstick.common import utils +from yardstick.benchmark.scenarios.networking import iperf3 + + +@mock.patch('yardstick.benchmark.scenarios.networking.iperf3.ssh') +class IperfTestCase(unittest.TestCase): + output_name_tcp = 'iperf3_sample_output.json' + output_name_udp = 'iperf3_sample_output_udp.json' + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'root', + 'key_filename': 'mykey.key' + }, + 'target': { + 'ip': '172.16.0.138', + 'user': 'root', + 'key_filename': 'mykey.key', + 'ipaddr': '172.16.0.138', + } + } + + def test_iperf_successful_setup(self, mock_ssh): + + p = iperf3.Iperf({}, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + p.setup() + self.assertIsNotNone(p.target) + self.assertIsNotNone(p.host) + mock_ssh.SSH.from_node().execute.assert_called_with("iperf3 -s -D") + + def test_iperf_unsuccessful_setup(self, mock_ssh): + + p = iperf3.Iperf({}, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.setup) + + def test_iperf_successful_teardown(self, mock_ssh): + + p = iperf3.Iperf({}, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + p.target = mock_ssh.SSH.from_node() + + p.teardown() + self.assertTrue(mock_ssh.SSH.from_node().close.called) + mock_ssh.SSH.from_node().execute.assert_called_with("pkill iperf3") + + def test_iperf_successful_no_sla(self, mock_ssh): + + options = {} + args = {'options': options} + result = {} + + p = iperf3.Iperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output(self.output_name_tcp) + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = utils.flatten_dict_key(jsonutils.loads(sample_output)) + p.run(result) + self.assertEqual(result, expected_result) + + def test_iperf_successful_sla(self, mock_ssh): + + options = {} + args = { + 'options': options, + 'sla': {'bytes_per_second': 15000000} + } + result = {} + + p = iperf3.Iperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output(self.output_name_tcp) + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = utils.flatten_dict_key(jsonutils.loads(sample_output)) + p.run(result) + self.assertEqual(result, expected_result) + + def test_iperf_unsuccessful_sla(self, mock_ssh): + + options = {} + args = { + 'options': options, + 'sla': {'bytes_per_second': 25000000} + } + result = {} + + p = iperf3.Iperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output(self.output_name_tcp) + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + self.assertRaises(AssertionError, p.run, result) + + def test_iperf_successful_sla_jitter(self, mock_ssh): + options = {"protocol": "udp", "bandwidth": "20m"} + args = { + 'options': options, + 'sla': {'jitter': 10} + } + result = {} + + p = iperf3.Iperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output(self.output_name_udp) + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = utils.flatten_dict_key(jsonutils.loads(sample_output)) + p.run(result) + self.assertEqual(result, expected_result) + + def test_iperf_unsuccessful_sla_jitter(self, mock_ssh): + options = {"protocol": "udp", "bandwidth": "20m"} + args = { + 'options': options, + 'sla': {'jitter': 0.0001} + } + result = {} + + p = iperf3.Iperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output(self.output_name_udp) + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + self.assertRaises(AssertionError, p.run, result) + + def test_iperf_successful_tcp_protocal(self, mock_ssh): + options = {"protocol": "tcp", "nodelay": "yes"} + args = { + 'options': options, + 'sla': {'bytes_per_second': 15000000} + } + result = {} + + p = iperf3.Iperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output(self.output_name_tcp) + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = utils.flatten_dict_key(jsonutils.loads(sample_output)) + p.run(result) + self.assertEqual(result, expected_result) + + def test_iperf_unsuccessful_script_error(self, mock_ssh): + + options = {} + args = {'options': options} + result = {} + + p = iperf3.Iperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.run, result) + + def _read_sample_output(self, filename): + curr_path = os.path.dirname(os.path.abspath(__file__)) + output = os.path.join(curr_path, filename) + with open(output) as f: + sample_output = f.read() + return sample_output + + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_netperf.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_netperf.py new file mode 100755 index 000000000..d82a00931 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_netperf.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for yardstick.benchmark.scenarios.networking.netperf.Netperf + +from __future__ import absolute_import + +import os +import unittest + +import mock +from oslo_serialization import jsonutils + +from yardstick.benchmark.scenarios.networking import netperf + + +@mock.patch('yardstick.benchmark.scenarios.networking.netperf.ssh') +class NetperfTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'cirros', + 'key_filename': 'mykey.key' + }, + 'target': { + 'ip': '172.16.0.138', + 'user': 'cirros', + 'key_filename': 'mykey.key', + 'ipaddr': '172.16.0.138' + } + } + + def test_netperf_successful_setup(self, mock_ssh): + + p = netperf.Netperf({}, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + p.setup() + self.assertIsNotNone(p.server) + self.assertIsNotNone(p.client) + self.assertTrue(p.setup_done) + + def test_netperf_successful_no_sla(self, mock_ssh): + + options = {} + args = {'options': options} + result = {} + + p = netperf.Netperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output() + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = jsonutils.loads(sample_output) + p.run(result) + self.assertEqual(result, expected_result) + + def test_netperf_successful_sla(self, mock_ssh): + + options = {} + args = { + 'options': options, + 'sla': {'mean_latency': 100} + } + result = {} + + p = netperf.Netperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output() + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = jsonutils.loads(sample_output) + p.run(result) + self.assertEqual(result, expected_result) + + def test_netperf_unsuccessful_sla(self, mock_ssh): + + options = {} + args = { + 'options': options, + 'sla': {'mean_latency': 5} + } + result = {} + + p = netperf.Netperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output() + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + self.assertRaises(AssertionError, p.run, result) + + def test_netperf_unsuccessful_script_error(self, mock_ssh): + + options = {} + args = {'options': options} + result = {} + + p = netperf.Netperf(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.run, result) + + def _read_sample_output(self): + curr_path = os.path.dirname(os.path.abspath(__file__)) + output = os.path.join(curr_path, 'netperf_sample_output.json') + with open(output) as f: + sample_output = f.read() + return sample_output + + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_netperf_node.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_netperf_node.py new file mode 100755 index 000000000..8be9bb94d --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_netperf_node.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for +# yardstick.benchmark.scenarios.networking.netperf_node.NetperfNode + +from __future__ import absolute_import + +import os +import unittest + +import mock +from oslo_serialization import jsonutils + +from yardstick.benchmark.scenarios.networking import netperf_node + + +@mock.patch('yardstick.benchmark.scenarios.networking.netperf_node.ssh') +class NetperfNodeTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '192.168.10.10', + 'user': 'root', + 'password': 'root' + }, + 'target': { + 'ip': '192.168.10.11', + 'user': 'root', + 'password': 'root' + } + } + + def test_netperf_node_successful_setup(self, mock_ssh): + + p = netperf_node.NetperfNode({}, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + p.setup() + self.assertIsNotNone(p.server) + self.assertIsNotNone(p.client) + self.assertTrue(p.setup_done) + + def test_netperf_node_successful_no_sla(self, mock_ssh): + + options = {} + args = {'options': options} + result = {} + + p = netperf_node.NetperfNode(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output() + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = jsonutils.loads(sample_output) + p.run(result) + self.assertEqual(result, expected_result) + + def test_netperf_node_successful_sla(self, mock_ssh): + + options = {} + args = { + 'options': options, + 'sla': {'mean_latency': 100} + } + result = {} + + p = netperf_node.NetperfNode(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output() + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + expected_result = jsonutils.loads(sample_output) + p.run(result) + self.assertEqual(result, expected_result) + + def test_netperf_node_unsuccessful_sla(self, mock_ssh): + + options = {} + args = { + 'options': options, + 'sla': {'mean_latency': 5} + } + result = {} + + p = netperf_node.NetperfNode(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + sample_output = self._read_sample_output() + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + self.assertRaises(AssertionError, p.run, result) + + def test_netperf_node_unsuccessful_script_error(self, mock_ssh): + + options = {} + args = {'options': options} + result = {} + + p = netperf_node.NetperfNode(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + p.host = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.run, result) + + def _read_sample_output(self): + curr_path = os.path.dirname(os.path.abspath(__file__)) + output = os.path.join(curr_path, 'netperf_sample_output.json') + with open(output) as f: + sample_output = f.read() + return sample_output + + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_netutilization.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_netutilization.py new file mode 100644 index 000000000..1227e056e --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_netutilization.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2016 Huawei Technologies Co.,Ltd and other. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for +# yardstick.benchmark.scenarios.networking.netutilization.NetUtilization + +from __future__ import absolute_import +import mock +import unittest +import os + +from yardstick.benchmark.scenarios.networking import netutilization + + +@mock.patch('yardstick.benchmark.scenarios.networking.netutilization.ssh') +class NetUtilizationTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'cirros', + 'key_filename': "mykey.key" + } + } + + self.result = {} + + def test_setup_success(self, mock_ssh): + options = { + "interval": 1, + "count": 1 + } + args = {'options': options} + + n = netutilization.NetUtilization(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + n.setup() + self.assertIsNotNone(n.client) + self.assertTrue(n.setup_done) + + def test_execute_command_success(self, mock_ssh): + options = { + "interval": 1, + "count": 1 + } + args = {'options': options} + + n = netutilization.NetUtilization(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + n.setup() + + expected_result = 'abcdefg' + mock_ssh.SSH.from_node().execute.return_value = (0, expected_result, '') + result = n._execute_command("foo") + self.assertEqual(result, expected_result) + + def test_execute_command_failed(self, mock_ssh): + options = { + "interval": 1, + "count": 1 + } + args = {'options': options} + + n = netutilization.NetUtilization(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + n.setup() + + mock_ssh.SSH.from_node().execute.return_value = (127, '', 'abcdefg') + self.assertRaises(RuntimeError, n._execute_command, + "failed") + + def test_get_network_utilization_success(self, mock_ssh): + options = { + "interval": 1, + "count": 1 + } + args = {'options': options} + + n = netutilization.NetUtilization(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + n.setup() + + mpstat_output = self._read_file("netutilization_sample_output1.txt") + mock_ssh.SSH.from_node().execute.return_value = (0, mpstat_output, '') + result = n._get_network_utilization() + + expected_result = \ + {"network_utilization_maximun": { + "lo": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}, + "eth0": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}}, + "network_utilization_average": { + "lo": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}, + "eth0": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}}, + "network_utilization_minimum": { + "lo": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}, + "eth0": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}}} + + self.assertDictEqual(result, expected_result) + + def test_get_network_utilization_2_success(self, mock_ssh): + options = { + "interval": 1, + "count": 2 + } + args = {'options': options} + + n = netutilization.NetUtilization(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + n.setup() + + mpstat_output = self._read_file("netutilization_sample_output2.txt") + mock_ssh.SSH.from_node().execute.return_value = (0, mpstat_output, '') + result = n._get_network_utilization() + + expected_result = \ + {"network_utilization_maximun": { + "lo": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}, + "eth0": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}}, + "network_utilization_average": { + "lo": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}, + "eth0": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}}, + "network_utilization_minimum": { + "lo": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}, + "eth0": {"rxcmp/s": "0.00", + "%ifutil": "0.00", + "txcmp/s": "0.00", + "txkB/s": "0.00", + "rxkB/s": "0.00", + "rxpck/s": "0.00", + "txpck/s": "0.00", + "rxmcst/s": "0.00"}}} + + self.assertDictEqual(result, expected_result) + + def _read_file(self, filename): + curr_path = os.path.dirname(os.path.abspath(__file__)) + output = os.path.join(curr_path, filename) + with open(output) as f: + sample_output = f.read() + return sample_output diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_networkcapacity.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_networkcapacity.py new file mode 100644 index 000000000..3e7a3c5ee --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_networkcapacity.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for +# yardstick.benchmark.scenarios.networking.networkcapacity.NetworkCapacity + +from __future__ import absolute_import + +import unittest + +import mock +from oslo_serialization import jsonutils + +from yardstick.benchmark.scenarios.networking import networkcapacity + +SAMPLE_OUTPUT = \ + '{"Number of connections":"308","Number of frames received": "166503"}' + + +@mock.patch('yardstick.benchmark.scenarios.networking.networkcapacity.ssh') +class NetworkCapacityTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'cirros', + 'password': "root" + }, + } + + self.result = {} + + def test_capacity_successful_setup(self, mock_ssh): + c = networkcapacity.NetworkCapacity({}, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + c.setup() + self.assertIsNotNone(c.client) + self.assertTrue(c.setup_done) + + def test_capacity_successful(self, mock_ssh): + c = networkcapacity.NetworkCapacity({}, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (0, SAMPLE_OUTPUT, '') + c.run(self.result) + expected_result = jsonutils.loads(SAMPLE_OUTPUT) + self.assertEqual(self.result, expected_result) + + def test_capacity_unsuccessful_script_error(self, mock_ssh): + c = networkcapacity.NetworkCapacity({}, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, c.run, self.result) diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_nstat.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_nstat.py new file mode 100644 index 000000000..7dd5351b1 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_nstat.py @@ -0,0 +1,113 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +import mock +import unittest + +from yardstick.benchmark.scenarios.networking import nstat + + +@mock.patch('yardstick.benchmark.scenarios.networking.nstat.ssh') +class NstatTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + "host": { + "ip": "192.168.50.28", + "user": "root", + "key_filename": "mykey.key" + } + } + + def test_nstat_successful_setup(self, mock_ssh): + + n = nstat.Nstat({}, self.ctx) + n.setup() + + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.assertIsNotNone(n.client) + self.assertTrue(n.setup_done) + + def test_nstat_successful_no_sla(self, mock_ssh): + + options = { + "duration": 0 + } + args = { + "options": options, + } + n = nstat.Nstat(args, self.ctx) + result = {} + + sample_output = '#kernel\nIpInReceives 1837 0.0\nIpInHdrErrors 0 0.0\nIpInAddrErrors 2 0.0\nIcmpInMsgs 319 0.0\nIcmpInErrors 0 0.0\nTcpInSegs 36 0.0\nTcpInErrs 0 0.0\nUdpInDatagrams 1318 0.0\nUdpInErrors 0 0.0\n' # pylint: disable=line-too-long + + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + n.run(result) + expected_result = {"TcpInErrs": 0, "UdpInDatagrams": 1318, + "Tcp_segment_error_rate": 0.0, "IpInAddrErrors": 2, + "IpInHdrErrors": 0, "IcmpInErrors": 0, "IpErrors": 2, + "TcpInSegs": 36, "IpInReceives": 1837, "IcmpInMsgs": 319, + "IP_datagram_error_rate": 0.001, "Udp_datagram_error_rate": 0.0, + "Icmp_message_error_rate": 0.0, "UdpInErrors": 0} + self.assertEqual(result, expected_result) + + def test_nstat_successful_sla(self, mock_ssh): + + options = { + "duration": 0 + } + sla = { + "IP_datagram_error_rate": 0.1 + } + args = { + "options": options, + "sla": sla + } + n = nstat.Nstat(args, self.ctx) + result = {} + + sample_output = '#kernel\nIpInReceives 1837 0.0\nIpInHdrErrors 0 0.0\nIpInAddrErrors 2 0.0\nIcmpInMsgs 319 0.0\nIcmpInErrors 0 0.0\nTcpInSegs 36 0.0\nTcpInErrs 0 0.0\nUdpInDatagrams 1318 0.0\nUdpInErrors 0 0.0\n' # pylint: disable=line-too-long + + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + n.run(result) + expected_result = {"TcpInErrs": 0, "UdpInDatagrams": 1318, + "Tcp_segment_error_rate": 0.0, "IpInAddrErrors": 2, + "IpInHdrErrors": 0, "IcmpInErrors": 0, "IpErrors": 2, + "TcpInSegs": 36, "IpInReceives": 1837, "IcmpInMsgs": 319, + "IP_datagram_error_rate": 0.001, "Udp_datagram_error_rate": 0.0, + "Icmp_message_error_rate": 0.0, "UdpInErrors": 0} + self.assertEqual(result, expected_result) + + def test_nstat_unsuccessful_cmd_error(self, mock_ssh): + + options = { + "duration": 0 + } + sla = { + "IP_datagram_error_rate": 0.1 + } + args = { + "options": options, + "sla": sla + } + n = nstat.Nstat(args, self.ctx) + result = {} + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, n.run, result) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_ping.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_ping.py new file mode 100644 index 000000000..06353249a --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_ping.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for yardstick.benchmark.scenarios.networking.ping.Ping + +from __future__ import absolute_import +import mock +import unittest + +from yardstick.benchmark.scenarios.networking import ping + + +class PingTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'cirros', + 'key_filename': "mykey.key" + }, + "target": { + "ipaddr": "10.229.17.105", + } + } + + @mock.patch('yardstick.benchmark.scenarios.networking.ping.ssh') + def test_ping_successful_no_sla(self, mock_ssh): + + args = { + 'options': {'packetsize': 200}, + 'target': 'ares.demo' + } + result = {} + + p = ping.Ping(args, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (0, '100', '') + p.run(result) + self.assertEqual(result, {'rtt.ares': 100.0}) + + @mock.patch('yardstick.benchmark.scenarios.networking.ping.ssh') + def test_ping_successful_sla(self, mock_ssh): + + args = { + 'options': {'packetsize': 200}, + 'sla': {'max_rtt': 150}, + 'target': 'ares.demo' + } + result = {} + + p = ping.Ping(args, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (0, '100', '') + p.run(result) + self.assertEqual(result, {'rtt.ares': 100.0}) + + @mock.patch('yardstick.benchmark.scenarios.networking.ping.ssh') + def test_ping_unsuccessful_sla(self, mock_ssh): + + args = { + 'options': {'packetsize': 200}, + 'sla': {'max_rtt': 50}, + 'target': 'ares.demo' + } + result = {} + + p = ping.Ping(args, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (0, '100', '') + self.assertRaises(AssertionError, p.run, result) + + @mock.patch('yardstick.benchmark.scenarios.networking.ping.ssh') + def test_ping_unsuccessful_script_error(self, mock_ssh): + + args = { + 'options': {'packetsize': 200}, + 'sla': {'max_rtt': 50}, + 'target': 'ares.demo' + } + result = {} + + p = ping.Ping(args, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.run, result) + + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_ping6.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_ping6.py new file mode 100644 index 000000000..d2be6f576 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_ping6.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for yardstick.benchmark.scenarios.networking.ping.Ping + +from __future__ import absolute_import +import mock +import unittest + +from yardstick.benchmark.scenarios.networking import ping6 + + +class PingTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'nodes': { + 'host1': { + 'ip': '172.16.0.137', + 'user': 'cirros', + 'role': "Controller", + 'key_filename': "mykey.key", + 'password': "root" + }, + 'host2': { + "ip": "172.16.0.138", + "key_filename": "/root/.ssh/id_rsa", + "role": "Compute", + "name": "node3.IPV6", + "user": "root" + }, + } + } + + def test_get_controller_node(self): + args = { + 'options': {'host': 'host1', 'packetsize': 200, 'ping_count': 5}, + 'sla': {'max_rtt': 50} + } + p = ping6.Ping6(args, self.ctx) + controller_node = p._get_controller_node(['host1', 'host2']) + self.assertEqual(controller_node, 'host1') + + @mock.patch('yardstick.benchmark.scenarios.networking.ping6.ssh') + def test_ping_successful_setup(self, mock_ssh): + args = { + 'options': {'host': 'host1', 'packetsize': 200, 'ping_count': 5}, + 'sla': {'max_rtt': 50} + } + p = ping6.Ping6(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '0', '') + p.setup() + + self.assertTrue(p.setup_done) + + @mock.patch('yardstick.benchmark.scenarios.networking.ping6.ssh') + def test_ping_successful_no_sla(self, mock_ssh): + args = { + 'options': {'host': 'host1', 'packetsize': 200, 'ping_count': 5}, + + } + result = {} + + p = ping6.Ping6(args, self.ctx) + p.client = mock_ssh.SSH.from_node() + mock_ssh.SSH.from_node().execute.side_effect = [(0, 'host1', ''), (0, 100, '')] + p.run(result) + self.assertEqual(result, {'rtt': 100.0}) + + @mock.patch('yardstick.benchmark.scenarios.networking.ping6.ssh') + def test_ping_successful_sla(self, mock_ssh): + args = { + 'options': {'host': 'host1', 'packetsize': 200, 'ping_count': 5}, + 'sla': {'max_rtt': 150} + } + result = {} + + p = ping6.Ping6(args, self.ctx) + p.client = mock_ssh.SSH.from_node() + mock_ssh.SSH.from_node().execute.side_effect = [(0, 'host1', ''), (0, 100, '')] + p.run(result) + self.assertEqual(result, {'rtt': 100.0}) + + @mock.patch('yardstick.benchmark.scenarios.networking.ping6.ssh') + def test_ping_unsuccessful_sla(self, mock_ssh): + args = { + 'options': {'host': 'host1', 'packetsize': 200, 'ping_count': 5}, + 'sla': {'max_rtt': 50} + } + result = {} + + p = ping6.Ping6(args, self.ctx) + p.client = mock_ssh.SSH.from_node() + mock_ssh.SSH.from_node().execute.side_effect = [(0, 'host1', ''), (0, 100, '')] + self.assertRaises(AssertionError, p.run, result) + + @mock.patch('yardstick.benchmark.scenarios.networking.ping6.ssh') + def test_ping_unsuccessful_script_error(self, mock_ssh): + + args = { + 'options': {'host': 'host1', 'packetsize': 200, 'ping_count': 5}, + 'sla': {'max_rtt': 150} + } + result = {} + + p = ping6.Ping6(args, self.ctx) + p.client = mock_ssh.SSH.from_node() + mock_ssh.SSH.from_node().execute.side_effect = [ + (0, 'host1', ''), (1, '', 'FOOBAR')] + self.assertRaises(RuntimeError, p.run, result) + + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen.py new file mode 100644 index 000000000..acd9027d3 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen.py @@ -0,0 +1,675 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +import mock +import unittest + +from oslo_serialization import jsonutils + +from yardstick.benchmark.scenarios.networking import pktgen + + +@mock.patch('yardstick.benchmark.scenarios.networking.pktgen.ssh') +class PktgenTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'root', + 'key_filename': 'mykey.key' + }, + 'target': { + 'ip': '172.16.0.138', + 'user': 'root', + 'key_filename': 'mykey.key', + 'ipaddr': '172.16.0.138' + } + } + + def test_pktgen_successful_setup(self, mock_ssh): + + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.setup() + + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.assertIsNotNone(p.server) + self.assertIsNotNone(p.client) + self.assertTrue(p.setup_done) + + def test_pktgen_successful_iptables_setup(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.number_of_ports = args['options']['number_of_ports'] + + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + p._iptables_setup() + + mock_ssh.SSH.from_node().execute.assert_called_with( + "sudo iptables -F; " + "sudo iptables -A INPUT -p udp --dport 1000:%s -j DROP" + % 1010, timeout=60) + + def test_pktgen_unsuccessful_iptables_setup(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + } + + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.number_of_ports = args['options']['number_of_ports'] + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p._iptables_setup) + + def test_pktgen_successful_iptables_get_result(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + } + + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.number_of_ports = args['options']['number_of_ports'] + + mock_ssh.SSH.from_node().execute.return_value = (0, '150000', '') + p._iptables_get_result() + + mock_ssh.SSH.from_node().execute.assert_called_with( + "sudo iptables -L INPUT -vnx |" + "awk '/dpts:1000:%s/ {{printf \"%%s\", $1}}'" + % 1010) + + def test_pktgen_unsuccessful_iptables_get_result(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + } + + p = pktgen.Pktgen(args, self.ctx) + + p.server = mock_ssh.SSH.from_node() + p.number_of_ports = args['options']['number_of_ports'] + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p._iptables_get_result) + + def test_pktgen_successful_no_sla(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + } + result = {} + + p = pktgen.Pktgen(args, self.ctx) + + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + p._iptables_get_result = mock.Mock(return_value=149300) + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149776, "packetsize": 60, "flows": 110, "ppm": 3179}' + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + p.run(result) + expected_result = jsonutils.loads(sample_output) + expected_result["packets_received"] = 149300 + expected_result["packetsize"] = 60 + self.assertEqual(result, expected_result) + + def test_pktgen_successful_sla(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + 'sla': {'max_ppm': 10000} + } + result = {} + + p = pktgen.Pktgen(args, self.ctx) + + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + p._iptables_get_result = mock.Mock(return_value=149300) + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149776, "packetsize": 60, "flows": 110, "ppm": 3179}' + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + p.run(result) + expected_result = jsonutils.loads(sample_output) + expected_result["packets_received"] = 149300 + expected_result["packetsize"] = 60 + self.assertEqual(result, expected_result) + + def test_pktgen_unsuccessful_sla(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + 'sla': {'max_ppm': 1000} + } + result = {} + + p = pktgen.Pktgen(args, self.ctx) + + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + p._iptables_get_result = mock.Mock(return_value=149300) + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149776, "packetsize": 60, "flows": 110}' + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + self.assertRaises(AssertionError, p.run, result) + + def test_pktgen_unsuccessful_script_error(self, mock_ssh): + + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + 'sla': {'max_ppm': 1000} + } + result = {} + + p = pktgen.Pktgen(args, self.ctx) + + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.run, result) + + def test_pktgen_get_vnic_driver_name(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, 'ixgbevf', '') + + vnic_driver_name = p._get_vnic_driver_name() + self.assertEqual(vnic_driver_name, 'ixgbevf') + + def test_pktgen_unsuccessful_get_vnic_driver_name(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._get_vnic_driver_name) + + def test_pktgen_get_sriov_queue_number(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '2', '') + + p.queue_number = p._get_sriov_queue_number() + self.assertEqual(p.queue_number, 2) + + def test_pktgen_unsuccessful_get_sriov_queue_number(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._get_sriov_queue_number) + + def test_pktgen_get_available_queue_number(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '4', '') + + p._get_available_queue_number() + + mock_ssh.SSH.from_node().execute.assert_called_with( + "sudo ethtool -l eth0 | grep Combined | head -1 |" + "awk '{printf $2}'") + + def test_pktgen_unsuccessful_get_available_queue_number(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._get_available_queue_number) + + def test_pktgen_get_usable_queue_number(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '1', '') + + p._get_usable_queue_number() + + mock_ssh.SSH.from_node().execute.assert_called_with( + "sudo ethtool -l eth0 | grep Combined | tail -1 |" + "awk '{printf $2}'") + + def test_pktgen_unsuccessful_get_usable_queue_number(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._get_usable_queue_number) + + def test_pktgen_enable_ovs_multiqueue(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '4', '') + + p._get_usable_queue_number = mock.Mock(return_value=1) + p._get_available_queue_number = mock.Mock(return_value=4) + + p.queue_number = p._enable_ovs_multiqueue() + self.assertEqual(p.queue_number, 4) + + def test_pktgen_enable_ovs_multiqueue_1q(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '1', '') + + p._get_usable_queue_number = mock.Mock(return_value=1) + p._get_available_queue_number = mock.Mock(return_value=1) + + p.queue_number = p._enable_ovs_multiqueue() + self.assertEqual(p.queue_number, 1) + + def test_pktgen_unsuccessful_enable_ovs_multiqueue(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + p._get_usable_queue_number = mock.Mock(return_value=1) + p._get_available_queue_number = mock.Mock(return_value=4) + + self.assertRaises(RuntimeError, p._enable_ovs_multiqueue) + + def test_pktgen_setup_irqmapping_ovs(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '10', '') + + p._setup_irqmapping_ovs(4) + + mock_ssh.SSH.from_node().execute.assert_called_with( + "echo 8 | sudo tee /proc/irq/10/smp_affinity") + + def test_pktgen_setup_irqmapping_ovs_1q(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '10', '') + + p._setup_irqmapping_ovs(1) + + mock_ssh.SSH.from_node().execute.assert_called_with( + "echo 1 | sudo tee /proc/irq/10/smp_affinity") + + def test_pktgen_unsuccessful_setup_irqmapping_ovs(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._setup_irqmapping_ovs, 4) + + def test_pktgen_unsuccessful_setup_irqmapping_ovs_1q(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._setup_irqmapping_ovs, 1) + + def test_pktgen_setup_irqmapping_sriov(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '10', '') + + p._setup_irqmapping_sriov(2) + + mock_ssh.SSH.from_node().execute.assert_called_with( + "echo 2 | sudo tee /proc/irq/10/smp_affinity") + + def test_pktgen_setup_irqmapping_sriov_1q(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '10', '') + + p._setup_irqmapping_sriov(1) + + mock_ssh.SSH.from_node().execute.assert_called_with( + "echo 1 | sudo tee /proc/irq/10/smp_affinity") + + def test_pktgen_unsuccessful_setup_irqmapping_sriov(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._setup_irqmapping_sriov, 2) + + def test_pktgen_unsuccessful_setup_irqmapping_sriov_1q(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._setup_irqmapping_sriov, 1) + + def test_pktgen_is_irqbalance_disabled(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + p._is_irqbalance_disabled() + + mock_ssh.SSH.from_node().execute.assert_called_with( + "grep ENABLED /etc/default/irqbalance") + + def test_pktgen_unsuccessful_is_irqbalance_disabled(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._is_irqbalance_disabled) + + def test_pktgen_disable_irqbalance(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + p._disable_irqbalance() + + mock_ssh.SSH.from_node().execute.assert_called_with( + "sudo service irqbalance disable") + + def test_pktgen_unsuccessful_disable_irqbalance(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + self.assertRaises(RuntimeError, p._disable_irqbalance) + + def test_pktgen_multiqueue_setup_ovs(self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'multiqueue': True}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '4', '') + + p._is_irqbalance_disabled = mock.Mock(return_value=False) + p._get_vnic_driver_name = mock.Mock(return_value="virtio_net") + p._get_usable_queue_number = mock.Mock(return_value=1) + p._get_available_queue_number = mock.Mock(return_value=4) + + p.multiqueue_setup() + + self.assertEqual(p.queue_number, 4) + + def test_pktgen_multiqueue_setup_ovs_1q(self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'multiqueue': True}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '1', '') + + p._is_irqbalance_disabled = mock.Mock(return_value=False) + p._get_vnic_driver_name = mock.Mock(return_value="virtio_net") + p._get_usable_queue_number = mock.Mock(return_value=1) + p._get_available_queue_number = mock.Mock(return_value=1) + + p.multiqueue_setup() + + self.assertEqual(p.queue_number, 1) + + def test_pktgen_multiqueue_setup_sriov(self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'multiqueue': True}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '2', '') + + p._is_irqbalance_disabled = mock.Mock(return_value=False) + p._get_vnic_driver_name = mock.Mock(return_value="ixgbevf") + + p.multiqueue_setup() + + self.assertEqual(p.queue_number, 2) + + def test_pktgen_multiqueue_setup_sriov_1q(self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'multiqueue': True}, + } + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + mock_ssh.SSH.from_node().execute.return_value = (0, '1', '') + + p._is_irqbalance_disabled = mock.Mock(return_value=False) + p._get_vnic_driver_name = mock.Mock(return_value="ixgbevf") + + p.multiqueue_setup() + + self.assertEqual(p.queue_number, 1) + + def test_pktgen_run_with_setup_done(self, mock_ssh): + args = { + 'options': { + 'packetsize': 60, + 'number_of_ports': 10, + 'duration': 20, + 'multiqueue': True}, + 'sla': { + 'max_ppm': 1}} + result = {} + p = pktgen.Pktgen(args, self.ctx) + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + p.setup_done = True + p.multiqueue_setup_done = True + + mock_iptables_result = mock.Mock() + mock_iptables_result.return_value = 149300 + p._iptables_get_result = mock_iptables_result + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149300, "flows": 110, "ppm": 0}' + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + p.run(result) + expected_result = jsonutils.loads(sample_output) + expected_result["packets_received"] = 149300 + expected_result["packetsize"] = 60 + self.assertEqual(result, expected_result) + + def test_pktgen_run_with_ovs_multiqueque(self, mock_ssh): + args = { + 'options': { + 'packetsize': 60, + 'number_of_ports': 10, + 'duration': 20, + 'multiqueue': True}, + 'sla': { + 'max_ppm': 1}} + result = {} + + p = pktgen.Pktgen(args, self.ctx) + + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + p._get_vnic_driver_name = mock.Mock(return_value="virtio_net") + p._get_usable_queue_number = mock.Mock(return_value=1) + p._get_available_queue_number = mock.Mock(return_value=4) + p._enable_ovs_multiqueue = mock.Mock(return_value=4) + p._setup_irqmapping_ovs = mock.Mock() + p._iptables_get_result = mock.Mock(return_value=149300) + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149300, "flows": 110, "ppm": 0}' + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + p.run(result) + expected_result = jsonutils.loads(sample_output) + expected_result["packets_received"] = 149300 + expected_result["packetsize"] = 60 + self.assertEqual(result, expected_result) + + def test_pktgen_run_with_sriov_multiqueque(self, mock_ssh): + args = { + 'options': { + 'packetsize': 60, + 'number_of_ports': 10, + 'duration': 20, + 'multiqueue': True}, + 'sla': { + 'max_ppm': 1}} + result = {} + + p = pktgen.Pktgen(args, self.ctx) + + p.server = mock_ssh.SSH.from_node() + p.client = mock_ssh.SSH.from_node() + + p._get_vnic_driver_name = mock.Mock(return_value="ixgbevf") + p._get_sriov_queue_number = mock.Mock(return_value=2) + p._setup_irqmapping_sriov = mock.Mock() + p._iptables_get_result = mock.Mock(return_value=149300) + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149300, "flows": 110, "ppm": 0}' + mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + p.run(result) + expected_result = jsonutils.loads(sample_output) + expected_result["packets_received"] = 149300 + expected_result["packetsize"] = 60 + self.assertEqual(result, expected_result) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py new file mode 100644 index 000000000..99399abdc --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py @@ -0,0 +1,186 @@ +############################################################################## +# Copyright (c) 2015 ZTE and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +import mock +import unittest + +import yardstick.common.utils as utils +from yardstick.benchmark.scenarios.networking import pktgen_dpdk + + +class PktgenDPDKLatencyTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'root', + 'key_filename': 'mykey.key' + }, + 'target': { + 'ip': '172.16.0.138', + 'user': 'root', + 'key_filename': 'mykey.key', + 'ipaddr': '172.16.0.138' + } + } + + self._mock_ssh = mock.patch( + 'yardstick.benchmark.scenarios.networking.pktgen_dpdk.ssh') + self.mock_ssh = self._mock_ssh.start() + self._mock_time = mock.patch( + 'yardstick.benchmark.scenarios.networking.pktgen_dpdk.time') + self.mock_time = self._mock_time.start() + + self.addCleanup(self._stop_mock) + + def _stop_mock(self): + self._mock_ssh.stop() + self._mock_time.stop() + + def test_pktgen_dpdk_successful_setup(self): + + args = { + 'options': {'packetsize': 60}, + } + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + p.setup() + + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.assertIsNotNone(p.server) + self.assertIsNotNone(p.client) + self.assertTrue(p.setup_done) + + def test_pktgen_dpdk_successful_get_port_ip(self): + + args = { + 'options': {'packetsize': 60}, + } + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + p.server = self.mock_ssh.SSH.from_node() + + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + utils.get_port_ip(p.server, "eth1") + + self.mock_ssh.SSH.from_node().execute.assert_called_with( + "ifconfig eth1 |grep 'inet addr' |awk '{print $2}' |cut -d ':' -f2 ") + + def test_pktgen_dpdk_unsuccessful_get_port_ip(self): + + args = { + 'options': {'packetsize': 60}, + } + + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + p.server = self.mock_ssh.SSH.from_node() + + self.mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, utils.get_port_ip, p.server, "eth1") + + def test_pktgen_dpdk_successful_get_port_mac(self): + + args = { + 'options': {'packetsize': 60}, + } + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + p.server = self.mock_ssh.SSH.from_node() + + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + utils.get_port_mac(p.server, "eth1") + + self.mock_ssh.SSH.from_node().execute.assert_called_with( + "ifconfig |grep HWaddr |grep eth1 |awk '{print $5}' ") + + def test_pktgen_dpdk_unsuccessful_get_port_mac(self): + + args = { + 'options': {'packetsize': 60}, + } + + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + p.server = self.mock_ssh.SSH.from_node() + + self.mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, utils.get_port_mac, p.server, "eth1") + + def test_pktgen_dpdk_successful_no_sla(self): + + args = { + 'options': {'packetsize': 60}, + } + + result = {} + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + + sample_output = '100\n110\n112\n130\n149\n150\n90\n150\n200\n162\n' + self.mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + p.run(result) + # with python 3 we get float, might be due python division changes + # AssertionError: {'avg_latency': 132.33333333333334} != { + # 'avg_latency': 132} + delta = result['avg_latency'] - 132 + self.assertLessEqual(delta, 1) + + def test_pktgen_dpdk_successful_sla(self): + + args = { + 'options': {'packetsize': 60}, + 'sla': {'max_latency': 100} + } + result = {} + + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + + sample_output = '100\n100\n100\n100\n100\n100\n100\n100\n100\n100\n' + self.mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + + p.run(result) + + self.assertEqual(result, {"avg_latency": 100}) + + def test_pktgen_dpdk_unsuccessful_sla(self): + + args = { + 'options': {'packetsize': 60}, + 'sla': {'max_latency': 100} + } + result = {} + + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + + p.server = self.mock_ssh.SSH.from_node() + p.client = self.mock_ssh.SSH.from_node() + + sample_output = '100\n110\n112\n130\n149\n150\n90\n150\n200\n162\n' + self.mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') + self.assertRaises(AssertionError, p.run, result) + + def test_pktgen_dpdk_unsuccessful_script_error(self): + + args = { + 'options': {'packetsize': 60}, + 'sla': {'max_latency': 100} + } + result = {} + + p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx) + + self.mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.run, result) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk_throughput.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk_throughput.py new file mode 100644 index 000000000..1b12bd507 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk_throughput.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python +############################################################################## +# Copyright (c) 2017 Nokia and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for yardstick.benchmark.scenarios.networking.pktgen.PktgenDPDK + +from __future__ import absolute_import +import unittest + +from oslo_serialization import jsonutils +import mock + +from yardstick.benchmark.scenarios.networking import pktgen_dpdk_throughput + + +# pylint: disable=unused-argument +# disable this for now because I keep forgetting mock patch arg ordering + + +@mock.patch('yardstick.benchmark.scenarios.networking.pktgen_dpdk_throughput.ssh') +class PktgenDPDKTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'root', + 'key_filename': 'mykey.key' + }, + 'target': { + 'ip': '172.16.0.138', + 'user': 'root', + 'key_filename': 'mykey.key', + } + } + + self._mock_time = mock.patch( + 'yardstick.benchmark.scenarios.networking.pktgen_dpdk_throughput.time') + self.mock_time = self._mock_time.start() + + self.addCleanup(self._cleanup) + + def _cleanup(self): + self._mock_time.stop() + + def test_pktgen_dpdk_throughput_successful_setup(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + p.setup() + + mock_ssh.SSH().execute.return_value = (0, '', '') + self.assertIsNotNone(p.server) + self.assertIsNotNone(p.client) + self.assertTrue(p.setup_done) + + def test_pktgen_dpdk_throughput_successful_no_sla(self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + } + + result = {} + + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + + p.server = mock_ssh.SSH() + p.client = mock_ssh.SSH() + + mock_dpdk_result = mock.Mock() + mock_dpdk_result.return_value = 149300 + p._dpdk_get_result = mock_dpdk_result + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149776, "flows": 110}' + mock_ssh.SSH().execute.return_value = (0, sample_output, '') + + p.run(result) + expected_result = jsonutils.loads(sample_output) + expected_result["packets_received"] = 149300 + expected_result["packetsize"] = 60 + self.assertEqual(result, expected_result) + + def test_pktgen_dpdk_throughput_successful_sla(self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + 'sla': {'max_ppm': 10000} + } + result = {} + + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + + p.server = mock_ssh.SSH() + p.client = mock_ssh.SSH() + + mock_dpdk_result = mock.Mock() + mock_dpdk_result.return_value = 149300 + p._dpdk_get_result = mock_dpdk_result + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149776, "flows": 110}' + mock_ssh.SSH().execute.return_value = (0, sample_output, '') + + p.run(result) + expected_result = jsonutils.loads(sample_output) + expected_result["packets_received"] = 149300 + expected_result["packetsize"] = 60 + self.assertEqual(result, expected_result) + + def test_pktgen_dpdk_throughput_unsuccessful_sla(self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + 'sla': {'max_ppm': 1000} + } + result = {} + + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + + p.server = mock_ssh.SSH() + p.client = mock_ssh.SSH() + + mock_dpdk_result = mock.Mock() + mock_dpdk_result.return_value = 149300 + p._dpdk_get_result = mock_dpdk_result + + sample_output = '{"packets_per_second": 9753, "errors": 0, \ + "packets_sent": 149776, "flows": 110}' + mock_ssh.SSH().execute.return_value = (0, sample_output, '') + self.assertRaises(AssertionError, p.run, result) + + def test_pktgen_dpdk_throughput_unsuccessful_script_error( + self, mock_ssh): + args = { + 'options': {'packetsize': 60, 'number_of_ports': 10}, + 'sla': {'max_ppm': 1000} + } + result = {} + + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + + p.server = mock_ssh.SSH() + p.client = mock_ssh.SSH() + + mock_ssh.SSH().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, p.run, result) + + def test_pktgen_dpdk_throughput_is_dpdk_setup(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + p.server = mock_ssh.SSH() + + mock_ssh.SSH().execute.return_value = (0, '', '') + + p._is_dpdk_setup("server") + + mock_ssh.SSH().execute.assert_called_with( + "ip a | grep eth1 2>/dev/null") + + def test_pktgen_dpdk_throughput_dpdk_setup(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + p.server = mock_ssh.SSH() + p.client = mock_ssh.SSH() + + mock_ssh.SSH().execute.return_value = (0, '', '') + + p.dpdk_setup() + + self.assertTrue(p.dpdk_setup_done) + + def test_pktgen_dpdk_throughput_dpdk_get_result(self, mock_ssh): + args = { + 'options': {'packetsize': 60}, + } + p = pktgen_dpdk_throughput.PktgenDPDK(args, self.ctx) + p.server = mock_ssh.SSH() + p.client = mock_ssh.SSH() + + mock_ssh.SSH().execute.return_value = (0, '10000', '') + + p._dpdk_get_result() + + mock_ssh.SSH().execute.assert_called_with( + "sudo /dpdk/destdir/bin/dpdk-procinfo -- --stats-reset > /dev/null 2>&1") + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_sfc.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_sfc.py new file mode 100644 index 000000000..78c0352dd --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_sfc.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Unittest for yardstick.benchmark.scenarios.networking.sfc + +from __future__ import absolute_import +import mock +import unittest + +from yardstick.benchmark.scenarios.networking import sfc + + +class SfcTestCase(unittest.TestCase): + + def setUp(self): + scenario_cfg = {} + context_cfg = { + # Used in Sfc.setup() + 'target': { + 'user': 'root', + 'password': 'opnfv', + 'ip': '127.0.0.1', + }, + + # Used in Sfc.run() + 'host': { + 'user': 'root', + 'password': 'opnfv', + 'ip': None, + } + } + + self.sfc = sfc.Sfc(scenario_cfg=scenario_cfg, context_cfg=context_cfg) + + @mock.patch('yardstick.benchmark.scenarios.networking.sfc.ssh') + @mock.patch('yardstick.benchmark.scenarios.networking.sfc.sfc_openstack') + @mock.patch('yardstick.benchmark.scenarios.networking.sfc.subprocess') + def test_run_for_success(self, mock_subprocess, mock_openstack, mock_ssh): + # Mock a successfull SSH in Sfc.setup() and Sfc.run() + mock_ssh.SSH.from_node().execute.return_value = (0, '100', '') + mock_openstack.get_an_IP.return_value = "127.0.0.1" + mock_subprocess.call.return_value = 'mocked!' + + result = {} + self.sfc.setup() + self.sfc.run(result) + self.sfc.teardown() + + @mock.patch('yardstick.benchmark.scenarios.networking.sfc.ssh') + @mock.patch('yardstick.benchmark.scenarios.networking.sfc.sfc_openstack') + @mock.patch('yardstick.benchmark.scenarios.networking.sfc.subprocess') + def test2_run_for_success(self, mock_subprocess, mock_openstack, mock_ssh): + # Mock a successfull SSH in Sfc.setup() and Sfc.run() + mock_ssh.SSH.from_node().execute.return_value = ( + 0, 'vxlan_tool.py', 'succeeded timed out') + mock_openstack.get_an_IP.return_value = "127.0.0.1" + mock_subprocess.call.return_value = 'mocked!' + + result = {} + self.sfc.setup() + self.sfc.run(result) + self.sfc.teardown() + + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py new file mode 100644 index 000000000..fb55b5ea0 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py @@ -0,0 +1,798 @@ +#!/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. +# + +# Unittest for yardstick.benchmark.scenarios.networking.test_vnf_generic + +from __future__ import absolute_import + +import os +import errno +import unittest +import mock + +from copy import deepcopy + +from yardstick.tests.unit import STL_MOCKS +from yardstick.benchmark.scenarios.networking.vnf_generic import \ + SshManager, NetworkServiceTestCase, IncorrectConfig, \ + open_relative_file +from yardstick.network_services.collector.subscriber import Collector +from yardstick.network_services.vnf_generic.vnf.base import \ + GenericTrafficGen, GenericVNF + + +# pylint: disable=unused-argument +# disable this for now because I keep forgetting mock patch arg ordering + + +COMPLETE_TREX_VNFD = { + 'vnfd:vnfd-catalog': { + 'vnfd': [ + { + 'benchmark': { + 'kpi': [ + 'rx_throughput_fps', + 'tx_throughput_fps', + 'tx_throughput_mbps', + 'rx_throughput_mbps', + 'tx_throughput_pc_linerate', + 'rx_throughput_pc_linerate', + 'min_latency', + 'max_latency', + 'avg_latency', + ], + }, + 'connection-point': [ + { + 'name': 'xe0', + 'type': 'VPORT', + }, + { + 'name': 'xe1', + 'type': 'VPORT', + }, + ], + 'description': 'TRex stateless traffic generator for RFC2544', + 'id': 'TrexTrafficGen', + 'mgmt-interface': { + 'ip': '1.1.1.1', + 'password': 'berta', + 'user': 'berta', + 'vdu-id': 'trexgen-baremetal', + }, + 'name': 'trexgen', + 'short-name': 'trexgen', + 'class-name': 'TrexTrafficGen', + 'vdu': [ + { + 'description': 'TRex stateless traffic generator for RFC2544', + 'external-interface': [ + { + 'name': 'xe0', + 'virtual-interface': { + 'bandwidth': '10 Gbps', + 'dst_ip': '1.1.1.1', + 'dst_mac': '00:01:02:03:04:05', + 'local_ip': '1.1.1.2', + 'local_mac': '00:01:02:03:05:05', + 'type': 'PCI-PASSTHROUGH', + 'netmask': "255.255.255.0", + 'driver': 'i40', + 'vpci': '0000:00:10.2', + }, + 'vnfd-connection-point-ref': 'xe0', + }, + { + 'name': 'xe1', + 'virtual-interface': { + 'bandwidth': '10 Gbps', + 'dst_ip': '2.1.1.1', + 'dst_mac': '00:01:02:03:04:06', + 'local_ip': '2.1.1.2', + 'local_mac': '00:01:02:03:05:06', + 'type': 'PCI-PASSTHROUGH', + 'netmask': "255.255.255.0", + 'driver': 'i40', + 'vpci': '0000:00:10.1', + }, + 'vnfd-connection-point-ref': 'xe1', + }, + ], + 'id': 'trexgen-baremetal', + 'name': 'trexgen-baremetal', + }, + ], + }, + ], + }, +} + +IP_ADDR_SHOW = """ +28: eth1: mtu 1500 qdisc mq state UP \ +group default qlen 1000 + link/ether 90:e2:ba:a7:6a:c8 brd ff:ff:ff:ff:ff:ff + inet 1.1.1.1/8 brd 1.255.255.255 scope global eth1 + inet6 fe80::92e2:baff:fea7:6ac8/64 scope link + valid_lft forever preferred_lft forever +29: eth5: mtu 1500 qdisc mq state UP \ +group default qlen 1000 + link/ether 90:e2:ba:a7:6a:c9 brd ff:ff:ff:ff:ff:ff + inet 2.1.1.1/8 brd 2.255.255.255 scope global eth5 + inet6 fe80::92e2:baff:fea7:6ac9/64 scope link tentative + valid_lft forever preferred_lft forever +""" + +SYS_CLASS_NET = """ +lrwxrwxrwx 1 root root 0 sie 10 14:16 eth1 -> \ +../../devices/pci0000:80/0000:80:02.2/0000:84:00.1/net/eth1 +lrwxrwxrwx 1 root root 0 sie 3 10:37 eth2 -> \ +../../devices/pci0000:00/0000:00:01.1/0000:84:00.2/net/eth5 +""" + +TRAFFIC_PROFILE = { + "schema": "isb:traffic_profile:0.1", + "name": "fixed", + "description": "Fixed traffic profile to run UDP traffic", + "traffic_profile": { + "traffic_type": "FixedTraffic", + "frame_rate": 100, # pps + "flow_number": 10, + "frame_size": 64, + }, +} + + +class TestNetworkServiceTestCase(unittest.TestCase): + + def setUp(self): + self.tg__1 = { + 'name': 'trafficgen_1.yardstick', + 'ip': '10.10.10.11', + 'role': 'TrafficGen', + 'user': 'root', + 'password': 'r00t', + 'interfaces': { + 'xe0': { + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.20', + 'local_mac': '00:00:00:00:00:01', + 'driver': 'i40e', + 'vpci': '0000:07:00.0', + 'dpdk_port_num': 0, + }, + 'xe1': { + 'netmask': '255.255.255.0', + 'local_ip': '152.16.40.20', + 'local_mac': '00:00:00:00:00:02', + 'driver': 'i40e', + 'vpci': '0000:07:00.1', + 'dpdk_port_num': 1, + }, + }, + } + + self.vnf__1 = { + 'name': 'vnf.yardstick', + 'ip': '10.10.10.12', + 'host': '10.223.197.164', + 'role': 'vnf', + 'user': 'root', + 'password': 'r00t', + 'interfaces': { + 'xe0': { + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.19', + 'local_mac': '00:00:00:00:00:03', + 'driver': 'i40e', + 'vpci': '0000:07:00.0', + 'dpdk_port_num': 0, + }, + 'xe1': { + 'netmask': '255.255.255.0', + 'local_ip': '152.16.40.19', + 'local_mac': '00:00:00:00:00:04', + 'driver': 'i40e', + 'vpci': '0000:07:00.1', + 'dpdk_port_num': 1, + }, + }, + 'routing_table': [ + { + 'netmask': '255.255.255.0', + 'gateway': '152.16.100.20', + 'network': '152.16.100.20', + 'if': 'xe0', + }, + { + 'netmask': '255.255.255.0', + 'gateway': '152.16.40.20', + 'network': '152.16.40.20', + 'if': 'xe1', + }, + ], + 'nd_route_tbl': [ + { + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:6414', + 'network': '0064:ff9b:0:0:0:0:9810:6414', + 'if': 'xe0', + }, + { + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:2814', + 'network': '0064:ff9b:0:0:0:0:9810:2814', + 'if': 'xe1', + }, + ], + } + + self.context_cfg = { + 'nodes': { + 'tg__1': self.tg__1, + 'vnf__1': self.vnf__1, + }, + 'networks': { + GenericVNF.UPLINK: { + 'vld_id': GenericVNF.UPLINK, + }, + GenericVNF.DOWNLINK: { + 'vld_id': GenericVNF.DOWNLINK, + }, + }, + } + + self.vld0 = { + 'vnfd-connection-point-ref': [ + { + 'vnfd-connection-point-ref': 'xe0', + 'member-vnf-index-ref': '1', + 'vnfd-id-ref': 'trexgen' + }, + { + 'vnfd-connection-point-ref': 'xe0', + 'member-vnf-index-ref': '2', + 'vnfd-id-ref': 'trexgen' + } + ], + 'type': 'ELAN', + 'id': GenericVNF.UPLINK, + 'name': 'tg__1 to vnf__1 link 1' + } + + self.vld1 = { + 'vnfd-connection-point-ref': [ + { + 'vnfd-connection-point-ref': 'xe1', + 'member-vnf-index-ref': '1', + 'vnfd-id-ref': 'trexgen' + }, + { + 'vnfd-connection-point-ref': 'xe1', + 'member-vnf-index-ref': '2', + 'vnfd-id-ref': 'trexgen' + } + ], + 'type': 'ELAN', + 'id': GenericVNF.DOWNLINK, + 'name': 'vnf__1 to tg__1 link 2' + } + + self.topology = { + 'id': 'trex-tg-topology', + 'short-name': 'trex-tg-topology', + 'name': 'trex-tg-topology', + 'description': 'trex-tg-topology', + 'constituent-vnfd': [ + { + 'member-vnf-index': '1', + 'VNF model': 'tg_trex_tpl.yaml', + 'vnfd-id-ref': 'tg__1', + }, + { + 'member-vnf-index': '2', + 'VNF model': 'tg_trex_tpl.yaml', + 'vnfd-id-ref': 'vnf__1', + }, + ], + 'vld': [self.vld0, self.vld1], + } + + self.scenario_cfg = { + 'task_path': "", + "topology": self._get_file_abspath("vpe_vnf_topology.yaml"), + 'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7', + 'tc': 'tc_ipv4_1Mflow_64B_packetsize', + 'traffic_profile': 'ipv4_throughput_vpe.yaml', + 'type': 'ISB', + 'tc_options': { + 'rfc2544': { + 'allowed_drop_rate': '0.8 - 1', + }, + }, + 'options': { + 'framesize': {'64B': 100} + }, + 'runner': { + 'object': 'NetworkServiceTestCase', + 'interval': 35, + 'output_filename': 'yardstick.out', + 'runner_id': 74476, + 'duration': 400, + 'type': 'Duration', + }, + 'traffic_options': { + 'flow': 'ipv4_1flow_Packets_vpe.yaml', + 'imix': 'imix_voice.yaml' + }, + 'nodes': { + 'tg__2': 'trafficgen_2.yardstick', + 'tg__1': 'trafficgen_1.yardstick', + 'vnf__1': 'vnf.yardstick', + }, + } + + self.s = NetworkServiceTestCase(self.scenario_cfg, self.context_cfg) + + def _get_file_abspath(self, filename): + curr_path = os.path.dirname(os.path.abspath(__file__)) + file_path = os.path.join(curr_path, filename) + return file_path + + def test_ssh_manager(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, "")) + ssh.from_node.return_value = ssh_mock + for _, node_dict in self.context_cfg["nodes"].items(): + with SshManager(node_dict) as conn: + self.assertIsNotNone(conn) + + def test___init__(self): + assert self.topology + + def test__get_ip_flow_range_string(self): + self.scenario_cfg["traffic_options"]["flow"] = \ + self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") + result = '152.16.100.2-152.16.100.254' + self.assertEqual(result, self.s._get_ip_flow_range( + '152.16.100.2-152.16.100.254')) + + def test__get_ip_flow_range(self): + self.scenario_cfg["traffic_options"]["flow"] = \ + self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") + 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") + self.scenario_cfg["options"] = {} + self.scenario_cfg['options'] = { + 'flow': { + 'src_ip': [ + { + 'tg__1': 'xe0', + }, + ], + 'dst_ip': [ + { + 'tg__1': 'xe1', + }, + ], + 'public_ip': ['1.1.1.1'], + }, + } + + self.assertEqual({'flow': {}}, self.s._get_traffic_flow()) + + def test___get_traffic_flow_error(self): + self.scenario_cfg["traffic_options"]["flow"] = \ + "ipv4_1flow_Packets_vpe.yaml1" + self.assertEqual({'flow': {}}, self.s._get_traffic_flow()) + + def test_get_vnf_imp(self): + vnfd = COMPLETE_TREX_VNFD['vnfd:vnfd-catalog']['vnfd'][0]['class-name'] + with mock.patch.dict("sys.modules", STL_MOCKS): + self.assertIsNotNone(self.s.get_vnf_impl(vnfd)) + + with self.assertRaises(IncorrectConfig) as raised: + self.s.get_vnf_impl('NonExistentClass') + + exc_str = str(raised.exception) + print(exc_str) + self.assertIn('No implementation', exc_str) + self.assertIn('found in', exc_str) + + def test_load_vnf_models_invalid(self): + self.context_cfg["nodes"]['tg__1']['VNF model'] = \ + self._get_file_abspath("tg_trex_tpl.yaml") + self.context_cfg["nodes"]['vnf__1']['VNF model'] = \ + self._get_file_abspath("tg_trex_tpl.yaml") + + vnf = mock.Mock(autospec=GenericVNF) + self.s.get_vnf_impl = mock.Mock(return_value=vnf) + + self.assertIsNotNone( + self.s.load_vnf_models(self.scenario_cfg, self.context_cfg)) + + def test_load_vnf_models_no_model(self): + vnf = mock.Mock(autospec=GenericVNF) + self.s.get_vnf_impl = mock.Mock(return_value=vnf) + + self.assertIsNotNone( + self.s.load_vnf_models(self.scenario_cfg, self.context_cfg)) + + def test_map_topology_to_infrastructure(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, "")) + ssh.from_node.return_value = ssh_mock + self.s.map_topology_to_infrastructure() + + nodes = self.context_cfg["nodes"] + self.assertEqual( + "../../vnf_descriptors/tg_rfc2544_tpl.yaml", nodes['tg__1']['VNF model']) + self.assertEqual("../../vnf_descriptors/vpe_vnf.yaml", + nodes['vnf__1']['VNF model']) + + def test_map_topology_to_infrastructure_insufficient_nodes(self): + del self.context_cfg['nodes']['vnf__1'] + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(1, SYS_CLASS_NET + IP_ADDR_SHOW, "")) + ssh.from_node.return_value = ssh_mock + + with self.assertRaises(IncorrectConfig): + self.s.map_topology_to_infrastructure() + + def test_map_topology_to_infrastructure_config_invalid(self): + cfg = dict(self.context_cfg) + del cfg['nodes']['vnf__1']['interfaces']['xe0']['local_mac'] + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, "")) + ssh.from_node.return_value = ssh_mock + + with self.assertRaises(IncorrectConfig): + self.s.map_topology_to_infrastructure() + + def test__resolve_topology_invalid_config(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, "")) + ssh.from_node.return_value = ssh_mock + + # purge an important key from the data structure + for interface in self.tg__1['interfaces'].values(): + del interface['local_mac'] + + with mock.patch( + "yardstick.benchmark.scenarios.networking.vnf_generic.LOG"): + with self.assertRaises(IncorrectConfig) as raised: + self.s._resolve_topology() + + self.assertIn('not found', str(raised.exception)) + + # restore local_mac + for index, interface in enumerate(self.tg__1['interfaces'].values()): + interface['local_mac'] = '00:00:00:00:00:{:2x}'.format(index) + + # make a connection point ref with 3 points + self.s.topology["vld"][0]['vnfd-connection-point-ref'].append( + self.s.topology["vld"][0]['vnfd-connection-point-ref'][0]) + + with mock.patch( + "yardstick.benchmark.scenarios.networking.vnf_generic.LOG"): + with self.assertRaises(IncorrectConfig) as raised: + self.s._resolve_topology() + + self.assertIn('wrong endpoint count', str(raised.exception)) + + # make a connection point ref with 1 point + self.s.topology["vld"][0]['vnfd-connection-point-ref'] = \ + self.s.topology["vld"][0]['vnfd-connection-point-ref'][:1] + + with mock.patch( + "yardstick.benchmark.scenarios.networking.vnf_generic.LOG"): + with self.assertRaises(IncorrectConfig) as raised: + self.s._resolve_topology() + + self.assertIn('wrong endpoint count', str(raised.exception)) + + def test_run(self): + tgen = mock.Mock(autospec=GenericTrafficGen) + tgen.traffic_finished = True + verified_dict = {"verified": True} + tgen.verify_traffic = lambda x: verified_dict + tgen.name = "tgen__1" + vnf = mock.Mock(autospec=GenericVNF) + vnf.runs_traffic = False + self.s.vnfs = [tgen, vnf] + self.s.traffic_profile = mock.Mock() + self.s.collector = mock.Mock(autospec=Collector) + self.s.collector.get_kpi = \ + mock.Mock(return_value={tgen.name: verified_dict}) + result = {} + self.s.run(result) + self.assertDictEqual(result, {tgen.name: verified_dict}) + + def test_setup(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, "")) + ssh.from_node.return_value = ssh_mock + + tgen = mock.Mock(autospec=GenericTrafficGen) + tgen.traffic_finished = True + verified_dict = {"verified": True} + tgen.verify_traffic = lambda x: verified_dict + tgen.terminate = mock.Mock(return_value=True) + tgen.name = "tgen__1" + vnf = mock.Mock(autospec=GenericVNF) + vnf.runs_traffic = False + vnf.terminate = mock.Mock(return_value=True) + self.s.vnfs = [tgen, vnf] + self.s.traffic_profile = mock.Mock() + self.s.collector = mock.Mock(autospec=Collector) + self.s.collector.get_kpi = \ + mock.Mock(return_value={tgen.name: verified_dict}) + self.s.map_topology_to_infrastructure = mock.Mock(return_value=0) + self.s.load_vnf_models = mock.Mock(return_value=self.s.vnfs) + self.s._fill_traffic_profile = \ + mock.Mock(return_value=TRAFFIC_PROFILE) + self.assertEqual(None, self.s.setup()) + + def test_setup_exception(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, "")) + ssh.from_node.return_value = ssh_mock + + tgen = mock.Mock(autospec=GenericTrafficGen) + tgen.traffic_finished = True + verified_dict = {"verified": True} + tgen.verify_traffic = lambda x: verified_dict + tgen.terminate = mock.Mock(return_value=True) + tgen.name = "tgen__1" + vnf = mock.Mock(autospec=GenericVNF) + vnf.runs_traffic = False + vnf.instantiate.side_effect = RuntimeError( + "error during instantiate") + vnf.terminate = mock.Mock(return_value=True) + self.s.vnfs = [tgen, vnf] + self.s.traffic_profile = mock.Mock() + self.s.collector = mock.Mock(autospec=Collector) + self.s.collector.get_kpi = \ + mock.Mock(return_value={tgen.name: verified_dict}) + self.s.map_topology_to_infrastructure = mock.Mock(return_value=0) + self.s.load_vnf_models = mock.Mock(return_value=self.s.vnfs) + self.s._fill_traffic_profile = \ + mock.Mock(return_value=TRAFFIC_PROFILE) + with self.assertRaises(RuntimeError): + self.s.setup() + + def test__get_traffic_profile(self): + self.scenario_cfg["traffic_profile"] = \ + self._get_file_abspath("ipv4_throughput_vpe.yaml") + self.assertIsNotNone(self.s._get_traffic_profile()) + + def test__get_traffic_profile_exception(self): + with mock.patch.dict(self.scenario_cfg, {'traffic_profile': ''}): + with self.assertRaises(IOError): + self.s._get_traffic_profile() + + def test___get_traffic_imix_exception(self): + with mock.patch.dict(self.scenario_cfg["traffic_options"], {'imix': ''}): + self.assertEqual({'imix': {'64B': 100}}, + self.s._get_traffic_imix()) + + def test__fill_traffic_profile(self): + with mock.patch.dict("sys.modules", STL_MOCKS): + self.scenario_cfg["traffic_profile"] = \ + self._get_file_abspath("ipv4_throughput_vpe.yaml") + self.scenario_cfg["traffic_options"]["flow"] = \ + self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml") + self.scenario_cfg["traffic_options"]["imix"] = \ + self._get_file_abspath("imix_voice.yaml") + self.assertIsNotNone(self.s._fill_traffic_profile()) + + def test_teardown(self): + vnf = mock.Mock(autospec=GenericVNF) + vnf.terminate = mock.Mock(return_value=True) + vnf.name = str(vnf) + self.s.vnfs = [vnf] + self.s.traffic_profile = mock.Mock() + self.s.collector = mock.Mock(autospec=Collector) + self.s.collector.stop = \ + mock.Mock(return_value=True) + self.assertIsNone(self.s.teardown()) + + def test_teardown_exception(self): + vnf = mock.Mock(autospec=GenericVNF) + vnf.terminate = mock.Mock( + side_effect=RuntimeError("error duing terminate")) + vnf.name = str(vnf) + self.s.vnfs = [vnf] + self.s.traffic_profile = mock.Mock() + self.s.collector = mock.Mock(autospec=Collector) + self.s.collector.stop = \ + mock.Mock(return_value=True) + with self.assertRaises(RuntimeError): + self.s.teardown() + + SAMPLE_NETDEVS = { + 'enp11s0': { + 'address': '0a:de:ad:be:ef:f5', + 'device': '0x1533', + 'driver': 'igb', + 'ifindex': '2', + 'interface_name': 'enp11s0', + 'operstate': 'down', + 'pci_bus_id': '0000:0b:00.0', + 'subsystem_device': '0x1533', + 'subsystem_vendor': '0x15d9', + 'vendor': '0x8086' + }, + 'lan': { + 'address': '0a:de:ad:be:ef:f4', + 'device': '0x153a', + 'driver': 'e1000e', + 'ifindex': '3', + 'interface_name': 'lan', + 'operstate': 'up', + 'pci_bus_id': '0000:00:19.0', + 'subsystem_device': '0x153a', + 'subsystem_vendor': '0x15d9', + 'vendor': '0x8086' + } + } + + SAMPLE_VM_NETDEVS = { + 'eth1': { + 'address': 'fa:de:ad:be:ef:5b', + 'device': '0x0001', + 'driver': 'virtio_net', + 'ifindex': '3', + 'interface_name': 'eth1', + 'operstate': 'down', + 'pci_bus_id': '0000:00:04.0', + 'vendor': '0x1af4' + } + } + + def test_parse_netdev_info(self): + output = """\ +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/ifindex:2 +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/address:0a:de:ad:be:ef:f5 +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/operstate:down +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/vendor:0x8086 +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/device:0x1533 +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/subsystem_vendor:0x15d9 +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/subsystem_device:0x1533 +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/driver:igb +/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/pci_bus_id:0000:0b:00.0 +/sys/devices/pci0000:00/0000:00:19.0/net/lan/ifindex:3 +/sys/devices/pci0000:00/0000:00:19.0/net/lan/address:0a:de:ad:be:ef:f4 +/sys/devices/pci0000:00/0000:00:19.0/net/lan/operstate:up +/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/vendor:0x8086 +/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/device:0x153a +/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/subsystem_vendor:0x15d9 +/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/subsystem_device:0x153a +/sys/devices/pci0000:00/0000:00:19.0/net/lan/driver:e1000e +/sys/devices/pci0000:00/0000:00:19.0/net/lan/pci_bus_id:0000:00:19.0 +""" + res = NetworkServiceTestCase.parse_netdev_info(output) + assert res == self.SAMPLE_NETDEVS + + def test_parse_netdev_info_virtio(self): + output = """\ +/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/ifindex:3 +/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/address:fa:de:ad:be:ef:5b +/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/operstate:down +/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/device/vendor:0x1af4 +/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/device/device:0x0001 +/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/driver:virtio_net +""" + res = NetworkServiceTestCase.parse_netdev_info(output) + assert res == self.SAMPLE_VM_NETDEVS + + def test_probe_missing_values(self): + netdevs = self.SAMPLE_NETDEVS.copy() + network = {'local_mac': '0a:de:ad:be:ef:f5'} + NetworkServiceTestCase._probe_missing_values(netdevs, network) + assert network['vpci'] == '0000:0b:00.0' + + network = {'local_mac': '0a:de:ad:be:ef:f4'} + NetworkServiceTestCase._probe_missing_values(netdevs, network) + assert network['vpci'] == '0000:00:19.0' + + # TODO: Split this into several tests, for different IOError sub-types + def test_open_relative_path(self): + mock_open = mock.mock_open() + mock_open_result = mock_open() + mock_open_call_count = 1 # initial call to get result + + module_name = \ + 'yardstick.benchmark.scenarios.networking.vnf_generic.open' + + # test + with mock.patch(module_name, mock_open, create=True): + self.assertEqual(open_relative_file( + 'foo', 'bar'), mock_open_result) + + mock_open_call_count += 1 # one more call expected + self.assertEqual(mock_open.call_count, mock_open_call_count) + self.assertIn('foo', mock_open.call_args_list[-1][0][0]) + self.assertNotIn('bar', mock_open.call_args_list[-1][0][0]) + + def open_effect(*args, **kwargs): + if kwargs.get('name', args[0]) == os.path.join('bar', 'foo'): + return mock_open_result + raise IOError(errno.ENOENT, 'not found') + + mock_open.side_effect = open_effect + self.assertEqual(open_relative_file( + 'foo', 'bar'), mock_open_result) + + mock_open_call_count += 2 # two more calls expected + self.assertEqual(mock_open.call_count, mock_open_call_count) + self.assertIn('foo', mock_open.call_args_list[-1][0][0]) + self.assertIn('bar', mock_open.call_args_list[-1][0][0]) + + # test an IOError of type ENOENT + mock_open.side_effect = IOError(errno.ENOENT, 'not found') + with self.assertRaises(IOError): + # the second call still raises + open_relative_file('foo', 'bar') + + mock_open_call_count += 2 # two more calls expected + self.assertEqual(mock_open.call_count, mock_open_call_count) + self.assertIn('foo', mock_open.call_args_list[-1][0][0]) + self.assertIn('bar', mock_open.call_args_list[-1][0][0]) + + # test an IOError other than ENOENT + mock_open.side_effect = IOError(errno.EBUSY, 'busy') + with self.assertRaises(IOError): + open_relative_file('foo', 'bar') + + mock_open_call_count += 1 # one more call expected + self.assertEqual(mock_open.call_count, mock_open_call_count) diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf.py new file mode 100644 index 000000000..be8ac55d0 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python + +# Copyright 2016 Intel Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Unittest for yardstick.benchmark.scenarios.networking.vsperf.Vsperf + +from __future__ import absolute_import +try: + from unittest import mock +except ImportError: + import mock +import unittest + +from yardstick.benchmark.scenarios.networking import vsperf + + +@mock.patch('yardstick.benchmark.scenarios.networking.vsperf.subprocess') +@mock.patch('yardstick.benchmark.scenarios.networking.vsperf.ssh') +class VsperfTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + "host": { + "ip": "10.229.47.137", + "user": "ubuntu", + "password": "ubuntu", + }, + } + self.args = { + 'options': { + 'testname': 'p2p_rfc2544_continuous', + 'traffic_type': 'continuous', + 'frame_size': '64', + 'bidirectional': 'True', + 'iload': 100, + 'trafficgen_port1': 'eth1', + 'trafficgen_port2': 'eth3', + 'external_bridge': 'br-ex', + 'conf_file': 'vsperf-yardstick.conf', + 'setup_script': 'setup_yardstick.sh', + 'test_params': 'TRAFFICGEN_DURATION=30;', + }, + 'sla': { + 'metrics': 'throughput_rx_fps', + 'throughput_rx_fps': 500000, + 'action': 'monitor', + } + } + + def test_vsperf_setup(self, mock_ssh, mock_subprocess): + p = vsperf.Vsperf(self.args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_subprocess.call().execute.return_value = None + + p.setup() + self.assertIsNotNone(p.client) + self.assertTrue(p.setup_done) + + def test_vsperf_teardown(self, mock_ssh, mock_subprocess): + p = vsperf.Vsperf(self.args, self.ctx) + + # setup() specific mocks + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_subprocess.call().execute.return_value = None + + p.setup() + self.assertIsNotNone(p.client) + self.assertTrue(p.setup_done) + + p.teardown() + self.assertFalse(p.setup_done) + + def test_vsperf_run_ok(self, mock_ssh, mock_subprocess): + p = vsperf.Vsperf(self.args, self.ctx) + + # setup() specific mocks + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_subprocess.call().execute.return_value = None + + # run() specific mocks + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_ssh.SSH.from_node().execute.return_value = ( + 0, 'throughput_rx_fps\r\n14797660.000\r\n', '') + + result = {} + p.run(result) + + self.assertEqual(result['throughput_rx_fps'], '14797660.000') + + def test_vsperf_run_falied_vsperf_execution(self, mock_ssh, + mock_subprocess): + p = vsperf.Vsperf(self.args, self.ctx) + + # setup() specific mocks + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_subprocess.call().execute.return_value = None + + # run() specific mocks + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + result = {} + self.assertRaises(RuntimeError, p.run, result) + + def test_vsperf_run_falied_csv_report(self, mock_ssh, mock_subprocess): + p = vsperf.Vsperf(self.args, self.ctx) + + # setup() specific mocks + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_subprocess.call().execute.return_value = None + + # run() specific mocks + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + result = {} + self.assertRaises(RuntimeError, p.run, result) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py new file mode 100644 index 000000000..1923960e9 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py @@ -0,0 +1,221 @@ +# Copyright 2017 Nokia +# +# 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 subprocess +import time + +import mock +import unittest + +from yardstick.benchmark.scenarios.networking import vsperf_dpdk + + +class VsperfDPDKTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + "host": { + "ip": "10.229.47.137", + "user": "ubuntu", + "password": "ubuntu", + }, + } + self.args = { + 'task_id': "1234-5678", + 'options': { + 'testname': 'pvp_tput', + 'traffic_type': 'rfc2544_throughput', + 'frame_size': '64', + 'test_params': 'TRAFFICGEN_DURATION=30;', + 'trafficgen_port1': 'ens4', + 'trafficgen_port2': 'ens5', + 'conf_file': 'vsperf-yardstick.conf', + 'setup_script': 'setup_yardstick.sh', + 'moongen_helper_file': '~/moongen.py', + 'moongen_host_ip': '10.5.201.151', + 'moongen_port1_mac': '8c:dc:d4:ae:7c:5c', + 'moongen_port2_mac': '8c:dc:d4:ae:7c:5d', + 'trafficgen_port1_nw': 'test2', + 'trafficgen_port2_nw': 'test3', + }, + 'sla': { + 'metrics': 'throughput_rx_fps', + 'throughput_rx_fps': 500000, + 'action': 'monitor', + } + } + + self.scenario = vsperf_dpdk.VsperfDPDK(self.args, self.ctx) + + self._mock_ssh = mock.patch( + 'yardstick.benchmark.scenarios.networking.vsperf_dpdk.ssh') + self.mock_ssh = self._mock_ssh.start() + self._mock_subprocess_call = mock.patch.object(subprocess, 'call') + self.mock_subprocess_call = self._mock_subprocess_call.start() + + self.addCleanup(self._cleanup) + + def _cleanup(self): + self._mock_ssh.stop() + self._mock_subprocess_call.stop() + + def test_setup(self): + # setup() specific mocks + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + def test_teardown(self): + # setup() specific mocks + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + self.scenario.teardown() + self.assertFalse(self.scenario.setup_done) + + def test_is_dpdk_setup_no(self): + # setup() specific mocks + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + # is_dpdk_setup() specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, 'dummy', '') + + result = self.scenario._is_dpdk_setup() + self.assertFalse(result) + + def test_is_dpdk_setup_yes(self): + # setup() specific mocks + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + # is_dpdk_setup() specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + result = self.scenario._is_dpdk_setup() + self.assertTrue(result) + + @mock.patch.object(time, 'sleep') + def test_dpdk_setup_first(self, *args): + # setup() specific mocks + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + # is_dpdk_setup() specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, 'dummy', '') + + self.scenario.dpdk_setup() + self.assertFalse(self.scenario._is_dpdk_setup()) + self.assertTrue(self.scenario.dpdk_setup_done) + + @mock.patch.object(time, 'sleep') + def test_dpdk_setup_next(self, *args): + # setup() specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + self.scenario.dpdk_setup() + self.assertTrue(self.scenario._is_dpdk_setup()) + self.assertTrue(self.scenario.dpdk_setup_done) + + @mock.patch.object(time, 'sleep') + def test_dpdk_setup_runtime_error(self, *args): + + # setup specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + self.assertTrue(self.scenario.setup_done) + + self.assertRaises(RuntimeError, self.scenario.dpdk_setup) + + @mock.patch.object(subprocess, 'check_output') + @mock.patch('time.sleep') + def test_run_ok(self, *args): + # setup() specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + # run() specific mocks + self.mock_subprocess_call().execute.return_value = None + self.mock_ssh.SSH.from_node().execute.return_value = ( + 0, 'throughput_rx_fps\r\n14797660.000\r\n', '') + + result = {} + self.scenario.run(result) + + self.assertEqual(result['throughput_rx_fps'], '14797660.000') + + def test_run_failed_vsperf_execution(self): + # setup() specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + self.mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + result = {} + self.assertRaises(RuntimeError, self.scenario.run, result) + + def test_run_falied_csv_report(self): + # setup() specific mocks + self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + self.mock_subprocess_call().execute.return_value = None + + self.scenario.setup() + self.assertIsNotNone(self.scenario.client) + self.assertTrue(self.scenario.setup_done) + + # run() specific mocks + self.mock_subprocess_call().execute.return_value = None + self.mock_ssh.SSH.from_node().execute.return_value = (1, '', '') + + result = {} + self.assertRaises(RuntimeError, self.scenario.run, result) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/tg_trex_tpl.yaml b/yardstick/tests/unit/benchmark/scenarios/networking/tg_trex_tpl.yaml new file mode 100644 index 000000000..b1641836b --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/tg_trex_tpl.yaml @@ -0,0 +1,75 @@ +# 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. + +vnfd:vnfd-catalog: + vnfd: + - id: TrexTrafficGen # NSPerf class mapping + name: trexgen + short-name: trexgen + description: TRex stateless traffic generator for tests + vm-flavor: + vcpu-count: '4' + memory-mb: '4096' + mgmt-interface: + vdu-id: trexgen-baremetal + user: '{{user}}' # Value filled by vnfdgen + password: '{{password}}' # Value filled by vnfdgen + ip: '{{ip}}' # Value filled by vnfdgen + connection-point: + - name: xe0 + type: VPORT + - name: xe1 + type: VPORT + vdu: + - id: trexgen-baremetal + name: trexgen-baremetal + description: TRex stateless traffic generator for tests + 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_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 + 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 + vpci: '{{ interfaces.xe1.vpci }}' # 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 + vld_id: '{{ interfaces.xe1.vld_id }}' # Value filled by vnfdgen + bandwidth: 10 Gbps + vnfd-connection-point-ref: xe1 + + benchmark: + kpi: + - rx_throughput_fps + - tx_throughput_fps + - tx_throughput_mbps + - rx_throughput_mbps + - tx_throughput_pc_linerate + - rx_throughput_pc_linerate + - min_latency + - max_latency + - avg_latency diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/vpe_vnf_topology.yaml b/yardstick/tests/unit/benchmark/scenarios/networking/vpe_vnf_topology.yaml new file mode 100644 index 000000000..1ac6c1f89 --- /dev/null +++ b/yardstick/tests/unit/benchmark/scenarios/networking/vpe_vnf_topology.yaml @@ -0,0 +1,50 @@ +# 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. + +nsd:nsd-catalog: + nsd: + - id: VPE + name: VPE + short-name: VPE + description: scenario with VPE,L3fwd and VNF + constituent-vnfd: + - member-vnf-index: '1' + vnfd-id-ref: tg__1 + VNF model: ../../vnf_descriptors/tg_rfc2544_tpl.yaml #tg_vpe_upstream.yaml #VPE VNF + - member-vnf-index: '2' + vnfd-id-ref: vnf__1 + VNF model: ../../vnf_descriptors/vpe_vnf.yaml #tg_l3fwd.yaml #tg_trex_tpl.yaml #TREX + + vld: + - id: uplink + name: tg__1 to vnf__1 link 1 + type: ELAN + vnfd-connection-point-ref: + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe0 + vnfd-id-ref: tg__1 #TREX + - member-vnf-index-ref: '2' + vnfd-connection-point-ref: xe0 + vnfd-id-ref: vnf__1 #VNF + + - id: downlink + name: vnf__1 to tg__1 link 2 + type: ELAN + vnfd-connection-point-ref: + - member-vnf-index-ref: '2' + vnfd-connection-point-ref: xe1 + vnfd-id-ref: vnf__1 #L3fwd + - member-vnf-index-ref: '1' + vnfd-connection-point-ref: xe1 + vnfd-id-ref: tg__1 #VPE VNF -- cgit 1.2.3-korg