Bug 718190. (Bv2a) 3 tests which use over 2 GiB files: Fix .diskSpaceAvailable handling, Improve .fileSize handling. r=mbanner.
authorSerge Gautherie <sgautherie.bz@free.fr>
Thu, 19 Apr 2012 17:45:39 +0200
changeset 11671 7fe3e7bebed6e27b889afd070975bfd75e51e55f
parent 11670 26c2c8008156966302f82799f2d74ade4cafe3de
child 11672 d04fc59c787f9646b7048b392ff6020e241c6fce
push id529
push userbugzilla@standard8.plus.com
push dateMon, 04 Jun 2012 19:55:55 +0000
treeherdercomm-beta@109334822255 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbanner
bugs718190
Bug 718190. (Bv2a) 3 tests which use over 2 GiB files: Fix .diskSpaceAvailable handling, Improve .fileSize handling. r=mbanner.
mailnews/imap/test/unit/test_largeOfflineStore.js
mailnews/local/test/unit/test_over2GBMailboxes.js
mailnews/local/test/unit/test_over4GBMailboxes.js
--- a/mailnews/imap/test/unit/test_largeOfflineStore.js
+++ b/mailnews/imap/test/unit/test_largeOfflineStore.js
@@ -35,36 +35,41 @@ function run_test()
    * Set up an IMAP server.
    */
   gIMAPDaemon = new imapDaemon();
   gServer = makeServer(gIMAPDaemon, "");
   gIMAPIncomingServer = createLocalIMAPServer();
   gIMAPIncomingServer.maximumConnectionsNumber = 1;
 
   // Figure out the name of the IMAP inbox
-  let inboxFile = gIMAPIncomingServer.rootMsgFolder.filePath.clone();
+  let inboxFile = gIMAPIncomingServer.rootMsgFolder.filePath;
   inboxFile.append("INBOX");
   if (!inboxFile.exists())
     inboxFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0644", 8));
 
+  let neededFreeSpace = 0x200000000;
   // On Windows, check whether the drive is NTFS. If it is, mark the file as
   // sparse. If it isn't, then bail out now, because in all probability it is
   // FAT32, which doesn't support file sizes greater than 4 GB.
   if ("@mozilla.org/windows-registry-key;1" in Cc &&
       get_file_system(inboxFile) != "NTFS")
   {
     dump("On Windows, this test only works on NTFS volumes.\n");
     endTest();
     return;
   }
+
   let isFileSparse = mark_file_region_sparse(inboxFile, 0, 0x10000000f);
