Bug 821579 - B2G 3G: Add Marionette test for Data Connection. r=vicamo
authorJessica Jong <jjong@mozilla.com>
Mon, 09 Sep 2013 10:57:14 +0800
changeset 146773 b8c3080fc0e5bcb09af7d8043260adc1b05e2441
parent 146772 144f672e64d1f9e0c5f2d058ad31f9698481dd75
child 146774 bf9034be6a6480e0e826158c68799c49f9b6fb65
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersvicamo
bugs821579
milestone26.0a1
Bug 821579 - B2G 3G: Add Marionette test for Data Connection. r=vicamo
dom/network/tests/marionette/manifest.ini
dom/network/tests/marionette/test_mobile_data_connection.js
--- a/dom/network/tests/marionette/manifest.ini
+++ b/dom/network/tests/marionette/manifest.ini
@@ -5,15 +5,16 @@ qemu = true
 
 [test_mobile_networks.js]
 disabled = Bug 808783
 [test_mobile_voice_state.js]
 [test_mobile_iccinfo.js]
 [test_mobile_operator_names.js]
 [test_mobile_preferred_network_type.js]
 disabled = Bug 808783
+[test_mobile_data_connection.js]
 [test_mobile_data_location.js]
 [test_mobile_data_state.js]
 [test_mobile_mmi.js]
 [test_mobile_roaming_preference.js]
 [test_call_barring_get_option.js]
 [test_call_barring_set_error.js]
 [test_call_barring_change_password.js]
