1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/libjar/test/unit/test_jarchannel.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,202 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ 1.6 + */ 1.7 + 1.8 +/** 1.9 + * Tests some basic jar channel functionality 1.10 + */ 1.11 + 1.12 + 1.13 +const {classes: Cc, 1.14 + interfaces: Ci, 1.15 + results: Cr, 1.16 + Constructor: ctor 1.17 + } = Components; 1.18 + 1.19 +const ios = Cc["@mozilla.org/network/io-service;1"]. 1.20 + getService(Ci.nsIIOService); 1.21 +const dirSvc = Cc["@mozilla.org/file/directory_service;1"]. 1.22 + getService(Ci.nsIProperties); 1.23 +const obs = Cc["@mozilla.org/observer-service;1"]. 1.24 + getService(Ci.nsIObserverService); 1.25 + 1.26 +const nsIBinaryInputStream = ctor("@mozilla.org/binaryinputstream;1", 1.27 + "nsIBinaryInputStream", 1.28 + "setInputStream" 1.29 + ); 1.30 + 1.31 +const fileBase = "test_bug637286.zip"; 1.32 +const file = do_get_file("data/" + fileBase); 1.33 +// on child we'll test with jar:remoteopenfile:// instead of jar:file:// 1.34 +const jarBase = "jar:" + filePrefix + ios.newFileURI(file).spec + "!"; 1.35 +const tmpDir = dirSvc.get("TmpD", Ci.nsIFile); 1.36 + 1.37 +function Listener(callback) { 1.38 + this._callback = callback; 1.39 +} 1.40 +Listener.prototype = { 1.41 + gotStartRequest: false, 1.42 + available: -1, 1.43 + gotStopRequest: false, 1.44 + QueryInterface: function(iid) { 1.45 + if (iid.equals(Ci.nsISupports) || 1.46 + iid.equals(Ci.nsIRequestObserver)) 1.47 + return this; 1.48 + throw Cr.NS_ERROR_NO_INTERFACE; 1.49 + }, 1.50 + onDataAvailable: function(request, ctx, stream, offset, count) { 1.51 + try { 1.52 + this.available = stream.available(); 1.53 + do_check_eq(this.available, count); 1.54 + // Need to consume stream to avoid assertion 1.55 + new nsIBinaryInputStream(stream).readBytes(count); 1.56 + } 1.57 + catch (ex) { 1.58 + do_throw(ex); 1.59 + } 1.60 + }, 1.61 + onStartRequest: function(request, ctx) { 1.62 + this.gotStartRequest = true; 1.63 + }, 1.64 + onStopRequest: function(request, ctx) { 1.65 + this.gotStopRequest = true; 1.66 + if (this._callback) { 1.67 + this._callback.call(null, this); 1.68 + } 1.69 + } 1.70 +}; 1.71 + 1.72 +/** 1.73 + * Basic reading test for asynchronously opened jar channel 1.74 + */ 1.75 +function testAsync() { 1.76 + var uri = jarBase + "/inner40.zip"; 1.77 + var chan = ios.newChannel(uri, null, null); 1.78 + do_check_true(chan.contentLength < 0); 1.79 + chan.asyncOpen(new Listener(function(l) { 1.80 + do_check_true(chan.contentLength > 0); 1.81 + do_check_true(l.gotStartRequest); 1.82 + do_check_true(l.gotStopRequest); 1.83 + do_check_eq(l.available, chan.contentLength); 1.84 + 1.85 + run_next_test(); 1.86 + }), null); 1.87 +} 1.88 + 1.89 +add_test(testAsync); 1.90 +// Run same test again so we test the codepath for a zipcache hit 1.91 +add_test(testAsync); 1.92 + 1.93 + 1.94 +// In e10s child processes we don't currently support 1.95 +// 1) synchronously opening jar files on parent 1.96 +// 2) nested jar channels in e10s: (app:// doesn't use them). 1.97 +// 3) we can't do file lock checks on android, so skip those tests too. 1.98 +if (!inChild) { 1.99 + 1.100 + /** 1.101 + * Basic reading test for synchronously opened jar channels 1.102 + */ 1.103 + add_test(function testSync() { 1.104 + var uri = jarBase + "/inner40.zip"; 1.105 + var chan = ios.newChannel(uri, null, null); 1.106 + var stream = chan.open(); 1.107 + do_check_true(chan.contentLength > 0); 1.108 + do_check_eq(stream.available(), chan.contentLength); 1.109 + stream.close(); 1.110 + stream.close(); // should still not throw 1.111 + 1.112 + run_next_test(); 1.113 + }); 1.114 + 1.115 + 1.116 + /** 1.117 + * Basic reading test for synchronously opened, nested jar channels 1.118 + */ 1.119 + add_test(function testSyncNested() { 1.120 + var uri = "jar:" + jarBase + "/inner40.zip!/foo"; 1.121 + var chan = ios.newChannel(uri, null, null); 1.122 + var stream = chan.open(); 1.123 + do_check_true(chan.contentLength > 0); 1.124 + do_check_eq(stream.available(), chan.contentLength); 1.125 + stream.close(); 1.126 + stream.close(); // should still not throw 1.127 + 1.128 + run_next_test(); 1.129 + }); 1.130 + 1.131 + /** 1.132 + * Basic reading test for asynchronously opened, nested jar channels 1.133 + */ 1.134 + add_test(function testAsyncNested(next) { 1.135 + var uri = "jar:" + jarBase + "/inner40.zip!/foo"; 1.136 + var chan = ios.newChannel(uri, null, null); 1.137 + chan.asyncOpen(new Listener(function(l) { 1.138 + do_check_true(chan.contentLength > 0); 1.139 + do_check_true(l.gotStartRequest); 1.140 + do_check_true(l.gotStopRequest); 1.141 + do_check_eq(l.available, chan.contentLength); 1.142 + 1.143 + run_next_test(); 1.144 + }), null); 1.145 + }); 1.146 + 1.147 + /** 1.148 + * Verify that file locks are released when closing a synchronously 1.149 + * opened jar channel stream 1.150 + */ 1.151 + add_test(function testSyncCloseUnlocks() { 1.152 + var copy = tmpDir.clone(); 1.153 + copy.append(fileBase); 1.154 + file.copyTo(copy.parent, copy.leafName); 1.155 + 1.156 + var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip"; 1.157 + var chan = ios.newChannel(uri, null, null); 1.158 + var stream = chan.open(); 1.159 + do_check_true(chan.contentLength > 0); 1.160 + stream.close(); 1.161 + 1.162 + // Drop any jar caches 1.163 + obs.notifyObservers(null, "chrome-flush-caches", null); 1.164 + 1.165 + try { 1.166 + copy.remove(false); 1.167 + } 1.168 + catch (ex) { 1.169 + do_throw(ex); 1.170 + } 1.171 + 1.172 + run_next_test(); 1.173 + }); 1.174 + 1.175 + /** 1.176 + * Verify that file locks are released when closing an asynchronously 1.177 + * opened jar channel stream 1.178 + */ 1.179 + add_test(function testAsyncCloseUnlocks() { 1.180 + var copy = tmpDir.clone(); 1.181 + copy.append(fileBase); 1.182 + file.copyTo(copy.parent, copy.leafName); 1.183 + 1.184 + var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip"; 1.185 + var chan = ios.newChannel(uri, null, null); 1.186 + chan.asyncOpen(new Listener(function (l) { 1.187 + do_check_true(chan.contentLength > 0); 1.188 + 1.189 + // Drop any jar caches 1.190 + obs.notifyObservers(null, "chrome-flush-caches", null); 1.191 + 1.192 + try { 1.193 + copy.remove(false); 1.194 + } 1.195 + catch (ex) { 1.196 + do_throw(ex); 1.197 + } 1.198 + 1.199 + run_next_test(); 1.200 + }), null); 1.201 + }); 1.202 + 1.203 +} // if !inChild 1.204 + 1.205 +function run_test() run_next_test();