-  if (!isFileSparse && inboxFile.diskSpaceAvailable < 0x200000000)
-  {
-    dump("On systems where files can't be marked sparse, this test needs 8 " +
-         "GB of free disk space.\n");
+  let freeDiskSpace = inboxFile.diskSpaceAvailable;
+  do_print("Free disk space = " + toMiBString(freeDiskSpace));
+  if (!isFileSparse && freeDiskSpace < neededFreeSpace) {
+    do_print("This test needs " + toMiBString(neededFreeSpace) +
+             " free space to run. Aborting.");
+    todo_check_true(false);
+
     endTest();
     return;
   }
 
   let inbox = gIMAPDaemon.getMailbox("INBOX");
 
   let ioService = Cc["@mozilla.org/network/io-service;1"]
                     .getService(Ci.nsIIOService);
@@ -100,16 +105,18 @@ function run_test()
   // seek to 15 bytes past 4GB.
   outputStream.seek(0, 0x10000000f);
   // Write an empty "from" line.
   outputStream.write("from\r\n", 6);
   outputStream.close();
 
   // Save initial file size.
   gOfflineStoreSize = gIMAPInbox.filePath.fileSize;
+  do_print("Offline store size (before 1st downloadAllForOffline()) = " +
+           gOfflineStoreSize);
 
   // Download for offline use, to append created messages to local IMAP inbox.
   gIMAPInbox.downloadAllForOffline(UrlListener, null);
 }
 
 var UrlListener =
 {
   OnStartRunningUrl: function(url) {},
@@ -120,48 +127,48 @@ var UrlListener =
 
     if (!gDownloadedOnce) {
       gDownloadedOnce = true;
       // Call downloadAllForOffline() a second time.
       gIMAPInbox.downloadAllForOffline(UrlListener, null);
       return;
     }
 
-    // verify that the message headers have the offline flag set.
+    // Make sure offline store grew (i.e., we were not writing over data).
+    let offlineStoreSize = gIMAPInbox.filePath.fileSize;
+    do_print("Offline store size (after 2nd downloadAllForOffline()) = " +
+             offlineStoreSize + ". (Msg hdr offsets should be close to it.)");
+    do_check_true(offlineStoreSize > gOfflineStoreSize);
+
+    // Verify that the message headers have the offline flag set.
     let msgEnumerator = gIMAPInbox.msgDatabase.EnumerateMessages();
     let offset = new Object;
     let size = new Object;
-    while (msgEnumerator.hasMoreElements())
-    {
+    while (msgEnumerator.hasMoreElements()) {
       let header = msgEnumerator.getNext();
       // Verify that each message has been downloaded and looks OK.
-      if (header instanceof Components.interfaces.nsIMsgDBHdr &&
-          (header.flags & Ci.nsMsgMessageFlags.Offline))
-        gIMAPInbox.getOfflineFileStream(header.messageKey, offset, size).close();
-      else
+      if (!(header instanceof Components.interfaces.nsIMsgDBHdr &&
+            (header.flags & Ci.nsMsgMessageFlags.Offline)))
         do_throw("Message not downloaded for offline use");
 
-      dump("msg hdr offset = " + offset.value + "\n");
+      gIMAPInbox.getOfflineFileStream(header.messageKey, offset, size).close();
+      do_print("Msg hdr offset = " + offset.value);
     }
-    let offlineStoreSize = gIMAPInbox.filePath.fileSize;
-    dump("offline store size = " + offlineStoreSize + "\n");
-    // Make sure offline store grew (i.e., we're not writing over data).
-    do_check_true(offlineStoreSize > gOfflineStoreSize);
 
     try {
       do_timeout(1000, endTest);
     } catch(ex) {
       do_throw(ex);
     }
   }
 };
 
 function endTest()
 {
-  // free up disk space - if you want to look at the file after running
+  // Free up disk space - if you want to look at the file after running
   // this test, comment out this line.
   if (gIMAPInbox)
     gIMAPInbox.filePath.remove(false);
 
   if (gIMAPIncomingServer)
     gIMAPIncomingServer.closeCachedConnections();
   if (gServer)
     gServer.stop();
--- a/mailnews/local/test/unit/test_over2GBMailboxes.js
+++ b/mailnews/local/test/unit/test_over2GBMailboxes.js
@@ -3,30 +3,36 @@
 /* Test of accessing over 2 GiB local folder. */
 
 load("../../../resources/messageGenerator.js");
 const bugmail10 = do_get_file("../../../data/bugmail10");
 
 Services.prefs.setCharPref("mail.serverDefaultStoreContractID",
                            "@mozilla.org/msgstore/berkeleystore;1");
 
+var gLocalInboxSize;
 var gLocalTrashFolder;
 
 function run_test()
 {
   loadLocalMailAccount();
 
   // "Master" do_test_pending(), paired with a do_test_finished() at the end of
   // all the operations.
   do_test_pending();
 
-  let inboxFile = gLocalInboxFolder.filePath.clone();
-  var freeDiskSpace = inboxFile.diskSpaceAvailable;
-  if (freeDiskSpace < 0x100000000) {
-    dump("not enough free disk space: " + freeDiskSpace + "\n");
+  let inboxFile = gLocalInboxFolder.filePath;
+
+  let neededFreeSpace = 0x100000000;
+  let freeDiskSpace = inboxFile.diskSpaceAvailable;
+  do_print("Free disk space = " + toMiBString(freeDiskSpace));
+  if (freeDiskSpace < neededFreeSpace) {
+    do_print("This test needs " + toMiBString(neededFreeSpace) +
+             " free space to run. Aborting.");
+    todo_check_true(false);
 
     endTest();
     return;
   }
 
   // "Trash" folder
   gLocalTrashFolder = gLocalIncomingServer.rootMsgFolder.getChildNamed("Trash");
 
@@ -37,16 +43,21 @@ function run_test()
   // Open in write-only mode, no truncate.
   outputStream.init(inboxFile, 0x02, -1, 0);
   // seek past 2GB.
   outputStream.seek(0, 0x80000010);
   // Write a "space" character.
   outputStream.write(" ", 1);
   outputStream.close();
 
+  // Save initial file size.
+  gLocalInboxSize = gLocalInboxFolder.filePath.fileSize;
+  do_print("Local inbox size (before copyFileMessageInLocalFolder()) = " +
+           gLocalInboxSize);
+
   // Append mail data to over 2 GiB position for over 2 GiB msgkey.
   copyFileMessageInLocalFolder(bugmail10, 0, "", null, copyMessages);
 }
 
 // Get message whose msg key is over 2 GiB.
 function getMessageHdr()
 {
   let msgEnum = gLocalInboxFolder.msgDatabase.EnumerateMessages();
@@ -57,29 +68,36 @@ function getMessageHdr()
     }
   }
 
   do_throw("Over 2 GiB msgkey was not found!");
 }
 
 function copyMessages()
 {
-  // copy the message into the subfolder
+  // Make sure inbox file grew (i.e., we were not writing over data).
+  let localInboxSize = gLocalInboxFolder.filePath.fileSize;
+  do_print("Local inbox size (after copyFileMessageInLocalFolder()) = " +
+           localInboxSize);
+  do_check_true(localInboxSize > gLocalInboxSize);
+
+  // Copy the message into the subfolder.
   let messages = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
   messages.appendElement(getMessageHdr(), false);
   MailServices.copy.CopyMessages(gLocalInboxFolder, messages, gLocalTrashFolder,
                                  false, copyListener2, null, false);
 }
 
 var copyListener2 = {
   OnStartCopy : function() {},
   OnProgress: function(aProgress, aProgressMax) {},
   SetMessageKey : function(aKey) {},
   OnStopCopy : function(aStatus) {
     do_check_eq(aStatus, 0);
+
     do_timeout(0, accessOver2GBMsg);
   }
 };
 
 // streamMessage() test by over 2 GiB mail offset.
 function accessOver2GBMsg()
 {
   let messenger = Cc["@mozilla.org/messenger;1"].createInstance(Ci.nsIMessenger);
@@ -100,28 +118,28 @@ gStreamListener = {
     let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
                     .createInstance(Ci.nsIFileInputStream);
     let stream = Cc["@mozilla.org/scriptableinputstream;1"]
                    .createInstance(Ci.nsIScriptableInputStream);
 
     fstream.init(bugmail10, -1, 0, 0);
     stream.init(fstream);
     let original = stream.read(this._data.length);
+    do_check_eq(this._data, original);
 
-    do_check_eq(this._data, original);
     do_timeout(0, endTest);
   },
   onDataAvailable : function (aRequest, aContext, aInputStream, aOff, aCount) {
     if (this._stream == null) {
       this._stream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
       this._stream.init(aInputStream);
     }
     this._data += this._stream.read(aCount);
   },
 };
 
 function endTest() {
-  // free up disk space - if you want to look at the file after running
+  // Free up disk space - if you want to look at the file after running
   // this test, comment out this line.
   gLocalInboxFolder.filePath.remove(false);
 
   do_test_finished();
 }
