Bug 821578 - Add Marionette test for data call with multiple APN. f=edgar, r=hsinyi
authorJessica Jong <jjong@mozilla.com>
Fri, 06 Jun 2014 19:15:00 -0400
changeset 206652 30e1107561f5c28a1292d6d7f07cc29c66d1e278
parent 206651 eccdf8bfd1391c1b1ea1fc39fc0ab5aa54753a2e
child 206653 f6395f17c99f68a0b04294eb781b1ac8ee2a1a44
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershsinyi
bugs821578
milestone32.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 821578 - Add Marionette test for data call with multiple APN. f=edgar, r=hsinyi
dom/system/gonk/tests/marionette/head.js
dom/system/gonk/tests/marionette/manifest.ini
dom/system/gonk/tests/marionette/test_data_connection.js
dom/system/gonk/tests/marionette/test_multiple_data_connection.js
dom/system/gonk/tests/marionette/test_network_active_changed.js
--- a/dom/system/gonk/tests/marionette/head.js
+++ b/dom/system/gonk/tests/marionette/head.js
@@ -1,15 +1,28 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_CONTEXT = "chrome";
 
+const SETTINGS_KEY_DATA_ENABLED = "ril.data.enabled";
+const SETTINGS_KEY_DATA_APN_SETTINGS  = "ril.data.apnSettings";
+
+const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
+const TOPIC_INTERFACE_STATE_CHANGED = "network-interface-state-changed";
+const TOPIC_NETWORK_ACTIVE_CHANGED = "network-active-changed";
+
 let Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise;
 
+let ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
+ok(ril, "ril.constructor is " + ril.constructor);
+
+let radioInterface = ril.getRadioInterface(0);
+ok(radioInterface, "radioInterface.constructor is " + radioInterface.constrctor);
+
 /**
  * Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject.
  *
  * Fulfill params: A DOMEvent.
  * Reject params: A DOMEvent.
  *
  * @param aRequest
  *        A DOMRequest instance.
@@ -111,16 +124,113 @@ function waitForObserverEvent(aTopic) {
       obs.removeObserver(observer, aTopic);
       deferred.resolve(subject);
     }
   }, aTopic, false);
 
   return deferred.promise;
 }
 
+let mobileTypeMapping = {
+  "default": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
+  "mms": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS,
+  "supl": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL,
+  "ims": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS,
+  "dun": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN
+};
+
+/**
+ * Set the default data connection enabling state, wait for
+ * "network-connection-state-changed" event and verify state.
+ *
+ * Fulfill params: (none)
+ *
+ * @param aEnabled
+ *        A boolean state.
+ *
+ * @return A deferred promise.
+ */
+function setDataEnabledAndWait(aEnabled) {
+  let promises = [];
+  promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
+    .then(function(aSubject) {
+      ok(aSubject instanceof Ci.nsIRilNetworkInterface,
+         "subject should be an instance of nsIRILNetworkInterface");
+      is(aSubject.type, Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
+         "subject.type should be " + Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE);
+      is(aSubject.state,
+         aEnabled ? Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED
+                  : Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
+         "subject.state should be " + aEnabled ? "CONNECTED" : "DISCONNECTED");
+    }));
+  promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aEnabled));
+
+  return Promise.all(promises);
+}
+
+/**
+ * Setup a certain type of data connection, wait for
+ * "network-connection-state-changed" event and verify state.
+ *
+ * Fulfill params: (none)
+ *
+ * @param aType
+ *        The string of the type of data connection to setup.
+ *
+ * @return A deferred promise.
+ */
+function setupDataCallAndWait(aType) {
+  log("setupDataCallAndWait: " + aType);
+
+  let promises = [];
+  promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
+    .then(function(aSubject) {
+      let networkType = mobileTypeMapping[aType];
+      ok(aSubject instanceof Ci.nsIRilNetworkInterface,
+         "subject should be an instance of nsIRILNetworkInterface");
+      is(aSubject.type, networkType,
+         "subject.type should be " + networkType);
+      is(aSubject.state, Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED,
+         "subject.state should be CONNECTED");
+    }));
+  promises.push(radioInterface.setupDataCallByType(aType));
+
+  return Promise.all(promises);
+}
+
+/**
+ * Deactivate a certain type of data connection, wait for
+ * "network-connection-state-changed" event and verify state.
+ *
+ * Fulfill params: (none)
+ *
+ * @param aType
+ *        The string of the type of data connection to deactivate.
+ *
+ * @return A deferred promise.
+ */
+function deactivateDataCallAndWait(aType) {
+  log("deactivateDataCallAndWait: " + aType);
+
+  let promises = [];
+  promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
+    .then(function(aSubject) {
+      let networkType = mobileTypeMapping[aType];
+      ok(aSubject instanceof Ci.nsIRilNetworkInterface,
+         "subject should be an instance of nsIRILNetworkInterface");
+      is(aSubject.type, networkType,
+         "subject.type should be " + networkType);
+      is(aSubject.state, Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
+         "subject.state should be DISCONNECTED");
+    }));
+  promises.push(radioInterface.deactivateDataCallByType(aType));
+
+  return Promise.all(promises);
+}
+
 /**
  * Basic test routine helper.
  *
  * This helper does nothing but clean-ups.
  *
  * @param aTestCaseMain
  *        A function that takes no parameter.
  */
