Bug 1166274 - Part 2: Add test for wifi static ip. r=hchang
authorEdgar Chen <echen@mozilla.com>
Wed, 04 Feb 2015 23:26:11 +0800
changeset 246915 e532ebecafc6bedcf1024a90f5d3c985bee3ec3b
parent 246914 86ab6cc5a3ae6ae92d7924d96f57a9df3d615755
child 246916 23773d965ecc512fd6e2a36b41c739f9948ebab3
push id28846
push userryanvm@gmail.com
push dateWed, 03 Jun 2015 19:51:00 +0000
treeherdermozilla-central@e5ee2c56963c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershchang
bugs1166274
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1166274 - Part 2: Add test for wifi static ip. r=hchang
dom/wifi/test/marionette/head.js
dom/wifi/test/marionette/manifest.ini
dom/wifi/test/marionette/test_wifi_static_ip.js
--- a/dom/wifi/test/marionette/head.js
+++ b/dom/wifi/test/marionette/head.js
@@ -429,16 +429,33 @@ let gTestSuite = (function() {
    */
   function getKnownNetworks() {
     let request = wifiManager.getKnownNetworks();
     return wrapDomRequestAsPromise(request)
       .then(event => event.target.result);
   }
 
   /**
+   * Set the given network to static ip mode.
+   *
+   * Resolve when we set static ip mode successfully; reject when any error
+   * occurs.
+   *
+   * Fulfill params: (none)
+   * Reject params: (none)
+   *
+   * @return A deferred promise.
+   */
+  function setStaticIpMode(aNetwork, aConfig) {
+    let request = wifiManager.setStaticIpMode(aNetwork, aConfig);
+    return wrapDomRequestAsPromise(request)
+      .then(event => event.target.result);
+  }
+
+  /**
    * Issue a request to scan all wifi available networks.
    *
    * Resolve when we get the scan result; reject when any error
    * occurs.
    *
    * Fulfill params: An array of MozWifiNetwork
    * Reject params: (none)
    *
@@ -1021,16 +1038,127 @@ let gTestSuite = (function() {
           return;
         }
         throw 'Unexpected number of running processes:' + aProcessName +
               ', expected: ' + aExpectedNum + ', actual: ' + detail.length;
       });
   }
 
   /**
+   * Execute 'netcfg' shell and parse the result.
+   *
+   * Resolve when the executing is successful and reject otherwise.
+   *
+   * Fulfill params: Command result object, each key of which is the interface
+   *                 name and value is { ip(string), prefix(string) }.
+   * Reject params: String that indicates the reason of rejection.
+   *
+   * @return A deferred promise.
+   */
+  function exeAndParseNetcfg() {
+    return runEmulatorShellSafe(['netcfg'])
+      .then(function (aLines) {
+        // Sample output:
+        //
+        // lo       UP     127.0.0.1/8   0x00000049 00:00:00:00:00:00
+        // eth0     UP     10.0.2.15/24  0x00001043 52:54:00:12:34:56
+        // rmnet1   DOWN   0.0.0.0/0   0x00001002 52:54:00:12:34:58
+        // rmnet2   DOWN   0.0.0.0/0   0x00001002 52:54:00:12:34:59
+        // rmnet3   DOWN   0.0.0.0/0   0x00001002 52:54:00:12:34:5a
+        // wlan0    UP     192.168.1.1/24  0x00001043 52:54:00:12:34:5b
+        // sit0     DOWN   0.0.0.0/0   0x00000080 00:00:00:00:00:00
+        // rmnet0   UP     10.0.2.100/24  0x00001043 52:54:00:12:34:57
+        //
+        let netcfgResult = {};
+        aLines.forEach(function (aLine) {
+          let tokens = aLine.split(/\s+/);
+          if (tokens.length < 5) {
+            return;
+          }
+          let ifname = tokens[0];
+          let [ip, prefix] = tokens[2].split('/');
+          netcfgResult[ifname] = { ip: ip, prefix: prefix };
+        });
+        log("netcfg result:" + JSON.stringify(netcfgResult));
+
+        return netcfgResult;
+      });
+  }
+
+  /**
+   * Execute 'ip route' and parse the result.
+   *
+   * Resolve when the executing is successful and reject otherwise.
+   *
+   * Fulfill params: Command result object, each key of which is the interface
+   *                 name and value is { src(string), gateway(string),
+   *                 default(boolean) }.
+   * Reject params: String that indicates the reason of rejection.
+   *
+   * @return A deferred promise.
+   */
+  function exeAndParseIpRoute() {
+    return runEmulatorShellSafe(['ip', 'route'])
+      .then(function (aLines) {
+        // Sample output:
+        //
+        // 10.0.2.4 via 10.0.2.2 dev rmnet0
+        // 10.0.2.3 via 10.0.2.2 dev rmnet0
+        // 192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.1
+        // 10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
+        // 10.0.2.0/24 dev rmnet0  proto kernel  scope link  src 10.0.2.100
+        // default via 10.0.2.2 dev rmnet0
+        // default via 10.0.2.2 dev eth0  metric 2
+        //
+
+        let ipRouteResult = {};
+
+        // Parse source ip for each interface.
+        aLines.forEach(function (aLine) {
+          let tokens = aLine.trim().split(/\s+/);
+          let srcIndex = tokens.indexOf('src');
+          if (srcIndex < 0 || srcIndex + 1 >= tokens.length) {
+            return;
+          }
+          let ifname = tokens[2];
+          let src = tokens[srcIndex + 1];
+          ipRouteResult[ifname] = { src: src, default: false, gateway: null };
+        });
+
+        // Parse default interfaces.
+        aLines.forEach(function (aLine) {
+          let tokens = aLine.split(/\s+/);
+          if (tokens.length < 2) {
+            return;
+          }
+          if ('default' === tokens[0]) {
+            let ifnameIndex = tokens.indexOf('dev');
+            if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) {
+              return;
+            }
+            let ifname = tokens[ifnameIndex + 1];
+            if (!ipRouteResult[ifname]) {
+              return;
+            }
+            ipRouteResult[ifname].default = true;
+            let gwIndex = tokens.indexOf('via');
+            if (gwIndex < 0 || gwIndex + 1 >= tokens.length) {
+              return;
+            }
+            ipRouteResult[ifname].gateway = tokens[gwIndex + 1];
+            return;
+          }
+        });
+        log("ip route result:" + JSON.stringify(ipRouteResult));
+
+        return ipRouteResult;
+      });
+  }
+
+  /**
    * Verify everything about routing when the wifi tethering is either on or off.
    *
    * We use two unix commands to verify the routing: 'netcfg' and 'ip route'.
    * For now the following two things will be checked:
    *   1) The default route interface should be 'rmnet0'.
    *   2) wlan0 is up and its ip is set to a private subnet.
    *
    * We also verify iptables output as netd's NatController will execute
@@ -1039,97 +1167,18 @@ let gTestSuite = (function() {
    * Resolve when the verification is successful and reject otherwise.
    *
    * Fulfill params: (none)
    * Reject params: String that indicates the reason of rejection.
    *
    * @return A deferred promise.
    */
   function verifyTetheringRouting(aEnabled) {
-    let netcfgResult = {};
-    let ipRouteResult = {};
-
-    // Execute 'netcfg' and parse to |netcfgResult|, each key of which is the
-    // interface name and value is { ip(string) }.
-    function exeAndParseNetcfg() {
-      return runEmulatorShellSafe(['netcfg'])
-        .then(function (aLines) {
-          // Sample output:
-          //
-          // lo       UP     127.0.0.1/8   0x00000049 00:00:00:00:00:00
-          // eth0     UP     10.0.2.15/24  0x00001043 52:54:00:12:34:56
-          // rmnet1   DOWN   0.0.0.0/0   0x00001002 52:54:00:12:34:58
-          // rmnet2   DOWN   0.0.0.0/0   0x00001002 52:54:00:12:34:59
-          // rmnet3   DOWN   0.0.0.0/0   0x00001002 52:54:00:12:34:5a
-          // wlan0    UP     192.168.1.1/24  0x00001043 52:54:00:12:34:5b
-          // sit0     DOWN   0.0.0.0/0   0x00000080 00:00:00:00:00:00
-          // rmnet0   UP     10.0.2.100/24  0x00001043 52:54:00:12:34:57
-          //
-          aLines.forEach(function (aLine) {
-            let tokens = aLine.split(/\s+/);
-            if (tokens.length < 5) {
-              return;
-            }
-            let ifname = tokens[0];
-            let ip = (tokens[2].split('/'))[0];
-            netcfgResult[ifname] = { ip: ip };
-          });
-        });
-    }
-
-    // Execute 'ip route' and parse to |ipRouteResult|, each key of which is the
-    // interface name and value is { src(string), default(boolean) }.
-    function exeAndParseIpRoute() {
-      return runEmulatorShellSafe(['ip', 'route'])
-        .then(function (aLines) {
-          // Sample output:
-          //
-          // 10.0.2.4 via 10.0.2.2 dev rmnet0
-          // 10.0.2.3 via 10.0.2.2 dev rmnet0
-          // 192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.1
-          // 10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
-          // 10.0.2.0/24 dev rmnet0  proto kernel  scope link  src 10.0.2.100
-          // default via 10.0.2.2 dev rmnet0
-          // default via 10.0.2.2 dev eth0  metric 2
-          //
-
-          // Parse source ip for each interface.
-          aLines.forEach(function (aLine) {
-            let tokens = aLine.trim().split(/\s+/);
-            let srcIndex = tokens.indexOf('src');
-            if (srcIndex < 0 || srcIndex + 1 >= tokens.length) {
-              return;
-            }
-            let ifname = tokens[2];
-            let src = tokens[srcIndex + 1];
-            ipRouteResult[ifname] = { src: src, default: false };
-          });
-
-          // Parse default interfaces.
-          aLines.forEach(function (aLine) {
-            let tokens = aLine.split(/\s+/);
-            if (tokens.length < 2) {
-              return;
-            }
-            if ('default' === tokens[0]) {
-              let ifnameIndex = tokens.indexOf('dev');
-              if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) {
-                return;
-              }
-              let ifname = tokens[ifnameIndex + 1];
-              if (ipRouteResult[ifname]) {
-                ipRouteResult[ifname].default = true;
-              }
-              return;
-            }
-          });
-
-        });
-
-    }
+    let netcfgResult;
+    let ipRouteResult;
 
     // Find MASQUERADE in POSTROUTING section. 'MASQUERADE' should be found
     // when tethering is enabled. 'MASQUERADE' shouldn't be found when tethering
     // is disabled.
     function verifyIptables() {
       return runEmulatorShellSafe(['iptables', '-t', 'nat', '-L', 'POSTROUTING'])
         .then(function(aLines) {
           // $ iptables -t nat -L POSTROUTING
@@ -1153,32 +1202,31 @@ let gTestSuite = (function() {
           if ((aEnabled && !found) || (!aEnabled && found)) {
             throw 'MASQUERADE' + (found ? '' : ' not') + ' found while tethering is ' +
                   (aEnabled ? 'enabled' : 'disabled');
           }
         });
     }
 
     function verifyDefaultRouteAndIp(aExpectedWifiTetheringIp) {
-      log(JSON.stringify(ipRouteResult));
-      log(JSON.stringify(netcfgResult));
-
       if (aEnabled) {
         isOrThrow(ipRouteResult['rmnet0'].src, netcfgResult['rmnet0'].ip, 'rmnet0.ip');
         isOrThrow(ipRouteResult['rmnet0'].default, true, 'rmnet0.default');
 
         isOrThrow(ipRouteResult['wlan0'].src, netcfgResult['wlan0'].ip, 'wlan0.ip');
         isOrThrow(ipRouteResult['wlan0'].src, aExpectedWifiTetheringIp, 'expected ip');
         isOrThrow(ipRouteResult['wlan0'].default, false, 'wlan0.default');
       }
     }
 
     return verifyIptables()
       .then(exeAndParseNetcfg)
+      .then((aResult) => { netcfgResult = aResult; })
       .then(exeAndParseIpRoute)
+      .then((aResult) => { ipRouteResult = aResult; })
       .then(() => getSettings(SETTINGS_TETHERING_WIFI_IP))
       .then(ip => verifyDefaultRouteAndIp(ip));
   }
 
   /**
    * Clean up all the allocated resources and running services for the test.
    *
    * After the test no matter success or failure, we should
@@ -1239,26 +1287,29 @@ let gTestSuite = (function() {
   suite.killAllHostapd = killAllHostapd;
   suite.wrapDomRequestAsPromise = wrapDomRequestAsPromise;
   suite.waitForWifiManagerEventOnce = waitForWifiManagerEventOnce;
   suite.verifyNumOfProcesses = verifyNumOfProcesses;
   suite.testWifiScanWithRetry = testWifiScanWithRetry;
   suite.getFirstIndexBySsid = getFirstIndexBySsid;
   suite.testAssociate = testAssociate;
   suite.getKnownNetworks = getKnownNetworks;
+  suite.setStaticIpMode = setStaticIpMode;
   suite.requestWifiScan = requestWifiScan;
   suite.waitForConnected = waitForConnected;
   suite.forgetNetwork = forgetNetwork;
   suite.waitForTimeout = waitForTimeout;
   suite.waitForRilDataConnected = waitForRilDataConnected;
   suite.requestTetheringEnabled = requestTetheringEnabled;
   suite.importCert = importCert;
   suite.getImportedCerts = getImportedCerts;
   suite.deleteCert = deleteCert;
   suite.writeFile = writeFile;
+  suite.exeAndParseNetcfg = exeAndParseNetcfg;
+  suite.exeAndParseIpRoute = exeAndParseIpRoute;
 
   /**
    * Common test routine.
    *
    * Start a test with the given test case chain. The test environment will be
    * settled down before the test. After the test, all the affected things will
    * be restored.
    *
--- a/dom/wifi/test/marionette/manifest.ini
+++ b/dom/wifi/test/marionette/manifest.ini
@@ -3,16 +3,17 @@ b2g = true
 browser = false
 qemu = true
 
 [test_wifi_enable.js]
 [test_wifi_scan.js]
 [test_wifi_associate.js]
 [test_wifi_associate_wo_connect.js]
 [test_wifi_auto_connect.js]
+[test_wifi_static_ip.js]
 [test_wifi_tethering_wifi_disabled.js]
 [test_wifi_tethering_wifi_inactive.js]
 [test_wifi_tethering_wifi_active.js]
 [test_wifi_manage_server_certificate.js]
 [test_wifi_manage_user_certificate.js]
 [test_wifi_manage_pkcs12_certificate.js]
 [test_wifi_associate_WPA_EAP_PEAP.js]
 [test_wifi_associate_WPA_EAP_TTLS.js]
new file mode 100644
--- /dev/null
+++ b/dom/wifi/test/marionette/test_wifi_static_ip.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = 'head.js';
+
+const STATIC_IP_CONFIG = {
+  enabled: true,
+  ipaddr: "192.168.111.222",
+  proxy: "",
+  maskLength: 24,
+  gateway: "192.168.111.1",
+  dns1: "8.8.8.8",
+  dns2: "8.8.4.4",
+};
+
+function testAssociateWithStaticIp(aNetwork, aStaticIpConfig) {
+  return gTestSuite.setStaticIpMode(aNetwork, aStaticIpConfig)
+    .then(() => gTestSuite.testAssociate(aNetwork))
+    // Check ip address and prefix.
+    .then(() => gTestSuite.exeAndParseNetcfg())
+    .then((aResult) => {
+      is(aResult["wlan0"].ip, aStaticIpConfig.ipaddr, "Check ip address");
+      is(aResult["wlan0"].prefix, aStaticIpConfig.maskLength, "Check prefix");
+    })
+    // Check routing.
+    .then(() => gTestSuite.exeAndParseIpRoute())
+    .then((aResult) => {
+      is(aResult["wlan0"].src, aStaticIpConfig.ipaddr, "Check ip address");
+      is(aResult["wlan0"].default, true, "Check default route");
+      is(aResult["wlan0"].gateway, aStaticIpConfig.gateway, "Check gateway");
+    });
+}
+
+// Start test.
+gTestSuite.doTest(function() {
+  return gTestSuite.ensureWifiEnabled(true)
+    .then(() => gTestSuite.requestWifiScan())
+    .then((aNetworks) => testAssociateWithStaticIp(aNetworks[0],
+                                                   STATIC_IP_CONFIG));
+});