2020import com .mongodb .ReadPreference ;
2121import com .mongodb .ServerAddress ;
2222import com .mongodb .client .test .CollectionHelper ;
23+ import com .mongodb .connection .ClusterDescription ;
2324import com .mongodb .event .CommandFailedEvent ;
2425import com .mongodb .event .CommandSucceededEvent ;
2526import com .mongodb .internal .connection .TestClusterListener ;
@@ -136,7 +137,7 @@ void overloadErrorRetriedOnDifferentReplicaSetServer() throws InterruptedExcepti
136137 .applyToClusterSettings (builder -> builder .addClusterListener (clusterListener ))
137138 .build ())) {
138139
139- waitForPrimaryDiscovery ();
140+ waitForClusterDiscovery ();
140141
141142 MongoCollection <Document > collection = client .getDatabase (getDefaultDatabaseName ())
142143 .getCollection (COLLECTION_NAME );
@@ -188,7 +189,7 @@ void nonOverloadErrorRetriedOnSameReplicaSetServer() throws InterruptedException
188189 .applyToClusterSettings (builder -> builder .addClusterListener (clusterListener ))
189190 .build ())) {
190191
191- waitForPrimaryDiscovery ();
192+ waitForClusterDiscovery ();
192193
193194 MongoCollection <Document > collection = client .getDatabase (getDefaultDatabaseName ())
194195 .getCollection (COLLECTION_NAME );
@@ -211,9 +212,21 @@ void nonOverloadErrorRetriedOnSameReplicaSetServer() throws InterruptedException
211212 }
212213 }
213214
214- private void waitForPrimaryDiscovery () throws InterruptedException , TimeoutException {
215+ private void waitForClusterDiscovery () throws InterruptedException , TimeoutException {
215216 clusterListener .waitForClusterDescriptionChangedEvents (
216- event -> event .getNewDescription ().hasReadableServer (ReadPreference .primary ()),
217+ event -> {
218+ ClusterDescription desc = event .getNewDescription ();
219+ // We need both primary and secondary to be discovered (not UNKNOWN) before running the test.
220+ //
221+ // 1. The failpoint is set on the primary. If the primary is not yet discovered,
222+ // primaryPreferred may route the find to a secondary, and the failpoint never fires.
223+ //
224+ // 2. When the primary is deprioritized on retry, primaryPreferred falls back to a secondary.
225+ // If the secondaries are still UNKNOWN at that point, the fallback yields no selectable servers,
226+ // causing the deprioritized primary to be selected again.
227+ return desc .hasReadableServer (ReadPreference .primary ())
228+ && desc .hasReadableServer (ReadPreference .secondary ());
229+ },
217230 1 , Duration .ofSeconds (10 ));
218231 }
219232}
0 commit comments