autotest: Migrates network_WiFiRoaming/004SuspendTimeout to new method.

Replaces network_WiFiRoaming/004SuspendTimeout test with script and control
file in network_WiFi_RoamSuspendTimeout directory.  New code conforms to test
infrastructure changes provided to address crbug.com/224443.

In this test, the DUT connects to the AP and goes to sleep.  While the
DUT is asleep, the AP deauths the DUT.  The test checks to see whether
the DUT reconnects after it wakes up.

BUG=chromium:263889
TEST=autotest

Change-Id: I7783c342fbe5d9fcd97d4b333996e70f58df55e4
Reviewed-on: https://chromium-review.googlesource.com/176010
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Commit-Queue: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
diff --git a/server/site_linux_router.py b/server/site_linux_router.py
index 25fd942..cd30f40 100644
--- a/server/site_linux_router.py
+++ b/server/site_linux_router.py
@@ -7,6 +7,7 @@
 import re
 import string
 
+from autotest_lib.client.common_lib import base_utils
 from autotest_lib.client.common_lib import error
 from autotest_lib.server import site_linux_system
 from autotest_lib.server.cros import wifi_test_utils
@@ -784,16 +785,29 @@
         self.iw_runner.set_tx_power(interface, power)
 
 
-    def deauth(self, params):
+    def deauth_client(self, client_mac):
         """Deauthenticates a client described in params.
 
-        @param params dict containing a key 'client'.
+        @param client_mac string containing the mac address of the client to be
+               deauthenticated.
 
         """
         self.router.run('%s -p%s deauthenticate %s' %
                         (self.cmd_hostapd_cli,
                          self.hostapd['conf']['ctrl_interface'],
-                         params['client']))
+                         client_mac))
+
+
+    @base_utils.deprecated
+    def deauth(self, params):
+        """Deauthenticates a client described in params.
+
+        Deprecated: Call 'deauth_client', instead.
+
+        @param params dict containing a key 'client'.
+
+        """
+        self.deauth_client(params['client'])
 
 
     def send_management_frame(self, frame_type, instance=0):
