Merge "Add task-args(from yaml file) candidates in /api/v2/yardstick/testcases API"
[yardstick.git] / yardstick / benchmark / scenarios / compute / qemu_migrate.py
1 from __future__ import absolute_import
2 from __future__ import print_function
3
4 import logging
5 import os
6 import re
7 import time
8
9
10 import pkg_resources
11 from oslo_serialization import jsonutils
12
13 import yardstick.ssh as ssh
14 from yardstick.benchmark.scenarios import base
15
16 LOG = logging.getLogger(__name__)
17 LOG.setLevel(logging.DEBUG)
18
19
20 class QemuMigrate(base.Scenario):
21     """
22     Execute a live migration for two host using qemu
23
24     """
25
26     __scenario_type__ = "QemuMigrate"
27
28     TARGET_SCRIPT = "qemu_migrate_benchmark.bash"
29     WORKSPACE = "/root/workspace"
30     REBOOT_CMD_PATTERN = r";\s*reboot\b"
31
32     def __init__(self, scenario_cfg, context_cfg):
33         self.scenario_cfg = scenario_cfg
34         self.context_cfg = context_cfg
35         self.setup_done = False
36
37     def _connect_host(self):
38         host = self.context_cfg["host"]
39         self.host = ssh.SSH.from_node(host, defaults={"user": "root"})
40         self.host.wait(timeout=600)
41
42     def _put_files(self, client):
43         setup_options = self.scenario_cfg["setup_options"]
44         script_dir = setup_options["script_dir"]
45         LOG.debug("Send scripts from %s to workspace %s",
46                   script_dir, self.WORKSPACE)
47         client.put(script_dir, self.WORKSPACE, recursive=True)
48
49     def _run_setup_cmd(self, client, cmd):
50         LOG.debug("Run cmd: %s", cmd)
51         status, stdout, stderr = client.execute(cmd)
52         if status:
53             if re.search(self.REBOOT_CMD_PATTERN, cmd):
54                 LOG.debug("Error on reboot")
55             else:
56                 raise RuntimeError(stderr)
57
58     def _run_host_setup_scripts(self, scripts):
59         setup_options = self.scenario_cfg["setup_options"]
60         script_dir = os.path.basename(setup_options["script_dir"])
61
62         for script in scripts:
63             cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
64                   (self.WORKSPACE, script_dir, script)
65             self._run_setup_cmd(self.host, cmd)
66
67             if re.search(self.REBOOT_CMD_PATTERN, cmd):
68                 time.sleep(3)
69                 self._connect_host()
70
71     def setup(self):
72         """scenario setup"""
73         setup_options = self.scenario_cfg["setup_options"]
74         host_setup_seqs = setup_options["host_setup_seqs"]
75
76         self._connect_host()
77         self._put_files(self.host)
78         self._run_host_setup_scripts(host_setup_seqs)
79
80         # copy script to host
81         self.target_script = pkg_resources.resource_filename(
82             "yardstick.benchmark.scenarios.compute",
83             QemuMigrate.TARGET_SCRIPT)
84         self.host.put_file(self.target_script, "~/qemu_migrate_benchmark.sh")
85
86         self.setup_done = True
87
88     def run(self, result):
89         """execute the benchmark"""
90
91         options = self.scenario_cfg["options"]
92         smp = options.get("smp", 2)
93         qmp_sock_src = options.get("qmp_src_path", "/tmp/qmp-sock-src")
94         qmp_sock_dst = options.get("qmp_dst_path", "/tmp/qmp-sock-dst")
95         incoming_ip = options.get("incoming_ip", 0)
96         migrate_to_port = options.get("migrate_to_port", 4444)
97         max_down_time = options.get("max_down_time", 0.10)
98         cmd_args = " %s %s %s %s %s %s" %\
99                    (smp, qmp_sock_src, qmp_sock_dst, incoming_ip,
100                     migrate_to_port, max_down_time)
101         cmd = "bash migrate_benchmark.sh %s" % (cmd_args)
102         LOG.debug("Executing command: %s", cmd)
103         status, stdout, stderr = self.host.execute(cmd)
104         if status:
105             raise RuntimeError(stderr)
106
107         result.update(jsonutils.loads(stdout))
108
109         if "sla" in self.scenario_cfg:
110             sla_error = ""
111             for t, timevalue in result.items():
112                 if 'max_%s' % t not in self.scenario_cfg['sla']:
113                     continue
114
115                 sla_time = int(self.scenario_cfg['sla'][
116                                'max_%s' % t])
117                 timevalue = int(timevalue)
118                 if timevalue > sla_time:
119                     sla_error += "%s timevalue %d > sla:max_%s(%d); " % \
120                         (t, timevalue, t, sla_time)
121             assert sla_error == "", sla_error
122
123
124 def _test():    # pragma: no cover
125     """internal test function"""
126     key_filename = pkg_resources.resource_filename("yardstick.resources",
127                                                    "files/yardstick_key")
128     ctx = {
129         "host": {
130             "ip": "10.229.47.137",
131             "user": "root",
132             "key_filename": key_filename
133         }
134     }
135
136     logger = logging.getLogger("yardstick")
137     logger.setLevel(logging.DEBUG)
138     options = {
139         "smp": 2,
140         "migrate_to_port": 4444,
141         "incoming_ip": 0,
142         "qmp_sock_src": "/tmp/qmp-sock-src",
143         "qmp_sock_dst": "/tmp/qmp-sock-dst",
144         "max_down_time": 0.10
145     }
146     args = {
147         "options": options
148     }
149     result = {}
150     migrate = QemuMigrate(args, ctx)
151     migrate.run(result)
152     print(result)
153
154 if __name__ == '__main__':    # pragma: no cover
155     _test()