Merge "Rollback the presetting change seems causing MH detect device failure"
diff --git a/acts/framework/acts/controllers/fuchsia_device.py b/acts/framework/acts/controllers/fuchsia_device.py
index 34586bb..105bcfd 100644
--- a/acts/framework/acts/controllers/fuchsia_device.py
+++ b/acts/framework/acts/controllers/fuchsia_device.py
@@ -922,8 +922,8 @@
                 ) or network["status"].upper() != status.upper():
                     self.log.info(
                         "Connection failed: a network failure occurred that is unrelated"
-                        "to remove network or incorrect status update. \nExpected state: " (
-                            state, status, network))
+                        "to remove network or incorrect status update. \nExpected state: "
+                        % (state, status, network))
                     return False
                 else:
                     return True
diff --git a/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_policy_utils.py b/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_policy_utils.py
index 82c296d..4a59de7 100644
--- a/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_policy_utils.py
+++ b/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_policy_utils.py
@@ -1,31 +1,88 @@
+#!/usr/bin/env python3
+#
+#   Copyright 2020 - The Android Open Source Project
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+SAVED_NETWORKS = "saved_networks"
+CLIENT_STATE = "client_connections_state"
+CONNECTIONS_ENABLED = "ConnectionsEnabled"
+CONNECTIONS_DISABLED = "ConnectionsDisabled"
+
+
 def setup_policy_tests(fuchsia_devices):
-    """ Preserve networks already saved on devices before removing them to
-        setup up for a clean test environment. Initialize the client controller
-        and enable connections.
+    """ Preserves networks already saved on devices before removing them to
+        setup up for a clean test environment. Records the state of client
+        connections before tests. Initializes the client controller
+        and enables connections.
     Args:
-        fuchsia_device: the devices under test
+        fuchsia_devices: the devices under test
     Returns:
-        A dict of the networks that were saved on the device, indexed by the device
+        A dict of the data to restore after tests indexed by device. The data
+        for each device is a dict of the saved data, ie saved networks and
+        state of client connections.
     """
-    preserved_saved_networks = {}
+    preserved_data_by_device = {}
     for fd in fuchsia_devices:
+        data = {}
+        # Collect and delete networks saved on the device.
         fd.wlan_policy_lib.wlanCreateClientController()
         result_get = fd.wlan_policy_lib.wlanGetSavedNetworks()
-        preserved_saved_networks[fd] = result_get['result']
+        if result_get.get("result") != None:
+            data[SAVED_NETWORKS] = result_get['result']
         fd.wlan_policy_lib.wlanRemoveAllNetworks()
-    return preserved_saved_networks
+
+        # Get the currect client connection state (connections enabled or disabled)
+        # and enable connections by default.
+        fd.wlan_policy_lib.wlanSetNewListener()
+        result_update = fd.wlan_policy_lib.wlanGetUpdate()
+        if result_update.get("result") != None and result_update.get(
+                "result").get("state") != None:
+            data[CLIENT_STATE] = result_update.get("result").get("state")
+        else:
+            fd.log.warn("Failed to get update; test will not start or "
+                        "stop client connections at the end of the test.")
+        fd.wlan_policy_lib.wlanStartClientConnections()
+
+        preserved_data_by_device[fd] = data
+    return preserved_data_by_device
 
 
-def restore_saved_networks(fuchsia_devices, preserved_networks):
+def restore_state(fuchsia_devices, preserved_data):
+    """ Restore the state of the test device to what it was before tests began.
+        Remove any remaining saved networks, and restore the saved networks and
+        client connections state recorded by setup_policy_tests
+    Args:
+        fuchsia_devices: The fuchsia devices under test
+        preserved data: Dict of data indexed by fuchsia device, as returned
+                        by setup_policy_tests
+    """
     for fd in fuchsia_devices:
-        for network in preserved_networks[fd]:
+        data = preserved_data[fd]
+        fd.wlan_policy_lib.wlanRemoveAllNetworks()
+        for network in data[SAVED_NETWORKS]:
             save_network(fd, network["ssid"], network["security_type"],
                          network["credential_value"])
+        for starting_state in data[CLIENT_STATE]:
+            if starting_state == CONNECTIONS_ENABLED:
+                fd.wlan_policy_lib.wlanStartClientConnections()
+            elif starting_state == CONNECTIONS_DISABLED:
+                fd.wlan_policy_lib.wlanStopClientConnections()
 
 
 def save_network(fd, ssid, security_type, password=""):
     """ Saves a network as specified on the given device and verify that the operation succeeded.
