aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dashboard/opnfv_yardstick_tc056.json301
-rw-r--r--yardstick/benchmark/contexts/standalone/model.py52
-rw-r--r--yardstick/benchmark/contexts/standalone/ovs_dpdk.py206
-rw-r--r--yardstick/benchmark/contexts/standalone/sriov.py56
-rw-r--r--yardstick/common/exceptions.py30
-rw-r--r--yardstick/tests/unit/benchmark/contexts/standalone/test_model.py337
-rw-r--r--yardstick/tests/unit/benchmark/contexts/standalone/test_ovs_dpdk.py238
-rw-r--r--yardstick/tests/unit/benchmark/contexts/standalone/test_sriov.py80
8 files changed, 912 insertions, 388 deletions
diff --git a/dashboard/opnfv_yardstick_tc056.json b/dashboard/opnfv_yardstick_tc056.json
new file mode 100644
index 000000000..5d7f2b013
--- /dev/null
+++ b/dashboard/opnfv_yardstick_tc056.json
@@ -0,0 +1,301 @@
+{
+ "__inputs": [
+ {
+ "name": "DS_YARDSTICK",
+ "label": "yardstick",
+ "description": "",
+ "type": "datasource",
+ "pluginId": "influxdb",
+ "pluginName": "InfluxDB"
+ }
+ ],
+ "__requires": [
+ {
+ "type": "grafana",
+ "id": "grafana",
+ "name": "Grafana",
+ "version": "4.4.3"
+ },
+ {
+ "type": "panel",
+ "id": "graph",
+ "name": "Graph",
+ "version": ""
+ },
+ {
+ "type": "datasource",
+ "id": "influxdb",
+ "name": "InfluxDB",
+ "version": "1.0.0"
+ },
+ {
+ "type": "panel",
+ "id": "singlestat",
+ "name": "Singlestat",
+ "version": ""
+ }
+ ],
+ "annotations": {
+ "list": []
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "id": null,
+ "links": [],
+ "refresh": "1m",
+ "rows": [
+ {
+ "collapse": false,
+ "height": 340,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "yardstick",
+ "description": "",
+ "fill": 1,
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": true,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "",
+ "dsType": "influxdb",
+ "groupBy": [],
+ "measurement": "opnfv_yardstick_tc056",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "query": "SELECT \"openstack-user-list_outage_time\" FROM \"opnfv_yardstick_tc056\" WHERE $timeFilter",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "openstack-volume-list_outage_time"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": []
+ }
+ ],
+ "thresholds": [
+ {
+ "colorMode": "critical",
+ "fill": true,
+ "line": true,
+ "op": "gt",
+ "value": 5
+ },
+ {
+ "colorMode": "ok",
+ "fill": true,
+ "line": true,
+ "op": "lt",
+ "value": 5
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "command monitor (outage time)",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": true,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "yardstick",
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 4,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "alias": "",
+ "dsType": "influxdb",
+ "groupBy": [],
+ "measurement": "opnfv_yardstick_tc056",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "query": "SELECT \"sla_pass\" FROM \"opnfv_yardstick_tc056\" WHERE $timeFilter",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "sla_pass"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": []
+ }
+ ],
+ "thresholds": "0.5,1",
+ "title": "SLA PASS/FAIL",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "avg"
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Dashboard Row",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "HA"
+ ],
+ "templating": {
+ "list": []
+ },
+ "time": {
+ "from": "now/d",
+ "to": "now/d"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "",
+ "title": "opnfv_yardstick_tc056",
+ "version": 2
+}
diff --git a/yardstick/benchmark/contexts/standalone/model.py b/yardstick/benchmark/contexts/standalone/model.py
index 14738da8a..f18d090d8 100644
--- a/yardstick/benchmark/contexts/standalone/model.py
+++ b/yardstick/benchmark/contexts/standalone/model.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from __future__ import absolute_import
import os
import re
import time
@@ -25,11 +24,12 @@ from netaddr import IPNetwork
import xml.etree.ElementTree as ET
from yardstick import ssh
-from yardstick.common.constants import YARDSTICK_ROOT_PATH
+from yardstick.common import constants
+from yardstick.common import exceptions
from yardstick.common.yaml_loader import yaml_load
from yardstick.network_services.utils import PciAddress
from yardstick.network_services.helpers.cpu import CpuSysCores
-from yardstick.common.utils import write_file
+
LOG = logging.getLogger(__name__)
@@ -106,12 +106,17 @@ class Libvirt(object):
@staticmethod
def virsh_create_vm(connection, cfg):
- err = connection.execute("virsh create %s" % cfg)[0]
- LOG.info("VM create status: %s", err)
+ LOG.info('VM create, XML config: %s', cfg)
+ status, _, error = connection.execute('virsh create %s' % cfg)
+ if status:
+ raise exceptions.LibvirtCreateError(error=error)
@staticmethod
def virsh_destroy_vm(vm_name, connection):
- connection.execute("virsh destroy %s" % vm_name)
+ LOG.info('VM destroy, VM name: %s', vm_name)
+ status, _, error = connection.execute('virsh destroy %s' % vm_name)
+ if status:
+ LOG.warning('Error destroying VM %s. Error: %s', vm_name, error)
@staticmethod
def _add_interface_address(interface, pci_address):
@@ -132,7 +137,7 @@ class Libvirt(object):
return vm_pci
@classmethod
- def add_ovs_interface(cls, vpath, port_num, vpci, vports_mac, xml):
+ def add_ovs_interface(cls, vpath, port_num, vpci, vports_mac, xml_str):
"""Add a DPDK OVS 'interface' XML node in 'devices' node
<devices>
@@ -156,7 +161,7 @@ class Libvirt(object):
vhost_path = ('{0}/var/run/openvswitch/dpdkvhostuser{1}'.
format(vpath, port_num))
- root = ET.parse(xml)
+ root = ET.fromstring(xml_str)
pci_address = PciAddress(vpci.strip())
device = root.find('devices')
@@ -181,10 +186,10 @@ class Libvirt(object):
cls._add_interface_address(interface, pci_address)
- root.write(xml)
+ return ET.tostring(root)
@classmethod
- def add_sriov_interfaces(cls, vm_pci, vf_pci, vf_mac, xml):
+ def add_sriov_interfaces(cls, vm_pci, vf_pci, vf_mac, xml_str):
"""Add a SR-IOV 'interface' XML node in 'devices' node
<devices>
@@ -207,7 +212,7 @@ class Libvirt(object):
-sr_iov-how_sr_iov_libvirt_works
"""
- root = ET.parse(xml)
+ root = ET.fromstring(xml_str)
device = root.find('devices')
interface = ET.SubElement(device, 'interface')
@@ -224,7 +229,7 @@ class Libvirt(object):
pci_vm_address = PciAddress(vm_pci.strip())
cls._add_interface_address(interface, pci_vm_address)
- root.write(xml)
+ return ET.tostring(root)
@staticmethod
def create_snapshot_qemu(connection, index, vm_image):
@@ -237,7 +242,8 @@ class Libvirt(object):
return image
@classmethod
- def build_vm_xml(cls, connection, flavor, cfg, vm_name, index):
+ def build_vm_xml(cls, connection, flavor, vm_name, index):
+ """Build the XML from the configuration parameters"""
memory = flavor.get('ram', '4096')
extra_spec = flavor.get('extra_specs', {})
cpu = extra_spec.get('hw:cpu_cores', '2')
@@ -261,9 +267,7 @@ class Libvirt(object):
socket=socket, threads=threads,
vm_image=image, cpuset=cpuset, cputune=cputune)
- write_file(cfg, vm_xml)
-
- return [vcpu, mac]
+ return vm_xml, mac
@staticmethod
def update_interrupts_hugepages_perf(connection):
@@ -283,6 +287,13 @@ class Libvirt(object):
cpuset = "%s,%s" % (cores, threads)
return cpuset
+ @classmethod
+ def write_file(cls, file_name, xml_str):
+ """Dump a XML string to a file"""
+ root = ET.fromstring(xml_str)
+ et = ET.ElementTree(element=root)
+ et.write(file_name, encoding='utf-8', method='xml')
+
class StandaloneContextHelper(object):
""" This class handles all the common code for standalone
@@ -374,7 +385,8 @@ class StandaloneContextHelper(object):
except IOError as io_error:
if io_error.errno != errno.ENOENT:
raise
- self.file_path = os.path.join(YARDSTICK_ROOT_PATH, file_path)
+ self.file_path = os.path.join(constants.YARDSTICK_ROOT_PATH,
+ file_path)
cfg = self.read_config_file()
nodes.extend([node for node in cfg["nodes"] if str(node["role"]) != nfvi_role])
@@ -506,7 +518,7 @@ class OvsDeploy(object):
StandaloneContextHelper.install_req_libs(self.connection, pkgs)
def ovs_deploy(self):
- ovs_deploy = os.path.join(YARDSTICK_ROOT_PATH,
+ ovs_deploy = os.path.join(constants.YARDSTICK_ROOT_PATH,
"yardstick/resources/scripts/install/",
self.OVS_DEPLOY_SCRIPT)
if os.path.isfile(ovs_deploy):
@@ -522,4 +534,6 @@ class OvsDeploy(object):
cmd = "sudo -E %s --ovs='%s' --dpdk='%s' -p='%s'" % (remote_ovs_deploy,
ovs, dpdk, http_proxy)
- self.connection.execute(cmd)
+ exit_status, _, stderr = self.connection.execute(cmd)
+ if exit_status:
+ raise exceptions.OVSDeployError(stderr=stderr)
diff --git a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py
index a18b42ea5..30b685eec 100644
--- a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py
+++ b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py
@@ -12,26 +12,24 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from __future__ import absolute_import
-import os
-import logging
+import io
import collections
+import logging
+import os
+import re
import time
-from collections import OrderedDict
-
from yardstick import ssh
-from yardstick.network_services.utils import get_nsb_option
-from yardstick.network_services.utils import provision_tool
from yardstick.benchmark.contexts.base import Context
-from yardstick.benchmark.contexts.standalone.model import Libvirt
-from yardstick.benchmark.contexts.standalone.model import StandaloneContextHelper
-from yardstick.benchmark.contexts.standalone.model import Server
-from yardstick.benchmark.contexts.standalone.model import OvsDeploy
-from yardstick.network_services.utils import PciAddress
+from yardstick.benchmark.contexts.standalone import model
+from yardstick.common import exceptions
+from yardstick.network_services import utils
+
LOG = logging.getLogger(__name__)
+MAIN_BRIDGE = 'br0'
+
class OvsDpdkContext(Context):
""" This class handles OVS standalone nodes - VM running on Non-Managed NFVi
@@ -50,8 +48,8 @@ class OvsDpdkContext(Context):
}
DEFAULT_OVS = '2.6.0'
-
- PKILL_TEMPLATE = "pkill %s %s"
+ CMD_TIMEOUT = 30
+ DEFAULT_USER_PATH = '/usr/local'
def __init__(self):
self.file_path = None
@@ -65,8 +63,8 @@ class OvsDpdkContext(Context):
self.attrs = {}
self.vm_flavor = None
self.servers = None
- self.helper = StandaloneContextHelper()
- self.vnf_node = Server()
+ self.helper = model.StandaloneContextHelper()
+ self.vnf_node = model.Server()
self.ovs_properties = {}
self.wait_for_vswitchd = 10
super(OvsDpdkContext, self).__init__()
@@ -93,34 +91,32 @@ class OvsDpdkContext(Context):
LOG.debug("Networks: %r", self.networks)
def setup_ovs(self):
- vpath = self.ovs_properties.get("vpath", "/usr/local")
- xargs_kill_cmd = self.PKILL_TEMPLATE % ('-9', 'ovs')
-
+ """Initialize OVS-DPDK"""
+ vpath = self.ovs_properties.get('vpath', self.DEFAULT_USER_PATH)
create_from = os.path.join(vpath, 'etc/openvswitch/conf.db')
create_to = os.path.join(vpath, 'share/openvswitch/vswitch.ovsschema')
cmd_list = [
- "chmod 0666 /dev/vfio/*",
- "chmod a+x /dev/vfio",
- "pkill -9 ovs",
- xargs_kill_cmd,
- "killall -r 'ovs*'",
- "mkdir -p {0}/etc/openvswitch".format(vpath),
- "mkdir -p {0}/var/run/openvswitch".format(vpath),
- "rm {0}/etc/openvswitch/conf.db".format(vpath),
- "ovsdb-tool create {0} {1}".format(create_from, create_to),
- "modprobe vfio-pci",
- "chmod a+x /dev/vfio",
- "chmod 0666 /dev/vfio/*",
+ 'killall -r "ovs.*" -q | true',
+ 'mkdir -p {0}/etc/openvswitch'.format(vpath),
+ 'mkdir -p {0}/var/run/openvswitch'.format(vpath),
+ 'rm {0}/etc/openvswitch/conf.db | true'.format(vpath),
+ 'ovsdb-tool create {0} {1}'.format(create_from, create_to),
+ 'modprobe vfio-pci',
+ 'chmod a+x /dev/vfio',
+ 'chmod 0666 /dev/vfio/*',
]
- for cmd in cmd_list:
- self.connection.execute(cmd)
- bind_cmd = "{dpdk_devbind} --force -b {driver} {port}"
- phy_driver = "vfio-pci"
+
+ bind_cmd = '%s --force -b vfio-pci {port}' % self.dpdk_devbind
for port in self.networks.values():
- vpci = port.get("phy_port")
- self.connection.execute(bind_cmd.format(
- dpdk_devbind=self.dpdk_devbind, driver=phy_driver, port=vpci))
+ cmd_list.append(bind_cmd.format(port=port.get('phy_port')))
+
+ for cmd in cmd_list:
+ LOG.info(cmd)
+ exit_status, _, stderr = self.connection.execute(
+ cmd, timeout=self.CMD_TIMEOUT)
+ if exit_status:
+ raise exceptions.OVSSetupError(command=cmd, error=stderr)
def start_ovs_serverswitch(self):
vpath = self.ovs_properties.get("vpath")
@@ -166,56 +162,78 @@ class OvsDpdkContext(Context):
vpath = self.ovs_properties.get("vpath", "/usr/local")
version = self.ovs_properties.get('version', {})
ovs_ver = [int(x) for x in version.get('ovs', self.DEFAULT_OVS).split('.')]
- ovs_add_port = \
- "ovs-vsctl add-port {br} {port} -- set Interface {port} type={type_}{dpdk_args}"
- ovs_add_queue = "ovs-vsctl set Interface {port} options:n_rxq={queue}"
- chmod_vpath = "chmod 0777 {0}/var/run/openvswitch/dpdkvhostuser*"
-
- cmd_dpdk_list = [
- "ovs-vsctl del-br br0",
- "rm -rf {0}/var/run/openvswitch/dpdkvhostuser*".format(vpath),
- "ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev",
+ ovs_add_port = ('ovs-vsctl add-port {br} {port} -- '
+ 'set Interface {port} type={type_}{dpdk_args}')
+ ovs_add_queue = 'ovs-vsctl set Interface {port} options:n_rxq={queue}'
+ chmod_vpath = 'chmod 0777 {0}/var/run/openvswitch/dpdkvhostuser*'
+
+ cmd_list = [
+ 'ovs-vsctl --if-exists del-br {0}'.format(MAIN_BRIDGE),
+ 'rm -rf {0}/var/run/openvswitch/dpdkvhostuser*'.format(vpath),
+ 'ovs-vsctl add-br {0} -- set bridge {0} datapath_type=netdev'.
+ format(MAIN_BRIDGE)
]
- ordered_network = OrderedDict(self.networks)
+ ordered_network = collections.OrderedDict(self.networks)
for index, vnf in enumerate(ordered_network.values()):
if ovs_ver >= [2, 7, 0]:
dpdk_args = " options:dpdk-devargs=%s" % vnf.get("phy_port")
- dpdk_list.append(ovs_add_port.format(br='br0', port='dpdk%s' % vnf.get("port_num", 0),
- type_='dpdk', dpdk_args=dpdk_args))
- dpdk_list.append(ovs_add_queue.format(port='dpdk%s' % vnf.get("port_num", 0),
- queue=self.ovs_properties.get("queues", 1)))
+ dpdk_list.append(ovs_add_port.format(
+ br=MAIN_BRIDGE, port='dpdk%s' % vnf.get("port_num", 0),
+ type_='dpdk', dpdk_args=dpdk_args))
+ dpdk_list.append(ovs_add_queue.format(
+ port='dpdk%s' % vnf.get("port_num", 0),
+ queue=self.ovs_properties.get("queues", 1)))
# Sorting the array to make sure we execute dpdk0... in the order
list.sort(dpdk_list)
- cmd_dpdk_list.extend(dpdk_list)
+ cmd_list.extend(dpdk_list)
# Need to do two for loop to maintain the dpdk/vhost ports.
for index, _ in enumerate(ordered_network):
- cmd_dpdk_list.append(ovs_add_port.format(br='br0', port='dpdkvhostuser%s' % index,
- type_='dpdkvhostuser', dpdk_args=""))
-
- for cmd in cmd_dpdk_list:
- LOG.info(cmd)
- self.connection.execute(cmd)
-
- # Fixme: add flows code
- ovs_flow = "ovs-ofctl add-flow br0 in_port=%s,action=output:%s"
+ cmd_list.append(ovs_add_port.format(
+ br=MAIN_BRIDGE, port='dpdkvhostuser%s' % index,
+ type_='dpdkvhostuser', dpdk_args=""))
+ ovs_flow = ("ovs-ofctl add-flow {0} in_port=%s,action=output:%s".
+ format(MAIN_BRIDGE))
network_count = len(ordered_network) + 1
for in_port, out_port in zip(range(1, network_count),
range(network_count, network_count * 2)):
- self.connection.execute(ovs_flow % (in_port, out_port))
- self.connection.execute(ovs_flow % (out_port, in_port))
+ cmd_list.append(ovs_flow % (in_port, out_port))
+ cmd_list.append(ovs_flow % (out_port, in_port))
- self.connection.execute(chmod_vpath.format(vpath))
+ cmd_list.append(chmod_vpath.format(vpath))
+
+ for cmd in cmd_list:
+ LOG.info(cmd)
+ exit_status, _, stderr = self.connection.execute(
+ cmd, timeout=self.CMD_TIMEOUT)
+ if exit_status:
+ raise exceptions.OVSSetupError(command=cmd, error=stderr)
+
+ def _check_hugepages(self):
+ meminfo = io.BytesIO()
+ self.connection.get_file_obj('/proc/meminfo', meminfo)
+ regex = re.compile(r"HugePages_Total:\s+(?P<hp_total>\d+)[\n\r]"
+ r"HugePages_Free:\s+(?P<hp_free>\d+)")
+ match = regex.search(meminfo.getvalue().decode('utf-8'))
+ if not match:
+ raise exceptions.OVSHugepagesInfoError()
+ if int(match.group('hp_total')) == 0:
+ raise exceptions.OVSHugepagesNotConfigured()
+ if int(match.group('hp_free')) == 0:
+ raise exceptions.OVSHugepagesZeroFree(
+ total_hugepages=int(match.group('hp_total')))
def cleanup_ovs_dpdk_env(self):
- self.connection.execute("ovs-vsctl del-br br0")
+ self.connection.execute(
+ 'ovs-vsctl --if-exists del-br {0}'.format(MAIN_BRIDGE))
self.connection.execute("pkill -9 ovs")
def check_ovs_dpdk_env(self):
self.cleanup_ovs_dpdk_env()
+ self._check_hugepages()
version = self.ovs_properties.get("version", {})
ovs_ver = version.get("ovs", self.DEFAULT_OVS)
@@ -223,13 +241,15 @@ class OvsDpdkContext(Context):
supported_version = self.SUPPORTED_OVS_TO_DPDK_MAP.get(ovs_ver, None)
if supported_version is None or supported_version.split('.')[:2] != dpdk_ver[:2]:
- raise Exception("Unsupported ovs '{}'. Please check the config...".format(ovs_ver))
+ raise exceptions.OVSUnsupportedVersion(
+ ovs_version=ovs_ver,
+ ovs_to_dpdk_map=self.SUPPORTED_OVS_TO_DPDK_MAP)
status = self.connection.execute("ovs-vsctl -V | grep -i '%s'" % ovs_ver)[0]
if status:
- deploy = OvsDeploy(self.connection,
- get_nsb_option("bin_path"),
- self.ovs_properties)
+ deploy = model.OvsDeploy(self.connection,
+ utils.get_nsb_option("bin_path"),
+ self.ovs_properties)
deploy.ovs_deploy()
def deploy(self):
@@ -240,15 +260,15 @@ class OvsDpdkContext(Context):
return
self.connection = ssh.SSH.from_node(self.host_mgmt)
- self.dpdk_devbind = provision_tool(
+ self.dpdk_devbind = utils.provision_tool(
self.connection,
- os.path.join(get_nsb_option("bin_path"), "dpdk-devbind.py"))
+ os.path.join(utils.get_nsb_option('bin_path'), 'dpdk-devbind.py'))
# Check dpdk/ovs version, if not present install
self.check_ovs_dpdk_env()
# Todo: NFVi deploy (sriov, vswitch, ovs etc) based on the config.
- StandaloneContextHelper.install_req_libs(self.connection)
- self.networks = StandaloneContextHelper.get_nic_details(
+ model.StandaloneContextHelper.install_req_libs(self.connection)
+ self.networks = model.StandaloneContextHelper.get_nic_details(
self.connection, self.networks, self.dpdk_devbind)
self.setup_ovs()
@@ -256,9 +276,8 @@ class OvsDpdkContext(Context):
self.setup_ovs_bridge_add_flows()
self.nodes = self.setup_ovs_dpdk_context()
LOG.debug("Waiting for VM to come up...")
- self.nodes = StandaloneContextHelper.wait_for_vnfs_to_start(self.connection,
- self.servers,
- self.nodes)
+ self.nodes = model.StandaloneContextHelper.wait_for_vnfs_to_start(
+ self.connection, self.servers, self.nodes)
def undeploy(self):
@@ -278,7 +297,7 @@ class OvsDpdkContext(Context):
# Todo: NFVi undeploy (sriov, vswitch, ovs etc) based on the config.
for vm in self.vm_names:
- Libvirt.check_if_vm_exists_and_delete(vm, self.connection)
+ model.Libvirt.check_if_vm_exists_and_delete(vm, self.connection)
def _get_server(self, attr_name):
"""lookup server info by name from context
@@ -333,50 +352,53 @@ class OvsDpdkContext(Context):
return result
def configure_nics_for_ovs_dpdk(self):
- portlist = OrderedDict(self.networks)
+ portlist = collections.OrderedDict(self.networks)
for key in portlist:
- mac = StandaloneContextHelper.get_mac_address()
+ mac = model.StandaloneContextHelper.get_mac_address()
portlist[key].update({'mac': mac})
self.networks = portlist
LOG.info("Ports %s", self.networks)
- def _enable_interfaces(self, index, vfs, cfg):
+ def _enable_interfaces(self, index, vfs, xml_str):
vpath = self.ovs_properties.get("vpath", "/usr/local")
vf = self.networks[vfs[0]]
port_num = vf.get('port_num', 0)
- vpci = PciAddress(vf['vpci'].strip())
+ vpci = utils.PciAddress(vf['vpci'].strip())
# Generate the vpci for the interfaces
slot = index + port_num + 10
vf['vpci'] = \
"{}:{}:{:02x}.{}".format(vpci.domain, vpci.bus, slot, vpci.function)
- Libvirt.add_ovs_interface(vpath, port_num, vf['vpci'], vf['mac'], str(cfg))
+ return model.Libvirt.add_ovs_interface(
+ vpath, port_num, vf['vpci'], vf['mac'], xml_str)
def setup_ovs_dpdk_context(self):
nodes = []
self.configure_nics_for_ovs_dpdk()
- for index, (key, vnf) in enumerate(OrderedDict(self.servers).items()):
+ for index, (key, vnf) in enumerate(collections.OrderedDict(
+ self.servers).items()):
cfg = '/tmp/vm_ovs_%d.xml' % index
vm_name = "vm_%d" % index
# 1. Check and delete VM if already exists
- Libvirt.check_if_vm_exists_and_delete(vm_name, self.connection)
+ model.Libvirt.check_if_vm_exists_and_delete(vm_name,
+ self.connection)
+ xml_str, mac = model.Libvirt.build_vm_xml(
+ self.connection, self.vm_flavor, vm_name, index)
- _, mac = Libvirt.build_vm_xml(self.connection, self.vm_flavor,
- cfg, vm_name, index)
# 2: Cleanup already available VMs
- for vkey, vfs in OrderedDict(vnf["network_ports"]).items():
- if vkey == "mgmt":
- continue
- self._enable_interfaces(index, vfs, cfg)
+ for vfs in [vfs for vfs_name, vfs in vnf["network_ports"].items()
+ if vfs_name != 'mgmt']:
+ xml_str = self._enable_interfaces(index, vfs, xml_str)
# copy xml to target...
+ model.Libvirt.write_file(cfg, xml_str)
self.connection.put(cfg, cfg)
# NOTE: launch through libvirt
LOG.info("virsh create ...")
- Libvirt.virsh_create_vm(self.connection, cfg)
+ model.Libvirt.virsh_create_vm(self.connection, cfg)
self.vm_names.append(vm_name)
diff --git a/yardstick/benchmark/contexts/standalone/sriov.py b/yardstick/benchmark/contexts/standalone/sriov.py
index d7620552b..5db419e6a 100644
--- a/yardstick/benchmark/contexts/standalone/sriov.py
+++ b/yardstick/benchmark/contexts/standalone/sriov.py
@@ -16,15 +16,12 @@ from __future__ import absolute_import
import os
import logging
import collections
-from collections import OrderedDict
from yardstick import ssh
from yardstick.network_services.utils import get_nsb_option
from yardstick.network_services.utils import provision_tool
from yardstick.benchmark.contexts.base import Context
-from yardstick.benchmark.contexts.standalone.model import Libvirt
-from yardstick.benchmark.contexts.standalone.model import StandaloneContextHelper
-from yardstick.benchmark.contexts.standalone.model import Server
+from yardstick.benchmark.contexts.standalone import model
from yardstick.network_services.utils import PciAddress
LOG = logging.getLogger(__name__)
@@ -49,8 +46,8 @@ class SriovContext(Context):
self.attrs = {}
self.vm_flavor = None
self.servers = None
- self.helper = StandaloneContextHelper()
- self.vnf_node = Server()
+ self.helper = model.StandaloneContextHelper()
+ self.vnf_node = model.Server()
self.drivers = []
super(SriovContext, self).__init__()
@@ -87,15 +84,14 @@ class SriovContext(Context):
os.path.join(get_nsb_option("bin_path"), "dpdk-devbind.py"))
# Todo: NFVi deploy (sriov, vswitch, ovs etc) based on the config.
- StandaloneContextHelper.install_req_libs(self.connection)
- self.networks = StandaloneContextHelper.get_nic_details(
+ model.StandaloneContextHelper.install_req_libs(self.connection)
+ self.networks = model.StandaloneContextHelper.get_nic_details(
self.connection, self.networks, self.dpdk_devbind)
self.nodes = self.setup_sriov_context()
LOG.debug("Waiting for VM to come up...")
- self.nodes = StandaloneContextHelper.wait_for_vnfs_to_start(self.connection,
- self.servers,
- self.nodes)
+ self.nodes = model.StandaloneContextHelper.wait_for_vnfs_to_start(
+ self.connection, self.servers, self.nodes)
def undeploy(self):
"""don't need to undeploy"""
@@ -105,7 +101,7 @@ class SriovContext(Context):
# Todo: NFVi undeploy (sriov, vswitch, ovs etc) based on the config.
for vm in self.vm_names:
- Libvirt.check_if_vm_exists_and_delete(vm, self.connection)
+ model.Libvirt.check_if_vm_exists_and_delete(vm, self.connection)
# Bind nics back to kernel
for ports in self.networks.values():
@@ -136,8 +132,8 @@ class SriovContext(Context):
except StopIteration:
pass
else:
- raise ValueError("Duplicate nodes!!! Nodes: %s %s" %
- (node, duplicate))
+ raise ValueError("Duplicate nodes!!! Nodes: %s %s"
+ % (node, duplicate))
node["name"] = attr_name
return node
@@ -179,7 +175,7 @@ class SriovContext(Context):
self.connection.execute(build_vfs.format(ports.get('phy_port')))
# configure VFs...
- mac = StandaloneContextHelper.get_mac_address()
+ mac = model.StandaloneContextHelper.get_mac_address()
interface = ports.get('interface')
if interface is not None:
self.connection.execute(vf_cmd.format(interface, mac))
@@ -201,7 +197,7 @@ class SriovContext(Context):
slot = index + idx + 10
vf['vpci'] = \
"{}:{}:{:02x}.{}".format(vpci.domain, vpci.bus, slot, vpci.function)
- Libvirt.add_sriov_interfaces(
+ model.Libvirt.add_sriov_interfaces(
vf['vpci'], vf['vf_pci']['vf_pci'], vf['mac'], str(cfg))
self.connection.execute("ifconfig %s up" % vf['interface'])
self.connection.execute(vf_spoofchk.format(vf['interface']))
@@ -212,34 +208,37 @@ class SriovContext(Context):
# 1 : modprobe host_driver with num_vfs
self.configure_nics_for_sriov()
- for index, (key, vnf) in enumerate(OrderedDict(self.servers).items()):
+ for index, (key, vnf) in enumerate(collections.OrderedDict(
+ self.servers).items()):
cfg = '/tmp/vm_sriov_%s.xml' % str(index)
vm_name = "vm_%s" % str(index)
# 1. Check and delete VM if already exists
- Libvirt.check_if_vm_exists_and_delete(vm_name, self.connection)
+ model.Libvirt.check_if_vm_exists_and_delete(vm_name,
+ self.connection)
+ xml_str, mac = model.Libvirt.build_vm_xml(
+ self.connection, self.vm_flavor, vm_name, index)
- _, mac = Libvirt.build_vm_xml(self.connection, self.vm_flavor, cfg, vm_name, index)
# 2: Cleanup already available VMs
- for idx, (vkey, vfs) in enumerate(OrderedDict(vnf["network_ports"]).items()):
- if vkey == "mgmt":
- continue
+ network_ports = collections.OrderedDict(
+ {k: v for k, v in vnf["network_ports"].items() if k != 'mgmt'})
+ for idx, vfs in enumerate(network_ports.values()):
self._enable_interfaces(index, idx, vfs, cfg)
# copy xml to target...
+ model.Libvirt.write_file(cfg, xml_str)
self.connection.put(cfg, cfg)
# NOTE: launch through libvirt
LOG.info("virsh create ...")
- Libvirt.virsh_create_vm(self.connection, cfg)
+ model.Libvirt.virsh_create_vm(self.connection, cfg)
self.vm_names.append(vm_name)
# build vnf node details
- nodes.append(self.vnf_node.generate_vnf_instance(self.vm_flavor,
- self.networks,
- self.host_mgmt.get('ip'),
- key, vnf, mac))
+ nodes.append(self.vnf_node.generate_vnf_instance(
+ self.vm_flavor, self.networks, self.host_mgmt.get('ip'),
+ key, vnf, mac))
return nodes
@@ -248,7 +247,8 @@ class SriovContext(Context):
"mac": vfmac,
"pf_if": pfif
}
- vfs = StandaloneContextHelper.get_virtual_devices(self.connection, value)
+ vfs = model.StandaloneContextHelper.get_virtual_devices(
+ self.connection, value)
for k, v in vfs.items():
m = PciAddress(k.strip())
m1 = PciAddress(value.strip())
diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py
index 43d1eb598..439b9cb1b 100644
--- a/yardstick/common/exceptions.py
+++ b/yardstick/common/exceptions.py
@@ -82,6 +82,36 @@ class DPDKSetupDriverError(YardstickException):
message = '"igb_uio" driver is not loaded'
+class OVSUnsupportedVersion(YardstickException):
+ message = ('Unsupported OVS version "%(ovs_version)s". Please check the '
+ 'config. OVS to DPDK version map: %(ovs_to_dpdk_map)s.')
+
+
+class OVSHugepagesInfoError(YardstickException):
+ message = 'MemInfo cannnot be retrieved.'
+
+
+class OVSHugepagesNotConfigured(YardstickException):
+ message = 'HugePages are not configured in this system.'
+
+
+class OVSHugepagesZeroFree(YardstickException):
+ message = ('There are no HugePages free in this system. Total HugePages '
+ 'configured: %(total_hugepages)s')
+
+
+class OVSDeployError(YardstickException):
+ message = 'OVS deploy tool failed with error: %(stderr)s.'
+
+
+class OVSSetupError(YardstickException):
+ message = 'OVS setup error. Command: %(command)s. Error: %(error)s.'
+
+
+class LibvirtCreateError(YardstickException):
+ message = 'Error creating the virtual machine. Error: %(error)s.'
+
+
class ScenarioConfigContextNameNotFound(YardstickException):
message = 'Context name "%(context_name)s" not found'
diff --git a/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py b/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py
index 18ea3c4e6..b1dcee209 100644
--- a/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py
+++ b/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py
@@ -13,12 +13,17 @@
# limitations under the License.
import copy
+import mock
import os
import unittest
-import mock
+import uuid
from xml.etree import ElementTree
+
+from yardstick import ssh
from yardstick.benchmark.contexts.standalone import model
+from yardstick.common import exceptions
+from yardstick import constants
from yardstick.network_services import utils
@@ -38,22 +43,19 @@ XML_SAMPLE_INTERFACE = """<?xml version="1.0"?>
</domain>
"""
+
class ModelLibvirtTestCase(unittest.TestCase):
def setUp(self):
- self.xml = ElementTree.ElementTree(
- element=ElementTree.fromstring(XML_SAMPLE))
self.pci_address_str = '0001:04:03.2'
self.pci_address = utils.PciAddress(self.pci_address_str)
self.mac = '00:00:00:00:00:01'
- self._mock_write_xml = mock.patch.object(ElementTree.ElementTree,
- 'write')
- self.mock_write_xml = self._mock_write_xml.start()
-
+ self._mock_ssh = mock.Mock()
+ self.mock_ssh = self._mock_ssh.start()
self.addCleanup(self._cleanup)
def _cleanup(self):
- self._mock_write_xml.stop()
+ self._mock_ssh.stop()
# TODO: Remove mocking of yardstick.ssh.SSH (here and elsewhere)
# In this case, we are mocking a param to be passed into other methods
@@ -67,20 +69,31 @@ class ModelLibvirtTestCase(unittest.TestCase):
model.Libvirt.check_if_vm_exists_and_delete("vm_0", ssh_mock)
def test_virsh_create_vm(self):
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
- ssh.return_value = ssh_mock
- # NOTE(ralonsoh): this test doesn't cover function execution.
- model.Libvirt.virsh_create_vm(ssh_mock, "vm_0")
+ self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0))
+ model.Libvirt.virsh_create_vm(self.mock_ssh, 'vm_0')
+ self.mock_ssh.execute.assert_called_once_with('virsh create vm_0')
+
+ def test_virsh_create_vm_error(self):
+ self.mock_ssh.execute = mock.Mock(return_value=(1, 0, 'error_create'))
+ with self.assertRaises(exceptions.LibvirtCreateError) as exc:
+ model.Libvirt.virsh_create_vm(self.mock_ssh, 'vm_0')
+ self.assertEqual('Error creating the virtual machine. Error: '
+ 'error_create.', str(exc.exception))
+ self.mock_ssh.execute.assert_called_once_with('virsh create vm_0')
def test_virsh_destroy_vm(self):
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
- ssh.return_value = ssh_mock
- # NOTE(ralonsoh): this test doesn't cover function execution.
- model.Libvirt.virsh_destroy_vm("vm_0", ssh_mock)
+ self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0))
+ model.Libvirt.virsh_destroy_vm('vm_0', self.mock_ssh)
+ self.mock_ssh.execute.assert_called_once_with('virsh destroy vm_0')
+
+ @mock.patch.object(model, 'LOG')
+ def test_virsh_destroy_vm_error(self, mock_logger):
+ self.mock_ssh.execute = mock.Mock(return_value=(1, 0, 'error_destroy'))
+ mock_logger.warning = mock.Mock()
+ model.Libvirt.virsh_destroy_vm('vm_0', self.mock_ssh)
+ mock_logger.warning.assert_called_once_with(
+ 'Error destroying VM %s. Error: %s', 'vm_0', 'error_destroy')
+ self.mock_ssh.execute.assert_called_once_with('virsh destroy vm_0')
def test_add_interface_address(self):
xml = ElementTree.ElementTree(
@@ -98,72 +111,65 @@ class ModelLibvirtTestCase(unittest.TestCase):
result.get('function'))
def test_add_ovs_interfaces(self):
- xml_input = mock.Mock()
- with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \
- as mock_parse:
- xml = copy.deepcopy(self.xml)
- mock_parse.return_value = xml
- model.Libvirt.add_ovs_interface(
- '/usr/local', 0, self.pci_address_str, self.mac, xml_input)
- mock_parse.assert_called_once_with(xml_input)
- self.mock_write_xml.assert_called_once_with(xml_input)
- interface = xml.find('devices').find('interface')
- self.assertEqual('vhostuser', interface.get('type'))
- mac = interface.find('mac')
- self.assertEqual(self.mac, mac.get('address'))
- source = interface.find('source')
- self.assertEqual('unix', source.get('type'))
- self.assertEqual('/usr/local/var/run/openvswitch/dpdkvhostuser0',
- source.get('path'))
- self.assertEqual('client', source.get('mode'))
- _model = interface.find('model')
- self.assertEqual('virtio', _model.get('type'))
- driver = interface.find('driver')
- self.assertEqual('4', driver.get('queues'))
- host = driver.find('host')
- self.assertEqual('off', host.get('mrg_rxbuf'))
- self.assertIsNotNone(interface.find('address'))
+ xml_input = copy.deepcopy(XML_SAMPLE)
+ xml_output = model.Libvirt.add_ovs_interface(
+ '/usr/local', 0, self.pci_address_str, self.mac, xml_input)
+
+ root = ElementTree.fromstring(xml_output)
+ et_out = ElementTree.ElementTree(element=root)
+ interface = et_out.find('devices').find('interface')
+ self.assertEqual('vhostuser', interface.get('type'))
+ mac = interface.find('mac')
+ self.assertEqual(self.mac, mac.get('address'))
+ source = interface.find('source')
+ self.assertEqual('unix', source.get('type'))
+ self.assertEqual('/usr/local/var/run/openvswitch/dpdkvhostuser0',
+ source.get('path'))
+ self.assertEqual('client', source.get('mode'))
+ _model = interface.find('model')
+ self.assertEqual('virtio', _model.get('type'))
+ driver = interface.find('driver')
+ self.assertEqual('4', driver.get('queues'))
+ host = driver.find('host')
+ self.assertEqual('off', host.get('mrg_rxbuf'))
+ self.assertIsNotNone(interface.find('address'))
def test_add_sriov_interfaces(self):
- xml_input = mock.Mock()
- with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \
- as mock_parse:
- xml = copy.deepcopy(self.xml)
- mock_parse.return_value = xml
- vm_pci = '0001:05:04.2'
- model.Libvirt.add_sriov_interfaces(
- vm_pci, self.pci_address_str, self.mac, xml_input)
- mock_parse.assert_called_once_with(xml_input)
- self.mock_write_xml.assert_called_once_with(xml_input)
- interface = xml.find('devices').find('interface')
- self.assertEqual('yes', interface.get('managed'))
- self.assertEqual('hostdev', interface.get('type'))
- mac = interface.find('mac')
- self.assertEqual(self.mac, mac.get('address'))
- source = interface.find('source')
- source_address = source.find('address')
- self.assertIsNotNone(source.find('address'))
-
- self.assertEqual('pci', source_address.get('type'))
- self.assertEqual('0x' + self.pci_address_str.split(':')[0],
- source_address.get('domain'))
- self.assertEqual('0x' + self.pci_address_str.split(':')[1],
- source_address.get('bus'))
- self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[0],
- source_address.get('slot'))
- self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[1],
- source_address.get('function'))
-
- interface_address = interface.find('address')
- self.assertEqual('pci', interface_address.get('type'))
- self.assertEqual('0x' + vm_pci.split(':')[0],
- interface_address.get('domain'))
- self.assertEqual('0x' + vm_pci.split(':')[1],
- interface_address.get('bus'))
- self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[0],
- interface_address.get('slot'))
- self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[1],
- interface_address.get('function'))
+ xml_input = copy.deepcopy(XML_SAMPLE)
+ vm_pci = '0001:05:04.2'
+ xml_output = model.Libvirt.add_sriov_interfaces(
+ vm_pci, self.pci_address_str, self.mac, xml_input)
+ root = ElementTree.fromstring(xml_output)
+ et_out = ElementTree.ElementTree(element=root)
+ interface = et_out.find('devices').find('interface')
+ self.assertEqual('yes', interface.get('managed'))
+ self.assertEqual('hostdev', interface.get('type'))
+ mac = interface.find('mac')
+ self.assertEqual(self.mac, mac.get('address'))
+ source = interface.find('source')
+ source_address = source.find('address')
+ self.assertIsNotNone(source.find('address'))
+
+ self.assertEqual('pci', source_address.get('type'))
+ self.assertEqual('0x' + self.pci_address_str.split(':')[0],
+ source_address.get('domain'))
+ self.assertEqual('0x' + self.pci_address_str.split(':')[1],
+ source_address.get('bus'))
+ self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[0],
+ source_address.get('slot'))
+ self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[1],
+ source_address.get('function'))
+
+ interface_address = interface.find('address')
+ self.assertEqual('pci', interface_address.get('type'))
+ self.assertEqual('0x' + vm_pci.split(':')[0],
+ interface_address.get('domain'))
+ self.assertEqual('0x' + vm_pci.split(':')[1],
+ interface_address.get('bus'))
+ self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[0],
+ interface_address.get('slot'))
+ self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[1],
+ interface_address.get('function'))
def test_create_snapshot_qemu(self):
result = "/var/lib/libvirt/images/0.qcow2"
@@ -175,24 +181,38 @@ class ModelLibvirtTestCase(unittest.TestCase):
image = model.Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img")
self.assertEqual(image, result)
- @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf')
- @mock.patch.object(model.Libvirt, 'create_snapshot_qemu')
+ @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf', return_value='4,5')
+ @mock.patch.object(model.Libvirt, 'create_snapshot_qemu',
+ return_value='qemu_image')
def test_build_vm_xml(self, mock_create_snapshot_qemu,
- *args):
- # NOTE(ralonsoh): this test doesn't cover function execution. This test
- # should also check mocked function calls.
- cfg_file = 'test_config_file.cfg'
- self.addCleanup(os.remove, cfg_file)
- result = [4]
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = \
- mock.Mock(return_value=(0, "a", ""))
- ssh.return_value = ssh_mock
- mock_create_snapshot_qemu.return_value = "0.img"
-
- status = model.Libvirt.build_vm_xml(ssh_mock, {}, cfg_file, 'vm_0', 0)
- self.assertEqual(status[0], result[0])
+ mock_pin_vcpu_for_perf):
+ extra_specs = {'hw:cpu_cores': '4',
+ 'hw:cpu_sockets': '3',
+ 'hw:cpu_threads': '2',
+ 'cputune': 'cool'}
+ flavor = {'ram': '1024',
+ 'extra_specs': extra_specs,
+ 'hw_socket': '1',
+ 'images': 'images'}
+ mac = model.StandaloneContextHelper.get_mac_address(0x00)
+ _uuid = uuid.uuid4()
+ connection = mock.Mock()
+ with mock.patch.object(model.StandaloneContextHelper,
+ 'get_mac_address', return_value=mac) as \
+ mock_get_mac_address, \
+ mock.patch.object(uuid, 'uuid4', return_value=_uuid):
+ xml_out, mac = model.Libvirt.build_vm_xml(
+ connection, flavor, 'vm_name', 100)
+
+ xml_ref = model.VM_TEMPLATE.format(vm_name='vm_name',
+ random_uuid=_uuid, mac_addr=mac, memory='1024', vcpu='8', cpu='4',
+ numa_cpus='0-7', socket='3', threads='2',
+ vm_image='qemu_image', cpuset='4,5', cputune='cool')
+ self.assertEqual(xml_ref, xml_out)
+ mock_get_mac_address.assert_called_once_with(0x00)
+ mock_create_snapshot_qemu.assert_called_once_with(
+ connection, 100, 'images')
+ mock_pin_vcpu_for_perf.assert_called_once_with(connection, '1')
# TODO: Edit this test to test state instead of output
# update_interrupts_hugepages_perf does not return anything
@@ -398,43 +418,80 @@ class ServerTestCase(unittest.TestCase):
class OvsDeployTestCase(unittest.TestCase):
- NETWORKS = {
- 'mgmt': {'cidr': '152.16.100.10/24'},
- 'private_0': {
- 'phy_port': "0000:05:00.0",
- 'vpci': "0000:00:07.0",
- 'driver': 'i40e',
- 'mac': '',
- 'cidr': '152.16.100.10/24',
- 'gateway_ip': '152.16.100.20'},
- 'public_0': {
- 'phy_port': "0000:05:00.1",
- 'vpci': "0000:00:08.0",
- 'driver': 'i40e',
- 'mac': '',
- 'cidr': '152.16.40.10/24',
- 'gateway_ip': '152.16.100.20'}
- }
-
- @mock.patch('yardstick.ssh.SSH')
- def setUp(self, mock_ssh):
- self.ovs_deploy = model.OvsDeploy(mock_ssh, '/tmp/dpdk-devbind.py', {})
+ OVS_DETAILS = {'version': {'ovs': 'ovs_version', 'dpdk': 'dpdk_version'}}
- def test___init__(self):
- self.assertIsNotNone(self.ovs_deploy.connection)
-
- @mock.patch('yardstick.benchmark.contexts.standalone.model.os')
- def test_prerequisite(self, *args):
- # NOTE(ralonsoh): this test should check mocked function calls.
- self.ovs_deploy.helper = mock.Mock()
- self.assertIsNone(self.ovs_deploy.prerequisite())
-
- @mock.patch('yardstick.benchmark.contexts.standalone.model.os')
- def test_prerequisite_2(self, *args):
- # NOTE(ralonsoh): this test should check mocked function calls. Rename
- # this test properly.
- self.ovs_deploy.helper = mock.Mock()
- self.ovs_deploy.connection.execute = mock.Mock(
- return_value=(1, '1.2.3.4 00:00:00:00:00:01', ''))
- self.ovs_deploy.prerequisite = mock.Mock()
- self.assertIsNone(self.ovs_deploy.ovs_deploy())
+ def setUp(self):
+ self._mock_ssh = mock.patch.object(ssh, 'SSH')
+ self.mock_ssh = self._mock_ssh .start()
+ self.ovs_deploy = model.OvsDeploy(self.mock_ssh,
+ '/tmp/dpdk-devbind.py',
+ self.OVS_DETAILS)
+ self._mock_path_isfile = mock.patch.object(os.path, 'isfile')
+ self._mock_path_join = mock.patch.object(os.path, 'join')
+ self.mock_path_isfile = self._mock_path_isfile.start()
+ self.mock_path_join = self._mock_path_join.start()
+
+ self.addCleanup(self._stop_mock)
+
+ def _stop_mock(self):
+ self._mock_ssh.stop()
+ self._mock_path_isfile.stop()
+ self._mock_path_join.stop()
+
+ @mock.patch.object(model.StandaloneContextHelper, 'install_req_libs')
+ def test_prerequisite(self, mock_install_req_libs):
+ pkgs = ["git", "build-essential", "pkg-config", "automake",
+ "autotools-dev", "libltdl-dev", "cmake", "libnuma-dev",
+ "libpcap-dev"]
+ self.ovs_deploy.prerequisite()
+ mock_install_req_libs.assert_called_once_with(
+ self.ovs_deploy.connection, pkgs)
+
+ def test_ovs_deploy_no_file(self):
+ self.mock_path_isfile.return_value = False
+ mock_file = mock.Mock()
+ self.mock_path_join.return_value = mock_file
+
+ self.ovs_deploy.ovs_deploy()
+ self.mock_path_isfile.assert_called_once_with(mock_file)
+ self.mock_path_join.assert_called_once_with(
+ constants.YARDSTICK_ROOT_PATH,
+ 'yardstick/resources/scripts/install/',
+ self.ovs_deploy.OVS_DEPLOY_SCRIPT)
+
+ @mock.patch.object(os.environ, 'get', return_value='test_proxy')
+ def test_ovs_deploy(self, mock_env_get):
+ self.mock_path_isfile.return_value = True
+ mock_deploy_file = mock.Mock()
+ mock_remove_ovs_deploy = mock.Mock()
+ self.mock_path_join.side_effect = [mock_deploy_file,
+ mock_remove_ovs_deploy]
+ dpdk_version = self.OVS_DETAILS['version']['dpdk']
+ ovs_version = self.OVS_DETAILS['version']['ovs']
+
+ with mock.patch.object(self.ovs_deploy.connection, 'put') as \
+ mock_put, \
+ mock.patch.object(self.ovs_deploy.connection, 'execute') as \
+ mock_execute, \
+ mock.patch.object(self.ovs_deploy, 'prerequisite'):
+ mock_execute.return_value = (0, 0, 0)
+ self.ovs_deploy.ovs_deploy()
+
+ self.mock_path_isfile.assert_called_once_with(mock_deploy_file)
+ self.mock_path_join.assert_has_calls([
+ mock.call(constants.YARDSTICK_ROOT_PATH,
+ 'yardstick/resources/scripts/install/',
+ self.ovs_deploy.OVS_DEPLOY_SCRIPT),
+ mock.call(self.ovs_deploy.bin_path,
+ self.ovs_deploy.OVS_DEPLOY_SCRIPT)
+ ])
+ mock_put.assert_called_once_with(mock_deploy_file,
+ mock_remove_ovs_deploy)
+ cmd = ("sudo -E %(remote_ovs_deploy)s --ovs='%(ovs_version)s' "
+ "--dpdk='%(dpdk_version)s' -p='%(proxy)s'" %
+ {'remote_ovs_deploy': mock_remove_ovs_deploy,
+ 'ovs_version': ovs_version,
+ 'dpdk_version': dpdk_version,
+ 'proxy': 'test_proxy'})
+ mock_execute.assert_called_once_with(cmd)
+ mock_env_get.assert_called_once_with('http_proxy', '')
diff --git a/yardstick/tests/unit/benchmark/contexts/standalone/test_ovs_dpdk.py b/yardstick/tests/unit/benchmark/contexts/standalone/test_ovs_dpdk.py
index 0223fd3ff..bc3bb73cd 100644
--- a/yardstick/tests/unit/benchmark/contexts/standalone/test_ovs_dpdk.py
+++ b/yardstick/tests/unit/benchmark/contexts/standalone/test_ovs_dpdk.py
@@ -12,12 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import io
import os
import mock
+import six
import unittest
+from yardstick.benchmark.contexts.standalone import model
from yardstick.benchmark.contexts.standalone import ovs_dpdk
+from yardstick.common import exceptions
+from yardstick.network_services import utils
class OvsDpdkContextTestCase(unittest.TestCase):
@@ -27,7 +32,6 @@ class OvsDpdkContextTestCase(unittest.TestCase):
NODES_DUPLICATE_SAMPLE = "nodes_duplicate_sample.yaml"
NETWORKS = {
- 'mgmt': {'cidr': '152.16.100.10/24'},
'private_0': {
'phy_port': "0000:05:00.0",
'vpci': "0000:00:07.0",
@@ -82,15 +86,43 @@ class OvsDpdkContextTestCase(unittest.TestCase):
self.assertIsNone(self.ovs_dpdk.init(ATTRS))
def test_setup_ovs(self):
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = \
- mock.Mock(return_value=(0, "a", ""))
- ssh.return_value = ssh_mock
- self.ovs_dpdk.connection = ssh_mock
- self.ovs_dpdk.networks = self.NETWORKS
- self.ovs_dpdk.ovs_properties = {}
- self.assertIsNone(self.ovs_dpdk.setup_ovs())
+ fake_path = '/fake_path'
+ fake_dpdk_nic_bind = 'dpdk_tool.py'
+ self.ovs_dpdk.ovs_properties = {'vpath': fake_path}
+ self.ovs_dpdk.dpdk_devbind = fake_dpdk_nic_bind
+ self.ovs_dpdk.networks = self.NETWORKS
+ self.ovs_dpdk.connection = mock.Mock()
+ self.ovs_dpdk.connection.execute = mock.Mock(return_value=(0, 0, 0))
+ create_from = fake_path + '/etc/openvswitch/conf.db'
+ create_to = fake_path + '/share/openvswitch/vswitch.ovsschema'
+ cmd_list = [
+ 'killall -r "ovs.*" -q | true',
+ 'mkdir -p {0}/etc/openvswitch'.format(fake_path),
+ 'mkdir -p {0}/var/run/openvswitch'.format(fake_path),
+ 'rm {0}/etc/openvswitch/conf.db | true'.format(fake_path),
+ 'ovsdb-tool create {0} {1}'.format(create_from, create_to),
+ 'modprobe vfio-pci',
+ 'chmod a+x /dev/vfio',
+ 'chmod 0666 /dev/vfio/*',
+ '{0} --force -b vfio-pci {1}'.format(fake_dpdk_nic_bind,
+ self.ovs_dpdk.networks['private_0']['phy_port']),
+ '{0} --force -b vfio-pci {1}'.format(fake_dpdk_nic_bind,
+ self.ovs_dpdk.networks['public_0']['phy_port'])
+ ]
+ calls = [mock.call(cmd, timeout=self.ovs_dpdk.CMD_TIMEOUT)
+ for cmd in cmd_list]
+
+ self.ovs_dpdk.setup_ovs()
+ self.ovs_dpdk.connection.execute.assert_has_calls(calls,
+ any_order=True)
+
+ def test_setup_ovs_exception(self):
+ self.ovs_dpdk.networks = self.NETWORKS
+ self.ovs_dpdk.connection = mock.Mock()
+ self.ovs_dpdk.connection.execute = mock.Mock(return_value=(1, 0, 0))
+
+ with self.assertRaises(exceptions.OVSSetupError):
+ self.ovs_dpdk.setup_ovs()
def test_start_ovs_serverswitch(self):
with mock.patch("yardstick.ssh.SSH") as ssh:
@@ -129,34 +161,45 @@ class OvsDpdkContextTestCase(unittest.TestCase):
self.ovs_dpdk.wait_for_vswitchd = 0
self.assertIsNone(self.ovs_dpdk.cleanup_ovs_dpdk_env())
- @mock.patch('yardstick.benchmark.contexts.standalone.model.OvsDeploy')
- def test_check_ovs_dpdk_env(self, mock_ovs):
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = \
- mock.Mock(return_value=(1, "a", ""))
- ssh.return_value = ssh_mock
- self.ovs_dpdk.connection = ssh_mock
- self.ovs_dpdk.networks = self.NETWORKS
- self.ovs_dpdk.ovs_properties = {
- 'version': {'ovs': '2.7.0', 'dpdk': '16.11.1'}
- }
- self.ovs_dpdk.wait_for_vswitchd = 0
- self.ovs_dpdk.cleanup_ovs_dpdk_env = mock.Mock()
- self.assertIsNone(self.ovs_dpdk.check_ovs_dpdk_env())
- self.ovs_dpdk.ovs_properties = {
- 'version': {'ovs': '2.0.0'}
- }
- self.ovs_dpdk.wait_for_vswitchd = 0
- self.cleanup_ovs_dpdk_env = mock.Mock()
- mock_ovs.deploy = mock.Mock()
- # NOTE(elfoley): Check for a specific Exception
- self.assertRaises(Exception, self.ovs_dpdk.check_ovs_dpdk_env)
+ @mock.patch.object(ovs_dpdk.OvsDpdkContext, '_check_hugepages')
+ @mock.patch.object(utils, 'get_nsb_option')
+ @mock.patch.object(model.OvsDeploy, 'ovs_deploy')
+ def test_check_ovs_dpdk_env(self, mock_ovs_deploy, mock_get_nsb_option,
+ mock_check_hugepages):
+ self.ovs_dpdk.connection = mock.Mock()
+ self.ovs_dpdk.connection.execute = mock.Mock(
+ return_value=(1, 0, 0))
+ self.ovs_dpdk.networks = self.NETWORKS
+ self.ovs_dpdk.ovs_properties = {
+ 'version': {'ovs': '2.7.0', 'dpdk': '16.11.1'}
+ }
+ self.ovs_dpdk.wait_for_vswitchd = 0
+ self.ovs_dpdk.cleanup_ovs_dpdk_env = mock.Mock()
+ mock_get_nsb_option.return_value = 'fake_path'
+
+ self.ovs_dpdk.check_ovs_dpdk_env()
+ mock_ovs_deploy.assert_called_once()
+ mock_check_hugepages.assert_called_once()
+ mock_get_nsb_option.assert_called_once_with('bin_path')
+
+ @mock.patch.object(ovs_dpdk.OvsDpdkContext, '_check_hugepages')
+ def test_check_ovs_dpdk_env_wrong_version(self, mock_check_hugepages):
+ self.ovs_dpdk.connection = mock.Mock()
+ self.ovs_dpdk.connection.execute = mock.Mock(
+ return_value=(1, 0, 0))
+ self.ovs_dpdk.networks = self.NETWORKS
+ self.ovs_dpdk.ovs_properties = {
+ 'version': {'ovs': '0.0.1', 'dpdk': '9.8.7'}
+ }
+ self.ovs_dpdk.wait_for_vswitchd = 0
+ self.ovs_dpdk.cleanup_ovs_dpdk_env = mock.Mock()
- @mock.patch('yardstick.ssh.SSH')
- def test_deploy(self, mock_ssh):
- mock_ssh.execute.return_value = 0, "a", ""
+ with self.assertRaises(exceptions.OVSUnsupportedVersion):
+ self.ovs_dpdk.check_ovs_dpdk_env()
+ mock_check_hugepages.assert_called_once()
+ @mock.patch('yardstick.ssh.SSH')
+ def test_deploy(self, *args):
self.ovs_dpdk.vm_deploy = False
self.assertIsNone(self.ovs_dpdk.deploy())
@@ -174,21 +217,19 @@ class OvsDpdkContextTestCase(unittest.TestCase):
# output.
self.assertIsNone(self.ovs_dpdk.deploy())
- @mock.patch('yardstick.benchmark.contexts.standalone.model.Libvirt')
- @mock.patch('yardstick.ssh.SSH')
- def test_undeploy(self, mock_ssh, *args):
- mock_ssh.execute.return_value = 0, "a", ""
-
- self.ovs_dpdk.vm_deploy = False
- self.assertIsNone(self.ovs_dpdk.undeploy())
-
+ @mock.patch.object(model.Libvirt, 'check_if_vm_exists_and_delete')
+ def test_undeploy(self, mock_libvirt):
self.ovs_dpdk.vm_deploy = True
- self.ovs_dpdk.connection = mock_ssh
+ self.ovs_dpdk.connection = mock.Mock()
self.ovs_dpdk.vm_names = ['vm_0', 'vm_1']
self.ovs_dpdk.drivers = ['vm_0', 'vm_1']
self.ovs_dpdk.cleanup_ovs_dpdk_env = mock.Mock()
self.ovs_dpdk.networks = self.NETWORKS
- self.assertIsNone(self.ovs_dpdk.undeploy())
+ self.ovs_dpdk.undeploy()
+ mock_libvirt.assert_has_calls([
+ mock.call(self.ovs_dpdk.vm_names[0], self.ovs_dpdk.connection),
+ mock.call(self.ovs_dpdk.vm_names[1], self.ovs_dpdk.connection)
+ ])
def _get_file_abspath(self, filename):
curr_path = os.path.dirname(os.path.abspath(__file__))
@@ -310,34 +351,28 @@ class OvsDpdkContextTestCase(unittest.TestCase):
self.ovs_dpdk.get_vf_datas = mock.Mock(return_value="")
self.assertIsNone(self.ovs_dpdk.configure_nics_for_ovs_dpdk())
- @mock.patch('yardstick.benchmark.contexts.standalone.ovs_dpdk.Libvirt')
- def test__enable_interfaces(self, *args):
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = \
- mock.Mock(return_value=(0, "a", ""))
- ssh.return_value = ssh_mock
+ @mock.patch.object(model.Libvirt, 'add_ovs_interface')
+ def test__enable_interfaces(self, mock_add_ovs_interface):
self.ovs_dpdk.vm_deploy = True
- self.ovs_dpdk.connection = ssh_mock
+ self.ovs_dpdk.connection = mock.Mock()
self.ovs_dpdk.vm_names = ['vm_0', 'vm_1']
self.ovs_dpdk.drivers = []
self.ovs_dpdk.networks = self.NETWORKS
+ self.ovs_dpdk.ovs_properties = {'vpath': 'fake_path'}
self.ovs_dpdk.get_vf_datas = mock.Mock(return_value="")
- self.assertIsNone(self.ovs_dpdk._enable_interfaces(
- 0, ["private_0"], 'test'))
-
- @mock.patch('yardstick.benchmark.contexts.standalone.model.Server')
- @mock.patch('yardstick.benchmark.contexts.standalone.ovs_dpdk.Libvirt')
- def test_setup_ovs_dpdk_context(self, mock_libvirt, *args):
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = \
- mock.Mock(return_value=(0, "a", ""))
- ssh_mock.put = \
- mock.Mock(return_value=(0, "a", ""))
- ssh.return_value = ssh_mock
+ self.ovs_dpdk._enable_interfaces(0, ["private_0"], 'test')
+ mock_add_ovs_interface.assert_called_once_with(
+ 'fake_path', 0, self.NETWORKS['private_0']['vpci'],
+ self.NETWORKS['private_0']['mac'], 'test')
+
+ @mock.patch.object(model.Libvirt, 'write_file')
+ @mock.patch.object(model.Libvirt, 'build_vm_xml')
+ @mock.patch.object(model.Libvirt, 'check_if_vm_exists_and_delete')
+ @mock.patch.object(model.Libvirt, 'virsh_create_vm')
+ def test_setup_ovs_dpdk_context(self, mock_create_vm, mock_check_if_exists,
+ mock_build_xml, mock_write_file):
self.ovs_dpdk.vm_deploy = True
- self.ovs_dpdk.connection = ssh_mock
+ self.ovs_dpdk.connection = mock.Mock()
self.ovs_dpdk.vm_names = ['vm_0', 'vm_1']
self.ovs_dpdk.drivers = []
self.ovs_dpdk.servers = {
@@ -353,11 +388,64 @@ class OvsDpdkContextTestCase(unittest.TestCase):
self.ovs_dpdk.host_mgmt = {}
self.ovs_dpdk.flavor = {}
self.ovs_dpdk.configure_nics_for_ovs_dpdk = mock.Mock(return_value="")
- mock_libvirt.build_vm_xml.return_value = [6, "00:00:00:00:00:01"]
- self.ovs_dpdk._enable_interfaces = mock.Mock(return_value="")
- mock_libvirt.virsh_create_vm.return_value = ""
- mock_libvirt.pin_vcpu_for_perf.return_value = ""
+ xml_str = mock.Mock()
+ mock_build_xml.return_value = (xml_str, '00:00:00:00:00:01')
+ self.ovs_dpdk._enable_interfaces = mock.Mock(return_value=xml_str)
+ vnf_instance = mock.Mock()
self.ovs_dpdk.vnf_node.generate_vnf_instance = mock.Mock(
- return_value={})
-
- self.assertIsNotNone(self.ovs_dpdk.setup_ovs_dpdk_context())
+ return_value=vnf_instance)
+
+ self.assertEqual([vnf_instance],
+ self.ovs_dpdk.setup_ovs_dpdk_context())
+ mock_create_vm.assert_called_once_with(
+ self.ovs_dpdk.connection, '/tmp/vm_ovs_0.xml')
+ mock_check_if_exists.assert_called_once_with(
+ 'vm_0', self.ovs_dpdk.connection)
+ mock_build_xml.assert_called_once_with(
+ self.ovs_dpdk.connection, self.ovs_dpdk.vm_flavor, 'vm_0', 0)
+ mock_write_file.assert_called_once_with('/tmp/vm_ovs_0.xml', xml_str)
+
+ @mock.patch.object(io, 'BytesIO')
+ def test__check_hugepages(self, mock_bytesio):
+ data = six.BytesIO('HugePages_Total: 20\n'
+ 'HugePages_Free: 20\n'
+ 'HugePages_Rsvd: 0\n'
+ 'HugePages_Surp: 0\n'
+ 'Hugepagesize: 1048576 kB'.encode())
+ mock_bytesio.return_value = data
+ self.ovs_dpdk.connection = mock.Mock()
+ self.ovs_dpdk._check_hugepages()
+
+ @mock.patch.object(io, 'BytesIO')
+ def test__check_hugepages_no_info(self, mock_bytesio):
+ data = six.BytesIO(''.encode())
+ mock_bytesio.return_value = data
+ self.ovs_dpdk.connection = mock.Mock()
+ with self.assertRaises(exceptions.OVSHugepagesInfoError):
+ self.ovs_dpdk._check_hugepages()
+
+ @mock.patch.object(io, 'BytesIO')
+ def test__check_hugepages_no_total_hp(self, mock_bytesio):
+ data = six.BytesIO('HugePages_Total: 0\n'
+ 'HugePages_Free: 0\n'
+ 'HugePages_Rsvd: 0\n'
+ 'HugePages_Surp: 0\n'
+ 'Hugepagesize: 1048576 kB'.encode())
+ mock_bytesio.return_value = data
+ self.ovs_dpdk.connection = mock.Mock()
+ with self.assertRaises(exceptions.OVSHugepagesNotConfigured):
+ self.ovs_dpdk._check_hugepages()
+
+ @mock.patch.object(io, 'BytesIO')
+ def test__check_hugepages_no_free_hp(self, mock_bytesio):
+ data = six.BytesIO('HugePages_Total: 20\n'
+ 'HugePages_Free: 0\n'
+ 'HugePages_Rsvd: 0\n'
+ 'HugePages_Surp: 0\n'
+ 'Hugepagesize: 1048576 kB'.encode())
+ mock_bytesio.return_value = data
+ self.ovs_dpdk.connection = mock.Mock()
+ with self.assertRaises(exceptions.OVSHugepagesZeroFree) as exc:
+ self.ovs_dpdk._check_hugepages()
+ self.assertEqual('There are no HugePages free in this system. Total '
+ 'HugePages configured: 20', exc.exception.msg)
diff --git a/yardstick/tests/unit/benchmark/contexts/standalone/test_sriov.py b/yardstick/tests/unit/benchmark/contexts/standalone/test_sriov.py
index f0953ef55..e70ab0ae8 100644
--- a/yardstick/tests/unit/benchmark/contexts/standalone/test_sriov.py
+++ b/yardstick/tests/unit/benchmark/contexts/standalone/test_sriov.py
@@ -18,6 +18,7 @@ import mock
import unittest
from yardstick import ssh
+from yardstick.benchmark.contexts.standalone import model
from yardstick.benchmark.contexts.standalone import sriov
@@ -69,10 +70,11 @@ class SriovContextTestCase(unittest.TestCase):
if self.sriov in self.sriov.list:
self.sriov._delete_context()
- @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt')
- @mock.patch('yardstick.benchmark.contexts.standalone.model.StandaloneContextHelper')
- @mock.patch('yardstick.benchmark.contexts.standalone.model.Server')
- def test___init__(self, mock_helper, mock_server, *args):
+ @mock.patch.object(model, 'StandaloneContextHelper')
+ @mock.patch.object(model, 'Libvirt')
+ @mock.patch.object(model, 'Server')
+ def test___init__(self, mock_helper, mock_libvirt, mock_server):
+ # pylint: disable=unused-argument
# NOTE(ralonsoh): this test doesn't cover function execution.
self.sriov.helper = mock_helper
self.sriov.vnf_node = mock_server
@@ -97,9 +99,11 @@ class SriovContextTestCase(unittest.TestCase):
self.sriov.wait_for_vnfs_to_start = mock.Mock(return_value={})
self.assertIsNone(self.sriov.deploy())
- @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt')
@mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
- def test_undeploy(self, mock_ssh, *args):
+ @mock.patch.object(model, 'Libvirt')
+ def test_undeploy(self, mock_libvirt, mock_ssh):
+ # pylint: disable=unused-argument
+ # NOTE(ralonsoh): the pylint exception should be removed.
self.sriov.vm_deploy = False
self.assertIsNone(self.sriov.undeploy())
@@ -237,11 +241,11 @@ class SriovContextTestCase(unittest.TestCase):
self.sriov._get_vf_data = mock.Mock(return_value="")
self.assertIsNone(self.sriov.configure_nics_for_sriov())
- @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt')
- @mock.patch.object(ssh, 'SSH')
- def test__enable_interfaces(self, mock_ssh, *args):
- mock_ssh.return_value = 0, "a", ""
-
+ @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
+ @mock.patch.object(model, 'Libvirt')
+ def test__enable_interfaces(self, mock_libvirt, mock_ssh):
+ # pylint: disable=unused-argument
+ # NOTE(ralonsoh): the pylint exception should be removed.
self.sriov.vm_deploy = True
self.sriov.connection = mock_ssh
self.sriov.vm_names = ['vm_0', 'vm_1']
@@ -251,20 +255,12 @@ class SriovContextTestCase(unittest.TestCase):
self.assertIsNone(self.sriov._enable_interfaces(
0, 0, ["private_0"], 'test'))
- @mock.patch('yardstick.benchmark.contexts.standalone.model.Server')
- @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt')
- def test_setup_sriov_context(self, mock_libvirt, *args):
- with mock.patch("yardstick.ssh.SSH") as ssh:
- ssh_mock = mock.Mock(autospec=ssh.SSH)
- ssh_mock.execute = \
- mock.Mock(return_value=(0, "a", ""))
- ssh_mock.put = \
- mock.Mock(return_value=(0, "a", ""))
- ssh.return_value = ssh_mock
- self.sriov.vm_deploy = True
- self.sriov.connection = ssh_mock
- self.sriov.vm_names = ['vm_0', 'vm_1']
- self.sriov.drivers = []
+ @mock.patch.object(model.Libvirt, 'build_vm_xml')
+ @mock.patch.object(model.Libvirt, 'check_if_vm_exists_and_delete')
+ @mock.patch.object(model.Libvirt, 'write_file')
+ @mock.patch.object(model.Libvirt, 'virsh_create_vm')
+ def test_setup_sriov_context(self, mock_create_vm, mock_write_file,
+ mock_check, mock_build_vm_xml):
self.sriov.servers = {
'vnf_0': {
'network_ports': {
@@ -274,15 +270,31 @@ class SriovContextTestCase(unittest.TestCase):
}
}
}
- self.sriov.networks = self.NETWORKS
- self.sriov.host_mgmt = {}
- self.sriov.flavor = {}
- self.sriov.configure_nics_for_sriov = mock.Mock(return_value="")
- mock_libvirt.build_vm_xml = mock.Mock(
- return_value=[6, "00:00:00:00:00:01"])
- self.sriov._enable_interfaces = mock.Mock(return_value="")
- self.sriov.vnf_node.generate_vnf_instance = mock.Mock(return_value={})
- self.assertIsNotNone(self.sriov.setup_sriov_context())
+ connection = mock.Mock()
+ self.sriov.connection = connection
+ self.sriov.host_mgmt = {'ip': '1.2.3.4'}
+ self.sriov.vm_flavor = 'flavor'
+ self.sriov.networks = 'networks'
+ self.sriov.configure_nics_for_sriov = mock.Mock()
+ cfg = '/tmp/vm_sriov_0.xml'
+ vm_name = 'vm_0'
+ xml_out = mock.Mock()
+ mock_build_vm_xml.return_value = (xml_out, '00:00:00:00:00:01')
+
+ with mock.patch.object(self.sriov, 'vnf_node') as mock_vnf_node, \
+ mock.patch.object(self.sriov, '_enable_interfaces'):
+ mock_vnf_node.generate_vnf_instance = mock.Mock(
+ return_value='node')
+ nodes_out = self.sriov.setup_sriov_context()
+ self.assertEqual(['node'], nodes_out)
+ mock_vnf_node.generate_vnf_instance.assert_called_once_with(
+ 'flavor', 'networks', '1.2.3.4', 'vnf_0',
+ self.sriov.servers['vnf_0'], '00:00:00:00:00:01')
+ mock_build_vm_xml.assert_called_once_with(
+ connection, 'flavor', vm_name, 0)
+ mock_create_vm.assert_called_once_with(connection, cfg)
+ mock_check.assert_called_once_with(vm_name, connection)
+ mock_write_file.assert_called_once_with(cfg, xml_out)
def test__get_vf_data(self):
with mock.patch("yardstick.ssh.SSH") as ssh: