2 # Copyright (c) 2016, Tieto Corporation
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
9 from remotehost import Host
13 class TestSkip(Exception):
14 def __init__(self, reason):
19 # get host based on name
20 def get_host(devices, dev_name):
21 dev = config.get_device(devices, dev_name)
22 host = Host(host = dev['hostname'],
23 ifname = dev['ifname'],
29 # Run setup_hw - hardware specific
30 def setup_hw_host_iface(host, iface, setup_params, force_restart=False):
32 setup_hw = setup_params['setup_hw']
35 if setup_params['restart_device'] == True:
43 host.execute([setup_hw, "-I", iface, restart])
47 def setup_hw_host(host, setup_params, force_restart=False):
48 ifaces = re.split('; | |, ', host.ifname)
50 setup_hw_host_iface(host, iface, setup_params, force_restart)
52 def setup_hw(hosts, setup_params, force_restart=False):
54 setup_hw_host(host, setup_params, force_restart)
56 # get traces - hw specific
57 def trace_start(hosts, setup_params):
59 trace_start_stop(host, setup_params, start=True)
61 def trace_stop(hosts, setup_params):
63 trace_start_stop(host, setup_params, start=False)
65 def trace_start_stop(host, setup_params, start):
66 if setup_params['trace'] == False:
69 start_trace = setup_params['trace_start']
70 stop_trace = setup_params['trace_stop']
75 trace_dir = setup_params['log_dir'] + host.ifname + "/remote_traces"
76 host.add_log(trace_dir + "/*")
77 host.execute([cmd, "-I", host.ifname, "-D", trace_dir])
82 def perf_start(hosts, setup_params):
84 perf_start_stop(host, setup_params, start=True)
86 def perf_stop(hosts, setup_params):
88 perf_start_stop(host, setup_params, start=False)
90 def perf_start_stop(host, setup_params, start):
91 if setup_params['perf'] == False:
94 perf_start = setup_params['perf_start']
95 perf_stop = setup_params['perf_stop']
100 perf_dir = setup_params['log_dir'] + host.ifname + "/remote_perf"
101 host.add_log(perf_dir + "/*")
102 host.execute([cmd, "-I", host.ifname, "-D", perf_dir])
106 # hostapd/wpa_supplicant helpers
107 def run_hostapd(host, setup_params):
110 tc_name = setup_params['tc_name']
111 log_dir = setup_params['log_dir']
112 log_file = log_dir + tc_name + "_hostapd_" + host.name + "_" + host.ifname + ".log"
113 host.execute(["rm", log_file])
114 log = " -f " + log_file
119 host.add_log(log_file)
120 status, buf = host.execute([setup_params['hostapd'], "-B", "-ddt", "-g", "udp:" + host.port, log])
122 raise Exception("Could not run hostapd: " + buf)
124 def run_wpasupplicant(host, setup_params):
127 tc_name = setup_params['tc_name']
128 log_dir = setup_params['log_dir']
129 log_file = log_dir + tc_name + "_wpa_supplicant_" + host.name + "_" + host.ifname + ".log"
130 host.execute(["rm", log_file])
131 log = " -f " + log_file
136 host.add_log(log_file)
137 status, buf = host.execute([setup_params['wpa_supplicant'], "-B", "-ddt", "-g", "udp:" + host.port, log])
139 raise Exception("Could not run wpa_supplicant: " + buf)
141 def get_ap_params(channel="1", bw="HT20", country="US", security="open", ht_capab=None, vht_capab=None):
142 ssid = "test_" + channel + "_" + security + "_" + bw
145 params = hostapd.b_only_params(channel, ssid, country)
147 params = hostapd.g_only_params(channel, ssid, country)
148 elif bw == "g_only_wmm":
149 params = hostapd.g_only_params(channel, ssid, country)
150 params['wmm_enabled'] = "1"
152 params = hostapd.a_only_params(channel, ssid, country)
153 elif bw == "a_only_wmm":
154 params = hostapd.a_only_params(channel, ssid, country)
155 params['wmm_enabled'] = "1"
157 params = hostapd.ht20_params(channel, ssid, country)
160 params['ht_capab'] = params['ht_capab'] + ht_capab
162 params['ht_capab'] = ht_capab
164 params = hostapd.ht40_plus_params(channel, ssid, country)
166 params['ht_capab'] = params['ht_capab'] + ht_capab
168 params = hostapd.ht40_minus_params(channel, ssid, country)
170 params['ht_capab'] = params['ht_capab'] + ht_capab
172 params = hostapd.ht40_plus_params(channel, ssid, country)
174 params['ht_capab'] = params['ht_capab'] + ht_capab
177 params['vht_capab'] = params['vht_capab'] + vht_capab
179 params['vht_capab'] = vht_capab
180 params['ieee80211ac'] = "1"
181 params['vht_oper_chwidth'] = "1"
182 params['vht_oper_centr_freq_seg0_idx'] = str(int(channel) + 6)
186 # now setup security params
187 if security == "tkip":
188 sec_params = hostapd.wpa_params(passphrase="testtest")
189 elif security == "ccmp":
190 sec_params = hostapd.wpa2_params(passphrase="testtest")
191 elif security == "mixed":
192 sec_params = hostapd.wpa_mixed_params(passphrase="testtest")
193 elif security == "wep":
194 sec_params = { "wep_key0" : "123456789a",
195 "wep_default_key" : "0",
197 elif security == "wep_shared":
198 sec_params = { "wep_key0" : "123456789a",
199 "wep_default_key" : "0",
204 params.update(sec_params)
209 def get_ipv4(client, ifname=None):
211 ifname = client.ifname
212 status, buf = client.execute(["ifconfig", ifname])
213 lines = buf.splitlines()
216 res = line.find("inet addr:")
222 addr = words[1].split(":")
227 def get_ipv6(client, ifname=None):
230 ifname = client.ifname
231 status, buf = client.execute(["ifconfig", ifname])
232 lines = buf.splitlines()
235 res = line.find("Scope:Link")
241 if words[0] == "inet6" and words[1] == "addr:":
243 addr = addr_mask.split("/")
248 def get_ip(client, addr_type="ipv6", iface=None):
249 if addr_type == "ipv6":
250 return get_ipv6(client, iface)
251 elif addr_type == "ipv4":
252 return get_ipv4(client, iface)
254 return "unknown addr_type: " + addr_type
256 def get_ipv4_addr(setup_params, number):
258 ipv4_base = setup_params['ipv4_test_net']
260 ipv4_base = "172.16.12.0"
262 parts = ipv4_base.split('.')
263 ipv4 = parts[0] + "." + parts[1] + "." + parts[2] + "." + str(number)
267 def get_mac_addr(host, iface=None):
270 status, buf = host.execute(["ifconfig", iface])
272 raise Exception("ifconfig " + iface)
280 raise Exception("Could not find HWaddr")
282 # connectivity/ping helpers
283 def get_ping_packet_loss(ping_res):
285 lines = ping_res.splitlines()
287 if line.find("packet loss") != -1:
294 sections = loss_line.split(",")
296 for section in sections:
297 if section.find("packet loss") != -1:
298 words = section.split()
303 def ac_to_ping_ac(qos):
316 def ping_run(host, ip, result, ifname=None, addr_type="ipv4", deadline="5", qos=None):
319 if addr_type == "ipv6":
324 ping = ping + ["-w", deadline, "-I", ifname]
326 ping = ping + ["-Q", ac_to_ping_ac(qos)]
329 flush_arp_cache(host)
331 thread = host.execute_run(ping, result)
334 def ping_wait(host, thread, timeout=None):
335 host.wait_execute_complete(thread, timeout)
337 raise Exception("ping thread still alive")
339 def flush_arp_cache(host):
340 host.execute(["ip", "-s", "-s", "neigh", "flush", "all"])
342 def check_connectivity(a, b, addr_type = "ipv4", deadline="5", qos=None):
343 addr_a = get_ip(a, addr_type)
344 addr_b = get_ip(b, addr_type)
346 if addr_type == "ipv4":
351 ping_a_b = ping + ["-w", deadline, "-I", a.ifname]
352 ping_b_a = ping + ["-w", deadline, "-I", b.ifname]
354 ping_a_b = ping_a_b + ["-Q", ac_to_ping_ac(qos)]
355 ping_b_a = ping_b_a + ["-Q", ac_to_ping_ac(qos)]
356 ping_a_b = ping_a_b + [addr_b]
357 ping_b_a = ping_b_a + [addr_a]
363 status, buf = a.execute(ping_a_b)
364 if status == 2 and ping == "ping6":
365 # tentative possible for a while, try again
367 status, buf = a.execute(ping_a_b)
369 raise Exception("ping " + a.name + "/" + a.ifname + " >> " + b.name + "/" + b.ifname)
371 a_b = get_ping_packet_loss(buf)
377 status, buf = b.execute(ping_b_a)
379 raise Exception("ping " + b.name + "/" + b.ifname + " >> " + a.name + "/" + a.ifname)
381 b_a = get_ping_packet_loss(buf)
383 if int(a_b[:-1]) > 40:
384 raise Exception("Too high packet lost: " + a_b)
386 if int(b_a[:-1]) > 40:
387 raise Exception("Too high packet lost: " + b_a)
393 def get_iperf_speed(iperf_res, pattern="Mbits/sec"):
394 lines = iperf_res.splitlines()
400 # first find last SUM line
402 res = line.find("[SUM]")
406 # next check SUM status
408 words = sum_line.split()
410 res = word.find(pattern)
412 return words[count - 1] + " " + pattern
415 # no SUM - one thread - find last line
417 res = line.find(pattern)
422 return "0 " + pattern
425 words = last_line.split()
427 res = word.find(pattern)
429 return words[count - 1] + " " + pattern
432 return "0 " + pattern
434 def ac_to_iperf_ac(qos):
447 def iperf_run(server, client, server_ip, client_res, server_res,
448 l4="udp", bw="30M", test_time="30", parallel="5",
449 qos="be", param=" -i 5 ", ifname=None, l3="ipv4",
450 port="5001", iperf="iperf"):
452 ifname = client.ifname
455 iperf_server = [iperf]
456 elif iperf == "iperf3":
457 iperf_server = [iperf, "-1"]
460 iperf_client = [iperf, "-c", server_ip, "-p", port]
461 iperf_server = iperf_server + ["-p", port]
463 iperf_client = [iperf, "-V", "-c", server_ip + "%" + ifname, "-p", port]
464 iperf_server = iperf_server + ["-V", "-p", port]
468 iperf_server = iperf_server + ["-s", "-f", "m", param]
469 iperf_client = iperf_client + ["-f", "m", "-t", test_time]
472 iperf_client = iperf_client + ["-P", parallel]
475 if iperf != "iperf3":
476 iperf_server = iperf_server + ["-u"]
477 iperf_client = iperf_client + ["-u", "-b", bw]
480 iperf_client = iperf_client + ["-Q", ac_to_iperf_ac(qos)]
482 flush_arp_cache(server)
483 flush_arp_cache(client)
485 server_thread = server.execute_run(iperf_server, server_res)
487 client_thread = client.execute_run(iperf_client, client_res)
489 return server_thread, client_thread
491 def iperf_wait(server, client, server_thread, client_thread, timeout=None, iperf="iperf"):
492 client.wait_execute_complete(client_thread, timeout)
493 if client_thread.isAlive():
494 raise Exception("iperf client thread still alive")
496 server.wait_execute_complete(server_thread, 5)
497 if server_thread.isAlive():
498 server.execute(["killall", "-s", "INT", iperf])
501 server.wait_execute_complete(server_thread, 5)
502 if server_thread.isAlive():
503 raise Execption("iperf server thread still alive")
507 def run_tp_test(server, client, l3="ipv4", iperf="iperf", l4="tcp", test_time="10", parallel="5",
508 qos="be", bw="30M", ifname=None, port="5001"):
512 server_ip = get_ip(server, l3)
514 server_thread, client_thread = iperf_run(server, client, server_ip, client_res, server_res,
515 l3=l3, iperf=iperf, l4=l4, test_time=test_time,
516 parallel=parallel, qos=qos, bw=bw, ifname=ifname,
518 iperf_wait(server, client, server_thread, client_thread, iperf=iperf, timeout=int(test_time) + 10)
520 if client_res[0] != 0:
521 raise Exception(iperf + " client: " + client_res[1])
522 if server_res[0] != 0:
523 raise Exception(iperf + " server: " + server_res[1])
524 if client_res[1] is None:
525 raise Exception(iperf + " client result issue")
526 if server_res[1] is None:
527 raise Exception(iperf + " server result issue")
530 result = server_res[1]
531 if iperf == "iperf3":
532 result = client_res[1]
534 speed = get_iperf_speed(result)
537 def get_iperf_bw(bw, parallel, spacial_streams=2):
540 elif bw == "g_only" or bw == "g_only_wmm" or bw == "a_only" or bw == "a_only_wmm":
543 max_tp = 72 * spacial_streams
544 elif bw == "HT40+" or bw == "HT40-":
545 max_tp = 150 * spacial_streams
547 max_tp = 433 * spacial_streams
551 max_tp = 1.2 * max_tp
553 return str(int(max_tp/int(parallel))) + "M"