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 ssh_port = host.get("ssh_port", 5555)
97 key_filename = host.get("key_filename", "~/.ssh/id_rsa")
99 LOG.debug("user:%s, host:%s", user, ip)
100 self.guest = ssh.SSH(user, ip, port=ssh_port,
101 key_filename=key_filename)
102 self.guest.wait(timeout=600)
104 def _run_setup_cmd(self, client, cmd):
105 LOG.debug("Run cmd: %s", cmd)
106 status, stdout, stderr = client.execute(cmd)
108 if re.search(self.REBOOT_CMD_PATTERN, cmd):
109 LOG.debug("Error on reboot")
111 raise RuntimeError(stderr)
113 def _run_host_setup_scripts(self, scripts):
114 setup_options = self.scenario_cfg["setup_options"]
115 script_dir = os.path.basename(setup_options["script_dir"])
117 for script in scripts:
118 cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
119 (self.WORKSPACE, script_dir, script)
120 self._run_setup_cmd(self.host, cmd)
122 if re.search(self.REBOOT_CMD_PATTERN, cmd):
126 def _run_guest_setup_scripts(self, scripts):
127 setup_options = self.scenario_cfg["setup_options"]
128 script_dir = os.path.basename(setup_options["script_dir"])
130 for script in scripts:
131 cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
132 (self.WORKSPACE, script_dir, script)
133 self._run_setup_cmd(self.guest, cmd)
135 if re.search(self.REBOOT_CMD_PATTERN, cmd):
137 self._connect_guest()
141 setup_options = self.scenario_cfg["setup_options"]
142 host_setup_seqs = setup_options["host_setup_seqs"]
143 guest_setup_seqs = setup_options["guest_setup_seqs"]
146 self._put_files(self.host)
147 self._run_host_setup_scripts(host_setup_seqs)
149 self._connect_guest()
150 self._put_files(self.guest)
151 self._run_guest_setup_scripts(guest_setup_seqs)
153 # copy script to host
154 self.target_script = pkg_resources.resource_filename(
155 "yardstick.benchmark.scenarios.compute",
156 Cyclictest.TARGET_SCRIPT)
157 self.guest.run("cat > ~/cyclictest_benchmark.sh",
158 stdin=open(self.target_script, "rb"))
160 self.setup_done = True
162 def run(self, result):
163 """execute the benchmark"""
164 default_args = "-m -n -q"
166 if not self.setup_done:
169 options = self.scenario_cfg["options"]
170 affinity = options.get("affinity", 1)
171 interval = options.get("interval", 1000)
172 priority = options.get("priority", 99)
173 loops = options.get("loops", 1000)
174 threads = options.get("threads", 1)
175 histogram = options.get("histogram", 90)
177 cmd_args = "-a %s -i %s -p %s -l %s -t %s -h %s %s" \
178 % (affinity, interval, priority, loops,
179 threads, histogram, default_args)
180 cmd = "bash cyclictest_benchmark.sh %s" % (cmd_args)
181 LOG.debug("Executing command: %s", cmd)
182 status, stdout, stderr = self.guest.execute(cmd)
184 raise RuntimeError(stderr)
186 result.update(json.loads(stdout))
188 if "sla" in self.scenario_cfg:
190 for t, latency in result.items():
191 if 'max_%s_latency' % t not in self.scenario_cfg['sla']:
194 sla_latency = int(self.scenario_cfg['sla'][
195 'max_%s_latency' % t])
196 latency = int(latency)
197 if latency > sla_latency:
198 sla_error += "%s latency %d > sla:max_%s_latency(%d); " % \
199 (t, latency, t, sla_latency)
200 assert sla_error == "", sla_error
203 def _test(): # pragma: no cover
204 '''internal test function'''
205 key_filename = pkg_resources.resource_filename("yardstick.resources",
206 "files/yardstick_key")
209 "ip": "10.229.47.137",
211 "key_filename": key_filename
215 logger = logging.getLogger("yardstick")
216 logger.setLevel(logging.DEBUG)
227 "max_min_latency": 100,
228 "max_avg_latency": 500,
229 "max_max_latency": 1000,
237 cyclictest = Cyclictest(args, ctx)
238 cyclictest.run(result)
241 if __name__ == '__main__': # pragma: no cover