OLD | NEW |
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 # Copyright (c) 2011 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, datetime, fnmatch, logging, os, re, string, threading, time | 5 import common, datetime, 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_linux_server |
10 from autotest_lib.server import site_host_attributes | 11 from autotest_lib.server import site_host_attributes |
11 from autotest_lib.server import site_eap_certs | 12 from autotest_lib.server import site_eap_certs |
12 from autotest_lib.server import test | 13 from autotest_lib.server import test |
13 from autotest_lib.client.common_lib import error | 14 from autotest_lib.client.common_lib import error |
14 | 15 |
15 class NotImplemented(Exception): | 16 class NotImplemented(Exception): |
16 def __init__(self, what): | 17 def __init__(self, what): |
17 self.what = what | 18 self.what = what |
18 | 19 |
19 | 20 |
(...skipping 27 matching lines...) Expand all Loading... |
47 client_monitor_stop stop monitoring for wireless system events | 48 client_monitor_stop stop monitoring for wireless system events |
48 client_check_event_* check the client's event log for an event; | 49 client_check_event_* check the client's event log for an event; |
49 should always be preceded by client_monitor_start | 50 should always be preceded by client_monitor_start |
50 sleep pause on the autotest server for a time | 51 sleep pause on the autotest server for a time |
51 client_ping ping the server on the client machine | 52 client_ping ping the server on the client machine |
52 server_ping ping the client on the server machine | 53 server_ping ping the client on the server machine |
53 client_iperf run iperf on the client to the server | 54 client_iperf run iperf on the client to the server |
54 server_iperf run iperf on the server to the client | 55 server_iperf run iperf on the server to the client |
55 client_netperf run netperf on the client to the server | 56 client_netperf run netperf on the client to the server |
56 server_netperf run netperf on the server to the client | 57 server_netperf run netperf on the server to the client |
| 58 vpn_client_load_tunnel load 'tun' device for VPN client |
| 59 vpn_client_config launch a VPN client to connect with the |
| 60 VPN server |
57 | 61 |
58 Steps that are done on the client or server machine are implemented in | 62 Steps that are done on the client or server machine are implemented in |
59 this class. Steps that are done on the wifi router are implemented in | 63 this class. Steps that are done on the wifi router are implemented in |
60 a separate class that knows how to control the router. There are presently | 64 a separate class that knows how to control the router. There are presently |
61 two classes: BSDRouter for routers based on FreeBSD and LinuxRouter for | 65 two classes: BSDRouter for routers based on FreeBSD and LinuxRouter for |
62 those based on Linux/mac80211. Additional router support can be added | 66 those based on Linux/mac80211. Additional router support can be added |
63 by adding a new class and auto-selecting it in __init__. | 67 by adding a new class and auto-selecting it in __init__. |
64 | 68 |
65 The WiFiTest class could be generalized to handle clients other than | 69 The WiFiTest class could be generalized to handle clients other than |
66 ChromeOS; this would useful for systems that use Network Manager or | 70 ChromeOS; this would useful for systems that use Network Manager or |
67 wpa_supplicant directly. | 71 wpa_supplicant directly. |
68 """ | 72 """ |
69 | 73 |
70 def __init__(self, name, steps, config): | 74 def __init__(self, name, steps, config): |
71 self.name = name | 75 self.name = name |
72 self.steps = steps | 76 self.steps = steps |
73 self.perf_keyvals = {} | 77 self.perf_keyvals = {} |
74 | 78 |
75 self.cur_frequency = None; | 79 self.cur_frequency = None |
76 self.cur_phymode = None; | 80 self.cur_phymode = None |
77 self.cur_security = None; | 81 self.cur_security = None |
| 82 self.vpn_kind = None |
78 | 83 |
79 router = config['router'] | 84 router = config['router'] |
| 85 # |
| 86 # The server machine may be multi-homed or only on the wifi |
| 87 # network. When only on the wifi net we suppress server_* |
| 88 # requests since we cannot initiate them from the control machine. |
| 89 # |
| 90 server = config['server'] |
| 91 # NB: server may not be reachable on the control network |
| 92 |
80 self.router = hosts.create_host(router['addr']) | 93 self.router = hosts.create_host(router['addr']) |
81 # NB: truncate SSID to 32 characters | 94 # NB: truncate SSID to 32 characters |
82 self.defssid = self.__get_defssid(router['addr'])[0:32] | 95 self.defssid = self.__get_defssid(router['addr'])[0:32] |
83 | 96 |
84 defaults = config.get('defaults', {}) | 97 defaults = config.get('defaults', {}) |
85 self.deftimeout = defaults.get('timeout', 30) | 98 self.deftimeout = defaults.get('timeout', 30) |
86 self.defpingcount = defaults.get('pingcount', 10) | 99 self.defpingcount = defaults.get('pingcount', 10) |
87 self.defwaittime = defaults.get('netperf_wait_time', 3) | 100 self.defwaittime = defaults.get('netperf_wait_time', 3) |
88 self.defiperfport = str(defaults.get('iperf_port', 12866)) | 101 self.defiperfport = str(defaults.get('iperf_port', 12866)) |
89 self.defnetperfport = str(defaults.get('netperf_port', 12865)) | 102 self.defnetperfport = str(defaults.get('netperf_port', 12865)) |
(...skipping 19 matching lines...) Expand all Loading... |
109 # The address on the wifi network is retrieved each time it | 122 # The address on the wifi network is retrieved each time it |
110 # associates to the router. | 123 # associates to the router. |
111 # | 124 # |
112 client = config['client'] | 125 client = config['client'] |
113 self.client = hosts.create_host(client['addr']) | 126 self.client = hosts.create_host(client['addr']) |
114 self.client_at = autotest.Autotest(self.client) | 127 self.client_at = autotest.Autotest(self.client) |
115 self.client_wifi_ip = None # client's IP address on wifi net | 128 self.client_wifi_ip = None # client's IP address on wifi net |
116 self.client_wifi_device_path = None # client's flimflam wifi path | 129 self.client_wifi_device_path = None # client's flimflam wifi path |
117 self.client_installed_scripts = {} | 130 self.client_installed_scripts = {} |
118 | 131 |
119 # | |
120 # The server machine may be multi-homed or only on the wifi | |
121 # network. When only on the wifi net we suppress server_* | |
122 # requests since we cannot initiate them from the control machine. | |
123 # | |
124 server = config['server'] | |
125 # NB: server may not be reachable on the control network | |
126 if 'addr' in server: | 132 if 'addr' in server: |
127 self.server = hosts.create_host(server['addr']) | 133 self.server = hosts.create_host(server['addr']) |
128 self.server_at = autotest.Autotest(self.server) | 134 self.server_at = autotest.Autotest(self.server) |
129 # if not specified assume the same as the control address | 135 # if not specified assume the same as the control address |
130 self.server_wifi_ip = server.get('wifi_addr', self.server.ip) | 136 self.server_wifi_ip = server.get('wifi_addr', self.server.ip) |
131 self.__server_discover_commands(server) | 137 self.__server_discover_commands(server) |
132 else: | 138 else: |
133 self.server = None | 139 self.server = None |
134 # NB: wifi address must be set if not reachable from control | 140 # NB: wifi address must be set if not reachable from control |
135 self.server_wifi_ip = server['wifi_addr'] | 141 self.server_wifi_ip = server['wifi_addr'] |
136 | 142 |
| 143 # hosting_server is a machine which hosts network services, |
| 144 # such as VPN. |
| 145 self.hosting_server = site_linux_server.LinuxServer(self.server, server) |
| 146 |
137 # potential bg thread for ping untilstop | 147 # potential bg thread for ping untilstop |
138 self.ping_thread = None | 148 self.ping_thread = None |
139 | 149 |
140 # potential bg thread for client network monitoring | 150 # potential bg thread for client network monitoring |
141 self.client_netdump_thread = None | 151 self.client_netdump_thread = None |
142 self.__client_discover_commands(client) | 152 self.__client_discover_commands(client) |
143 self.profile_save({}) | 153 self.profile_save({}) |
144 self.firewall_rules = [] | 154 self.firewall_rules = [] |
145 | 155 |
146 # interface name on client | 156 # interface name on client |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 logging.info("%s: step '%s' (expect failure) params %s", | 279 logging.info("%s: step '%s' (expect failure) params %s", |
270 self.name, method, params) | 280 self.name, method, params) |
271 else: | 281 else: |
272 logging.info("%s: step '%s' params %s", self.name, method, | 282 logging.info("%s: step '%s' params %s", self.name, method, |
273 params) | 283 params) |
274 | 284 |
275 self.error_message = '' | 285 self.error_message = '' |
276 func = getattr(self, method, None) | 286 func = getattr(self, method, None) |
277 if func is None: | 287 if func is None: |
278 func = getattr(self.wifi, method, None) | 288 func = getattr(self.wifi, method, None) |
| 289 if func is None: |
| 290 func = getattr(self.hosting_server, method, None) |
279 if func is not None: | 291 if func is not None: |
280 try: | 292 try: |
281 func(params) | 293 func(params) |
282 if expect_failure is True: | 294 if expect_failure is True: |
283 expect_failure = False | 295 expect_failure = False |
284 raise error.TestFail("Expected failure") | 296 raise error.TestFail("Expected failure") |
285 except Exception, e: | 297 except Exception, e: |
286 if expect_failure is True: | 298 if expect_failure is True: |
287 if not failure_string: | 299 if not failure_string: |
288 continue | 300 continue |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 | 378 |
367 def install_files(self, params): | 379 def install_files(self, params): |
368 """ Install files on the client or router with the provided | 380 """ Install files on the client or router with the provided |
369 contents""" | 381 contents""" |
370 | 382 |
371 systemname = params.get('system', None) | 383 systemname = params.get('system', None) |
372 if systemname == 'router': | 384 if systemname == 'router': |
373 system = self.router | 385 system = self.router |
374 elif systemname == 'client': | 386 elif systemname == 'client': |
375 system = self.client | 387 system = self.client |
| 388 elif systemname == 'server': |
| 389 system = self.server |
376 else: | 390 else: |
377 raise error.TestFail('install_files: Must specify router or client') | 391 raise error.TestFail('install_files: Must specify router, ' |
| 392 'server or client') |
378 | 393 |
379 for name,contents in params.get('files', {}).iteritems(): | 394 for name,contents in params.get('files', {}).iteritems(): |
380 self.insert_file(system, name, contents) | 395 self.insert_file(system, name, contents) |
381 | 396 |
382 | 397 |
383 def connect(self, params): | 398 def connect(self, params): |
384 """ Connect client to AP/router """ | 399 """ Connect client to AP/router """ |
385 | 400 |
386 script_client_file = self.install_script('site_wlan_connect.py', | 401 script_client_file = self.install_script('site_wlan_connect.py', |
387 'site_wlan_wait_state.py') | 402 'site_wlan_wait_state.py') |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 def client_suspend_end(self, params): | 1089 def client_suspend_end(self, params): |
1075 """ Join the backgrounded suspend thread """ | 1090 """ Join the backgrounded suspend thread """ |
1076 | 1091 |
1077 self.client_suspend_thread.join() | 1092 self.client_suspend_thread.join() |
1078 if self.client_suspend_thread.result.exit_status: | 1093 if self.client_suspend_thread.result.exit_status: |
1079 raise error.TestError('suspend failed') | 1094 raise error.TestError('suspend failed') |
1080 | 1095 |
1081 def restart_supplicant(self, params): | 1096 def restart_supplicant(self, params): |
1082 """ Restart wpa_supplicant. Cert params are unfortunately "sticky". """ | 1097 """ Restart wpa_supplicant. Cert params are unfortunately "sticky". """ |
1083 | 1098 |
1084 self.client.run("stop wpasupplicant; start wpasupplicant"); | 1099 self.client.run("stop wpasupplicant; start wpasupplicant") |
1085 | 1100 |
1086 def __list_profile(self): | 1101 def __list_profile(self): |
1087 ret = [] | 1102 ret = [] |
1088 result = self.client.run('%s/test/list-entries' % | 1103 result = self.client.run('%s/test/list-entries' % |
1089 self.client_cmd_flimflam_lib) | 1104 self.client_cmd_flimflam_lib) |
1090 for line in result.stdout.splitlines(): | 1105 for line in result.stdout.splitlines(): |
1091 m = re.search('\[(wifi_.*)\]', line) | 1106 m = re.search('\[(wifi_.*)\]', line) |
1092 if m is not None: | 1107 if m is not None: |
1093 ret.append(m.group(1)) | 1108 ret.append(m.group(1)) |
1094 return ret | 1109 return ret |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 system = { 'client': self.client, | 1179 system = { 'client': self.client, |
1165 'server': self.server, | 1180 'server': self.server, |
1166 'router': self.router }.get(name) | 1181 'router': self.router }.get(name) |
1167 if not system: | 1182 if not system: |
1168 raise error.TestFail('time_sync: Must specify ' | 1183 raise error.TestFail('time_sync: Must specify ' |
1169 'router, client or server') | 1184 'router, client or server') |
1170 datefmt = '%m%d%H%M%Y.%S' if name == 'client' else '%Y%m%d%H%M.%S' | 1185 datefmt = '%m%d%H%M%Y.%S' if name == 'client' else '%Y%m%d%H%M.%S' |
1171 system.run('date -u %s' % | 1186 system.run('date -u %s' % |
1172 datetime.datetime.utcnow().strftime(datefmt)) | 1187 datetime.datetime.utcnow().strftime(datefmt)) |
1173 | 1188 |
| 1189 def vpn_client_load_tunnel(self, params): |
| 1190 """ Load the 'tun' device. |
| 1191 |
| 1192 Necessary when the VPN Server is configured with 'dev tun'. |
| 1193 """ |
| 1194 result = self.client.run('modprobe tun') # When server using tunnel. |
| 1195 |
| 1196 def vpn_client_config(self, params): |
| 1197 """ Configure & launch the VPN client. |
| 1198 |
| 1199 Parameters: |
| 1200 |
| 1201 'kind' : required |
| 1202 Indicates the kind of VPN which is to be used. |
| 1203 Valid values are: |
| 1204 |
| 1205 openvpn |
| 1206 |
| 1207 'vpn-host-ip': optional |
| 1208 Specifies the IP of the VPN server. If not provided, |
| 1209 defaults to 'self.server_wifi_ip' |
| 1210 |
| 1211 'files' : required |
| 1212 A dict which contains a set of file names. |
| 1213 |
| 1214 'ca-certificate' : path to CA certificate file |
| 1215 'client-certificate' : path to client certificate file |
| 1216 'client-key' : path to client key file |
| 1217 """ |
| 1218 self.vpn_client_kill({}) # Must be first. Relies on self.vpn_kind. |
| 1219 self.vpn_kind = params.get('kind', None) |
| 1220 vpn_host_ip = params.get('vpn-host-ip', self.server_wifi_ip) |
| 1221 |
| 1222 # Must get 'ca_certificate', 'client-certificate' and 'client-key'. |
| 1223 cert_pathnames = params.get('files', {}) |
| 1224 |
| 1225 if self.vpn_kind is None: |
| 1226 raise error.TestFail('No VPN kind specified for this test.') |
| 1227 elif self.vpn_kind == 'openvpn': |
| 1228 # connect-vpn openvpn <name> <host> <domain> <cafile> <certfile> |
| 1229 result = self.client.run('%s/test/connect-vpn openvpn ' |
| 1230 'vpn-name %s vpn-domain ' |
| 1231 '%s ' # ca certificate |
| 1232 '%s ' # client certificate |
| 1233 '%s' % # client key |
| 1234 (self.client_cmd_flimflam_lib, |
| 1235 vpn_host_ip, |
| 1236 cert_pathnames['ca-certificate'], |
| 1237 cert_pathnames['client-certificate'], |
| 1238 cert_pathnames['client-key'])) |
| 1239 else: |
| 1240 raise error.TestFail('(internal error): No launch case ' |
| 1241 'for VPN kind (%s)' % self.vpn_kind) |
| 1242 |
| 1243 def vpn_client_kill(self, params): |
| 1244 """ Kill the VPN client if it's running. """ |
| 1245 if self.vpn_kind is not None: |
| 1246 if self.vpn_kind == 'openvpn': |
| 1247 self.server.run("pkill openvpn") |
| 1248 else: |
| 1249 raise error.TestFail('(internal error): No kill case ' |
| 1250 'for VPN kind (%s)' % self.vpn_kind) |
| 1251 self.vpn_kind = None |
1174 | 1252 |
1175 class HelperThread(threading.Thread): | 1253 class HelperThread(threading.Thread): |
1176 # Class that wraps a ping command in a thread so it can run in the bg. | 1254 # Class that wraps a ping command in a thread so it can run in the bg. |
1177 def __init__(self, client, cmd): | 1255 def __init__(self, client, cmd): |
1178 threading.Thread.__init__(self) | 1256 threading.Thread.__init__(self) |
1179 self.client = client | 1257 self.client = client |
1180 self.cmd = cmd | 1258 self.cmd = cmd |
1181 | 1259 |
1182 def run(self): | 1260 def run(self): |
1183 # NB: set ignore_status as we're always terminated w/ pkill | 1261 # NB: set ignore_status as we're always terminated w/ pkill |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 except error.TestFail: | 1377 except error.TestFail: |
1300 if 'expect_failure' in testcase: | 1378 if 'expect_failure' in testcase: |
1301 self.expect_failure(name, testcase['expect_failure']) | 1379 self.expect_failure(name, testcase['expect_failure']) |
1302 else: | 1380 else: |
1303 raise | 1381 raise |
1304 except Exception, e: | 1382 except Exception, e: |
1305 if 'expect_failure' in testcase: | 1383 if 'expect_failure' in testcase: |
1306 self.expect_failure(name, testcase['expect_failure']) | 1384 self.expect_failure(name, testcase['expect_failure']) |
1307 else: | 1385 else: |
1308 raise | 1386 raise |
OLD | NEW |