1414*/
1515
1616using System ;
17- using System . Collections ;
1817using System . Collections . Generic ;
19- using System . IO ;
2018using System . Linq ;
21- using System . Reflection ;
2219using System . Threading ;
2320using FluentAssertions ;
2421using MongoDB . Bson ;
22+ using MongoDB . Bson . TestHelpers . JsonDrivenTests ;
2523using MongoDB . Driver . Core ;
2624using MongoDB . Driver . Core . Clusters . ServerSelectors ;
2725using MongoDB . Driver . Core . Events ;
3028
3129namespace MongoDB . Driver . Tests . Specifications . command_monitoring
3230{
33- public class TestRunner
31+ public class CommandMonitoringTestRunner
3432 {
3533 private static MongoClient __client ;
3634 private static EventCapturer __capturedEvents ;
@@ -39,7 +37,7 @@ public class TestRunner
3937 private static bool __oneTimeSetupHasRun = false ;
4038 private static object __oneTimeSetupLock = new object ( ) ;
4139
42- static TestRunner ( )
40+ static CommandMonitoringTestRunner ( )
4341 {
4442 __commandsToCapture = new string [ ]
4543 {
@@ -66,7 +64,7 @@ static TestRunner()
6664 } ;
6765 }
6866
69- public TestRunner ( )
67+ public CommandMonitoringTestRunner ( )
7068 {
7169 lock ( __oneTimeSetupLock )
7270 {
@@ -101,9 +99,9 @@ public bool OneTimeSetup()
10199
102100 [ SkippableTheory ]
103101 [ ClassData ( typeof ( TestCaseFactory ) ) ]
104- public void RunTestDefinition ( IEnumerable < BsonDocument > data , string databaseName , string collectionName , BsonDocument definition , bool async )
102+ public void RunTestDefinition ( JsonDrivenTestCase testCase )
105103 {
106- definition = ( BsonDocument ) DeepCopy ( definition ) ; // protect against side effects when the same definition is run twice (async=false/true)
104+ var definition = testCase . Test ;
107105
108106 BsonValue bsonValue ;
109107 if ( definition . TryGetValue ( "ignore_if_server_version_greater_than" , out bsonValue ) )
@@ -136,18 +134,21 @@ public void RunTestDefinition(IEnumerable<BsonDocument> data, string databaseNam
136134 }
137135 }
138136
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 ) ;
143144
144145 database . DropCollection ( collection . CollectionNamespace . CollectionName ) ;
145146 collection . InsertMany ( data ) ;
146147
147148 __capturedEvents . Clear ( ) ;
148149 try
149150 {
150- ExecuteOperation ( database , collection , ( BsonDocument ) definition [ "operation" ] , async ) ;
151+ ExecuteOperation ( database , collectionName , operation , definition [ "async" ] . AsBoolean ) ;
151152 }
152153 catch ( NotImplementedException )
153154 {
@@ -196,13 +197,24 @@ public void RunTestDefinition(IEnumerable<BsonDocument> data, string databaseNam
196197 }
197198 }
198199
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+
199211 private SemanticVersion GetServerVersion ( )
200212 {
201213 var server = __client . Cluster . SelectServer ( WritableServerSelector . Instance , CancellationToken . None ) ;
202214 return server . Description . Version ;
203215 }
204216
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 )
206218 {
207219 var name = ( string ) operation [ "name" ] ;
208220 Func < ICrudOperationTest > factory ;
@@ -219,9 +231,40 @@ private void ExecuteOperation(IMongoDatabase database, IMongoCollection<BsonDocu
219231 throw new SkipException ( reason ) ;
220232 }
221233
234+ var collection = GetCollection ( database , collectionName , operation ) ;
222235 test . Execute ( __client . Cluster . Description , database , collection , arguments , async) ;
223236 }
224237
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+
225268 private void VerifyCommandStartedEvent ( CommandStartedEvent actual , BsonDocument expected , string databaseName , string collectionName )
226269 {
227270 actual . CommandName . Should ( ) . Be ( expected [ "command_name" ] . ToString ( ) ) ;
@@ -250,7 +293,7 @@ private void VerifyCommandFailedEvent(CommandFailedEvent actual, BsonDocument ex
250293
251294 private BsonDocument MassageCommand ( string commandName , BsonDocument command )
252295 {
253- var massagedCommand = ( BsonDocument ) DeepCopy ( command ) ;
296+ var massagedCommand = ( BsonDocument ) command . DeepClone ( ) ;
254297 switch ( commandName )
255298 {
256299 case "delete" :
@@ -267,12 +310,6 @@ private BsonDocument MassageCommand(string commandName, BsonDocument command)
267310 break ;
268311 case "update" :
269312 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-
276313 break ;
277314 }
278315
@@ -284,7 +321,7 @@ private BsonDocument MassageCommand(string commandName, BsonDocument command)
284321
285322 private BsonDocument MassageReply ( string commandName , BsonDocument reply , BsonDocument expectedReply )
286323 {
287- var massagedReply = ( BsonDocument ) DeepCopy ( reply ) ;
324+ var massagedReply = ( BsonDocument ) reply . DeepClone ( ) ;
288325 switch ( commandName )
289326 {
290327 case "find" :
@@ -318,78 +355,25 @@ private BsonDocument MassageReply(string commandName, BsonDocument reply, BsonDo
318355 return massagedReply ;
319356 }
320357
321- private BsonValue DeepCopy ( BsonValue value )
358+ // nested types
359+ private class TestCaseFactory : JsonDrivenTestCaseFactory
322360 {
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." ;
342363
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 )
349366 {
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 )
358369 {
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 } )
364371 {
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 ) ;
374375 }
375376 }
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- }
393377 }
394378 }
395379 }
0 commit comments