function run_test() {
// Just check we're running tests okay
do_check_true(true);
// Check the interface has been loaded correctly
do_check_true("btIBittorrentTracker" in Components.interfaces);
// Check the component has been registered correctly
do_check_true("@wikiscraps.com/tracker;1" in Components.classes);
// Grab the service
var trackerService = Components.
classes["@wikiscraps.com/tracker;1"].
getService(Components.interfaces.btIBittorrentTracker);
do_test_pending();
// Make a request to the tracker
trackerService.start(
// infohash of http://www.mininova.org/det/3194273
"\x72\xc2\x4e\x55\xc3\x2c\xde\xf7\x23\x78\x12\xf1\x69\x4d\xad\xd1\xe7\x13\x19\x97",
// announceURI
"http://tracker.mininova.org/announce",
"", // tracker Id
// peer id (should've generated & recorded this)
"-YY0000-000003030303",
6881, // local bittorrent port
-1, // maximumPeers (-1 means use default)
0, // uploaded bytes
0, // downloaded bytes
0, // remaining bytes...
{
onResponse : function(peers, interval, trackerId) {
// got a list of peers
do_check_true(peers instanceof Array);
// finished tests
do_test_finished();
},
onError : function(serverResponse) {
// darn. Fail the test.
do_throw("Unknown error, server response was:\n" + serverResponse);
do_test_finished();
}
});
}
So you pass the tracker service the information needed to make a call to the tracker, and some kind of observer/callback to use when there's a result known. Okay? Got it? Cool.
Anyways, I started seeing a BloatView report after running this test. It didn't appear originally, so I assume it only appears when some kind of leak occurs.
== BloatView: ALL (cumulative) LEAK STATISTICS
|<----------------Class--------------->|<-----Bytes------>|<----------------Objects---------------->|<--------------References-------------->|
Per-Inst Leaked Total Rem Mean StdDev Total Rem Mean StdDev
0 TOTAL 27 520 24783 11 ( 183.34 +/- 238.02) 80546 13 ( 263.14 +/- 337.35)
2 BackstagePass 24 24 1 1 ( 1.00 +/- 0.00) 6366 4 ( 148.79 +/- 78.75)
19 XPCNativeScriptableShared 112 112 1053 1 ( 12.21 +/- 1.38) 0 0 ( 0.00 +/- 0.00)
22 XPCWrappedNative 56 168 1322 3 ( 661.75 +/- 381.27) 8044 3 ( 682.46 +/- 383.57)
23 XPCWrappedNativeProto 32 64 519 2 ( 260.00 +/- 149.61) 0 0 ( 0.00 +/- 0.00)
100 nsJSID 36 36 116 1 ( 58.25 +/- 33.42) 499 1 ( 117.51 +/- 67.79)
135 nsStringBuffer 8 8 2600 1 ( 435.41 +/- 266.14) 4832 1 ( 413.00 +/- 254.37)
144 nsSystemPrincipal 36 36 1 1 ( 1.00 +/- 0.00) 347 1 ( 4.72 +/- 1.09)
147 nsThread 72 72 3 1 ( 1.80 +/- 0.84) 4598 3 ( 571.22 +/- 379.54)
nsTraceRefcntImpl::DumpStatistics: 180 entries
Ouch. So, going back over what I'd done recently, I found this:
if (Tracker.prototype._bencoding == false) {
try {
Tracker.prototype._bencoding = Components.
classes["@wikiscraps.com/encoding/bencoding;1"].
getService(Components.interfaces.Bencoding);
} catch(e) {
callback.onError("Bencoding component not loaded");
return;
}
}
It seems loading a XPCOM service, and then leaving it in a 'global' variable and never explicitly releasing it caused a leak. Whoops. The BloatView goes away if I switch to using local variables and acquire the service each time it's needed, so it seems I can call that fixed?
More information on testing a JavaScript Add-on with XPCShell (Interfaces and components!).
More information on writing XPCShell unit tests.
No comments:
Post a Comment