summaryrefslogtreecommitdiffstats
path: root/netwerk/test/httpserver/test/test_sjs_object_state.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/httpserver/test/test_sjs_object_state.js')
-rw-r--r--netwerk/test/httpserver/test/test_sjs_object_state.js305
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",
+ ]),
+};