new file mode 100644
--- /dev/null
+++ b/dom/network/tests/marionette/test_mobile_data_connection.js
@@ -0,0 +1,308 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+
+const DATA_KEY = "ril.data.enabled";
+const DATA_ROAMING_KEY = "ril.data.roaming_enabled";
+const APN_KEY = "ril.data.apnSettings";
+
+SpecialPowers.setBoolPref("dom.mozSettings.enabled", true);
+SpecialPowers.addPermission("mobileconnection", true, document);
+SpecialPowers.addPermission("settings-read", true, document);
+SpecialPowers.addPermission("settings-write", true, document);
+
+let settings = window.navigator.mozSettings;
+let connection = window.navigator.mozMobileConnection;
+ok(connection instanceof MozMobileConnection,
+   "connection is instanceof " + connection.constructor);
+
+
+let pendingEmulatorCmdCount = 0;
+function sendCmdToEmulator(cmd, callback) {
+  ++pendingEmulatorCmdCount;
+
+  runEmulatorCmd(cmd, function (result) {
+    --pendingEmulatorCmdCount;
+
+    is(result[0], "OK", "Emulator response");
+
+    if (callback) {
+      callback();
+    }
+  });
+}
+
+let tasks = {
+  // List of test fuctions. Each of them should call |tasks.next()| when
+  // completed or |tasks.finish()| to jump to the last one.
+  _tasks: [],
+  _nextTaskIndex: 0,
+
+  push: function push(func) {
+    this._tasks.push(func);
+  },
+
+  next: function next() {
+    let index = this._nextTaskIndex++;
+    let task = this._tasks[index];
+    try {
+      task();
+    } catch (ex) {
+      ok(false, "test task[" + index + "] throws: " + ex);
+      // Run last task as clean up if possible.
+      if (index != this._tasks.length - 1) {
+        this.finish();
+      }
+    }
+  },
+
+  finish: function finish() {
+    this._tasks[this._tasks.length - 1]();
+  },
+
+  run: function run() {
+    this.next();
+  }
+};
+
+function setSetting(key, value, callback) {
+  let setLock = settings.createLock();
+  let obj = {};
+  obj[key] = value;
+
+  let setReq = setLock.set(obj);
+  setReq.addEventListener("success", function onSetSuccess() {
+    ok(true, "set '" + key + "' to " + obj[key]);
+    if (callback) {
+      callback();
+    }
+  });
+  setReq.addEventListener("error", function onSetError() {
+    ok(false, "cannot set '" + key + "'");
+    tasks.finish();
+  });
+}
+
+function getSetting(key, callback) {
+  let getLock = settings.createLock();
+
+  let getReq = getLock.get(key);
+  getReq.addEventListener("success", function onGetSuccess() {
+    ok(true, "get " + key + " setting okay");
+    let value = getReq.result[key];
+    callback(value);
+  });
+  getReq.addEventListener("error", function onGetError() {
+    ok(false, "cannot get '" + key + "'");
+    tasks.finish();
+  });
+}
+
+function setEmulatorAPN(callback) {
+  let apn =
+    [
+      [
+        {"carrier":"T-Mobile US",
+         "apn":"epc.tmobile.com",
+         "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
+         "types":["default","supl","mms"]}
+      ]
+    ];
+  setSetting(APN_KEY, apn, callback);
+}
+
+function setEmulatorRoaming(roaming, callback) {
+  log("Setting emulator roaming state: " + roaming + ".");
+
+  // Set voice registration state first and then data registration state.
+  let cmd = "gsm voice " + (roaming ? "roaming" : "home");
+  sendCmdToEmulator(cmd, function() {
+
+    connection.addEventListener("voicechange", function onvoicechange() {
+      connection.removeEventListener("voicechange", onvoicechange);
+      log("mobileConnection.voice.roaming is now '"
+        + connection.voice.roaming + "'.");
+      is(connection.voice.roaming, roaming, "voice.roaming");
+
+      let cmd = "gsm data " + (roaming ? "roaming" : "home");
+      sendCmdToEmulator(cmd, function () {
+
+        connection.addEventListener("datachange", function ondatachange() {
+          connection.removeEventListener("datachange", ondatachange);
+          log("mobileConnection.data.roaming is now '"
+            + connection.data.roaming + "'.");
+          is(connection.data.roaming, roaming, "data.roaming");
+          if (callback) {
+            callback();
+          }
+        });
+      });
+    });
+  });
+}
+
+function setEmulatorHome(callback) {
+  let voiceRegistration = false;
+  let dataRegistration = false;
+
+  if (connection.voice.state != "registered") {
+    sendCmdToEmulator("gsm voice home", function() {
+      connection.addEventListener("voicechange", function onvoicechange() {
+        connection.removeEventListener("voicechange", onvoicechange);
+        log("mobileConnection.voice.state is now '"
+          + connection.voice.state + "'.");
+        is(connection.voice.state, "registered", "voice.state");
+        voiceRegistration = true;
+      });
+    });
+  } else {
+    voiceRegistration = true;
+  }
+
+  if (connection.data.state != "registered") {
+    sendCmdToEmulator("gsm data home", function() {
+      connection.addEventListener("datachange", function ondatachange() {
+        connection.removeEventListener("datachange", ondatachange);
+        log("mobileConnection.data.state is now '"
+          + connection.data.state + "'.");
+        is(connection.data.state, "registered", "data.state");
+        dataRegistration = true;
+      });
+    });
+  } else {
+    dataRegistration = true;
+  }
+
+  waitFor(callback, function() {
+    return (voiceRegistration && dataRegistration);
+  });
+}
+
+
+tasks.push(function verifyInitialState() {
+  log("Verifying initial state.");
+
+  // Want to start test with mobileConnection.data.state 'registered',
+  // This is the default state; if it is not currently this value then set it.
+  setEmulatorHome(function() {
+    // Want to start test with data off,
+    // This is the default state; if it is not currently this value then set it.
+    getSetting(DATA_KEY, function(result) {
+      let value = result;
+      log("Starting data enabled: " + value);
+      if (value) {
+        setSetting(DATA_KEY, false);
+
+        connection.addEventListener("datachange", function ondatachange() {
+          connection.removeEventListener("datachange", ondatachange);
+          log("mobileConnection.data.connected is now '"
+            + connection.data.connected + "'.");
+          is(connection.data.connected, false, "data.connected");
+          setEmulatorAPN(function() {
+            tasks.next();
+          });
+        });
+      } else {
+        setEmulatorAPN(function() {
+          tasks.next();
+        });
+      }
+    });
+  });
+});
+
+tasks.push(function testEnableData() {
+  log("Turn data on.");
+
+  connection.addEventListener("datachange", function ondatachange() {
+    connection.removeEventListener("datachange", ondatachange);
+    log("mobileConnection.data.connected is now '"
+      + connection.data.connected + "'.");
+    is(connection.data.connected, true, "data.connected");
+    tasks.next();
+  });
+
+  setSetting(DATA_KEY, true);
+});
+
+tasks.push(function testDisableDataRoamingWhileRoaming() {
+  log("Disable data roaming while roaming.");
+
+  setSetting(DATA_ROAMING_KEY, false);
+
+  // Wait for roaming state to change, then data connection should
+  // be disconnected due to data roaming set to off.
+  setEmulatorRoaming(true, function() {
+    connection.addEventListener("datachange", function ondatachange() {
+      connection.removeEventListener("datachange", ondatachange);
+      log("mobileConnection.data.connected is now '"
+        + connection.data.connected + "'.");
+      is(connection.data.connected, false, "data.connected");
+      tasks.next();
+    });
+  });
+});
+
+tasks.push(function testEnableDataRoamingWhileRoaming() {
+  log("Enable data roaming while roaming.");
+
+  // Data should be re-connected as we enabled data roaming.
+  connection.addEventListener("datachange", function ondatachange() {
+    connection.removeEventListener("datachange", ondatachange);
+    log("mobileConnection.data.connected is now '"
+      + connection.data.connected + "'.");
+    is(connection.data.connected, true, "data.connected");
+    tasks.next();
+  });
+
+  setSetting(DATA_ROAMING_KEY, true);
+});
+
+tasks.push(function testDisableDataRoamingWhileNotRoaming() {
+  log("Disable data roaming while not roaming.");
+
+  // Wait for roaming state to change then set data roaming back
+  // to off.
+  setEmulatorRoaming(false, function() {
+    setSetting(DATA_ROAMING_KEY, false);
+
+    // No change event will be received cause data connection state
+    // remains the same.
+    window.setTimeout(function() {
+      is(connection.data.connected, true, "data.connected");
+      tasks.next();
+    }, 1000);
+  });
+});
+
+tasks.push(function testDisableData() {
+  log("Turn data off.");
+
+  connection.addEventListener("datachange", function ondatachange() {
+    connection.removeEventListener("datachange", ondatachange);
+    log("mobileConnection.data.connected is now '"
+      + connection.data.connected + "'.");
+    is(connection.data.connected, false, "data.connected");
+    tasks.next();
+  });
+
+  setSetting(DATA_KEY, false);
+});
+
+// WARNING: All tasks should be pushed before this!!!
+tasks.push(function cleanUp() {
+  if (pendingEmulatorCmdCount) {
+    window.setTimeout(cleanUp, 100);
+    return;
+  }
+
+  SpecialPowers.removePermission("mobileconnection", document);
+  SpecialPowers.removePermission("settings-write", document);
+  SpecialPowers.removePermission("settings-read", document);
+  SpecialPowers.clearUserPref("dom.mozSettings.enabled");
+  finish();
+});
+
+tasks.run();
+