Snap for 4778776 from b1297ff102e35190c71a0bcca3de96cf4759cae0 to pi-release

Change-Id: Ib0435288a3f2b6114f2b9b15686a5d361b176105
diff --git a/acts/framework/acts/test_utils/wifi/wifi_retail_ap.py b/acts/framework/acts/test_utils/wifi/wifi_retail_ap.py
index 40155dc..6e1ca7b 100644
--- a/acts/framework/acts/test_utils/wifi/wifi_retail_ap.py
+++ b/acts/framework/acts/test_utils/wifi/wifi_retail_ap.py
@@ -33,6 +33,7 @@
     SUPPORTED_APS = {
         ("Netgear", "R7000"): "NetgearR7000AP",
         ("Netgear", "R7500"): "NetgearR7500AP",
+        ("Netgear", "R7800"): "NetgearR7800AP",
         ("Netgear", "R8000"): "NetgearR8000AP"
     }
     objs = []
@@ -51,7 +52,7 @@
 
 
 def visit_config_page(browser, url, page_load_timeout, num_tries):
-    """ Method to visit Netgear AP webpages
+    """ Method to visit Netgear AP webpages.
 
     This function visits a web page and checks the the resulting URL matches
     the intended URL, i.e. no redirects have happened
@@ -66,13 +67,10 @@
         try:
             browser.visit(url)
         except:
-            raise TimeoutError(
-                "Page load timout. Could be due to connectivity or alerts.")
+            browser.visit("https://www.google.com/")
         if browser.url.split("/")[-1] == url.split("/")[-1]:
             break
         if idx == num_tries - 1:
-            print(browser.url)
-            print(url)
             raise RuntimeError("URL was unreachable.")
 
 
@@ -95,6 +93,23 @@
         """
         raise NotImplementedError
 
+    def validate_ap_settings(self):
+        """ Function to validate ap settings.
+
+        This function compares the actual ap settings read from the web GUI
+        with the assumed settings saved in the AP object. When called after AP
+        configuration, this method helps ensure that our configuration was
+        successful.
+
+        Raises:
+            ValueError: If read AP settings do not match stored settings.
+        """
+        assumed_ap_settings = self.ap_settings.copy()
+        actual_ap_settings = self.read_ap_settings()
+        if assumed_ap_settings != actual_ap_settings:
+            raise ValueError(
+                "Discrepancy in AP settings. Potential configuration error.")
+
     def configure_ap(self):
         """ Function that configures ap based on values of ap_settings.
 
@@ -104,7 +119,7 @@
         raise NotImplementedError
 
     def set_radio_on_off(self, network, status):
-        """ Function that turns the radio on or off
+        """ Function that turns the radio on or off.
 
         Args:
             network: string containing network identifier (2G, 5G_1, 5G_2)
@@ -114,7 +129,7 @@
         self.update_ap_settings(setting_to_update)
 
     def set_ssid(self, network, ssid):
-        """ Function that sets network SSID
+        """ Function that sets network SSID.
 
         Args:
             network: string containing network identifier (2G, 5G_1, 5G_2)
@@ -124,7 +139,7 @@
         self.update_ap_settings(setting_to_update)
 
     def set_channel(self, network, channel):
-        """ Function that sets network channel
+        """ Function that sets network channel.
 
         Args:
             network: string containing network identifier (2G, 5G_1, 5G_2)
@@ -134,7 +149,7 @@
         self.update_ap_settings(setting_to_update)
 
     def set_bandwidth(self, network, bandwidth):
-        """ Function that sets network bandwidth/mode
+        """ Function that sets network bandwidth/mode.
 
         Args:
             network: string containing network identifier (2G, 5G_1, 5G_2)
@@ -144,7 +159,7 @@
         self.update_ap_settings(setting_to_update)
 
     def set_power(self, network, power):
-        """ Function that sets network transmit power
+        """ Function that sets network transmit power.
 
         Args:
             network: string containing network identifier (2G, 5G_1, 5G_2)
@@ -154,7 +169,7 @@
         self.update_ap_settings(setting_to_update)
 
     def set_security(self, network, security_type, *password):
