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 |