aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolodymyr Mytnyk <volodymyrx.mytnyk@intel.com>2019-02-05 12:56:33 +0000
committerGerrit Code Review <gerrit@opnfv.org>2019-02-05 12:56:33 +0000
commit0e79473ddc9d5185185f555303d40fdc075c9920 (patch)
tree733c6a5f52b766299e41e9d4500ee939d355a583
parentdeea27f8e9c99b0a547b4c8c2f39dd99d5c4f1a8 (diff)
parent1d8674c2108b03dbb75713a7cd0b224edebb284f (diff)
Merge "Add vBNG test cases stats processing functionality"
-rw-r--r--samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_8ports_1port_congested_IMIX.yaml22
-rw-r--r--samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_IMIX_scale_up.yaml22
-rw-r--r--samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_1port_congested-8.yaml232
-rw-r--r--samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_scale_up.yaml25
-rw-r--r--yardstick/benchmark/scenarios/networking/vnf_generic.py8
-rw-r--r--yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py99
-rw-r--r--yardstick/network_services/traffic_profile/ixia_rfc2544.py136
-rw-r--r--yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py277
-rw-r--r--yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py9
-rw-r--r--yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py88
-rw-r--r--yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py192
-rw-r--r--yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py257
12 files changed, 1116 insertions, 251 deletions
diff --git a/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_8ports_1port_congested_IMIX.yaml b/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_8ports_1port_congested_IMIX.yaml
index 2c2010a11..441886224 100644
--- a/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_8ports_1port_congested_IMIX.yaml
+++ b/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_8ports_1port_congested_IMIX.yaml
@@ -15,6 +15,9 @@
---
{% set sessions_per_port = sessions_per_port or 4000 %}
{% set sessions_per_svlan = sessions_per_svlan or 1000 %}
+{% set duration = duration or 60 %}
+{% set tolerance_low = tolerance_low or 0.0001 %}
+{% set tolerance_high = tolerance_high or 0.0001 %}
schema: yardstick:task:0.1
description: >
vBNG RFC2544 test case with QoS base line with link congestion.
@@ -31,10 +34,11 @@ scenarios:
tg__0: tg_0.yardstick
vnf__0: vnf_0.yardstick
options:
+ duration: {{ duration }}
pppoe_client: # access network
sessions_per_port: {{ sessions_per_port }}
sessions_per_svlan: {{ sessions_per_svlan }}
- pap_user: 'wfnos'
+ pap_user: 'pppoe_user'
pap_password: ''
ip: [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}, {'tg__0': 'xe4'}, {'tg__0': 'xe6'}]
s_vlan: 100 # s-vlan applies per device group
@@ -52,17 +56,27 @@ scenarios:
framesize:
uplink: {70B: 33, 940B: 33, 1470B: 34}
downlink: {68B: 3, 932B: 1, 1470B: 96}
+ priority:
+ # 0 - (000) Routine
+ # 1 - (001) Priority
+ # 2 - (010) Immediate
+ # 3 - (011) Flash
+ # 4 - (100) Flash Override
+ # 5 - (101) CRITIC/ECP
+ # 6 - (110) Internetwork Control
+ # 7 - (111) Network Control
+ tos: {precedence: [0, 4, 7]}
flow:
src_ip: [{'tg__0': 'xe0'}, {'tg__0': 'xe2'}, {'tg__0': 'xe4'}, {'tg__0': 'xe6'}]
dst_ip: [{'tg__0': 'xe1'}, {'tg__0': 'xe3'}, {'tg__0': 'xe5'}, {'tg__0': 'xe7'}]
count: 1
traffic_type: 4
rfc2544:
- allowed_drop_rate: 0.0001 - 0.0001
+ allowed_drop_rate: "{{ tolerance_low }} - {{ tolerance_high }}"
runner:
type: Iteration
- iterations: 10
- interval: 75
+ iterations: 1
+ interval: {{ duration + 15 }}
context:
type: Node
name: yardstick
diff --git a/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_IMIX_scale_up.yaml b/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_IMIX_scale_up.yaml
index f0696ab24..afd60cc69 100644
--- a/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_IMIX_scale_up.yaml
+++ b/samples/vnf_samples/nsut/bng/tc_bng_pppoe_rfc2544_ixia_IMIX_scale_up.yaml
@@ -15,8 +15,10 @@
---
{% set sessions_per_port = sessions_per_port or 4000 %}
{% set sessions_per_svlan = sessions_per_svlan or 1000 %}
+{% set duration = duration or 60 %}
{% set vports = vports or 2 %}
-{% set svlans_per_port = sessions_per_port / sessions_per_svlan %}
+{% set tolerance_low = tolerance_low or 0.0001 %}
+{% set tolerance_high = tolerance_high or 0.0001 %}
schema: yardstick:task:0.1
description: >
vBNG RFC2544 test case with QoS base line without link congestion.
@@ -28,16 +30,16 @@ scenarios:
topology: "../agnostic/agnostic_vnf_topology_ixia_{{ vports }}ports.yaml"
ixia_config: IxiaPppoeClient
extra_args:
- svlans_per_port: {{ svlans_per_port|int }}
access_vports_num: {{ vports|int / 2 }}
nodes:
tg__0: tg_0.yardstick
vnf__0: vnf_0.yardstick
options:
+ duration: {{ duration }}
pppoe_client: # access network
sessions_per_port: {{ sessions_per_port }}
sessions_per_svlan: {{ sessions_per_svlan }}
- pap_user: 'wfnos'
+ pap_user: 'pppoe_user'
pap_password: ''
ip:
{% for vnf_num in range(0, vports|int, 2) %}
@@ -64,6 +66,16 @@ scenarios:
framesize:
uplink: {70B: 33, 940B: 33, 1470B: 34}
downlink: {68B: 3, 932B: 1, 1470B: 96}
+ priority:
+ # 0 - (000) Routine
+ # 1 - (001) Priority
+ # 2 - (010) Immediate
+ # 3 - (011) Flash
+ # 4 - (100) Flash Override
+ # 5 - (101) CRITIC/ECP
+ # 6 - (110) Internetwork Control
+ # 7 - (111) Network Control
+ tos: {precedence: [0, 4, 7]}
flow:
src_ip:
{% for vnf_num in range(0, vports|int, 2) %}
@@ -76,11 +88,11 @@ scenarios:
count: 1
traffic_type: 4
rfc2544:
- allowed_drop_rate: 0.0001 - 0.0001
+ allowed_drop_rate: "{{ tolerance_low }} - {{ tolerance_high }}"
runner:
type: Iteration
iterations: 10
- interval: 75
+ interval: {{ duration + 15 }}
context:
type: Node
name: yardstick
diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_1port_congested-8.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_1port_congested-8.yaml
index a3170048a..77bc55751 100644
--- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_1port_congested-8.yaml
+++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_1port_congested-8.yaml
@@ -25,9 +25,10 @@ traffic_profile:
duration: {{ duration }}
enable_latency: True
-uplink_0:
+uplink_0: # traffic flow from xe0 to xe1
ipv4:
id: 1
+ frame_rate: 25%
port: xe0
outer_l2:
framesize: &uplink_framesize
@@ -49,12 +50,17 @@ uplink_0:
1518B: "{{get(imix, 'imix.uplink.1518B', '0') }}"
outer_l3v4:
- priority:
+ priority: &uplink_precedence
+ {% if priority %}
+ {{ priority }}
+ {% else %}
tos:
- precedence: &uplink_precedence [0, 4, 7]
-downlink_0:
+ precedence: [0, 4, 7]
+ {% endif %}
+downlink_0: # traffic flow from xe1 to xe0
ipv4:
id: 2
+ frame_rate: 50%
port: xe1
outer_l2:
framesize: &downlink_framesize
@@ -76,337 +82,311 @@ downlink_0:
1518B: "{{get(imix, 'imix.downlink.1518B', '0') }}"
outer_l3v4:
- priority:
+ priority: &downlink_precedence
+ {% if priority %}
+ {{ priority }}
+ {% else %}
tos:
- precedence: &downlink_precedence [0, 4, 7]
-uplink_1:
+ precedence: [0, 4, 7]
+ {% endif %}
+uplink_1: # traffic flow from xe0 to xe1
ipv4:
id: 3
+ frame_rate: 25%
port: xe0
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_1:
+ priority: *uplink_precedence
+downlink_1: # traffic flow from xe1 to xe0
ipv4:
id: 4
+ frame_rate: 50%
port: xe1
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_2:
+ priority: *downlink_precedence
+uplink_2: # traffic flow from xe0 to xe3
ipv4:
id: 5
+ frame_rate: 25%
port: xe0
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_2:
+ priority: *uplink_precedence
+downlink_2: # traffic flow from xe3 to xe0
ipv4:
id: 6
+ frame_rate: 50%
port: xe3
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_3:
+ priority: *downlink_precedence
+uplink_3: # traffic flow from xe0 to xe3
ipv4:
id: 7
+ frame_rate: 25%
port: xe0
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_3:
+ priority: *uplink_precedence
+downlink_3: # traffic flow from xe3 to xe0
ipv4:
id: 8
+ frame_rate: 50%
port: xe3
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_4:
+ priority: *downlink_precedence
+uplink_4: # traffic flow from xe2 to xe5
ipv4:
id: 9
+ frame_rate: 25%
port: xe2
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_4:
+ priority: *uplink_precedence
+downlink_4: # traffic flow from xe5 to xe2
ipv4:
id: 10
+ frame_rate: 7%
port: xe5
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_5:
+ priority: *downlink_precedence
+uplink_5: # traffic flow from xe2 to xe5
ipv4:
id: 11
+ frame_rate: 25%
port: xe2
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_5:
+ priority: *uplink_precedence
+downlink_5: # traffic flow from xe5 to xe2
ipv4:
id: 12
+ frame_rate: 7%
port: xe5
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_6:
+ priority: *downlink_precedence
+uplink_6: # traffic flow from xe2 to xe5
ipv4:
id: 13
+ frame_rate: 25%
port: xe2
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_6:
+ priority: *uplink_precedence
+downlink_6: # traffic flow from xe5 to xe2
ipv4:
id: 14
+ frame_rate: 7%
port: xe5
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_7:
+ priority: *downlink_precedence
+uplink_7: # traffic flow from xe2 to xe5
ipv4:
id: 15
+ frame_rate: 25%
port: xe2
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_7:
+ priority: *uplink_precedence
+downlink_7: # traffic flow from xe5 to xe2
ipv4:
id: 16
+ frame_rate: 7%
port: xe5
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_8:
+ priority: *downlink_precedence
+uplink_8: # traffic flow from xe4 to xe5
ipv4:
id: 17
+ frame_rate: 25%
port: xe4
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_8:
+ priority: *uplink_precedence
+downlink_8: # traffic flow from xe5 to xe4
ipv4:
id: 18
+ frame_rate: 7%
port: xe5
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_9:
+ priority: *downlink_precedence
+uplink_9: # traffic flow from xe4 to xe5
ipv4:
id: 19
+ frame_rate: 25%
port: xe4
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_9:
+ priority: *uplink_precedence
+downlink_9: # traffic flow from xe5 to xe4
ipv4:
id: 20
+ frame_rate: 7%
port: xe5
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_10:
+ priority: *downlink_precedence
+uplink_10: # traffic flow from xe4 to xe7
ipv4:
id: 21
+ frame_rate: 25%
port: xe4
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_10:
+ priority: *uplink_precedence
+downlink_10: # traffic flow from xe7 to xe4
ipv4:
id: 22
+ frame_rate: 7%
port: xe7
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_11:
+ priority: *downlink_precedence
+uplink_11: # traffic flow from xe4 to xe7
ipv4:
id: 23
+ frame_rate: 25%
port: xe4
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_11:
+ priority: *uplink_precedence
+downlink_11: # traffic flow from xe7 to xe4
ipv4:
id: 24
+ frame_rate: 7%
port: xe7
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
+ priority: *downlink_precedence
-uplink_12:
+uplink_12: # traffic flow from xe6 to xe7
ipv4:
id: 25
+ frame_rate: 25%
port: xe6
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_12:
+ priority: *uplink_precedence
+downlink_12: # traffic flow from xe7 to xe6
ipv4:
id: 26
+ frame_rate: 7%
port: xe7
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_13:
+ priority: *downlink_precedence
+uplink_13: # traffic flow from xe6 to xe7
ipv4:
id: 27
+ frame_rate: 25%
port: xe6
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_13:
+ priority: *uplink_precedence
+downlink_13: # traffic flow from xe7 to xe6
ipv4:
id: 28
+ frame_rate: 7%
port: xe7
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_14:
+ priority: *downlink_precedence
+uplink_14: # traffic flow from xe6 to xe7
ipv4:
id: 29
+ frame_rate: 25%
port: xe6
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_14:
+ priority: *uplink_precedence
+downlink_14: # traffic flow from xe7 to xe6
ipv4:
id: 30
+ frame_rate: 7%
port: xe7
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
-uplink_15:
+ priority: *downlink_precedence
+uplink_15: # traffic flow from xe6 to xe7
ipv4:
id: 31
+ frame_rate: 25%
port: xe6
outer_l2:
framesize: *uplink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *uplink_precedence
-downlink_15:
+ priority: *uplink_precedence
+downlink_15: # traffic flow from xe7 to xe6
ipv4:
id: 32
+ frame_rate: 7%
port: xe7
outer_l2:
framesize: *downlink_framesize
outer_l3v4:
- priority:
- tos:
- precedence: *downlink_precedence
+ priority: *downlink_precedence
diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_scale_up.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_scale_up.yaml
index 4f427b76a..91658a586 100644
--- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_scale_up.yaml
+++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vbng_scale_up.yaml
@@ -13,7 +13,6 @@
# limitations under the License.
---
-{% set svlan_per_port = get(extra_args, 'svlans_per_port') %}
{% set ports = get(extra_args, 'access_vports_num')|int %}
schema: "nsb:traffic_profile:0.1"
@@ -23,11 +22,11 @@ name: rfc2544
description: Traffic profile to run RFC2544 latency
traffic_profile:
traffic_type : IXIARFC2544PppoeScenarioProfile # defines traffic behavior - constant or look for highest possible throughput
- frame_rate : 12.5% # pc of linerate
+ frame_rate : 100% # pc of linerate
duration: {{ duration }}
enable_latency: True
-{% for i in range(svlan_per_port|int * ports|int) %}
+{% for i in range(ports|int) %}
uplink_{{ i }}:
ipv4:
id: {{ (i * 2) + 1 }}
@@ -51,9 +50,13 @@ uplink_{{ i }}:
1518B: "{{get(imix, 'imix.uplink.1518B', '0') }}"
outer_l3v4:
- priority:
- tos:
- precedence: [0, 4, 7]
+ priority:
+ {% if priority %}
+ {{ priority }}
+ {% else %}
+ tos:
+ precedence: [0, 4, 7]
+ {% endif %}
downlink_{{ i }}:
ipv4:
id: {{ (i * 2) + 2 }}
@@ -77,7 +80,11 @@ downlink_{{ i }}:
1518B: "{{get(imix, 'imix.downlink.1518B', '0') }}"
outer_l3v4:
- priority:
- tos:
- precedence: [0, 4, 7]
+ priority:
+ {% if priority %}
+ {{ priority }}
+ {% else %}
+ tos:
+ precedence: [0, 4, 7]
+ {% endif %}
{% endfor %}
diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py
index 3fd1845a0..dd5f4726f 100644
--- a/yardstick/benchmark/scenarios/networking/vnf_generic.py
+++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py
@@ -164,6 +164,13 @@ class NetworkServiceBase(scenario_base.Scenario):
imix = {}
return imix
+ def _get_ip_priority(self):
+ try:
+ priority = self.scenario_cfg['options']['priority']
+ except KeyError:
+ priority = {}
+ return priority
+
def _get_traffic_profile(self):
profile = self.scenario_cfg["traffic_profile"]
path = self.scenario_cfg["task_path"]
@@ -201,6 +208,7 @@ class NetworkServiceBase(scenario_base.Scenario):
tprofile_data = {
'flow': self._get_traffic_flow(),
'imix': self._get_traffic_imix(),
+ 'priority': self._get_ip_priority(),
tprofile_base.TrafficProfile.UPLINK: {},
tprofile_base.TrafficProfile.DOWNLINK: {},
'extra_args': extra_args,
diff --git a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
index cc627ef78..e0b7aa000 100644
--- a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
+++ b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
@@ -14,6 +14,8 @@
import ipaddress
import logging
+import re
+import collections
import IxNetwork
@@ -62,6 +64,13 @@ SUPPORTED_TOS_FIELDS = [
'reliability'
]
+IP_PRIORITY_PATTERN = r'[^\w+]*.+(Raw priority|' \
+ 'Precedence|' \
+ 'Default PHB|' \
+ 'Class selector PHB|' \
+ 'Assured forwarding selector PHB|' \
+ 'Expedited forwarding PHB)'
+
class Vlan(object):
def __init__(self,
@@ -99,6 +108,18 @@ class IxNextgen(object): # pragma: no cover
"Store-Forward_Max_latency_ns": 'Store-Forward Max Latency (ns)',
}
+ FLOWS_STATS_NAME_MAP = {
+ "Tx_Port": 'Tx Port',
+ "VLAN-ID": 'VLAN:VLAN-ID',
+ "IP_Priority": re.compile(IP_PRIORITY_PATTERN),
+ "Flow_Group": 'Flow Group',
+ "Tx_Frames": 'Tx Frames',
+ "Rx_Frames": 'Rx Frames',
+ "Store-Forward_Avg_latency_ns": 'Store-Forward Avg Latency (ns)',
+ "Store-Forward_Min_latency_ns": 'Store-Forward Min Latency (ns)',
+ "Store-Forward_Max_latency_ns": 'Store-Forward Max Latency (ns)'
+ }
+
PPPOX_CLIENT_PER_PORT_NAME_MAP = {
'subs_port': 'Port',
'Sessions_Up': 'Sessions Up',
@@ -111,6 +132,18 @@ class IxNextgen(object): # pragma: no cover
FLOW_STATISTICS = '::ixNet::OBJ-/statistics/view:"Flow Statistics"'
PPPOX_CLIENT_PER_PORT = '::ixNet::OBJ-/statistics/view:"PPPoX Client Per Port"'
+ PPPOE_SCENARIO_STATS = {
+ 'port_statistics': PORT_STATISTICS,
+ 'flow_statistic': FLOW_STATISTICS,
+ 'pppox_client_per_port': PPPOX_CLIENT_PER_PORT
+ }
+
+ PPPOE_SCENARIO_STATS_MAP = {
+ 'port_statistics': PORT_STATS_NAME_MAP,
+ 'flow_statistic': FLOWS_STATS_NAME_MAP,
+ 'pppox_client_per_port': PPPOX_CLIENT_PER_PORT_NAME_MAP
+ }
+
@staticmethod
def get_config(tg_cfg):
card = []
@@ -731,6 +764,19 @@ class IxNextgen(object): # pragma: no cover
'getColumnValues', view_obj, data_ixia)
for data_yardstick, data_ixia in name_map.items()}
+ def _get_view_page_stats(self, view_obj):
+ """Get full view page stats
+
+ :param view_obj: view object, e.g.
+ '::ixNet::OBJ-/statistics/view:"Port Statistics"'
+ :return: (list) List of dicts. Each dict represents view page row
+ """
+ view = view_obj + '/page'
+ column_headers = self.ixnet.getAttribute(view, '-columnCaptions')
+ view_rows = self.ixnet.getAttribute(view, '-rowValues')
+ view_page = [dict(zip(column_headers, row[0])) for row in view_rows]
+ return view_page
+
def _set_egress_flow_tracking(self, encapsulation, offset):
"""Set egress flow tracking options
@@ -753,7 +799,7 @@ class IxNextgen(object): # pragma: no cover
self.ixnet.setAttribute(enc_obj, '-offset', offset)
self.ixnet.commit()
- def _set_flow_tracking(self, track_by):
+ def set_flow_tracking(self, track_by):
"""Set flow tracking options
:param track_by: list of tracking fields
@@ -780,24 +826,39 @@ class IxNextgen(object): # pragma: no cover
return stats
def get_pppoe_scenario_statistics(self):
- """Retrieve port, flow and PPPoE subscribers statistics
-
- "Port Statistics" parameters are stored in self.PORT_STATS_NAME_MAP.
- "Flow Statistics" parameters are stored in self.LATENCY_NAME_MAP.
- "PPPoX Client Per Port" parameters are stored in
- self.PPPOE_CLIENT_PER_PORT_NAME_MAP
-
- :return: dictionary with the statistics; the keys of this dictionary
- are PORT_STATS_NAME_MAP, LATENCY_NAME_MAP and
- PPPOE_CLIENT_PER_PORT_NAME_MAP keys.
- """
- stats = self._build_stats_map(self.PORT_STATISTICS,
- self.PORT_STATS_NAME_MAP)
- stats.update(self._build_stats_map(self.FLOW_STATISTICS,
- self.LATENCY_NAME_MAP))
- stats.update(self._build_stats_map(self.PPPOX_CLIENT_PER_PORT,
- self.PPPOX_CLIENT_PER_PORT_NAME_MAP))
- return stats
+ """Retrieve port, flow and PPPoE subscribers statistics"""
+ stats = collections.defaultdict(list)
+ result = collections.defaultdict(list)
+ for stat, view in self.PPPOE_SCENARIO_STATS.items():
+ # Get view total pages number
+ total_pages = self.ixnet.getAttribute(
+ view + '/page', '-totalPages')
+ # Collect stats from all view pages
+ for page in range(1, int(total_pages) + 1):
+ current_page = int(self.ixnet.getAttribute(
+ view + '/page', '-currentPage'))
+ if page != int(current_page):
+ self.ixnet.setAttribute(view + '/page', '-currentPage',
+ str(page))
+ self.ixnet.commit()
+ page_data = self._get_view_page_stats(view)
+ stats[stat].extend(page_data)
+ # Filter collected views stats
+ for stat in stats:
+ for view_row in stats[stat]:
+ filtered_row = {}
+ for key, value in self.PPPOE_SCENARIO_STATS_MAP[stat].items():
+ if isinstance(value, str):
+ filtered_row.update({key: view_row[value]})
+ # Handle keys which values are represented by regex
+ else:
+ for k in view_row.keys():
+ if value.match(k):
+ value = value.match(k).group()
+ filtered_row.update({key: view_row[value]})
+ break
+ result[stat].append(filtered_row)
+ return result
def start_protocols(self):
self.ixnet.execute('startAllProtocols')
diff --git a/yardstick/network_services/traffic_profile/ixia_rfc2544.py b/yardstick/network_services/traffic_profile/ixia_rfc2544.py
index 7df590fb3..89bb3ef7a 100644
--- a/yardstick/network_services/traffic_profile/ixia_rfc2544.py
+++ b/yardstick/network_services/traffic_profile/ixia_rfc2544.py
@@ -146,12 +146,16 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
return result
- def _ixia_traffic_generate(self, traffic, ixia_obj):
+ def _ixia_traffic_generate(self, traffic, ixia_obj, traffic_gen):
ixia_obj.update_frame(traffic, self.config.duration)
ixia_obj.update_ip_packet(traffic)
ixia_obj.update_l4(traffic)
+ self._update_traffic_tracking_options(traffic_gen)
ixia_obj.start_traffic()
+ def _update_traffic_tracking_options(self, traffic_gen):
+ traffic_gen.update_tracking_options()
+
def update_traffic_profile(self, traffic_generator):
def port_generator():
for vld_id, intfs in sorted(traffic_generator.networks.items()):
@@ -183,11 +187,12 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
self.rate = self._get_next_rate()
traffic = self._get_ixia_traffic_profile(self.full_profile, mac)
- self._ixia_traffic_generate(traffic, ixia_obj)
+ self._ixia_traffic_generate(traffic, ixia_obj, traffic_generator)
return first_run
+ # pylint: disable=unused-argument
def get_drop_percentage(self, samples, tol_min, tolerance, precision,
- resolution, first_run=False):
+ resolution, first_run=False, tc_rfc2544_opts=None):
completed = False
drop_percent = 100.0
num_ifaces = len(samples)
@@ -275,12 +280,131 @@ class IXIARFC2544PppoeScenarioProfile(IXIARFC2544Profile):
self.full_profile.update({downlink: self.params[downlink]})
def update_traffic_profile(self, traffic_generator):
+
+ networks = collections.OrderedDict()
+
+ # Sort network interfaces pairs
+ for i in range(len(traffic_generator.networks)):
+ uplink = '_'.join([self.UPLINK, str(i)])
+ downlink = '_'.join([self.DOWNLINK, str(i)])
+ if uplink in traffic_generator.networks:
+ networks[uplink] = traffic_generator.networks[uplink]
+ if downlink in traffic_generator.networks:
+ networks[downlink] = traffic_generator.networks[downlink]
+
def port_generator():
- for vld_id, intfs in sorted(traffic_generator.networks.items()):
- if not vld_id.startswith((self.UPLINK, self.DOWNLINK)):
- continue
+ for intfs in networks.values():
for intf in intfs:
yield traffic_generator.vnfd_helper.port_num(intf)
self._get_flow_groups_params()
self.ports = [port for port in port_generator()]
+
+ def _get_prio_flows_drop_percentage(self, stats):
+ drop_percent = 100
+ for prio_id in stats:
+ prio_flow = stats[prio_id]
+ sum_packet_drop = abs(prio_flow['out_packets'] - prio_flow['in_packets'])
+ try:
+ drop_percent = round(
+ (sum_packet_drop / float(prio_flow['out_packets'])) * 100,
+ self.DROP_PERCENT_ROUND)
+ except ZeroDivisionError:
+ LOG.info('No traffic is flowing')
+ prio_flow['DropPercentage'] = drop_percent
+ return stats
+
+ def _get_summary_pppoe_subs_counters(self, samples):
+ result = {}
+ keys = ['sessions_up',
+ 'sessions_down',
+ 'sessions_not_started',
+ 'sessions_total']
+ for key in keys:
+ result[key] = \
+ sum([samples[port][key] for port in samples
+ if key in samples[port]])
+ return result
+
+ def get_drop_percentage(self, samples, tol_min, tolerance, precision,
+ resolution, first_run=False, tc_rfc2544_opts=None):
+ completed = False
+ sum_drop_percent = 100
+ num_ifaces = len(samples)
+ duration = self.config.duration
+ priority_stats = samples.pop('priority_stats')
+ priority_stats = self._get_prio_flows_drop_percentage(priority_stats)
+ summary_subs_stats = self._get_summary_pppoe_subs_counters(samples)
+ in_packets_sum = sum(
+ [samples[iface]['in_packets'] for iface in samples])
+ out_packets_sum = sum(
+ [samples[iface]['out_packets'] for iface in samples])
+ rx_throughput = round(float(in_packets_sum) / duration, 3)
+ tx_throughput = round(float(out_packets_sum) / duration, 3)
+ sum_packet_drop = abs(out_packets_sum - in_packets_sum)
+
+ try:
+ sum_drop_percent = round(
+ (sum_packet_drop / float(out_packets_sum)) * 100,
+ self.DROP_PERCENT_ROUND)
+ except ZeroDivisionError:
+ LOG.info('No traffic is flowing')
+
+ latency_ns_avg = float(
+ sum([samples[iface]['Store-Forward_Avg_latency_ns']
+ for iface in samples])) / num_ifaces
+ latency_ns_min = float(
+ sum([samples[iface]['Store-Forward_Min_latency_ns']
+ for iface in samples])) / num_ifaces
+ latency_ns_max = float(
+ sum([samples[iface]['Store-Forward_Max_latency_ns']
+ for iface in samples])) / num_ifaces
+
+ samples['TxThroughput'] = tx_throughput
+ samples['RxThroughput'] = rx_throughput
+ samples['DropPercentage'] = sum_drop_percent
+ samples['latency_ns_avg'] = latency_ns_avg
+ samples['latency_ns_min'] = latency_ns_min
+ samples['latency_ns_max'] = latency_ns_max
+ samples['priority'] = priority_stats
+ samples.update(summary_subs_stats)
+
+ if tc_rfc2544_opts:
+ priority = tc_rfc2544_opts.get('priority')
+ if priority:
+ drop_percent = samples['priority'][priority]['DropPercentage']
+ else:
+ drop_percent = sum_drop_percent
+ else:
+ drop_percent = sum_drop_percent
+
+ if first_run:
+ completed = True if drop_percent <= tolerance else False
+ if (first_run and
+ self.rate_unit == tp_base.TrafficProfileConfig.RATE_FPS):
+ self.rate = float(out_packets_sum) / duration / num_ifaces
+
+ if drop_percent > tolerance:
+ self.max_rate = self.rate
+ elif drop_percent < tol_min:
+ self.min_rate = self.rate
+ else:
+ completed = True
+
+ next_rate = self._get_next_rate()
+ if abs(next_rate - self.rate) < resolution:
+ LOG.debug("rate=%s, next_rate=%s, resolution=%s", self.rate,
+ next_rate, resolution)
+ # stop test if the difference between the rate transmission
+ # in two iterations is smaller than the value of the resolution
+ completed = True
+
+ LOG.debug("tolerance=%s, tolerance_precision=%s drop_percent=%s "
+ "completed=%s", tolerance, precision, drop_percent,
+ completed)
+
+ samples['Status'] = self.STATUS_FAIL
+ if round(drop_percent, precision) <= tolerance:
+ samples['Status'] = self.STATUS_SUCCESS
+
+ return completed, samples
diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
index 2c3140f8c..f8eec4f4c 100644
--- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
+++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
@@ -15,6 +15,7 @@
import ipaddress
import logging
import six
+import collections
import os
import time
@@ -34,7 +35,7 @@ LOG = logging.getLogger(__name__)
WAIT_AFTER_CFG_LOAD = 10
WAIT_FOR_TRAFFIC = 30
-WAIT_PROTOCOLS_STARTED = 360
+WAIT_PROTOCOLS_STARTED = 420
class IxiaBasicScenario(object):
@@ -66,6 +67,47 @@ class IxiaBasicScenario(object):
self.client.create_traffic_model(self._uplink_vports,
self._downlink_vports)
+ def _get_stats(self):
+ return self.client.get_statistics()
+
+ def generate_samples(self, resource_helper, ports, duration):
+ stats = self._get_stats()
+
+ samples = {}
+ # this is not DPDK port num, but this is whatever number we gave
+ # when we selected ports and programmed the profile
+ for port_num in ports:
+ try:
+ # reverse lookup port name from port_num so the stats dict is descriptive
+ intf = resource_helper.vnfd_helper.find_interface_by_port(port_num)
+ port_name = intf['name']
+ avg_latency = stats['Store-Forward_Avg_latency_ns'][port_num]
+ min_latency = stats['Store-Forward_Min_latency_ns'][port_num]
+ max_latency = stats['Store-Forward_Max_latency_ns'][port_num]
+ samples[port_name] = {
+ 'rx_throughput_kps': float(stats['Rx_Rate_Kbps'][port_num]),
+ 'tx_throughput_kps': float(stats['Tx_Rate_Kbps'][port_num]),
+ 'rx_throughput_mbps': float(stats['Rx_Rate_Mbps'][port_num]),
+ 'tx_throughput_mbps': float(stats['Tx_Rate_Mbps'][port_num]),
+ 'in_packets': int(stats['Valid_Frames_Rx'][port_num]),
+ 'out_packets': int(stats['Frames_Tx'][port_num]),
+ 'RxThroughput': float(stats['Valid_Frames_Rx'][port_num]) / duration,
+ 'TxThroughput': float(stats['Frames_Tx'][port_num]) / duration,
+ 'Store-Forward_Avg_latency_ns': utils.safe_cast(avg_latency, int, 0),
+ 'Store-Forward_Min_latency_ns': utils.safe_cast(min_latency, int, 0),
+ 'Store-Forward_Max_latency_ns': utils.safe_cast(max_latency, int, 0)
+ }
+ except IndexError:
+ pass
+
+ return samples
+
+ def update_tracking_options(self):
+ pass
+
+ def get_tc_rfc2544_options(self):
+ pass
+
class IxiaL3Scenario(IxiaBasicScenario):
"""Ixia scenario for L3 flow between static ip's"""
@@ -172,8 +214,12 @@ class IxiaPppoeClientScenario(object):
traffic_profile.full_profile)
endpoints_obj_pairs = \
self._get_endpoints_src_dst_obj_pairs(endpoints_id_pairs)
- uplink_endpoints = endpoints_obj_pairs[::2]
- downlink_endpoints = endpoints_obj_pairs[1::2]
+ if endpoints_obj_pairs:
+ uplink_endpoints = endpoints_obj_pairs[::2]
+ downlink_endpoints = endpoints_obj_pairs[1::2]
+ else:
+ uplink_endpoints = self._access_topologies
+ downlink_endpoints = self._core_topologies
self.client.create_ipv4_traffic_model(uplink_endpoints,
downlink_endpoints)
@@ -266,18 +312,14 @@ class IxiaPppoeClientScenario(object):
device groups pairs between which flow groups will be created:
1. In case uplink/downlink flows in traffic profile doesn't have
- specified 'port' key, flows will be created between each device
- group on access port and device group on corresponding core port.
+ specified 'port' key, flows will be created between topologies
+ on corresponding access and core port.
E.g.:
- Device groups created on access port xe0: dg1, dg2, dg3
- Device groups created on core port xe1: dg4
+ Access topology on xe0: topology1
+ Core topology on xe1: topology2
Flows will be created between:
- dg1 -> dg4
- dg4 -> dg1
- dg2 -> dg4
- dg4 -> dg2
- dg3 -> dg4
- dg4 -> dg3
+ topology1 -> topology2
+ topology2 -> topology1
2. In case uplink/downlink flows in traffic profile have specified
'port' key, flows will be created between device groups on this
@@ -338,13 +380,6 @@ class IxiaPppoeClientScenario(object):
[endpoint_obj_pairs.extend([up, down])
for up, down in zip(uplink_dev_groups, downlink_dev_groups)]
- if not endpoint_obj_pairs:
- for up, down in zip(uplink_ports, downlink_ports):
- uplink_dev_groups = port_to_dev_group_mapping[up]
- downlink_dev_groups = \
- port_to_dev_group_mapping[down] * len(uplink_dev_groups)
- [endpoint_obj_pairs.extend(list(i))
- for i in zip(uplink_dev_groups, downlink_dev_groups)]
return endpoint_obj_pairs
def _fill_ixia_config(self):
@@ -438,6 +473,168 @@ class IxiaPppoeClientScenario(object):
bgp_type=ipv4["bgp"].get("bgp_type"))
self.protocols.append(bgp_peer_obj)
+ def update_tracking_options(self):
+ priority_map = {
+ 'raw': 'ipv4Raw0',
+ 'tos': {'precedence': 'ipv4Precedence0'},
+ 'dscp': {'defaultPHB': 'ipv4DefaultPhb0',
+ 'selectorPHB': 'ipv4ClassSelectorPhb0',
+ 'assuredPHB': 'ipv4AssuredForwardingPhb0',
+ 'expeditedPHB': 'ipv4ExpeditedForwardingPhb0'}
+ }
+
+ prio_trackby_key = 'ipv4Precedence0'
+
+ try:
+ priority = list(self._ixia_cfg['priority'])[0]
+ if priority == 'raw':
+ prio_trackby_key = priority_map[priority]
+ elif priority in ['tos', 'dscp']:
+ priority_type = list(self._ixia_cfg['priority'][priority])[0]
+ prio_trackby_key = priority_map[priority][priority_type]
+ except KeyError:
+ pass
+
+ tracking_options = ['flowGroup0', 'vlanVlanId0', prio_trackby_key]
+ self.client.set_flow_tracking(tracking_options)
+
+ def get_tc_rfc2544_options(self):
+ return self._ixia_cfg.get('rfc2544')
+
+ def _get_stats(self):
+ return self.client.get_pppoe_scenario_statistics()
+
+ @staticmethod
+ def get_flow_id_data(stats, flow_id, key):
+ result = [float(flow.get(key)) for flow in stats if flow['id'] == flow_id]
+ return sum(result) / len(result)
+
+ def get_priority_flows_stats(self, samples, duration):
+ results = {}
+ priorities = set([flow['IP_Priority'] for flow in samples])
+ for priority in priorities:
+ tx_frames = sum(
+ [int(flow['Tx_Frames']) for flow in samples
+ if flow['IP_Priority'] == priority])
+ rx_frames = sum(
+ [int(flow['Rx_Frames']) for flow in samples
+ if flow['IP_Priority'] == priority])
+ prio_flows_num = len([flow for flow in samples
+ if flow['IP_Priority'] == priority])
+ avg_latency_ns = sum(
+ [int(flow['Store-Forward_Avg_latency_ns']) for flow in samples
+ if flow['IP_Priority'] == priority]) / prio_flows_num
+ min_latency_ns = sum(
+ [int(flow['Store-Forward_Min_latency_ns']) for flow in samples
+ if flow['IP_Priority'] == priority]) / prio_flows_num
+ max_latency_ns = sum(
+ [int(flow['Store-Forward_Max_latency_ns']) for flow in samples
+ if flow['IP_Priority'] == priority]) / prio_flows_num
+ tx_throughput = float(tx_frames) / duration
+ rx_throughput = float(rx_frames) / duration
+ results[priority] = {
+ 'in_packets': rx_frames,
+ 'out_packets': tx_frames,
+ 'RxThroughput': round(rx_throughput, 3),
+ 'TxThroughput': round(tx_throughput, 3),
+ 'avg_latency_ns': utils.safe_cast(avg_latency_ns, int, 0),
+ 'min_latency_ns': utils.safe_cast(min_latency_ns, int, 0),
+ 'max_latency_ns': utils.safe_cast(max_latency_ns, int, 0)
+ }
+ return results
+
+ def generate_samples(self, resource_helper, ports, duration):
+
+ stats = self._get_stats()
+ samples = {}
+ ports_stats = stats['port_statistics']
+ flows_stats = stats['flow_statistic']
+ pppoe_subs_per_port = stats['pppox_client_per_port']
+
+ # Get sorted list of ixia ports names
+ ixia_port_names = sorted([data['port_name'] for data in ports_stats])
+
+ # Set 'port_id' key for ports stats items
+ for item in ports_stats:
+ port_id = item.pop('port_name').split('-')[-1].strip()
+ item['port_id'] = int(port_id)
+
+ # Set 'id' key for flows stats items
+ for item in flows_stats:
+ flow_id = item.pop('Flow_Group').split('-')[1].strip()
+ item['id'] = int(flow_id)
+
+ # Set 'port_id' key for pppoe subs per port stats
+ for item in pppoe_subs_per_port:
+ port_id = item.pop('subs_port').split('-')[-1].strip()
+ item['port_id'] = int(port_id)
+
+ # Map traffic flows to ports
+ port_flow_map = collections.defaultdict(set)
+ for item in flows_stats:
+ tx_port = item.pop('Tx_Port')
+ tx_port_index = ixia_port_names.index(tx_port)
+ port_flow_map[tx_port_index].update([item['id']])
+
+ # Sort ports stats
+ ports_stats = sorted(ports_stats, key=lambda k: k['port_id'])
+
+ # Get priority flows stats
+ prio_flows_stats = self.get_priority_flows_stats(flows_stats, duration)
+ samples['priority_stats'] = prio_flows_stats
+
+ # this is not DPDK port num, but this is whatever number we gave
+ # when we selected ports and programmed the profile
+ for port_num in ports:
+ try:
+ # reverse lookup port name from port_num so the stats dict is descriptive
+ intf = resource_helper.vnfd_helper.find_interface_by_port(port_num)
+ port_name = intf['name']
+ port_id = ports_stats[port_num]['port_id']
+ port_subs_stats = \
+ [port_data for port_data in pppoe_subs_per_port
+ if port_data.get('port_id') == port_id]
+
+ avg_latency = \
+ sum([float(self.get_flow_id_data(
+ flows_stats, flow, 'Store-Forward_Avg_latency_ns'))
+ for flow in port_flow_map[port_num]]) / len(port_flow_map[port_num])
+ min_latency = \
+ sum([float(self.get_flow_id_data(
+ flows_stats, flow, 'Store-Forward_Min_latency_ns'))
+ for flow in port_flow_map[port_num]]) / len(port_flow_map[port_num])
+ max_latency = \
+ sum([float(self.get_flow_id_data(
+ flows_stats, flow, 'Store-Forward_Max_latency_ns'))
+ for flow in port_flow_map[port_num]]) / len(port_flow_map[port_num])
+
+ samples[port_name] = {
+ 'rx_throughput_kps': float(ports_stats[port_num]['Rx_Rate_Kbps']),
+ 'tx_throughput_kps': float(ports_stats[port_num]['Tx_Rate_Kbps']),
+ 'rx_throughput_mbps': float(ports_stats[port_num]['Rx_Rate_Mbps']),
+ 'tx_throughput_mbps': float(ports_stats[port_num]['Tx_Rate_Mbps']),
+ 'in_packets': int(ports_stats[port_num]['Valid_Frames_Rx']),
+ 'out_packets': int(ports_stats[port_num]['Frames_Tx']),
+ 'RxThroughput': float(ports_stats[port_num]['Valid_Frames_Rx']) / duration,
+ 'TxThroughput': float(ports_stats[port_num]['Frames_Tx']) / duration,
+ 'Store-Forward_Avg_latency_ns': utils.safe_cast(avg_latency, int, 0),
+ 'Store-Forward_Min_latency_ns': utils.safe_cast(min_latency, int, 0),
+ 'Store-Forward_Max_latency_ns': utils.safe_cast(max_latency, int, 0)
+ }
+
+ if port_subs_stats:
+ samples[port_name].update(
+ {'sessions_up': int(port_subs_stats[0]['Sessions_Up']),
+ 'sessions_down': int(port_subs_stats[0]['Sessions_Down']),
+ 'sessions_not_started': int(port_subs_stats[0]['Sessions_Not_Started']),
+ 'sessions_total': int(port_subs_stats[0]['Sessions_Total'])}
+ )
+
+ except IndexError:
+ pass
+
+ return samples
+
class IxiaRfc2544Helper(Rfc2544ResourceHelper):
@@ -474,9 +671,6 @@ class IxiaResourceHelper(ClientResourceHelper):
def _connect(self, client=None):
self.client.connect(self.vnfd_helper)
- def get_stats(self, *args, **kwargs):
- return self.client.get_statistics()
-
def setup(self):
super(IxiaResourceHelper, self).setup()
self._init_ix_scenario()
@@ -486,36 +680,7 @@ class IxiaResourceHelper(ClientResourceHelper):
self._terminated.value = 1
def generate_samples(self, ports, duration):
- stats = self.get_stats()
-
- samples = {}
- # this is not DPDK port num, but this is whatever number we gave
- # when we selected ports and programmed the profile
- for port_num in ports:
- try:
- # reverse lookup port name from port_num so the stats dict is descriptive
- intf = self.vnfd_helper.find_interface_by_port(port_num)
- port_name = intf['name']
- avg_latency = stats['Store-Forward_Avg_latency_ns'][port_num]
- min_latency = stats['Store-Forward_Min_latency_ns'][port_num]
- max_latency = stats['Store-Forward_Max_latency_ns'][port_num]
- samples[port_name] = {
- 'rx_throughput_kps': float(stats['Rx_Rate_Kbps'][port_num]),
- 'tx_throughput_kps': float(stats['Tx_Rate_Kbps'][port_num]),
- 'rx_throughput_mbps': float(stats['Rx_Rate_Mbps'][port_num]),
- 'tx_throughput_mbps': float(stats['Tx_Rate_Mbps'][port_num]),
- 'in_packets': int(stats['Valid_Frames_Rx'][port_num]),
- 'out_packets': int(stats['Frames_Tx'][port_num]),
- 'RxThroughput': float(stats['Valid_Frames_Rx'][port_num]) / duration,
- 'TxThroughput': float(stats['Frames_Tx'][port_num]) / duration,
- 'Store-Forward_Avg_latency_ns': utils.safe_cast(avg_latency, int, 0),
- 'Store-Forward_Min_latency_ns': utils.safe_cast(min_latency, int, 0),
- 'Store-Forward_Max_latency_ns': utils.safe_cast(max_latency, int, 0)
- }
- except IndexError:
- pass
-
- return samples
+ return self._ix_scenario.generate_samples(self, ports, duration)
def _init_ix_scenario(self):
ixia_config = self.scenario_helper.scenario_cfg.get('ixia_config', 'IxiaBasic')
@@ -536,6 +701,9 @@ class IxiaResourceHelper(ClientResourceHelper):
self._ix_scenario.apply_config()
self._ix_scenario.create_traffic_model(traffic_profile)
+ def update_tracking_options(self):
+ self._ix_scenario.update_tracking_options()
+
def run_traffic(self, traffic_profile):
if self._terminated.value:
return
@@ -570,12 +738,13 @@ class IxiaResourceHelper(ClientResourceHelper):
# pylint: disable=unnecessary-lambda
utils.wait_until_true(lambda: self.client.is_traffic_stopped(),
timeout=traffic_profile.config.duration * 2)
+ rfc2544_opts = self._ix_scenario.get_tc_rfc2544_options()
samples = self.generate_samples(traffic_profile.ports,
traffic_profile.config.duration)
completed, samples = traffic_profile.get_drop_percentage(
samples, min_tol, max_tol, precision, resolution,
- first_run=first_run)
+ first_run=first_run, tc_rfc2544_opts=rfc2544_opts)
self._queue.put(samples)
if completed:
diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py
index 8ad35aa51..304d05564 100644
--- a/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py
+++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py
@@ -640,6 +640,14 @@ class TestNetworkServiceTestCase(unittest.TestCase):
self.assertEqual({'imix': {'64B': 100}},
self.s._get_traffic_imix())
+ def test__get_ip_priority(self):
+ with mock.patch.dict(self.scenario_cfg["options"],
+ {'priority': {'raw': '0x01'}}):
+ self.assertEqual({'raw': '0x01'}, self.s._get_ip_priority())
+
+ def test__get_ip_priority_exception(self):
+ self.assertEqual({}, self.s._get_ip_priority())
+
@mock.patch.object(base.TrafficProfile, 'get')
@mock.patch.object(vnfdgen, 'generate_vnfd')
def test__fill_traffic_profile(self, mock_generate, mock_tprofile_get):
@@ -656,6 +664,7 @@ class TestNetworkServiceTestCase(unittest.TestCase):
'extra_args': {'arg1': 'value1', 'arg2': 'value2'},
'flow': {'flow': {}},
'imix': {'imix': {'64B': 100}},
+ 'priority': {},
'uplink': {},
'duration': 30,
'simulated_users': {
diff --git a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
index 110224742..38ca26b08 100644
--- a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
+++ b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
@@ -15,8 +15,10 @@
import mock
import IxNetwork
import unittest
+import re
from copy import deepcopy
+from collections import OrderedDict
from yardstick.common import exceptions
from yardstick.network_services.libs.ixia_libs.ixnet import ixnet_api
@@ -633,9 +635,9 @@ class TestIxNextgen(unittest.TestCase):
mock.call(self.ixnet_gen.FLOW_STATISTICS,
self.ixnet_gen.LATENCY_NAME_MAP)])
- def test__set_flow_tracking(self):
+ def test_set_flow_tracking(self):
self.ixnet_gen._ixnet.getList.return_value = ['traffic_item']
- self.ixnet_gen._set_flow_tracking(track_by=['vlanVlanId0'])
+ self.ixnet_gen.set_flow_tracking(track_by=['vlanVlanId0'])
self.ixnet_gen.ixnet.setAttribute.assert_called_once_with(
'traffic_item/tracking', '-trackBy', ['vlanVlanId0'])
self.assertEqual(self.ixnet.commit.call_count, 1)
@@ -653,17 +655,77 @@ class TestIxNextgen(unittest.TestCase):
'encapsulation', '-offset', 'IPv4 TOS Precedence')
self.assertEqual(self.ixnet.commit.call_count, 2)
- def test_get_pppoe_scenario_statistics(self):
- with mock.patch.object(self.ixnet_gen, '_build_stats_map') as \
- mock_build_stats:
- self.ixnet_gen.get_pppoe_scenario_statistics()
-
- mock_build_stats.assert_any_call(self.ixnet_gen.PORT_STATISTICS,
- self.ixnet_gen.PORT_STATS_NAME_MAP)
- mock_build_stats.assert_any_call(self.ixnet_gen.FLOW_STATISTICS,
- self.ixnet_gen.LATENCY_NAME_MAP)
- mock_build_stats.assert_any_call(self.ixnet_gen.PPPOX_CLIENT_PER_PORT,
- self.ixnet_gen.PPPOX_CLIENT_PER_PORT_NAME_MAP)
+ def test__get_view_page_stats(self):
+ expected_stats = [
+ {'header1': 'row1_1', 'header2': 'row1_2'},
+ {'header1': 'row2_1', 'header2': 'row2_2'}
+ ]
+ self.ixnet_gen._ixnet.getAttribute.side_effect = [
+ ['header1', 'header2'],
+ [
+ [['row1_1', 'row1_2']],
+ [['row2_1', 'row2_2']]
+ ]
+ ]
+ stats = self.ixnet_gen._get_view_page_stats('view_obj')
+ self.assertListEqual(stats, expected_stats)
+
+ @mock.patch.object(ixnet_api.IxNextgen, '_get_view_page_stats')
+ def test_get_pppoe_scenario_statistics(self, mock_get_view):
+
+ pattern = re.compile('Flow 2')
+
+ expected_stats = {
+ 'port_statistics': [{
+ 'port_1': 'port_stat1',
+ 'port_2': 'port_stat2'
+ }],
+ 'flow_statistic': [{
+ 'flow_1': 'flow_stat1',
+ 'flow_2': 'flow_stat2'
+ }],
+ 'pppox_client_per_port': [{
+ 'sub_1': 'sub_stat1',
+ 'sub_2': 'sub_stat2'
+ }]
+ }
+
+ pppoe_scenario_stats = OrderedDict([
+ ('port_statistics', 'view_obj'),
+ ('flow_statistic', 'view_obj'),
+ ('pppox_client_per_port', 'view_obj')
+ ])
+
+ pppoe_scenario_stats_map = {
+ 'port_statistics': {'port_1': 'Port 1',
+ 'port_2': 'Port 2'},
+ 'flow_statistic': {'flow_1': 'Flow 1',
+ 'flow_2': pattern},
+ 'pppox_client_per_port': {'sub_1': 'Sub 1',
+ 'sub_2': 'Sub 2'}
+ }
+
+ # All stats keys
+ port_stats = [{'Port 1': 'port_stat1',
+ 'Port 2': 'port_stat2',
+ 'Port 3': 'port_stat3'}]
+ flows_stats = [{'Flow 1': 'flow_stat1',
+ 'Flow 2': 'flow_stat2',
+ 'Flow 3': 'flow_stat3'}]
+ pppoe_sub_stats = [{'Sub 1': 'sub_stat1',
+ 'Sub 2': 'sub_stat2',
+ 'Sub 3': 'sub_stat3'}]
+
+ mock_get_view.side_effect = [port_stats, flows_stats, pppoe_sub_stats]
+ self.ixnet_gen._ixnet.getAttribute.return_value = '1'
+
+ with mock.patch.multiple(ixnet_api.IxNextgen,
+ PPPOE_SCENARIO_STATS=pppoe_scenario_stats,
+ PPPOE_SCENARIO_STATS_MAP=pppoe_scenario_stats_map):
+ stats = self.ixnet_gen.get_pppoe_scenario_statistics()
+ self.assertDictEqual(stats, expected_stats)
+ self.assertEqual(self.ixnet_gen.ixnet.getAttribute.call_count, 6)
+ self.ixnet_gen.ixnet.setAttribute.assert_not_called()
def test__update_ipv4_address(self):
with mock.patch.object(self.ixnet_gen, '_get_field_in_stack_item',
diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py
index 3d12dddcf..a71a240a2 100644
--- a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py
+++ b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py
@@ -487,7 +487,9 @@ class TestIXIARFC2544Profile(unittest.TestCase):
result = r_f_c2544_profile._get_ixia_traffic_profile({})
self.assertDictEqual(result, expected)
- def test__ixia_traffic_generate(self):
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544Profile,
+ '_update_traffic_tracking_options')
+ def test__ixia_traffic_generate(self, mock_upd_tracking_opts):
traffic_generator = mock.Mock(
autospec=trex_traffic_profile.TrexProfile)
traffic_generator.networks = {
@@ -502,8 +504,16 @@ class TestIXIARFC2544Profile(unittest.TestCase):
r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile(
self.TRAFFIC_PROFILE)
r_f_c2544_profile.rate = 100
- result = r_f_c2544_profile._ixia_traffic_generate(traffic, ixia_obj)
+ result = r_f_c2544_profile._ixia_traffic_generate(traffic, ixia_obj,
+ traffic_generator)
self.assertIsNone(result)
+ mock_upd_tracking_opts.assert_called_once_with(traffic_generator)
+
+ def test__update_traffic_tracking_options(self):
+ mock_traffic_gen = mock.Mock()
+ rfc2544_profile = ixia_rfc2544.IXIARFC2544Profile(self.TRAFFIC_PROFILE)
+ rfc2544_profile._update_traffic_tracking_options(mock_traffic_gen)
+ mock_traffic_gen.update_tracking_options.assert_called_once()
def test_execute_traffic_first_run(self):
rfc2544_profile = ixia_rfc2544.IXIARFC2544Profile(self.TRAFFIC_PROFILE)
@@ -741,6 +751,7 @@ class TestIXIARFC2544PppoeScenarioProfile(unittest.TestCase):
def setUp(self):
self.ixia_tp = ixia_rfc2544.IXIARFC2544PppoeScenarioProfile(
self.TRAFFIC_PROFILE)
+ self.ixia_tp._get_next_rate = mock.Mock(return_value=0.1)
def test___init__(self):
self.assertIsInstance(self.ixia_tp.full_profile,
@@ -755,3 +766,180 @@ class TestIXIARFC2544PppoeScenarioProfile(unittest.TestCase):
self.ixia_tp._get_flow_groups_params()
self.assertDictEqual(self.ixia_tp.full_profile, expected_tp)
+
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544PppoeScenarioProfile,
+ '_get_flow_groups_params')
+ def test_update_traffic_profile(self, mock_get_flow_groups_params):
+ networks = {
+ 'uplink_0': 'data1',
+ 'downlink_0': 'data2',
+ 'uplink_1': 'data3',
+ 'downlink_1': 'data4'
+ }
+ ports = ['xe0', 'xe1', 'xe2', 'xe3']
+ mock_traffic_gen = mock.Mock()
+ mock_traffic_gen.networks = networks
+ mock_traffic_gen.vnfd_helper.port_num.side_effect = ports
+ self.ixia_tp.update_traffic_profile(mock_traffic_gen)
+ mock_get_flow_groups_params.assert_called_once()
+ self.assertEqual(self.ixia_tp.ports, ports)
+
+ def test__get_prio_flows_drop_percentage(self):
+
+ input_stats = {
+ '0': {
+ 'in_packets': 50,
+ 'out_packets': 100,
+ 'Store-Forward_Avg_latency_ns': 10,
+ 'Store-Forward_Min_latency_ns': 10,
+ 'Store-Forward_Max_latency_ns': 10}}
+
+ result = self.ixia_tp._get_prio_flows_drop_percentage(input_stats)
+ self.assertIsNotNone(result['0'].get('DropPercentage'))
+ self.assertEqual(result['0'].get('DropPercentage'), 50.0)
+
+ def test__get_prio_flows_drop_percentage_traffic_not_flowing(self):
+ input_stats = {
+ '0': {
+ 'in_packets': 0,
+ 'out_packets': 0,
+ 'Store-Forward_Avg_latency_ns': 0,
+ 'Store-Forward_Min_latency_ns': 0,
+ 'Store-Forward_Max_latency_ns': 0}}
+
+ result = self.ixia_tp._get_prio_flows_drop_percentage(input_stats)
+ self.assertIsNotNone(result['0'].get('DropPercentage'))
+ self.assertEqual(result['0'].get('DropPercentage'), 100)
+
+ def test__get_summary_pppoe_subs_counters(self):
+ input_stats = {
+ 'xe0': {
+ 'out_packets': 100,
+ 'sessions_up': 4,
+ 'sessions_down': 0,
+ 'sessions_not_started': 0,
+ 'sessions_total': 4},
+ 'xe1': {
+ 'out_packets': 100,
+ 'sessions_up': 4,
+ 'sessions_down': 0,
+ 'sessions_not_started': 0,
+ 'sessions_total': 4}
+ }
+
+ expected_stats = {
+ 'sessions_up': 8,
+ 'sessions_down': 0,
+ 'sessions_not_started': 0,
+ 'sessions_total': 8
+ }
+
+ res = self.ixia_tp._get_summary_pppoe_subs_counters(input_stats)
+ self.assertDictEqual(res, expected_stats)
+
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544PppoeScenarioProfile,
+ '_get_prio_flows_drop_percentage')
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544PppoeScenarioProfile,
+ '_get_summary_pppoe_subs_counters')
+ def test_get_drop_percentage(self, mock_get_pppoe_subs,
+ mock_sum_prio_drop_rate):
+ samples = {
+ 'priority_stats': {
+ '0': {
+ 'in_packets': 100,
+ 'out_packets': 100,
+ 'Store-Forward_Avg_latency_ns': 10,
+ 'Store-Forward_Min_latency_ns': 10,
+ 'Store-Forward_Max_latency_ns': 10}},
+ 'xe0': {
+ 'in_packets': 100,
+ 'out_packets': 100,
+ 'Store-Forward_Avg_latency_ns': 10,
+ 'Store-Forward_Min_latency_ns': 10,
+ 'Store-Forward_Max_latency_ns': 10}}
+
+ mock_get_pppoe_subs.return_value = {'sessions_up': 1}
+ mock_sum_prio_drop_rate.return_value = {'0': {'DropPercentage': 0.0}}
+
+ status, res = self.ixia_tp.get_drop_percentage(
+ samples, tol_min=0.0, tolerance=0.0001, precision=0,
+ resolution=0.1, first_run=True)
+ self.assertIsNotNone(res.get('DropPercentage'))
+ self.assertIsNotNone(res.get('priority'))
+ self.assertIsNotNone(res.get('sessions_up'))
+ self.assertEqual(res['DropPercentage'], 0.0)
+ self.assertTrue(status)
+ mock_sum_prio_drop_rate.assert_called_once()
+ mock_get_pppoe_subs.assert_called_once()
+
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544PppoeScenarioProfile,
+ '_get_prio_flows_drop_percentage')
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544PppoeScenarioProfile,
+ '_get_summary_pppoe_subs_counters')
+ def test_get_drop_percentage_failed_status(self, mock_get_pppoe_subs,
+ mock_sum_prio_drop_rate):
+ samples = {
+ 'priority_stats': {
+ '0': {
+ 'in_packets': 90,
+ 'out_packets': 100,
+ 'Store-Forward_Avg_latency_ns': 10,
+ 'Store-Forward_Min_latency_ns': 10,
+ 'Store-Forward_Max_latency_ns': 10}},
+ 'xe0': {
+ 'in_packets': 90,
+ 'out_packets': 100,
+ 'Store-Forward_Avg_latency_ns': 10,
+ 'Store-Forward_Min_latency_ns': 10,
+ 'Store-Forward_Max_latency_ns': 10}}
+
+ mock_get_pppoe_subs.return_value = {'sessions_up': 1}
+ mock_sum_prio_drop_rate.return_value = {'0': {'DropPercentage': 0.0}}
+
+ status, res = self.ixia_tp.get_drop_percentage(
+ samples, tol_min=0.0, tolerance=0.0001, precision=0,
+ resolution=0.1, first_run=True)
+ self.assertIsNotNone(res.get('DropPercentage'))
+ self.assertIsNotNone(res.get('priority'))
+ self.assertIsNotNone(res.get('sessions_up'))
+ self.assertEqual(res['DropPercentage'], 10.0)
+ self.assertFalse(status)
+ mock_sum_prio_drop_rate.assert_called_once()
+ mock_get_pppoe_subs.assert_called_once()
+
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544PppoeScenarioProfile,
+ '_get_prio_flows_drop_percentage')
+ @mock.patch.object(ixia_rfc2544.IXIARFC2544PppoeScenarioProfile,
+ '_get_summary_pppoe_subs_counters')
+ def test_get_drop_percentage_priority_flow_check(self, mock_get_pppoe_subs,
+ mock_sum_prio_drop_rate):
+ samples = {
+ 'priority_stats': {
+ '0': {
+ 'in_packets': 100,
+ 'out_packets': 100,
+ 'Store-Forward_Avg_latency_ns': 10,
+ 'Store-Forward_Min_latency_ns': 10,
+ 'Store-Forward_Max_latency_ns': 10}},
+ 'xe0': {
+ 'in_packets': 90,
+ 'out_packets': 100,
+ 'Store-Forward_Avg_latency_ns': 10,
+ 'Store-Forward_Min_latency_ns': 10,
+ 'Store-Forward_Max_latency_ns': 10
+ }}
+
+ mock_get_pppoe_subs.return_value = {'sessions_up': 1}
+ mock_sum_prio_drop_rate.return_value = {'0': {'DropPercentage': 0.0}}
+
+ tc_rfc2544_opts = {'priority': '0',
+ 'allowed_drop_rate': '0.0001 - 0.0001'}
+ status, res = self.ixia_tp.get_drop_percentage(
+ samples, tol_min=15.0000, tolerance=15.0001, precision=0,
+ resolution=0.1, first_run=True, tc_rfc2544_opts=tc_rfc2544_opts)
+ self.assertIsNotNone(res.get('DropPercentage'))
+ self.assertIsNotNone(res.get('priority'))
+ self.assertIsNotNone(res.get('sessions_up'))
+ self.assertTrue(status)
+ mock_sum_prio_drop_rate.assert_called_once()
+ mock_get_pppoe_subs.assert_called_once()
diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py
index a8f697d4d..9db8b7b00 100644
--- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py
+++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py
@@ -491,6 +491,22 @@ class TestIXIATrafficGen(unittest.TestCase):
class TestIxiaBasicScenario(unittest.TestCase):
+
+ STATS = {'stat_name': ['Card01/Port01',
+ 'Card02/Port02'],
+ 'port_name': ['Ethernet - 001', 'Ethernet - 002'],
+ 'Frames_Tx': ['150', '150'],
+ 'Valid_Frames_Rx': ['150', '150'],
+ 'Frames_Tx_Rate': ['0.0', '0.0'],
+ 'Valid_Frames_Rx_Rate': ['0.0', '0.0'],
+ 'Tx_Rate_Kbps': ['0.0', '0.0'],
+ 'Rx_Rate_Mbps': ['0.0', '0.0'],
+ 'Tx_Rate_Mbps': ['0.0', '0.0'],
+ 'Rx_Rate_Kbps': ['0.0', '0.0'],
+ 'Store-Forward_Max_latency_ns': ['100', '200'],
+ 'Store-Forward_Min_latency_ns': ['100', '200'],
+ 'Store-Forward_Avg_latency_ns': ['100', '200']}
+
def setUp(self):
self._mock_IxNextgen = mock.patch.object(ixnet_api, 'IxNextgen')
self.mock_IxNextgen = self._mock_IxNextgen.start()
@@ -523,6 +539,48 @@ class TestIxiaBasicScenario(unittest.TestCase):
def test_stop_protocols(self):
self.assertIsNone(self.scenario.stop_protocols())
+ def test__get_stats(self):
+ self.scenario._get_stats()
+ self.scenario.client.get_statistics.assert_called_once()
+
+ @mock.patch.object(tg_rfc2544_ixia.IxiaBasicScenario, '_get_stats')
+ def test_generate_samples(self, mock_get_stats):
+
+ expected_samples = {'xe0': {
+ 'in_packets': 150,
+ 'out_packets': 150,
+ 'rx_throughput_mbps': 0.0,
+ 'rx_throughput_kps': 0.0,
+ 'RxThroughput': 5.0,
+ 'TxThroughput': 5.0,
+ 'tx_throughput_mbps': 0.0,
+ 'tx_throughput_kps': 0.0,
+ 'Store-Forward_Max_latency_ns': 100,
+ 'Store-Forward_Min_latency_ns': 100,
+ 'Store-Forward_Avg_latency_ns': 100},
+ 'xe1': {
+ 'in_packets': 150,
+ 'out_packets': 150,
+ 'rx_throughput_mbps': 0.0,
+ 'rx_throughput_kps': 0.0,
+ 'RxThroughput': 5.0,
+ 'TxThroughput': 5.0,
+ 'tx_throughput_mbps': 0.0,
+ 'tx_throughput_kps': 0.0,
+ 'Store-Forward_Max_latency_ns': 200,
+ 'Store-Forward_Min_latency_ns': 200,
+ 'Store-Forward_Avg_latency_ns': 200}}
+
+ res_helper = mock.Mock()
+ res_helper.vnfd_helper.find_interface_by_port.side_effect = \
+ [{'name': 'xe0'}, {'name': 'xe1'}]
+ ports = [0, 1]
+ duration = 30
+ mock_get_stats.return_value = self.STATS
+ samples = self.scenario.generate_samples(res_helper, ports, duration)
+ mock_get_stats.assert_called_once()
+ self.assertEqual(samples, expected_samples)
+
class TestIxiaL3Scenario(TestIxiaBasicScenario):
IXIA_CFG = {
@@ -632,6 +690,9 @@ class TestIxiaPppoeClientScenario(unittest.TestCase):
'gateway_ip': ['10.1.1.1', '10.2.2.1'],
'ip': ['10.1.1.1', '10.2.2.1'],
'prefix': ['24', '24']
+ },
+ 'priority': {
+ 'tos': {'precedence': [0, 4]}
}
}
@@ -696,6 +757,30 @@ class TestIxiaPppoeClientScenario(unittest.TestCase):
self.scenario.client.create_ipv4_traffic_model.assert_called_once_with(
uplink_endpoints, downlink_endpoints)
+ @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
+ '_get_endpoints_src_dst_id_pairs')
+ @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
+ '_get_endpoints_src_dst_obj_pairs')
+ def test_create_traffic_model_topology_based_flows(self, mock_obj_pairs,
+ mock_id_pairs):
+ uplink_topologies = ['topology1', 'topology3']
+ downlink_topologies = ['topology2', 'topology4']
+ mock_id_pairs.return_value = []
+ mock_obj_pairs.return_value = []
+ mock_tp = mock.Mock()
+ mock_tp.full_profile = {'uplink_0': 'data',
+ 'downlink_0': 'data',
+ 'uplink_1': 'data',
+ 'downlink_1': 'data'
+ }
+ self.scenario._access_topologies = ['topology1', 'topology3']
+ self.scenario._core_topologies = ['topology2', 'topology4']
+ self.scenario.create_traffic_model(mock_tp)
+ mock_id_pairs.assert_called_once_with(mock_tp.full_profile)
+ mock_obj_pairs.assert_called_once_with([])
+ self.scenario.client.create_ipv4_traffic_model.assert_called_once_with(
+ uplink_topologies, downlink_topologies)
+
def test__get_endpoints_src_dst_id_pairs(self):
full_tp = OrderedDict([
('uplink_0', {'ipv4': {'port': 'xe0'}}),
@@ -765,22 +850,10 @@ class TestIxiaPppoeClientScenario(unittest.TestCase):
}
}
- expected_result = ['tp1_dg1', 'tp3_dg1', 'tp1_dg2', 'tp3_dg1',
- 'tp1_dg3', 'tp3_dg1', 'tp1_dg4', 'tp3_dg1',
- 'tp2_dg1', 'tp4_dg1', 'tp2_dg2', 'tp4_dg1',
- 'tp2_dg3', 'tp4_dg1', 'tp2_dg4', 'tp4_dg1']
-
self.scenario._ixia_cfg = ixia_cfg
- self.scenario._access_topologies = ['topology1', 'topology2']
- self.scenario._core_topologies = ['topology3', 'topology4']
- self.mock_IxNextgen.get_topology_device_groups.side_effect = \
- [['tp1_dg1', 'tp1_dg2', 'tp1_dg3', 'tp1_dg4'],
- ['tp2_dg1', 'tp2_dg2', 'tp2_dg3', 'tp2_dg4'],
- ['tp3_dg1'],
- ['tp4_dg1']]
res = self.scenario._get_endpoints_src_dst_obj_pairs(
endpoints_id_pairs)
- self.assertEqual(res, expected_result)
+ self.assertEqual(res, [])
def test_run_protocols(self):
self.scenario.client.is_protocols_running.return_value = True
@@ -1017,3 +1090,161 @@ class TestIxiaPppoeClientScenario(unittest.TestCase):
local_as=bgp_params["bgp"]["as_number"],
bgp_type=bgp_params["bgp"]["bgp_type"])
])
+
+ def test_update_tracking_options_raw_priority(self):
+ raw_priority = {'raw': 4}
+ self.scenario._ixia_cfg['priority'] = raw_priority
+ self.scenario.update_tracking_options()
+ self.scenario.client.set_flow_tracking.assert_called_once_with(
+ ['flowGroup0', 'vlanVlanId0', 'ipv4Raw0'])
+
+ def test_update_tracking_options_tos_priority(self):
+ tos_priority = {'tos': {'precedence': [4, 7]}}
+ self.scenario._ixia_cfg['priority'] = tos_priority
+ self.scenario.update_tracking_options()
+ self.scenario.client.set_flow_tracking.assert_called_once_with(
+ ['flowGroup0', 'vlanVlanId0', 'ipv4Precedence0'])
+
+ def test_update_tracking_options_dscp_priority(self):
+ dscp_priority = {'dscp': {'defaultPHB': [4, 7]}}
+ self.scenario._ixia_cfg['priority'] = dscp_priority
+ self.scenario.update_tracking_options()
+ self.scenario.client.set_flow_tracking.assert_called_once_with(
+ ['flowGroup0', 'vlanVlanId0', 'ipv4DefaultPhb0'])
+
+ def test_update_tracking_options_invalid_priority_data(self):
+ invalid_priority = {'tos': {'inet-precedence': [4, 7]}}
+ self.scenario._ixia_cfg['priority'] = invalid_priority
+ self.scenario.update_tracking_options()
+ self.scenario.client.set_flow_tracking.assert_called_once_with(
+ ['flowGroup0', 'vlanVlanId0', 'ipv4Precedence0'])
+
+ def test_get_tc_rfc2544_options(self):
+ rfc2544_tc_opts = {'allowed_drop_rate': '0.0001 - 0.0001'}
+ self.scenario._ixia_cfg['rfc2544'] = rfc2544_tc_opts
+ res = self.scenario.get_tc_rfc2544_options()
+ self.assertEqual(res, rfc2544_tc_opts)
+
+ def test__get_stats(self):
+ self.scenario._get_stats()
+ self.scenario.client.get_pppoe_scenario_statistics.assert_called_once()
+
+ def test_get_flow_id_data(self):
+ stats = [{'id': 1, 'in_packets': 10, 'out_packets': 20}]
+ key = "in_packets"
+ flow_id = 1
+ res = self.scenario.get_flow_id_data(stats, flow_id, key)
+ self.assertEqual(res, 10)
+
+ @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario, '_get_stats')
+ @mock.patch.object(tg_rfc2544_ixia.IxiaPppoeClientScenario,
+ 'get_priority_flows_stats')
+ def test_generate_samples(self, mock_prio_flow_statistics,
+ mock_get_stats):
+ ixia_stats = {
+ 'flow_statistic': [
+ {'Flow_Group': 'RFC2544-1 - Flow Group 0001',
+ 'Frames_Delta': '0',
+ 'IP_Priority': '0',
+ 'Rx_Frames': '3000',
+ 'Tx_Frames': '3000',
+ 'VLAN-ID': '100',
+ 'Tx_Port': 'Ethernet - 001',
+ 'Store-Forward_Avg_latency_ns': '2',
+ 'Store-Forward_Min_latency_ns': '2',
+ 'Store-Forward_Max_latency_ns': '2'},
+ {'Flow_Group': 'RFC2544-2 - Flow Group 0001',
+ 'Frames_Delta': '0',
+ 'IP_Priority': '0',
+ 'Rx_Frames': '3000',
+ 'Tx_Frames': '3000',
+ 'VLAN-ID': '101',
+ 'Tx_Port': 'Ethernet - 002',
+ 'Store-Forward_Avg_latency_ns': '2',
+ 'Store-Forward_Min_latency_ns': '2',
+ 'Store-Forward_Max_latency_ns': '2'
+ }],
+ 'port_statistics': [
+ {'Frames_Tx': '3000',
+ 'Valid_Frames_Rx': '3000',
+ 'Rx_Rate_Kbps': '0.0',
+ 'Tx_Rate_Kbps': '0.0',
+ 'Rx_Rate_Mbps': '0.0',
+ 'Tx_Rate_Mbps': '0.0',
+ 'port_name': 'Ethernet - 001'},
+ {'Frames_Tx': '3000',
+ 'Valid_Frames_Rx': '3000',
+ 'Rx_Rate_Kbps': '0.0',
+ 'Tx_Rate_Kbps': '0.0',
+ 'Rx_Rate_Mbps': '0.0',
+ 'Tx_Rate_Mbps': '0.0',
+ 'port_name': 'Ethernet - 002'}],
+ 'pppox_client_per_port': [
+ {'Sessions_Down': '0',
+ 'Sessions_Not_Started': '0',
+ 'Sessions_Total': '1',
+ 'Sessions_Up': '1',
+ 'subs_port': 'Ethernet - 001'}]}
+
+ prio_flows_stats = {
+ '0': {
+ 'in_packets': 6000,
+ 'out_packets': 6000,
+ 'RxThroughput': 200.0,
+ 'TxThroughput': 200.0,
+ 'avg_latency_ns': 2,
+ 'max_latency_ns': 2,
+ 'min_latency_ns': 2
+ }
+ }
+
+ expected_result = {'priority_stats': {
+ '0': {'RxThroughput': 200.0,
+ 'TxThroughput': 200.0,
+ 'avg_latency_ns': 2,
+ 'max_latency_ns': 2,
+ 'min_latency_ns': 2,
+ 'in_packets': 6000,
+ 'out_packets': 6000}},
+ 'xe0': {'RxThroughput': 100.0,
+ 'Store-Forward_Avg_latency_ns': 2,
+ 'Store-Forward_Max_latency_ns': 2,
+ 'Store-Forward_Min_latency_ns': 2,
+ 'TxThroughput': 100.0,
+ 'in_packets': 3000,
+ 'out_packets': 3000,
+ 'rx_throughput_kps': 0.0,
+ 'rx_throughput_mbps': 0.0,
+ 'sessions_down': 0,
+ 'sessions_not_started': 0,
+ 'sessions_total': 1,
+ 'sessions_up': 1,
+ 'tx_throughput_kps': 0.0,
+ 'tx_throughput_mbps': 0.0},
+ 'xe1': {'RxThroughput': 100.0,
+ 'Store-Forward_Avg_latency_ns': 2,
+ 'Store-Forward_Max_latency_ns': 2,
+ 'Store-Forward_Min_latency_ns': 2,
+ 'TxThroughput': 100.0,
+ 'in_packets': 3000,
+ 'out_packets': 3000,
+ 'rx_throughput_kps': 0.0,
+ 'rx_throughput_mbps': 0.0,
+ 'tx_throughput_kps': 0.0,
+ 'tx_throughput_mbps': 0.0}}
+
+ mock_get_stats.return_value = ixia_stats
+ mock_prio_flow_statistics.return_value = prio_flows_stats
+ ports = [0, 1]
+ port_names = [{'name': 'xe0'}, {'name': 'xe1'}]
+ duration = 30
+ res_helper = mock.Mock()
+ res_helper.vnfd_helper.find_interface_by_port.side_effect = \
+ port_names
+ samples = self.scenario.generate_samples(res_helper, ports, duration)
+ self.assertIsNotNone(samples)
+ self.assertIsNotNone(samples.get('xe0'))
+ self.assertIsNotNone(samples.get('xe1'))
+ self.assertEqual(samples, expected_result)
+ mock_get_stats.assert_called_once()
+ mock_prio_flow_statistics.assert_called_once()