14
14
*/
15
15
16
16
using System ;
17
- using System . Collections ;
18
17
using System . Collections . Generic ;
19
- using System . IO ;
20
18
using System . Linq ;
21
- using System . Reflection ;
22
19
using System . Threading ;
23
20
using FluentAssertions ;
24
21
using MongoDB . Bson ;
22
+ using MongoDB . Bson . TestHelpers . JsonDrivenTests ;
25
23
using MongoDB . Driver . Core ;
26
24
using MongoDB . Driver . Core . Clusters . ServerSelectors ;
27
25
using MongoDB . Driver . Core . Events ;
30
28
31
29
namespace MongoDB . Driver . Tests . Specifications . command_monitoring
32
30
{
33
- public class TestRunner
31
+ public class CommandMonitoringTestRunner
34
32
{
35
33
private static MongoClient __client ;
36
34
private static EventCapturer __capturedEvents ;
@@ -39,7 +37,7 @@ public class TestRunner
39
37
private static bool __oneTimeSetupHasRun = false ;
40
38
private static object __oneTimeSetupLock = new object ( ) ;
41
39
42
- static TestRunner ( )
40
+ static CommandMonitoringTestRunner ( )
43
41
{
44
42
__commandsToCapture = new string [ ]
45
43
{
@@ -66,7 +64,7 @@ static TestRunner()
66
64
} ;
67
65
}
68
66
69
- public TestRunner ( )
67
+ public CommandMonitoringTestRunner ( )
70
68
{
71
69
lock ( __oneTimeSetupLock )
72
70
{
@@ -101,9 +99,9 @@ public bool OneTimeSetup()
101
99
102
100
[ SkippableTheory ]
103
101
[ ClassData ( typeof ( TestCaseFactory ) ) ]
104
- public void RunTestDefinition ( IEnumerable < BsonDocument > data , string databaseName , string collectionName , BsonDocument definition , bool async )
102
+ public void RunTestDefinition ( JsonDrivenTestCase testCase )
105
103
{
106
- definition = ( BsonDocument ) DeepCopy ( definition ) ; // protect against side effects when the same definition is run twice (async=false/true)
104
+ var definition = testCase . Test ;
107
105
108
106
BsonValue bsonValue ;
109
107
if ( definition . TryGetValue ( "ignore_if_server_version_greater_than" , out bsonValue ) )
@@ -136,18 +134,21 @@ public void RunTestDefinition(IEnumerable<BsonDocument> data, string databaseNam
136
134
}
137
135
}
138
136
139
- var database = __client
140
- . GetDatabase ( databaseName ) ;
141
- var collection = database
142
- . GetCollection < BsonDocument > ( collectionName ) ;
137
+ var data = testCase . Shared [ "data" ] . AsBsonArray . Cast < BsonDocument > ( ) . ToList ( ) ;
138
+ var databaseName = testCase . Shared [ "database_name" ] . AsString ;
139
+ var collectionName = testCase . Shared [ "collection_name" ] . AsString ;
140
+
141
+ var operation = ( BsonDocument ) definition [ "operation" ] ;
142
+ var database = __client . GetDatabase ( databaseName ) ;
143
+ var collection = database . GetCollection < BsonDocument > ( collectionName ) ;
143
144
144
145
database . DropCollection ( collection . CollectionNamespace . CollectionName ) ;
145
146
collection . InsertMany ( data ) ;
146
147
147
148
__capturedEvents . Clear ( ) ;
148
149
try
149
150
{
150
- ExecuteOperation ( database , collection , ( BsonDocument ) definition [ "operation" ] , async ) ;
151
+ ExecuteOperation ( database , collectionName , operation , definition [ "async" ] . AsBoolean ) ;
151
152
}
152
153
catch ( NotImplementedException )
153
154
{
@@ -196,13 +197,24 @@ public void RunTestDefinition(IEnumerable<BsonDocument> data, string databaseNam
196
197
}
197
198
}
198
199
200
+ private IMongoCollection < BsonDocument > GetCollection ( IMongoDatabase database , string collectionName , BsonDocument operation )
201
+ {
202
+ var collectionSettings = ParseOperationCollectionSettings ( operation ) ;
203
+
204
+ var collection = database . GetCollection < BsonDocument > (
205
+ collectionName ,
206
+ collectionSettings ) ;
207
+
208
+ return collection ;
209
+ }
210
+
199
211
private SemanticVersion GetServerVersion ( )
200
212
{
201
213
var server = __client . Cluster . SelectServer ( WritableServerSelector . Instance , CancellationToken . None ) ;
202
214
return server . Description . Version ;
203
215
}
204
216
205
- private void ExecuteOperation ( IMongoDatabase database , IMongoCollection < BsonDocument > collection , BsonDocument operation , bool async )
217
+ private void ExecuteOperation ( IMongoDatabase database , string collectionName , BsonDocument operation , bool async )
206
218
{
207
219
var name = ( string ) operation [ "name" ] ;
208
220
Func < ICrudOperationTest > factory ;
@@ -219,9 +231,40 @@ private void ExecuteOperation(IMongoDatabase database, IMongoCollection<BsonDocu
219
231
throw new SkipException ( reason ) ;
220
232
}
221
233
234
+ var collection = GetCollection ( database , collectionName , operation ) ;
222
235
test . Execute ( __client . Cluster . Description , database , collection , arguments , async) ;
223
236
}
224
237
238
+ private MongoCollectionSettings ParseCollectionSettings ( BsonDocument collectionOptions )
239
+ {
240
+ var settings = new MongoCollectionSettings ( ) ;
241
+ foreach ( var collectionOption in collectionOptions . Elements )
242
+ {
243
+ switch ( collectionOption . Name )
244
+ {
245
+ case "writeConcern" :
246
+ settings . WriteConcern = WriteConcern . FromBsonDocument ( collectionOption . Value . AsBsonDocument ) ;
247
+ break ;
248
+ default :
249
+ throw new FormatException ( $ "Unexpected collection option: { collectionOption . Name } .") ;
250
+ }
251
+ }
252
+
253
+ return settings ;
254
+ }
255
+
256
+ private MongoCollectionSettings ParseOperationCollectionSettings ( BsonDocument operation )
257
+ {
258
+ if ( operation . TryGetValue ( "collectionOptions" , out var collectionOptions ) )
259
+ {
260
+ return ParseCollectionSettings ( collectionOptions . AsBsonDocument ) ;
261
+ }
262
+ else
263
+ {
264
+ return null ;
265
+ }
266
+ }
267
+
225
268
private void VerifyCommandStartedEvent ( CommandStartedEvent actual , BsonDocument expected , string databaseName , string collectionName )
226
269
{
227
270
actual . CommandName . Should ( ) . Be ( expected [ "command_name" ] . ToString ( ) ) ;
@@ -250,7 +293,7 @@ private void VerifyCommandFailedEvent(CommandFailedEvent actual, BsonDocument ex
250
293
251
294
private BsonDocument MassageCommand ( string commandName , BsonDocument command )
252
295
{
253
- var massagedCommand = ( BsonDocument ) DeepCopy ( command ) ;
296
+ var massagedCommand = ( BsonDocument ) command . DeepClone ( ) ;
254
297
switch ( commandName )
255
298
{
256
299
case "delete" :
@@ -267,12 +310,6 @@ private BsonDocument MassageCommand(string commandName, BsonDocument command)
267
310
break ;
268
311
case "update" :
269
312
massagedCommand [ "ordered" ] = massagedCommand . GetValue ( "ordered" , true ) ;
270
- foreach ( BsonDocument update in ( BsonArray ) massagedCommand [ "updates" ] )
271
- {
272
- update [ "multi" ] = update . GetValue ( "multi" , false ) ;
273
- update [ "upsert" ] = update . GetValue ( "upsert" , false ) ;
274
- }
275
-
276
313
break ;
277
314
}
278
315
@@ -284,7 +321,7 @@ private BsonDocument MassageCommand(string commandName, BsonDocument command)
284
321
285
322
private BsonDocument MassageReply ( string commandName , BsonDocument reply , BsonDocument expectedReply )
286
323
{
287
- var massagedReply = ( BsonDocument ) DeepCopy ( reply ) ;
324
+ var massagedReply = ( BsonDocument ) reply . DeepClone ( ) ;
288
325
switch ( commandName )
289
326
{
290
327
case "find" :
@@ -318,78 +355,25 @@ private BsonDocument MassageReply(string commandName, BsonDocument reply, BsonDo
318
355
return massagedReply ;
319
356
}
320
357
321
- private BsonValue DeepCopy ( BsonValue value )
358
+ // nested types
359
+ private class TestCaseFactory : JsonDrivenTestCaseFactory
322
360
{
323
- if ( value . BsonType == BsonType . Document )
324
- {
325
- var document = new BsonDocument ( ) ;
326
- foreach ( var element in ( BsonDocument ) value )
327
- {
328
- document . Add ( element . Name , DeepCopy ( element . Value ) ) ;
329
- }
330
-
331
- return document ;
332
- }
333
- else if ( value . BsonType == BsonType . Array )
334
- {
335
- var array = new BsonArray ( ) ;
336
- foreach ( var element in ( BsonArray ) value )
337
- {
338
- array . Add ( DeepCopy ( element ) ) ;
339
- }
340
- return array ;
341
- }
361
+ // protected properties
362
+ protected override string PathPrefix => "MongoDB.Driver.Tests.Specifications.command_monitoring.tests." ;
342
363
343
- return value ;
344
- }
345
-
346
- private class TestCaseFactory : IEnumerable < object [ ] >
347
- {
348
- public IEnumerator < object [ ] > GetEnumerator ( )
364
+ // protected methods
365
+ protected override IEnumerable < JsonDrivenTestCase > CreateTestCases ( BsonDocument document )
349
366
{
350
- const string prefix = "MongoDB.Driver.Tests.Specifications.command_monitoring.tests." ;
351
- var testDocuments = typeof ( TestCaseFactory ) . GetTypeInfo ( ) . Assembly
352
- . GetManifestResourceNames ( )
353
- . Where ( path => path . StartsWith ( prefix ) && path . EndsWith ( ".json" ) )
354
- . Select ( path => ReadDocument ( path ) ) ;
355
-
356
- var testCases = new List < object [ ] > ( ) ;
357
- foreach ( var testDocument in testDocuments )
367
+ var testCases = base . CreateTestCases ( document ) ;
368
+ foreach ( var testCase in testCases )
358
369
{
359
- var data = testDocument [ "data" ] . AsBsonArray . Cast < BsonDocument > ( ) . ToList ( ) ;
360
- var databaseName = testDocument [ "database_name" ] . ToString ( ) ;
361
- var collectionName = testDocument [ "collection_name" ] . ToString ( ) ;
362
-
363
- foreach ( BsonDocument definition in testDocument [ "tests" ] . AsBsonArray )
370
+ foreach ( var async in new [ ] { false , true } )
364
371
{
365
- foreach ( var async in new [ ] { false , true } )
366
- {
367
- //var testCase = new TestCaseData(data, databaseName, collectionName, definition, async);
368
- //testCase.SetCategory("Specifications");
369
- //testCase.SetCategory("command-monitoring");
370
- //testCase.SetName($"{definition["description"]}({async})");
371
- var testCase = new object [ ] { data , databaseName , collectionName , definition , async } ;
372
- testCases . Add ( testCase ) ;
373
- }
372
+ var name = $ "{ testCase . Name } :async={ async} ";
373
+ var test = testCase . Test . DeepClone ( ) . AsBsonDocument . Add ( "async" , async ) ;
374
+ yield return new JsonDrivenTestCase( name , testCase . Shared , test ) ;
374
375
}
375
376
}
376
-
377
- return testCases . GetEnumerator ( ) ;
378
- }
379
-
380
- IEnumerator IEnumerable . GetEnumerator ( )
381
- {
382
- return GetEnumerator ( ) ;
383
- }
384
-
385
- private static BsonDocument ReadDocument ( string path )
386
- {
387
- using ( var definitionStream = typeof ( TestCaseFactory ) . GetTypeInfo ( ) . Assembly . GetManifestResourceStream ( path ) )
388
- using ( var definitionStringReader = new StreamReader ( definitionStream ) )
389
- {
390
- var definitionString = definitionStringReader . ReadToEnd ( ) ;
391
- return BsonDocument . Parse ( definitionString ) ;
392
- }
393
377
}
394
378
}
395
379
}
0 commit comments