diff --git a/server/site_tests/network_WiFiRoaming/004SuspendTimeout b/server/site_tests/network_WiFiRoaming/004SuspendTimeout
deleted file mode 100644
index f58548d..0000000
--- a/server/site_tests/network_WiFiRoaming/004SuspendTimeout
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This test run seeks to place the DUT in suspend-to-RAM for longer
-# than the AP will wait for it, to see if/how the DUT notices that
-# it's been disassociated.
-#
-# open authentication (no crypto)
-{ "name":"Suspend",
-  "steps":[             # Channel 1,6,11
-    [ "create",         { "type":"hostap" } ],
-
-    # Connect the DUT to an AP
-    [ "config",         { "channel":"2412", "mode":"11b",
-                          "ssid_suffix": "t1",
-                          "ap_max_inactivity" : '10'} ],
-    [ "connect",        { "security":"none" } ],
-    [ "client_ping",    { "count":"10" } ],
-
-    # Put the system to sleep for 20 seconds
-    [ "client_suspend_bg", { "suspend_time": "20" } ],
-
-    # Wait for DUT to go to sleep
-    [ "sleep",          { "time":"15" } ],
-
-    # Deauth the DUT while it sleeps
-    [ "client_deauth",  { } ],
-
-    # Wait for DUT to wake up
-    [ "client_suspend_end",  { } ],
-
-    # If the DUT realizes that it has been deauthed, then it should
-    # reassociate quickly and the ping below should succeeed.
-    [ "client_ping",    { "count":"10" } ],
-
-    # Pull some time differences out of the logs
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":"Reason: 7",
-                          "perf":"deauth" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":": associated",
-                          "perf":"reassociated" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":" -> COMPLETED",
-                          "perf":"reconnect" } ],
-    [ "destroy" ],
-
-  ],
-}
diff --git a/server/site_tests/network_WiFiRoaming/004SuspendTimeoutRSN b/server/site_tests/network_WiFiRoaming/004SuspendTimeoutRSN
deleted file mode 100644
index ef2c3cb..0000000
--- a/server/site_tests/network_WiFiRoaming/004SuspendTimeoutRSN
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This test run seeks to place the DUT in suspend-to-RAM for longer
-# than the AP will wait for it, to see if/how the DUT notices that
-# it's been disassociated.
-#
-# RSN+CCMP/WPA-PSK authentication
-{ "name":"SuspendRSN",
-  "steps":[             # Channel [1,6,11]
-    [ "create",         { "type":"hostap" } ],
-
-    # Connect the DUT to an AP
-    [ "config",         { "channel":"2412", "mode":"11g",
-                          "wpa":"2", "wpa_key_mgmt":"WPA-PSK",
-                          "wpa_pairwise":"CCMP",
-                          "wpa_passphrase":"chromeos",
-                          "ap_max_inactivity" : '10'} ],
-    [ "connect",        { "security":"rsn", "psk":"chromeos" } ],
-    [ "client_ping",    { "count":"10" } ],
-
-    # Put the system to sleep for 20 seconds
-    [ "client_suspend_bg", { "suspend_time": "20" } ],
-
-    # Wait for DUT to go to sleep
-    [ "sleep",          { "time":"15" } ],
-
-    # Deauth the DUT while it sleeps
-    [ "client_deauth",  { } ],
-
-    # Wait for DUT to wake up
-    [ "client_suspend_end",  { } ],
-
-    # If the DUT realizes that it has been deauthed, then it should
-    # reassociate quickly and the ping below should succeeed.
-    [ "client_ping",    { "count":"10" } ],
-
-    # Pull some time differences out of the logs
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":"Reason: 7",
-                          "perf":"deauth" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":": associated",
-                          "perf":"reassociated" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":" -> COMPLETED",
-                          "perf":"reconnect" } ],
-    [ "destroy" ],
-
-  ],
-}
diff --git a/server/site_tests/network_WiFiRoaming/004SuspendTimeoutWEP b/server/site_tests/network_WiFiRoaming/004SuspendTimeoutWEP
deleted file mode 100644
index 8070714..0000000
--- a/server/site_tests/network_WiFiRoaming/004SuspendTimeoutWEP
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This test run seeks to place the DUT in suspend-to-RAM for longer
-# than the AP will wait for it, to see if/how the DUT notices that
-# it's been disassociated.
-#
-# static key WEP-40
-{ "name":"SuspendWEP",
-  "steps":[             # Channel [1,6,11]
-    [ "create",         { "type":"hostap" } ],
-
-    # Connect the DUT to an AP
-    [ "config",         { "channel":"2412", "mode":"11g",
-                          "ssid_suffix": "t1",
-#                          "authmode":"open", "wepmode":"on",
-                          "wepmode":"on",
-                          # 10 digits : 0123456789
-                          "wep_key0":  "0123456789",
-                          "wep_key1":  "89abcdef01",
-                          "wep_key2":  "9876543210",
-                          "wep_key3":  "fedcba9876",
-                          "deftxkey":"1",
-                          "ap_max_inactivity" : '10'} ],
-
-    # key index 1, 40-bit WEP
-    [ "connect",        { "security":"wep", "psk":"1:89abcdef01" } ],
-    [ "client_ping",    { "count":"10" } ],
-
-    # Put the system to sleep for 20 seconds
-    [ "client_suspend_bg", { "suspend_time": "20" } ],
-
-    # Wait for DUT to go to sleep
-    [ "sleep",          { "time":"15" } ],
-
-    # Deauth the DUT while it sleeps
-    [ "client_deauth",  { } ],
-
-    # Wait for DUT to wake up
-    [ "client_suspend_end",  { } ],
-
-    # If the DUT realizes that it has been deauthed, then it should
-    # reassociate quickly and the ping below should succeeed.
-    [ "client_ping",    { "count":"10" } ],
-
-    # Pull some time differences out of the logs
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":"Reason: 7",
-                          "perf":"deauth" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":": associated",
-                          "perf":"reassociated" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":" -> COMPLETED",
-                          "perf":"reconnect" } ],
-    [ "destroy" ],
-
-  ],
-}
diff --git a/server/site_tests/network_WiFiRoaming/004SuspendTimeoutWPA b/server/site_tests/network_WiFiRoaming/004SuspendTimeoutWPA
deleted file mode 100644
index d286f15..0000000
--- a/server/site_tests/network_WiFiRoaming/004SuspendTimeoutWPA
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This test run seeks to place the DUT in suspend-to-RAM for longer
-# than the AP will wait for it, to see if/how the DUT notices that
-# it's been disassociated.
-#
-# WPA+TKIP/WPA-PSK authentication
-{ "name":"SuspendWPA",
-  "steps":[             # Channel 1,6,11
-    [ "create",         { "type":"hostap" } ],
-
-    # Connect the DUT to an AP
-    [ "config",         { "channel":"2412", "mode":"11g",
-                          "wpa":"1", "wpa_key_mgmt":"WPA-PSK",
-                          "wpa_pairwise":"TKIP",
-                          "wpa_passphrase":"chromeos",
-                          "ap_max_inactivity" : '10'} ],
-    [ "connect",        { "security":"wpa", "psk":"chromeos" } ],
-    [ "client_ping",    { "count":"10" } ],
-
-    # Put the system to sleep for 20 seconds
-    [ "client_suspend_bg", { "suspend_time": "20" } ],
-
-    # Wait for DUT to go to sleep
-    [ "sleep",          { "time":"15" } ],
-
-    # Deauth the DUT while it sleeps
-    [ "client_deauth",  { } ],
-
-    # Wait for DUT to wake up
-    [ "client_suspend_end",  { } ],
-
-    # If the DUT realizes that it has been deauthed, then it should
-    # reassociate quickly and the ping below should succeeed.
-    [ "client_ping",    { "count":"10" } ],
-
-    # Pull some time differences out of the logs
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":"Reason: 7",
-                          "perf":"deauth" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":": associated",
-                          "perf":"reassociated" } ],
-    [ "log_time_diff",  { "from":"Low-level resume complete",
-                          "to":" -> COMPLETED",
-                          "perf":"reconnect" } ],
-    [ "destroy" ],
-
-  ],
-}
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11a b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11a
new file mode 100644
index 0000000..3bc6991
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11a
@@ -0,0 +1,32 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_check11a'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This test verifies that DUT can reconnect to an open 802.11a network
+on channel 48 after deauthentication while the DUT is suspended.
+"""
+
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    a_mode = hostap_config.HostapConfig.MODE_11A
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(channel=48,
+                                                              mode=a_mode))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11b b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11b
new file mode 100644
index 0000000..65510cf
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11b
@@ -0,0 +1,33 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_check11b'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This test attempts to verify that we can reconnect to a router over 802.11b
+on channel 6 (2.4 Ghz band) and correctly send IP traffic after
+deauthentication while the DUT is suspended.
+"""
+
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    b_mode = hostap_config.HostapConfig.MODE_11B
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(channel=6,
+                                                              mode=b_mode))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11g b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11g
new file mode 100644
index 0000000..40eecb2
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_check11g
@@ -0,0 +1,33 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_check11g'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This test attempts to verify that we can reconnect to a router over 802.11g
+on channel 11 (2.4 Ghz band) and correctly send IP traffic after
+deauthentication while the DUT is suspended.
+"""
+
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    g_mode = hostap_config.HostapConfig.MODE_11G
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(channel=11,
+                                                              mode=g_mode))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWEP104 b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWEP104
new file mode 100644
index 0000000..a3a20bd
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWEP104
@@ -0,0 +1,44 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_checkWEP104'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This test case verifies that the DUT can reconnect to an AP using WEP
+shared system authentication after deauthentication while the DUT is suspended.
+"""
+
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
+from autotest_lib.server.cros.network import hostap_config
+
+
+
+def run(machine):
+    # FYI: D-Bus requires string parameters must be valid UTF-8.
+    wep_keys = ['0123456789abcdef0123456789',
+                '123456789abcdef01234567890',
+                '23456789abcdef012345678901',
+                '3456789abcdef0123456789012']
+    wep_config = xmlrpc_security_types.WEPConfig(
+            wep_keys,
+            wep_default_key=2,
+            auth_algorithm=xmlrpc_security_types.WEPConfig.AUTH_ALGORITHM_SHARED)
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(
+                         frequency=2412,
+                         mode=hostap_config.HostapConfig.MODE_11G,
+                         security_config=wep_config))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWEP40 b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWEP40
new file mode 100644
index 0000000..1c37c00
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWEP40
@@ -0,0 +1,44 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_checkWEP40'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This test case verifies that the DUT can reconnect to an AP using
+WEP open system authentication after deauthentication while the DUT is
+suspended.
+"""
+
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    # FYI: D-Bus requires string parameters must be valid UTF-8.
+    wep_keys = ['abcde',
+                'fghij',
+                'klmno',
+                'pqrst']
+    wep_config = xmlrpc_security_types.WEPConfig(
+            wep_keys,
+            wep_default_key=2,
+            auth_algorithm=xmlrpc_security_types.WEPConfig.AUTH_ALGORITHM_OPEN)
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(
+                         frequency=2437,
+                         mode=hostap_config.HostapConfig.MODE_11G,
+                         security_config=wep_config))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA2 b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA2
new file mode 100644
index 0000000..3a1e143
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA2
@@ -0,0 +1,38 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_checkWPA2'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This tests verifies that we can reconnect to an AP broadcasting a WPA2 (aka
+RSN) network after deauthentication while the DUT is suspended.  By definition,
+traffic on this network is encrypted under AES.
+"""
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    wpa_config = xmlrpc_security_types.WPAConfig(
+            psk='chromeos',
+            wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA2,
+            wpa2_ciphers=[xmlrpc_security_types.WPAConfig.CIPHER_CCMP])
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(
+                         frequency=2412,
+                         mode=hostap_config.HostapConfig.MODE_11G,
+                         security_config=wpa_config))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_CCMP b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_CCMP
new file mode 100644
index 0000000..255effb
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_CCMP
@@ -0,0 +1,37 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_checkWPA_CCMP'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This tests verifies that we can reconnect to an AP broadcasting a WPA network
+using AES based CCMP after deauthentication while the DUT is suspended.
+"""
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    wpa_config = xmlrpc_security_types.WPAConfig(
+            psk='chromeos',
+            wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA,
+            wpa_ciphers=[xmlrpc_security_types.WPAConfig.CIPHER_CCMP])
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(
+                         frequency=2412,
+                         mode=hostap_config.HostapConfig.MODE_11G,
+                         security_config=wpa_config))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_TKIP b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_TKIP
new file mode 100644
index 0000000..0fee5e1
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_TKIP
@@ -0,0 +1,39 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_checkWPA_TKIP'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This tests verifies that we can reconnect to an AP broadcasting a WPA network
+using TKIP after deauthentication while the DUT is suspended.  TKIP is
+deprecated for having some security holes, and WPA is deprecated in favor of
+WPA2, but routers of a certain age only support this mode.
+"""
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    wpa_config = xmlrpc_security_types.WPAConfig(
+            psk='chromeos',
+            wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA,
+            wpa_ciphers=[xmlrpc_security_types.WPAConfig.CIPHER_TKIP])
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(
+                         frequency=2412,
+                         mode=hostap_config.HostapConfig.MODE_11G,
+                         security_config=wpa_config))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_multi b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_multi
new file mode 100644
index 0000000..c3e8df9
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/control.RSTwifi_checkWPA_multi
@@ -0,0 +1,39 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'wdg@chromium.com'
+NAME = 'network_WiFi_RoamSuspendTimeout.RSTwifi_checkWPA_multi'
+TIME = 'SHORT'
+TEST_TYPE = 'Server'
+SUITE = 'wifi_matfunc'
+DEPENDENCIES = 'wificell'
+
+DOC = """
+This tests verifies that we can reconnect to an AP broadcasting a WPA network
+supporting both AES based CCMP and TKIP after deauthentication while the DUT
+is suspended.
+"""
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
+from autotest_lib.server.cros.network import hostap_config
+
+
+def run(machine):
+    wpa_config = xmlrpc_security_types.WPAConfig(
+            psk='chromeos',
+            wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA,
+            wpa_ciphers=[xmlrpc_security_types.WPAConfig.CIPHER_CCMP,
+                         xmlrpc_security_types.WPAConfig.CIPHER_TKIP])
+    job.run_test('network_WiFi_RoamSuspendTimeout',
+                 tag=NAME.split('.')[1],
+                 host=hosts.create_host(machine),
+                 raw_cmdline_args=args,
+                 additional_params=hostap_config.HostapConfig(
+                         frequency=2412,
+                         mode=hostap_config.HostapConfig.MODE_11G,
+                         security_config=wpa_config))
+
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/network_WiFi_RoamSuspendTimeout/network_WiFi_RoamSuspendTimeout.py b/server/site_tests/network_WiFi_RoamSuspendTimeout/network_WiFi_RoamSuspendTimeout.py
new file mode 100644
index 0000000..0e17a4a
--- /dev/null
+++ b/server/site_tests/network_WiFi_RoamSuspendTimeout/network_WiFi_RoamSuspendTimeout.py
@@ -0,0 +1,60 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import logging
+import time
+
+from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
+from autotest_lib.server.cros.network import wifi_cell_test_base
+
+class network_WiFi_RoamSuspendTimeout(wifi_cell_test_base.WiFiCellTestBase):
+    """Tests roaming to an AP that changes while we're suspended.
+
+    This test run seeks to place the DUT in suspend-to-RAM, rearrange the
+    environment behind the DUT's back and watch what happens when the
+    DUT wakes up.
+
+    """
+    version = 1
+
+
+    def parse_additional_arguments(self, commandline_args, additional_params):
+        """Hook into super class to take control files parameters.
+
+        @param commandline_args dict of parsed parameters from the autotest.
+        @param additional_params HostapConfig
+
+        """
+        self._router_conf = additional_params
+
+
+    def run_once(self):
+        """Test body."""
+        logging.info("- Set up AP, connect.")
+        self.context.configure(self._router_conf)
+
+        client_conf = xmlrpc_datatypes.AssociationParameters()
+        try:
+            client_conf.security_config = self._router_conf.security_config
+        except AttributeError:
+            pass  # OK if self._router_conf has no security_config.
+        client_conf.ssid = self.context.router.get_ssid()
+
+        self.context.assert_connect_wifi(client_conf)
+        self.context.assert_ping_from_dut()
+
+        # Suspend the DUT then, locally, wait 15 seconds to make sure the
+        # DUT is really asleep before we proceed.  Then, deauth the DUT
+        # while it sleeps.
+        logging.info("- Suspend & deauthenticate during suspend.")
+        self.context.client.do_suspend_bg(20)
+        time.sleep(15)
+        self.context.router.deauth_client(self.context.client.wifi_mac)
+
+        # If the DUT realizes that it has been deauthed, then it should
+        # reassociate quickly and the ping below should succeed.
+        logging.info("- Verify that we roam back to same network.")
+        self.context.wait_for_connection(client_conf.ssid)
+
+        self.context.router.deconfig()