--- a/dom/system/gonk/tests/marionette/manifest.ini
+++ b/dom/system/gonk/tests/marionette/manifest.ini
@@ -6,8 +6,9 @@ qemu = true
 [test_geolocation.js]
 disabled = Bug 808783
 [test_fakevolume.js]
 [test_ril_code_quality.py]
 [test_screen_state.js]
 [test_dsds_numRadioInterfaces.js]
 [test_data_connection.js]
 [test_network_active_changed.js]
+[test_multiple_data_connection.js]
--- a/dom/system/gonk/tests/marionette/test_data_connection.js
+++ b/dom/system/gonk/tests/marionette/test_data_connection.js
@@ -1,93 +1,31 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 60000;
 MARIONETTE_HEAD_JS = "head.js";
 
-Cu.import("resource://gre/modules/Promise.jsm");
-
-const DATA_KEY = "ril.data.enabled";
-const APN_KEY  = "ril.data.apnSettings";
-const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
-
-let ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
-ok(ril, "ril.constructor is " + ril.constructor);
-
-let radioInterface = ril.getRadioInterface(0);
-ok(radioInterface, "radioInterface.constructor is " + radioInterface.constrctor);
-
 function setEmulatorAPN() {
   let apn = [
     [{"carrier":"T-Mobile US",
       "apn":"epc.tmobile.com",
       "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
       "types":["default","supl","mms","ims","dun"]}]
   ];
 
-  return setSettings(APN_KEY, apn);
-}
-
-function setupDataCallAndWait(type, networkType) {
-  let promises = [];
-  promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED));
-  promises.push(radioInterface.setupDataCallByType(type));
-
-  return Promise.all(promises).then(function(results) {
-    let subject = results[0];
-    ok(subject instanceof Ci.nsIRilNetworkInterface,
-       "subject should be an instance of nsIRILNetworkInterface");
-    is(subject.type, networkType,
-       "subject.type should be " + networkType);
-    is(subject.state, Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED,
-       "subject.state should be CONNECTED");
-  });
-}
-
-function deactivateDataCallAndWait(type, networkType) {
-  let promises = [];
-  promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED));
-  promises.push(radioInterface.deactivateDataCallByType(type));
-
-  return Promise.all(promises).then(function(results) {
-    let subject = results[0];
-    ok(subject instanceof Ci.nsIRilNetworkInterface,
-       "subject should be an instance of nsIRILNetworkInterface");
-    is(subject.type, networkType,
-       "subject.type should be " + networkType);
-    is(subject.state, Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
-       "subject.state should be DISCONNECTED");
-  });
-}
-
-function setDataEnabledAndWait(enabled) {
-  let promises = [];
-  promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED));
-  promises.push(setSettings(DATA_KEY, enabled));
-
-  return Promise.all(promises).then(function(results) {
-    let subject = results[0];
-    ok(subject instanceof Ci.nsIRilNetworkInterface,
-       "subject should be an instance of nsIRILNetworkInterface");
-    is(subject.type, Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
-       "subject.type should be " + Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE);
-    is(subject.state,
-       enabled ? Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED
-               : Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
-       "subject.state should be " + enabled ? "CONNECTED" : "DISCONNECTED");
-  });
+  return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
 }
 
 // Test initial State
 function testInitialState() {
   log("= testInitialState =");
 
   // Data should be off before starting any test.
-  return getSettings(DATA_KEY)
+  return getSettings(SETTINGS_KEY_DATA_ENABLED)
     .then(value => {
       is(value, false, "Data must be off");
     });
 }
 
 // Test default data Connection
 function testDefaultDataConnection() {
   log("= testDefaultDataConnection =");
@@ -100,40 +38,32 @@ function testDefaultDataConnection() {
 
 // Test non default data connection
 function testNonDefaultDataConnection() {
   log("= testNonDefaultDataConnection =");
 
   function doTestNonDefaultDataConnection(type) {
     log("doTestNonDefaultDataConnection: " + type);
 
-    let typeMapping = {
-      "mms": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS,
-      "supl": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL,
-      "ims": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS,
-      "dun": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN
-    };
-    let networkType = typeMapping[type];
-
-    return setupDataCallAndWait(type, networkType)
-      .then(() => deactivateDataCallAndWait(type, networkType));
+    return setupDataCallAndWait(type)
+      .then(() => deactivateDataCallAndWait(type));
   }
 
   let currentApn;
-  return getSettings(APN_KEY)
+  return getSettings(SETTINGS_KEY_DATA_APN_SETTINGS)
     .then(value => {
       currentApn = value;
     })
     .then(setEmulatorAPN)
     .then(() => doTestNonDefaultDataConnection("mms"))
     .then(() => doTestNonDefaultDataConnection("supl"))
     .then(() => doTestNonDefaultDataConnection("ims"))
     .then(() => doTestNonDefaultDataConnection("dun"))
     // Restore APN settings
-    .then(() => setSettings(APN_KEY, currentApn));
+    .then(() => setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, currentApn));
 }
 
 // Start test
 startTestBase(function() {
   return testInitialState()
     .then(() => testDefaultDataConnection())
     .then(() => testNonDefaultDataConnection());
 });
new file mode 100644
--- /dev/null
+++ b/dom/system/gonk/tests/marionette/test_multiple_data_connection.js
@@ -0,0 +1,88 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
+
+// Must sync with hardware/ril/reference-ril/reference-ril.c
+const MAX_DATA_CONTEXTS = 4;
+
+function setEmulatorAPN() {
+  // Use different apn for each network type.
+  let apn = [[ { "carrier":"T-Mobile US",
+                 "apn":"epc1.tmobile.com",
+                 "types":["default"] },
+               { "carrier":"T-Mobile US",
+                 "apn":"epc2.tmobile.com",
+                 "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
+                 "types":["mms"] },
+               { "carrier":"T-Mobile US",
+                 "apn":"epc3.tmobile.com",
+                 "types":["supl"] },
+               { "carrier":"T-Mobile US",
+                 "apn":"epc4.tmobile.com",
+                 "types":["ims"] },
+               { "carrier":"T-Mobile US",
+                 "apn":"epc5.tmobile.com",
+                 "types":["dun"] }]];
+
+  return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
+}
+
+// Test initial State
+function testInitialState() {
+  log("= testInitialState =");
+
+  // Data should be off before starting any test.
+  return getSettings(SETTINGS_KEY_DATA_ENABLED)
+    .then(value => {
+      is(value, false, "Data must be off");
+    });
+}
+
+function testSetupConcurrentDataCalls() {
+  log("= testSetupConcurrentDataCalls =");
+
+  let promise = Promise.resolve();
+  let types = Object.keys(mobileTypeMapping);
+  // Skip default mobile type.
+  for (let i = 1; i < MAX_DATA_CONTEXTS; i++) {
+    let type = types[i];
+    promise = promise.then(() => setupDataCallAndWait(type));
+  }
+  return promise;
+}
+
+function testDeactivateConcurrentDataCalls() {
+  log("= testDeactivateConcurrentDataCalls =");
+
+  let promise = Promise.resolve();
+  let types = Object.keys(mobileTypeMapping);
+  // Skip default mobile type.
+  for (let i = 1; i < MAX_DATA_CONTEXTS; i++) {
+    let type = types[i];
+    promise = promise.then(() => deactivateDataCallAndWait(type));
+  }
+  return promise;
+}
+
+// Start test
+startTestBase(function() {
+
+  let origApnSettings;
+  return testInitialState()
+    .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS))
+    .then(value => {
+      origApnSettings = value;
+    })
+    .then(() => setEmulatorAPN())
+    .then(() => setDataEnabledAndWait(true))
+    .then(() => testSetupConcurrentDataCalls())
+    .then(() => testDeactivateConcurrentDataCalls())
+    .then(() => setDataEnabledAndWait(false))
+    .then(() => {
+      if (origApnSettings) {
+        return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings);
+      }
+    });
+});
--- a/dom/system/gonk/tests/marionette/test_network_active_changed.js
+++ b/dom/system/gonk/tests/marionette/test_network_active_changed.js
@@ -1,17 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 60000;
 MARIONETTE_HEAD_JS = "head.js";
 
-const SETTINGS_KEY_DATA_ENABLED = "ril.data.enabled";
-const TOPIC_NETWORK_ACTIVE_CHANGED = "network-active-changed";
-
 let networkManager =
   Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager);
 ok(networkManager,
    "networkManager.constructor is " + networkManager.constructor);
 
 function testInitialState() {
   return getSettings(SETTINGS_KEY_DATA_ENABLED)
     .then((enabled) => {