-        """ Function that sets network security setting and password (optional)
+        """ Function that sets network security setting and password.
 
         Args:
             network: string containing network identifier (2G, 5G_1, 5G_2)
@@ -224,8 +239,7 @@
 
 
 class NetgearR7000AP(WifiRetailAP):
-    """ Class that implements Netgear R7500 AP.
-    """
+    """ Class that implements Netgear R7500 AP."""
 
     def __init__(self, ap_settings):
         self.ap_settings = ap_settings.copy()
@@ -245,8 +259,8 @@
         self.CHROME_OPTIONS.add_argument("--allow-running-insecure-content")
         self.CHROME_OPTIONS.add_argument("--ignore-certificate-errors")
         self.CHROME_CAPABILITIES = DesiredCapabilities.CHROME.copy()
-        self.CHROME_CAPABILITIES['acceptSslCerts'] = True
-        self.CHROME_CAPABILITIES['acceptInsecureCerts'] = True
+        self.CHROME_CAPABILITIES["acceptSslCerts"] = True
+        self.CHROME_CAPABILITIES["acceptInsecureCerts"] = True
         if self.ap_settings["headless_browser"]:
             self.CHROME_OPTIONS.add_argument("--headless")
             self.CHROME_OPTIONS.add_argument("--disable-gpu")
@@ -299,6 +313,24 @@
             ("2G", "password"): "passphrase",
             ("5G_1", "password"): "passphrase_an"
         }
+        self.BW_MODE_VALUES = {
+            "g and b": "11g",
+            "145Mbps": "VHT20",
+            "300Mbps": "VHT40",
+            "HT80": "VHT80"
+        }
+        self.POWER_MODE_VALUES = {
+            "1": "100%",
+            "2": "75%",
+            "3": "50%",
+            "4": "25%"
+        }
+        self.BW_MODE_TEXT = {
+            "11g": "Up to 54 Mbps",
+            "VHT20": "Up to 289 Mbps",
+            "VHT40": "Up to 600 Mbps",
+            "VHT80": "Up to 1300 Mbps"
+        }
         self.read_ap_settings()
         if ap_settings.items() <= self.ap_settings.items():
             return
@@ -306,16 +338,7 @@
             self.update_ap_settings(ap_settings)
 
     def read_ap_settings(self):
-        """ Function to read ap settings.
-        """
-        BW_MODE_VALUES = {
-            "g and b": "11g",
-            "145Mbps": "VHT20",
-            "300Mbps": "VHT40",
-            "HT80": "VHT80"
-        }
-        POWER_MODE_VALUES = {"1": "100%", "2": "75%", "3": "50%", "4": "25%"}
-
+        """ Function to read ap settings."""
         with splinter.Browser(
                 "chrome",
                 options=self.CHROME_OPTIONS,
@@ -337,12 +360,12 @@
                 else:
                     config_item = browser.find_by_name(value)
                     if "bandwidth" in key:
-                        self.ap_settings["{}_{}".format(
-                            key[1],
-                            key[0])] = BW_MODE_VALUES[config_item.first.value]
-                    elif "power" in key:
                         self.ap_settings["{}_{}".format(key[1], key[
-                            0])] = POWER_MODE_VALUES[config_item.first.value]
+                            0])] = self.BW_MODE_VALUES[config_item.first.value]
+                    elif "power" in key:
+                        self.ap_settings["{}_{}".format(
+                            key[1], key[0])] = self.POWER_MODE_VALUES[
+                                config_item.first.value]
                     elif "region" in key:
                         self.ap_settings["region"] = self.REGION_MAP[
                             config_item.first.value]
@@ -357,29 +380,8 @@
                             key[1], key[0])] = config_item.first.value
         return self.ap_settings.copy()
 
-    def validate_ap_settings(self):
-        """ Function to validate ap settings
-
-        This function compares the actual ap settings read from the web GUI
-        with the assumed settings saved in the AP object. When called after AP
-        configuration, this method helps ensure that our configuration was
-        successful.
-        """
-        assumed_ap_settings = self.ap_settings.copy()
-        actual_ap_settings = self.read_ap_settings()
-        if assumed_ap_settings != actual_ap_settings:
-            raise ValueError(
-                "Discrepancy in AP settings. Potential configuration error.")
-
     def configure_ap(self):
