Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* -*- 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.
*/
ChromeUtils.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() {
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() {
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() {
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",
]),
};