--- a/mailnews/local/test/unit/test_over4GBMailboxes.js
+++ b/mailnews/local/test/unit/test_over4GBMailboxes.js
@@ -59,92 +59,113 @@ var dummyMsgWindow =
 function run_test()
 {
   loadLocalMailAccount();
 
   // "Master" do_test_pending(), paired with a do_test_finished() at the end of
   // all the operations.
   do_test_pending();
 
+  let inboxFile = gLocalInboxFolder.filePath;
+
+  let neededFreeSpace = 0x110000000;
   // On Windows, check whether the drive is NTFS. If it is, mark the file as
   // sparse. If it isn't, then bail out now, because in all probability it is
   // FAT32, which doesn't support file sizes greater than 4 GB.
   if ("@mozilla.org/windows-registry-key;1" in Cc &&
-      get_file_system(gLocalInboxFolder.filePath) != "NTFS")
+      get_file_system(inboxFile) != "NTFS")
   {
     dump("On Windows, this test only works on NTFS volumes.\n");
 
     endTest();
     return;
   }
-  if (gLocalInboxFolder.filePath.clone().diskSpaceAvailable < 0x110000000)
-  {
-    dump("this test needs >4 GB of free disk space.\n");
+
+  let freeDiskSpace = inboxFile.diskSpaceAvailable;
+  do_print("Free disk space = " + toMiBString(freeDiskSpace));
+  if (freeDiskSpace < neededFreeSpace) {
+    do_print("This test needs " + toMiBString(neededFreeSpace) +
+             " free space to run. Aborting.");
+    todo_check_true(false);
 
     endTest();
     return;
   }
 
-  // put a single message in the Inbox.
+  // Put a single message in the Inbox.
   let messageGenerator = new MessageGenerator();
   let message = messageGenerator.makeMessage();
   let localInbox = gLocalInboxFolder.QueryInterface(Ci.nsIMsgLocalMailFolder);
   localInbox.addMessage(message.toMboxString());
 
+  // Refresh 'inboxFile'.
+  inboxFile = gLocalInboxFolder.filePath;
+
   // Grow local inbox to over 4 GiB.
   let plugStore = gLocalInboxFolder.msgStore;
   do {
-    let inboxFile = gLocalInboxFolder.filePath.clone();
     let nextOffset = inboxFile.fileSize + kSparseBlockSize;
     // "Add" a new (empty) sparse block at the end of the file.
     mark_file_region_sparse(inboxFile, inboxFile.fileSize,
                             kSparseBlockSize);
+
     let reusable = new Object;
     let newMsgHdr = new Object;
     let outputStream = plugStore.getNewMsgOutputStream(gLocalInboxFolder,
                                                        newMsgHdr, reusable)
                                 .QueryInterface(Ci.nsISeekableStream);
+    // Skip directly to the new end of the file.
     outputStream.seek(0, nextOffset);
     // Add a CR+LF at end of previous message then
     // write the (same) message another time.
     let mboxString = "\r\n" + message.toMboxString();
     outputStream.write(mboxString, mboxString.length);
     outputStream.close();
     plugStore.finishNewMessage(outputStream, newMsgHdr);
+
+    // Refresh 'inboxFile'.
+    inboxFile = gLocalInboxFolder.filePath;
   }
-  while (gLocalInboxFolder.filePath.fileSize < 0x100000000)
+  while (inboxFile.fileSize < 0x100000000)
 
   // Save initial file size.
-  gLocalInboxSize = gLocalInboxFolder.filePath.fileSize;
+  gLocalInboxSize = inboxFile.fileSize;
+  do_print("Local inbox size (before copyFileMessageInLocalFolder()) = " +
+           gLocalInboxSize);
 
   // Use copyFileMessageInLocalFolder() to (try to) append another message
   //  to local inbox.
   let file = do_get_file("../../../data/multipart-complex2");
-  try {
-    copyFileMessageInLocalFolder(file, 0, "", dummyMsgWindow,
-                                 function(aMessageHeadersKeys, aStatus) {
-      do_check_false(Components.isSuccessCode(aStatus));
-    });
-  } catch (ex) {
-  }
+  copyFileMessageInLocalFolder(file, 0, "", dummyMsgWindow,
+                               function(aMessageHeadersKeys, aStatus) {
+    do_check_false(Components.isSuccessCode(aStatus));
+  });
+  do_check_true(gGotAlert);
+
+  // Make sure inbox file did not grow (i.e., no data were appended).
+  let localInboxSize = gLocalInboxFolder.filePath.fileSize;
+  do_print("Local inbox size (after copyFileMessageInLocalFolder()) = " +
+           localInboxSize);
+  do_check_eq(localInboxSize, gLocalInboxSize);
 
   // Force the db closed, so that getDatabaseWithReparse will notice
   // that it's out of date.
   gLocalInboxFolder.msgDatabase.ForceClosed();
   gLocalInboxFolder.msgDatabase = null;
   try {
     gLocalInboxFolder.getDatabaseWithReparse(ParseListener, dummyMsgWindow);
   } catch (ex) {
-    do_check_true(ex.result == Cr.NS_ERROR_NOT_INITIALIZED);
+    do_check_eq(ex.result, Cr.NS_ERROR_NOT_INITIALIZED);
   }
 }
 
 function testCompact()
 {
-  // mark messages as deleted.
+  // Very first header in msgDB is retained,
+  // then all other headers are marked as deleted.
   let msgDB = gLocalInboxFolder.msgDatabase;
   let enumerator = msgDB.EnumerateMessages();
   let firstHdr = true;
   let messages = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
   while (enumerator.hasMoreElements()) {
     let header = enumerator.getNext();
     if (header instanceof Components.interfaces.nsIMsgDBHdr && !firstHdr)
       messages.appendElement(header, false);
@@ -159,37 +180,40 @@ function testCompact()
 
 var ParseListener =
 {
   OnStartRunningUrl: function (aUrl) {},
   OnStopRunningUrl: function (aUrl, aExitCode) {
     // Check: reparse successful
     do_check_eq(aExitCode, 0);
     do_check_true(gLocalInboxFolder.msgDatabase.summaryValid);
+
     testCompact();
   }
 };
 
 var CompactListener =
 {
   OnStartRunningUrl: function (aUrl) {},
   OnStopRunningUrl: function (aUrl, aExitCode) {
     // Check: message successfully copied.
     do_check_eq(aExitCode, 0);
     do_check_true(gLocalInboxFolder.msgDatabase.summaryValid);
-    // check that folder size isn't much bigger than our sparse block size,
-    // i.e., that we just have one message.
-    do_check_true(gLocalInboxFolder.filePath.fileSize < kSparseBlockSize + 1000);
+
+    // Check that folder size isn't much bigger than our sparse block size, ...
+    let localInboxSize = gLocalInboxFolder.filePath.fileSize;
+    do_print("Local inbox size (after compact()) = " + localInboxSize);
+    do_check_true(localInboxSize < kSparseBlockSize + 1000);
+    // ... i.e., that we just have one message.
     do_check_eq(gLocalInboxFolder.getTotalMessages(false), 1);
 
-    do_check_true(gGotAlert);
     endTest();
   }
 };
 
 function endTest()
 {
-  // free up disk space - if you want to look at the file after running
+  // Free up disk space - if you want to look at the file after running
   // this test, comment out this line.
   gLocalInboxFolder.filePath.remove(false);
 
   do_test_finished();
 }