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 ##############################################################################
16 import yardstick.ssh as ssh
17 from yardstick.benchmark.scenarios import base
19 LOG = logging.getLogger(__name__)
20 LOG.setLevel(logging.DEBUG)
23 class Cyclictest(base.Scenario):
24 """Execute cyclictest benchmark on guest vm
27 affinity - run thread #N on processor #N, if possible
31 interval - base interval of thread
35 loops - number of loops, 0 for endless
39 priority - priority of highest prio thread
43 threads - number of threads
47 histogram - dump a latency histogram to stdout after the run
48 here set the max time to be tracked
53 Read link below for more fio args description:
54 https://rt.wiki.kernel.org/index.php/Cyclictest
56 __scenario_type__ = "Cyclictest"
58 TARGET_SCRIPT = "cyclictest_benchmark.bash"
59 WORKSPACE = "/root/workspace/"
60 REBOOT_CMD_PATTERN = r";\s*reboot\b"
62 def __init__(self, scenario_cfg, context_cfg):
63 self.scenario_cfg = scenario_cfg
64 self.context_cfg = context_cfg
65 self.setup_done = False
67 def _put_files(self, client):
68 setup_options = self.scenario_cfg["setup_options"]
69 rpm_dir = setup_options["rpm_dir"]
70 script_dir = setup_options["script_dir"]
71 image_dir = setup_options["image_dir"]
72 LOG.debug("Send RPMs from %s to workspace %s" %
73 (rpm_dir, self.WORKSPACE))
74 client.put(rpm_dir, self.WORKSPACE, recursive=True)
75 LOG.debug("Send scripts from %s to workspace %s" %
76 (script_dir, self.WORKSPACE))
77 client.put(script_dir, self.WORKSPACE, recursive=True)
78 LOG.debug("Send guest image from %s to workspace %s" %
79 (image_dir, self.WORKSPACE))
80 client.put(image_dir, self.WORKSPACE, recursive=True)
82 def _connect_host(self):
83 host = self.context_cfg["host"]
84 user = host.get("user", "root")
85 ip = host.get("ip", None)
86 key_filename = host.get("key_filename", "~/.ssh/id_rsa")
88 LOG.debug("user:%s, host:%s", user, ip)
89 self.host = ssh.SSH(user, ip, key_filename=key_filename)
90 self.host.wait(timeout=600)
92 def _connect_guest(self):
93 host = self.context_cfg["host"]
94 user = host.get("user", "root")
95 ip = host.get("ip", None)
96 key_filename = host.get("key_filename", "~/.ssh/id_rsa")
98 LOG.debug("user:%s, host:%s", user, ip)
99 self.guest = ssh.SSH(user, ip, port=5555, key_filename=key_filename)
100 self.guest.wait(timeout=600)
102 def _run_setup_cmd(self, client, cmd):
103 LOG.debug("Run cmd: %s" % cmd)
104 status, stdout, stderr = client.execute(cmd)
106 if re.search(self.REBOOT_CMD_PATTERN, cmd):
107 LOG.debug("Error on reboot")
109 raise RuntimeError(stderr)
111 def _run_host_setup_scripts(self, scripts):
112 setup_options = self.scenario_cfg["setup_options"]
113 script_dir = os.path.basename(setup_options["script_dir"])
115 for script in scripts:
116 cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
117 (self.WORKSPACE, script_dir, script)
118 self._run_setup_cmd(self.host, cmd)
120 if re.search(self.REBOOT_CMD_PATTERN, cmd):
124 def _run_guest_setup_scripts(self, scripts):
125 setup_options = self.scenario_cfg["setup_options"]
126 script_dir = os.path.basename(setup_options["script_dir"])
128 for script in scripts:
129 cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
130 (self.WORKSPACE, script_dir, script)
131 self._run_setup_cmd(self.guest, cmd)
133 if re.search(self.REBOOT_CMD_PATTERN, cmd):
135 self._connect_guest()
139 setup_options = self.scenario_cfg["setup_options"]
140 host_setup_seqs = setup_options["host_setup_seqs"]
141 guest_setup_seqs = setup_options["guest_setup_seqs"]
144 self._put_files(self.host)
145 self._run_host_setup_scripts(host_setup_seqs)
147 self._connect_guest()
148 self._put_files(self.guest)
149 self._run_guest_setup_scripts(guest_setup_seqs)
151 # copy script to host
152 self.target_script = pkg_resources.resource_filename(
153 "yardstick.benchmark.scenarios.compute",
154 Cyclictest.TARGET_SCRIPT)
155 self.guest.run("cat > ~/cyclictest_benchmark.sh",
156 stdin=open(self.target_script, "rb"))
158 self.setup_done = True
160 def run(self, result):
161 """execute the benchmark"""
162 default_args = "-m -n -q"
164 if not self.setup_done:
167 options = self.scenario_cfg["options"]
168 affinity = options.get("affinity", 1)
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 -i %s -p %s -l %s -t %s -h %s %s" \
176 % (affinity, 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(json.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)
225 "max_min_latency": 100,
226 "max_avg_latency": 500,
227 "max_max_latency": 1000,
235 cyclictest = Cyclictest(args, ctx)
236 cyclictest.run(result)
239 if __name__ == '__main__': # pragma: no cover