Bug 980354 - 2/2: add more test cases for storage full event. r=hsinyi
authorVicamo Yang <vyang@mozilla.com>
Thu, 13 Mar 2014 13:44:53 +0900
changeset 190553 93c1de5151273362b55af4de26175d3abb1290f4
parent 190552 3103bfd98c391f6efbc275f6dbcb0fd9caf78c36
child 190554 a6b384b72e10dcc78ad93ea9b56f3292282890e6
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershsinyi
bugs980354
milestone30.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 980354 - 2/2: add more test cases for storage full event. r=hsinyi
dom/mobilemessage/tests/marionette/mmdb_head.js
dom/mobilemessage/tests/marionette/test_mmdb_foreachmatchedmmsdeliveryinfo.js
dom/mobilemessage/tests/marionette/test_mmdb_full_storage.js
dom/mobilemessage/tests/marionette/test_mmdb_new.js
--- a/dom/mobilemessage/tests/marionette/mmdb_head.js
+++ b/dom/mobilemessage/tests/marionette/mmdb_head.js
@@ -66,16 +66,251 @@ function initMobileMessageDB(aMmdb, aDbN
  *
  * @return The passed MobileMessageDB instance.
  */
 function closeMobileMessageDB(aMmdb) {
   aMmdb.close();
   return aMmdb;
 }
 
+/**
+ * Utility function for calling MMDB methods that takes either a
+ * nsIRilMobileMessageDatabaseCallback or a
+ * nsIRilMobileMessageDatabaseRecordCallback.
+ *
+ * Resolve when the target method notifies us with a successful result code;
+ * reject otherwise. In either case, the arguments passed are packed into an
+ * array and propagated to next action.
+ *
+ * Fulfill params: an array whose elements are the arguments of the original
+ *                 callback.
+ * Reject params: same as fulfill params.
+ *
+ * @param aMmdb
+ *        A MobileMessageDB instance.
+ * @param aMethodName
+ *        A string name for that target method.
+ * @param ...
+ *        Extra arguments to pass to that target method. The last callback
+ *        argument should always be excluded.
+ *
+ * @return A deferred promise.
+ */
+function callMmdbMethod(aMmdb, aMethodName) {
+  let deferred = Promise.defer();
+
+  let args = Array.slice(arguments, 2);
+  args.push({
+    notify: function(aRv) {
+      if (!Components.isSuccessCode(aRv)) {
+        ok(true, aMethodName + " returns a unsuccessful code: " + aRv);
+        deferred.reject(Array.slice(arguments));
+      } else {
+        ok(true, aMethodName + " returns a successful code: " + aRv);
+        deferred.resolve(Array.slice(arguments));
+      }
+    }
+  });
+  aMmdb[aMethodName].apply(aMmdb, args);
+
+  return deferred.promise;
+}
+
+/**
+ * A convenient function for calling |mmdb.saveSendingMessage(...)|.
+ *
+ * Fulfill params: [<Cr.NS_ERROR_FOO>, <DOM message>].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function saveSendingMessage(aMmdb, aMessage) {
+  return callMmdbMethod(aMmdb, "saveSendingMessage", aMessage);
+}
+
+/**
+ * A convenient function for calling |mmdb.saveReceivedMessage(...)|.
+ *
+ * Fulfill params: [<Cr.NS_ERROR_FOO>, <DOM message>].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function saveReceivedMessage(aMmdb, aMessage) {
+  return callMmdbMethod(aMmdb, "saveReceivedMessage", aMessage);
+}
+
+/**
+ * A convenient function for calling |mmdb.setMessageDeliveryByMessageId(...)|.
+ *
+ * Fulfill params: [<Cr.NS_ERROR_FOO>, <DOM message>].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function setMessageDeliveryByMessageId(aMmdb, aMessageId, aReceiver, aDelivery,
+                                       aDeliveryStatus, aEnvelopeId) {
+  return callMmdbMethod(aMmdb, "setMessageDeliveryByMessageId", aMessageId,
+                        aReceiver, aDelivery, aDeliveryStatus, aEnvelopeId);
+}
+
+/**
+ * A convenient function for calling
+ * |mmdb.setMessageDeliveryStatusByEnvelopeId(...)|.
+ *
+ * Fulfill params: [<Cr.NS_ERROR_FOO>, <DOM message>].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function setMessageDeliveryStatusByEnvelopeId(aMmdb, aEnvelopeId, aReceiver,
+                                              aDeliveryStatus) {
+  return callMmdbMethod(aMmdb, "setMessageDeliveryStatusByEnvelopeId",
+                        aMmdb, aEnvelopeId, aReceiver, aDeliveryStatus);
+}
+
+/**
+ * A convenient function for calling
+ * |mmdb.setMessageReadStatusByEnvelopeId(...)|.
+ *
+ * Fulfill params: [<Cr.NS_ERROR_FOO>, <DOM message>].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function setMessageReadStatusByEnvelopeId(aMmdb, aEnvelopeId, aReceiver,
+                                          aReadStatus) {
+  return callMmdbMethod(aMmdb, "setMessageReadStatusByEnvelopeId",
+                        aEnvelopeId, aReceiver, aReadStatus);
+}
+
+/**
+ * A convenient function for calling
+ * |mmdb.getMessageRecordByTransactionId(...)|.
+ *
+ * Fulfill params: [<Cr.NS_ERROR_FOO>, <DB Record>, <DOM message>].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function getMessageRecordByTransactionId(aMmdb, aTransactionId) {
+  return callMmdbMethod(aMmdb, "getMessageRecordByTransactionId",
+                        aTransactionId);
+}
+
+/**
+ * A convenient function for calling |mmdb.getMessageRecordById(...)|.
+ *
+ * Fulfill params: [<Cr.NS_ERROR_FOO>, <DB Record>, <DOM message>].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function getMessageRecordById(aMmdb, aMessageId) {
+  return callMmdbMethod(aMmdb, "getMessageRecordById", aMessageId);
+}
+
+/**
+ * A convenient function for calling |mmdb.markMessageRead(...)|.
+ *
+ * Fulfill params: Ci.nsIMobileMessageCallback.FOO.
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function markMessageRead(aMmdb, aMessageId, aRead) {
+  let deferred = Promise.defer();
+
+  aMmdb.markMessageRead(aMessageId, aRead, false, {
+    notifyMarkMessageReadFailed: function(aRv) {
+      ok(true, "markMessageRead returns a unsuccessful code: " + aRv);
+      deferred.reject(aRv);
+    },
+
+    notifyMessageMarkedRead: function(aRead) {
+      ok(true, "markMessageRead returns a successful code: " + Cr.NS_OK);
+      deferred.resolve(Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR);
+    }
+  });
+
+  return deferred.promise;
+}
+
+/**
+ * Utility function for calling cursor-based MMDB methods.
+ *
+ * Resolve when the target method notifies us with |notifyCursorDone|,
+ * reject otherwise.
+ *
+ * Fulfill params: [<Ci.nsIMobileMessageCallback.FOO>, [<DOM message/thread>]]
+ * Reject params: same as fulfill params.
+ *
+ * @param aMmdb
+ *        A MobileMessageDB instance.
+ * @param aMethodName
+ *        A string name for that target method.
+ * @param ...
+ *        Extra arguments to pass to that target method. The last callback
+ *        argument should always be excluded.
+ *
+ * @return A deferred promise.
+ */
+function createMmdbCursor(aMmdb, aMethodName) {
+  let deferred = Promise.defer();
+
+  let cursor;
+  let results = [];
+  let args = Array.slice(arguments, 2);
+  args.push({
+    notifyCursorError: function(aRv) {
+      ok(true, "notifyCursorError: " + aRv);
+      deferred.reject([aRv, results]);
+    },
+
+    notifyCursorResult: function(aResult) {
+      ok(true, "notifyCursorResult: " + aResult.id);
+      results.push(aResult);
+      cursor.handleContinue();
+    },
+
+    notifyCursorDone: function() {
+      ok(true, "notifyCursorDone");
+      deferred.resolve([Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR, results]);
+    }
+  });
+
+  cursor = aMmdb[aMethodName].apply(aMmdb, args);
+
+  return deferred.promise;
+}
+
+/**
+ * A convenient function for calling |mmdb.createMessageCursor(...)|.
+ *
+ * Fulfill params: [<Ci.nsIMobileMessageCallback.FOO>, [<DOM message>]].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function createMessageCursor(aMmdb, aFilter, aReverse) {
+  return createMmdbCursor(aMmdb, "createMessageCursor", aFilter, aReverse);
+}
+
+/**
+ * A convenient function for calling |mmdb.createThreadCursor(...)|.
+ *
+ * Fulfill params: [<Ci.nsIMobileMessageCallback.FOO>, [<DOM thread>]].
+ * Reject params: same as fulfill params.
+ *
+ * @return A deferred promise.
+ */
+function createThreadCursor(aMmdb) {
+  return createMmdbCursor(aMmdb, "createThreadCursor");
+}
+
 // A reference to a nsIUUIDGenerator service.
 let _uuidGenerator;
 
 /**
  * Generate a new UUID.
  *
  * @return A UUID string.
  */
--- a/dom/mobilemessage/tests/marionette/test_mmdb_foreachmatchedmmsdeliveryinfo.js
+++ b/dom/mobilemessage/tests/marionette/test_mmdb_foreachmatchedmmsdeliveryinfo.js
@@ -47,33 +47,29 @@ function doTest(aMmdb, aNeedle, aVerifyF
 }
 
 function testNotFound(aMmdb) {
   log("Testing unavailable");
 
   doTest(aMmdb, PHONE_0, function(aElement) {
     ok(false, "Should never have a match");
   }, 0);
-
-  return aMmdb;
 }
 
 function testDirectMatch(aMmdb) {
   log("Testing direct matching");
 
   for (let needle of [PHONE_1, EMAIL_1]) {
     let count = deliveryInfo.reduce(function(aCount, aElement) {
       return aElement.receiver == needle ? aCount + 1 : aCount;
     }, 0);
     doTest(aMmdb, needle, function(aElement) {
       is(aElement.receiver, needle, "element.receiver");
     }, count);
   }
-
-  return aMmdb;
 }
 
 function testPhoneMatch(aMmdb) {
   log("Testing phone matching");
 
   let verifyFunc = function(aValid, aElement) {
     ok(aValid.indexOf(aElement.receiver) >= 0, "element.receiver");
   };
@@ -82,20 +78,18 @@ function testPhoneMatch(aMmdb) {
     [PHONE_2, PHONE_2_NET],
     [PHONE_3, PHONE_3_NET],
   ];
   for (let group of matchingGroups) {
     for (let item of group) {
       doTest(aMmdb, item, verifyFunc.bind(null, group), group.length);
     }
   }
-
-  return aMmdb;
 }
 
 startTestBase(function testCaseMain() {
   let mmdb = newMobileMessageDB();
   return initMobileMessageDB(mmdb, DBNAME, 0)
-    .then(testNotFound)
-    .then(testDirectMatch)
-    .then(testPhoneMatch)
-    .then(closeMobileMessageDB);
+    .then(() => testNotFound(mmdb))
+    .then(() => testDirectMatch(mmdb))
+    .then(() => testPhoneMatch(mmdb))
+    .then(() => closeMobileMessageDB(mmdb));
 });
--- a/dom/mobilemessage/tests/marionette/test_mmdb_full_storage.js
+++ b/dom/mobilemessage/tests/marionette/test_mmdb_full_storage.js
@@ -3,87 +3,117 @@
 
 MARIONETTE_TIMEOUT = 60000;
 MARIONETTE_HEAD_JS = 'mmdb_head.js';
 
 const DBNAME = "test_mmdb_full_storage:" + newUUID();
 
 let gIsDiskFull = true;
 
-let gMessageToSave = {
-  type: "sms",
-  sender: "+0987654321",
-  receiver: "+1234567890",
-  body: "quick fox jump over the lazy dog",
-  deliveryStatusRequested: false,
-  timestamp: Date.now(),
-  iccId: "1029384756"
-};
+function newSavableMessage() {
+  return {
+    type: "sms",
+    sender: "+0987654321",
+    receiver: "+1234567890",
+    body: "quick fox jump over the lazy dog",
+    deliveryStatusRequested: false,
+    messageClass: "normal",
+    timestamp: Date.now(),
+    iccId: "1029384756"
+  };
+}
+
+function isFileNoDeviceSpaceError(aErrorResult) {
+  is(aErrorResult, Cr.NS_ERROR_FILE_NO_DEVICE_SPACE, "Database error code");
+}
+
+function isCallbackStorageFullError(aErrorCode) {
+  is(aErrorCode, Ci.nsIMobileMessageCallback.STORAGE_FULL_ERROR,
+     "nsIMobileMessageCallback error code");
+}
 
 function testSaveSendingMessage(aMmdb) {
   log("testSaveSendingMessage()");
 
-  let deferred = Promise.defer();
+  gIsDiskFull = true;
+  return saveSendingMessage(aMmdb, newSavableMessage())
+    // Resolved/rejected results are both [<Cr.NS_ERROR_FOO>, <DOM message>],
+    // and we need only the error code in both cases.
+    .then((aValue) => aValue[0],
+          (aValue) => aValue[0])
+    .then(isFileNoDeviceSpaceError);
+}
 
-  aMmdb.saveSendingMessage(gMessageToSave,
-                          { notify : function(aRv, aDomMessage) {
-    if (aRv === Cr.NS_ERROR_FILE_NO_DEVICE_SPACE) {
-      ok(true, "Forbidden due to storage full.");
-      deferred.resolve(aMmdb);
-    } else {
-      ok(false, "Unexpected result: " + aRv);
-      deferred.reject(aRv);
-    }
-  }});
+function testSaveReceivedMessage(aMmdb) {
+  log("testSaveReceivedMessage()");
 
-  return deferred.promise;
+  gIsDiskFull = true;
+  return saveReceivedMessage(aMmdb, newSavableMessage())
+    // Resolved/rejected results are both [<Cr.NS_ERROR_FOO>, <DOM message>],
+    // and we need only the error code in both cases.
+    .then((aValue) => aValue[0],
+          (aValue) => aValue[0])
+    .then(isFileNoDeviceSpaceError);
 }
 
-function testSaveReceivingMessage(aMmdb) {
-  log("testSaveReceivingMessage()");
-
-  let deferred = Promise.defer();
+function testGetMessageRecordById(aMmdb) {
+  log("testGetMessageRecordById()");
 
-  aMmdb.saveReceivedMessage(gMessageToSave,
-                            { notify : function(aRv, aDomMessage) {
-    if (aRv === Cr.NS_ERROR_FILE_NO_DEVICE_SPACE) {
-      ok(true, "Forbidden due to storage full.");
-      deferred.resolve(aMmdb);
-    } else {
-      ok(false, "Unexpected result: " + aRv);
-      deferred.reject(aRv);
-    }
-  }});
+  gIsDiskFull = false;
+  return saveReceivedMessage(aMmdb, newSavableMessage())
+    // Resolved result is [<Cr.NS_ERROR_FOO>, <DOM message>],
+    .then(function(aValue) {
+      let domMessage = aValue[1];
 
-  return deferred.promise;
+      gIsDiskFull = true;
+      return getMessageRecordById(aMmdb, domMessage.id);
+    });
 }
 
-function testGetMessage(aMmdb) {
-  log("testGetMessage()");
+function testMarkMessageRead(aMmdb) {
+  log("testMarkMessageRead()");
 
-  let deferred = Promise.defer();
+  gIsDiskFull = false;
+  return saveReceivedMessage(aMmdb, newSavableMessage())
+    // Resolved/rejected results are both [<Cr.NS_ERROR_FOO>, <DOM message>].
+    .then(function(aValue) {
+      let domMessage = aValue[1];
 
-  aMmdb.getMessage(1,
-                   { notifyGetMessageFailed : function(aRv) {
-    if (aRv === Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR) {
-      ok(true, "Getting message successfully!");
-      deferred.resolve(aMmdb);
-    } else {
-      ok(false, "Unexpected result: " + aRv);
-      deferred.reject(aRv);
-    }
-  }});
+      gIsDiskFull = true;
+      return markMessageRead(aMmdb, domMessage.id, true)
+        .then(null, (aValue) => aValue)
+        .then(isCallbackStorageFullError);
+    });
+}
+
+function testCreateMessageCursor(aMmdb) {
+  log("testCreateMessageCursor()");
 
-  return deferred.promise;
+  gIsDiskFull = true;
+  return createMessageCursor(aMmdb, {}, false);
+}
+
+function testCreateThreadCursor(aMmdb) {
+  log("testCreateThreadCursor()");
+
+  gIsDiskFull = true;
+  return createThreadCursor(aMmdb);
 }
 
 startTestBase(function testCaseMain() {
 
   let mmdb = newMobileMessageDB();
-  mmdb.isDiskFull = function() {
-    return gIsDiskFull;
-  };
   return initMobileMessageDB(mmdb, DBNAME, 0)
-         .then(testSaveSendingMessage)
-         .then(testSaveReceivingMessage)
-         .then(testGetMessage)
-         .then(closeMobileMessageDB);
+    .then(function() {
+      mmdb.isDiskFull = function() {
+        return gIsDiskFull;
+      };
+    })
+
+    .then(() => testSaveSendingMessage(mmdb))
+    .then(() => testSaveReceivedMessage(mmdb))
+    .then(() => testGetMessageRecordById(mmdb))
+    .then(() => testMarkMessageRead(mmdb))
+    .then(() => testCreateMessageCursor(mmdb))
+    .then(() => testCreateThreadCursor(mmdb))
+
+    .then(() => closeMobileMessageDB(mmdb));
 });
--- a/dom/mobilemessage/tests/marionette/test_mmdb_new.js
+++ b/dom/mobilemessage/tests/marionette/test_mmdb_new.js
@@ -10,28 +10,27 @@ let dbVersion = 0;
 function check(aMmdb) {
   is(aMmdb.dbName, DBNAME, "dbName");
   if (!dbVersion) {
     ok(aMmdb.dbVersion, "dbVersion");
     dbVersion = aMmdb.dbVersion;
   } else {
     is(aMmdb.dbVersion, dbVersion, "dbVersion");
   }
-
-  return aMmdb;
 }
 
 startTestBase(function testCaseMain() {
   log("Test init MobileMessageDB");
 
   let mmdb = newMobileMessageDB();
   return initMobileMessageDB(mmdb, DBNAME, dbVersion)
-    .then(check)
-    .then(closeMobileMessageDB)
-    .then(check)
-    .then(function(aMmdb) {
+    .then(() => check(mmdb))
+    .then(() => closeMobileMessageDB(mmdb))
+    .then(() => check(mmdb))
+
+    .then(function() {
       log("Test re-init and close.");
-      return initMobileMessageDB(aMmdb, DBNAME, dbVersion);
+      return initMobileMessageDB(mmdb, DBNAME, dbVersion);
     })
-    .then(check)
-    .then(closeMobileMessageDB)
-    .then(check);
+    .then(() => check(mmdb))
+    .then(() => closeMobileMessageDB(mmdb))
+    .then(() => check(mmdb));
 });