blob: ccab7aae0595a748ece9b5dbc56bbeb1e912308b [file] [log] [blame]
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08001import os
2import sys
3import json
4import time
5import pprint
koder aka kdanilove21d7472015-02-14 19:02:04 -08006import logging
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08007import os.path
8import argparse
koder aka kdanilov3f356262015-02-13 08:06:14 -08009import traceback
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080010
11import io_scenario
12from itest import IOPerfTest
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080013
14import ssh_runner
15import rally_runner
16
17from starts_vms import nova_connect, create_vms_mt, clear_all
18
19
koder aka kdanilove21d7472015-02-14 19:02:04 -080020logger = logging.getLogger("io-perf-tool")
21logger.setLevel(logging.DEBUG)
22ch = logging.StreamHandler()
23ch.setLevel(logging.DEBUG)
24logger.addHandler(ch)
25
26log_format = '%(asctime)s - %(levelname)s - %(name)s - %(message)s'
27formatter = logging.Formatter(log_format,
28 "%H:%M:%S")
29ch.setFormatter(formatter)
30
31
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080032def run_io_test(tool,
33 script_args,
34 test_runner,
35 keep_temp_files=False):
36
37 files_dir = os.path.dirname(io_scenario.__file__)
38
39 path = 'iozone' if 'iozone' == tool else 'fio'
40 src_testtool_path = os.path.join(files_dir, path)
41
42 obj = IOPerfTest(script_args,
43 src_testtool_path,
44 None,
45 keep_temp_files)
46
47 return test_runner(obj)
48
49
50def parse_args(argv):
51 parser = argparse.ArgumentParser(
52 description="Run disk io performance test")
53
54 parser.add_argument("tool_type", help="test tool type",
55 choices=['iozone', 'fio'])
56
57 parser.add_argument("-l", dest='extra_logs',
58 action='store_true', default=False,
59 help="print some extra log info")
60
61 parser.add_argument("-o", "--io-opts", dest='io_opts',
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080062 help="cmd line options for io.py")
63
koder aka kdanilov3f356262015-02-13 08:06:14 -080064 parser.add_argument("-f", "--io-opts-file", dest='io_opts_file',
65 type=argparse.FileType('r'), default=None,
66 help="file with cmd line options for io.py")
67
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080068 parser.add_argument("-t", "--test-directory", help="directory with test",
69 dest="test_directory", required=True)
70
71 parser.add_argument("--max-preparation-time", default=300,
72 type=int, dest="max_preparation_time")
73
74 parser.add_argument("-k", "--keep", default=False,
75 help="keep temporary files",
76 dest="keep_temp_files", action='store_true')
77
78 parser.add_argument("--runner", required=True,
79 choices=["ssh", "rally"],
80 help="runner type")
81
82 parser.add_argument("--runner-extra-opts", default="",
83 dest="runner_opts", help="runner extra options")
84
85 return parser.parse_args(argv)
86
87
koder aka kdanilove21d7472015-02-14 19:02:04 -080088def format_measurements_stat(res):
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080089 if len(res) != 0:
90 bw_mean = 0.0
91 for measurement in res:
92 bw_mean += measurement["bw_mean"]
93
94 bw_mean /= len(res)
95
96 it = ((bw_mean - measurement["bw_mean"]) ** 2 for measurement in res)
97 bw_dev = sum(it) ** 0.5
98
99 meta = res[0]['__meta__']
100 key = "{0} {1} {2}k".format(meta['action'],
101 's' if meta['sync'] else 'a',
102 meta['blocksize'])
103
koder aka kdanilove21d7472015-02-14 19:02:04 -0800104 data = json.dumps({key: (int(bw_mean), int(bw_dev))})
105
106 return "\n====> {0}\n\n{1}\n".format(data, "=" * 80)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800107
koder aka kdanilov3f356262015-02-13 08:06:14 -0800108
109def get_io_opts(io_opts_file, io_opts):
110 if io_opts_file is not None and io_opts is not None:
111 print "Options --io-opts-file and --io-opts can't be " + \
112 "provided same time"
113 exit(1)
114
115 if io_opts_file is None and io_opts is None:
116 print "Either --io-opts-file or --io-opts should " + \
117 "be provided"
118 exit(1)
119
120 if io_opts_file is not None:
121 io_opts = []
122
123 opt_lines = io_opts_file.readlines()
124 opt_lines = [i for i in opt_lines if i != "" and not i.startswith("#")]
125
126 for opt_line in opt_lines:
koder aka kdanilove21d7472015-02-14 19:02:04 -0800127 if opt_line.strip() != "":
128 io_opts.append([opt.strip()
129 for opt in opt_line.strip().split(" ")
130 if opt.strip() != ""])
koder aka kdanilov3f356262015-02-13 08:06:14 -0800131 else:
132 io_opts = [[opt.strip()
133 for opt in io_opts.split(" ")
134 if opt.strip() != ""]]
135
136 if len(io_opts) == 0:
137 print "Can't found parameters for io. Check" + \
138 "--io-opts-file or --io-opts options"
139 exit(1)
140
141 return io_opts
142
143
koder aka kdanilove21d7472015-02-14 19:02:04 -0800144def format_result(res):
145 data = "\n{0}\n".format("=" * 80)
146 data += pprint.pformat(res) + "\n"
147 data += "{0}\n".format("=" * 80)
148 return data + "\n" + format_measurements_stat(res) + "\n"
149
150
koder aka kdanilov3f356262015-02-13 08:06:14 -0800151def main(argv):
152 opts = parse_args(argv)
153
154 if not opts.extra_logs:
155 def nolog(x):
156 pass
157
158 setlogger(nolog)
159
160 io_opts = get_io_opts(opts.io_opts_file, opts.io_opts)
161
162 if opts.runner == "rally":
koder aka kdanilove21d7472015-02-14 19:02:04 -0800163 logger.debug("Use rally runner")
koder aka kdanilov3f356262015-02-13 08:06:14 -0800164 for script_args in io_opts:
koder aka kdanilove21d7472015-02-14 19:02:04 -0800165
166 cmd_line = " ".join(script_args)
167 logger.debug("Run test with {0!r} params".format(cmd_line))
168
koder aka kdanilov3f356262015-02-13 08:06:14 -0800169 runner = rally_runner.get_rally_runner(
170 files_dir=os.path.dirname(io_scenario.__file__),
171 rally_extra_opts=opts.runner_opts.split(" "),
172 max_preparation_time=opts.max_preparation_time,
173 keep_temp_files=opts.keep_temp_files)
174
175 res = run_io_test(opts.tool_type,
176 script_args,
177 runner,
178 opts.keep_temp_files)
koder aka kdanilove21d7472015-02-14 19:02:04 -0800179 logger.debug(format_result(res))
koder aka kdanilov3f356262015-02-13 08:06:14 -0800180
181 elif opts.runner == "ssh":
koder aka kdanilove21d7472015-02-14 19:02:04 -0800182 logger.debug("Use ssh runner")
koder aka kdanilov3f356262015-02-13 08:06:14 -0800183 create_vms_opts = {}
184 for opt in opts.runner_opts.split(","):
185 name, val = opt.split("=", 1)
186 create_vms_opts[name] = val
187
188 user = create_vms_opts.pop("user")
189 key_file = create_vms_opts.pop("key_file")
190 aff_group = create_vms_opts.pop("aff_group", None)
191 raw_count = create_vms_opts.pop("count", "x1")
192
koder aka kdanilove21d7472015-02-14 19:02:04 -0800193 logger.debug("Connection to nova")
koder aka kdanilovec530332015-02-13 11:12:53 -0800194 nova = nova_connect()
195
koder aka kdanilov3f356262015-02-13 08:06:14 -0800196 if raw_count.startswith("x"):
koder aka kdanilove21d7472015-02-14 19:02:04 -0800197 logger.debug("Getting amount of compute services")
koder aka kdanilovec530332015-02-13 11:12:53 -0800198 count = len(nova.services.list(binary="nova-compute"))
koder aka kdanilove21d7472015-02-14 19:02:04 -0800199 count *= int(raw_count[1:])
koder aka kdanilov3f356262015-02-13 08:06:14 -0800200 else:
201 count = int(raw_count)
202
203 if aff_group is not None:
204 scheduler_hints = {'group': aff_group}
205 else:
206 scheduler_hints = None
207
208 create_vms_opts['scheduler_hints'] = scheduler_hints
209
koder aka kdanilov3f356262015-02-13 08:06:14 -0800210 # nova, amount, keypair_name, img_name,
211 # flavor_name, vol_sz=None, network_zone_name=None,
212 # flt_ip_pool=None, name_templ='ceph-test-{}',
213 # scheduler_hints=None
214
koder aka kdanilove21d7472015-02-14 19:02:04 -0800215 logger.debug("Will start {} vms".format(count))
216
koder aka kdanilov3f356262015-02-13 08:06:14 -0800217 try:
218 ips = [i[0] for i in create_vms_mt(nova, count, **create_vms_opts)]
219
220 uris = ["{0}@{1}::{2}".format(user, ip, key_file) for ip in ips]
221
222 for script_args in io_opts:
koder aka kdanilove21d7472015-02-14 19:02:04 -0800223 cmd_line = " ".join(script_args)
224 logger.debug("Run test with {0!r} params".format(cmd_line))
225 latest_start_time = opts.max_preparation_time + time.time()
koder aka kdanilov3f356262015-02-13 08:06:14 -0800226 runner = ssh_runner.get_ssh_runner(uris,
227 latest_start_time,
228 opts.keep_temp_files)
229 res = run_io_test(opts.tool_type,
230 script_args,
231 runner,
232 opts.keep_temp_files)
koder aka kdanilove21d7472015-02-14 19:02:04 -0800233 logger.debug(format_result(res))
koder aka kdanilov3f356262015-02-13 08:06:14 -0800234
koder aka kdanilov3f356262015-02-13 08:06:14 -0800235 except:
236 traceback.print_exc()
237 finally:
koder aka kdanilove21d7472015-02-14 19:02:04 -0800238 logger.debug("Clearing")
koder aka kdanilov3f356262015-02-13 08:06:14 -0800239 clear_all(nova)
240
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800241 return 0
242
243
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800244if __name__ == '__main__':
245 exit(main(sys.argv[1:]))