aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/benchmark
diff options
context:
space:
mode:
Diffstat (limited to 'yardstick/benchmark')
-rw-r--r--yardstick/benchmark/contexts/standalone/model.py6
-rw-r--r--yardstick/benchmark/contexts/standalone/ovs_dpdk.py51
-rw-r--r--yardstick/benchmark/core/report.py103
-rw-r--r--yardstick/benchmark/scenarios/storage/storperf.py4
4 files changed, 123 insertions, 41 deletions
diff --git a/yardstick/benchmark/contexts/standalone/model.py b/yardstick/benchmark/contexts/standalone/model.py
index fda667137..aa5fdd391 100644
--- a/yardstick/benchmark/contexts/standalone/model.py
+++ b/yardstick/benchmark/contexts/standalone/model.py
@@ -45,7 +45,7 @@ VM_TEMPLATE = """
<vcpu cpuset='{cpuset}'>{vcpu}</vcpu>
{cputune}
<os>
- <type arch="x86_64" machine="pc-i440fx-xenial">hvm</type>
+ <type arch="x86_64" machine="{machine}">hvm</type>
<boot dev="hd" />
</os>
<features>
@@ -306,6 +306,7 @@ class Libvirt(object):
cpuset = Libvirt.pin_vcpu_for_perf(connection, hw_socket)
cputune = extra_spec.get('cputune', '')
+ machine = extra_spec.get('machine_type', 'pc-i440fx-xenial')
mac = StandaloneContextHelper.get_mac_address(0x00)
image = cls.create_snapshot_qemu(connection, index,
flavor.get("images", None))
@@ -316,7 +317,8 @@ class Libvirt(object):
memory=memory, vcpu=vcpu, cpu=cpu,
numa_cpus=numa_cpus,
socket=socket, threads=threads,
- vm_image=image, cpuset=cpuset, cputune=cputune)
+ vm_image=image, cpuset=cpuset,
+ machine=machine, cputune=cputune)
# Add CD-ROM device
vm_xml = Libvirt.add_cdrom(cdrom_img, vm_xml)
diff --git a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py
index 42a275455..c6e19f614 100644
--- a/yardstick/benchmark/contexts/standalone/ovs_dpdk.py
+++ b/yardstick/benchmark/contexts/standalone/ovs_dpdk.py
@@ -74,6 +74,11 @@ class OvsDpdkContext(base.Context):
self.wait_for_vswitchd = 10
super(OvsDpdkContext, self).__init__()
+ def get_dpdk_socket_mem_size(self, socket_id):
+ """Get the size of OvS DPDK socket memory (Mb)"""
+ ram = self.ovs_properties.get("ram", {})
+ return ram.get('socket_%d' % (socket_id), 2048)
+
def init(self, attrs):
"""initializes itself from the supplied arguments"""
super(OvsDpdkContext, self).init(attrs)
@@ -134,9 +139,6 @@ class OvsDpdkContext(base.Context):
if pmd_cpu_mask:
pmd_mask = pmd_cpu_mask
- socket0 = self.ovs_properties.get("ram", {}).get("socket_0", "2048")
- socket1 = self.ovs_properties.get("ram", {}).get("socket_1", "2048")
-
ovs_other_config = "ovs-vsctl {0}set Open_vSwitch . other_config:{1}"
detach_cmd = "ovs-vswitchd unix:{0}{1} --pidfile --detach --log-file={2}"
@@ -154,7 +156,9 @@ class OvsDpdkContext(base.Context):
("ovsdb-server --remote=punix:/{0}/{1} --remote=ptcp:6640"
" --pidfile --detach").format(vpath, ovs_sock_path),
ovs_other_config.format("--no-wait ", "dpdk-init=true"),
- ovs_other_config.format("--no-wait ", "dpdk-socket-mem='%s,%s'" % (socket0, socket1)),
+ ovs_other_config.format("--no-wait ", "dpdk-socket-mem='%d,%d'" % (
+ self.get_dpdk_socket_mem_size(0),
+ self.get_dpdk_socket_mem_size(1))),
lcore_mask,
detach_cmd.format(vpath, ovs_sock_path, log_path),
ovs_other_config.format("", "pmd-cpu-mask=%s" % pmd_mask),
@@ -168,12 +172,12 @@ class OvsDpdkContext(base.Context):
def setup_ovs_bridge_add_flows(self):
dpdk_args = ""
- dpdk_list = []
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}{dpdk_rxq}')
+ 'set Interface {port} type={type_}{dpdk_args}'
+ '{dpdk_rxq}{pmd_rx_aff}')
chmod_vpath = 'chmod 0777 {0}/var/run/openvswitch/dpdkvhostuser*'
cmd_list = [
@@ -187,23 +191,38 @@ class OvsDpdkContext(base.Context):
if queues:
dpdk_rxq = " options:n_rxq={queue}".format(queue=queues)
- ordered_network = collections.OrderedDict(self.networks)
+ # Sorting the array to make sure we execute dpdk0... in the order
+ ordered_network = collections.OrderedDict(
+ sorted(self.networks.items(), key=lambda t: t[1].get('port_num', 0)))
+ pmd_rx_aff_ports = self.ovs_properties.get("dpdk_pmd-rxq-affinity", {})
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(
+ affinity = pmd_rx_aff_ports.get(vnf.get("port_num", -1), "")
+ if affinity:
+ pmd_rx_aff = ' other_config:pmd-rxq-affinity=' \
+ '"{affinity}"'.format(affinity=affinity)
+ else:
+ pmd_rx_aff = ""
+ cmd_list.append(ovs_add_port.format(
br=MAIN_BRIDGE, port='dpdk%s' % vnf.get("port_num", 0),
- type_='dpdk', dpdk_args=dpdk_args, dpdk_rxq=dpdk_rxq))
-
- # Sorting the array to make sure we execute dpdk0... in the order
- list.sort(dpdk_list)
- cmd_list.extend(dpdk_list)
+ type_='dpdk', dpdk_args=dpdk_args, dpdk_rxq=dpdk_rxq,
+ pmd_rx_aff=pmd_rx_aff))
# Need to do two for loop to maintain the dpdk/vhost ports.
+ pmd_rx_aff_ports = self.ovs_properties.get("vhost_pmd-rxq-affinity",
+ {})
for index, _ in enumerate(ordered_network):
+ affinity = pmd_rx_aff_ports.get(index)
+ if affinity:
+ pmd_rx_aff = ' other_config:pmd-rxq-affinity=' \
+ '"{affinity}"'.format(affinity=affinity)
+ else:
+ pmd_rx_aff = ""
cmd_list.append(ovs_add_port.format(
br=MAIN_BRIDGE, port='dpdkvhostuser%s' % index,
- type_='dpdkvhostuser', dpdk_args="", dpdk_rxq=""))
+ type_='dpdkvhostuser', dpdk_args="", dpdk_rxq=dpdk_rxq,
+ pmd_rx_aff=pmd_rx_aff))
ovs_flow = ("ovs-ofctl add-flow {0} in_port=%s,action=output:%s".
format(MAIN_BRIDGE))
@@ -399,7 +418,9 @@ class OvsDpdkContext(base.Context):
self.configure_nics_for_ovs_dpdk()
hp_total_mb = int(self.vm_flavor.get('ram', '4096')) * len(self.servers)
- common_utils.setup_hugepages(self.connection, hp_total_mb * 1024)
+ common_utils.setup_hugepages(self.connection, (hp_total_mb + \
+ self.get_dpdk_socket_mem_size(0) + \
+ self.get_dpdk_socket_mem_size(1)) * 1024)
self._check_hugepages()
diff --git a/yardstick/benchmark/core/report.py b/yardstick/benchmark/core/report.py
index 199602444..a484a49f3 100644
--- a/yardstick/benchmark/core/report.py
+++ b/yardstick/benchmark/core/report.py
@@ -1,7 +1,7 @@
-#############################################################################
-# Copyright (c) 2017 Rajesh Kudaka
+##############################################################################
+# Copyright (c) 2017 Rajesh Kudaka <4k.rajesh@gmail.com>
+# Copyright (c) 2018 Intel Corporation.
#
-# Author: Rajesh Kudaka 4k.rajesh@gmail.com
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
@@ -10,27 +10,76 @@
""" Handler for yardstick command 'report' """
-from __future__ import print_function
-
-from __future__ import absolute_import
-
import ast
import re
import uuid
+import jinja2
from api.utils import influx
-
-from django.conf import settings
-from django.template import Context
-from django.template import Template
-
from oslo_utils import encodeutils
from oslo_utils import uuidutils
from yardstick.common import constants as consts
-from yardstick.common.html_template import template
from yardstick.common.utils import cliargs
-settings.configure()
+
+class JSTree(object):
+ """Data structure to parse data for use with the JS library jsTree"""
+ def __init__(self):
+ self._created_nodes = ['#']
+ self.jstree_data = []
+
+ def _create_node(self, _id):
+ """Helper method for format_for_jstree to create each node.
+
+ Creates the node (and any required parents) and keeps track
+ of the created nodes.
+
+ :param _id: (string) id of the node to be created
+ :return: None
+ """
+ components = _id.split(".")
+
+ if len(components) == 1:
+ text = components[0]
+ parent_id = "#"
+ else:
+ text = components[-1]
+ parent_id = ".".join(components[:-1])
+ # make sure the parent has been created
+ if not parent_id in self._created_nodes:
+ self._create_node(parent_id)
+
+ self.jstree_data.append({"id": _id, "text": text, "parent": parent_id})
+ self._created_nodes.append(_id)
+
+ def format_for_jstree(self, data):
+ """Format the data into the required format for jsTree.
+
+ The data format expected is a list of key-value pairs which represent
+ the data and name for each metric e.g.:
+
+ [{'data': [0, ], 'name': 'tg__0.DropPackets'},
+ {'data': [548, ], 'name': 'tg__0.LatencyAvg.5'},]
+
+ This data is converted into the format required for jsTree to group and
+ display the metrics in a hierarchial fashion, including creating a
+ number of parent nodes e.g.::
+
+ [{"id": "tg__0", "text": "tg__0", "parent": "#"},
+ {"id": "tg__0.DropPackets", "text": "DropPackets", "parent": "tg__0"},
+ {"id": "tg__0.LatencyAvg", "text": "LatencyAvg", "parent": "tg__0"},
+ {"id": "tg__0.LatencyAvg.5", "text": "5", "parent": "tg__0.LatencyAvg"},]
+
+ :param data: (list) data to be converted
+ :return: list
+ """
+ self._created_nodes = ['#']
+ self.jstree_data = []
+
+ for item in data:
+ self._create_node(item["name"])
+
+ return self.jstree_data
class Report(object):
@@ -64,7 +113,7 @@ class Report(object):
if query_exec:
return query_exec
else:
- raise KeyError("Task ID or Test case not found..")
+ raise KeyError("Test case not found.")
def _get_tasks(self):
task_cmd = "select * from \"%s\" where task_id= '%s'"
@@ -73,7 +122,7 @@ class Report(object):
if query_exec:
return query_exec
else:
- raise KeyError("Task ID or Test case not found..")
+ raise KeyError("Task ID or Test case not found.")
@cliargs("task_id", type=str, help=" task id", nargs=1)
@cliargs("yaml_name", type=str, help=" Yaml file Name", nargs=1)
@@ -117,12 +166,22 @@ class Report(object):
series['data'] = values
temp_series.append(series)
- Template_html = Template(template)
- Context_html = Context({"series": temp_series,
- "Timestamp": self.Timestamp,
- "task_id": self.task_id,
- "table": table_vals})
+ template_dir = consts.YARDSTICK_ROOT_PATH + "yardstick/common"
+ template_environment = jinja2.Environment(
+ autoescape=False,
+ loader=jinja2.FileSystemLoader(template_dir),
+ trim_blocks=False)
+
+ context = {
+ "series": temp_series,
+ "Timestamps": self.Timestamp,
+ "task_id": self.task_id,
+ "table": table_vals,
+ }
+
+ template_html = template_environment.get_template("report.html.j2")
+
with open(consts.DEFAULT_HTML_FILE, "w") as file_open:
- file_open.write(Template_html.render(Context_html))
+ file_open.write(template_html.render(context))
print("Report generated. View /tmp/yardstick.htm")
diff --git a/yardstick/benchmark/scenarios/storage/storperf.py b/yardstick/benchmark/scenarios/storage/storperf.py
index 7c8e5fe66..5b8b00075 100644
--- a/yardstick/benchmark/scenarios/storage/storperf.py
+++ b/yardstick/benchmark/scenarios/storage/storperf.py
@@ -227,8 +227,8 @@ class StorPerf(base.Scenario):
LOG.info("Job %s completed with steady state %s",
job_id, steady_state)
- result_res = requests.get('http://%s:5000/api/v1.0/jobs?'
- 'type=status&id=%s' % (self.target, job_id))
+ result_res = requests.get('http://%s:5000/api/v1.0/jobs?id=%s' %
+ (self.target, job_id))
result_res_content = jsonutils.loads(
result_res.content)
result.update(result_res_content)