-        Returns true if there was an error, false otherwise
+        Returns true if there was no error, and false otherwise
     Args:
         fd: The Fuchsia device to save the network on
         ssid: The SSID or name of the network to save.
@@ -36,9 +93,9 @@
     """
     result_save = fd.wlan_policy_lib.wlanSaveNetwork(ssid, security_type,
                                                      password)
-    if result_save["error"] != None:
-        self.log.info("Failed to save network %s with error: %s" % ssid,
-                      result_save["error"])
+    if result_save.get("error") != None:
+        fd.log.info("Failed to save network %s with error: %s" %
+                    (ssid, result_save["error"]))
         return False
     else:
         return True
@@ -52,3 +109,4 @@
     fd.reboot()
     fd.wlan_policy_lib.wlanCreateClientController()
     fd.wlan_policy_lib.wlanStartClientConnections()
+    fd.wlan_policy_lib.wlanSetNewListener()
diff --git a/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_utils.py b/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_utils.py
index c935368..bebcb1e 100644
--- a/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_utils.py
+++ b/acts/framework/acts/test_utils/abstract_devices/utils_lib/wlan_utils.py
@@ -82,6 +82,9 @@
              check_connectivity, n_capabilities, ac_capabilities,
              vht_bandwidth, setup_bridge)
 
+    if not security:
+        target_security = "none"
+
     if security and security.wpa3:
         return associate(client,
                          ssid,
@@ -189,6 +192,7 @@
                             association_mechanism=association_mechanism,
                             target_security=target_security)
 
+
 def status(client):
     """Requests the state of WLAN network.
 
diff --git a/acts_tests/tests/google/fuchsia/wlan/WlanPhyComplianceABGTest.py b/acts_tests/tests/google/fuchsia/wlan/WlanPhyComplianceABGTest.py
index 606bfb9..8ef8591 100644
--- a/acts_tests/tests/google/fuchsia/wlan/WlanPhyComplianceABGTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/WlanPhyComplianceABGTest.py
@@ -21,6 +21,7 @@
 from acts.test_utils.abstract_devices.wlan_device import create_wlan_device
 from acts.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
 from acts.test_utils.abstract_devices.utils_lib.wlan_utils import validate_setup_ap_and_associate
+from acts.test_utils.abstract_devices.utils_lib.wlan_policy_utils import setup_policy_tests, restore_state
 from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
 
 
@@ -104,6 +105,16 @@
         self.utf8_ssid_2g_korean = 'ㅘㅙㅚㅛㅜㅝㅞㅟㅠ'
         self.utf8_password_2g_korean = 'ㅜㅝㅞㅟㅠㅘㅙㅚㅛ'
 
+        # These tests will either be performed by connecting through the policy
+        # layer or directly below at a core/driver layer.
+        self.association_mechanism = 'drivers'
+        if 'association_mechanism' in self.user_params:
+            if self.user_params['association_mechanism'] == 'policy':
+                self.association_mechanism = 'policy'
+                # Preserve networks already saved on device before removing
+                self.preexisting_state = setup_policy_tests(
+                    self.fuchsia_devices)
+
         self.access_point.stop_all_aps()
 
     def setup_test(self):
@@ -123,12 +134,17 @@
         self.dut.reset_wifi()
         self.access_point.stop_all_aps()
 
