aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries/python/honeycomb/Performance.py
diff options
context:
space:
mode:
Diffstat (limited to 'resources/libraries/python/honeycomb/Performance.py')
-rw-r--r--resources/libraries/python/honeycomb/Performance.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/resources/libraries/python/honeycomb/Performance.py b/resources/libraries/python/honeycomb/Performance.py
new file mode 100644
index 0000000000..1c6b0bc522
--- /dev/null
+++ b/resources/libraries/python/honeycomb/Performance.py
@@ -0,0 +1,129 @@
+# Copyright (c) 2017 Cisco and/or its affiliates.
+# 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.
+
+"""Implementation of keywords for testing Honeycomb performance."""
+
+from resources.libraries.python.ssh import SSH
+from resources.libraries.python.constants import Constants as Const
+from resources.libraries.python.honeycomb.HoneycombUtil import HoneycombError
+
+
+class Performance(object):
+ """Keywords used in Honeycomb performance testing."""
+
+ def __init__(self):
+ """Initializer."""
+ pass
+
+ @staticmethod
+ def configure_netconf_threads(node, threads):
+ """Set Honeycomb's Netconf thread count in configuration.
+
+ :param node: Honeycomb node.
+ :param threads: Number of threads.
+ :type node: dict
+ :type threads: int
+ :raises HoneycombError: If the operation fails.
+ """
+
+ find = "netconf-netty-threads"
+ replace = '\\"netconf-netty-threads\\": {0},'.format(threads)
+
+ argument = '"/{0}/c\\ {1}"'.format(find, replace)
+ path = "{0}/config/honeycomb.json".format(Const.REMOTE_HC_DIR)
+ command = "sed -i {0} {1}".format(argument, path)
+
+ ssh = SSH()
+ ssh.connect(node)
+ (ret_code, _, stderr) = ssh.exec_command_sudo(command)
+ if ret_code != 0:
+ raise HoneycombError("Failed to modify configuration on "
+ "node {0}, {1}".format(node, stderr))
+
+ @staticmethod
+ def run_traffic_script_on_dut(node, script, cores, reserved=2,
+ *args, **kwargs):
+ """Copy traffic script over to the specified node and execute with
+ the provided arguments.
+
+ :param node: Node in topology.
+ :param script: Name of the script to execute.
+ :param cores: Number of processor cores to use.
+ :param reserved: Number of cores reserved for other tasks. Default is 2,
+ one for system tasks and one for VPP main thread.
+ :param args: Sequential arguments for the script.
+ :param kwargs: Named arguments for the script.
+ :type node: dict
+ :type script: str
+ :type cores: int
+ :type reserved: int
+ :type args: list
+ :type kwargs: dict
+ """
+
+ path = "resources/traffic_scripts/honeycomb/{0}".format(script)
+
+ # Assemble arguments for traffic script
+ arguments = ""
+ for arg in args:
+ arguments += "{0} ".format(arg)
+
+ for key, value in kwargs.items():
+ arguments += "--{0} {1} ".format(key, value)
+
+ ssh = SSH()
+ ssh.connect(node)
+ ssh.scp(path, "/tmp")
+
+ # Use alternate scheduler, Ubuntu's default can't load-balance
+ # over isolcpus
+ scheduler = "chrt -f 99"
+ core_afi = "taskset -c {first}-{last}".format(
+ first=reserved, last=cores-1)
+
+ cmd = "{scheduler} {affinity} python /tmp/{script} {args}".format(
+ scheduler=scheduler,
+ affinity=core_afi,
+ script=script,
+ args=arguments)
+
+ ret_code, stdout, _ = ssh.exec_command_sudo(cmd, timeout=600)
+
+ ssh.exec_command("sudo pkill python ; rm /tmp/{0}".format(script))
+ if ret_code != 0:
+ raise HoneycombError("Traffic script failed to execute.")
+ for line in stdout.splitlines():
+ if "Avg. requests" in line:
+ return line
+
+ @staticmethod
+ def log_core_schedule(node, process):
+ """Determine which cores the process' threads are running on.
+
+ :param node: Honeycomb node.
+ :param process: Name of the process.
+ :type node: dict
+ :type process: str
+ """
+
+ # Get info on process and all of its children
+ cmd1 = """cat /proc/`pidof {0}`/task/*/stat""".format(process)
+
+ # Parse process ID, name and core index
+ cmd2 = """awk '{print $1" "$2" "$39}'"""
+
+ cmd = "{0} | {1}".format(cmd1, cmd2)
+
+ ssh = SSH()
+ ssh.connect(node)
+ ssh.exec_command(cmd)