blob: 5b9c0a5627f61cf980c75e2e65551cc4a1117168 [file] [log] [blame]
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08001import time
koder aka kdanilov4ec0f712015-02-19 19:19:27 -08002import socket
koder aka kdanilovdda86d32015-03-16 11:20:04 +02003import os.path
4import getpass
koder aka kdanilove21d7472015-02-14 19:02:04 -08005import logging
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08006import threading
7import contextlib
koder aka kdanilov4643fd62015-02-10 16:20:13 -08008import multiprocessing
9
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080010import paramiko
koder aka kdanilov4643fd62015-02-10 16:20:13 -080011
koder aka kdanilove21d7472015-02-14 19:02:04 -080012
13logger = logging.getLogger("io-perf-tool")
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080014
15
16def get_barrier(count, threaded=False):
17 if threaded:
18 class val(object):
19 value = count
20 cond = threading.Condition()
21 else:
22 val = multiprocessing.Value('i', count)
23 cond = multiprocessing.Condition()
koder aka kdanilov4643fd62015-02-10 16:20:13 -080024
25 def closure(timeout):
26 with cond:
27 val.value -= 1
28 if val.value == 0:
29 cond.notify_all()
30 else:
31 cond.wait(timeout)
32 return val.value == 0
33
34 return closure
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080035
36
koder aka kdanilov4ec0f712015-02-19 19:19:27 -080037def ssh_connect(creds, retry_count=60, timeout=1):
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080038 ssh = paramiko.SSHClient()
39 ssh.load_host_keys('/dev/null')
40 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
41 ssh.known_hosts = None
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080042 for i in range(retry_count):
43 try:
koder aka kdanilovdda86d32015-03-16 11:20:04 +020044 if creds.user is None:
45 user = getpass.getuser()
46 else:
47 user = creds.user
48
koder aka kdanilov4ec0f712015-02-19 19:19:27 -080049 if creds.passwd is not None:
50 ssh.connect(creds.host,
koder aka kdanilovdda86d32015-03-16 11:20:04 +020051 username=user,
koder aka kdanilov4ec0f712015-02-19 19:19:27 -080052 password=creds.passwd,
53 port=creds.port,
54 allow_agent=False,
55 look_for_keys=False)
56 return ssh
57
58 if creds.key_file is not None:
59 ssh.connect(creds.host,
koder aka kdanilovdda86d32015-03-16 11:20:04 +020060 username=user,
koder aka kdanilov4ec0f712015-02-19 19:19:27 -080061 key_filename=creds.key_file,
62 look_for_keys=False,
63 port=creds.port)
64 return ssh
koder aka kdanilovdda86d32015-03-16 11:20:04 +020065
66 key_file = os.path.expanduser('~/.ssh/id_rsa')
67 ssh.connect(creds.host,
68 username=user,
69 key_filename=key_file,
70 look_for_keys=False,
71 port=creds.port)
72 return ssh
73 # raise ValueError("Wrong credentials {0}".format(creds.__dict__))
koder aka kdanilov4ec0f712015-02-19 19:19:27 -080074 except paramiko.PasswordRequiredException:
75 raise
76 except socket.error:
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080077 if i == retry_count - 1:
78 raise
79 time.sleep(timeout)
80
81
82def wait_on_barrier(barrier, latest_start_time):
83 if barrier is not None:
84 if latest_start_time is not None:
85 timeout = latest_start_time - time.time()
86 else:
87 timeout = None
88
89 if timeout is not None and timeout > 0:
90 msg = "Ready and waiting on barrier. " + \
91 "Will wait at most {0} seconds"
koder aka kdanilove21d7472015-02-14 19:02:04 -080092 logger.debug(msg.format(int(timeout)))
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080093
94 if not barrier(timeout):
koder aka kdanilove21d7472015-02-14 19:02:04 -080095 logger.debug("Barrier timeouted")
koder aka kdanilov4ec0f712015-02-19 19:19:27 -080096 else:
97 logger.debug("Passing barrier, starting test")
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080098
99
100@contextlib.contextmanager
101def log_error(action, types=(Exception,)):
102 if not action.startswith("!"):
koder aka kdanilove21d7472015-02-14 19:02:04 -0800103 logger.debug("Starts : " + action)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800104 else:
105 action = action[1:]
106
107 try:
108 yield
109 except Exception as exc:
110 if isinstance(exc, types) and not isinstance(exc, StopIteration):
111 templ = "Error during {0} stage: {1}"
koder aka kdanilove21d7472015-02-14 19:02:04 -0800112 logger.debug(templ.format(action, exc.message))
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800113 raise
114
115
116def run_over_ssh(conn, cmd):
117 "should be replaces by normal implementation, with select"
118
119 stdin, stdout, stderr = conn.exec_command(cmd)
120 out = stdout.read()
121 err = stderr.read()
122 code = stdout.channel.recv_exit_status()
123 return code, out, err
koder aka kdanilov83cd7132015-02-14 21:37:14 -0800124
125
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800126def kb_to_ssize(ssize):
127 size_ext = {
128 4: 'P',
129 3: 'T',
130 2: 'G',
131 1: 'M',
132 0: 'K'
133 }
134
135 for idx in reversed(sorted(size_ext)):
136 if ssize > 1024 ** idx:
137 ext = size_ext[idx]
138 return "{0}{1}".format(int(ssize / 1024 ** idx), ext)
139 raise ValueError("Can't convert {0} to kb".format(ssize))
140
141
koder aka kdanilov83cd7132015-02-14 21:37:14 -0800142def ssize_to_kb(ssize):
143 try:
144 smap = dict(k=1, K=1, M=1024, m=1024, G=1024**2, g=1024**2)
145 for ext, coef in smap.items():
146 if ssize.endswith(ext):
147 return int(ssize[:-1]) * coef
148
149 if int(ssize) % 1024 != 0:
150 raise ValueError()
151
152 return int(ssize) / 1024
153
154 except (ValueError, TypeError, AttributeError):
155 tmpl = "Unknow size format {0!r} (or size not multiples 1024)"
156 raise ValueError(tmpl.format(ssize))
koder aka kdanilov8ad6e812015-03-22 14:42:18 +0200157
158
159def ssize_to_b(ssize):
160 try:
161 smap = dict(k=1, K=1, M=1024, m=1024, G=1024**2, g=1024**2)
162 for ext, coef in smap.items():
163 if ssize.endswith(ext):
164 return int(ssize[:-1]) * coef * 1024
165
166 return int(ssize)
167 except (ValueError, TypeError, AttributeError):
168 tmpl = "Unknow size format {0!r} (or size not multiples 1024)"
169 raise ValueError(tmpl.format(ssize))