Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: server/site_wifitest.py

Issue 3459004: Create implicit concept of iterations in wifitest (Closed) Base URL: ssh://gitrw.chromium.org/autotest.git
Patch Set: Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import common, fnmatch, logging, os, re, string, threading, time 5 import common, fnmatch, logging, os, re, string, threading, time
6 6
7 from autotest_lib.server import autotest, hosts, subcommand 7 from autotest_lib.server import autotest, hosts, subcommand
8 from autotest_lib.server import site_bsd_router 8 from autotest_lib.server import site_bsd_router
9 from autotest_lib.server import site_linux_router 9 from autotest_lib.server import site_linux_router
10 from autotest_lib.server import site_host_attributes 10 from autotest_lib.server import site_host_attributes
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 by adding a new class and auto-selecting it in __init__. 61 by adding a new class and auto-selecting it in __init__.
62 62
63 The WiFiTest class could be generalized to handle clients other than 63 The WiFiTest class could be generalized to handle clients other than
64 ChromeOS; this would useful for systems that use Network Manager or 64 ChromeOS; this would useful for systems that use Network Manager or
65 wpa_supplicant directly. 65 wpa_supplicant directly.
66 """ 66 """
67 67
68 def __init__(self, name, steps, config): 68 def __init__(self, name, steps, config):
69 self.name = name 69 self.name = name
70 self.steps = steps 70 self.steps = steps
71 self.keyvals = {} 71 self.perf_keyvals = {}
72 72
73 router = config['router'] 73 router = config['router']
74 self.router = hosts.create_host(router['addr']) 74 self.router = hosts.create_host(router['addr'])
75 # NB: truncate SSID to 32 characters 75 # NB: truncate SSID to 32 characters
76 self.defssid = self.__get_defssid(router['addr'])[0:32] 76 self.defssid = self.__get_defssid(router['addr'])[0:32]
77 77
78 defaults = config.get('defaults', {}) 78 defaults = config.get('defaults', {})
79 self.deftimeout = defaults.get('timeout', 30) 79 self.deftimeout = defaults.get('timeout', 30)
80 self.defpingcount = defaults.get('pingcount', 10) 80 self.defpingcount = defaults.get('pingcount', 10)
81 self.defwaittime = str(defaults.get('netperf_wait_time', 3)) 81 self.defwaittime = str(defaults.get('netperf_wait_time', 3))
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 self.server = None; 125 self.server = None;
126 # NB: wifi address must be set if not reachable from control 126 # NB: wifi address must be set if not reachable from control
127 self.server_wifi_ip = server['wifi_addr'] 127 self.server_wifi_ip = server['wifi_addr']
128 128
129 # potential bg thread for ping untilstop 129 # potential bg thread for ping untilstop
130 self.ping_thread = None 130 self.ping_thread = None
131 131
132 # potential bg thread for client network monitoring 132 # potential bg thread for client network monitoring
133 self.client_netdump_thread = None 133 self.client_netdump_thread = None
134 self.__client_discover_commands(client) 134 self.__client_discover_commands(client)
135 self.netperf_iter = 0
136 self.firewall_rules = [] 135 self.firewall_rules = []
137 136
137 # Find all repeated steps and create iterators for them
138 self.iterated_steps = {}
139 step_names = [step[0] for step in steps]
140 for step_name in list(set(step_names)):
141 if step_names.count(step_name) > 1:
142 self.iterated_steps[step_name] = 0
138 143
139 def cleanup(self, params): 144 def cleanup(self, params):
140 """ Cleanup state: disconnect client and destroy ap """ 145 """ Cleanup state: disconnect client and destroy ap """
141 self.disconnect({}) 146 self.disconnect({})
142 self.wifi.destroy({}) 147 self.wifi.destroy({})
143 self.client_netdump_stop({}) 148 self.client_netdump_stop({})
144 self.firewall_cleanup({}) 149 self.firewall_cleanup({})
145 150
146 151
147 def __client_discover_commands(self, client): 152 def __client_discover_commands(self, client):
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 in this class or the ancillary router class and invoked with 186 in this class or the ancillary router class and invoked with
182 the supplied parameter dictionary. 187 the supplied parameter dictionary.
183 """ 188 """
184 for s in self.steps: 189 for s in self.steps:
185 method = s[0] 190 method = s[0]
186 if len(s) > 1: 191 if len(s) > 1:
187 params = s[1] 192 params = s[1]
188 else: 193 else:
189 params = {} 194 params = {}
190 195
196 # What should perf data be prefixed with?
197 if 'perf_prefix' in params:
198 self.prefix = '%s_%s' % (method, params.pop('perf_prefix'))
199 elif method in self.iterated_steps:
200 self.prefix = '%s_%d' % (method, self.iterated_steps[method])
201 self.iterated_steps[method] += 1
202 else:
203 self.prefix = method
204
191 logging.info("%s: step '%s' params %s", self.name, method, params) 205 logging.info("%s: step '%s' params %s", self.name, method, params)
192 206
193 func = getattr(self, method, None) 207 func = getattr(self, method, None)
194 if func is None: 208 if func is None:
195 func = getattr(self.wifi, method, None) 209 func = getattr(self.wifi, method, None)
196 if func is not None: 210 if func is not None:
197 try: 211 try:
198 func(params) 212 func(params)
199 except Exception, e: 213 except Exception, e:
200 logging.error("%s: Step '%s' failed: %s; abort test", 214 logging.error("%s: Step '%s' failed: %s; abort test",
201 self.name, method, str(e)) 215 self.name, method, str(e))
202 self.cleanup(params) 216 self.cleanup(params)
203 raise e 217 raise e
204 break 218 break
205 else: 219 else:
206 logging.error("%s: Step '%s' unknown; abort test", 220 logging.error("%s: Step '%s' unknown; abort test",
207 self.name, method) 221 self.name, method)
208 self.cleanup(params) 222 self.cleanup(params)
209 break 223 break
210 224
211 # Other cleanup steps might be optional, but this is mandatory 225 # Other cleanup steps might be optional, but this is mandatory
212 self.client_netdump_stop({}) 226 self.client_netdump_stop({})
213 227
214 228
215 def write_keyvals(self, job): 229 def write_keyvals(self, job):
216 job.write_perf_keyval(self.keyvals) 230 job.write_perf_keyval(self.perf_keyvals)
217 231
232 def write_perf(self, data):
233 for key, value in data.iteritems():
234 self.perf_keyvals['%s_%s' % (self.prefix, key)] = value
218 235
219 def __get_ipaddr(self, host, ifnet): 236 def __get_ipaddr(self, host, ifnet):
220 # XXX gotta be a better way to do this 237 # XXX gotta be a better way to do this
221 result = host.run("%s %s" % (self.client_cmd_ifconfig, ifnet)) 238 result = host.run("%s %s" % (self.client_cmd_ifconfig, ifnet))
222 m = re.search('inet addr:([^ ]*)', result.stdout) 239 m = re.search('inet addr:([^ ]*)', result.stdout)
223 if m is None: 240 if m is None:
224 raise error.TestFail("No inet address found") 241 raise error.TestFail("No inet address found")
225 return m.group(1) 242 return m.group(1)
226 243
227 244
(...skipping 15 matching lines...) Expand all
243 result = self.client.run('python "%s" "%s" "%s" "%s" "%d" "%d"' % 260 result = self.client.run('python "%s" "%s" "%s" "%s" "%d" "%d"' %
244 (script_client_file, 261 (script_client_file,
245 params.get('ssid', self.wifi.get_ssid()), 262 params.get('ssid', self.wifi.get_ssid()),
246 params.get('security', ''), 263 params.get('security', ''),
247 params.get('psk', ''), 264 params.get('psk', ''),
248 params.get('assoc_timeout', self.deftimeout), 265 params.get('assoc_timeout', self.deftimeout),
249 params.get('config_timeout', self.deftimeout))).stdout.rstrip() 266 params.get('config_timeout', self.deftimeout))).stdout.rstrip()
250 267
251 result_times = re.match("OK ([0-9\.]*) ([0-9\.]*) .*", result) 268 result_times = re.match("OK ([0-9\.]*) ([0-9\.]*) .*", result)
252 269
253 self.keyvals['connect_config_s'] = result_times.group(1) 270 self.write_perf({'config_s': result_times.group(1),
254 self.keyvals['connect_assoc_s'] = result_times.group(2) 271 'assoc_s': result_times.group(2)})
255 for k in ('multiple_attempts', 'clear_error', 'fast_fail'): 272 for k in ('already_connected', 'clear_error', 'fast_fail',
273 'get_prop', 'in_progress', 'lost_dbus', 'multiple_attempts'):
256 if re.search(k, result) is not None: 274 if re.search(k, result) is not None:
257 self.keyvals[k] = 'true' 275 self.write_perf({k:'true'})
258 276
259 print "%s: %s" % (self.name, result) 277 print "%s: %s" % (self.name, result)
260 278
261 # fetch IP address of wireless device 279 # fetch IP address of wireless device
262 self.client_wifi_ip = self.__get_ipaddr(self.client, self.client_wlanif) 280 self.client_wifi_ip = self.__get_ipaddr(self.client, self.client_wlanif)
263 logging.info("%s: client WiFi-IP is %s", self.name, self.client_wifi_ip) 281 logging.info("%s: client WiFi-IP is %s", self.name, self.client_wifi_ip)
264 # TODO(sleffler) not right for non-mac80211 devices 282 # TODO(sleffler) not right for non-mac80211 devices
265 # TODO(sleffler) verify debugfs is mounted @ /sys/kernel/debug 283 # TODO(sleffler) verify debugfs is mounted @ /sys/kernel/debug
266 self.client_debugfs_path = "/sys/kernel/debug/ieee80211/%s/netdev:%s" \ 284 self.client_debugfs_path = "/sys/kernel/debug/ieee80211/%s/netdev:%s" \
267 % ("phy0", self.client_wlanif) 285 % ("phy0", self.client_wlanif)
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 stats['max'] = m.group(4) 435 stats['max'] = m.group(4)
418 return stats 436 return stats
419 437
420 438
421 def __print_pingstats(self, label, stats): 439 def __print_pingstats(self, label, stats):
422 logging.info("%s: %s%s/%s, %s%% loss, rtt %s/%s/%s", 440 logging.info("%s: %s%s/%s, %s%% loss, rtt %s/%s/%s",
423 self.name, label, stats['xmit'], stats['recv'], stats['loss'], 441 self.name, label, stats['xmit'], stats['recv'], stats['loss'],
424 stats['min'], stats['avg'], stats['max']) 442 stats['min'], stats['avg'], stats['max'])
425 443
426 444
427 def __ping_prefix(self, params):
428 if 'name' in params:
429 return params['name']
430
431 args = []
432 for k, v in params.items():
433 if k != 'count':
434 args.append('%s_%s' % (k, v))
435 return '/'.join(args)
436
437
438 def client_ping(self, params): 445 def client_ping(self, params):
439 """ Ping the server from the client """ 446 """ Ping the server from the client """
440 ping_ip = params.get('ping_ip', self.server_wifi_ip) 447 ping_ip = params.get('ping_ip', self.server_wifi_ip)
441 count = params.get('count', self.defpingcount) 448 count = params.get('count', self.defpingcount)
442 # set timeout for 3s / ping packet 449 # set timeout for 3s / ping packet
443 result = self.client.run("ping %s %s" % \ 450 result = self.client.run("ping %s %s" % \
444 (self.__ping_args(params), ping_ip), timeout=3*int(count)) 451 (self.__ping_args(params), ping_ip), timeout=3*int(count))
445 452
446 stats = self.__get_pingstats(result.stdout) 453 stats = self.__get_pingstats(result.stdout)
447 prefix = 'client_ping_%s_' % self.__ping_prefix(params) 454 self.write_perf(stats)
448 for k,v in stats.iteritems():
449 self.keyvals[prefix + k] = v
450 self.__print_pingstats("client_ping ", stats) 455 self.__print_pingstats("client_ping ", stats)
451 456
452 457
453 def client_ping_bg(self, params): 458 def client_ping_bg(self, params):
454 """ Ping the server from the client """ 459 """ Ping the server from the client """
455 ping_ip = params.get('ping_ip', self.server_wifi_ip) 460 ping_ip = params.get('ping_ip', self.server_wifi_ip)
456 cmd = "ping %s %s" % (self.__ping_args(params), ping_ip) 461 cmd = "ping %s %s" % (self.__ping_args(params), ping_ip)
457 self.ping_thread = HelperThread(self.client, cmd) 462 self.ping_thread = HelperThread(self.client, cmd)
458 self.ping_thread.start() 463 self.ping_thread.start()
459 464
(...skipping 11 matching lines...) Expand all
471 self.__unreachable("server_ping") 476 self.__unreachable("server_ping")
472 return 477 return
473 ping_ip = params.get('ping_ip', self.client_wifi_ip) 478 ping_ip = params.get('ping_ip', self.client_wifi_ip)
474 count = params.get('count', self.defpingcount) 479 count = params.get('count', self.defpingcount)
475 # set timeout for 3s / ping packet 480 # set timeout for 3s / ping packet
476 result = self.server.run("%s %s %s" % \ 481 result = self.server.run("%s %s %s" % \
477 (self.server_ping_cmd, self.__ping_args(params), 482 (self.server_ping_cmd, self.__ping_args(params),
478 ping_ip), timeout=3*int(count)) 483 ping_ip), timeout=3*int(count))
479 484
480 stats = self.__get_pingstats(result.stdout) 485 stats = self.__get_pingstats(result.stdout)
481 prefix = 'server_ping_' + self.__ping_prefix(params) 486 self.write_perf(stats)
482 for k,v in stats.iteritems():
483 self.keyvals['server_ping_' + k] = v
484 self.__print_pingstats("server_ping ", stats) 487 self.__print_pingstats("server_ping ", stats)
485 488
486 489
487 def server_ping_bg(self, params): 490 def server_ping_bg(self, params):
488 """ Ping the client from the server """ 491 """ Ping the client from the server """
489 if self.server is None: 492 if self.server is None:
490 self.__unreachable("server_ping_bg") 493 self.__unreachable("server_ping_bg")
491 return 494 return
492 ping_ip = params.get('ping_ip', self.client_wifi_ip) 495 ping_ip = params.get('ping_ip', self.client_wifi_ip)
493 cmd = "ping %s %s" % (self.__ping_args(params), ping_ip) 496 cmd = "ping %s %s" % (self.__ping_args(params), ping_ip)
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 # Run netperf command and receive command results 619 # Run netperf command and receive command results
617 t0 = time.time() 620 t0 = time.time()
618 results = client['host'].run("%s %s" % (client['cmd'], netperf_args)) 621 results = client['host'].run("%s %s" % (client['cmd'], netperf_args))
619 actual_time = time.time() - t0 622 actual_time = time.time() - t0
620 logging.info('actual_time: %f', actual_time) 623 logging.info('actual_time: %f', actual_time)
621 624
622 # Close up whatever firewall rules we created for netperf 625 # Close up whatever firewall rules we created for netperf
623 for rule in np_rules: 626 for rule in np_rules:
624 self.__firewall_close(rule) 627 self.__firewall_close(rule)
625 628
626 # Results are prefixed with the iteration or a caller-defined name 629 self.write_perf({'test':test, 'mode':mode, 'actual_time':actual_time})
627 prefix = 'Netperf_%s_' % params.get('name', str(self.netperf_iter))
628 self.netperf_iter += 1
629
630 self.keyvals[prefix + 'test'] = test
631 self.keyvals[prefix + 'mode'] = mode
632 self.keyvals[prefix + 'actual_time'] = actual_time
633 630
634 logging.info(results) 631 logging.info(results)
635 632
636 lines = results.stdout.splitlines() 633 lines = results.stdout.splitlines()
637 634
638 # Each test type has a different form of output 635 # Each test type has a different form of output
639 if test in ['TCP_STREAM', 'TCP_MAERTS', 'TCP_SENDFILE']: 636 if test in ['TCP_STREAM', 'TCP_MAERTS', 'TCP_SENDFILE']:
640 """Parses the following (works for both TCP_STREAM, TCP_MAERTS and 637 """Parses the following (works for both TCP_STREAM, TCP_MAERTS and
641 TCP_SENDFILE) and returns a singleton containing throughput. 638 TCP_SENDFILE) and returns a singleton containing throughput.
642 639
643 TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to \ 640 TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to \
644 foo.bar.com (10.10.10.3) port 0 AF_INET 641 foo.bar.com (10.10.10.3) port 0 AF_INET
645 Recv Send Send 642 Recv Send Send
646 Socket Socket Message Elapsed 643 Socket Socket Message Elapsed
647 Size Size Size Time Throughput 644 Size Size Size Time Throughput
648 bytes bytes bytes secs. 10^6bits/sec 645 bytes bytes bytes secs. 10^6bits/sec
649 646
650 87380 16384 16384 2.00 941.28 647 87380 16384 16384 2.00 941.28
651 """ 648 """
652 self.keyvals[prefix + 'Throughput'] = float(lines[6].split()[4]) 649 self.write_perf({'Throughput':float(lines[6].split()[4])})
653 elif test == 'UDP_STREAM': 650 elif test == 'UDP_STREAM':
654 """Parses the following and returns a touple containing throughput 651 """Parses the following and returns a touple containing throughput
655 and the number of errors. 652 and the number of errors.
656 653
657 UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET \ 654 UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET \
658 to foo.bar.com (10.10.10.3) port 0 AF_INET 655 to foo.bar.com (10.10.10.3) port 0 AF_INET
659 Socket Message Elapsed Messages 656 Socket Message Elapsed Messages
660 Size Size Time Okay Errors Throughput 657 Size Size Time Okay Errors Throughput
661 bytes bytes secs # # 10^6bits/sec 658 bytes bytes secs # # 10^6bits/sec
662 659
663 129024 65507 2.00 3673 0 961.87 660 129024 65507 2.00 3673 0 961.87
664 131072 2.00 3673 961.87 661 131072 2.00 3673 961.87
665 """ 662 """
666 udp_tokens = lines[5].split() 663 udp_tokens = lines[5].split()
667 self.keyvals[prefix + 'Throughput'] = float(udp_tokens[5]) 664 self.write_perf({'Throughput':float(udp_tokens[5]),
668 self.keyvals[prefix + 'Errors'] = float(udp_tokens[4]) 665 'Errors':float(udp_tokens[4])})
669 elif test in ['TCP_RR', 'TCP_CRR', 'UDP_RR']: 666 elif test in ['TCP_RR', 'TCP_CRR', 'UDP_RR']:
670 """Parses the following which works for both rr (TCP and UDP) 667 """Parses the following which works for both rr (TCP and UDP)
671 and crr tests and returns a singleton containing transfer rate. 668 and crr tests and returns a singleton containing transfer rate.
672 669
673 TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET \ 670 TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET \
674 to foo.bar.com (10.10.10.3) port 0 AF_INET 671 to foo.bar.com (10.10.10.3) port 0 AF_INET
675 Local /Remote 672 Local /Remote
676 Socket Size Request Resp. Elapsed Trans. 673 Socket Size Request Resp. Elapsed Trans.
677 Send Recv Size Size Time Rate 674 Send Recv Size Size Time Rate
678 bytes Bytes bytes bytes secs. per sec 675 bytes Bytes bytes bytes secs. per sec
679 676
680 16384 87380 1 1 2.00 14118.53 677 16384 87380 1 1 2.00 14118.53
681 16384 87380 678 16384 87380
682 """ 679 """
683 self.kevals[prefix + 'Trasnfer_Rate'] = float(lines[6].split()[5]) 680 self.write_perf({'Trasnfer_Rate':float(lines[6].split()[5])})
684 else: 681 else:
685 raise error.TestError('Unhandled test') 682 raise error.TestError('Unhandled test')
686 683
687 return True 684 return True
688 685
689 686
690 def client_netperf(self, params): 687 def client_netperf(self, params):
691 """ Run netperf on the client against the server """ 688 """ Run netperf on the client against the server """
692 self.__run_netperf('client', params) 689 self.__run_netperf('client', params)
693 690
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 if server_addr is None and hasattr(client_attributes, 'server_addr'): 802 if server_addr is None and hasattr(client_attributes, 'server_addr'):
806 server_addr = client_attributes.server_addr 803 server_addr = client_attributes.server_addr
807 if server_addr is not None: 804 if server_addr is not None:
808 server['addr'] = server_addr; 805 server['addr'] = server_addr;
809 # TODO(sleffler) check for wifi_addr when no control address 806 # TODO(sleffler) check for wifi_addr when no control address
810 807
811 # tag jobs w/ the router's address on the control network 808 # tag jobs w/ the router's address on the control network
812 config['tagname'] = router['addr'] 809 config['tagname'] = router['addr']
813 810
814 return config 811 return config
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698