7878import java .util .concurrent .Future ;
7979import java .util .concurrent .TimeUnit ;
8080import java .util .concurrent .atomic .AtomicLong ;
81+ import java .util .stream .Collectors ;
8182
8283import static com .mongodb .assertions .Assertions .assertFalse ;
8384import static com .mongodb .internal .thread .InterruptionUtil .interruptAndCreateMongoInterruptedException ;
8485import static java .lang .String .format ;
86+ import static java .util .Arrays .asList ;
8587import static org .junit .Assert .assertEquals ;
88+ import static org .junit .Assert .assertTrue ;
8689import static org .junit .Assert .fail ;
8790import static org .junit .Assume .assumeFalse ;
8891import static org .junit .Assume .assumeNotNull ;
@@ -285,40 +288,59 @@ public void shouldPassAllOutcomes() throws Exception {
285288 BsonDocument expectedEvent = cur .asDocument ();
286289 String type = expectedEvent .getString ("type" ).getValue ();
287290 if (type .equals ("ConnectionPoolCreated" )) {
291+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" , "options" );
288292 ConnectionPoolCreatedEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionPoolCreatedEvent .class );
289293 assertAddressMatch (expectedEvent , actualEvent .getServerId ().getAddress ());
290294 assertEquals (settings , actualEvent .getSettings ());
291295 } else if (type .equals ("ConnectionPoolCleared" )) {
296+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" );
292297 ConnectionPoolClearedEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionPoolClearedEvent .class );
293298 assertAddressMatch (expectedEvent , actualEvent .getServerId ().getAddress ());
294299 } else if (type .equals ("ConnectionPoolReady" )) {
300+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" );
295301 ConnectionPoolReadyEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionPoolReadyEvent .class );
296302 assertAddressMatch (expectedEvent , actualEvent .getServerId ().getAddress ());
297303 } else if (type .equals ("ConnectionPoolClosed" )) {
304+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" );
298305 ConnectionPoolClosedEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionPoolClosedEvent .class );
299306 assertAddressMatch (expectedEvent , actualEvent .getServerId ().getAddress ());
300307 } else if (type .equals ("ConnectionCreated" )) {
308+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" , "connectionId" );
301309 ConnectionCreatedEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionCreatedEvent .class );
310+ assertAddressMatch (expectedEvent , actualEvent .getConnectionId ().getServerId ().getAddress ());
302311 assertConnectionIdMatch (expectedEvent , actualEvent .getConnectionId ());
303312 } else if (type .equals ("ConnectionReady" )) {
313+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" , "connectionId" , "duration" );
304314 ConnectionReadyEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionReadyEvent .class );
305315 assertAddressMatch (expectedEvent , actualEvent .getConnectionId ().getServerId ().getAddress ());
316+ assertConnectionIdMatch (expectedEvent , actualEvent .getConnectionId ());
317+ assertDurationMatch (expectedEvent , actualEvent );
306318 } else if (type .equals ("ConnectionClosed" )) {
319+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" , "connectionId" , "reason" );
307320 ConnectionClosedEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionClosedEvent .class );
321+ assertAddressMatch (expectedEvent , actualEvent .getConnectionId ().getServerId ().getAddress ());
308322 assertConnectionIdMatch (expectedEvent , actualEvent .getConnectionId ());
309323 assertReasonMatch (expectedEvent , actualEvent );
310324 } else if (type .equals ("ConnectionCheckOutStarted" )) {
325+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" );
311326 ConnectionCheckOutStartedEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionCheckOutStartedEvent .class );
312327 assertAddressMatch (expectedEvent , actualEvent .getServerId ().getAddress ());
313328 } else if (type .equals ("ConnectionCheckOutFailed" )) {
329+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" , "reason" , "duration" );
314330 ConnectionCheckOutFailedEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionCheckOutFailedEvent .class );
315331 assertAddressMatch (expectedEvent , actualEvent .getServerId ().getAddress ());
316332 assertReasonMatch (expectedEvent , actualEvent );
333+ assertDurationMatch (expectedEvent , actualEvent );
317334 } else if (type .equals ("ConnectionCheckedOut" )) {
335+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" , "connectionId" , "duration" );
318336 ConnectionCheckedOutEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionCheckedOutEvent .class );
337+ assertAddressMatch (expectedEvent , actualEvent .getConnectionId ().getServerId ().getAddress ());
319338 assertConnectionIdMatch (expectedEvent , actualEvent .getConnectionId ());
339+ assertDurationMatch (expectedEvent , actualEvent );
320340 } else if (type .equals ("ConnectionCheckedIn" )) {
341+ assertHasOnlySupportedKeys (expectedEvent , "type" , "address" , "connectionId" );
321342 ConnectionCheckedInEvent actualEvent = getNextEvent (actualEventsIterator , ConnectionCheckedInEvent .class );
343+ assertAddressMatch (expectedEvent , actualEvent .getConnectionId ().getServerId ().getAddress ());
322344 assertConnectionIdMatch (expectedEvent , actualEvent .getConnectionId ());
323345 } else {
324346 throw new UnsupportedOperationException ("Unsupported event type " + type );
@@ -327,6 +349,16 @@ public void shouldPassAllOutcomes() throws Exception {
327349 }
328350 }
329351
352+ private static void assertHasOnlySupportedKeys (final BsonDocument document , final String ... supportedKeys ) {
353+ List <String > supportedKeysList = asList (supportedKeys );
354+ List <String > unsupportedKeys = document .keySet ().stream ()
355+ .filter (key -> !supportedKeysList .contains (key ))
356+ .collect (Collectors .toList ());
357+ if (!unsupportedKeys .isEmpty ()) {
358+ fail (format ("The runner encountered not yet supported keys %s in %s" , unsupportedKeys , document ));
359+ }
360+ }
361+
330362 private void assertReasonMatch (final BsonDocument expectedEvent , final ConnectionClosedEvent connectionClosedEvent ) {
331363 if (!expectedEvent .containsKey ("reason" )) {
332364 return ;
@@ -400,6 +432,32 @@ private void assertConnectionIdMatch(final BsonDocument expectedEvent, final Con
400432 }
401433 }
402434
435+ private static void assertDurationMatch (final BsonDocument expectedEvent , final ConnectionReadyEvent actualEvent ) {
436+ assertDurationMatch (expectedEvent , actualEvent .getElapsedTime (TimeUnit .MILLISECONDS ));
437+ }
438+
439+ private static void assertDurationMatch (final BsonDocument expectedEvent , final ConnectionCheckOutFailedEvent actualEvent ) {
440+ assertDurationMatch (expectedEvent , actualEvent .getElapsedTime (TimeUnit .MILLISECONDS ));
441+ }
442+
443+ private static void assertDurationMatch (final BsonDocument expectedEvent , final ConnectionCheckedOutEvent actualEvent ) {
444+ assertDurationMatch (expectedEvent , actualEvent .getElapsedTime (TimeUnit .MILLISECONDS ));
445+ }
446+
447+ private static void assertDurationMatch (final BsonDocument expectedEvent , final long actualDurationMillis ) {
448+ String durationKey = "duration" ;
449+ if (expectedEvent .isNumber (durationKey )) {
450+ assertTrue ("actualDurationMillis must not be negative" , actualDurationMillis >= 0 );
451+ long expectedDurationMillis = expectedEvent .getNumber (durationKey ).longValue ();
452+ if (expectedDurationMillis != ANY_INT ) {
453+ fail (format ("Unsupported duration value %d. Pay attention to the expected value unit when supporting the value" ,
454+ expectedDurationMillis ));
455+ }
456+ } else if (expectedEvent .containsKey (durationKey )) {
457+ fail (format ("Unsupported value %s" , expectedEvent .get (durationKey )));
458+ }
459+ }
460+
403461 private long adjustedConnectionIdLocalValue (final long connectionIdLocalValue ) {
404462 if (pool instanceof ConnectionIdAdjustingConnectionPool ) {
405463 return ((ConnectionIdAdjustingConnectionPool ) pool ).adjustedConnectionIdLocalValue (connectionIdLocalValue );
0 commit comments