Bug 396226 - Provide an API to asynchronously generate HTTP responses in httpd.js, and implement a state-storage system which can store object references to provide greater contextual information in handlers. NB: this push enables httpd.js debug output just in case something goes wrong, to be disabled as soon as it's clear nothing has -- expect the first Windows builds to finish next century sometime. r=sayrer
This commit is contained in:
Родитель
19bfe8dc73
Коммит
98d4570c74
|
@ -159,25 +159,39 @@ function OnRefTestLoad()
|
|||
createInstance(CI.nsIHttpServer);
|
||||
|
||||
try {
|
||||
if (gServer) {
|
||||
gServer.registerContentType("sjs", "sjs");
|
||||
// We want to try different ports in case the port we want
|
||||
// is being used.
|
||||
var tries = HTTP_SERVER_PORTS_TO_TRY;
|
||||
var succeeded = false;
|
||||
do {
|
||||
try {
|
||||
gServer.start(HTTP_SERVER_PORT);
|
||||
succeeded = true;
|
||||
} catch (ex) {
|
||||
gServer.stop();
|
||||
++HTTP_SERVER_PORT;
|
||||
if (--tries == 0) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
} while (!succeeded);
|
||||
if (gServer)
|
||||
StartHTTPServer();
|
||||
} catch (ex) {
|
||||
//gBrowser.loadURI('data:text/plain,' + ex);
|
||||
++gTestResults.Exception;
|
||||
dump("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n");
|
||||
DoneTests();
|
||||
}
|
||||
|
||||
StartTests();
|
||||
}
|
||||
|
||||
function StartHTTPServer()
|
||||
{
|
||||
gServer.registerContentType("sjs", "sjs");
|
||||
// We want to try different ports in case the port we want
|
||||
// is being used.
|
||||
var tries = HTTP_SERVER_PORTS_TO_TRY;
|
||||
do {
|
||||
try {
|
||||
gServer.start(HTTP_SERVER_PORT);
|
||||
return;
|
||||
} catch (ex) {
|
||||
++HTTP_SERVER_PORT;
|
||||
if (--tries == 0)
|
||||
throw ex;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
function StartTests()
|
||||
{
|
||||
try {
|
||||
// Need to read the manifest once we have the final HTTP_SERVER_PORT.
|
||||
ReadTopManifest(window.arguments[0]);
|
||||
BuildUseCounts();
|
||||
|
@ -525,9 +539,14 @@ function DoneTests()
|
|||
|
||||
dump("REFTEST INFO | Total canvas count = " + gRecycledCanvases.length + "\n");
|
||||
|
||||
function onStopped() {
|
||||
dump("REFTEST INFO | Quitting...\n");
|
||||
goQuitApplication();
|
||||
}
|
||||
if (gServer)
|
||||
gServer.stop();
|
||||
goQuitApplication();
|
||||
gServer.stop(onStopped);
|
||||
else
|
||||
onStopped();
|
||||
}
|
||||
|
||||
function setupZoom(contentRootElement) {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -44,6 +44,7 @@ interface nsIOutputStream;
|
|||
interface nsISimpleEnumerator;
|
||||
|
||||
interface nsIHttpServer;
|
||||
interface nsIHttpServerStoppedCallback;
|
||||
interface nsIHttpRequestHandler;
|
||||
interface nsIHttpRequestMetadata;
|
||||
interface nsIHttpResponse;
|
||||
|
@ -52,33 +53,41 @@ interface nsIHttpServerIdentity;
|
|||
/**
|
||||
* An interface which represents an HTTP server.
|
||||
*/
|
||||
[scriptable, uuid(DEEDE3E3-B813-4F3F-9C70-948E5700C410)]
|
||||
[scriptable, uuid(71ecfba5-15cf-457f-9642-4b33f6e9baf4)]
|
||||
interface nsIHttpServer : nsISupports
|
||||
{
|
||||
/**
|
||||
* Starts up this server, listening upon the given port. This method may
|
||||
* throw if the process does not have sufficient privileges to open a socket
|
||||
* for the given port, and it also throws when called upon a server which has
|
||||
* already been started.
|
||||
* Starts up this server, listening upon the given port.
|
||||
*
|
||||
* @param port
|
||||
* the port upon which listening should happen, or -1 if no specific port is
|
||||
* desired
|
||||
* @throws NS_ERROR_ALREADY_INITIALIZED
|
||||
* if this server is already started
|
||||
* @throws NS_ERROR_NOT_AVAILABLE
|
||||
* if the server is not started and cannot be started on the desired port
|
||||
* (perhaps because the port is already in use or because the process does
|
||||
* not have privileges to do so)
|
||||
* @note
|
||||
* Behavior is undefined if this method is called after stop() has been
|
||||
* called on this but before the provided callback function has been
|
||||
* called.
|
||||
*/
|
||||
void start(in long port);
|
||||
|
||||
/**
|
||||
* Shuts down this server if it is running; if it is not, this method is a
|
||||
* no-op.
|
||||
* Shuts down this server if it is running (including the period of time after
|
||||
* stop() has been called but before the provided callback has been called).
|
||||
*
|
||||
* This method will do its best to return after the socket in this
|
||||
* server has been closed and all pending requests have completed being
|
||||
* served, but this may or may not actually happen, since in some
|
||||
* implementations this may not actually be possible. Implementations which
|
||||
* can make this promise should make it explicit in implementation
|
||||
* documentation.
|
||||
* @param callback
|
||||
* an asynchronous callback used to notify the user when this server is
|
||||
* stopped and all pending requests have been fully served
|
||||
* @throws NS_ERROR_NULL_POINTER
|
||||
* if callback is null
|
||||
* @throws NS_ERROR_UNEXPECTED
|
||||
* if this server is not running
|
||||
*/
|
||||
void stop();
|
||||
void stop(in nsIHttpServerStoppedCallback callback);
|
||||
|
||||
/**
|
||||
* Associates the local file represented by the string file with all requests
|
||||
|
@ -213,6 +222,30 @@ interface nsIHttpServer : nsISupports
|
|||
* saved state.
|
||||
*/
|
||||
void setSharedState(in AString key, in AString value);
|
||||
|
||||
/**
|
||||
* Retrieves the object associated with the given key in this in
|
||||
* object-valued saved state. All keys are initially associated with null.
|
||||
*/
|
||||
nsISupports getObjectState(in AString key);
|
||||
|
||||
/**
|
||||
* Sets the object associated with the given key in this in object-valued
|
||||
* saved state. The value may be null.
|
||||
*/
|
||||
void setObjectState(in AString key, in nsISupports value);
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface through which a notification of the complete stopping (socket
|
||||
* closure, in-flight requests all fully served and responded to) of an HTTP
|
||||
* server may be received.
|
||||
*/
|
||||
[scriptable, function, uuid(925a6d33-9937-4c63-abe1-a1c56a986455)]
|
||||
interface nsIHttpServerStoppedCallback : nsISupports
|
||||
{
|
||||
/** Called when the corresponding server has been fully stopped. */
|
||||
void onStopped();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -450,7 +483,7 @@ interface nsIHttpRequestMetadata : nsIPropertyBag
|
|||
/**
|
||||
* Represents an HTTP response, as described in RFC 2616, section 6.
|
||||
*/
|
||||
[scriptable, uuid(a2aaaff7-03bd-43b6-b460-94671e288093)]
|
||||
[scriptable, uuid(4b023876-274e-41e8-83fb-e51f7aba43a6)]
|
||||
interface nsIHttpResponse : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -469,6 +502,9 @@ interface nsIHttpResponse : nsISupports
|
|||
* @throws NS_ERROR_INVALID_ARG
|
||||
* if httpVersion is not a valid HTTP version string, statusCode is greater
|
||||
* than 999, or description contains invalid characters
|
||||
* @throws NS_ERROR_NOT_AVAILABLE
|
||||
* if this response is being processed asynchronously and data has been
|
||||
* written to this response's body
|
||||
*/
|
||||
void setStatusLine(in string httpVersion,
|
||||
in unsigned short statusCode,
|
||||
|
@ -485,25 +521,73 @@ interface nsIHttpResponse : nsISupports
|
|||
* @param merge
|
||||
* when true, if the given header already exists in this, the values passed
|
||||
* to this function will be merged into the existing header, per RFC 2616
|
||||
* header semantics; when false, if the given header already exists in this,
|
||||
* it is overwritten with the passed-in values; if the header doesn't exist
|
||||
* in this, it is set regardless of the value of this parameter
|
||||
* header semantics (except for the Set-Cookie, WWW-Authenticate, and
|
||||
* Proxy-Authenticate headers, which will treat each such merged header as
|
||||
* an additional instance of the header, for real-world compatibility
|
||||
* reasons); when false, replaces any existing header of the given name (if
|
||||
* any exists) with a new header with the specified value
|
||||
* @throws NS_ERROR_INVALID_ARG
|
||||
* if name or value is not a valid header component
|
||||
* @throws NS_ERROR_NOT_AVAILABLE
|
||||
* if this response is being processed asynchronously and data has been
|
||||
* written to this response's body
|
||||
*/
|
||||
void setHeader(in string name, in string value, in boolean merge);
|
||||
|
||||
/**
|
||||
* A stream to which data appearing in the body of this response should be
|
||||
* written.
|
||||
* written. After this response has been designated as being processed
|
||||
* asynchronously, subsequent writes will be synchronously written to the
|
||||
* underlying transport. However, immediate write-through visible to the HTTP
|
||||
* client cannot be guaranteed, as intermediate buffers both in the server
|
||||
* socket and in the client may delay written data; be prepared for potential
|
||||
* delays.
|
||||
*
|
||||
* @note
|
||||
* As writes to the underlying transport are synchronous, care must be taken
|
||||
* not to block on these writes; it is even possible for deadlock to occur
|
||||
* in the case that the server and the client reside in the same process.
|
||||
* @throws NS_ERROR_NOT_AVAILABLE
|
||||
* if accessed after this response is fully constructed
|
||||
*/
|
||||
readonly attribute nsIOutputStream bodyOutputStream;
|
||||
|
||||
/**
|
||||
* Write a string to the response's output stream.
|
||||
* Writes a string to the response's output stream. This method is merely a
|
||||
* convenient shorthand for writing the same data to bodyOutputStream
|
||||
* directly.
|
||||
*
|
||||
* @note
|
||||
* This method is only guaranteed to work with ASCII data.
|
||||
* @throws NS_ERROR_NOT_AVAILABLE
|
||||
* if called after this response has been fully constructed
|
||||
*/
|
||||
void write(in string data);
|
||||
|
||||
/**
|
||||
* Signals that this response is being constructed asynchronously. Requests
|
||||
* are typically completely constructed during nsIHttpRequestHandler.handle;
|
||||
* however, responses which require significant resources (time, memory,
|
||||
* processing) to construct can be created and sent incrementally by calling
|
||||
* this method during the call to nsIHttpRequestHandler.handle. This method
|
||||
* only has this effect when called during nsIHttpRequestHandler.handle;
|
||||
* behavior is undefined if it is called at a later time. It may be called
|
||||
* multiple times with no ill effect, so long as each call occurs before
|
||||
* finish() is called.
|
||||
*
|
||||
* @throws NS_ERROR_UNEXPECTED
|
||||
* if not initially called within a nsIHttpRequestHandler.handle call or if
|
||||
* called after this response has been finished
|
||||
*/
|
||||
void processAsync();
|
||||
|
||||
/**
|
||||
* Signals that construction of this response is complete and that it may be
|
||||
* sent over the network to the client. This method may only be called after
|
||||
* processAsync() has been called. This method is idempotent.
|
||||
*
|
||||
* @throws NS_ERROR_UNEXPECTED
|
||||
* if processAsync() has not already been properly called
|
||||
*/
|
||||
void finish();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
function parseQueryString(str)
|
||||
{
|
||||
var paramArray = str.split("&");
|
||||
var regex = /^([^=]+)=(.*)$/;
|
||||
var params = {};
|
||||
for (var i = 0, sz = paramArray.length; i < sz; i++)
|
||||
{
|
||||
var match = regex.exec(paramArray[i]);
|
||||
if (!match)
|
||||
throw "Bad parameter in queryString! '" + paramArray[i] + "'";
|
||||
params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're relying somewhat dubiously on all data being sent as soon as it's
|
||||
* available at numerous levels (in Necko in the server-side part of the
|
||||
* connection, in the OS's outgoing socket buffer, in the OS's incoming socket
|
||||
* buffer, and in Necko in the client-side part of the connection), but to the
|
||||
* best of my knowledge there's no way to force data flow at all those levels,
|
||||
* so this is the best we can do.
|
||||
*/
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
/*
|
||||
* NB: A Content-Type header is *necessary* to avoid content-sniffing, which
|
||||
* will delay onStartRequest past the the point where the entire head of
|
||||
* the response has been received.
|
||||
*/
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
|
||||
var params = parseQueryString(request.queryString);
|
||||
|
||||
switch (params.state)
|
||||
{
|
||||
case "initial":
|
||||
response.processAsync();
|
||||
response.write("do");
|
||||
var state =
|
||||
{
|
||||
QueryInterface: function(iid)
|
||||
{
|
||||
if (iid.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
end: function()
|
||||
{
|
||||
response.write("ne");
|
||||
response.finish();
|
||||
}
|
||||
};
|
||||
state.wrappedJSObject = state;
|
||||
setObjectState("object-state-test", state);
|
||||
getObjectState("object-state-test", function(obj)
|
||||
{
|
||||
if (obj !== state)
|
||||
{
|
||||
response.write("FAIL bad state save");
|
||||
response.finish();
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case "intermediate":
|
||||
response.write("intermediate");
|
||||
break;
|
||||
|
||||
case "trigger":
|
||||
response.write("trigger");
|
||||
getObjectState("object-state-test", function(obj)
|
||||
{
|
||||
obj.wrappedJSObject.end();
|
||||
setObjectState("object-state-test", null);
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
response.setStatusLine(request.httpVersion, 500, "Unexpected State");
|
||||
response.write("Bad state: " + params.state);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -41,6 +41,8 @@ do_load_httpd_js();
|
|||
// if these tests fail, we'll want the debug output
|
||||
DEBUG = true;
|
||||
|
||||
const Timer = CC("@mozilla.org/timer;1", "nsITimer", "initWithCallback");
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new nsHttpServer instance. This function is intended to
|
||||
|
@ -193,11 +195,109 @@ function skipHeaders(iter)
|
|||
line = iter.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the exception e (which may be an XPConnect-created exception
|
||||
* object or a raw nsresult number) is the given nsresult.
|
||||
*
|
||||
* @param e : Exception or nsresult
|
||||
* the actual exception
|
||||
* @param code : nsresult
|
||||
* the expected exception
|
||||
*/
|
||||
function isException(e, code)
|
||||
{
|
||||
if (e !== code && e.result !== code)
|
||||
do_throw("unexpected error: " + e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending timers used by callLater, which must store them to avoid the timer
|
||||
* being canceled and destroyed. Stupid API...
|
||||
*/
|
||||
var __pendingTimers = [];
|
||||
|
||||
/**
|
||||
* Date.now() is not necessarily monotonically increasing (insert sob story
|
||||
* about times not being the right tool to use for measuring intervals of time,
|
||||
* robarnold can tell all), so be wary of error by erring by at least
|
||||
* __timerFuzz ms.
|
||||
*/
|
||||
const __timerFuzz = 15;
|
||||
|
||||
/**
|
||||
* Calls the given function at least the specified number of milliseconds later.
|
||||
* The callback will not undershoot the given time, but it might overshoot --
|
||||
* don't expect precision!
|
||||
*
|
||||
* @param milliseconds : uint
|
||||
* the number of milliseconds to delay
|
||||
* @param callback : function() : void
|
||||
* the function to call
|
||||
*/
|
||||
function callLater(msecs, callback)
|
||||
{
|
||||
do_check_true(msecs >= 0);
|
||||
|
||||
var start = Date.now();
|
||||
|
||||
function checkTime()
|
||||
{
|
||||
var index = __pendingTimers.indexOf(timer);
|
||||
do_check_true(index >= 0); // sanity
|
||||
__pendingTimers.splice(index, 1);
|
||||
do_check_eq(__pendingTimers.indexOf(timer), -1);
|
||||
|
||||
// The current nsITimer implementation can undershoot, but even if it
|
||||
// couldn't, paranoia is probably a virtue here given the potential for
|
||||
// random orange on tinderboxen.
|
||||
var end = Date.now();
|
||||
var elapsed = end - start;
|
||||
if (elapsed >= msecs)
|
||||
{
|
||||
dumpn("*** TIMER FIRE " + elapsed + "ms (" + msecs + "ms requested)");
|
||||
try
|
||||
{
|
||||
callback();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
do_throw("exception thrown from callLater callback: " + e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Timer undershot, retry with a little overshoot to try to avoid more
|
||||
// undershoots.
|
||||
var newDelay = msecs - elapsed;
|
||||
dumpn("*** TIMER UNDERSHOOT " + newDelay + "ms " +
|
||||
"(" + msecs + "ms requested, delaying)");
|
||||
|
||||
callLater(newDelay, callback);
|
||||
}
|
||||
|
||||
var timer =
|
||||
new Timer(checkTime, msecs + __timerFuzz, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
__pendingTimers.push(timer);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************
|
||||
* SIMPLE SUPPORT FOR LOADING/TESTING A SERIES OF URLS *
|
||||
*******************************************************/
|
||||
|
||||
/**
|
||||
* Create a completion callback which will stop the given server and end the
|
||||
* test, assuming nothing else remains to be done at that point.
|
||||
*/
|
||||
function testComplete(srv)
|
||||
{
|
||||
return function complete()
|
||||
{
|
||||
do_test_pending();
|
||||
srv.stop(function quit() { do_test_finished(); });
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a path to load from the tested HTTP server, along with actions to
|
||||
* take before, during, and after loading the associated page.
|
||||
|
@ -244,7 +344,14 @@ function runHttpTests(testArray, done)
|
|||
{
|
||||
if (++testIndex == testArray.length)
|
||||
{
|
||||
done();
|
||||
try
|
||||
{
|
||||
done();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
do_throw("error running test-completion callback: " + e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -397,7 +504,14 @@ function runRawTests(testArray, done)
|
|||
if (++testIndex == testArray.length)
|
||||
{
|
||||
do_test_finished();
|
||||
done();
|
||||
try
|
||||
{
|
||||
done();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
do_throw("error running test-completion callback: " + e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// basic functionality test, from the client programmer's POV
|
||||
/*
|
||||
* Basic functionality test, from the client programmer's POV.
|
||||
*/
|
||||
|
||||
var tests =
|
||||
[
|
||||
|
@ -65,7 +67,7 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ function run_test()
|
|||
srv.registerPathHandler("/content-length", contentLength);
|
||||
srv.start(PORT);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
const REQUEST_DATA = "12345678901234567";
|
||||
|
|
|
@ -77,7 +77,7 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
function start_normal(ch, cx)
|
||||
|
|
|
@ -63,7 +63,7 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,14 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); destroyTestDirectory(); });
|
||||
function done()
|
||||
{
|
||||
do_test_pending();
|
||||
destroyTestDirectory();
|
||||
srv.stop(function() { do_test_finished(); });
|
||||
}
|
||||
|
||||
runHttpTests(tests, done);
|
||||
}
|
||||
|
||||
function createTestDirectory()
|
||||
|
|
|
@ -57,7 +57,7 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
// TEST DATA
|
||||
|
|
|
@ -60,7 +60,7 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -49,12 +49,7 @@ function run_test()
|
|||
srv.registerPathHandler("/path-handler", pathHandler);
|
||||
srv.start(PORT);
|
||||
|
||||
function done()
|
||||
{
|
||||
srv.stop();
|
||||
}
|
||||
|
||||
runHttpTests(tests, done);
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,11 +42,15 @@
|
|||
*/
|
||||
|
||||
const PORT = 4444;
|
||||
const FAKE_PORT_ONE = 8888;
|
||||
const FAKE_PORT_TWO = 8889;
|
||||
|
||||
var srv;
|
||||
var srv, id;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
dumpn("*** run_test");
|
||||
|
||||
srv = createServer();
|
||||
|
||||
srv.registerPathHandler("/http/1.0-request", http10Request);
|
||||
|
@ -55,12 +59,9 @@ function run_test()
|
|||
http11goodHostWackyPort);
|
||||
srv.registerPathHandler("/http/1.1-ip-host", http11ipHost);
|
||||
|
||||
const FAKE_PORT_ONE = 8888;
|
||||
const FAKE_PORT_TWO = 8889;
|
||||
|
||||
srv.start(FAKE_PORT_ONE);
|
||||
|
||||
var id = srv.identity;
|
||||
id = srv.identity;
|
||||
|
||||
// The default location is http://localhost:PORT, where PORT is whatever you
|
||||
// provided when you started the server. http://127.0.0.1:PORT is also part
|
||||
|
@ -108,7 +109,26 @@ function run_test()
|
|||
// Okay, now that we've exercised that behavior, shut down the server and
|
||||
// restart it on the correct port, to exercise port-changing behaviors at
|
||||
// server start and stop.
|
||||
srv.stop();
|
||||
do_test_pending();
|
||||
srv.stop(function()
|
||||
{
|
||||
try
|
||||
{
|
||||
do_test_pending();
|
||||
run_test_2();
|
||||
}
|
||||
finally
|
||||
{
|
||||
do_test_finished();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_2()
|
||||
{
|
||||
dumpn("*** run_test_2");
|
||||
|
||||
do_test_finished();
|
||||
|
||||
// Our primary location is gone because it was dependent on the port on which
|
||||
// the server was running.
|
||||
|
@ -152,7 +172,26 @@ function run_test()
|
|||
do_check_false(id.has("http", "localhost", FAKE_PORT_ONE));
|
||||
do_check_false(id.has("http", "127.0.0.1", FAKE_PORT_ONE));
|
||||
|
||||
srv.stop();
|
||||
do_test_pending();
|
||||
srv.stop(function()
|
||||
{
|
||||
try
|
||||
{
|
||||
do_test_pending();
|
||||
run_test_3();
|
||||
}
|
||||
finally
|
||||
{
|
||||
do_test_finished();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_3()
|
||||
{
|
||||
dumpn("*** run_test_3");
|
||||
|
||||
do_test_finished();
|
||||
|
||||
// Only the default added location disappears; any others stay around,
|
||||
// possibly as the primary location. We may have removed the default primary
|
||||
|
@ -201,7 +240,7 @@ function run_test()
|
|||
|
||||
// Okay, finally done with identity testing. Our primary location is the one
|
||||
// we want it to be, so we're off!
|
||||
runRawTests(tests, function() { srv.stop(); });
|
||||
runRawTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,381 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is httpd.js code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Tests for correct behavior of asynchronous responses.
|
||||
*/
|
||||
|
||||
const PORT = 4444;
|
||||
const PREPATH = "http://localhost:" + PORT;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
var srv = createServer();
|
||||
for (var path in handlers)
|
||||
srv.registerPathHandler(path, handlers[path]);
|
||||
srv.start(PORT);
|
||||
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
* BEGIN TESTS *
|
||||
***************/
|
||||
|
||||
var test;
|
||||
var tests = [];
|
||||
var handlers = {};
|
||||
|
||||
function handleSync(request, response)
|
||||
{
|
||||
response.setStatusLine(request.httpVersion, 500, "handleSync fail");
|
||||
|
||||
try
|
||||
{
|
||||
response.finish();
|
||||
do_throw("finish called on sync response");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
response.setStatusLine(request.httpVersion, 200, "handleSync pass");
|
||||
}
|
||||
handlers["/handleSync"] = handleSync;
|
||||
|
||||
function start_handleSync(ch, cx)
|
||||
{
|
||||
do_check_eq(ch.responseStatus, 200);
|
||||
do_check_eq(ch.responseStatusText, "handleSync pass");
|
||||
}
|
||||
|
||||
test = new Test(PREPATH + "/handleSync",
|
||||
null, start_handleSync, null),
|
||||
tests.push(test);
|
||||
|
||||
|
||||
function handleAsync1(request, response)
|
||||
{
|
||||
response.setStatusLine(request.httpVersion, 500, "Old status line!");
|
||||
response.setHeader("X-Foo", "old value", false);
|
||||
|
||||
response.processAsync();
|
||||
|
||||
response.setStatusLine(request.httpVersion, 200, "New status line!");
|
||||
response.setHeader("X-Foo", "new value", false);
|
||||
|
||||
response.finish();
|
||||
|
||||
try
|
||||
{
|
||||
response.setStatusLine(request.httpVersion, 500, "Too late!");
|
||||
do_throw("late setStatusLine didn't throw");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
response.setHeader("X-Foo", "late value", false);
|
||||
do_throw("late setHeader didn't throw");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
response.bodyOutputStream;
|
||||
do_throw("late bodyOutputStream get didn't throw");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
response.write("fugly");
|
||||
do_throw("late write() didn't throw");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
}
|
||||
handlers["/handleAsync1"] = handleAsync1;
|
||||
|
||||
function start_handleAsync1(ch, cx)
|
||||
{
|
||||
do_check_eq(ch.responseStatus, 200);
|
||||
do_check_eq(ch.responseStatusText, "New status line!");
|
||||
do_check_eq(ch.getResponseHeader("X-Foo"), "new value");
|
||||
}
|
||||
|
||||
function stop_handleAsync1(ch, cx, status, data)
|
||||
{
|
||||
do_check_eq(data.length, 0);
|
||||
}
|
||||
|
||||
test = new Test(PREPATH + "/handleAsync1",
|
||||
null, start_handleAsync1, stop_handleAsync1),
|
||||
tests.push(test);
|
||||
|
||||
|
||||
const startToHeaderDelay = 500;
|
||||
const startToFinishedDelay = 750;
|
||||
|
||||
function handleAsync2(request, response)
|
||||
{
|
||||
response.processAsync();
|
||||
|
||||
response.setStatusLine(request.httpVersion, 200, "Status line");
|
||||
response.setHeader("X-Custom-Header", "value", false);
|
||||
|
||||
callLater(startToHeaderDelay, function()
|
||||
{
|
||||
var body = "BO";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
|
||||
try
|
||||
{
|
||||
response.setStatusLine(request.httpVersion, 500, "after body write");
|
||||
do_throw("setStatusLine succeeded");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
response.setHeader("X-Custom-Header", "new 1", false);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
callLater(startToFinishedDelay - startToHeaderDelay, function()
|
||||
{
|
||||
var body = "DY";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
|
||||
response.finish();
|
||||
response.finish(); // idempotency
|
||||
|
||||
try
|
||||
{
|
||||
response.setStatusLine(request.httpVersion, 500, "after finish");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
response.setHeader("X-Custom-Header", "new 2", false);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
response.write("EVIL");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
handlers["/handleAsync2"] = handleAsync2;
|
||||
|
||||
var startTime_handleAsync2;
|
||||
|
||||
function init_handleAsync2(ch)
|
||||
{
|
||||
var now = startTime_handleAsync2 = Date.now();
|
||||
dumpn("*** init_HandleAsync2: start time " + now);
|
||||
}
|
||||
|
||||
function start_handleAsync2(ch, cx)
|
||||
{
|
||||
var now = Date.now();
|
||||
dumpn("*** start_handleAsync2: onStartRequest time " + now + ", " +
|
||||
(now - startTime_handleAsync2) + "ms after start time");
|
||||
do_check_true(now >= startTime_handleAsync2 + startToHeaderDelay);
|
||||
|
||||
do_check_eq(ch.responseStatus, 200);
|
||||
do_check_eq(ch.responseStatusText, "Status line");
|
||||
do_check_eq(ch.getResponseHeader("X-Custom-Header"), "value");
|
||||
}
|
||||
|
||||
function stop_handleAsync2(ch, cx, status, data)
|
||||
{
|
||||
var now = Date.now();
|
||||
dumpn("*** stop_handleAsync2: onStopRequest time " + now + ", " +
|
||||
(now - startTime_handleAsync2) + "ms after header time");
|
||||
do_check_true(now >= startTime_handleAsync2 + startToFinishedDelay);
|
||||
|
||||
do_check_eq(String.fromCharCode.apply(null, data), "BODY");
|
||||
}
|
||||
|
||||
test = new Test(PREPATH + "/handleAsync2",
|
||||
init_handleAsync2, start_handleAsync2, stop_handleAsync2);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
const ASYNC_ERROR_BODY = "hi, I'm a body!";
|
||||
|
||||
function handleAsyncError(request, response)
|
||||
{
|
||||
response.setStatusLine(request.httpVersion, 200, "Async Error");
|
||||
response.setHeader("X-Foo", "header value", false);
|
||||
|
||||
response.processAsync();
|
||||
|
||||
response.write(ASYNC_ERROR_BODY, ASYNC_ERROR_BODY.length);
|
||||
|
||||
// No turning back now -- except if there's an error!
|
||||
throw "Monkey wrench!";
|
||||
}
|
||||
handlers["/handleAsyncError"] = handleAsyncError;
|
||||
|
||||
function start_handleAsyncError(ch, cx)
|
||||
{
|
||||
do_check_eq(ch.responseStatus, 200);
|
||||
do_check_eq(ch.responseStatusText, "Async Error");
|
||||
do_check_eq(ch.getResponseHeader("X-Foo"), "header value");
|
||||
}
|
||||
|
||||
function stop_handleAsyncError(ch, cx, status, data)
|
||||
{
|
||||
// Lies! But not really!
|
||||
do_check_true(ch.requestSucceeded);
|
||||
|
||||
// There's no way server APIs will ever guarantee exactly what data will show
|
||||
// up here, but they will guarantee sending a (not necessarily strict) prefix
|
||||
// of what was written.
|
||||
do_check_true(data.length <= ASYNC_ERROR_BODY.length);
|
||||
for (var i = 0, sz = data.length; i < sz; i++)
|
||||
do_check_eq(data[i] == ASYNC_ERROR_BODY.charCodeAt(i));
|
||||
}
|
||||
|
||||
test = new Test(PREPATH + "/handleAsyncError",
|
||||
null, start_handleAsyncError, stop_handleAsyncError);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
/*
|
||||
* Tests that accessing output stream *before* calling processAsync() works
|
||||
* correctly, sending written data immediately as it is written, not buffering
|
||||
* until finish() is called -- which for this much data would mean we would all
|
||||
* but certainly deadlock, since we're trying to read/write all this data in one
|
||||
* process on a single thread.
|
||||
*/
|
||||
function handleAsyncOrdering(request, response)
|
||||
{
|
||||
var out = new BinaryOutputStream(response.bodyOutputStream);
|
||||
|
||||
var data = [];
|
||||
for (var i = 0; i < 65536; i++)
|
||||
data[i] = 0;
|
||||
var count = 20;
|
||||
|
||||
var writeData =
|
||||
{
|
||||
run: function()
|
||||
{
|
||||
if (count-- === 0)
|
||||
{
|
||||
response.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
out.writeByteArray(data, data.length);
|
||||
step();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
try
|
||||
{
|
||||
do_throw("error writing data: " + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
response.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
function step()
|
||||
{
|
||||
// Use gThreadManager here because it's expedient, *not* because it's
|
||||
// intended for public use! If you do this in client code, expect me to
|
||||
// knowingly break your code by changing the variable name. :-P
|
||||
gThreadManager.currentThread
|
||||
.dispatch(writeData, Ci.nsIThreadManager.DISPATCH_NORMAL);
|
||||
}
|
||||
step();
|
||||
response.processAsync();
|
||||
}
|
||||
handlers["/handleAsyncOrdering"] = handleAsyncOrdering;
|
||||
|
||||
function stop_handleAsyncOrdering(ch, cx, status, data)
|
||||
{
|
||||
do_check_eq(data.length, 20 * 65536);
|
||||
do_check_true(data.every(function(v) { return v === 0; }));
|
||||
}
|
||||
|
||||
test = new Test(PREPATH + "/handleAsyncOrdering",
|
||||
null, null, stop_handleAsyncOrdering);
|
||||
tests.push(test);
|
||||
|
|
@ -69,7 +69,7 @@ function check200(ch)
|
|||
do_check_eq(ch.responseStatusText, "OK");
|
||||
}
|
||||
|
||||
function checkFile(ch)
|
||||
function checkFile(ch, cx, status, data)
|
||||
{
|
||||
do_check_eq(ch.responseStatus, 200);
|
||||
do_check_true(ch.requestSucceeded);
|
||||
|
@ -78,6 +78,8 @@ function checkFile(ch)
|
|||
actualFile.append("test_registerdirectory.js");
|
||||
do_check_eq(ch.getResponseHeader("Content-Length"),
|
||||
actualFile.fileSize.toString());
|
||||
do_check_eq(data.map(function(v) String.fromCharCode(v)).join(""),
|
||||
fileContents(actualFile));
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,8 +103,8 @@ test = new Test(BASE + "/test_registerdirectory.js",
|
|||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
checkFile,
|
||||
null);
|
||||
null,
|
||||
checkFile);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
|
@ -166,8 +168,8 @@ test = new Test(BASE + "/test_registerdirectory.js",
|
|||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
checkFile,
|
||||
null);
|
||||
null,
|
||||
checkFile);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
|
@ -256,8 +258,8 @@ test = new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js
|
|||
srv.registerDirectory("/foo/test_registerdirectory.js/",
|
||||
serverBasePath);
|
||||
},
|
||||
checkFile,
|
||||
null);
|
||||
null,
|
||||
checkFile);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
|
@ -266,7 +268,7 @@ tests.push(test);
|
|||
************************************/
|
||||
|
||||
test = new Test(BASE + "/foo/test_registerdirectory.js",
|
||||
nocache, checkFile, null);
|
||||
nocache, null, checkFile);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
|
@ -290,7 +292,7 @@ tests.push(test);
|
|||
**************************************/
|
||||
|
||||
test = new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
nocache, checkFile, null);
|
||||
nocache, null, checkFile);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
|
@ -321,7 +323,7 @@ function run_test()
|
|||
srv = createServer();
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,12 +40,6 @@
|
|||
|
||||
const BASE = "http://localhost:4444";
|
||||
|
||||
function isException(e, code)
|
||||
{
|
||||
if (e !== code && e.result !== code)
|
||||
do_throw("unexpected error: " + e);
|
||||
}
|
||||
|
||||
var file = do_get_file("test_registerfile.js");
|
||||
|
||||
function onStart(ch, cx)
|
||||
|
@ -78,5 +72,5 @@ function run_test()
|
|||
srv.registerFile("/foo", file);
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests([test], function() { srv.stop(); });
|
||||
runHttpTests([test], testComplete(srv));
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ function run_test()
|
|||
veryLongRequestLine);
|
||||
srv.start(PORT);
|
||||
|
||||
runRawTests(tests, function() { srv.stop(); });
|
||||
runRawTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,16 +54,16 @@ function run_test()
|
|||
srv.registerPathHandler("/writeInt", writeInt);
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
// TEST DATA
|
||||
|
||||
function succeeded(ch, cx, status)
|
||||
function succeeded(ch, cx, status, data)
|
||||
{
|
||||
|
||||
do_check_true(Components.isSuccessCode(status));
|
||||
do_check_eq(data.map(function(v) String.fromCharCode(v)).join(""), "1234");
|
||||
}
|
||||
|
||||
function check_1234(ch, cx)
|
||||
|
@ -71,7 +71,6 @@ function check_1234(ch, cx)
|
|||
do_check_eq(ch.getResponseHeader("Content-Length"), "4");
|
||||
}
|
||||
|
||||
|
||||
// PATH HANDLERS
|
||||
|
||||
function writeString(metadata, response)
|
||||
|
|
|
@ -48,7 +48,7 @@ function run_test()
|
|||
srv.setIndexHandler(myIndexHandler);
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ function run_test()
|
|||
|
||||
srv.start(4444);
|
||||
|
||||
runHttpTests(tests, function() { srv.stop() });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,12 +50,6 @@ var tests = [];
|
|||
* UTILITY FUNCTIONS *
|
||||
*********************/
|
||||
|
||||
function isException(e, code)
|
||||
{
|
||||
if (e !== code && e.result !== code)
|
||||
do_throw("unexpected error: " + e);
|
||||
}
|
||||
|
||||
function bytesToString(bytes)
|
||||
{
|
||||
return bytes.map(function(v) { return String.fromCharCode(v); }).join("");
|
||||
|
@ -241,5 +235,5 @@ function run_test()
|
|||
// test that doesn't care about throwing or not.
|
||||
|
||||
srv.start(4444);
|
||||
runHttpTests(tests, function() { srv.stop(); });
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http: *www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is httpd.js code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Tests that the object-state-preservation mechanism works correctly.
|
||||
*/
|
||||
|
||||
const PORT = 4444;
|
||||
|
||||
const PATH = "http://localhost:" + PORT + "/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(PORT);
|
||||
|
||||
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, cx)
|
||||
{
|
||||
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, cx, status, data)
|
||||
{
|
||||
dumpn("*** initialStop");
|
||||
|
||||
do_check_eq(data.map(function(v) { return String.fromCharCode(v); }).join(""),
|
||||
"done");
|
||||
|
||||
do_check_eq(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, cx)
|
||||
{
|
||||
dumpn("*** intermediateStart");
|
||||
|
||||
do_check_neq(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, cx, status, data)
|
||||
{
|
||||
dumpn("*** intermediateStop");
|
||||
|
||||
do_check_eq(data.map(function(v) { return String.fromCharCode(v); }).join(""),
|
||||
"intermediate");
|
||||
|
||||
do_check_neq(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, cx)
|
||||
{
|
||||
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, cx, status, data)
|
||||
{
|
||||
dumpn("*** triggerStop");
|
||||
|
||||
do_check_eq(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
|
||||
{
|
||||
quit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (triggerStopped && initialStopped)
|
||||
{
|
||||
finished = true;
|
||||
try
|
||||
{
|
||||
do_check_eq(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, null);
|
||||
}
|
||||
HTTPTestLoader.prototype =
|
||||
{
|
||||
onStartRequest: function(request, cx)
|
||||
{
|
||||
dumpn("*** HTTPTestLoader.onStartRequest for " + this._path);
|
||||
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
this._start(ch, cx);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
do_throw(this._path + ": error in onStartRequest: " + e);
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
dumpn("!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called...");
|
||||
}
|
||||
},
|
||||
onDataAvailable: function(request, cx, inputStream, offset, count)
|
||||
{
|
||||
dumpn("*** HTTPTestLoader.onDataAvailable for " + this._path);
|
||||
|
||||
Array.prototype.push.apply(this._data,
|
||||
makeBIS(inputStream).readByteArray(count));
|
||||
},
|
||||
onStopRequest: function(request, cx, status)
|
||||
{
|
||||
dumpn("*** HTTPTestLoader.onStopRequest for " + this._path);
|
||||
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
this._stop(ch, cx, status, this._data);
|
||||
},
|
||||
QueryInterface: function(aIID)
|
||||
{
|
||||
dumpn("*** QueryInterface: " + aIID);
|
||||
|
||||
if (aIID.equals(Ci.nsIStreamListener) ||
|
||||
aIID.equals(Ci.nsIRequestObserver) ||
|
||||
aIID.equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
|
@ -61,7 +61,8 @@ function run_test()
|
|||
"");
|
||||
do_check_eq(srv.getState("/state2.sjs", "private-value"),
|
||||
"newPrivate5");
|
||||
srv.stop();
|
||||
do_test_pending();
|
||||
srv.stop(function() { do_test_finished(); });
|
||||
}
|
||||
|
||||
runHttpTests(tests, done);
|
||||
|
|
|
@ -55,7 +55,8 @@ function run_test()
|
|||
|
||||
function done()
|
||||
{
|
||||
srv.stop();
|
||||
do_test_pending();
|
||||
srv.stop(function() { do_test_finished(); });
|
||||
do_check_eq(gStartCount, TEST_RUNS);
|
||||
do_check_true(lastPassed);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is httpd.js code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Tests for correct behavior of the server start() and stop() methods.
|
||||
*/
|
||||
|
||||
const PORT = 4444;
|
||||
const PREPATH = "http://localhost:" + PORT;
|
||||
|
||||
var srv, srv2;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
dumpn("*** run_test");
|
||||
|
||||
srv = createServer();
|
||||
srv.start(PORT);
|
||||
|
||||
try
|
||||
{
|
||||
srv.start(PORT);
|
||||
do_throw("starting a started server");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_ALREADY_INITIALIZED);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
srv.stop();
|
||||
do_throw("missing argument to stop");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NULL_POINTER);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
srv.stop(null);
|
||||
do_throw("null argument to stop");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NULL_POINTER);
|
||||
}
|
||||
|
||||
do_test_pending();
|
||||
srv.stop(function()
|
||||
{
|
||||
try
|
||||
{
|
||||
do_test_pending();
|
||||
run_test_2();
|
||||
}
|
||||
finally
|
||||
{
|
||||
do_test_finished();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_2()
|
||||
{
|
||||
dumpn("*** run_test_2");
|
||||
|
||||
do_test_finished();
|
||||
|
||||
srv.start(PORT);
|
||||
srv2 = createServer();
|
||||
|
||||
try
|
||||
{
|
||||
srv2.start(PORT);
|
||||
do_throw("two servers on one port?");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
do_test_pending();
|
||||
try
|
||||
{
|
||||
srv.stop({onStopped: function()
|
||||
{
|
||||
try
|
||||
{
|
||||
do_test_pending();
|
||||
run_test_3();
|
||||
}
|
||||
finally
|
||||
{
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
do_throw("error stopping with an object: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
function run_test_3()
|
||||
{
|
||||
dumpn("*** run_test_3");
|
||||
|
||||
do_test_finished();
|
||||
|
||||
srv.registerPathHandler("/handle", handle);
|
||||
srv.start(PORT);
|
||||
|
||||
// Don't rely on the exact (but implementation-constant) sequence of events
|
||||
// as it currently exists by making either run_test_4 or serverStopped handle
|
||||
// the final shutdown.
|
||||
do_test_pending();
|
||||
|
||||
runHttpTests([new Test(PREPATH + "/handle")], run_test_4);
|
||||
}
|
||||
|
||||
var testsComplete = false;
|
||||
|
||||
function run_test_4()
|
||||
{
|
||||
dumpn("*** run_test_4");
|
||||
|
||||
testsComplete = true;
|
||||
if (stopped)
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
|
||||
const INTERVAL = 500;
|
||||
|
||||
function handle(request, response)
|
||||
{
|
||||
response.processAsync();
|
||||
|
||||
dumpn("*** stopping server...");
|
||||
srv.stop(serverStopped);
|
||||
|
||||
callLater(INTERVAL, function()
|
||||
{
|
||||
do_check_false(stopped);
|
||||
|
||||
callLater(INTERVAL, function()
|
||||
{
|
||||
do_check_false(stopped);
|
||||
response.finish();
|
||||
|
||||
try
|
||||
{
|
||||
response.processAsync();
|
||||
do_throw("late processAsync didn't throw?");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
isException(e, Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var stopped = false;
|
||||
function serverStopped()
|
||||
{
|
||||
dumpn("*** server really, fully shut down now");
|
||||
stopped = true;
|
||||
if (testsComplete)
|
||||
do_test_finished();
|
||||
}
|
|
@ -236,8 +236,9 @@ var listener = {
|
|||
|
||||
current_test++;
|
||||
tests[current_test]();
|
||||
} else {
|
||||
httpserv.stop();
|
||||
} else {
|
||||
do_test_pending();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
|
|
|
@ -13,7 +13,8 @@ var listener = {
|
|||
},
|
||||
|
||||
onDownloadComplete: function(downloader, request, ctxt, status, file) {
|
||||
server.stop();
|
||||
do_test_pending();
|
||||
server.stop(do_test_finished);
|
||||
|
||||
if (!file)
|
||||
do_throw("Download failed");
|
||||
|
|
|
@ -11,8 +11,7 @@ TestListener.prototype.onStopRequest = function(request, context, status) {
|
|||
var channel = request.QueryInterface(Components.interfaces.nsIHttpChannel);
|
||||
do_check_eq(channel.responseStatus, 304);
|
||||
|
||||
server.stop();
|
||||
do_test_finished();
|
||||
server.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
|
|
@ -28,8 +28,7 @@ function after_channel_closed() {
|
|||
try {
|
||||
change_content_type();
|
||||
} finally {
|
||||
server.stop();
|
||||
do_test_finished();
|
||||
server.stop(do_test_finished);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@ TestListener.prototype.onStartRequest = function(request, context) {
|
|||
}
|
||||
|
||||
TestListener.prototype.onStopRequest = function(request, context, status) {
|
||||
httpserv.stop();
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
|
|
@ -63,8 +63,7 @@ function do_test() {
|
|||
}
|
||||
else {
|
||||
do_check_eq(handlers_called, "nocache,partial,cached");
|
||||
httpserv.stop();
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,8 +207,7 @@ var gTests = [
|
|||
function run_next_test()
|
||||
{
|
||||
if (gTests.length == 0) {
|
||||
httpserver.stop();
|
||||
do_test_finished();
|
||||
httpserver.stop(do_test_finished);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ function run_test_iteration(index) {
|
|||
sniffing_enabled = false;
|
||||
index = listener._iteration = 1;
|
||||
} else {
|
||||
httpserv.stop();
|
||||
do_test_pending();
|
||||
httpserv.stop(do_test_finished);
|
||||
return; // we're done
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,10 +32,12 @@ var listener = {
|
|||
},
|
||||
|
||||
onStopRequest: function test_onStopR(request, ctx, status) {
|
||||
if (this._iteration == 1)
|
||||
if (this._iteration == 1) {
|
||||
run_test_continued();
|
||||
else
|
||||
httpserv.stop();
|
||||
} else {
|
||||
do_test_pending();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
do_test_finished();
|
||||
},
|
||||
|
||||
|
|
|
@ -81,10 +81,12 @@ var listener = {
|
|||
},
|
||||
|
||||
onStopRequest: function test_onStopR(request, ctx, status) {
|
||||
if (this._iteration <= 2)
|
||||
if (this._iteration <= 2) {
|
||||
run_test_continued();
|
||||
else
|
||||
httpserv.stop();
|
||||
} else {
|
||||
do_test_pending();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
do_test_finished();
|
||||
},
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ function continue_test() {
|
|||
}
|
||||
|
||||
function finish_test(request, data, ctx) {
|
||||
httpserver.stop();
|
||||
do_test_pending();
|
||||
httpserver.stop(do_test_finished);
|
||||
do_check_eq(request.status, 0);
|
||||
do_check_eq(data.length, responseBody.length);
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
|
|
|
@ -33,8 +33,7 @@ var listener = {
|
|||
},
|
||||
|
||||
onStopRequest: function test_onStopR(request, ctx, status) {
|
||||
httpserv.stop();
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -131,7 +131,8 @@ function makeListener(headerIdx, bodyIdx) {
|
|||
}
|
||||
|
||||
if (bodyIdx == bodyList.length) {
|
||||
httpserv.stop();
|
||||
do_test_pending();
|
||||
httpserv.stop(do_test_finished);
|
||||
} else {
|
||||
doTest(headerIdx, bodyIdx);
|
||||
}
|
||||
|
|
|
@ -36,9 +36,8 @@ function firstTimeThrough(request, buffer)
|
|||
|
||||
function finish_test(request, buffer)
|
||||
{
|
||||
httpserver.stop();
|
||||
do_check_eq(buffer, responseBody);
|
||||
do_test_finished();
|
||||
httpserver.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
|
|
|
@ -132,8 +132,7 @@ function test_ftp_channel() {
|
|||
}
|
||||
|
||||
function end() {
|
||||
httpserv.stop();
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
|
|
@ -78,6 +78,7 @@ function run_test() {
|
|||
var entityID;
|
||||
|
||||
function get_entity_id(request, data, ctx) {
|
||||
dump("*** get_entity_id()\n");
|
||||
do_check_true(request instanceof Ci.nsIResumableChannel,
|
||||
"must be a resumable channel");
|
||||
entityID = request.entityID;
|
||||
|
@ -90,6 +91,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_resume(request, data, ctx) {
|
||||
dump("*** try_resume()\n");
|
||||
do_check_eq(request.status, NS_ERROR_NOT_RESUMABLE);
|
||||
|
||||
// Try a successful resume
|
||||
|
@ -99,6 +101,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_resume_zero(request, data, ctx) {
|
||||
dump("*** try_resume_zero()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(data, rangeBody.substring(1));
|
||||
|
||||
|
@ -110,6 +113,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_no_range(request, data, ctx) {
|
||||
dump("*** try_no_range()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(request.status, NS_ERROR_NOT_RESUMABLE);
|
||||
|
||||
|
@ -121,6 +125,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_bytes_range(request, data, ctx) {
|
||||
dump("*** try_bytes_range()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(data, rangeBody);
|
||||
|
||||
|
@ -132,6 +137,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_foo_bar_range(request, data, ctx) {
|
||||
dump("*** try_foo_bar_range()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(request.status, NS_ERROR_NOT_RESUMABLE);
|
||||
|
||||
|
@ -143,6 +149,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_foobar_range(request, data, ctx) {
|
||||
dump("*** try_foobar_range()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(request.status, NS_ERROR_NOT_RESUMABLE);
|
||||
|
||||
|
@ -154,6 +161,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_bytes_foobar_range(request, data, ctx) {
|
||||
dump("*** try_bytes_foobar_range()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(data, rangeBody);
|
||||
|
||||
|
@ -165,6 +173,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_bytesfoo_bar_range(request, data, ctx) {
|
||||
dump("*** try_bytesfoo_bar_range()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(request.status, NS_ERROR_NOT_RESUMABLE);
|
||||
|
||||
|
@ -175,6 +184,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function try_no_accept_ranges(request, data, ctx) {
|
||||
dump("*** try_no_accept_ranges()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(data, rangeBody);
|
||||
|
||||
|
@ -185,6 +195,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function success(request, data, ctx) {
|
||||
dump("*** success()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(data, rangeBody);
|
||||
|
||||
|
@ -197,6 +208,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function test_auth_nopw(request, data, ctx) {
|
||||
dump("*** test_auth_nopw()\n");
|
||||
do_check_false(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(request.status, NS_ERROR_ENTITY_CHANGED);
|
||||
|
||||
|
@ -207,6 +219,7 @@ function run_test() {
|
|||
chan.asyncOpen(new ChannelListener(test_auth, null, CL_EXPECT_FAILURE), null);
|
||||
}
|
||||
function test_auth(request, data, ctx) {
|
||||
dump("*** test_auth()\n");
|
||||
do_check_eq(request.status, NS_ERROR_NOT_RESUMABLE);
|
||||
do_check_true(request.nsIHttpChannel.responseStatus < 300);
|
||||
|
||||
|
@ -219,6 +232,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function test_auth_resume(request, data, ctx) {
|
||||
dump("*** test_auth_resume()\n");
|
||||
do_check_eq(data, rangeBody.substring(1));
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
|
||||
|
@ -230,6 +244,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function test_404(request, data, ctx) {
|
||||
dump("*** test_404()\n");
|
||||
do_check_eq(request.status, NS_ERROR_ENTITY_CHANGED);
|
||||
do_check_eq(request.nsIHttpChannel.responseStatus, 404);
|
||||
|
||||
|
@ -240,6 +255,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function test_416(request, data, ctx) {
|
||||
dump("*** test_416()\n");
|
||||
do_check_eq(request.status, NS_ERROR_ENTITY_CHANGED);
|
||||
do_check_eq(request.nsIHttpChannel.responseStatus, 416);
|
||||
|
||||
|
@ -251,6 +267,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function test_redir_resume(request, data, ctx) {
|
||||
dump("*** test_redir_resume()\n");
|
||||
do_check_true(request.nsIHttpChannel.requestSucceeded);
|
||||
do_check_eq(data, rangeBody.substring(1));
|
||||
do_check_eq(request.nsIHttpChannel.responseStatus, 206);
|
||||
|
@ -263,10 +280,10 @@ function run_test() {
|
|||
}
|
||||
|
||||
function test_redir_noresume(request, data, ctx) {
|
||||
dump("*** test_redir_noresume()\n");
|
||||
do_check_eq(request.status, NS_ERROR_NOT_RESUMABLE);
|
||||
|
||||
httpserver.stop();
|
||||
do_test_finished();
|
||||
httpserver.stop(do_test_finished);
|
||||
}
|
||||
|
||||
httpserver.start(4444);
|
||||
|
|
|
@ -67,8 +67,7 @@ Canceler.prototype = {
|
|||
};
|
||||
|
||||
function finish_test() {
|
||||
httpserver.stop();
|
||||
do_test_finished();
|
||||
httpserver.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function start_cache_read() {
|
||||
|
|
|
@ -57,8 +57,7 @@ TracingListener.prototype = {
|
|||
|
||||
onStopRequest: function(request, context, statusCode) {
|
||||
this.listener.onStopRequest(request, context, statusCode);
|
||||
httpserver.stop();
|
||||
do_test_finished();
|
||||
httpserver.stop(do_test_finished);
|
||||
},
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
|
|
|
@ -69,9 +69,9 @@ rdfLoadObserver.prototype =
|
|||
gPending -= 1;
|
||||
|
||||
if (gPending == 0) {
|
||||
server1.stop();
|
||||
server2.stop();
|
||||
do_test_finished();
|
||||
do_test_pending();
|
||||
server1.stop(do_test_finished);
|
||||
server2.stop(do_test_finished);
|
||||
}
|
||||
},
|
||||
onError : function() { }
|
||||
|
|
|
@ -114,6 +114,14 @@ function makeTags() {
|
|||
}
|
||||
}
|
||||
|
||||
var _quitting = false;
|
||||
|
||||
/** Quit when all activity has completed. */
|
||||
function serverStopped()
|
||||
{
|
||||
_quitting = true;
|
||||
}
|
||||
|
||||
// only run the "main" section if httpd.js was loaded ahead of us
|
||||
if (this["nsHttpServer"]) {
|
||||
//
|
||||
|
@ -121,10 +129,16 @@ if (this["nsHttpServer"]) {
|
|||
//
|
||||
runServer();
|
||||
|
||||
// We can only have gotten here if the /server/shutdown path was requested,
|
||||
// and we can shut down the xpcshell now that all testing requests have been
|
||||
// served.
|
||||
quit(0);
|
||||
// We can only have gotten here if the /server/shutdown path was requested.
|
||||
if (_quitting)
|
||||
{
|
||||
dumpn("HTTP server stopped, all pending requests complete");
|
||||
quit(0);
|
||||
}
|
||||
|
||||
// Impossible as the stop callback should have been called, but to be safe...
|
||||
dumpn("TEST-UNEXPECTED-FAIL | failure to correctly shut down HTTP server");
|
||||
quit(1);
|
||||
}
|
||||
|
||||
var serverBasePath;
|
||||
|
@ -276,8 +290,8 @@ function serverShutdown(metadata, response)
|
|||
var body = "Server shut down.";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
|
||||
// Note: this doesn't disrupt the current request.
|
||||
server.stop();
|
||||
dumpn("Server shutting down now...");
|
||||
server.stop(serverStopped);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -195,8 +195,11 @@ function getDownloadListener()
|
|||
do_test_finished();
|
||||
}
|
||||
|
||||
if (gDownloadCount == 0)
|
||||
httpserv.stop();
|
||||
if (gDownloadCount == 0 && typeof httpserv != "undefined" && httpserv)
|
||||
{
|
||||
do_test_pending();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
},
|
||||
onStateChange: function(a, b, c, d, e) { },
|
||||
onProgressChange: function(a, b, c, d, e, f, g) { },
|
||||
|
|
|
@ -78,10 +78,8 @@ function run_test()
|
|||
timer.init(observer, 0, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
if (Ci.nsIDownloadManager.DOWNLOAD_FINISHED == aDownload.state) {
|
||||
httpserv.stop();
|
||||
if (Ci.nsIDownloadManager.DOWNLOAD_FINISHED == aDownload.state)
|
||||
do_test_finished();
|
||||
}
|
||||
},
|
||||
onStateChange: function(a, b, c, d, e) { },
|
||||
onProgressChange: function(a, b, c, d, e, f, g) { },
|
||||
|
|
|
@ -60,7 +60,9 @@ function run_test()
|
|||
if (file.exists())
|
||||
file.remove(false);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
|
||||
|
||||
gDownloadCount++;
|
||||
|
||||
var dl = dm.addDownload(Ci.nsIDownloadManager.DOWNLOAD_TYPE_DOWNLOAD,
|
||||
createURI("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACGFjVEwAAAAEAAAAAHzNZtAAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAAAPoD6AEBim0EngAAAfVJREFUOI2tke9LEwEYx/0vwwgpRKLoTRC+iAhXSFJYYEERbZjd1N1+5I+dW+laeh1rmkKzbbftpuvWvN020aSs5t0+vVgO5hy98QvfNw/P9/N94OnpOUvp1UO8sSrCSpmX0RL+mMHCeoUP6V0S29/JlX6g6vt0BQTiVRLf6qimTdq0SZdtFiIKzukgvvlFBHGWKWm1E3Cy2bVU5Pmbr4iSwtjrT8jqDr+A1S0TlxiiVqvx3+ZU2WbcM8dUvERuD5ImpHYhlDAIhRfbARPvd1BNm0yladW0SRoWLsHHhgnZGpQPoPoT0nvgFPztAOdSkYxpoZoWXwyLzZJFomQxLnhYzu5hHsJvCw5siCQN3O7JdsCzcIFMpRmKbdWRtTqK9gePL4gwG0XVKxwBa7kST168wjCMdsDjeY1Nw0LJH7GSa9o7JyOKPgZvDuH1z+CenMI14WFsWu78wsOAymrBaoVFKY5e0Bm4eh1Zs5A1i8ujEeR8g77hcCdgxJNEyTcXRX8IfVvn4sA13qUOkTUbWbPpv7+InG/Q65A6AXeFz63Fj8tLDDpGcc6s/Zs1Ws2TcoX+e6dccGt8vQU4Dpx0r0PigiOIkih2AoYm1gms7Z8alPON7s3H2sia3HiqcOVRlIEHES6NvKVvOMz5OxLnbs93bz4L/QVUgSoBF8urgQAAABpmY1RMAAAAAQAAAA8AAAAQAAAAAQAAAAAA+gPoAQGATZxOAAAB82ZkQVQAAAACKJGt0OFLE3Ecx3H/yzBCChlR9CQIH0SEKyQpTLCgiDbWum3u3Eydc6u5ll6HqU1otu3cbmpn5+22iSa1Su/27sFyYzJ8Ul/4PPnxefGBX0/P/zqtWmdiqYqwWOZFSie8ZDCXrvA+v0dm6xtF/TuKdkBXPLlcJfP1CMW0yZs2+bLNXFLGNT5LKJJAEKcJRFc4c9E9v8Oz118QozJjrz4iKbv8BFY2TdxijFqtxpmLubKNJzhDYFmnuA9ZE3J7EMsYxOKJNva+20UxbTYqzSimTdawcAsh1kwo1KB8CNUfkN8HlxBuY9f8DhumhWJafDYs1nWLjG7hEYIsFPYx6/DLgkMbklkDn8/fxk/j22xUmmBp8whJPUJWfxMMzSJMp1C0CsfAalHn8fOXGIbRxo8iKuuGhVw6ZrHYzMSMhCiGGLg5yER4Cp8/gNsbZGxc6vzth5MKK9tWC4rRZbRtDcfV60iqhaRaXB5JIpUa9A3FO/FwMItcapbEcAxtS+Oi4xpvc3Uk1UZSbfrvJ5BKDXqd0U58V/jUKn1YmGfAOYJravXvW6O16Jcq9N87tXzLk27hk/Lp9DqjXHDOImd2OvGgN83k6kFXJJUa3RdPbq1gcuOJzJXRFI4HSS4Nv6FvKM75O1HO3Y50X/zX+wPZgSoB2RWdYAAAABpmY1RMAAAAAwAAAA8AAAAPAAAAAQAAAAEA+gPoAQHbRhjBAAAB9GZkQVQAAAAEKJGt0P9LE3Ecx/H9l2GEFDKi6Jcg/CEiXCFJYYEFRbSx1vll52bqNrdyy/TTYbomNNt2upva2Xm7baJJWendnv2w3JgMf+oNr18+vB684ONy/a/Tq4eML1aRFsq8nDMIL5rMZCp8KOyS3fxO0fiBqu/TEU8sVcl+O0K1HAqWQ6HsMJNS8I5FCUVmkeQpRmPLnLnoS27z/M1X5JjC0OtPCHWHX8DyhoVPjlOr1ThzMV928AenGV0yKO5BzoL8LsSzJvHEbAsH3u+gWg5rlUZUyyFn2vikECsWrNegfADVn1DYA68UbmFvcps1y0a1bL6YNquGTdaw8UtB5tf3sA7htw0HDqRyJsPDIy38LLHFWqUBFjeOENoRivaHYCiKNDWHqlc4BtJFgycvXmGaZgs/jmismjZK6ZiFYiPj0wJZDtF7s4/x8CTDI6P4AkGGxkT7bz+cUFnesptQji2hb+m4r15HaDZCs7k8mEKU6nT3J9rxQDCHUmqU5HAcfVPnovsa7/KHCM1BaA4992cRpTpdnlg7vit9bpY+zifp9QzinUz/e6s3F0dEhZ57p5Zv+TNNfFI+nS5PjAueKEp2ux33BTJMpPc7IlGqd148uZV1ixtPFa48msP9IMWlgbd09yc4fyfGuduRzosul+sv1q4qAfNb7esAAAAaZmNUTAAAAAUAAAAQAAAADwAAAAAAAAABAPoD6AEBp98YvwAAAflmZEFUAAAABiiRrZHhSxNxGMf3X4YRUohE0ZsgfBERrpCkMMGCItqwdZvu3Ezdzq3cWnodpqbQbNvN3dTOztttE01qld7t04vlYM7Rmx74vvnxfD+fB34u1/8cvVJjYrGCsFDiRcogvGgyu1rmfW6P9NY3CsZ3VP2AjoDJpQrpr0eolkPOcsiVHGaTCp7xKKHIHII4zZi03A44bfYmdnj2+guipDDy6iOyustPYHnTwivGqFar/NOcLTmMBmcYWzIo7EPGguwexNImsfhcK8D3bhfVcsiXG1Eth4xp4xVCrFmwUYXSIVR+QG4fPEK4FeBJ7JC3bFTL5rNps27YpA2bUSHI/MY+Vg1+2XDoQDJj4vcHWgFP49vky43S4uYRsnaEov0mGIoiTKdQ9TLHwErB4PHzl5im2Qp4FNFYN22U4jELhUYmZmREMUTfzX4mwlP4A2N4fUFGxuX2X3g4qbK8bTfLorSEvq3Te/U6smYjazaXh5LIxTrdA/F2wGAwg1JsLIrhGPqWzsXea7zN1pA1B1lz6Lk/h1ys0+WW2gF3hU/NxQ/zCfrcQ3imVv6+1ZvmgFym594ZF9waXW0CTgqn0+WWuOCOoqR32gH9vlUmVw7OLMrFemfzyaxtWNx4onBlOEXvgySXBt/QPRDn/B2Jc7cjnc0ul+sPqZsqAeXgvCsAAAAASUVORK5CYII="),
|
||||
createURI(file), null, null,
|
||||
|
@ -95,7 +97,8 @@ function run_test()
|
|||
do_test_finished();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
onStateChange: function(a, b, c, d, e) { }
|
||||
};
|
||||
|
||||
dm.addListener(listener);
|
||||
|
|
|
@ -137,17 +137,13 @@ function run_test()
|
|||
// extra real-resume check for the server
|
||||
do_check_true(didResumeServer);
|
||||
|
||||
httpserv.stop();
|
||||
httpserv.stop(do_test_finished);
|
||||
aDl.targetFile.remove(false);
|
||||
// we're done with the test!
|
||||
do_test_finished();
|
||||
}
|
||||
else if (aDl.state == nsIDM.DOWNLOAD_FAILED) {
|
||||
// this is only ok if we are not supposed to fail
|
||||
do_check_true(doNotError);
|
||||
httpserv.stop();
|
||||
// we're done with the test!
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
},
|
||||
onStateChange: function(a, b, aState, d, aDl) {
|
||||
|
|
|
@ -280,8 +280,7 @@ function run_test() {
|
|||
// cleanup
|
||||
prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
dm.removeListener(this);
|
||||
httpserv.stop();
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -123,9 +123,7 @@ function run_test()
|
|||
do_check_eq(data.length, aDl.amountTransferred);
|
||||
do_check_eq(data.length, aDl.size);
|
||||
|
||||
httpserv.stop();
|
||||
// we're done with the test!
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
},
|
||||
onStateChange: function(a, b, aState, d, aDl) {
|
||||
|
|
|
@ -136,17 +136,13 @@ function run_test()
|
|||
// extra real-resume check for the server
|
||||
do_check_true(didResumeServer);
|
||||
|
||||
httpserv.stop();
|
||||
aDl.targetFile.remove(false);
|
||||
// we're done with the test!
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
else if (aDl.state == nsIDM.DOWNLOAD_FAILED) {
|
||||
// this is only ok if we are not supposed to fail
|
||||
do_check_true(doNotError);
|
||||
httpserv.stop();
|
||||
// we're done with the test!
|
||||
do_test_finished();
|
||||
httpserv.stop(do_test_finished);
|
||||
}
|
||||
},
|
||||
onStateChange: function(a, b, aState, d, aDl) {
|
||||
|
|
|
@ -451,7 +451,6 @@ function run_test_pt4() {
|
|||
var item = gEM.getItemForID(ADDONS[i].id);
|
||||
do_check_item(item, "0.2", ADDONS[i]);
|
||||
}
|
||||
do_test_finished();
|
||||
|
||||
testserver.stop();
|
||||
testserver.stop(do_test_finished);
|
||||
}
|
||||
|
|
|
@ -53,9 +53,7 @@ const checkListener = {
|
|||
do_check_eq(item.minAppVersion, 1);
|
||||
do_check_eq(item.maxAppVersion, 1);
|
||||
|
||||
do_test_finished();
|
||||
|
||||
testserver.stop();
|
||||
testserver.stop(do_test_finished);
|
||||
},
|
||||
|
||||
// nsIAddonUpdateCheckListener
|
||||
|
|
|
@ -183,6 +183,5 @@ function run_test() {
|
|||
}
|
||||
|
||||
function test_complete() {
|
||||
testserver.stop();
|
||||
do_test_finished();
|
||||
testserver.stop(do_test_finished);
|
||||
}
|
||||
|
|
|
@ -88,8 +88,7 @@ var updateListener = {
|
|||
|
||||
onUpdateEnded: function()
|
||||
{
|
||||
server.stop();
|
||||
do_test_finished();
|
||||
server.stop(do_test_finished);
|
||||
},
|
||||
|
||||
onAddonUpdateStarted: function(addon)
|
||||
|
|
|
@ -124,8 +124,7 @@ onUpdateStarted: function()
|
|||
|
||||
onUpdateEnded: function()
|
||||
{
|
||||
server.stop();
|
||||
do_test_finished();
|
||||
server.stop(do_test_finished);
|
||||
},
|
||||
|
||||
onAddonUpdateStarted: function(addon)
|
||||
|
|
|
@ -52,9 +52,8 @@ var updateListener = {
|
|||
|
||||
onUpdateEnded: function onUpdateEnded()
|
||||
{
|
||||
server.stop();
|
||||
do_test_finished();
|
||||
do_check_eq(this._count, 2);
|
||||
server.stop(do_test_finished);
|
||||
},
|
||||
|
||||
onAddonUpdateStarted: function onAddonUpdateStarted(aAddon)
|
||||
|
|
|
@ -92,6 +92,5 @@ function run_test_pt2() {
|
|||
dump("Checking onUpdateEnded\n");
|
||||
do_check_true(checkListener._onUpdateEndedCalled);
|
||||
do_check_eq(checkListener._onAddonUpdateStartedCount, checkListener._onAddonUpdateEndedCount);
|
||||
testserver.stop();
|
||||
do_test_finished();
|
||||
testserver.stop(do_test_finished);
|
||||
}
|
||||
|
|
|
@ -340,7 +340,6 @@ function downloaded_c() {
|
|||
}
|
||||
|
||||
function test_complete() {
|
||||
testserver.stop();
|
||||
do_test_finished();
|
||||
testserver.stop(do_test_finished);
|
||||
}
|
||||
|
||||
|
|
|
@ -124,8 +124,7 @@ var RecommendedCallback = {
|
|||
},
|
||||
|
||||
searchFailed: function() {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Recommended results failed");
|
||||
}
|
||||
};
|
||||
|
@ -135,27 +134,23 @@ var SearchCallback = {
|
|||
do_check_false(addonRepo.isSearching);
|
||||
checkResults(addons, length);
|
||||
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
},
|
||||
|
||||
searchFailed: function() {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Search results failed");
|
||||
}
|
||||
};
|
||||
|
||||
var FailCallback = {
|
||||
searchSucceeded: function(addons, length, total) {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Should not be called");
|
||||
},
|
||||
|
||||
searchFailed: function() {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Should not be called");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -123,8 +123,7 @@ var RecommendedCallback = {
|
|||
},
|
||||
|
||||
searchFailed: function() {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Recommended results failed");
|
||||
}
|
||||
};
|
||||
|
@ -135,27 +134,23 @@ var SearchCallback = {
|
|||
do_check_eq(total, 100);
|
||||
checkResults(addons);
|
||||
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
},
|
||||
|
||||
searchFailed: function() {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Search results failed");
|
||||
}
|
||||
};
|
||||
|
||||
var FailCallback = {
|
||||
searchSucceeded: function(addons, length, total) {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Should not be called");
|
||||
},
|
||||
|
||||
searchFailed: function() {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Should not be called");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -63,13 +63,11 @@ var RecommendedCallback = {
|
|||
if (addons[i].rating != RESULTS[i])
|
||||
do_throw("Rating for " + addons[i].id + " was " + addons[i].rating + ", should have been " + RESULTS[i]);
|
||||
}
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
},
|
||||
|
||||
searchFailed: function() {
|
||||
do_test_finished();
|
||||
server.stop();
|
||||
server.stop(do_test_finished);
|
||||
do_throw("Recommended results failed");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -238,8 +238,7 @@ var installListener = {
|
|||
|
||||
function installNextAddon() {
|
||||
if (gIndex >= ADDONS.length) {
|
||||
testserver.stop();
|
||||
do_test_finished();
|
||||
testserver.stop(do_test_finished);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,8 +98,7 @@ function pathHandler(metadata, response) {
|
|||
gOSVersion + "&1.9&distribution&distribution-version");
|
||||
gBlocklist.observe(null, "quit-application", "");
|
||||
gBlocklist.observe(null, "xpcom-shutdown", "");
|
||||
testserver.stop();
|
||||
do_test_finished();
|
||||
testserver.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
|
|
@ -597,6 +597,5 @@ function run_test_pt3() {
|
|||
function check_test_pt3() {
|
||||
dump("Checking pt 3\n");
|
||||
check_state("appBlocks", "toolkitBlocks");
|
||||
gTestserver.stop();
|
||||
do_test_finished();
|
||||
gTestserver.stop(do_test_finished);
|
||||
}
|
||||
|
|
|
@ -526,6 +526,5 @@ function check_test_pt4() {
|
|||
}
|
||||
|
||||
function finish() {
|
||||
gTestserver.stop();
|
||||
do_test_finished();
|
||||
gTestserver.stop(do_test_finished);
|
||||
}
|
||||
|
|
|
@ -257,6 +257,5 @@ function test_addon_9() {
|
|||
}
|
||||
|
||||
function finish_test() {
|
||||
testserver.stop();
|
||||
do_test_finished();
|
||||
testserver.stop(do_test_finished);
|
||||
}
|
||||
|
|
|
@ -340,8 +340,9 @@ function start_httpserver(aRelativeDirName) {
|
|||
}
|
||||
|
||||
/* Helper for stopping the http server used by the tests */
|
||||
function stop_httpserver() {
|
||||
gTestserver.stop();
|
||||
function stop_httpserver(callback) {
|
||||
do_check_true(!!callback);
|
||||
gTestserver.stop(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -58,8 +58,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function end_test() {
|
||||
stop_httpserver();
|
||||
do_test_finished();
|
||||
stop_httpserver(do_test_finished);
|
||||
}
|
||||
|
||||
// Helper function for testing update counts returned from an update xml
|
||||
|
|
|
@ -58,8 +58,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function end_test() {
|
||||
stop_httpserver();
|
||||
do_test_finished();
|
||||
stop_httpserver(do_test_finished);
|
||||
}
|
||||
|
||||
// Helper function for testing mar downloads that have the correct size
|
||||
|
|
|
@ -62,8 +62,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function end_test() {
|
||||
do_test_finished();
|
||||
stop_httpserver();
|
||||
stop_httpserver(do_test_finished);
|
||||
}
|
||||
|
||||
// Helper function for parsing the result from the contructed url
|
||||
|
|
|
@ -64,8 +64,7 @@ function run_test() {
|
|||
}
|
||||
|
||||
function end_test() {
|
||||
stop_httpserver();
|
||||
do_test_finished();
|
||||
stop_httpserver(do_test_finished);
|
||||
}
|
||||
|
||||
// Returns human readable status text from the updates.properties bundle
|
||||
|
|
Загрузка…
Ссылка в новой задаче