Bug 719180: Part 2 - Add jar channel unit tests; r=taras
authorNils Maier <maierman@web.de>
Wed, 28 Nov 2012 13:13:13 -0500
changeset 114378 0e5ca55005ae8ef9002ac12472740104fb79fd47
parent 114377 736e9f98d97a1c9c4824a7d064ce28b050b4eb2f
child 114379 73fdd2c4f8f0e2e1ecb8334dcd7b7580e62ca7c6
push id18733
push usereakhgari@mozilla.com
push dateWed, 28 Nov 2012 18:14:10 +0000
treeherdermozilla-inbound@0e5ca55005ae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstaras
bugs719180
milestone20.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 719180: Part 2 - Add jar channel unit tests; r=taras
modules/libjar/test/unit/test_jarchannel.js
modules/libjar/test/unit/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/modules/libjar/test/unit/test_jarchannel.js
@@ -0,0 +1,187 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/**
+ * Tests some basic jar channel functionality
+ */
+
+
+const {classes: Cc,
+       interfaces: Ci,
+       results: Cr,
+       Constructor: ctor
+       } = Components;
+
+const ios = Cc["@mozilla.org/network/io-service;1"].
+                getService(Ci.nsIIOService);
+const dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+                getService(Ci.nsIProperties);
+const obs = Cc["@mozilla.org/observer-service;1"].
+                getService(Ci.nsIObserverService);
+
+const nsIBinaryInputStream = ctor("@mozilla.org/binaryinputstream;1",
+                               "nsIBinaryInputStream",
+                               "setInputStream"
+                               );
+
+const fileBase = "test_bug637286.zip";
+const file = do_get_file("data/" + fileBase);
+const jarBase = "jar:" + ios.newFileURI(file).spec + "!";
+const tmpDir = dirSvc.get("TmpD", Ci.nsIFile);
+
+function Listener(callback) {
+    this._callback = callback;
+}
+Listener.prototype = {
+    gotStartRequest: false,
+    available: -1,
+    gotStopRequest: false,
+    QueryInterface: function(iid) {
+        if (iid.equals(Ci.nsISupports) ||
+            iid.equals(Ci.nsIRequestObserver))
+            return this;
+        throw Cr.NS_ERROR_NO_INTERFACE;
+    },
+    onDataAvailable: function(request, ctx, stream, offset, count) {
+        try {
+            this.available = stream.available();
+            do_check_eq(this.available, count);
+            // Need to consume stream to avoid assertion
+            new nsIBinaryInputStream(stream).readBytes(count);
+        }
+        catch (ex) {
+            do_throw(ex);
+        }
+    },
+    onStartRequest: function(request, ctx) {
+        this.gotStartRequest = true;
+    },
+    onStopRequest: function(request, ctx) {
+        this.gotStopRequest = true;
+        if (this._callback) {
+            this._callback.call(null, this);
+        }
+    }
+};
+
+/**
+ * Basic reading test for synchronously opened jar channels
+ */
+add_test(function testSync() {
+    var uri = jarBase + "/inner40.zip";
+    var chan = ios.newChannel(uri, null, null);
+    var stream = chan.open();
+    do_check_true(chan.contentLength > 0);
+    do_check_eq(stream.available(), chan.contentLength);
+    stream.close();
+    stream.close(); // should still not throw
+
+    run_next_test();
+});
+
+/**
+ * Basic reading test for asynchronously opened jar channel
+ */
+add_test(function testAsync() {
+    var uri = jarBase + "/inner40.zip";
+    var chan = ios.newChannel(uri, null, null);
+    do_check_true(chan.contentLength < 0);
+    chan.asyncOpen(new Listener(function(l) {
+        do_check_true(chan.contentLength > 0);
+        do_check_true(l.gotStartRequest);
+        do_check_true(l.gotStopRequest);
+        do_check_eq(l.available, chan.contentLength);
+
+        run_next_test();
+    }), null);
+});
+
+/**
+ * Basic reading test for synchronously opened, nested jar channels
+ */
+add_test(function testSyncNested() {
+    var uri = "jar:" + jarBase + "/inner40.zip!/foo";
+    var chan = ios.newChannel(uri, null, null);
+    var stream = chan.open();
+    do_check_true(chan.contentLength > 0);
+    do_check_eq(stream.available(), chan.contentLength);
+    stream.close();
+    stream.close(); // should still not throw
+
+    run_next_test();
+});
+
+/**
+ * Basic reading test for asynchronously opened, nested jar channels
+ */
+add_test(function testAsyncNested(next) {
+    var uri = "jar:" + jarBase + "/inner40.zip!/foo";
+    var chan = ios.newChannel(uri, null, null);
+    chan.asyncOpen(new Listener(function(l) {
+        do_check_true(chan.contentLength > 0);
+        do_check_true(l.gotStartRequest);
+        do_check_true(l.gotStopRequest);
+        do_check_eq(l.available, chan.contentLength);
+
+        run_next_test();
+    }), null);
+});
+
+/**
+ * Verify that file locks are released when closing a synchronously
+ * opened jar channel stream
+ */
+add_test(function testSyncCloseUnlocks() {
+    var copy = tmpDir.clone();
+    copy.append(fileBase);
+    file.copyTo(copy.parent, copy.leafName);
+
+    var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip";
+    var chan = ios.newChannel(uri, null, null);
+    var stream = chan.open();
+    do_check_true(chan.contentLength > 0);
+    stream.close();
+
+    // Drop any jar caches
+    obs.notifyObservers(null, "chrome-flush-caches", null);
+
+    try {
+        copy.remove(false);
+    }
+    catch (ex) {
+        do_throw(ex);
+    }
+
+    run_next_test();
+});
+
+/**
+ * Verify that file locks are released when closing an asynchronously
+ * opened jar channel stream
+ */
+add_test(function testAsyncCloseUnlocks() {
+    var copy = tmpDir.clone();
+    copy.append(fileBase);
+    file.copyTo(copy.parent, copy.leafName);
+
+    var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip";
+    var chan = ios.newChannel(uri, null, null);
+    chan.asyncOpen(new Listener(function (l) {
+        do_check_true(chan.contentLength > 0);
+
+        // Drop any jar caches
+        obs.notifyObservers(null, "chrome-flush-caches", null);
+
+        try {
+            copy.remove(false);
+        }
+        catch (ex) {
+            do_throw(ex);
+        }
+
+        run_next_test();
+    }), null);
+});
+
+function run_test() run_next_test();
--- a/modules/libjar/test/unit/xpcshell.ini
+++ b/modules/libjar/test/unit/xpcshell.ini
@@ -1,12 +1,13 @@
 [DEFAULT]
 head = 
 tail = 
 
+[test_jarchannel.js]
 [test_bug278262.js]
 [test_bug333423.js]
 [test_bug336691.js]
 [test_bug370103.js]
 [test_bug379841.js]
 [test_bug407303.js]
 [test_bug453254.js]
 [test_bug458158.js]