+    def teardown_class(self):
+        if self.association_mechanism == 'policy':
+            restore_state(self.fuchsia_devices, self.preexisting_state)
+
     def on_fail(self, test_name, begin_time):
         super().on_fail(test_name, begin_time)
         self.access_point.stop_all_aps()
 
     def test_associate_11b_only_long_preamble(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -138,6 +154,7 @@
 
     def test_associate_11b_only_short_preamble(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -147,6 +164,7 @@
 
     def test_associate_11b_only_minimal_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -156,6 +174,7 @@
 
     def test_associate_11b_only_maximum_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -165,6 +184,7 @@
 
     def test_associate_11b_only_frag_threshold_430(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -174,6 +194,7 @@
 
     def test_associate_11b_only_rts_threshold_256(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -183,6 +204,7 @@
 
     def test_associate_11b_only_rts_256_frag_430(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -193,6 +215,7 @@
 
     def test_associate_11b_only_high_dtim_low_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -203,6 +226,7 @@
 
     def test_associate_11b_only_low_dtim_high_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -213,6 +237,7 @@
 
     def test_associate_11b_only_with_WMM_with_default_values(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -223,6 +248,7 @@
 
     def test_associate_11b_only_with_WMM_with_non_default_values(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -236,6 +262,7 @@
             hostapd_constants.WMM_11B_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BK)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -249,6 +276,7 @@
             hostapd_constants.WMM_11B_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BE)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -262,6 +290,7 @@
             hostapd_constants.WMM_11B_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VI)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -275,6 +304,7 @@
             hostapd_constants.WMM_11B_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -289,6 +319,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VI)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -303,6 +334,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -317,6 +349,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -331,6 +364,7 @@
             hostapd_constants.WMM_ACM_BE, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -345,6 +379,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['UNITED_STATES'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -358,6 +393,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['NON_COUNTRY'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -367,6 +403,7 @@
 
     def test_associate_11b_only_with_hidden_ssid(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -376,6 +413,7 @@
 
     def test_associate_11b_only_with_vendor_ie_in_beacon_correct_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -386,6 +424,7 @@
 
     def test_associate_11b_only_with_vendor_ie_in_beacon_zero_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -396,6 +435,7 @@
 
     def test_associate_11b_only_with_vendor_ie_in_assoc_correct_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -406,6 +446,7 @@
 
     def test_associate_11b_only_with_vendor_ie_in_assoc_zero_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -417,6 +458,7 @@
 
     def test_associate_11a_only_long_preamble(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -426,6 +468,7 @@
 
     def test_associate_11a_only_short_preamble(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -435,6 +478,7 @@
 
     def test_associate_11a_only_minimal_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -444,6 +488,7 @@
 
     def test_associate_11a_only_maximum_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -453,6 +498,7 @@
 
     def test_associate_11a_only_frag_threshold_430(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -462,6 +508,7 @@
 
     def test_associate_11a_only_rts_threshold_256(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -471,6 +518,7 @@
 
     def test_associate_11a_only_rts_256_frag_430(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -481,6 +529,7 @@
 
     def test_associate_11a_only_high_dtim_low_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -491,6 +540,7 @@
 
     def test_associate_11a_only_low_dtim_high_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -501,6 +551,7 @@
 
     def test_associate_11a_only_with_WMM_with_default_values(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -512,6 +563,7 @@
 
     def test_associate_11a_only_with_WMM_with_non_default_values(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -525,6 +577,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BK)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -538,6 +591,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BE)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -551,6 +605,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VI)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -564,6 +619,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -578,6 +634,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VI)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -592,6 +649,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -606,6 +664,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -620,6 +679,7 @@
             hostapd_constants.WMM_ACM_BE, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -634,6 +694,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['UNITED_STATES'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -647,6 +708,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['NON_COUNTRY'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -656,6 +718,7 @@
 
     def test_associate_11a_only_with_hidden_ssid(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -665,6 +728,7 @@
 
     def test_associate_11a_only_with_vendor_ie_in_beacon_correct_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -675,6 +739,7 @@
 
     def test_associate_11a_only_with_vendor_ie_in_beacon_zero_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -685,6 +750,7 @@
 
     def test_associate_11a_only_with_vendor_ie_in_assoc_correct_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -695,6 +761,7 @@
 
     def test_associate_11a_only_with_vendor_ie_in_assoc_zero_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -708,6 +775,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -720,6 +788,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -732,6 +801,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -744,6 +814,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -756,6 +827,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -768,6 +840,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -780,6 +853,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -793,6 +867,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -806,6 +881,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -821,6 +897,7 @@
             hostapd_constants.OFDM_ONLY_BASIC_RATES,
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -835,6 +912,7 @@
             hostapd_constants.OFDM_ONLY_BASIC_RATES,
             hostapd_constants.WMM_NON_DEFAULT_PARAMS)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -850,6 +928,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BK, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -865,6 +944,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BE, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -880,6 +960,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VI, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -895,6 +976,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VO, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -911,6 +993,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VI, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -927,6 +1010,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VO, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -943,6 +1027,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -959,6 +1044,7 @@
             hostapd_constants.WMM_ACM_BE, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO, data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -975,6 +1061,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['UNITED_STATES'], data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -990,6 +1077,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['NON_COUNTRY'], data_rates)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1001,6 +1089,7 @@
         data_rates = utils.merge_dicts(hostapd_constants.OFDM_DATA_RATES,
                                        hostapd_constants.OFDM_ONLY_BASIC_RATES)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1015,6 +1104,7 @@
             hostapd_constants.OFDM_ONLY_BASIC_RATES,
             hostapd_constants.VENDOR_IE['correct_length_beacon'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1028,6 +1118,7 @@
             hostapd_constants.OFDM_ONLY_BASIC_RATES,
             hostapd_constants.VENDOR_IE['zero_length_beacon_without_data'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1041,6 +1132,7 @@
             hostapd_constants.OFDM_ONLY_BASIC_RATES,
             hostapd_constants.VENDOR_IE['correct_length_association_response'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1056,6 +1148,7 @@
             hostapd_constants.VENDOR_IE['zero_length_association_'
                                         'response_without_data'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1065,6 +1158,7 @@
 
     def test_associate_11bg_only_long_preamble(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1074,6 +1168,7 @@
 
     def test_associate_11bg_short_preamble(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1083,6 +1178,7 @@
 
     def test_associate_11bg_minimal_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1092,6 +1188,7 @@
 
     def test_associate_11bg_maximum_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1101,6 +1198,7 @@
 
     def test_associate_11bg_frag_threshold_430(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1110,6 +1208,7 @@
 
     def test_associate_11bg_rts_threshold_256(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1119,6 +1218,7 @@
 
     def test_associate_11bg_rts_256_frag_430(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1129,6 +1229,7 @@
 
     def test_associate_11bg_high_dtim_low_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1139,6 +1240,7 @@
 
     def test_associate_11bg_low_dtim_high_beacon_interval(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1149,6 +1251,7 @@
 
     def test_associate_11bg_with_WMM_with_default_values(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1160,6 +1263,7 @@
 
     def test_associate_11bg_with_WMM_with_non_default_values(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1173,6 +1277,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BK)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1186,6 +1291,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_BE)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1199,6 +1305,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VI)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1212,6 +1319,7 @@
             hostapd_constants.WMM_PHYS_11A_11G_11N_11AC_DEFAULT_PARAMS,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1226,6 +1334,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VI)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1240,6 +1349,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_BE,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1254,6 +1364,7 @@
             hostapd_constants.WMM_ACM_BK, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1268,6 +1379,7 @@
             hostapd_constants.WMM_ACM_BE, hostapd_constants.WMM_ACM_VI,
             hostapd_constants.WMM_ACM_VO)
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1282,6 +1394,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['UNITED_STATES'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1295,6 +1408,7 @@
             hostapd_constants.COUNTRY_STRING['ALL'],
             hostapd_constants.COUNTRY_CODE['NON_COUNTRY'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1304,6 +1418,7 @@
 
     def test_associate_11bg_only_with_hidden_ssid(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1313,6 +1428,7 @@
 
     def test_associate_11bg_with_vendor_ie_in_beacon_correct_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1323,6 +1439,7 @@
 
     def test_associate_11bg_with_vendor_ie_in_beacon_zero_length(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1337,6 +1454,7 @@
             hostapd_constants.OFDM_ONLY_BASIC_RATES,
             hostapd_constants.VENDOR_IE['correct_length_association_response'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1352,6 +1470,7 @@
             hostapd_constants.VENDOR_IE['zero_length_association_'
                                         'response_without_data'])
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ag_legacy',
@@ -1361,6 +1480,7 @@
 
     def test_minimum_ssid_length_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1369,6 +1489,7 @@
 
     def test_minimum_ssid_length_5g_11ac_80mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1377,6 +1498,7 @@
 
     def test_maximum_ssid_length_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1385,6 +1507,7 @@
 
     def test_maximum_ssid_length_5g_11ac_80mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1393,6 +1516,7 @@
 
     def test_ssid_with_UTF8_characters_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1401,6 +1525,7 @@
 
     def test_ssid_with_UTF8_characters_5g_11ac_80mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1409,6 +1534,7 @@
 
     def test_ssid_with_UTF8_characters_french_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1417,6 +1543,7 @@
 
     def test_ssid_with_UTF8_characters_german_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1425,6 +1552,7 @@
 
     def test_ssid_with_UTF8_characters_dutch_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1433,6 +1561,7 @@
 
     def test_ssid_with_UTF8_characters_swedish_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1441,6 +1570,7 @@
 
     def test_ssid_with_UTF8_characters_norwegian_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1449,6 +1579,7 @@
 
     def test_ssid_with_UTF8_characters_danish_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1457,6 +1588,7 @@
 
     def test_ssid_with_UTF8_characters_japanese_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1465,6 +1597,7 @@
 
     def test_ssid_with_UTF8_characters_spanish_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1473,6 +1606,7 @@
 
     def test_ssid_with_UTF8_characters_italian_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
@@ -1481,6 +1615,7 @@
 
     def test_ssid_with_UTF8_characters_korean_2g_11n_20mhz(self):
         validate_setup_ap_and_associate(
+            association_mechanism=self.association_mechanism,
             access_point=self.access_point,
             client=self.dut,
             profile_name='whirlwind_11ab_legacy',
diff --git a/acts_tests/tests/google/fuchsia/wlan/WlanSecurityComplianceABGTest.py b/acts_tests/tests/google/fuchsia/wlan/WlanSecurityComplianceABGTest.py
index b04b837..2f43085 100644
--- a/acts_tests/tests/google/fuchsia/wlan/WlanSecurityComplianceABGTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/WlanSecurityComplianceABGTest.py
@@ -22,7 +22,7 @@
 from acts.test_utils.abstract_devices.wlan_device import create_wlan_device
 from acts.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
 from acts.test_utils.abstract_devices.utils_lib.wlan_utils import validate_setup_ap_and_associate
-from acts.test_utils.abstract_devices.utils_lib.wlan_policy_utils import setup_policy_tests, restore_saved_networks
+from acts.test_utils.abstract_devices.utils_lib.wlan_policy_utils import setup_policy_tests, restore_state
 from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
 from acts.utils import rand_ascii_str
 from acts.utils import rand_hex_str
@@ -184,8 +184,8 @@
         if 'association_mechanism' in self.user_params:
             if self.user_params['association_mechanism'] == 'policy':
                 self.association_mechanism = 'policy'
-                # Preserve networks already saved on device before removing
-                self.preserved_saved_networks = setup_policy_tests(
+                # Preserve state of device before tests and set up device.
+                self.preexisting_state = setup_policy_tests(
                     self.fuchsia_devices)
         self.access_point.stop_all_aps()
 
@@ -208,8 +208,7 @@
 
     def teardown_class(self):
         if self.association_mechanism == 'policy':
-            restore_saved_networks(self.fuchsia_devices,
-                                   self.preserved_saved_networks)
+            restore_state(self.fuchsia_devices, self.preexisting_state)
 
     def on_fail(self, test_name, begin_time):
         super().on_fail(test_name, begin_time)
diff --git a/acts_tests/tests/google/fuchsia/wlan_policy/HiddenNetworksTest.py b/acts_tests/tests/google/fuchsia/wlan_policy/HiddenNetworksTest.py
new file mode 100644
index 0000000..40c03b2
--- /dev/null
+++ b/acts_tests/tests/google/fuchsia/wlan_policy/HiddenNetworksTest.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python3
+#
+#   Copyright 2020 - The Android Open Source Project
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+from acts import signals
+from acts.controllers.ap_lib import hostapd_constants
+from acts.controllers.ap_lib import hostapd_security
+from acts.test_utils.abstract_devices.utils_lib.wlan_utils import setup_ap
+from acts.test_utils.abstract_devices.utils_lib.wlan_policy_utils import reboot_device, restore_state, save_network, setup_policy_tests
+from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
+from acts.utils import rand_ascii_str
+import time
+
+# These tests should have a longer timeout for connecting than normal connect
+# tests because the device should probabilistically perform active scans for
+# hidden networks. Multiple scans are necessary to verify a very low chance of
+# random failure.
+TIME_WAIT_FOR_CONNECT = 45
+TIME_ATTEMPT_SCANS = 45
+
+CONNECTIONS_ENABLED = "ConnectionsEnabled"
+CONNECTIONS_DISABLED = "ConnectionsDisabled"
+SECURITY_NONE = "none"
+WPA2 = "wpa2"
+
+
+class HiddenNetworksTest(WifiBaseTest):
+    """ Tests that WLAN Policy will detect hidden networks
+
+    Test Bed Requirement:
+    * One or more Fuchsia devices
+    * One Access Point
+    """
+    def setup_class(self):
+        super().setup_class()
+        # Start an AP with a hidden network
+        self.hidden_ssid = rand_ascii_str(hostapd_constants.AP_SSID_LENGTH_2G)
+        self.access_point = self.access_points[0]
+        self.hidden_password = rand_ascii_str(
+            hostapd_constants.AP_PASSPHRASE_LENGTH_2G)
+        self.hidden_security = WPA2
+        security = hostapd_security.Security(
+            security_mode=self.hidden_security, password=self.hidden_password)
+
+        self.access_point.stop_all_aps()
+        setup_ap(self.access_point,
+                 'whirlwind',
+                 hostapd_constants.AP_DEFAULT_CHANNEL_5G,
+                 self.hidden_ssid,
+                 hidden=True,
+                 security=security)
+
+        if len(self.fuchsia_devices) < 1:
+            raise EnvironmentError("No Fuchsia devices found.")
+        # Save the existing saved networks before we remove them for tests
+        # And remember whether client connections have started
+        self.preexisting_state = setup_policy_tests(self.fuchsia_devices)
+
+    def setup_test(self):
+        for fd in self.fuchsia_devices:
+            # Set new update listener so that the next test can always get the
+            # most recent udpdate immediately.
+            new_listener_result = fd.wlan_policy_lib.wlanSetNewListener()
+            if new_listener_result["error"] != None:
+                self.log.warn(
+                    "Error occurred initializing a new update listener for the facade, may"
+                    "cause errors in updates for tests: %s" %
+                    new_listener_result["error"])
+
+            resultRemove = fd.wlan_policy_lib.wlanRemoveAllNetworks()
+            if resultRemove["error"] != None:
+                self.log.error(
+                    "Error occurred when deleting all saved networks in test setup: %s"
+                    % resultRemove["error"])
+                raise EnvironmentError(
+                    "Failed to remove all networks in setup")
+
+            resultStart = fd.wlan_policy_lib.wlanStartClientConnections()
+            if resultStart["error"] != None:
+                self.log.error(
+                    "Error occurred when starting client connections in test setup: %s"
+                    % resultStart["error"])
+                raise EnvironmentError(
+                    "Failed to start client connections in setup")
+
+    def teardown_class(self):
+        self.access_point.stop_all_aps()
+        for fd in self.fuchsia_devices:
+            # Put back the networks that were saved before tests began.
+            restore_state(self.fuchsia_devices, self.preexisting_state)
+
+    def test_scan_hidden_networks(self):
+        # Scan a few times and check that we see the hidden networks in the
+        # results at least once. Even if hidden networks are scanned
+        # probabilistically, we should see it after a few tries.
+        for fd in self.fuchsia_devices:
+            start_time = time.time()
+            num_performed_scans = 0
+            while time.time() < start_time + TIME_ATTEMPT_SCANS:
+                num_performed_scans = num_performed_scans + 1
+                scan_result = fd.wlan_policy_lib.wlanScanForNetworks()
+                if scan_result["error"] != None:
+                    self.log.error(
+                        "Failed to scan for networks with error %s" %
+                        scan_result["error"])
+                    raise EnvironmentError("Failed to scan")
+                else:
+                    scans = scan_result["result"]
+                if self.hidden_ssid in scans:
+                    self.log.info(
+                        "SSID of hidden network seen after %d scans" %
+                        num_performed_scans)
+                    return
+
+            self.log.error("Failed to see SSID after %d scans" %
+                           num_performed_scans)
+            raise signals.TestFailure("Failed to see hidden network in scans")
+
+    def test_auto_connect_hidden_on_startup(self):
+        """ Test that if we are not connected to anything but have a hidden
+            network saved, we will eventually actively scan for it and connect."""
+        # Start up AP with an open network with a random SSID
+
+        for fd in self.fuchsia_devices:
+            # Test that we will auto connect without anything being triggered by
+            # saving a new network.
+            fd.wlan_policy_lib.wlanStopClientConnections()
+
+            # Save the network.
+            if not save_network(fd, self.hidden_ssid, self.hidden_security,
+                                self.hidden_password):
+                raise EnvironmentError("Failed to save network")
+
+            # Reboot the device and check that it auto connects.
+            reboot_device(fd)
+            if not fd.wait_for_connect(self.hidden_ssid,
+                                       self.hidden_security,
+                                       timeout=TIME_WAIT_FOR_CONNECT):
+                raise signals.TestFailure("Failed to connect to network")
+
+    def test_auto_connect_hidden_on_save(self):
+        """ Test that if we save a hidden network and are not connected to
+            anything, the device will connect to the hidden network that was
+            just saved. """
+        for fd in self.fuchsia_devices:
+            if not fd.wait_for_no_connections():
+                self.log.info(
+                    "Failed to get into a disconnected state to start the test"
+                )
+                raise EnvironmentError("Failed to disconnect all")
+
+            # Save the network and make sure that we see the device auto connect to it.
+            if not save_network(fd, self.hidden_ssid, self.hidden_security,
+                                self.hidden_password):
+                raise EnvironmentError("Failed to save network")
+
+            if not fd.wait_for_connect(self.hidden_ssid,
+                                       self.hidden_security,
+                                       timeout=TIME_WAIT_FOR_CONNECT):
+                raise signals.TestFailure("Failed to connect to network")
diff --git a/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py b/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py
index 536f5e1..e16c4f6 100644
--- a/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py
@@ -24,7 +24,7 @@
 from acts.controllers.ap_lib import hostapd_security
 from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
 from acts.test_utils.abstract_devices.utils_lib.wlan_utils import setup_ap
-from acts.test_utils.abstract_devices.utils_lib.wlan_policy_utils import reboot_device, restore_saved_networks, save_network, setup_policy_tests
+from acts.test_utils.abstract_devices.utils_lib.wlan_policy_utils import reboot_device, restore_state, save_network, setup_policy_tests
 from acts.utils import rand_ascii_str, rand_hex_str, timeout
 import requests
 import time
@@ -63,8 +63,7 @@
             raise EnvironmentError("No Fuchsia devices found.")
         # Save the existing saved networks before we remove them for tests
         # And remember whether client connections have started
-        self.preexisting_saved_networks = setup_policy_tests(
-            self.fuchsia_devices)
+        self.preserved_state = setup_policy_tests(self.fuchsia_devices)
         self.preexisting_client_connections_state = {}
         for fd in self.fuchsia_devices:
             fd.wlan_policy_lib.wlanSetNewListener()
@@ -115,8 +114,7 @@
             # Remove any networks remaining from tests
             fd.wlan_policy_lib.wlanRemoveAllNetworks()
         # Put back the networks that were saved before tests began.
-        restore_saved_networks(self.fuchsia_devices,
-                               self.preexisting_saved_networks)
+        restore_state(self.fuchsia_devices, self.preserved_state)
         self.access_points[0].stop_all_aps()
 
     def get_saved_networks(self, fd):
@@ -258,7 +256,7 @@
                                          self.credentialType(password),
                                          password)
 
-    def start_ap(self, ssid, security_type, password=None):
+    def start_ap(self, ssid, security_type, password=None, hidden=False):
         """ Starts an access point.
         Args:
             ssid: the SSID of the network to broadcast