Fix session handle tests so that multiple copies of the test can run

at the same time.
This commit is contained in:
Andrew Wilcox
2013-11-21 13:03:04 -05:00
committed by Nick Martin
parent 819019f08f
commit 67a589be8b

View File

@@ -1,60 +1,135 @@
var Fiber = Npm.require('fibers');
Tinytest.addAsync(
"livedata server - sessionHandle.onClose()",
function (test, onComplete) {
var connection;
var callbackHandle = Meteor.onConnection(function (sessionHandle) {
callbackHandle.stop();
test.isTrue(_.isString(sessionHandle.id), "sessionHandle.id exists and is a string");
// On the server side, wait for the connection to be closed.
sessionHandle.onClose(function () {
onComplete();
});
// Close the connection from the client.
connection.disconnect();
});
connection = DDP.connect(Meteor.absoluteUrl());
}
);
// like pollUntil but doesn't have to be called from testAsyncMulti.
var poll = function (test, onComplete, fn) {
//
// Call `fn` periodically until it returns true. If it does, call
// `success`. If it doesn't before the timeout, call `failed`.
//
// An implementation that used fibers would be easier to use, but
// don't want to rule out the possibility of eventually also running
// these tests from the client (which would need an additional
// signaling mechanism to tell the server when to do particular steps
// such as closing the connection on the server side).
var poll = function (fn, success, failed) {
var timeout = 10000;
var step = 200;
var start = (new Date()).valueOf();
var helper = function () {
if (fn()) {
test.ok();
onComplete();
success();
return;
}
if (start + timeout < (new Date()).valueOf()) {
test.fail();
onComplete();
failed();
return;
}
Meteor.setTimeout(helper, step);
};
helper();
};
Tinytest.addAsync("livedata server - sessionHandle.close()", function (test, onComplete) {
// Establish a connection from the server to the server, and wait
// until the client side of the connection has received the session
// id. On success call `succeeded` with two arguments, the client
// side `connection` and the server side `session`. Call `failed` on
// failure.
var establishConnection = function (test, succeeded, failed) {
// The connection from the client side.
var connection;
var callbackHandle = Meteor.onConnection(function (sessionHandle) {
callbackHandle.stop();
poll(test, onComplete, function () {
return ! connection.status().connected;
});
// Track incoming sessions server side until we know which one is
// ours.
var sessions = {};
// Close the connection from the server.
sessionHandle.close();
// Add incoming sessions to `sessions`.
var onConnectionHandle = Meteor.onConnection(function (session) {
test.isTrue(_.isString(session.id), "session handle id exists and is a string");
if (sessions[session.id]) {
test.fail("onConnection callback called multiple times for same session id");
failed();
}
else {
sessions[session.id] = session;
}
});
connection = DDP.connect(Meteor.absoluteUrl(), {retry: false});
});
// We've succeeded when we get the session id on the client side.
var onClientSessionId = function (sessionId) {
test.isTrue(connection.status().connected);
var session = sessions[sessionId];
if (! session) {
test.fail("No onConnection received server side for connected client");
failed();
}
else {
onConnectionHandle.stop();
succeeded(connection, session);
}
};
// Connect and wait until the connection receives its session id.
// Disable retries so that when the connection is closed we don't
// automatically keep reconnecting on the client side.
connection = DDP.connect(Meteor.absoluteUrl(), {retry: false});
poll(
function () {
return connection._lastSessionId;
},
function () {
onClientSessionId(connection._lastSessionId);
},
function () {
test.fail("client side of connection did not receive a session id");
failed();
}
);
};
Tinytest.addAsync(
"livedata server - sessionHandle.onClose()",
function (test, onComplete) {
establishConnection(
test,
function (connection, session) {
// On the server side, wait for the connection to be closed.
session.onClose(function () {
onComplete();
});
// Close the connection from the client.
connection.disconnect();
},
onComplete
);
}
);
Tinytest.addAsync(
"livedata server - sessionHandle.close()",
function (test, onComplete) {
establishConnection(
test,
function (connection, session) {
// Wait for the connection to be closed from the server side.
poll(
function () {
return ! connection.status().connected;
},
onComplete,
function () {
test.fail("timeout waiting for the connection to be closed on the server side");
onComplete();
}
);
// Close the connection from the server.
session.close();
},
onComplete
);
}
);
var innerCalled = null;
@@ -74,20 +149,20 @@ Meteor.methods({
Tinytest.addAsync(
"livedata server - sessionId in method invocation",
"livedata server - session in method invocation",
function (test, onComplete) {
var sessionId;
var callbackHandle = Meteor.onConnection(function (sessionHandle) {
callbackHandle.stop();
sessionId = sessionHandle.id;
});
innerCalled = function (methodInvocation) {
test.equal(methodInvocation.session.id, sessionId);
onComplete();
};
var connection = DDP.connect(Meteor.absoluteUrl());
connection.call('livedata_server_test_inner');
connection.disconnect();
establishConnection(
test,
function (connection, session) {
innerCalled = function (methodInvocation) {
test.equal(methodInvocation.session.id, session.id);
onComplete();
};
connection.call('livedata_server_test_inner');
connection.disconnect();
},
onComplete
);
}
);
@@ -95,35 +170,37 @@ Tinytest.addAsync(
Tinytest.addAsync(
"livedata server - session in nested method invocation",
function (test, onComplete) {
var sessionId;
var callbackHandle = Meteor.onConnection(function (sessionHandle) {
callbackHandle.stop();
sessionId = sessionHandle.id;
});
innerCalled = function (methodInvocation) {
test.equal(methodInvocation.session.id, sessionId);
onComplete();
};
var connection = DDP.connect(Meteor.absoluteUrl());
connection.call('livedata_server_test_outer');
connection.disconnect();
establishConnection(
test,
function (connection, session) {
innerCalled = function (methodInvocation) {
test.equal(methodInvocation.session.id, session.id);
onComplete();
};
connection.call('livedata_server_test_outer');
connection.disconnect();
},
onComplete
);
}
);
Tinytest.addAsync(
"livedata server - session data in nested method invocation",
function (test, onComplete) {
var callbackHandle = Meteor.onConnection(function (session) {
callbackHandle.stop();
session._sessionData.foo = 123;
});
innerCalled = function (methodInvocation) {
test.equal(methodInvocation._sessionData.foo, 123);
onComplete();
};
var connection = DDP.connect(Meteor.absoluteUrl());
connection.call('livedata_server_test_outer');
connection.disconnect();
establishConnection(
test,
function (connection, session) {
session._sessionData.foo = 123;
innerCalled = function (methodInvocation) {
test.equal(methodInvocation._sessionData.foo, 123);
onComplete();
};
connection.call('livedata_server_test_outer');
connection.disconnect();
},
onComplete
);
}
);