diff options
Diffstat (limited to 'netwerk/test/httpserver/test/test_sjs_object_state.js')
-rw-r--r-- | netwerk/test/httpserver/test/test_sjs_object_state.js | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/netwerk/test/httpserver/test/test_sjs_object_state.js b/netwerk/test/httpserver/test/test_sjs_object_state.js new file mode 100644 index 0000000000..4362dc7641 --- /dev/null +++ b/netwerk/test/httpserver/test/test_sjs_object_state.js @@ -0,0 +1,305 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Tests that the object-state-preservation mechanism works correctly. + */ + +XPCOMUtils.defineLazyGetter(this, "PATH", function () { + return "http://localhost:" + srv.identity.primaryPort + "/object-state.sjs"; +}); + +var srv; + +function run_test() { + srv = createServer(); + var sjsDir = do_get_file("data/sjs/"); + srv.registerDirectory("/", sjsDir); + srv.registerContentType("sjs", "sjs"); + srv.start(-1); + + do_test_pending(); + + new HTTPTestLoader(PATH + "?state=initial", initialStart, initialStop); +} + +/** ****************** + * OBSERVER METHODS * + ********************/ + +/* + * In practice the current implementation will guarantee an exact ordering of + * all start and stop callbacks. However, in the interests of robustness, this + * test will pass given any valid ordering of callbacks. Any ordering of calls + * which obeys the partial ordering shown by this directed acyclic graph will be + * handled correctly: + * + * initialStart + * | + * V + * intermediateStart + * | + * V + * intermediateStop + * | \ + * | V + * | initialStop + * V + * triggerStart + * | + * V + * triggerStop + * + */ + +var initialStarted = false; +function initialStart(ch) { + dumpn("*** initialStart"); + + if (initialStarted) { + do_throw("initialStart: initialStarted is true?!?!"); + } + + initialStarted = true; + + new HTTPTestLoader( + PATH + "?state=intermediate", + intermediateStart, + intermediateStop + ); +} + +var initialStopped = false; +function initialStop(ch, status, data) { + dumpn("*** initialStop"); + + Assert.equal( + data + .map(function (v) { + return String.fromCharCode(v); + }) + .join(""), + "done" + ); + + Assert.equal(srv.getObjectState("object-state-test"), null); + + if (!initialStarted) { + do_throw("initialStop: initialStarted is false?!?!"); + } + if (initialStopped) { + do_throw("initialStop: initialStopped is true?!?!"); + } + if (!intermediateStarted) { + do_throw("initialStop: intermediateStarted is false?!?!"); + } + if (!intermediateStopped) { + do_throw("initialStop: intermediateStopped is false?!?!"); + } + + initialStopped = true; + + checkForFinish(); +} + +var intermediateStarted = false; +function intermediateStart(ch) { + dumpn("*** intermediateStart"); + + Assert.notEqual(srv.getObjectState("object-state-test"), null); + + if (!initialStarted) { + do_throw("intermediateStart: initialStarted is false?!?!"); + } + if (intermediateStarted) { + do_throw("intermediateStart: intermediateStarted is true?!?!"); + } + + intermediateStarted = true; +} + +var intermediateStopped = false; +function intermediateStop(ch, status, data) { + dumpn("*** intermediateStop"); + + Assert.equal( + data + .map(function (v) { + return String.fromCharCode(v); + }) + .join(""), + "intermediate" + ); + + Assert.notEqual(srv.getObjectState("object-state-test"), null); + + if (!initialStarted) { + do_throw("intermediateStop: initialStarted is false?!?!"); + } + if (!intermediateStarted) { + do_throw("intermediateStop: intermediateStarted is false?!?!"); + } + if (intermediateStopped) { + do_throw("intermediateStop: intermediateStopped is true?!?!"); + } + + intermediateStopped = true; + + new HTTPTestLoader(PATH + "?state=trigger", triggerStart, triggerStop); +} + +var triggerStarted = false; +function triggerStart(ch) { + dumpn("*** triggerStart"); + + if (!initialStarted) { + do_throw("triggerStart: initialStarted is false?!?!"); + } + if (!intermediateStarted) { + do_throw("triggerStart: intermediateStarted is false?!?!"); + } + if (!intermediateStopped) { + do_throw("triggerStart: intermediateStopped is false?!?!"); + } + if (triggerStarted) { + do_throw("triggerStart: triggerStarted is true?!?!"); + } + + triggerStarted = true; +} + +var triggerStopped = false; +function triggerStop(ch, status, data) { + dumpn("*** triggerStop"); + + Assert.equal( + data + .map(function (v) { + return String.fromCharCode(v); + }) + .join(""), + "trigger" + ); + + if (!initialStarted) { + do_throw("triggerStop: initialStarted is false?!?!"); + } + if (!intermediateStarted) { + do_throw("triggerStop: intermediateStarted is false?!?!"); + } + if (!intermediateStopped) { + do_throw("triggerStop: intermediateStopped is false?!?!"); + } + if (!triggerStarted) { + do_throw("triggerStop: triggerStarted is false?!?!"); + } + if (triggerStopped) { + do_throw("triggerStop: triggerStopped is false?!?!"); + } + + triggerStopped = true; + + checkForFinish(); +} + +var finished = false; +function checkForFinish() { + if (finished) { + try { + do_throw("uh-oh, how are we being finished twice?!?!"); + } finally { + // eslint-disable-next-line no-undef + quit(1); + } + } + + if (triggerStopped && initialStopped) { + finished = true; + try { + Assert.equal(srv.getObjectState("object-state-test"), null); + + if (!initialStarted) { + do_throw("checkForFinish: initialStarted is false?!?!"); + } + if (!intermediateStarted) { + do_throw("checkForFinish: intermediateStarted is false?!?!"); + } + if (!intermediateStopped) { + do_throw("checkForFinish: intermediateStopped is false?!?!"); + } + if (!triggerStarted) { + do_throw("checkForFinish: triggerStarted is false?!?!"); + } + } finally { + srv.stop(do_test_finished); + } + } +} + +/** ******************************* + * UTILITY OBSERVABLE URL LOADER * + *********************************/ + +/** Stream listener for the channels. */ +function HTTPTestLoader(path, start, stop) { + /** Path to load. */ + this._path = path; + + /** Array of bytes of data in body of response. */ + this._data = []; + + /** onStartRequest callback. */ + this._start = start; + + /** onStopRequest callback. */ + this._stop = stop; + + var channel = makeChannel(path); + channel.asyncOpen(this); +} +HTTPTestLoader.prototype = { + onStartRequest(request) { + dumpn("*** HTTPTestLoader.onStartRequest for " + this._path); + + var ch = request + .QueryInterface(Ci.nsIHttpChannel) + .QueryInterface(Ci.nsIHttpChannelInternal); + + try { + try { + this._start(ch); + } catch (e) { + do_throw(this._path + ": error in onStartRequest: " + e); + } + } catch (e) { + dumpn( + "!!! swallowing onStartRequest exception so onStopRequest is " + + "called..." + ); + } + }, + onDataAvailable(request, inputStream, offset, count) { + dumpn("*** HTTPTestLoader.onDataAvailable for " + this._path); + + Array.prototype.push.apply( + this._data, + makeBIS(inputStream).readByteArray(count) + ); + }, + onStopRequest(request, status) { + dumpn("*** HTTPTestLoader.onStopRequest for " + this._path); + + var ch = request + .QueryInterface(Ci.nsIHttpChannel) + .QueryInterface(Ci.nsIHttpChannelInternal); + + this._stop(ch, status, this._data); + }, + QueryInterface: ChromeUtils.generateQI([ + "nsIStreamListener", + "nsIRequestObserver", + ]), +}; |