Skip to content

Commit

Permalink
[UTS] Don’t test on multiple transports
Browse files Browse the repository at this point in the history
This is part of removing some common private API usage for the unified
test suite.

ably-js is the only client library that offers multiple transports, so
testing on multiple transports will probably not be part of the UTS.
  • Loading branch information
lawrence-forooghian committed Jul 25, 2024
1 parent b3ad7f5 commit cfc66aa
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 174 deletions.
35 changes: 2 additions & 33 deletions test/common/modules/shared_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,6 @@ define([
return new this(this.createContext(context));
}

static forTestDefinition(thisInDescribe, label) {
if (!label) {
throw new Error('SharedHelper.forTestDefinition called without label');
}

const context = {
type: 'definition',
file: thisInDescribe.file,
suite: this.extractSuiteHierarchy(thisInDescribe),
label,
};

return new this(this.createContext(context));
}

recordTestStart() {
this.privateApiContext.recordTestStart();
}
Expand Down Expand Up @@ -331,7 +316,6 @@ define([

/* testFn is assumed to be a function of realtimeOptions that returns a mocha test */
static testOnAllTransports(thisInDescribe, name, testFn, skip) {
const helper = this.forTestDefinition(thisInDescribe, name).addingHelperFunction('testOnAllTransports');
var itFn = skip ? it.skip : it;

function createTest(options) {
Expand All @@ -341,23 +325,8 @@ define([
};
}

let transports = helper.availableTransports;
transports.forEach(function (transport) {
itFn(
name + '_with_' + transport + '_binary_transport',
createTest({ transports: [transport], useBinaryProtocol: true }),
);
itFn(
name + '_with_' + transport + '_text_transport',
createTest({ transports: [transport], useBinaryProtocol: false }),
);
});
/* Plus one for no transport specified (ie use websocket/base mechanism if
* present). (we explicitly specify all transports since node only does
* websocket+nodecomet if comet is explicitly requested)
* */
itFn(name + '_with_binary_transport', createTest({ transports, useBinaryProtocol: true }));
itFn(name + '_with_text_transport', createTest({ transports, useBinaryProtocol: false }));
itFn(name + '_with_binary_transport', createTest({ useBinaryProtocol: true }));
itFn(name + '_with_text_transport', createTest({ useBinaryProtocol: false }));
}

static restTestOnJsonMsgpack(name, testFn, skip) {
Expand Down
216 changes: 111 additions & 105 deletions test/realtime/failure.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,51 +201,48 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async
expect(value).to.be.below(max);
}

Helper.forTestDefinition(this, 'disconnected_backoff_').availableTransports.forEach(function (transport) {
/**
* @spec RTB1a
* @spec RTB1b
* @spec TO3l1
* @specpartial RTB1 - test backoff for connection
* @specpartial RTN14d - retries and retryIn calculation
* @specpartial TA2 - retryIn passed in ConnectionStateChange
*/
it('disconnected_backoff_' + transport, function (done) {
const helper = this.test.helper;
var disconnectedRetryTimeout = 150;
var realtime = helper.AblyRealtime({
disconnectedRetryTimeout: disconnectedRetryTimeout,
realtimeHost: 'invalid',
restHost: 'invalid',
transports: [transport],
});
/**
* @spec RTB1a
* @spec RTB1b
* @spec TO3l1
* @specpartial RTB1 - test backoff for connection
* @specpartial RTN14d - retries and retryIn calculation
* @specpartial TA2 - retryIn passed in ConnectionStateChange
*/
it('disconnected_backoff', function (done) {
const helper = this.test.helper;
var disconnectedRetryTimeout = 150;
var realtime = helper.AblyRealtime({
disconnectedRetryTimeout: disconnectedRetryTimeout,
realtimeHost: 'invalid',
restHost: 'invalid',
});

var retryCount = 0;
var retryTimeouts = [];
var retryCount = 0;
var retryTimeouts = [];

realtime.connection.on(function (stateChange) {
if (stateChange.previous === 'connecting' && stateChange.current === 'disconnected') {
if (retryCount > 4) {
// Upper bound = min((retryAttempt + 2) / 3, 2) * initialTimeout
// Lower bound = 0.8 * Upper bound
checkIsBetween(retryTimeouts[0], 120, 150);
checkIsBetween(retryTimeouts[1], 160, 200);
checkIsBetween(retryTimeouts[2], 200, 250);
realtime.connection.on(function (stateChange) {
if (stateChange.previous === 'connecting' && stateChange.current === 'disconnected') {
if (retryCount > 4) {
// Upper bound = min((retryAttempt + 2) / 3, 2) * initialTimeout
// Lower bound = 0.8 * Upper bound
checkIsBetween(retryTimeouts[0], 120, 150);
checkIsBetween(retryTimeouts[1], 160, 200);
checkIsBetween(retryTimeouts[2], 200, 250);

for (var i = 3; i < retryTimeouts.length; i++) {
checkIsBetween(retryTimeouts[i], 240, 300);
}
helper.closeAndFinish(done, realtime);
return;
}
try {
retryTimeouts.push(stateChange.retryIn);
retryCount += 1;
} catch (err) {
helper.closeAndFinish(done, realtime, err);
for (var i = 3; i < retryTimeouts.length; i++) {
checkIsBetween(retryTimeouts[i], 240, 300);
}
helper.closeAndFinish(done, realtime);
return;
}
});
try {
retryTimeouts.push(stateChange.retryIn);
retryCount += 1;
} catch (err) {
helper.closeAndFinish(done, realtime, err);
}
}
});
});

Expand Down Expand Up @@ -405,75 +402,84 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async
});
});

Helper.forTestDefinition(this, 'channel_backoff_').availableTransports.forEach(function (transport) {
/**
* @spec RTL13b
* @spec RTB1a
* @spec RTB1b
* @spec TO3l7
* @specpartial RTB1 - test backoff for channel
*/
it('channel_backoff_' + transport, function (done) {
const helper = this.test.helper;
var channelRetryTimeout = 150;
var realtime = helper.AblyRealtime({
channelRetryTimeout: channelRetryTimeout,
transports: [transport],
}),
channel = realtime.channels.get('failed_attach'),
originalProcessMessage = channel.processMessage.bind(channel),
retryCount = 0;

var performance = isBrowser ? window.performance : require('perf_hooks').performance;

helper.recordPrivateApi('replace.channel.processMessage');
channel.processMessage = async function (message) {
// Ignore ATTACHED messages
if (message.action === 11) {
return;
}
helper.recordPrivateApi('call.channel.processMessage');
await originalProcessMessage(message);
};
/**
* @spec RTL13b
* @spec RTB1a
* @spec RTB1b
* @spec TO3l7
* @specpartial RTB1 - test backoff for channel
*/
it('channel_backoff', function (done) {
const helper = this.test.helper;
var channelRetryTimeout = 150;
var realtime = helper.AblyRealtime({
channelRetryTimeout: channelRetryTimeout,
}),
channel = realtime.channels.get('failed_attach'),
originalProcessMessage = channel.processMessage.bind(channel),
retryCount = 0;

var retryTimeouts = [];
var performance = isBrowser ? window.performance : require('perf_hooks').performance;

realtime.connection.on('connected', function () {
helper.recordPrivateApi('write.realtime.options.timeouts.realtimeRequestTimeout');
realtime.options.timeouts.realtimeRequestTimeout = 1;
Helper.whenPromiseSettles(channel.attach(), function (err) {
if (err) {
var lastSuspended = performance.now();
channel.on(function (stateChange) {
if (stateChange.current === 'suspended') {
if (retryCount > 4) {
// Upper bound = min((retryAttempt + 2) / 3, 2) * initialTimeout
// Lower bound = 0.8 * Upper bound
// Additional 10 is a calculationDelayTimeout
checkIsBetween(retryTimeouts[0], 120, 150 + 10);
checkIsBetween(retryTimeouts[1], 160, 200 + 10);
checkIsBetween(retryTimeouts[2], 200, 250 + 10);

for (var i = 3; i < retryTimeouts.length; i++) {
checkIsBetween(retryTimeouts[i], 240, 300 + 10);
}
helper.closeAndFinish(done, realtime);
return;
}
var elapsedSinceSuspneded = performance.now() - lastSuspended;
lastSuspended = performance.now();
try {
retryTimeouts.push(elapsedSinceSuspneded);
retryCount += 1;
} catch (err) {
helper.closeAndFinish(done, realtime, err);
helper.recordPrivateApi('replace.channel.processMessage');
channel.processMessage = async function (message) {
// Ignore ATTACHED messages
if (message.action === 11) {
return;
}
helper.recordPrivateApi('call.channel.processMessage');
await originalProcessMessage(message);
};

var performance = isBrowser ? window.performance : require('perf_hooks').performance;

helper.recordPrivateApi('replace.channel.processMessage');
channel.processMessage = async function (message) {
// Ignore ATTACHED messages
if (message.action === 11) {
return;
}
helper.recordPrivateApi('call.channel.processMessage');
await originalProcessMessage(message);
};

var retryTimeouts = [];

realtime.connection.on('connected', function () {
helper.recordPrivateApi('write.realtime.options.timeouts.realtimeRequestTimeout');
realtime.options.timeouts.realtimeRequestTimeout = 1;
Helper.whenPromiseSettles(channel.attach(), function (err) {
if (err) {
var lastSuspended = performance.now();
channel.on(function (stateChange) {
if (stateChange.current === 'suspended') {
if (retryCount > 4) {
// Upper bound = min((retryAttempt + 2) / 3, 2) * initialTimeout
// Lower bound = 0.8 * Upper bound
// Additional 10 is a calculationDelayTimeout
checkIsBetween(retryTimeouts[0], 120, 150 + 10);
checkIsBetween(retryTimeouts[1], 160, 200 + 10);
checkIsBetween(retryTimeouts[2], 200, 250 + 10);

for (var i = 3; i < retryTimeouts.length; i++) {
checkIsBetween(retryTimeouts[i], 240, 300 + 10);
}
helper.closeAndFinish(done, realtime);
return;
}
});
} else {
helper.closeAndFinish(done, realtime, new Error('Expected channel attach to timeout'));
}
});
var elapsedSinceSuspneded = performance.now() - lastSuspended;
lastSuspended = performance.now();
try {
retryTimeouts.push(elapsedSinceSuspneded);
retryCount += 1;
} catch (err) {
helper.closeAndFinish(done, realtime, err);
}
}
});
} else {
helper.closeAndFinish(done, realtime, new Error('Expected channel attach to timeout'));
}
});
});
});
Expand Down
66 changes: 31 additions & 35 deletions test/realtime/init.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,43 @@ define(['ably', 'shared_helper', 'chai'], function (Ably, Helper, chai) {
});
});

/* Restrict to websocket or xhr polling for the v= test as if stream=false the
* recvRequest may not be the connectRequest by the time we check it. */
((testDefinitionHelper) => {
if (testDefinitionHelper.bestTransport === 'web_socket' || testDefinitionHelper.bestTransport === 'xhr_polling') {
/*
* Base init case.
* @spec RTN2f
*/
it('initbase0', function (done) {
const helper = this.test.helper;
var realtime;
/*
* Base init case.
* @spec RTN2f
*/
it('initbase0', function (done) {
const helper = this.test.helper;
var realtime;
try {
/* Restrict to websocket or xhr polling for the v= test as if stream=false the
* recvRequest may not be the connectRequest by the time we check it. */
realtime = helper.AblyRealtime({ transports: ['web_socket', 'xhr_polling'] });
realtime.connection.on('connected', function () {
/* check api version */
helper.recordPrivateApi('read.connectionManager.activeProtocol.transport');
var transport = realtime.connection.connectionManager.activeProtocol.transport;
var connectUri = helper.isWebsocket(transport)
? (() => {
helper.recordPrivateApi('read.transport.uri');
return transport.uri;
})()
: (() => {
helper.recordPrivateApi('read.transport.recvRequest.recvUri');
return transport.recvRequest.recvUri;
})();
try {
realtime = helper.AblyRealtime({ transports: ['web_socket', 'xhr_polling'] });
realtime.connection.on('connected', function () {
/* check api version */
helper.recordPrivateApi('read.connectionManager.activeProtocol.transport');
var transport = realtime.connection.connectionManager.activeProtocol.transport;
var connectUri = helper.isWebsocket(transport)
? (() => {
helper.recordPrivateApi('read.transport.uri');
return transport.uri;
})()
: (() => {
helper.recordPrivateApi('read.transport.recvRequest.recvUri');
return transport.recvRequest.recvUri;
})();
try {
expect(connectUri.indexOf('v=3') > -1, 'Check uri includes v=3').to.be.ok;
} catch (err) {
helper.closeAndFinish(done, realtime, err);
return;
}
helper.closeAndFinish(done, realtime);
});
helper.monitorConnection(done, realtime);
expect(connectUri.indexOf('v=3') > -1, 'Check uri includes v=3').to.be.ok;
} catch (err) {
helper.closeAndFinish(done, realtime, err);
return;
}
helper.closeAndFinish(done, realtime);
});
helper.monitorConnection(done, realtime);
} catch (err) {
helper.closeAndFinish(done, realtime, err);
}
})(Helper.forTestDefinition(this, 'initbase0'));
});

/**
* Init with key string.
Expand Down
2 changes: 1 addition & 1 deletion test/realtime/presence.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1913,7 +1913,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async
*/
it('leave_published_for_member_missing_from_sync', function (done) {
var helper = this.test.helper,
realtime = helper.AblyRealtime({ transports: helper.availableTransports }),
realtime = helper.AblyRealtime(),
continuousClientId = 'continuous',
goneClientId = 'gone',
continuousRealtime = helper.AblyRealtime({ clientId: continuousClientId }),
Expand Down

0 comments on commit cfc66aa

Please sign in to comment.