michael@0: Components.utils.import("resource://gre/modules/Services.jsm", this); michael@0: Components.utils.import("resource://gre/modules/Promise.jsm", this); michael@0: Components.utils.import("resource://gre/modules/Task.jsm", this); michael@0: Components.utils.import("resource://gre/modules/osfile.jsm", this); michael@0: michael@0: add_task(function init() { michael@0: do_get_profile(); michael@0: }); michael@0: michael@0: /** michael@0: * Test logging of file descriptors leaks. michael@0: */ michael@0: add_task(function system_shutdown() { michael@0: michael@0: // Test that unclosed files cause warnings michael@0: // Test that unclosed directories cause warnings michael@0: // Test that closed files do not cause warnings michael@0: // Test that closed directories do not cause warnings michael@0: function testLeaksOf(resource, topic) { michael@0: return Task.spawn(function() { michael@0: let deferred = Promise.defer(); michael@0: michael@0: // Register observer michael@0: Services.prefs.setBoolPref("toolkit.asyncshutdown.testing", true); michael@0: Services.prefs.setBoolPref("toolkit.osfile.log", true); michael@0: Services.prefs.setBoolPref("toolkit.osfile.log.redirect", true); michael@0: Services.prefs.setCharPref("toolkit.osfile.test.shutdown.observer", topic); michael@0: michael@0: let observer = function(aMessage) { michael@0: try { michael@0: do_print("Got message: " + aMessage); michael@0: if (!(aMessage instanceof Components.interfaces.nsIConsoleMessage)) { michael@0: return; michael@0: } michael@0: let message = aMessage.message; michael@0: do_print("Got message: " + message); michael@0: if (message.indexOf("TEST OS Controller WARNING") < 0) { michael@0: return; michael@0: } michael@0: do_print("Got message: " + message + ", looking for resource " + resource); michael@0: if (message.indexOf(resource) < 0) { michael@0: return; michael@0: } michael@0: do_print("Resource: " + resource + " found"); michael@0: do_execute_soon(deferred.resolve); michael@0: } catch (ex) { michael@0: do_execute_soon(function() { michael@0: deferred.reject(ex); michael@0: }); michael@0: } michael@0: }; michael@0: Services.console.registerListener(observer); michael@0: Services.obs.notifyObservers(null, topic, null); michael@0: do_timeout(1000, function() { michael@0: do_print("Timeout while waiting for resource: " + resource); michael@0: deferred.reject("timeout"); michael@0: }); michael@0: michael@0: let resolved = false; michael@0: try { michael@0: yield deferred.promise; michael@0: resolved = true; michael@0: } catch (ex if ex == "timeout") { michael@0: resolved = false; michael@0: } michael@0: Services.console.unregisterListener(observer); michael@0: Services.prefs.clearUserPref("toolkit.osfile.log"); michael@0: Services.prefs.clearUserPref("toolkit.osfile.log.redirect"); michael@0: Services.prefs.clearUserPref("toolkit.osfile.test.shutdown.observer"); michael@0: Services.prefs.clearUserPref("toolkit.async_shutdown.testing", true); michael@0: michael@0: throw new Task.Result(resolved); michael@0: }); michael@0: } michael@0: michael@0: let TEST_DIR = OS.Path.join((yield OS.File.getCurrentDirectory()), ".."); michael@0: do_print("Testing for leaks of directory iterator " + TEST_DIR); michael@0: let iterator = new OS.File.DirectoryIterator(TEST_DIR); michael@0: do_print("At this stage, we leak the directory"); michael@0: do_check_true((yield testLeaksOf(TEST_DIR, "test.shutdown.dir.leak"))); michael@0: yield iterator.close(); michael@0: do_print("At this stage, we don't leak the directory anymore"); michael@0: do_check_false((yield testLeaksOf(TEST_DIR, "test.shutdown.dir.noleak"))); michael@0: michael@0: let TEST_FILE = OS.Path.join(OS.Constants.Path.profileDir, "test"); michael@0: do_print("Testing for leaks of file descriptor: " + TEST_FILE); michael@0: let openedFile = yield OS.File.open(TEST_FILE, { create: true} ); michael@0: do_print("At this stage, we leak the file"); michael@0: do_check_true((yield testLeaksOf(TEST_FILE, "test.shutdown.file.leak"))); michael@0: yield openedFile.close(); michael@0: do_print("At this stage, we don't leak the file anymore"); michael@0: do_check_false((yield testLeaksOf(TEST_FILE, "test.shutdown.file.leak.2"))); michael@0: }); michael@0: michael@0: michael@0: function run_test() { michael@0: run_next_test(); michael@0: }