Bug 1028887 - Cause tests to fail when autoclosing Sqlite.jsm. r=Yoric
authorMichael Brennan <brennan.brisad@gmail.com>
Thu, 26 Jun 2014 06:24:21 +0200
changeset 211944 3a1f1bf7edb9003e1944d01592fa37f79ac2fb21
parent 211943 f0359665c82079b713b4b582760ee59ffae11285
child 211945 a2f064eaa41ab2b495f6de2e15a8dda1e7e2ae6e
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric
bugs1028887
milestone33.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 1028887 - Cause tests to fail when autoclosing Sqlite.jsm. r=Yoric
toolkit/modules/Sqlite.jsm
toolkit/modules/tests/xpcshell/test_sqlite.js
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -37,27 +37,38 @@ XPCOMUtils.defineLazyServiceGetter(this,
 // used for logging to distinguish connection instances.
 let connectionCounters = new Map();
 
 /**
  * Once `true`, reject any attempt to open or close a database.
  */
 let isClosed = false;
 
+this.Debugging = {
+  // Tests should fail if a connection auto closes.  The exception is
+  // when finalization itself is tested, in which case this flag
+  // should be set to false.
+  failTestsOnAutoClose: true
+};
+
 // Displays a script error message
 function logScriptError(message) {
   let consoleMessage = Cc["@mozilla.org/scripterror;1"].
                        createInstance(Ci.nsIScriptError);
   let stack = new Error();
   consoleMessage.init(message, stack.fileName, null, stack.lineNumber, 0,
                       Ci.nsIScriptError.errorFlag, "component javascript");
   Services.console.logMessage(consoleMessage);
 
-  // Always dump errors, in case the Console Service isn't listening anymore
-  dump("*** " + message + "\n");
+  // This `Promise.reject` will cause tests to fail.  The debugging
+  // flag can be used to suppress this for tests that explicitly
+  // test auto closes.
+  if (Debugging.failTestsOnAutoClose) {
+    Promise.reject(new Error(message));
+  }
 }
 
 /**
  * Barriers used to ensure that Sqlite.jsm is shutdown after all
  * its clients.
  */
 XPCOMUtils.defineLazyGetter(this, "Barriers", () => {
   let Barriers = {
--- a/toolkit/modules/tests/xpcshell/test_sqlite.js
+++ b/toolkit/modules/tests/xpcshell/test_sqlite.js
@@ -28,16 +28,22 @@ function sleep(ms) {
     notify: function () {
       deferred.resolve();
     },
   }, ms, timer.TYPE_ONE_SHOT);
 
   return deferred.promise;
 }
 
+// When testing finalization, use this to tell Sqlite.jsm to not throw
+// an uncatchable `Promise.reject`
+function failTestsOnAutoClose(enabled)  {
+  Cu.getGlobalForObject(Sqlite).Debugging.failTestsOnAutoClose = enabled;
+}
+
 function getConnection(dbName, extraOptions={}) {
   let path = dbName + ".sqlite";
   let options = {path: path};
   for (let [k, v] in Iterator(extraOptions)) {
     options[k] = v;
   }
 
   return Sqlite.openConnection(options);
@@ -906,28 +912,31 @@ add_task(function* test_readOnly_clone()
   yield c.close();
   yield clone.close();
 });
 
 /**
  * Test finalization
  */
 add_task(function* test_closed_by_witness() {
+  failTestsOnAutoClose(false);
   let c = yield getDummyDatabase("closed_by_witness");
 
   Services.obs.notifyObservers(null, "sqlite-finalization-witness",
                                c._connectionData._connectionIdentifier);
   // Since we triggered finalization ourselves, tell the witness to
   // forget the connection so it does not trigger a finalization again
   c._witness.forget();
   yield c._connectionData._deferredClose.promise;
   do_check_false(c._connectionData._open);
+  failTestsOnAutoClose(true);
 });
 
 add_task(function* test_warning_message_on_finalization() {
+  failTestsOnAutoClose(false);
   let c = yield getDummyDatabase("warning_message_on_finalization");
   let connectionIdentifier = c._connectionData._connectionIdentifier;
   let deferred = Promise.defer();
 
   let listener = {
     observe: function(msg) {
       let messageText = msg.message;
       // Make sure the message starts with a warning containing the
@@ -941,35 +950,38 @@ add_task(function* test_warning_message_
 
   Services.obs.notifyObservers(null, "sqlite-finalization-witness", connectionIdentifier);
   // Since we triggered finalization ourselves, tell the witness to
   // forget the connection so it does not trigger a finalization again
   c._witness.forget();
 
   yield deferred.promise;
   Services.console.unregisterListener(listener);
+  failTestsOnAutoClose(true);
 });
 
 add_task(function* test_error_message_on_unknown_finalization() {
+  failTestsOnAutoClose(false);
   let deferred = Promise.defer();
 
   let listener = {
     observe: function(msg) {
       let messageText = msg.message;
       if (messageText.indexOf("Error: Attempt to finalize unknown " +
                               "Sqlite connection: foo") !== -1) {
         deferred.resolve();
       }
     }
   };
   Services.console.registerListener(listener);
   Services.obs.notifyObservers(null, "sqlite-finalization-witness", "foo");
 
   yield deferred.promise;
   Services.console.unregisterListener(listener);
+  failTestsOnAutoClose(true);
 });
 
 add_task(function* test_forget_witness_on_close() {
   let c = yield getDummyDatabase("forget_witness_on_close");
 
   let forgetCalled = false;
   let oldWitness = c._witness;
   c._witness = {
@@ -980,16 +992,17 @@ add_task(function* test_forget_witness_o
   };
 
   yield c.close();
   // After close, witness should have forgotten the connection
   do_check_true(forgetCalled);
 });
 
 add_task(function* test_close_database_on_gc() {
+  failTestsOnAutoClose(false);
   let deferred = Promise.defer();
 
   for (let i = 0; i < 100; ++i) {
     let c = yield getDummyDatabase("gc_" + i);
     c._connectionData._deferredClose.promise.then(deferred.resolve);
   }
 
   // Call getDummyDatabase once more to clear any remaining
@@ -998,9 +1011,10 @@ add_task(function* test_close_database_o
   // test will timeout. Once that is fixed, we can remove this line
   // and be fine as long as at least one connection is
   // garbage-collected.
   let last = yield getDummyDatabase("gc_last");
   yield last.close();
 
   Components.utils.forceGC();
   yield deferred.promise;
+  failTestsOnAutoClose(true);
 });