1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and other.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 from __future__ import absolute_import
10 from __future__ import print_function
18 from oslo_serialization import jsonutils
20 import yardstick.ssh as ssh
21 from yardstick.benchmark.scenarios import base
23 LOG = logging.getLogger(__name__)
24 LOG.setLevel(logging.DEBUG)
27 class Cyclictest(base.Scenario):
28 """Execute cyclictest benchmark on guest vm
31 affinity - run thread #N on processor #N, if possible
35 interval - base interval of thread
39 loops - number of loops, 0 for endless
43 priority - priority of highest prio thread
47 threads - number of threads
51 histogram - dump a latency histogram to stdout after the run
52 here set the max time to be tracked
57 Read link below for more fio args description:
58 https://rt.wiki.kernel.org/index.php/Cyclictest
60 __scenario_type__ = "Cyclictest"
62 TARGET_SCRIPT = "cyclictest_benchmark.bash"
63 WORKSPACE = "/root/workspace/"
64 REBOOT_CMD_PATTERN = r";\s*reboot\b"
66 def __init__(self, scenario_cfg, context_cfg):
67 self.scenario_cfg = scenario_cfg
68 self.context_cfg = context_cfg
69 self.setup_done = False
71 def _put_files(self, client):
72 setup_options = self.scenario_cfg["setup_options"]
73 rpm_dir = setup_options["rpm_dir"]
74 script_dir = setup_options["script_dir"]
75 image_dir = setup_options["image_dir"]
76 LOG.debug("Send RPMs from %s to workspace %s",
77 rpm_dir, self.WORKSPACE)
78 client.put(rpm_dir, self.WORKSPACE, recursive=True)
79 LOG.debug("Send scripts from %s to workspace %s",
80 script_dir, self.WORKSPACE)
81 client.put(script_dir, self.WORKSPACE, recursive=True)
82 LOG.debug("Send guest image from %s to workspace %s",
83 image_dir, self.WORKSPACE)
84 client.put(image_dir, self.WORKSPACE, recursive=True)
86 def _connect_host(self):
87 host = self.context_cfg["host"]
89 self.host = ssh.SSH.from_node(host, defaults={"user": "root"})
90 self.host.wait(timeout=600)
92 def _connect_guest(self):
93 host = self.context_cfg["host"]
95 self.guest = ssh.SSH.from_node(host,
97 "user": "root", "ssh_port": 5555
99 self.guest.wait(timeout=600)
101 def _run_setup_cmd(self, client, cmd):
102 LOG.debug("Run cmd: %s", cmd)
103 status, stdout, stderr = client.execute(cmd)
105 if re.search(self.REBOOT_CMD_PATTERN, cmd):
106 LOG.debug("Error on reboot")
108 raise RuntimeError(stderr)
110 def _run_host_setup_scripts(self, scripts):
111 setup_options = self.scenario_cfg["setup_options"]
112 script_dir = os.path.basename(setup_options["script_dir"])
114 for script in scripts:
115 cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
116 (self.WORKSPACE, script_dir, script)
117 self._run_setup_cmd(self.host, cmd)
119 if re.search(self.REBOOT_CMD_PATTERN, cmd):
123 def _run_guest_setup_scripts(self, scripts):
124 setup_options = self.scenario_cfg["setup_options"]
125 script_dir = os.path.basename(setup_options["script_dir"])
127 for script in scripts:
128 cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
129 (self.WORKSPACE, script_dir, script)
130 self._run_setup_cmd(self.guest, cmd)
132 if re.search(self.REBOOT_CMD_PATTERN, cmd):
134 self._connect_guest()
138 setup_options = self.scenario_cfg["setup_options"]
139 host_setup_seqs = setup_options["host_setup_seqs"]
140 guest_setup_seqs = setup_options["guest_setup_seqs"]
143 self._put_files(self.host)
144 self._run_host_setup_scripts(host_setup_seqs)
146 self._connect_guest()
147 self._put_files(self.guest)
148 self._run_guest_setup_scripts(guest_setup_seqs)
150 # copy script to host
151 self.target_script = pkg_resources.resource_filename(
152 "yardstick.benchmark.scenarios.compute",
153 Cyclictest.TARGET_SCRIPT)
154 self.guest._put_file_shell(
155 self.target_script, '~/cyclictest_benchmark.sh')
157 self.setup_done = True
159 def run(self, result):
160 """execute the benchmark"""
161 default_args = "-m -n -q --notrace"
163 if not self.setup_done:
166 options = self.scenario_cfg["options"]
167 affinity = options.get("affinity", 1)
168 breaktrace = options.get("breaktrace", 1000)
169 interval = options.get("interval", 1000)
170 priority = options.get("priority", 99)
171 loops = options.get("loops", 1000)
172 threads = options.get("threads", 1)
173 histogram = options.get("histogram", 90)
175 cmd_args = "-a %s -b %s -i %s -p %s -l %s -t %s -h %s %s" \
176 % (affinity, breaktrace, interval, priority, loops,
177 threads, histogram, default_args)
178 cmd = "bash cyclictest_benchmark.sh %s" % (cmd_args)
179 LOG.debug("Executing command: %s", cmd)
180 status, stdout, stderr = self.guest.execute(cmd)
182 raise RuntimeError(stderr)
184 result.update(jsonutils.loads(stdout))
186 if "sla" in self.scenario_cfg:
188 for t, latency in result.items():
189 if 'max_%s_latency' % t not in self.scenario_cfg['sla']:
192 sla_latency = int(self.scenario_cfg['sla'][
193 'max_%s_latency' % t])
194 latency = int(latency)
195 if latency > sla_latency:
196 sla_error += "%s latency %d > sla:max_%s_latency(%d); " % \
197 (t, latency, t, sla_latency)
198 assert sla_error == "", sla_error
201 def _test(): # pragma: no cover
202 """internal test function"""
203 key_filename = pkg_resources.resource_filename("yardstick.resources",
204 "files/yardstick_key")
207 "ip": "10.229.47.137",
209 "key_filename": key_filename
213 logger = logging.getLogger("yardstick")
214 logger.setLevel(logging.DEBUG)
226 "max_min_latency": 100,
227 "max_avg_latency": 500,
228 "max_max_latency": 1000,
236 cyclictest = Cyclictest(args, ctx)
237 cyclictest.run(result)
241 if __name__ == '__main__': # pragma: no cover