summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--requirements.txt2
-rw-r--r--tools/confgenwizard/__init__.py0
-rw-r--r--tools/confgenwizard/nicinfo.py236
-rw-r--r--tools/confgenwizard/vsperfwiz.py736
-rw-r--r--tools/pkt_gen/testcenter/testcenter.py6
5 files changed, 978 insertions, 2 deletions
diff --git a/requirements.txt b/requirements.txt
index cb5a0d89..03049fdb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -20,3 +20,5 @@ matplotlib==2.2.2
numpy
pycrypto
tabulate
+pypsi
+paramiko
diff --git a/tools/confgenwizard/__init__.py b/tools/confgenwizard/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tools/confgenwizard/__init__.py
diff --git a/tools/confgenwizard/nicinfo.py b/tools/confgenwizard/nicinfo.py
new file mode 100644
index 00000000..631b92c5
--- /dev/null
+++ b/tools/confgenwizard/nicinfo.py
@@ -0,0 +1,236 @@
+# Copyright 2019-2020 Spirent Communications.
+#
+# 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.
+
+"""
+Retrieve information from remote host.
+In this file, we retrive only NIC PICs
+"""
+
+from __future__ import print_function
+import sys
+import subprocess
+import os
+from os.path import exists
+from stat import S_ISDIR
+import paramiko
+
+# The PCI device class for ETHERNET devices
+ETHERNET_CLASS = "0200"
+LSPCI_PATH = '/usr/bin/lspci'
+RECV_BYTES = 4096
+ADVANCED = True
+
+
+#pylint: disable=too-many-instance-attributes
+class RemoteInfo(object):
+ """
+ Class to extract information from a remote system
+ """
+
+ def __init__(self, host, username, password):
+ """
+ Perform Initialization
+ """
+ # Dict of ethernet devices present. Dictionary indexed by PCI address.
+ # Each device within this is itself a dictionary of device properties
+ self.nic_devices = {}
+ if host == 'local':
+ self.local = True
+ else:
+ self.local = False
+ # Assuming port as 22.
+ self.port = 22
+ self.hostname = host
+ self.password = password
+ self.username = username
+ self.client = paramiko.Transport((self.hostname, self.port))
+ self.client.connect(username=self.username,
+ password=self.password)
+ self.session = self.client.open_channel(kind='session')
+ self.session.get_pty()
+ self.sftp = paramiko.SFTPClient.from_transport(self.client)
+
+ def sftp_exists(self, path):
+ """
+ Check if remote file exist
+ """
+ try:
+ self.sftp.stat(path)
+ return True
+ except IOError:
+ return False
+
+ def sft_listdir(self, path):
+ """
+ List directories on remote nost
+ """
+ files = []
+ for fil in self.sftp.listdir_attr(path):
+ if not S_ISDIR(fil.st_mode):
+ files.append(fil.filename)
+ return files
+
+ def is_connected(self):
+ """
+ Check if session is connected.
+ """
+ return self.client.is_active()
+
+ def new_channel(self):
+ """
+ FOr every command a new session is setup
+ """
+ if not self.is_connected():
+ self.client = paramiko.Transport((self.hostname, self.port))
+ self.client.connect(username=self.username,
+ password=self.password)
+ self.session = self.client.open_channel(kind='session')
+
+ # This is roughly compatible with check_output function in subprocess module
+ # which is only available in python 2.7.
+ def check_output(self, args, stderr=None):
+ '''
+ Run a command and capture its output
+ '''
+ stdout_data = []
+ stderr_data = []
+ if self.local:
+ return subprocess.Popen(args, stdout=subprocess.PIPE,
+ stderr=stderr,
+ universal_newlines=True).communicate()[0]
+ else:
+ self.new_channel()
+ separator = ' '
+ command = separator.join(args)
+ # self.session.get_pty()
+ self.session.exec_command(command)
+ while True:
+ if self.session.recv_ready():
+ stdout_data.append(self.session.recv(RECV_BYTES))
+ if self.session.recv_stderr_ready():
+ stderr_data.append(self.session.recv_stderr(RECV_BYTES))
+ if self.session.exit_status_ready():
+ break
+ if stdout_data:
+ return b"".join(stdout_data)
+ return b"".join(stderr_data)
+
+ def get_pci_details(self, dev_id):
+ '''
+ This function gets additional details for a PCI device
+ '''
+ device = {}
+
+ extra_info = self.check_output([LSPCI_PATH,
+ "-vmmks", dev_id]).splitlines()
+
+ # parse lspci details
+ for line in extra_info:
+ if not line:
+ continue
+ if self.local:
+ name, value = line.split("\t", 1)
+ else:
+ name, value = line.decode().split("\t", 1)
+ name = name.strip(":") + "_str"
+ device[name] = value
+ # check for a unix interface name
+ sys_path = "/sys/bus/pci/devices/%s/net/" % dev_id
+ device["Interface"] = ""
+ if self.local:
+ if exists(sys_path):
+ device["Interface"] = ",".join(os.listdir(sys_path))
+ else:
+ if self.sftp_exists(sys_path):
+ device["Interface"] = ",".join(self.sft_listdir(sys_path))
+
+ # check if a port is used for ssh connection
+ device["Ssh_if"] = False
+ device["Active"] = ""
+
+ return device
+
+ def get_nic_details(self):
+ '''
+ This function populates the "devices" dictionary. The keys used are
+ the pci addresses (domain:bus:slot.func). The values are themselves
+ dictionaries - one for each NIC.
+ '''
+ devinfos = []
+ # first loop through and read details for all devices
+ # request machine readable format, with numeric IDs
+ dev = {}
+ dev_lines = self.check_output([LSPCI_PATH, "-Dvmmn"]).splitlines()
+ for dev_line in dev_lines:
+ if not dev_line:
+ if dev["Class"] == ETHERNET_CLASS:
+ # convert device and vendor ids to numbers, then add to
+ # global
+ dev["Vendor"] = int(dev["Vendor"], 16)
+ dev["Device"] = int(dev["Device"], 16)
+ self.nic_devices[dev["Slot"]] = dict(
+ dev) # use dict to make copy of dev
+ else:
+ # values = re.split(r'\t+', str(dev_line))
+ if self.local:
+ name, value = dev_line.split('\t', 1)
+ else:
+ name, value = dev_line.decode().split("\t", 1)
+ dev[name.rstrip(":")] = value
+
+ # based on the basic info, get extended text details
+ for dev in self.nic_devices:
+ # get additional info and add it to existing data
+ if ADVANCED:
+ self.nic_devices[dev].update(self.get_pci_details(dev).items())
+ devinfos.append(self.nic_devices[dev])
+ return devinfos
+
+ def dev_id_from_dev_name(self, dev_name):
+ '''
+ Take a device "name" - a string passed in by user to identify a NIC
+ device, and determine the device id - i.e. the domain:bus:slot.func-for
+ it, which can then be used to index into the devices array
+ '''
+ # dev = None
+ # check if it's already a suitable index
+ if dev_name in self.nic_devices:
+ return dev_name
+ # check if it's an index just missing the domain part
+ elif "0000:" + dev_name in self.nic_devices:
+ return "0000:" + dev_name
+ else:
+ # check if it's an interface name, e.g. eth1
+ for dev in self.nic_devices:
+ if dev_name in self.nic_devices[dev]["Interface"].split(","):
+ return self.nic_devices[dev]["Slot"]
+ # if nothing else matches - error
+ print("Unknown device: %s. "
+ "Please specify device in \"bus:slot.func\" format" % dev_name)
+ sys.exit(1)
+
+
+def main():
+ '''program main function'''
+ host = input("Enter Host IP: ")
+ username = input("Enter User Name: ")
+ pwd = input("Enter Password: ")
+ rhi = RemoteInfo(host, username, pwd)
+ dev_list = rhi.get_nic_details()
+ for dev in dev_list:
+ print(dev["Slot"])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/confgenwizard/vsperfwiz.py b/tools/confgenwizard/vsperfwiz.py
new file mode 100644
index 00000000..48a2d504
--- /dev/null
+++ b/tools/confgenwizard/vsperfwiz.py
@@ -0,0 +1,736 @@
+# Copyright 2019-2020 Spirent Communications.
+#
+# 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.
+
+"""
+Tool to create configuration file for VSPERF
+"""
+
+from __future__ import print_function
+import signal
+import sys
+from pypsi import wizard as wiz
+from pypsi.shell import Shell
+import nicinfo
+
+
+#pylint: disable=too-many-instance-attributes
+class VsperfWizard(object):
+ """
+ Class to create wizards
+ """
+
+ def __init__(self):
+ """
+ Perform Initialization.
+ """
+ self.shell = Shell()
+ self.vpp_values = {}
+ self.dut_values = {}
+ self.main_values = {}
+ self.guest_values = {}
+ self.ovs_values = {}
+ self.ixnet_values = {}
+ self.stc_values = {}
+ self.trex_values = {}
+ self.traffic_values = {}
+ self.vpp_values = {}
+ self.wiz_dut = None
+ self.wiz_ixnet = None
+ self.wiz_stc = None
+ self.wiz_ovs = None
+ self.wiz_traffic = None
+ self.wiz_main = None
+ self.wiz_guest = None
+ self.wiz_trex = None
+ self.wiz_vpp = None
+ self.rhi = None
+ self.devices = ''
+ self.devs = {}
+
+
+
+######## Support Functions ############################
+ def get_nicpcis(self):
+ """
+ Get NIC information from Remote Host
+ """
+ self.rhi = nicinfo.RemoteInfo(self.dut_values['dutip'],
+ self.dut_values['dutuname'],
+ self.dut_values['dutpwd'])
+ dev_list = self.rhi.get_nic_details()
+ index = 0
+ for dev in dev_list:
+ self.devices += str("(" + str(index) + ")" + " "
+ + str(dev["Slot"]) + ', ')
+ self.devs[str(index)] = str(dev["Slot"])
+ index = index + 1
+
+ def get_nics_string(self):
+ """
+ Create string that's acceptable to configuration
+ """
+ indexes = self.main_values['nics'].split(',')
+ wlns = ''
+ for index in indexes:
+ wlns += "'" + self.devs[index] + "' ,"
+ print(wlns)
+ return wlns.rstrip(',')
+
+
+############# All the Wizards ##################################
+
+ def dut_wizard(self):
+ """
+ Wizard to collect DUT information
+ """
+ self.wiz_dut = wiz.PromptWizard(
+ name="VSPERF DUT Info Collection",
+ description="This collects DUT info",
+ steps=(
+ # The list of input prompts to ask the user.
+ wiz.WizardStep(
+ # ID where the value will be stored
+ id="dutip",
+ # Display name
+ name="Enter the IP address of the DUT [local]",
+ # Help message
+ help="IP address of the DUT host",
+ # List of validators to run on the input
+ validators=(wiz.required_validator)
+ ),
+ wiz.WizardStep(
+ # ID where the value will be stored
+ id="dutuname",
+ # Display name
+ name="Enter the username to connect to DUT",
+ # Help message
+ help="Username for DUT host",
+ # List of validators to run on the input
+ validators=(wiz.required_validator)
+ ),
+ wiz.WizardStep(
+ # ID where the value will be stored
+ id="dutpwd",
+ # Display name
+ name="Enter the Password to connect to DUT",
+ # Help message
+ help="Password for the DUT host",
+ # List of validators to run on the input
+ validators=(wiz.required_validator)
+ ),
+ )
+ )
+
+ def main_wizard(self):
+ """
+ The Main Wizard
+ """
+ # First get the nics.
+ self.get_nicpcis()
+ self.wiz_main = wiz.PromptWizard(
+ name="VSPERF Common Configuration",
+ description="This configuration covers Basic inputs",
+ steps=(
+ # The list of input prompts to ask the user.
+ wiz.WizardStep(
+ # ID where the value will be stored
+ id="vswitch",
+ # Display name
+ name="VSwitch to use? - OVS or VPP?",
+ # Help message
+ help=" Enter the vswitch to use - either OVS or VPP",
+ # List of validators to run on the input
+ default='OVS'
+ ),
+ wiz.WizardStep(
+ id='nics',
+ name="NICs to Whitelist: " + self.devices,
+ help="Enter the list (separated by comma) of PCI-IDs",
+ validators=(wiz.required_validator),
+ ),
+ wiz.WizardStep(
+ id='tgen',
+ name=("What trafficgen to use: [TestCenter" +
+ " IxNet, Moongen, Trex]?"),
+ help=("Enter the trafficgen to use -" +
+ " TestCenter, IxNet, Moongen, Trex"),
+ validators=(wiz.required_validator),
+ default="Trex"
+ ),
+ wiz.WizardStep(
+ id='guest',
+ name=("Is Scenario either PVP or PVVP?"),
+ help=("This is ti capture guest Configuration"),
+ validators=(wiz.required_validator),
+ default="YES"
+ )
+ )
+ )
+
+ def traffic_wizard(self):
+ """
+ Wizard to collectd Traffic Info.
+ """
+ self.wiz_traffic = wiz.PromptWizard(
+ name="Traffic Configuration",
+ description="This configuration covers Traffic specifc inputs",
+ steps=(
+ wiz.WizardStep(
+ id='pktsizes',
+ name='Enter the Packet Sizes - comma separated',
+ help="Allowed values: (64,128,256,512,1024,1280,1518)",
+ validators=(wiz.required_validator)
+ ),
+ wiz.WizardStep(
+ id='duration',
+ name='Enter the Duration (in secs) for the traffic',
+ help="Enter for how long each iteration should be",
+ default='60',
+ ),
+ # wiz.WizardStep(
+ # id='multistream',
+ # name='Multistream preferred?',
+ # help="Multistream preference - Yes or No",
+ # default='No',
+ # validators=(wiz.required_validator)
+ #),
+ wiz.WizardStep(
+ id='count',
+ name='Number of flows?',
+ help="Enter the number of flows - 2 - 1,000,000",
+ default='2',
+ # validators=(wiz.required_validator)
+ ),
+ )
+ )
+
+ def ovs_wizard(self):
+ """
+ Wizard to collect OVS Information
+ """
+ self.wiz_ovs = wiz.PromptWizard(
+ name="Vswitch Configuration",
+ description="Specific configurations of the virtual-Switch",
+ steps=(
+ wiz.WizardStep(
+ id='type',
+ name='OVS Type? [Vanilla or DPDK]',
+ help='Enter either Vanilla or DPDK',
+ default='Vanilla',
+ ),
+ wiz.WizardStep(
+ id='mask',
+ name='Enter the CPU Mask for OVS to use',
+ help='Mask for OVS PMDs',
+ default='30',
+ ),
+ )
+ )
+
+ def vpp_wizard(self):
+ """
+ Wizard to collect VPP configuration
+ """
+ self.wiz_vpp = wiz.PromptWizard(
+ name="Vswitch Configuration",
+ description="Specific configurations of the virtual-Switch",
+ steps=(
+ wiz.WizardStep(
+ id='mode',
+ name='L2 Connection mode xconnect|bridge|l2patch to use?',
+ help='Select the l2 connection mode',
+ default='xconnect',
+ ),
+ )
+ )
+
+ def trex_wizard(self):
+ """
+ Wizard to collect Trex configuration
+ """
+ self.wiz_trex = wiz.PromptWizard(
+ name="Trex Traffic Generator Configuration",
+ description="Specific configurations of Trex TGen",
+ steps=(
+ wiz.WizardStep(
+ id='hostip',
+ name='What is IP address of the T-Rex Host?',
+ help='Enter the IP address of host where Trex is running',
+ validators=(wiz.required_validator)
+ ),
+ wiz.WizardStep(
+ id='user',
+ name='What is Usernameof the T-Rex Host?',
+ help='Enter the Username of host where Trex is running',
+ default='root',
+ ),
+ wiz.WizardStep(
+ id='bdir',
+ name='What is Dir where the T-Rex Binary resides?',
+ help='Enter the Location where Trex Binary is',
+ default='/root/trex_2.37/scripts/',
+ ),
+ wiz.WizardStep(
+ id='pci1',
+ name='What is PCI address of the port-1?',
+ help='Enter the PCI address of Data port 1',
+ validators=(wiz.required_validator)
+ ),
+ wiz.WizardStep(
+ id='pci2',
+ name='What is PCI address of the port-2?',
+ help='Enter the PCI address of Data port 2',
+ validators=(wiz.required_validator)
+ ),
+ wiz.WizardStep(
+ id='rate',
+ name='What is Line rate (in Gbps) of the ports?',
+ help='Enter the linerate of the ports',
+ default='10',
+ ),
+ wiz.WizardStep(
+ id='prom',
+ name='T-Rex Promiscuous enabled?',
+ help='Do you want to enable the Promiscuous mode?',
+ default='False',
+ ),
+ wiz.WizardStep(
+ id='lat',
+ name='Whats the Trex Latency PPS?',
+ help='Enter the Latency value in PPS',
+ default='1000',
+ ),
+ wiz.WizardStep(
+ id='bslv',
+ name='Do you want Binary Loss Verification Enabled?',
+ help='Enter True if you want it to be enabled.',
+ default='True',
+ ),
+ wiz.WizardStep(
+ id='maxrep',
+ name='If Loss Verification, what the max rep?',
+ help='If BSLV is enabled, whats the max repetition value?',
+ default='2',
+ ),
+ )
+ )
+
+ def stc_wizard(self):
+ """
+ Wizard to collect STC configuration
+ """
+ self.wiz_stc = wiz.PromptWizard(
+ name="Spirent STC Traffic Generator Configuration",
+ description="Specific configurations of Spirent-STC TGen",
+ steps=(
+ wiz.WizardStep(
+ id='lab',
+ name='Lab Server IP?',
+ help='Enter the IP of Lab Server',
+ default='10.10.120.244',
+ ),
+ wiz.WizardStep(
+ id='lisc',
+ name='License Server IP?',
+ help='Enter the IP of the License Server',
+ default='10.10.120.246',
+ ),
+ wiz.WizardStep(
+ id='eaddr',
+ name='East Port Chassis Address?',
+ help='IP address of the East-Port',
+ default='10.10.120.245',
+ ),
+ wiz.WizardStep(
+ id='eslot',
+ name='East Port Slot Number',
+ help='Slot Number of the East Port',
+ default='1',
+ ),
+ wiz.WizardStep(
+ id='eport',
+ name='Port Number of the East-Port',
+ help='Port Number for the East Port',
+ default='1',
+ ),
+ wiz.WizardStep(
+ id='eint',
+ name='East port Interface Address',
+ help='IP to use for East Port?',
+ default='192.85.1.3',
+ ),
+ wiz.WizardStep(
+ id='egw',
+ name='Gateway Address for East Port',
+ help='IP of the East-Port Gateway',
+ default='192.85.1.103',
+ ),
+ wiz.WizardStep(
+ id='waddr',
+ name='West Port Chassis Address?',
+ help='IP address of the West-Port',
+ default='10.10.120.245',
+ ),
+ wiz.WizardStep(
+ id='wslot',
+ name='West Port Slot Number',
+ help='Slot Number of the West Port',
+ default='1',
+ ),
+ wiz.WizardStep(
+ id='wport',
+ name='Port Number of the West-Port',
+ help='Port Number for the West Port',
+ default='2',
+ ),
+ wiz.WizardStep(
+ id='wint',
+ name='West port Interface Address',
+ help='IP to use for West Port?',
+ default='192.85.1.103',
+ ),
+ wiz.WizardStep(
+ id='wgw',
+ name='Gateway Address for West Port',
+ help='IP of the West-Port Gateway',
+ default='192.85.1.3',
+ ),
+ wiz.WizardStep(
+ id='script',
+ name='Name of the Script to use for RFC2544 Tests?',
+ help='Script Name to use for RFC 2544 Tests.',
+ default='testcenter-rfc2544-rest.py',
+ ),
+ )
+ )
+
+ def ixnet_wizard(self):
+ """
+ Wizard to collect ixnet configuration
+ """
+ self.wiz_ixnet = wiz.PromptWizard(
+ name="Ixia IxNet Traffic Generator Configuration",
+ description="Specific configurations of Ixia-Ixnet TGen",
+ steps=(
+ wiz.WizardStep(
+ id='card',
+ name='Card Number?',
+ help='Chassis Card Number',
+ default='1',
+ ),
+ wiz.WizardStep(
+ id='port1',
+ name='Port-1 Number?',
+ help='Chassis Port-1 Number',
+ default='5',
+ ),
+ wiz.WizardStep(
+ id='port2',
+ name='Port-2 Number?',
+ help='Chassis Port-2 Number',
+ default='6',
+ ),
+ wiz.WizardStep(
+ id='libp1',
+ name='IXIA Library path?',
+ help='Library path of Ixia',
+ default='/opt/ixnet/ixos-api/8.01.0.2/lib/ixTcl1.0',
+ ),
+ wiz.WizardStep(
+ id='libp2',
+ name='IXNET Library Path',
+ help='Library Path for the IXNET',
+ default='/opt/ixnet/ixnetwork/8.01.1029.6/lib/IxTclNetwork',
+ ),
+ wiz.WizardStep(
+ id='host',
+ name='IP of the CHassis?',
+ help='Chassis IP',
+ default='10.10.50.6',
+ ),
+ wiz.WizardStep(
+ id='machine',
+ name='IP of the API Server?',
+ help='API Server IP ',
+ default='10.10.120.6',
+ ),
+ wiz.WizardStep(
+ id='port',
+ name='Port of the API Server?',
+ help='API Server Port',
+ default='9127',
+ ),
+ wiz.WizardStep(
+ id='user',
+ name='Username for the API server?',
+ help='Username to use to connect to API Server',
+ default='vsperf_sandbox',
+ ),
+ wiz.WizardStep(
+ id='tdir',
+ name='Path for Results Directory on API Server',
+ help='Results Path on API Server',
+ default='c:/ixia_results/vsperf_sandbox',
+ ),
+ wiz.WizardStep(
+ id='rdir',
+ name='Path for Results directory on DUT',
+ help='DUT Results Path',
+ default='/mnt/ixia_results/vsperf_sandbox',
+ ),
+ )
+ )
+
+ def guest_wizard(self):
+ """
+ Wizard to collect guest configuration
+ """
+ self.wiz_guest = wiz.PromptWizard(
+ name="Guest Configuration for PVP and PVVP Scenarios",
+ description="Guest configurations",
+ steps=(
+ wiz.WizardStep(
+ id='image',
+ name='Enter the Path for the iamge',
+ help='Complete path where image resides',
+ default='/home/opnfv/vloop-vnf-ubuntu-14.04_20160823.qcow2',
+ ),
+ wiz.WizardStep(
+ id='mode',
+ name='Enter the forwarding mode to use',
+ help='one of io|mac|mac_retry|macswap|flowgen|rxonly|....',
+ default='io',
+ ),
+ wiz.WizardStep(
+ id='smp',
+ name='Number of SMP to use?',
+ help='While Spawning the guest, how many SMPs to use?',
+ default='2',
+ ),
+ wiz.WizardStep(
+ id='cores',
+ name="Guest Core binding. For 2 cores a & b: ['a', 'b']",
+ help='Enter the cores to use in the specified format',
+ default="['8', '9']",
+ ),
+ )
+ )
+
+############### All the Run Operations ######################
+
+ def run_dutwiz(self):
+ """
+ Run the DUT wizard
+ """
+ self.dut_wizard()
+ self.dut_values = self.wiz_dut.run(self.shell)
+
+ def run_mainwiz(self):
+ """
+ Run the Main wizard
+ """
+ self.main_wizard()
+ self.main_values = self.wiz_main.run(self.shell)
+ print(self.main_values['nics'])
+
+ def run_vswitchwiz(self):
+ """
+ Run the vSwitch wizard
+ """
+ if self.main_values['vswitch'] == "OVS":
+ self.ovs_wizard()
+ self.ovs_values = self.wiz_ovs.run(self.shell)
+ elif self.main_values['vswitch'] == 'VPP':
+ self.vpp_wizard()
+ self.vpp_values = self.wiz_vpp.run(self.shell)
+
+ def run_trafficwiz(self):
+ """
+ Run the Traffic wizard
+ """
+ self.traffic_wizard()
+ self.traffic_values = self.wiz_traffic.run(self.shell)
+
+ def run_tgenwiz(self):
+ """
+ Run the Tgen wizard
+ """
+ if self.main_values['tgen'] == "Trex":
+ self.trex_wizard()
+ self.trex_values = self.wiz_trex.run(self.shell)
+ elif self.main_values['tgen'] == "TestCenter":
+ self.stc_wizard()
+ self.stc_values = self.wiz_stc.run(self.shell)
+ elif self.main_values['tgen'] == 'IxNet':
+ self.ixnet_wizard()
+ self.ixnet_values = self.wiz_ixnet.run(self.shell)
+
+ def run_guestwiz(self):
+ """
+ Run the Guest wizard
+ """
+ if self.main_values['guest'] == 'YES':
+ self.guest_wizard()
+ self.guest_values = self.wiz_guest.run(self.shell)
+
+################ Prepare Configuration File ##################
+ #pylint: disable=too-many-statements
+ def prepare_conffile(self):
+ """
+ Create the Configuration file that can be used with VSPERF
+ """
+ with open("./vsperf.conf", 'w+') as ofile:
+ ofile.write("#### This file is Automatically Created ####\n\n")
+ if self.main_values['vswitch'] == "OVS":
+ if self.ovs_values['type'] == "Vanilla":
+ ofile.write("VSWITCH = 'OvsVanilla'\n")
+ else:
+ ofile.write("VSWITCH = 'OvsDpdkVhost'\n")
+ ofile.write("VSWITCH_PMD_CPU_MASK = '" +
+ self.ovs_values['mask'] + "'\n")
+ else:
+ ofile.write("VSWITCH = 'VppDpdkVhost'\n")
+ ofile.write("VSWITCH_VPP_L2_CONNECT_MODE = '" +
+ self.vpp_values['mode'] + "'\n")
+ nics = self.get_nics_string()
+ wln = "WHITELIST_NICS = [" + nics + "]" + "\n"
+ ofile.write(wln)
+ ofile.write("RTE_TARGET = 'x86_64-native-linuxapp-gcc'")
+ ofile.write("\n")
+ ofile.write("TRAFFICGEN = " + "'" + self.main_values['tgen'] + "'")
+ ofile.write("\n")
+ ofile.write("VSWITCH_BRIDGE_NAME = 'vsperf-br0'")
+ ofile.write("\n")
+ ofile.write("TRAFFICGEN_DURATION = " +
+ self.traffic_values['duration'] + "\n")
+ ofile.write("TRAFFICGEN_LOSSRATE = 0" + "\n")
+ ofile.write("TRAFFICGEN_PKT_SIZES = (" +
+ self.traffic_values['pktsizes'] +
+ ")" + "\n")
+ if self.main_values['tgen'] == "Trex":
+ ofile.write("TRAFFICGEN_TREX_HOST_IP_ADDR = '" +
+ self.trex_values['hostip'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_TREX_USER = '" +
+ self.trex_values['user'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_TREX_BASE_DIR = '" +
+ self.trex_values['bdir'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_TREX_LINE_SPEED_GBPS = '" +
+ self.trex_values['rate'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_TREX_PORT1 = '" +
+ self.trex_values['pci1'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_TREX_PORT2 = '" +
+ self.trex_values['pci2'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_TREX_PROMISCUOUS = " +
+ self.trex_values['prom'] + "\n")
+ ofile.write("TRAFFICGEN_TREX_LATENCY_PPS = " +
+ self.trex_values['lat'] + "\n")
+ ofile.write("TRAFFICGEN_TREX_RFC2544_BINARY_SEARCH_LOSS_VERIFICATION = " +
+ self.trex_values['bslv'])
+ ofile.write("TRAFFICGEN_TREX_MAX_REPEAT = " +
+ self.trex_values['maxrep'] + "\n")
+ elif self.main_values['tgen'] == "TestCenter":
+ ofile.write("TRAFFICGEN_STC_LAB_SERVER_ADDR = '" +
+ self.stc_values['lab'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_LICENSE_SERVER_ADDR = '" +
+ self.stc_values['lisc'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_EAST_CHASSIS_ADDR = '" +
+ self.stc_values['eaddr'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_EAST_SLOT_NUM = '" +
+ self.stc_values['eslot'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_EAST_PORT_NUM = '" +
+ self.stc_values['eport'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_EAST_INTF_ADDR = '" +
+ self.stc_values['eint'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_EAST_INTF_GATEWAY_ADDR = '" +
+ self.stc_values['egw'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_WEST_CHASSIS_ADDR = '" +
+ self.stc_values['waddr'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_WEST_SLOT_NUM = '" +
+ self.stc_values['wslot'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_WEST_PORT_NUM = '" +
+ self.stc_values['wport'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_WEST_INTF_ADDR = '" +
+ self.stc_values['wint'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_WEST_INTF_GATEWAY_ADDR = '" +
+ self.stc_values['wgw'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_STC_RFC2544_TPUT_TEST_FILE_NAME = '" +
+ self.stc_values['script'] + "'" + "\n")
+ elif self.main_values['tgen'] == 'IxNet':
+ print("IXIA Trafficgen")
+ # Ixia/IxNet configuration
+ ofile.write("TRAFFICGEN_IXIA_CARD = '" +
+ self.ixnet_values['card'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXIA_PORT1 = '" +
+ self.ixnet_values['port1'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXIA_PORT2 = '" +
+ self.ixnet_values['port2'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXIA_LIB_PATH = '" +
+ self.ixnet_values['libp1'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXNET_LIB_PATH = '" +
+ self.ixnet_values['libp2'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXIA_HOST = '" +
+ self.ixnet_values['host'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXNET_MACHINE = '" +
+ self.ixnet_values['machine'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXNET_PORT = '" +
+ self.ixnet_values['port'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXNET_USER = '" +
+ self.ixnet_values['user'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXNET_TESTER_RESULT_DIR = '" +
+ self.ixnet_values['tdir'] + "'" + "\n")
+ ofile.write("TRAFFICGEN_IXNET_DUT_RESULT_DIR = '" +
+ self.ixnet_values['rdir'] + "'" + "\n")
+ if self.main_values['guest'] == 'YES':
+ ofile.write("GUEST_IMAGE = ['" +
+ self.guest_values['image'] + "']" + "\n")
+ ofile.write("GUEST_TESTPMD_FWD_MODE = ['" +
+ self.guest_values['mode'] + "']" + "\n")
+ ofile.write("GUEST_SMP = ['" +
+ self.guest_values['smp'] + "']" + "\n")
+ ofile.write("GUEST_CORE_BINDING = [" +
+ self.guest_values['cores'] + ",]" + "\n")
+
+
+def signal_handler(signum, frame):
+ """
+ Signal Handler
+ """
+ print("\n You interrupted, No File will be generated!")
+ print(signum, frame)
+ sys.exit(0)
+
+
+def main():
+ """
+ The Main Function
+ """
+ try:
+ vwiz = VsperfWizard()
+ vwiz.run_dutwiz()
+ vwiz.run_mainwiz()
+ vwiz.run_vswitchwiz()
+ vwiz.run_trafficwiz()
+ vwiz.run_tgenwiz()
+ vwiz.run_guestwiz()
+ vwiz.prepare_conffile()
+ except (KeyboardInterrupt, MemoryError):
+ print("Some Error Occured, No file will be generated!")
+
+ print("Thanks for using the VSPERF-WIZARD, Please look for vsperf.conf " +
+ "file in the current folder")
+
+
+if __name__ == "__main__":
+ signal.signal(signal.SIGINT, signal_handler)
+ main()
diff --git a/tools/pkt_gen/testcenter/testcenter.py b/tools/pkt_gen/testcenter/testcenter.py
index f01069e2..73967bae 100644
--- a/tools/pkt_gen/testcenter/testcenter.py
+++ b/tools/pkt_gen/testcenter/testcenter.py
@@ -436,11 +436,13 @@ class TestCenter(trafficgen.ITrafficGenerator):
if traffic['imix']['enabled']:
if traffic['imix']['type'] == 'genome':
genome = traffic['imix']['genome']
- args.append('--imix' + ' ' + genome)
+ args.append('--imix')
+ args.append(genome)
if settings.getValue("TRAFFICGEN_STC_LIVE_RESULTS") == "True":
args.append('--live_results')
- args.append('--logfile' + ' ' + self._liveresults_file)
+ args.append('--logfile')
+ args.append(self._liveresults_file)
if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
args.append("--verbose")