Chromium Code Reviews| OLD | NEW |
|---|---|
| 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, 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 | 10 |
| 11 class NotImplemented(Exception): | 11 class NotImplemented(Exception): |
| 12 def __init__(self, what): | 12 def __init__(self, what): |
| 13 self.what = what | 13 self.what = what |
| 14 | 14 |
| 15 | 15 |
| 16 def __str__(self): | 16 def __str__(self): |
| 17 return repr("Test method '%s' not implemented" % self.what) | 17 return repr("Test method '%s' not implemented" % self.what) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 a separate class that knows how to control the router. There are presently | 56 a separate class that knows how to control the router. There are presently |
| 57 two classes: BSDRouter for routers based on FreeBSD and LinuxRouter for | 57 two classes: BSDRouter for routers based on FreeBSD and LinuxRouter for |
| 58 those based on Linux/mac80211. Additional router support can be added | 58 those based on Linux/mac80211. Additional router support can be added |
| 59 by adding a new class and auto-selecting it in __init__. | 59 by adding a new class and auto-selecting it in __init__. |
| 60 | 60 |
| 61 The WiFiTest class could be generalized to handle clients other than | 61 The WiFiTest class could be generalized to handle clients other than |
| 62 ChromeOS; this would useful for systems that use Network Manager or | 62 ChromeOS; this would useful for systems that use Network Manager or |
| 63 wpa_supplicant directly. | 63 wpa_supplicant directly. |
| 64 """ | 64 """ |
| 65 | 65 |
| 66 def __init__(self, name, steps, router, client, server): | 66 def __init__(self, name, steps, config): |
| 67 self.name = name | 67 self.name = name |
| 68 self.steps = steps | 68 self.steps = steps |
| 69 self.router = router['host'] | 69 |
| 70 router = config['router'] | |
| 71 self.router = hosts.create_host(router['addr']) | |
| 72 # NB: truncate SSID to 32 characters | |
|
neb
2010/04/10 00:04:24
What does NB: stand for?
Sam Leffler
2010/04/12 15:52:55
Nota Bene
| |
| 73 self.defssid = self.__get_defssid(router['addr'])[0:32] | |
| 74 | |
| 75 if 'type' not in router: | |
| 76 # auto-detect router type | |
| 77 if site_linux_router.isLinuxRouter(self.router): | |
| 78 router['type'] = 'linux' | |
| 79 if site_bsd_router.isBSDRouter(self.router): | |
| 80 router['type'] = 'bsd' | |
| 81 else: | |
| 82 raise Exception('Unable to autodetect router type') | |
| 83 if router['type'] == 'linux': | |
| 84 self.wifi = site_linux_router.LinuxRouter(self.router, router, | |
| 85 self.defssid) | |
| 86 elif router['type'] == 'bsd': | |
| 87 self.wifi = site_bsd_router.BSDRouter(self.router, router, | |
| 88 self.defssid) | |
| 89 else: | |
| 90 raise Exception('Unsupported router') | |
| 91 | |
| 70 # | 92 # |
| 71 # The client machine must be reachable from the control machine. | 93 # The client machine must be reachable from the control machine. |
| 72 # The address on the wifi network is retrieved after it each time | 94 # The address on the wifi network is retrieved each time it |
| 73 # it associates to the router. | 95 # associates to the router. |
| 74 # | 96 # |
| 75 self.client = client['host'] | 97 client = config['client'] |
| 98 self.client = hosts.create_host(client['addr']) | |
| 76 self.client_at = autotest.Autotest(self.client) | 99 self.client_at = autotest.Autotest(self.client) |
| 77 self.client_wifi_ip = None # client's IP address on wifi net | 100 self.client_wifi_ip = None # client's IP address on wifi net |
| 101 # interface name on client | |
| 102 self.client_wlanif = client.get('wlandev', "wlan0") | |
| 103 | |
| 78 # | 104 # |
| 79 # The server machine may be multi-homed or only on the wifi | 105 # The server machine may be multi-homed or only on the wifi |
| 80 # network. When only on the wifi net we suppress server_* | 106 # network. When only on the wifi net we suppress server_* |
| 81 # requests since we cannot initiate them from the control machine. | 107 # requests since we cannot initiate them from the control machine. |
| 82 # | 108 # |
| 83 self.server = getattr(server, 'host', None) | 109 server = config['server'] |
| 84 if self.server is not None: | 110 # NB: server may not be reachable on the control network |
| 111 if 'addr' in server: | |
| 112 self.server = hosts.create_host(server['addr']) | |
| 85 self.server_at = autotest.Autotest(self.server) | 113 self.server_at = autotest.Autotest(self.server) |
| 86 # if not specified assume the same as the control address | 114 # if not specified assume the same as the control address |
| 87 self.server_wifi_ip = getattr(server, 'wifi_addr', self.server.ip) | 115 self.server_wifi_ip = getattr(server, 'wifi_addr', self.server.ip) |
| 88 else: | 116 else: |
| 89 # NB: must be set if not reachable from control | 117 self.server = None; |
| 118 # NB: wifi address must be set if not reachable from control | |
| 90 self.server_wifi_ip = server['wifi_addr'] | 119 self.server_wifi_ip = server['wifi_addr'] |
| 91 | 120 |
| 92 # NB: truncate SSID to 32 characters | |
| 93 self.defssid = self.__get_defssid()[0:32] | |
| 94 # interface name on client | |
| 95 self.wlanif = "wlan0" | |
| 96 | |
| 97 # auto-detect router type | |
| 98 router_uname = self.router.run('uname').stdout | |
| 99 if re.search('Linux', router_uname): | |
| 100 self.wifi = site_linux_router.LinuxRouter(self.router, router, self. defssid) | |
| 101 elif re.search('BSD', router_uname): | |
| 102 self.wifi = site_bsd_router.BSDRouter(self.router, router, self.defs sid) | |
| 103 else: | |
| 104 raise Exception('Unsupported router') | |
| 105 | |
| 106 # potential bg thread for ping untilstop | 121 # potential bg thread for ping untilstop |
| 107 self.ping_thread = None | 122 self.ping_thread = None |
| 108 | 123 |
| 109 | 124 |
| 110 def cleanup(self, params): | 125 def cleanup(self, params): |
| 111 """ Cleanup state: disconnect client and destroy ap """ | 126 """ Cleanup state: disconnect client and destroy ap """ |
| 112 self.disconnect({}) | 127 self.disconnect({}) |
| 113 self.wifi.destroy({}) | 128 self.wifi.destroy({}) |
| 114 | 129 |
| 115 | 130 |
| 116 def __get_defssid(self): | 131 def __get_defssid(self, ipaddr): |
| 117 # | 132 # |
| 118 # Calculate ssid based on test name; this lets us track progress | 133 # Calculate ssid based on test name; this lets us track progress |
| 119 # by watching beacon frames. | 134 # by watching beacon frames. |
| 120 # | 135 # |
| 121 return re.sub('[^a-zA-Z0-9_]', '_', \ | 136 return re.sub('[^a-zA-Z0-9_]', '_', "%s_%s" % (self.name, ipaddr)) |
| 122 "%s_%s" % (self.name, self.router.ip)) | |
| 123 | 137 |
| 124 | 138 |
| 125 def run(self): | 139 def run(self): |
| 126 """ | 140 """ |
| 127 Run a WiFi test. Each step is interpreted as a method either | 141 Run a WiFi test. Each step is interpreted as a method either |
| 128 in this class or the ancillary router class and invoked with | 142 in this class or the ancillary router class and invoked with |
| 129 the supplied parameter dictionary. | 143 the supplied parameter dictionary. |
| 130 """ | 144 """ |
| 131 for s in self.steps: | 145 for s in self.steps: |
| 132 method = s[0] | 146 method = s[0] |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 | 257 |
| 244 def connect(self, params): | 258 def connect(self, params): |
| 245 """ Connect client to AP/router """ | 259 """ Connect client to AP/router """ |
| 246 if 'ssid' not in params: | 260 if 'ssid' not in params: |
| 247 params['ssid'] = self.defssid | 261 params['ssid'] = self.defssid |
| 248 script = self.__get_connect_script(params) | 262 script = self.__get_connect_script(params) |
| 249 result = self.client.run("python<<'EOF'\n%s\nEOF\n" % script) | 263 result = self.client.run("python<<'EOF'\n%s\nEOF\n" % script) |
| 250 print "%s: %s" % (self.name, result.stdout[0:-1]) | 264 print "%s: %s" % (self.name, result.stdout[0:-1]) |
| 251 | 265 |
| 252 # fetch IP address of wireless device | 266 # fetch IP address of wireless device |
| 253 self.client_wifi_ip = self.__get_ipaddr(self.client, self.wlanif) | 267 self.client_wifi_ip = self.__get_ipaddr(self.client, self.client_wlanif) |
| 254 logging.info("%s: client WiFi-IP is %s", self.name, self.client_wifi_ip) | 268 logging.info("%s: client WiFi-IP is %s", self.name, self.client_wifi_ip) |
| 255 | 269 |
| 256 | 270 |
| 257 def __get_disconnect_script(self, params): | 271 def __get_disconnect_script(self, params): |
| 258 return ''' | 272 return ''' |
| 259 import dbus, dbus.mainloop.glib, gobject, sys, time | 273 import dbus, dbus.mainloop.glib, gobject, sys, time |
| 260 | 274 |
| 261 ssid = "''' + params['ssid'] + '''" | 275 ssid = "''' + params['ssid'] + '''" |
| 262 wait_timeout = ''' + params.get('wait_timeout', "15") + ''' | 276 wait_timeout = ''' + params.get('wait_timeout', "15") + ''' |
| 263 | 277 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 if 'ssid' not in params: | 310 if 'ssid' not in params: |
| 297 params['ssid'] = self.defssid | 311 params['ssid'] = self.defssid |
| 298 self.client_ping_bg_stop({}) | 312 self.client_ping_bg_stop({}) |
| 299 script = self.__get_disconnect_script(params) | 313 script = self.__get_disconnect_script(params) |
| 300 result = self.client.run("python<<'EOF'\n%s\nEOF\n" % script) | 314 result = self.client.run("python<<'EOF'\n%s\nEOF\n" % script) |
| 301 print "%s: %s" % (self.name, result.stdout[0:-1]) | 315 print "%s: %s" % (self.name, result.stdout[0:-1]) |
| 302 | 316 |
| 303 | 317 |
| 304 def client_check_bintval(self, params): | 318 def client_check_bintval(self, params): |
| 305 """ Verify negotiated beacon interval """ | 319 """ Verify negotiated beacon interval """ |
| 306 result = self.router.run("ifconfig %s" % self.wlanif) | 320 result = self.router.run("ifconfig %s" % self.client_wlanif) |
| 307 want = params[0] | 321 want = params[0] |
| 308 m = re.search('bintval ([0-9]*)', result.stdout) | 322 m = re.search('bintval ([0-9]*)', result.stdout) |
| 309 if m is None: | 323 if m is None: |
| 310 raise NameError | 324 raise NameError |
| 311 if m.group(1) != want: | 325 if m.group(1) != want: |
| 312 logging.error("client_check_bintval: wanted %s got %s", | 326 logging.error("client_check_bintval: wanted %s got %s", |
| 313 want, m.group(1)) | 327 want, m.group(1)) |
| 314 raise AssertionError | 328 raise AssertionError |
| 315 | 329 |
| 316 | 330 |
| 317 def client_check_dtimperiod(self, params): | 331 def client_check_dtimperiod(self, params): |
| 318 """ Verify negotiated DTIM period """ | 332 """ Verify negotiated DTIM period """ |
| 319 result = self.router.run("ifconfig %s" % self.wlanif) | 333 result = self.router.run("ifconfig %s" % self.client_wlanif) |
| 320 want = params[0] | 334 want = params[0] |
| 321 m = re.search('dtimperiod ([0-9]*)', result.stdout) | 335 m = re.search('dtimperiod ([0-9]*)', result.stdout) |
| 322 if m is None: | 336 if m is None: |
| 323 raise NameError | 337 raise NameError |
| 324 if m.group(1) != want: | 338 if m.group(1) != want: |
| 325 logging.error("client_check_dtimperiod: wanted %s got %s", | 339 logging.error("client_check_dtimperiod: wanted %s got %s", |
| 326 want, m.group(1)) | 340 want, m.group(1)) |
| 327 raise AssertionError | 341 raise AssertionError |
| 328 | 342 |
| 329 | 343 |
| 330 def client_check_rifs(self, params): | 344 def client_check_rifs(self, params): |
| 331 """ Verify negotiated RIFS setting """ | 345 """ Verify negotiated RIFS setting """ |
| 332 result = self.router.run("ifconfig %s" % self.wlanif) | 346 result = self.router.run("ifconfig %s" % self.client_wlanif) |
| 333 m = re.search('[^-]rifs', result.stdout) | 347 m = re.search('[^-]rifs', result.stdout) |
| 334 if m is None: | 348 if m is None: |
| 335 raise AssertionError | 349 raise AssertionError |
| 336 | 350 |
| 337 | 351 |
| 338 def client_check_shortgi(self, params): | 352 def client_check_shortgi(self, params): |
| 339 """ Verify negotiated Short GI setting """ | 353 """ Verify negotiated Short GI setting """ |
| 340 result = self.router.run("ifconfig %s" % self.wlanif) | 354 result = self.router.run("ifconfig %s" % self.client_wlanif) |
| 341 m = re.search('[^-]shortgi', result.stdout) | 355 m = re.search('[^-]shortgi', result.stdout) |
| 342 if m is None: | 356 if m is None: |
| 343 raise AssertionError | 357 raise AssertionError |
| 344 | 358 |
| 345 | 359 |
| 346 def client_monitor_start(self, params): | 360 def client_monitor_start(self, params): |
| 347 """ Start monitoring system events """ | 361 """ Start monitoring system events """ |
| 348 raise NotImplemented("client_monitor_start") | 362 raise NotImplemented("client_monitor_start") |
| 349 | 363 |
| 350 | 364 |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 try: | 641 try: |
| 628 test = eval(fd.read()) | 642 test = eval(fd.read()) |
| 629 except Exception, e: | 643 except Exception, e: |
| 630 logging.error("%s: %s", os.path.join(dir, file), str(e)) | 644 logging.error("%s: %s", os.path.join(dir, file), str(e)) |
| 631 raise e | 645 raise e |
| 632 test['file'] = file | 646 test['file'] = file |
| 633 tests.append(test) | 647 tests.append(test) |
| 634 # use filenames to sort | 648 # use filenames to sort |
| 635 return sorted(tests, cmp=__byfile) | 649 return sorted(tests, cmp=__byfile) |
| 636 | 650 |
| 651 | |
| 652 def read_wifi_testbed_config(file, client_addr=None, server_addr=None, | |
| 653 router_addr=None): | |
| 654 # read configuration file | |
| 655 fd = open(file) | |
| 656 config = eval(fd.read()) | |
| 657 | |
| 658 # client must be reachable on the control network | |
| 659 client = config['client'] | |
| 660 if client_addr is not None: | |
| 661 client['addr'] = client_addr; | |
| 662 | |
| 663 # router must be reachable on the control network | |
| 664 router = config['router'] | |
| 665 if router_addr is not None: | |
| 666 server['router'] = router_addr; | |
| 667 | |
| 668 server = config['server'] | |
| 669 if server_addr is not None: | |
| 670 server['addr'] = server_addr; | |
| 671 # TODO(sleffler) check for wifi_addr when no control address | |
| 672 | |
| 673 # tag jobs w/ the router's address on the control network | |
| 674 config['tagname'] = router['addr'] | |
| 675 | |
| 676 return config | |
| OLD | NEW |