@@ -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