Skip to content

Commit ba29e04

Browse files
committed
test(NODE-6858): add tests for ServerSelectionError
1 parent 82d6ce6 commit ba29e04

File tree

1 file changed

+85
-25
lines changed

1 file changed

+85
-25
lines changed

test/integration/change-streams/change_stream.test.ts

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
type CommandStartedEvent,
1515
type Db,
1616
isHello,
17+
LEGACY_HELLO_COMMAND,
1718
Long,
1819
MongoAPIError,
1920
MongoChangeStreamError,
@@ -1818,7 +1819,7 @@ describe('Change Streams', function () {
18181819
});
18191820
});
18201821

1821-
describe('ChangeStream resumability', function () {
1822+
describe.only('ChangeStream resumability', function () {
18221823
let client: MongoClient;
18231824
let collection: Collection;
18241825
let changeStream: ChangeStream;
@@ -1832,30 +1833,30 @@ describe('ChangeStream resumability', function () {
18321833
};
18331834

18341835
const resumableErrorCodes = [
1835-
{ error: 'HostUnreachable', code: 6, message: 'host unreachable' },
1836-
{ error: 'HostNotFound', code: 7, message: 'hot not found' },
1837-
{ error: 'NetworkTimeout', code: 89, message: 'network timeout' },
1838-
{ error: 'ShutdownInProgress', code: 91, message: 'shutdown in progress' },
1839-
{ error: 'PrimarySteppedDown', code: 189, message: 'primary stepped down' },
1840-
{ error: 'ExceededTimeLimit', code: 262, message: 'operation exceeded time limit' },
1841-
{ error: 'SocketException', code: 9001, message: 'socket exception' },
1842-
{ error: 'NotWritablePrimary', code: 10107, message: 'not writable primary' },
1843-
{ error: 'InterruptedAtShutdown', code: 11600, message: 'interrupted at shutdown' },
1844-
{
1845-
error: 'InterruptedDueToReplStateChange',
1846-
code: 11602,
1847-
message: 'interrupted due to state change'
1848-
},
1849-
{ error: 'NotPrimaryNoSecondaryOk', code: 13435, message: 'not primary and no secondary ok' },
1850-
{ error: 'StaleShardVersion', code: 63, message: 'stale shard version' },
1851-
{ error: 'StaleEpoch', code: 150, message: 'stale epoch' },
1852-
{ error: 'RetryChangeStream', code: 234, message: 'retry change stream' },
1853-
{
1854-
error: 'FailedToSatisfyReadPreference',
1855-
code: 133,
1856-
message: 'failed to satisfy read preference'
1857-
},
1858-
{ error: 'CursorNotFound', code: 43, message: 'cursor not found' }
1836+
{ error: 'HostUnreachable', code: 6, message: 'host unreachable' }
1837+
// { error: 'HostNotFound', code: 7, message: 'hot not found' },
1838+
// { error: 'NetworkTimeout', code: 89, message: 'network timeout' },
1839+
// { error: 'ShutdownInProgress', code: 91, message: 'shutdown in progress' },
1840+
// { error: 'PrimarySteppedDown', code: 189, message: 'primary stepped down' },
1841+
// { error: 'ExceededTimeLimit', code: 262, message: 'operation exceeded time limit' },
1842+
// { error: 'SocketException', code: 9001, message: 'socket exception' },
1843+
// { error: 'NotWritablePrimary', code: 10107, message: 'not writable primary' },
1844+
// { error: 'InterruptedAtShutdown', code: 11600, message: 'interrupted at shutdown' },
1845+
// {
1846+
// error: 'InterruptedDueToReplStateChange',
1847+
// code: 11602,
1848+
// message: 'interrupted due to state change'
1849+
// },
1850+
// { error: 'NotPrimaryNoSecondaryOk', code: 13435, message: 'not primary and no secondary ok' },
1851+
// { error: 'StaleShardVersion', code: 63, message: 'stale shard version' },
1852+
// { error: 'StaleEpoch', code: 150, message: 'stale epoch' },
1853+
// { error: 'RetryChangeStream', code: 234, message: 'retry change stream' },
1854+
// {
1855+
// error: 'FailedToSatisfyReadPreference',
1856+
// code: 133,
1857+
// message: 'failed to satisfy read preference'
1858+
// },
1859+
// { error: 'CursorNotFound', code: 43, message: 'cursor not found' }
18591860
];
18601861

18611862
beforeEach(function () {
@@ -2045,6 +2046,65 @@ describe('ChangeStream resumability', function () {
20452046
expect(changeStream.closed).to.be.true;
20462047
});
20472048
});
2049+
2050+
context.only('when the error is not a server error', function () {
2051+
let client1: MongoClient;
2052+
let client2: MongoClient;
2053+
2054+
beforeEach(async function () {
2055+
client1 = this.configuration.newClient(
2056+
{},
2057+
{ serverSelectionTimeoutMS: 1000, appName: 'client-errors' }
2058+
);
2059+
client2 = this.configuration.newClient();
2060+
2061+
collection = client1.db('client-errors').collection('test');
2062+
});
2063+
2064+
afterEach(async function () {
2065+
await client2.db('admin').command({
2066+
configureFailPoint: 'failCommand',
2067+
mode: 'off',
2068+
data: { appName: 'client-errors' }
2069+
} as FailCommandFailPoint);
2070+
2071+
await client1?.close();
2072+
await client2?.close();
2073+
});
2074+
2075+
it(
2076+
'should resume on ServerSelectionError',
2077+
{ requires: { topology: '!single' } },
2078+
async function () {
2079+
changeStream = collection.watch([]);
2080+
await initIteratorMode(changeStream);
2081+
2082+
await collection.insertOne({ a: 1 });
2083+
2084+
await client2.db('admin').command({
2085+
configureFailPoint: 'failCommand',
2086+
mode: 'alwaysOn',
2087+
data: {
2088+
failCommands: ['ping', 'hello', LEGACY_HELLO_COMMAND],
2089+
closeConnection: true,
2090+
handshakeCommands: true,
2091+
failInternalCommands: true,
2092+
appName: 'client-errors'
2093+
}
2094+
} as FailCommandFailPoint);
2095+
await client2
2096+
.db('admin')
2097+
.command({ replSetFreeze: 0 }, { readPreference: ReadPreference.secondary });
2098+
await client2
2099+
.db('admin')
2100+
.command({ replSetStepDown: 15, secondaryCatchUpPeriodSecs: 10, force: true });
2101+
// await sleep(15_000);
2102+
2103+
const change = await changeStream.next();
2104+
expect(change).to.containSubset({ operationType: 'insert', fullDocument: { a: 1 } });
2105+
}
2106+
);
2107+
});
20482108
});
20492109

20502110
context('#hasNext', function () {

0 commit comments

Comments
 (0)