|
1 Components.utils.import("resource://gre/modules/Services.jsm", this); |
|
2 Components.utils.import("resource://gre/modules/Promise.jsm", this); |
|
3 Components.utils.import("resource://gre/modules/Task.jsm", this); |
|
4 Components.utils.import("resource://gre/modules/osfile.jsm", this); |
|
5 |
|
6 add_task(function init() { |
|
7 do_get_profile(); |
|
8 }); |
|
9 |
|
10 /** |
|
11 * Test logging of file descriptors leaks. |
|
12 */ |
|
13 add_task(function system_shutdown() { |
|
14 |
|
15 // Test that unclosed files cause warnings |
|
16 // Test that unclosed directories cause warnings |
|
17 // Test that closed files do not cause warnings |
|
18 // Test that closed directories do not cause warnings |
|
19 function testLeaksOf(resource, topic) { |
|
20 return Task.spawn(function() { |
|
21 let deferred = Promise.defer(); |
|
22 |
|
23 // Register observer |
|
24 Services.prefs.setBoolPref("toolkit.asyncshutdown.testing", true); |
|
25 Services.prefs.setBoolPref("toolkit.osfile.log", true); |
|
26 Services.prefs.setBoolPref("toolkit.osfile.log.redirect", true); |
|
27 Services.prefs.setCharPref("toolkit.osfile.test.shutdown.observer", topic); |
|
28 |
|
29 let observer = function(aMessage) { |
|
30 try { |
|
31 do_print("Got message: " + aMessage); |
|
32 if (!(aMessage instanceof Components.interfaces.nsIConsoleMessage)) { |
|
33 return; |
|
34 } |
|
35 let message = aMessage.message; |
|
36 do_print("Got message: " + message); |
|
37 if (message.indexOf("TEST OS Controller WARNING") < 0) { |
|
38 return; |
|
39 } |
|
40 do_print("Got message: " + message + ", looking for resource " + resource); |
|
41 if (message.indexOf(resource) < 0) { |
|
42 return; |
|
43 } |
|
44 do_print("Resource: " + resource + " found"); |
|
45 do_execute_soon(deferred.resolve); |
|
46 } catch (ex) { |
|
47 do_execute_soon(function() { |
|
48 deferred.reject(ex); |
|
49 }); |
|
50 } |
|
51 }; |
|
52 Services.console.registerListener(observer); |
|
53 Services.obs.notifyObservers(null, topic, null); |
|
54 do_timeout(1000, function() { |
|
55 do_print("Timeout while waiting for resource: " + resource); |
|
56 deferred.reject("timeout"); |
|
57 }); |
|
58 |
|
59 let resolved = false; |
|
60 try { |
|
61 yield deferred.promise; |
|
62 resolved = true; |
|
63 } catch (ex if ex == "timeout") { |
|
64 resolved = false; |
|
65 } |
|
66 Services.console.unregisterListener(observer); |
|
67 Services.prefs.clearUserPref("toolkit.osfile.log"); |
|
68 Services.prefs.clearUserPref("toolkit.osfile.log.redirect"); |
|
69 Services.prefs.clearUserPref("toolkit.osfile.test.shutdown.observer"); |
|
70 Services.prefs.clearUserPref("toolkit.async_shutdown.testing", true); |
|
71 |
|
72 throw new Task.Result(resolved); |
|
73 }); |
|
74 } |
|
75 |
|
76 let TEST_DIR = OS.Path.join((yield OS.File.getCurrentDirectory()), ".."); |
|
77 do_print("Testing for leaks of directory iterator " + TEST_DIR); |
|
78 let iterator = new OS.File.DirectoryIterator(TEST_DIR); |
|
79 do_print("At this stage, we leak the directory"); |
|
80 do_check_true((yield testLeaksOf(TEST_DIR, "test.shutdown.dir.leak"))); |
|
81 yield iterator.close(); |
|
82 do_print("At this stage, we don't leak the directory anymore"); |
|
83 do_check_false((yield testLeaksOf(TEST_DIR, "test.shutdown.dir.noleak"))); |
|
84 |
|
85 let TEST_FILE = OS.Path.join(OS.Constants.Path.profileDir, "test"); |
|
86 do_print("Testing for leaks of file descriptor: " + TEST_FILE); |
|
87 let openedFile = yield OS.File.open(TEST_FILE, { create: true} ); |
|
88 do_print("At this stage, we leak the file"); |
|
89 do_check_true((yield testLeaksOf(TEST_FILE, "test.shutdown.file.leak"))); |
|
90 yield openedFile.close(); |
|
91 do_print("At this stage, we don't leak the file anymore"); |
|
92 do_check_false((yield testLeaksOf(TEST_FILE, "test.shutdown.file.leak.2"))); |
|
93 }); |
|
94 |
|
95 |
|
96 function run_test() { |
|
97 run_next_test(); |
|
98 } |