1
1
/*
2
- * Copyright (c) 2015 MongoDB, Inc.
2
+ * Copyright 2015-2016 MongoDB, Inc.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
32
32
import org .bson .BsonArray ;
33
33
import org .bson .BsonBoolean ;
34
34
import org .bson .BsonDocument ;
35
+ import org .bson .BsonDocumentWriter ;
35
36
import org .bson .BsonDouble ;
36
37
import org .bson .BsonInt32 ;
37
38
import org .bson .BsonInt64 ;
38
39
import org .bson .BsonString ;
39
40
import org .bson .BsonValue ;
40
41
import org .bson .Document ;
42
+ import org .bson .codecs .BsonDocumentCodec ;
43
+ import org .bson .codecs .BsonValueCodecProvider ;
44
+ import org .bson .codecs .Codec ;
41
45
import org .bson .codecs .DocumentCodec ;
46
+ import org .bson .codecs .EncoderContext ;
47
+ import org .bson .codecs .configuration .CodecProvider ;
48
+ import org .bson .codecs .configuration .CodecRegistries ;
49
+ import org .bson .codecs .configuration .CodecRegistry ;
42
50
import org .junit .AfterClass ;
43
51
import org .junit .Before ;
44
52
import org .junit .BeforeClass ;
69
77
// See https://github.com/mongodb/specifications/tree/master/source/command-monitoring/tests
70
78
@ RunWith (Parameterized .class )
71
79
public class CommandMonitoringTest {
80
+ private static final CodecRegistry CODEC_REGISTRY_HACK = CodecRegistries .fromProviders (new BsonValueCodecProvider (),
81
+ new CodecProvider () {
82
+ @ Override
83
+ @ SuppressWarnings ("unchecked" )
84
+ public <T > Codec <T > get (final Class <T > clazz , final CodecRegistry registry ) {
85
+ // Use BsonDocumentCodec even for a private sub-class of BsonDocument
86
+ if (BsonDocument .class .isAssignableFrom (clazz )) {
87
+ return (Codec <T >) new BsonDocumentCodec (registry );
88
+ }
89
+ return null ;
90
+ }
91
+ });
92
+
72
93
private static MongoClient mongoClient ;
73
94
private static TestCommandListener commandListener ;
74
95
private final String filename ;
@@ -210,43 +231,48 @@ private CommandSucceededEvent massageExpectedCommandSucceededEvent(final Command
210
231
}
211
232
212
233
private CommandSucceededEvent massageActualCommandSucceededEvent (final CommandSucceededEvent actual ) {
234
+ BsonDocument response = getWritableCloneOfCommand (actual .getResponse ());
235
+
213
236
// massage numbers that are the wrong BSON type
214
- actual . getResponse (). put ("ok" , new BsonDouble (actual . getResponse () .getNumber ("ok" ).doubleValue ()));
215
- if (actual . getResponse () .containsKey ("n" )) {
216
- actual . getResponse (). put ("n" , new BsonInt32 (actual . getResponse () .getNumber ("n" ).intValue ()));
237
+ response . put ("ok" , new BsonDouble (response .getNumber ("ok" ).doubleValue ()));
238
+ if (response .containsKey ("n" )) {
239
+ response . put ("n" , new BsonInt32 (response .getNumber ("n" ).intValue ()));
217
240
}
218
241
219
242
if (actual .getCommandName ().equals ("find" ) || actual .getCommandName ().equals ("getMore" )) {
220
- if (actual . getResponse () .containsKey ("cursor" )) {
221
- if (actual . getResponse () .getDocument ("cursor" ).containsKey ("id" )
222
- && !actual . getResponse () .getDocument ("cursor" ).getInt64 ("id" ).equals (new BsonInt64 (0 ))) {
223
- actual . getResponse () .getDocument ("cursor" ).put ("id" , new BsonInt64 (42 ));
243
+ if (response .containsKey ("cursor" )) {
244
+ if (response .getDocument ("cursor" ).containsKey ("id" )
245
+ && !response .getDocument ("cursor" ).getInt64 ("id" ).equals (new BsonInt64 (0 ))) {
246
+ response .getDocument ("cursor" ).put ("id" , new BsonInt64 (42 ));
224
247
}
225
248
}
226
249
} else if (actual .getCommandName ().equals ("killCursors" )) {
227
- actual . getResponse () .getArray ("cursorsUnknown" ).set (0 , new BsonInt64 (42 ));
250
+ response .getArray ("cursorsUnknown" ).set (0 , new BsonInt64 (42 ));
228
251
} else if (isWriteCommand (actual .getCommandName ())) {
229
- if (actual . getResponse () .containsKey ("writeErrors" )) {
230
- for (Iterator <BsonValue > iter = actual . getResponse () .getArray ("writeErrors" ).iterator (); iter .hasNext ();) {
252
+ if (response .containsKey ("writeErrors" )) {
253
+ for (Iterator <BsonValue > iter = response .getArray ("writeErrors" ).iterator (); iter .hasNext ();) {
231
254
BsonDocument cur = iter .next ().asDocument ();
232
255
cur .put ("code" , new BsonInt32 (42 ));
233
256
cur .put ("errmsg" , new BsonString ("" ));
234
257
}
235
258
}
236
259
if (actual .getCommandName ().equals ("update" )) {
237
- actual . getResponse () .remove ("nModified" );
260
+ response .remove ("nModified" );
238
261
}
239
262
}
240
- return actual ;
263
+ return new CommandSucceededEvent (actual .getRequestId (), actual .getConnectionDescription (), actual .getCommandName (), response ,
264
+ actual .getElapsedTime (TimeUnit .NANOSECONDS ));
241
265
}
242
266
243
267
private boolean isWriteCommand (final String commandName ) {
244
268
return asList ("insert" , "update" , "delete" ).contains (commandName );
245
269
}
246
270
247
271
private CommandStartedEvent massageActualCommandStartedEvent (final CommandStartedEvent actual ) {
272
+ BsonDocument command = getWritableCloneOfCommand (actual .getCommand ());
273
+
248
274
if (actual .getCommandName ().equals ("update" )) {
249
- for (Iterator <BsonValue > iter = actual . getCommand () .getArray ("updates" ).iterator (); iter .hasNext ();) {
275
+ for (Iterator <BsonValue > iter = command .getArray ("updates" ).iterator (); iter .hasNext ();) {
250
276
BsonDocument curUpdate = iter .next ().asDocument ();
251
277
if (!curUpdate .containsKey ("multi" )) {
252
278
curUpdate .put ("multi" , BsonBoolean .FALSE );
@@ -256,12 +282,13 @@ private CommandStartedEvent massageActualCommandStartedEvent(final CommandStarte
256
282
}
257
283
}
258
284
} else if (actual .getCommandName ().equals ("getMore" )) {
259
- actual . getCommand () .put ("getMore" , new BsonInt64 (42 ));
285
+ command .put ("getMore" , new BsonInt64 (42 ));
260
286
} else if (actual .getCommandName ().equals ("killCursors" )) {
261
- actual . getCommand () .getArray ("cursors" ).set (0 , new BsonInt64 (42 ));
287
+ command .getArray ("cursors" ).set (0 , new BsonInt64 (42 ));
262
288
}
263
289
264
- return actual ;
290
+ return new CommandStartedEvent (actual .getRequestId (), actual .getConnectionDescription (), actual .getDatabaseName (),
291
+ actual .getCommandName (), command );
265
292
}
266
293
267
294
private void executeOperation () {
@@ -298,6 +325,15 @@ private List<CommandEvent> getExpectedEvents(final BsonArray expectedEventDocume
298
325
return expectedEvents ;
299
326
}
300
327
328
+
329
+ private BsonDocument getWritableCloneOfCommand (final BsonDocument original ) {
330
+ BsonDocument clone = new BsonDocument ();
331
+ BsonDocumentWriter writer = new BsonDocumentWriter (clone );
332
+ new BsonDocumentCodec (CODEC_REGISTRY_HACK ).encode (writer , original , EncoderContext .builder ().build ());
333
+ return clone ;
334
+ }
335
+
336
+
301
337
@ Parameterized .Parameters (name = "{1}" )
302
338
public static Collection <Object []> data () throws URISyntaxException , IOException {
303
339
List <Object []> data = new ArrayList <Object []>();
0 commit comments