-        """ Function to configure ap wireless settings
-        """
-        BW_MODE_TEXT = {
-            "11g": "Up to 54 Mbps",
-            "VHT20": "Up to 289 Mbps",
-            "VHT40": "Up to 600 Mbps",
-            "VHT80": "Up to 1300 Mbps"
-        }
+        """ Function to configure ap wireless settings."""
         # Turn radios on or off
         self.configure_radio_on_off()
         # Configure radios
@@ -404,7 +406,7 @@
                 elif "bandwidth" in key:
                     config_item = browser.find_by_name(value).first
                     config_item.select_by_text(
-                        BW_MODE_TEXT[self.ap_settings["{}_{}".format(
+                        self.BW_MODE_TEXT[self.ap_settings["{}_{}".format(
                             key[1], key[0])]])
 
             # Update security settings (passwords updated only if applicable)
@@ -455,8 +457,7 @@
             self.validate_ap_settings()
 
     def configure_radio_on_off(self):
-        """ Helper configuration function to turn radios on/off
-        """
+        """ Helper configuration function to turn radios on/off."""
         with splinter.Browser(
                 "chrome",
                 options=self.CHROME_OPTIONS,
@@ -489,29 +490,28 @@
 
 
 class NetgearR7500AP(WifiRetailAP):
-    """ Class that implements Netgear R7000 AP.
-
-    NOTE: Many of the functions here are reused in NetgearR8000AP
-    """
+    """ Class that implements Netgear R7500 AP."""
 
     def __init__(self, ap_settings):
         self.ap_settings = ap_settings.copy()
-        self.CONFIG_PAGE = "http://{}:{}@{}/index.htm".format(
-            self.ap_settings["admin_username"],
-            self.ap_settings["admin_password"], self.ap_settings["ip_address"])
-        self.CONFIG_PAGE_NOLOGIN = "http://{}/index.htm".format(
-            self.ap_settings["ip_address"])
-        self.CONFIG_PAGE_ADVANCED = "http://{}:{}@{}/adv_index.htm".format(
-            self.ap_settings["admin_username"],
-            self.ap_settings["admin_password"], self.ap_settings["ip_address"])
+        self.CONFIG_PAGE = "{}://{}:{}@{}:{}/index.htm".format(
+            self.ap_settings["protocol"], self.ap_settings["admin_username"],
+            self.ap_settings["admin_password"], self.ap_settings["ip_address"],
+            self.ap_settings["port"])
+        self.CONFIG_PAGE_NOLOGIN = "{}://{}:{}/index.htm".format(
+            self.ap_settings["protocol"], self.ap_settings["ip_address"],
+            self.ap_settings["port"])
+        self.CONFIG_PAGE_ADVANCED = "{}://{}:{}/adv_index.htm".format(
+            self.ap_settings["protocol"], self.ap_settings["ip_address"],
+            self.ap_settings["port"])
         self.CHROME_OPTIONS = splinter.driver.webdriver.chrome.Options()
         self.CHROME_OPTIONS.add_argument("--no-proxy-server")
         self.CHROME_OPTIONS.add_argument("--no-sandbox")
         self.CHROME_OPTIONS.add_argument("--allow-running-insecure-content")
         self.CHROME_OPTIONS.add_argument("--ignore-certificate-errors")
         self.CHROME_CAPABILITIES = DesiredCapabilities.CHROME.copy()
-        self.CHROME_CAPABILITIES['acceptSslCerts'] = True
-        self.CHROME_CAPABILITIES['acceptInsecureCerts'] = True
+        self.CHROME_CAPABILITIES["acceptSslCerts"] = True
+        self.CHROME_CAPABILITIES["acceptInsecureCerts"] = True
         if self.ap_settings["headless_browser"]:
             self.CHROME_OPTIONS.add_argument("--headless")
             self.CHROME_OPTIONS.add_argument("--disable-gpu")
@@ -562,16 +562,17 @@
             "20": "Singapore",
             "21": "Taiwan"
         }
-        self.read_ap_settings()
-        if ap_settings.items() <= self.ap_settings.items():
-            return
-        else:
-            self.update_ap_settings(ap_settings)
-
-    def read_ap_settings(self):
-        """ Function to read ap wireless settings
-        """
-        BW_MODE_VALUES = {
+        self.BW_MODE_TEXT_2G = {
+            "11g": "Up to 54 Mbps",
+            "VHT20": "Up to 289 Mbps",
+            "VHT40": "Up to 600 Mbps"
+        }
+        self.BW_MODE_TEXT_5G = {
+            "VHT20": "Up to 347 Mbps",
+            "VHT40": "Up to 800 Mbps",
+            "VHT80": "Up to 1733 Mbps"
+        }
+        self.BW_MODE_VALUES = {
             "1": "11g",
             "2": "VHT20",
             "3": "VHT40",
@@ -579,6 +580,14 @@
             "8": "VHT40",
             "9": "VHT80"
         }
+        self.read_ap_settings()
+        if ap_settings.items() <= self.ap_settings.items():
+            return
+        else:
+            self.update_ap_settings(ap_settings)
+
+    def read_ap_settings(self):
+        """ Function to read ap wireless settings."""
         # Get radio status (on/off)
         self.read_radio_on_off()
         # Get radio configuration. Note that if both radios are off, the below
@@ -589,9 +598,10 @@
                 desired_capabilities=self.CHROME_CAPABILITIES) as browser:
             visit_config_page(browser, self.CONFIG_PAGE, BROWSER_WAIT_MED, 10)
             visit_config_page(browser, self.CONFIG_PAGE, BROWSER_WAIT_MED, 10)
+            sleep(BROWSER_WAIT_SHORT)
             wireless_button = browser.find_by_id("wireless").first
             wireless_button.click()
-            sleep(BROWSER_WAIT_SHORT)
+            sleep(BROWSER_WAIT_MED)
 
             with browser.get_iframe("formframe") as iframe:
                 for key, value in self.CONFIG_PAGE_FIELDS.items():
@@ -599,7 +609,7 @@
                         config_item = iframe.find_by_name(value).first
                         self.ap_settings["{}_{}".format(
                             key[1],
-                            key[0])] = BW_MODE_VALUES[config_item.value]
+                            key[0])] = self.BW_MODE_VALUES[config_item.value]
                     elif "region" in key:
                         config_item = iframe.find_by_name(value).first
                         self.ap_settings["region"] = self.REGION_MAP[
@@ -625,19 +635,7 @@
         return self.ap_settings.copy()
 
     def configure_ap(self):
-        """ Function to configure ap wireless settings
-        """
-        BW_MODE_TEXT_2G = {
-            "11g": "Up to 54 Mbps",
-            "VHT20": "Up to 289 Mbps",
-            "VHT40": "Up to 600 Mbps"
-        }
-        BW_MODE_TEXT_5G = {
-            "VHT20": "Up to 347 Mbps",
-            "VHT40": "Up to 800 Mbps",
-            "VHT80": "Up to 1733 Mbps"
-        }
-
+        """ Function to configure ap wireless settings."""
         # Turn radios on or off
         self.configure_radio_on_off()
         # Configure radios
@@ -647,6 +645,7 @@
                 desired_capabilities=self.CHROME_CAPABILITIES) as browser:
             visit_config_page(browser, self.CONFIG_PAGE, BROWSER_WAIT_MED, 10)
             visit_config_page(browser, self.CONFIG_PAGE, BROWSER_WAIT_MED, 10)
+            sleep(BROWSER_WAIT_SHORT)
             wireless_button = browser.find_by_id("wireless").first
             wireless_button.click()
             sleep(BROWSER_WAIT_MED)
@@ -675,12 +674,12 @@
                     elif key == ("2G", "bandwidth"):
                         config_item = iframe.find_by_name(value).first
                         config_item.select_by_text(
-                            str(BW_MODE_TEXT_2G[self.ap_settings[
+                            str(self.BW_MODE_TEXT_2G[self.ap_settings[
                                 "{}_{}".format(key[1], key[0])]]))
                     elif key == ("5G_1", "bandwidth"):
                         config_item = iframe.find_by_name(value).first
                         config_item.select_by_text(
-                            str(BW_MODE_TEXT_5G[self.ap_settings[
+                            str(self.BW_MODE_TEXT_5G[self.ap_settings[
                                 "{}_{}".format(key[1], key[0])]]))
 
                 # Update passwords for WPA2-PSK protected networks
@@ -712,13 +711,13 @@
                 except:
                     pass
                 sleep(BROWSER_WAIT_SHORT)
+            sleep(BROWSER_WAIT_EXTRA_LONG)
             visit_config_page(browser, self.CONFIG_PAGE,
                               BROWSER_WAIT_EXTRA_LONG, 10)
-            sleep(BROWSER_WAIT_LONG)
+            self.validate_ap_settings()
 
     def configure_radio_on_off(self):
-        """ Helper configuration function to turn radios on/off
-        """
+        """ Helper configuration function to turn radios on/off."""
         with splinter.Browser(
                 "chrome",
                 options=self.CHROME_OPTIONS,
@@ -726,6 +725,7 @@
             visit_config_page(browser, self.CONFIG_PAGE, BROWSER_WAIT_MED, 10)
             visit_config_page(browser, self.CONFIG_PAGE_ADVANCED,
                               BROWSER_WAIT_MED, 10)
+            sleep(BROWSER_WAIT_SHORT)
             wireless_button = browser.find_by_id("advanced_bt").first
             wireless_button.click()
             sleep(BROWSER_WAIT_SHORT)
@@ -757,8 +757,7 @@
                                       BROWSER_WAIT_EXTRA_LONG, 10)
 
     def read_radio_on_off(self):
-        """ Helper configuration function to read radio status
-        """
+        """ Helper configuration function to read radio status."""
         with splinter.Browser(
                 "chrome",
                 options=self.CHROME_OPTIONS,
@@ -782,6 +781,104 @@
                             config_item.checked)
 
 
+class NetgearR7800AP(NetgearR7500AP):
+    """ Class that implements Netgear R7800 AP."""
+
+    def __init__(self, ap_settings):
+        self.ap_settings = ap_settings.copy()
+        self.CONFIG_PAGE = "{}://{}:{}@{}:{}/index.htm".format(
+            self.ap_settings["protocol"], self.ap_settings["admin_username"],
+            self.ap_settings["admin_password"], self.ap_settings["ip_address"],
+            self.ap_settings["port"])
+        self.CONFIG_PAGE_NOLOGIN = "{}://{}:{}/index.htm".format(
+            self.ap_settings["protocol"], self.ap_settings["ip_address"],
+            self.ap_settings["port"])
+        self.CONFIG_PAGE_ADVANCED = "{}://{}:{}/adv_index.htm".format(
+            self.ap_settings["protocol"], self.ap_settings["ip_address"],
+            self.ap_settings["port"])
+        self.CHROME_OPTIONS = splinter.driver.webdriver.chrome.Options()
+        self.CHROME_OPTIONS.add_argument("--no-proxy-server")
+        self.CHROME_OPTIONS.add_argument("--no-sandbox")
+        self.CHROME_OPTIONS.add_argument("--allow-running-insecure-content")
+        self.CHROME_OPTIONS.add_argument("--ignore-certificate-errors")
+        self.CHROME_CAPABILITIES = DesiredCapabilities.CHROME.copy()
+        self.CHROME_CAPABILITIES["acceptSslCerts"] = True
+        self.CHROME_CAPABILITIES["acceptInsecureCerts"] = True
+        if self.ap_settings["headless_browser"]:
+            self.CHROME_OPTIONS.add_argument("--headless")
+            self.CHROME_OPTIONS.add_argument("--disable-gpu")
+        self.NETWORKS = ["2G", "5G_1"]
+        self.CHANNEL_BAND_MAP = {
+            "2G": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
+            "5G_1": [
+                36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120,
+                124, 128, 132, 136, 140, 149, 153, 157, 161, 165
+            ]
+        }
+        self.CONFIG_PAGE_FIELDS = {
+            "region": "WRegion",
+            ("2G", "status"): "enable_ap",
+            ("5G_1", "status"): "enable_ap_an",
+            ("2G", "ssid"): "ssid",
+            ("5G_1", "ssid"): "ssid_an",
+            ("2G", "channel"): "w_channel",
+            ("5G_1", "channel"): "w_channel_an",
+            ("2G", "bandwidth"): "opmode",
+            ("5G_1", "bandwidth"): "opmode_an",
+            ("2G", "security_type"): "security_type",
+            ("5G_1", "security_type"): "security_type_an",
+            ("2G", "password"): "passphrase",
+            ("5G_1", "password"): "passphrase_an"
+        }
+        self.REGION_MAP = {
+            "0": "Africa",
+            "1": "Asia",
+            "2": "Australia",
+            "3": "Canada",
+            "4": "Europe",
+            "5": "Israel",
+            "6": "Japan",
+            "7": "Korea",
+            "8": "Mexico",
+            "9": "South America",
+            "10": "United States",
+            "11": "China",
+            "12": "India",
+            "13": "Malaysia",
+            "14": "Middle East(Algeria/Syria/Yemen)",
+            "15": "Middle East(Iran/Labanon/Qatar)",
+            "16": "Middle East(Turkey/Egypt/Tunisia/Kuwait)",
+            "17": "Middle East(Saudi Arabia)",
+            "18": "Middle East(United Arab Emirates)",
+            "19": "Russia",
+            "20": "Singapore",
+            "21": "Taiwan"
+        }
+        self.BW_MODE_TEXT_2G = {
+            "11g": "Up to 54 Mbps",
+            "VHT20": "Up to 347 Mbps",
+            "VHT40": "Up to 600 Mbps"
+        }
+        self.BW_MODE_TEXT_5G = {
+            "VHT20": "Up to 347 Mbps",
+            "VHT40": "Up to 800 Mbps",
+            "VHT80": "Up to 1733 Mbps"
+        }
+        self.BW_MODE_VALUES = {
+            "1": "11g",
+            "2": "VHT20",
+            "3": "VHT40",
+            "7": "VHT20",
+            "8": "VHT40",
+            "9": "VHT80"
+        }
+        self.read_ap_settings()
+        if ap_settings.items() <= self.ap_settings.items():
+            return
+        else:
+            self.update_ap_settings(ap_settings)
+
+
 class NetgearR8000AP(NetgearR7000AP):
     """ Class that implements Netgear R8000 AP.
 
diff --git a/acts/tests/google/wifi/WifiSoftApAcsTest.py b/acts/tests/google/wifi/WifiSoftApAcsTest.py
index 2c22d25..ad4403a 100755
--- a/acts/tests/google/wifi/WifiSoftApAcsTest.py
+++ b/acts/tests/google/wifi/WifiSoftApAcsTest.py
@@ -90,6 +90,7 @@
                 del self.user_params["open_network"]
         except:
             pass
+        self.access_points[0].close()
 
     def teardown_class(self):
         if hasattr(self, 'iperf_server'):
@@ -149,7 +150,7 @@
         softap_info = self.dut_client.droid.wifiGetConnectionInfo()
         self.log.debug("DUT is connected to softAP %s with details: %s" %
                        (softap[wutils.WifiEnums.SSID_KEY], softap_info))
-        frequency = softap_info['link_speed']
+        frequency = softap_info['frequency']
         return hostapd_constants.CHANNEL_MAP[frequency]
 
     def configure_ap(self, channel_2g=None, channel_5g=None):
diff --git a/acts/tests/google/wifi/WifiStressTest.py b/acts/tests/google/wifi/WifiStressTest.py
index 160135e..17d6c75 100755
--- a/acts/tests/google/wifi/WifiStressTest.py
+++ b/acts/tests/google/wifi/WifiStressTest.py
@@ -58,7 +58,7 @@
             req_param_names=req_params, opt_param_names=opt_param)
 
         if "AccessPoint" in self.user_params:
-            self.legacy_configure_ap_and_start()
+            self.legacy_configure_ap_and_start(ap_count=2)
 
         asserts.assert_true(
             len(self.reference_networks) > 0,