Skip to content

Commit 470b964

Browse files
authored
CSHARP-4394: Improve test coverage for retryable handshake errors (mongodb#975)
1 parent 8f203d7 commit 470b964

File tree

9 files changed

+6672
-229
lines changed

9 files changed

+6672
-229
lines changed

specifications/retryable-reads/tests/unified/handshakeError.json

Lines changed: 2874 additions & 52 deletions
Large diffs are not rendered by default.

specifications/retryable-reads/tests/unified/handshakeError.yml

Lines changed: 1266 additions & 53 deletions
Large diffs are not rendered by default.

specifications/retryable-writes/tests/unified/handshakeError.json

Lines changed: 1583 additions & 65 deletions
Large diffs are not rendered by default.

specifications/retryable-writes/tests/unified/handshakeError.yml

Lines changed: 706 additions & 58 deletions
Large diffs are not rendered by default.

tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsUnifiedTestRunner.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
using System.Collections.Generic;
17+
using System.Linq;
1718
using MongoDB.Bson;
1819
using MongoDB.Bson.TestHelpers.JsonDrivenTests;
1920
using MongoDB.Driver.Core.TestHelpers.Logging;
@@ -27,6 +28,13 @@ namespace MongoDB.Driver.Tests.Specifications.retryable_reads
2728
[Trait("Category", "Serverless")]
2829
public sealed class RetryableReadsUnifiedTestRunner : LoggableTestClass
2930
{
31+
private readonly static string[] __operationsToSkip =
32+
new[]
33+
{
34+
"findOne",
35+
"listIndexNames"
36+
};
37+
3038
// public constructors
3139
public RetryableReadsUnifiedTestRunner(ITestOutputHelper testOutputHelper)
3240
: base(testOutputHelper)
@@ -55,6 +63,11 @@ protected override IEnumerable<JsonDrivenTestCase> CreateTestCases(BsonDocument
5563
{
5664
foreach (var testCase in base.CreateTestCases(document))
5765
{
66+
if (__operationsToSkip.Any(testCase.Name.Contains))
67+
{
68+
continue;
69+
}
70+
5871
foreach (var async in new[] { false, true })
5972
{
6073
var name = $"{testCase.Name}:async={async}";
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Threading;
18+
using System.Threading.Tasks;
19+
using MongoDB.Bson;
20+
using MongoDB.Driver.Core.Misc;
21+
22+
namespace MongoDB.Driver.Tests.UnifiedTestOperations
23+
{
24+
public class UnifiedListCollectionNamesOperation : IUnifiedEntityTestOperation
25+
{
26+
private readonly IMongoDatabase _database;
27+
private readonly ListCollectionNamesOptions _options;
28+
private readonly IClientSessionHandle _session;
29+
30+
public UnifiedListCollectionNamesOperation(
31+
IMongoDatabase database,
32+
ListCollectionNamesOptions options,
33+
IClientSessionHandle session)
34+
{
35+
_database = Ensure.IsNotNull(database, nameof(database));
36+
_options = options; // can be null
37+
_session = session;
38+
}
39+
40+
public OperationResult Execute(CancellationToken cancellationToken)
41+
{
42+
try
43+
{
44+
using var cursor = _session == null
45+
? _database.ListCollectionNames(_options, cancellationToken)
46+
: _database.ListCollectionNames(_session, _options, cancellationToken);
47+
48+
var collections = cursor.ToList(cancellationToken);
49+
50+
return OperationResult.FromResult(new BsonArray(collections));
51+
}
52+
catch (Exception ex)
53+
{
54+
return OperationResult.FromException(ex);
55+
}
56+
}
57+
58+
public async Task<OperationResult> ExecuteAsync(CancellationToken cancellationToken)
59+
{
60+
try
61+
{
62+
using var cursor = _session == null
63+
? await _database.ListCollectionNamesAsync(_options, cancellationToken)
64+
: await _database.ListCollectionNamesAsync(_session, _options, cancellationToken);
65+
66+
var collections = await cursor.ToListAsync(cancellationToken);
67+
68+
return OperationResult.FromResult(new BsonArray(collections));
69+
}
70+
catch (Exception ex)
71+
{
72+
return OperationResult.FromException(ex);
73+
}
74+
}
75+
}
76+
77+
public class UnifiedListCollectionNamesOperationBuilder
78+
{
79+
private readonly UnifiedEntityMap _entityMap;
80+
81+
public UnifiedListCollectionNamesOperationBuilder(UnifiedEntityMap entityMap)
82+
{
83+
_entityMap = entityMap;
84+
}
85+
86+
public UnifiedListCollectionNamesOperation Build(string targetDatabaseId, BsonDocument arguments)
87+
{
88+
var database = _entityMap.GetDatabase(targetDatabaseId);
89+
90+
var listCollectionsOptions = new ListCollectionNamesOptions();
91+
IClientSessionHandle session = null;
92+
93+
if (arguments != null)
94+
{
95+
foreach (var argument in arguments)
96+
{
97+
switch (argument.Name)
98+
{
99+
case "filter":
100+
listCollectionsOptions.Filter = argument.Value.AsBsonDocument;
101+
break;
102+
case "session":
103+
session = _entityMap.GetSession(argument.Value.AsString);
104+
break;
105+
default:
106+
throw new FormatException($"Invalid {nameof(UnifiedListCollectionNamesOperation)} argument name: '{argument.Name}'.");
107+
}
108+
}
109+
}
110+
111+
return new UnifiedListCollectionNamesOperation(database, listCollectionsOptions, session);
112+
}
113+
}
114+
}

tests/MongoDB.Driver.Tests/UnifiedTestOperations/UnifiedListCollectionsOperation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public UnifiedListCollectionsOperation Build(string targetDatabaseId, BsonDocume
106106
session = _entityMap.GetSession(argument.Value.AsString);
107107
break;
108108
default:
109-
throw new FormatException($"Invalid AssertIndexNotExistsOperation argument name: '{argument.Name}'.");
109+
throw new FormatException($"Invalid {nameof(UnifiedListCollectionsOperation)} argument name: '{argument.Name}'.");
110110
}
111111
}
112112
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Threading;
18+
using System.Threading.Tasks;
19+
using MongoDB.Bson;
20+
21+
namespace MongoDB.Driver.Tests.UnifiedTestOperations
22+
{
23+
public class UnifiedListDatabaseNamesOperation : IUnifiedEntityTestOperation
24+
{
25+
private readonly IMongoClient _client;
26+
private readonly ListDatabaseNamesOptions _options = null;
27+
private readonly IClientSessionHandle _session = null;
28+
29+
public UnifiedListDatabaseNamesOperation(
30+
IMongoClient client,
31+
ListDatabaseNamesOptions options,
32+
IClientSessionHandle session)
33+
{
34+
_client = client;
35+
_options = options;
36+
_session = session;
37+
}
38+
39+
public OperationResult Execute(CancellationToken cancellationToken)
40+
{
41+
try
42+
{
43+
using var cursor = _session == null
44+
? _client.ListDatabaseNames(_options, cancellationToken)
45+
: _client.ListDatabaseNames(_session, _options, cancellationToken);
46+
47+
var result = cursor.ToList(cancellationToken);
48+
49+
return OperationResult.FromResult(new BsonArray(result));
50+
}
51+
catch (Exception exception)
52+
{
53+
return OperationResult.FromException(exception);
54+
}
55+
}
56+
57+
public async Task<OperationResult> ExecuteAsync(CancellationToken cancellationToken)
58+
{
59+
try
60+
{
61+
using var cursor = _session == null
62+
? await _client.ListDatabaseNamesAsync(_options, cancellationToken)
63+
: await _client.ListDatabaseNamesAsync(_session, _options, cancellationToken);
64+
65+
var result = await cursor.ToListAsync(cancellationToken);
66+
67+
return OperationResult.FromResult(new BsonArray(result));
68+
}
69+
catch (Exception exception)
70+
{
71+
return OperationResult.FromException(exception);
72+
}
73+
}
74+
}
75+
76+
public class UnifiedListDatabaseNamesOperationBuilder
77+
{
78+
private readonly UnifiedEntityMap _entityMap;
79+
80+
public UnifiedListDatabaseNamesOperationBuilder(UnifiedEntityMap entityMap)
81+
{
82+
_entityMap = entityMap;
83+
}
84+
85+
public UnifiedListDatabaseNamesOperation Build(string targetClientId, BsonDocument arguments)
86+
{
87+
var client = _entityMap.GetClient(targetClientId);
88+
ListDatabaseNamesOptions options = null;
89+
IClientSessionHandle session = null;
90+
91+
if (arguments != null)
92+
{
93+
foreach (var argument in arguments)
94+
{
95+
switch (argument.Name)
96+
{
97+
case "filter":
98+
options ??= new ListDatabaseNamesOptions();
99+
options.Filter = new BsonDocumentFilterDefinition<BsonDocument>(argument.Value.AsBsonDocument);
100+
break;
101+
case "session":
102+
session = _entityMap.GetSession(argument.Value.AsString);
103+
break;
104+
default:
105+
throw new FormatException($"Invalid ListDatabasesOperation argument name: '{argument.Name}'.");
106+
}
107+
}
108+
}
109+
110+
return new UnifiedListDatabaseNamesOperation(client, options, session);
111+
}
112+
}
113+
}

tests/MongoDB.Driver.Tests/UnifiedTestOperations/UnifiedTestOperationFactory.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public IUnifiedTestOperation CreateOperation(string operationName, string target
7272
"close" => new UnifiedCloseClientOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
7373
"createChangeStream" => new UnifiedCreateChangeStreamOnClientOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
7474
"listDatabases" => new UnifiedListDatabasesOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
75+
"listDatabaseNames" => new UnifiedListDatabaseNamesOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
7576
_ => throw new FormatException($"Invalid method name: '{operationName}'."),
7677
},
7778
_ when _entityMap.HasCollection(targetEntityId) => operationName switch
@@ -107,6 +108,7 @@ public IUnifiedTestOperation CreateOperation(string operationName, string target
107108
"createChangeStream" => new UnifiedCreateChangeStreamOnDatabaseOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
108109
"dropCollection" => new UnifiedDropCollectionOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
109110
"listCollections" => new UnifiedListCollectionsOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
111+
"listCollectionNames" => new UnifiedListCollectionNamesOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
110112
"runCommand" => new UnifiedRunCommandOperationBuilder(_entityMap).Build(targetEntityId, operationArguments),
111113
_ => throw new FormatException($"Invalid method name: '{operationName}'."),
112114
},

0 commit comments

Comments
 (0)