summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQiLiang <liangqi1@huawei.com>2015-11-25 09:23:46 +0800
committerQiLiang <liangqi1@huawei.com>2016-01-10 09:59:03 +0000
commita33f57371c740e0ab749bfffa4d31c08ef5c5b74 (patch)
treec8d315a5e6fbfa81a2b022613c3df5dddbd15fe2
parent4f4edd840823ff6a0151e3f5220241183e27e560 (diff)
Support run cyclictest on BareMetal
JIRA: YARDSTICK-122 Change-Id: I8144215059a9abea08314a4c1e6a733dcdf0df53 Signed-off-by: QiLiang <liangqi1@huawei.com>
-rw-r--r--samples/cyclictest-node-context.yaml50
-rwxr-xr-xsetup.py1
-rw-r--r--tests/unit/benchmark/scenarios/compute/test_cyclictest.py159
-rw-r--r--yardstick/benchmark/scenarios/compute/cyclictest.py105
-rw-r--r--yardstick/ssh.py7
5 files changed, 227 insertions, 95 deletions
diff --git a/samples/cyclictest-node-context.yaml b/samples/cyclictest-node-context.yaml
new file mode 100644
index 000000000..d74d1e5e3
--- /dev/null
+++ b/samples/cyclictest-node-context.yaml
@@ -0,0 +1,50 @@
+---
+# Sample benchmark task config file
+# Measure system high resolution by using Cyclictest
+#
+# For this sample just like running the command below on the test vm and
+# getting latencies info back to the yardstick.
+#
+# sudo bash cyclictest -a 1 -i 1000 -p 99 -l 1000 -t 1 -h 90 -m -n -q
+#
+
+schema: "yardstick:task:0.1"
+
+scenarios:
+-
+ type: Cyclictest
+ options:
+ affinity: 1
+ interval: 1000
+ priority: 99
+ loops: 1000
+ threads: 1
+ histogram: 90
+ host: kvm.LF
+ runner:
+ type: Duration
+ duration: 1
+ interval: 1
+ sla:
+ max_min_latency: 50
+ max_avg_latency: 100
+ max_max_latency: 1000
+ action: monitor
+ setup_options:
+ rpm_dir: "/opt/rpm"
+ script_dir: "/opt/scripts"
+ image_dir: "/opt/image"
+ host_setup_seqs:
+ - "host-setup0.sh"
+ - "reboot"
+ - "host-setup1.sh"
+ - "host-run-qemu.sh"
+ guest_setup_seqs:
+ - "guest-setup0.sh"
+ - "reboot"
+ - "guest-setup1.sh"
+
+context:
+ type: Node
+ name: LF
+ file: /root/yardstick/pod.yaml
diff --git a/setup.py b/setup.py
index 3ef09d111..48f00f47c 100755
--- a/setup.py
+++ b/setup.py
@@ -36,6 +36,7 @@ setup(
"mock>=1.0.1", # remove with python3
"paramiko",
"netifaces",
+ "scp",
"six",
"testrepository>=0.0.18",
"testtools>=1.4.0"
diff --git a/tests/unit/benchmark/scenarios/compute/test_cyclictest.py b/tests/unit/benchmark/scenarios/compute/test_cyclictest.py
index a87b39142..807429025 100644
--- a/tests/unit/benchmark/scenarios/compute/test_cyclictest.py
+++ b/tests/unit/benchmark/scenarios/compute/test_cyclictest.py
@@ -22,41 +22,65 @@ from yardstick.benchmark.scenarios.compute import cyclictest
class CyclictestTestCase(unittest.TestCase):
def setUp(self):
- self.ctx = {
+ self.scenario_cfg = {
+ "host": "kvm.LF",
+ "setup_options": {
+ "rpm_dir": "/opt/rpm",
+ "host_setup_seqs": [
+ "host-setup0.sh",
+ "host-setup1.sh",
+ "host-run-qemu.sh"
+ ],
+ "script_dir": "/opt/scripts",
+ "image_dir": "/opt/image",
+ "guest_setup_seqs": [
+ "guest-setup0.sh",
+ "guest-setup1.sh"
+ ]
+ },
+ "sla": {
+ "action": "monitor",
+ "max_min_latency": 50,
+ "max_avg_latency": 100,
+ "max_max_latency": 1000
+ },
+ "options": {
+ "priority": 99,
+ "threads": 1,
+ "loops": 1000,
+ "affinity": 1,
+ "interval": 1000,
+ "histogram": 90
+ }
+ }
+ self.context_cfg = {
"host": {
- "ip": "192.168.50.28",
- "user": "root",
- "key_filename": "mykey.key"
+ "ip": "10.229.43.154",
+ "key_filename": "/yardstick/resources/files/yardstick_key",
+ "role": "BareMetal",
+ "name": "kvm.LF",
+ "user": "root"
}
}
def test_cyclictest_successful_setup(self, mock_ssh):
- c = cyclictest.Cyclictest({}, self.ctx)
- c.setup()
-
+ c = cyclictest.Cyclictest(self.scenario_cfg, self.context_cfg)
mock_ssh.SSH().execute.return_value = (0, '', '')
- self.assertIsNotNone(c.client)
+
+ c.setup()
+ self.assertIsNotNone(c.guest)
+ self.assertIsNotNone(c.host)
self.assertEqual(c.setup_done, True)
def test_cyclictest_successful_no_sla(self, mock_ssh):
-
- options = {
- "affinity": 2,
- "interval": 100,
- "priority": 88,
- "loops": 10000,
- "threads": 2,
- "histogram": 80
- }
- args = {
- "options": options,
- }
- c = cyclictest.Cyclictest(args, self.ctx)
result = {}
+ self.scenario_cfg.pop("sla", None)
+ c = cyclictest.Cyclictest(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH().execute.return_value = (0, '', '')
+ c.setup()
- c.server = mock_ssh.SSH()
-
+ c.guest = mock_ssh.SSH()
sample_output = '{"min": 100, "avg": 500, "max": 1000}'
mock_ssh.SSH().execute.return_value = (0, sample_output, '')
@@ -65,29 +89,19 @@ class CyclictestTestCase(unittest.TestCase):
self.assertEqual(result, expected_result)
def test_cyclictest_successful_sla(self, mock_ssh):
-
- options = {
- "affinity": 2,
- "interval": 100,
- "priority": 88,
- "loops": 10000,
- "threads": 2,
- "histogram": 80
- }
- sla = {
- "max_min_latency": 100,
- "max_avg_latency": 500,
- "max_max_latency": 1000,
- }
- args = {
- "options": options,
- "sla": sla
- }
- c = cyclictest.Cyclictest(args, self.ctx)
result = {}
+ self.scenario_cfg.update({"sla": {
+ "action": "monitor",
+ "max_min_latency": 100,
+ "max_avg_latency": 500,
+ "max_max_latency": 1000
+ }
+ })
+ c = cyclictest.Cyclictest(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH().execute.return_value = (0, '', '')
+ c.setup()
- c.server = mock_ssh.SSH()
-
+ c.guest = mock_ssh.SSH()
sample_output = '{"min": 100, "avg": 500, "max": 1000}'
mock_ssh.SSH().execute.return_value = (0, sample_output, '')
@@ -97,14 +111,13 @@ class CyclictestTestCase(unittest.TestCase):
def test_cyclictest_unsuccessful_sla_min_latency(self, mock_ssh):
- args = {
- "options": {},
- "sla": {"max_min_latency": 10}
- }
- c = cyclictest.Cyclictest(args, self.ctx)
result = {}
+ self.scenario_cfg.update({"sla": {"max_min_latency": 10}})
+ c = cyclictest.Cyclictest(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH().execute.return_value = (0, '', '')
+ c.setup()
- c.server = mock_ssh.SSH()
+ c.guest = mock_ssh.SSH()
sample_output = '{"min": 100, "avg": 500, "max": 1000}'
mock_ssh.SSH().execute.return_value = (0, sample_output, '')
@@ -112,14 +125,13 @@ class CyclictestTestCase(unittest.TestCase):
def test_cyclictest_unsuccessful_sla_avg_latency(self, mock_ssh):
- args = {
- "options": {},
- "sla": {"max_avg_latency": 10}
- }
- c = cyclictest.Cyclictest(args, self.ctx)
result = {}
+ self.scenario_cfg.update({"sla": {"max_avg_latency": 10}})
+ c = cyclictest.Cyclictest(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH().execute.return_value = (0, '', '')
+ c.setup()
- c.server = mock_ssh.SSH()
+ c.guest = mock_ssh.SSH()
sample_output = '{"min": 100, "avg": 500, "max": 1000}'
mock_ssh.SSH().execute.return_value = (0, sample_output, '')
@@ -127,14 +139,13 @@ class CyclictestTestCase(unittest.TestCase):
def test_cyclictest_unsuccessful_sla_max_latency(self, mock_ssh):
- args = {
- "options": {},
- "sla": {"max_max_latency": 10}
- }
- c = cyclictest.Cyclictest(args, self.ctx)
result = {}
+ self.scenario_cfg.update({"sla": {"max_max_latency": 10}})
+ c = cyclictest.Cyclictest(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH().execute.return_value = (0, '', '')
+ c.setup()
- c.server = mock_ssh.SSH()
+ c.guest = mock_ssh.SSH()
sample_output = '{"min": 100, "avg": 500, "max": 1000}'
mock_ssh.SSH().execute.return_value = (0, sample_output, '')
@@ -142,27 +153,13 @@ class CyclictestTestCase(unittest.TestCase):
def test_cyclictest_unsuccessful_script_error(self, mock_ssh):
- options = {
- "affinity": 2,
- "interval": 100,
- "priority": 88,
- "loops": 10000,
- "threads": 2,
- "histogram": 80
- }
- sla = {
- "max_min_latency": 100,
- "max_avg_latency": 500,
- "max_max_latency": 1000,
- }
- args = {
- "options": options,
- "sla": sla
- }
- c = cyclictest.Cyclictest(args, self.ctx)
result = {}
+ self.scenario_cfg.update({"sla": {"max_max_latency": 10}})
+ c = cyclictest.Cyclictest(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH().execute.return_value = (0, '', '')
+ c.setup()
- c.server = mock_ssh.SSH()
+ c.guest = mock_ssh.SSH()
mock_ssh.SSH().execute.return_value = (1, '', 'FOOBAR')
self.assertRaises(RuntimeError, c.run, result)
diff --git a/yardstick/benchmark/scenarios/compute/cyclictest.py b/yardstick/benchmark/scenarios/compute/cyclictest.py
index e8fc63cf7..478b0a1a2 100644
--- a/yardstick/benchmark/scenarios/compute/cyclictest.py
+++ b/yardstick/benchmark/scenarios/compute/cyclictest.py
@@ -9,6 +9,9 @@
import pkg_resources
import logging
import json
+import re
+import time
+import os
import yardstick.ssh as ssh
from yardstick.benchmark.scenarios import base
@@ -53,30 +56,104 @@ class Cyclictest(base.Scenario):
__scenario_type__ = "Cyclictest"
TARGET_SCRIPT = "cyclictest_benchmark.bash"
+ WORKSPACE = "/root/workspace/"
+ REBOOT_CMD_PATTERN = r";\s*reboot\b"
def __init__(self, scenario_cfg, context_cfg):
self.scenario_cfg = scenario_cfg
self.context_cfg = context_cfg
self.setup_done = False
- def setup(self):
- '''scenario setup'''
- self.target_script = pkg_resources.resource_filename(
- "yardstick.benchmark.scenarios.compute",
- Cyclictest.TARGET_SCRIPT)
+ def _put_files(self, client):
+ setup_options = self.scenario_cfg["setup_options"]
+ rpm_dir = setup_options["rpm_dir"]
+ script_dir = setup_options["script_dir"]
+ image_dir = setup_options["image_dir"]
+ LOG.debug("Send RPMs from %s to workspace %s" %
+ (rpm_dir, self.WORKSPACE))
+ client.put(rpm_dir, self.WORKSPACE, recursive=True)
+ LOG.debug("Send scripts from %s to workspace %s" %
+ (script_dir, self.WORKSPACE))
+ client.put(script_dir, self.WORKSPACE, recursive=True)
+ LOG.debug("Send guest image from %s to workspace %s" %
+ (image_dir, self.WORKSPACE))
+ client.put(image_dir, self.WORKSPACE, recursive=True)
+
+ def _connect_host(self):
+ host = self.context_cfg["host"]
+ user = host.get("user", "root")
+ ip = host.get("ip", None)
+ key_filename = host.get("key_filename", "~/.ssh/id_rsa")
+
+ LOG.debug("user:%s, host:%s", user, ip)
+ self.host = ssh.SSH(user, ip, key_filename=key_filename)
+ self.host.wait(timeout=600)
+
+ def _connect_guest(self):
host = self.context_cfg["host"]
user = host.get("user", "root")
ip = host.get("ip", None)
key_filename = host.get("key_filename", "~/.ssh/id_rsa")
LOG.debug("user:%s, host:%s", user, ip)
- print "key_filename:" + key_filename
- self.client = ssh.SSH(user, ip, key_filename=key_filename)
- self.client.wait(timeout=600)
+ self.guest = ssh.SSH(user, ip, port=5555, key_filename=key_filename)
+ self.guest.wait(timeout=600)
+
+ def _run_setup_cmd(self, client, cmd):
+ LOG.debug("Run cmd: %s" % cmd)
+ status, stdout, stderr = client.execute(cmd)
+ if status:
+ if re.search(self.REBOOT_CMD_PATTERN, cmd):
+ LOG.debug("Error on reboot")
+ else:
+ raise RuntimeError(stderr)
+
+ def _run_host_setup_scripts(self, scripts):
+ setup_options = self.scenario_cfg["setup_options"]
+ script_dir = os.path.basename(setup_options["script_dir"])
+
+ for script in scripts:
+ cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
+ (self.WORKSPACE, script_dir, script)
+ self._run_setup_cmd(self.host, cmd)
+
+ if re.search(self.REBOOT_CMD_PATTERN, cmd):
+ time.sleep(3)
+ self._connect_host()
+
+ def _run_guest_setup_scripts(self, scripts):
+ setup_options = self.scenario_cfg["setup_options"]
+ script_dir = os.path.basename(setup_options["script_dir"])
+
+ for script in scripts:
+ cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
+ (self.WORKSPACE, script_dir, script)
+ self._run_setup_cmd(self.guest, cmd)
+
+ if re.search(self.REBOOT_CMD_PATTERN, cmd):
+ time.sleep(3)
+ self._connect_guest()
+
+ def setup(self):
+ '''scenario setup'''
+ setup_options = self.scenario_cfg["setup_options"]
+ host_setup_seqs = setup_options["host_setup_seqs"]
+ guest_setup_seqs = setup_options["guest_setup_seqs"]
+
+ self._connect_host()
+ self._put_files(self.host)
+ self._run_host_setup_scripts(host_setup_seqs)
+
+ self._connect_guest()
+ self._put_files(self.guest)
+ self._run_guest_setup_scripts(guest_setup_seqs)
# copy script to host
- self.client.run("cat > ~/cyclictest_benchmark.sh",
- stdin=open(self.target_script, "rb"))
+ self.target_script = pkg_resources.resource_filename(
+ "yardstick.benchmark.scenarios.compute",
+ Cyclictest.TARGET_SCRIPT)
+ self.guest.run("cat > ~/cyclictest_benchmark.sh",
+ stdin=open(self.target_script, "rb"))
self.setup_done = True
@@ -98,9 +175,9 @@ class Cyclictest(base.Scenario):
cmd_args = "-a %s -i %s -p %s -l %s -t %s -h %s %s" \
% (affinity, interval, priority, loops,
threads, histogram, default_args)
- cmd = "sudo bash cyclictest_benchmark.sh %s" % (cmd_args)
+ cmd = "bash cyclictest_benchmark.sh %s" % (cmd_args)
LOG.debug("Executing command: %s", cmd)
- status, stdout, stderr = self.client.execute(cmd)
+ status, stdout, stderr = self.guest.execute(cmd)
if status:
raise RuntimeError(stderr)
@@ -121,7 +198,7 @@ class Cyclictest(base.Scenario):
assert sla_error == "", sla_error
-def _test():
+def _test(): # pragma: no cover
'''internal test function'''
key_filename = pkg_resources.resource_filename("yardstick.resources",
"files/yardstick_key")
@@ -159,5 +236,5 @@ def _test():
cyclictest.run(result)
print result
-if __name__ == '__main__':
+if __name__ == '__main__': # pragma: no cover
_test()
diff --git a/yardstick/ssh.py b/yardstick/ssh.py
index 253fd2e3d..339f834b7 100644
--- a/yardstick/ssh.py
+++ b/yardstick/ssh.py
@@ -63,6 +63,7 @@ import socket
import time
import paramiko
+from scp import SCPClient
import six
import logging
@@ -254,3 +255,9 @@ class SSH(object):
time.sleep(interval)
if time.time() > (start_time + timeout):
raise SSHTimeout("Timeout waiting for '%s'" % self.host)
+
+ def put(self, files, remote_path=b'.', recursive=False):
+ client = self._get_client()
+
+ with SCPClient(client.get_transport()) as scp:
+ scp.put(files, remote_path, recursive)