Skip to content

Commit

Permalink
CSHARP-1438, CSHARP-1436: implemented read and write concern specific…
Browse files Browse the repository at this point in the history
…ation.
  • Loading branch information
craiggwilson committed Oct 15, 2015
1 parent 592b4ff commit 6157640
Show file tree
Hide file tree
Showing 50 changed files with 1,948 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ public void When_nothing_is_specified(string connectionString)
subject.MaxPoolSize.Should().Be(null);
subject.MinPoolSize.Should().Be(null);
subject.Password.Should().BeNull();
subject.ReadConcernLevel.Should().BeNull();
subject.ReadPreference.Should().BeNull();
subject.ReadPreferenceTags.Should().BeNull();
subject.ReplicaSet.Should().BeNull();
Expand Down Expand Up @@ -188,6 +189,7 @@ public void When_everything_is_specified()
"maxLifeTime=5ms;" +
"maxPoolSize=20;" +
"minPoolSize=15;" +
"readConcernLevel=majority;" +
"readPreference=primary;" +
"readPreferenceTags=dc:1;" +
"replicaSet=funny;" +
Expand Down Expand Up @@ -219,6 +221,7 @@ public void When_everything_is_specified()
subject.MaxPoolSize.Should().Be(20);
subject.MinPoolSize.Should().Be(15);
subject.Password.Should().Be("pass");
subject.ReadConcernLevel.Should().Be(ReadConcernLevel.Majority);
subject.ReadPreference.Should().Be(ReadPreferenceMode.Primary);
subject.ReadPreferenceTags.Single().Should().Be(new TagSet(new[] { new Tag("dc", "1") }));
subject.ReplicaSet.Should().Be("funny");
Expand Down Expand Up @@ -410,6 +413,16 @@ public void When_password_is_specified(string connectionString, string password)
subject.Password.Should().Be(password);
}

[Test]
[TestCase("mongodb://localhost?readConcernLevel=local", ReadConcernLevel.Local)]
[TestCase("mongodb://localhost?readConcernLevel=majority", ReadConcernLevel.Majority)]
public void When_readConcernLevel_is_specified(string connectionString, ReadConcernLevel readConcernLevel)
{
var subject = new ConnectionString(connectionString);

subject.ReadConcernLevel.Should().Be(readConcernLevel);
}

[Test]
[TestCase("mongodb://localhost?readPreference=primary", ReadPreferenceMode.Primary)]
[TestCase("mongodb://localhost?readPreference=primaryPreferred", ReadPreferenceMode.PrimaryPreferred)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,11 @@ public void UseCursor_should_have_the_correct_value()

[Test]
public void CreateCommand_should_create_the_correct_command(
[Values("2.4.0", "2.6.0", "2.8.0")] string serverVersion,
[Values("2.4.0", "2.6.0", "2.8.0", "3.0.0", "3.2.0")] string serverVersion,
[Values(null, false, true)] bool? allowDiskUse,
[Values(null, 10, 20)] int? batchSize,
[Values(null, 2000)] int? maxTime,
[Values(null, ReadConcernLevel.Local, ReadConcernLevel.Majority)] ReadConcernLevel? readConcernLevel,
[Values(null, false, true)] bool? useCursor)
{
var semanticServerVersion = SemanticVersion.Parse(serverVersion);
Expand All @@ -132,6 +133,7 @@ public void CreateCommand_should_create_the_correct_command(
AllowDiskUse = allowDiskUse,
BatchSize = batchSize,
MaxTime = maxTime.HasValue ? TimeSpan.FromMilliseconds(maxTime.Value) : (TimeSpan?)null,
ReadConcern = new ReadConcern(readConcernLevel),
UseCursor = useCursor
};

Expand All @@ -143,6 +145,11 @@ public void CreateCommand_should_create_the_correct_command(
{ "maxTimeMS", () => maxTime.Value, maxTime.HasValue }
};

if (subject.ReadConcern.ShouldBeSent(semanticServerVersion))
{
expectedResult["readConcern"] = subject.ReadConcern.ToBsonDocument();
}

if (semanticServerVersion >= new SemanticVersion(2, 6, 0) && useCursor.GetValueOrDefault(true))
{
expectedResult["cursor"] = new BsonDocument
Expand All @@ -151,9 +158,16 @@ public void CreateCommand_should_create_the_correct_command(
};
}

var result = subject.CreateCommand(semanticServerVersion);

result.Should().Be(expectedResult);
if (semanticServerVersion < new SemanticVersion(3, 2, 0) && subject.ReadConcern.Level.GetValueOrDefault(ReadConcernLevel.Local) != ReadConcernLevel.Local)
{
Action act = () => subject.CreateCommand(semanticServerVersion);
act.ShouldThrow<MongoClientException>();
}
else
{
var result = subject.CreateCommand(semanticServerVersion);
result.Should().Be(expectedResult);
}
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ public void Constructor_should_throw_when_message_encoder_settings_is_null()
}

[Test]
public void CreateCommand_should_create_the_correct_command()
public void CreateCommand_should_create_the_correct_command(
[Values("3.0.0", "3.2.0")] string serverVersion,
[Values(null, ReadConcernLevel.Local, ReadConcernLevel.Majority)] ReadConcernLevel? readConcernLevel)
{
var semanticServerVersion = SemanticVersion.Parse(serverVersion);
var filter = new BsonDocument("x", 1);
var hint = "funny";
var limit = 10;
Expand All @@ -69,9 +72,21 @@ public void CreateCommand_should_create_the_correct_command()
{ "maxTimeMS", maxTime.TotalMilliseconds }
};

var result = subject.CreateCommand();
if (subject.ReadConcern.ShouldBeSent(semanticServerVersion))
{
expectedResult["readConcern"] = subject.ReadConcern.ToBsonDocument();
}

result.Should().Be(expectedResult);
if (semanticServerVersion < new SemanticVersion(3, 2, 0) && subject.ReadConcern.Level.GetValueOrDefault(ReadConcernLevel.Local) != ReadConcernLevel.Local)
{
Action act = () => subject.CreateCommand(semanticServerVersion);
act.ShouldThrow<MongoClientException>();
}
else
{
var result = subject.CreateCommand(semanticServerVersion);
result.Should().Be(expectedResult);
}
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Core.Misc;
using NUnit.Framework;

namespace MongoDB.Driver.Core.Operations
Expand Down Expand Up @@ -70,12 +71,16 @@ public void Constructor_should_throw_when_message_encoder_settings_is_null()
}

[Test]
public void CreateCommand_should_create_the_correct_command()
public void CreateCommand_should_create_the_correct_command(
[Values("3.0.0", "3.2.0")] string serverVersion,
[Values(null, ReadConcernLevel.Local, ReadConcernLevel.Majority)] ReadConcernLevel? readConcernLevel)
{
var semanticServerVersion = SemanticVersion.Parse(serverVersion);
var subject = new DistinctOperation<int>(_collectionNamespace, _valueSerializer, _fieldName, _messageEncoderSettings)
{
Filter = new BsonDocument("x", 1),
MaxTime = TimeSpan.FromSeconds(20),
ReadConcern = new ReadConcern(readConcernLevel)
};

var expectedResult = new BsonDocument
Expand All @@ -85,9 +90,22 @@ public void CreateCommand_should_create_the_correct_command()
{ "query", BsonDocument.Parse("{ x: 1 }") },
{ "maxTimeMS", 20000 }
};
var result = subject.CreateCommand();

result.Should().Be(expectedResult);
if (subject.ReadConcern.ShouldBeSent(semanticServerVersion))
{
expectedResult["readConcern"] = subject.ReadConcern.ToBsonDocument();
}

if (semanticServerVersion < new SemanticVersion(3, 2, 0) && subject.ReadConcern.Level.GetValueOrDefault(ReadConcernLevel.Local) != ReadConcernLevel.Local)
{
Action act = () => subject.CreateCommand(semanticServerVersion);
act.ShouldThrow<MongoClientException>();
}
else
{
var result = subject.CreateCommand(semanticServerVersion);
result.Should().Be(expectedResult);
}
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Core.Clusters;
using MongoDB.Driver.Core.Misc;
using MongoDB.Driver.Core.Servers;
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
using NUnit.Framework;
Expand Down Expand Up @@ -122,7 +123,7 @@ public void constructor_should_initialize_instance()
subject.NoCursorTimeout.Should().NotHaveValue();
subject.OplogReplay.Should().NotHaveValue();
subject.Projection.Should().BeNull();
subject.ReadConcern.Should().NotHaveValue();
subject.ReadConcern.Should().Be(ReadConcern.Default);
subject.ResultSerializer.Should().Be(BsonDocumentSerializer.Instance);
subject.ReturnKey.Should().NotHaveValue();
subject.ShowRecordId.Should().NotHaveValue();
Expand Down Expand Up @@ -380,17 +381,17 @@ public void CreateCommand_should_return_expected_result_when_projection_is_provi

[Test]
public void CreateCommand_should_return_expected_result_when_readConcern_is_provided(
[Values(0, 1)]
int value)
[Values("{level: 'local'}", "{level: 'majority'}")]
string readConcernJson)
{
var subject = new FindCommandOperation<BsonDocument>(_collectionNamespace, BsonDocumentSerializer.Instance, _messageEncoderSettings);
subject.ReadConcern = value;
subject.ReadConcern = ReadConcern.FromBsonDocument(BsonDocument.Parse(readConcernJson));
var reflector = new Reflector(subject);
var serverDescription = CreateServerDescription();

var result = reflector.CreateCommand(serverDescription, null);

result.Should().Be($"{{ find : '{_collectionNamespace.CollectionName}', readConcern : {value} }}");
result.Should().Be($"{{ find : '{_collectionNamespace.CollectionName}', readConcern : {readConcernJson} }}");
}

[Test]
Expand Down Expand Up @@ -746,16 +747,14 @@ public void Projection_get_and_set_should_work(
}

[Test]
public void ReadConcern_get_and_set_should_work(
[Values(null, 0, 1)]
int? value)
public void ReadConcern_get_and_set_should_work()
{
var subject = new FindCommandOperation<BsonDocument>(_collectionNamespace, BsonDocumentSerializer.Instance, _messageEncoderSettings);

subject.ReadConcern = value;
subject.ReadConcern = ReadConcern.Majority;
var result = subject.ReadConcern;

result.Should().Be(value);
result.Should().Be(ReadConcern.Majority);
}

[Test]
Expand Down Expand Up @@ -866,7 +865,7 @@ private ServerDescription CreateServerDescription(ServerType type = ServerType.S
var clusterId = new ClusterId(1);
var endPoint = new DnsEndPoint("localhost", 27017);
var serverId = new ServerId(clusterId, endPoint);
return new ServerDescription(serverId, endPoint, type: type);
return new ServerDescription(serverId, endPoint, type: type, version: new SemanticVersion(3, 2, 0));
}

private void EnsureTestData()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public void constructor_should_initialize_instance()
subject.NoCursorTimeout.Should().NotHaveValue();
subject.OplogReplay.Should().NotHaveValue();
subject.Projection.Should().BeNull();
subject.ReadConcern.Should().NotHaveValue();
subject.ReadConcern.Should().Be(ReadConcern.Default);
subject.ResultSerializer.Should().Be(BsonDocumentSerializer.Instance);
subject.ReturnKey.Should().NotHaveValue();
subject.ShowRecordId.Should().NotHaveValue();
Expand Down Expand Up @@ -171,7 +171,7 @@ public void CreateFindCommandOperation_should_return_expected_result()
subject.NoCursorTimeout = true;
subject.OplogReplay = true;
subject.Projection = new BsonDocument("projection", 1);
subject.ReadConcern = 5;
subject.ReadConcern = ReadConcern.Local;
subject.ReturnKey = true;
subject.ShowRecordId = true;
subject.SingleBatch = true;
Expand Down Expand Up @@ -211,7 +211,10 @@ public void CreateFindCommandOperation_should_return_expected_result()
[Test]
public void CreateFindCommandOperation_should_return_expected_result_when_modifiers_are_provided()
{
var subject = new FindOperation<BsonDocument>(_collectionNamespace, BsonDocumentSerializer.Instance, _messageEncoderSettings);
var subject = new FindOperation<BsonDocument>(_collectionNamespace, BsonDocumentSerializer.Instance, _messageEncoderSettings)
{
ReadConcern = ReadConcern.Majority
};
subject.Modifiers = new BsonDocument
{
{ "$hint", "x_1" },
Expand All @@ -231,6 +234,7 @@ public void CreateFindCommandOperation_should_return_expected_result_when_modifi
result.MaxScan.Should().Be(subject.Modifiers["$maxScan"].AsInt32);
result.MaxTime.Should().Be(TimeSpan.FromMilliseconds(subject.Modifiers["$maxTimeMS"].AsInt32));
result.Min.Should().Be(subject.Modifiers["$min"].AsBsonDocument);
result.ReadConcern.Should().Be(subject.ReadConcern);
result.ShowRecordId.Should().Be(subject.Modifiers["$showDiskLoc"].AsBoolean);
result.Snapshot.Should().Be(subject.Modifiers["$snapshot"].AsBoolean);
result.Sort.Should().Be(subject.Modifiers["$orderby"].AsBsonDocument);
Expand All @@ -254,7 +258,7 @@ public void CreateFindOpcodeOperation_should_return_expected_result()
subject.NoCursorTimeout = true;
subject.OplogReplay = true;
subject.Projection = new BsonDocument("projection", 1);
subject.ReadConcern = 5;
subject.ReadConcern = ReadConcern.Local;
subject.ReturnKey = true;
subject.ShowRecordId = true;
subject.SingleBatch = false;
Expand Down Expand Up @@ -367,6 +371,21 @@ public void Execute_should_find_documents_matching_options(
result.Should().HaveCount(1);
}

[Test]
[RequiresServer("EnsureTestData", VersionLessThan = "3.1.0")]
public void Execute_should_raise_an_error_when_an_unsupported_read_concern_is_specified(
[Values(false, true)]
bool async)
{
var subject = new FindOperation<BsonDocument>(_collectionNamespace, BsonDocumentSerializer.Instance, _messageEncoderSettings)
{
ReadConcern = ReadConcern.Majority
};

Action act = () => ExecuteOperation(subject, async);
act.ShouldThrow<MongoClientException>();
}

[Test]
public void ExecuteAsync_should_throw_when_binding_is_null()
{
Expand Down Expand Up @@ -566,16 +585,14 @@ public void Projection_get_and_set_should_work(
}

[Test]
public void ReadConcern_get_and_set_should_work(
[Values(null, 0, 1)]
int? value)
public void ReadConcern_get_and_set_should_work()
{
var subject = new FindOperation<BsonDocument>(_collectionNamespace, BsonDocumentSerializer.Instance, _messageEncoderSettings);

subject.ReadConcern = value;
subject.ReadConcern = ReadConcern.Local;
var result = subject.ReadConcern;

result.Should().Be(value);
result.Should().Be(ReadConcern.Local);
}

[Test]
Expand Down
13 changes: 13 additions & 0 deletions src/MongoDB.Driver.Core.Tests/MongoDB.Driver.Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@
<Compile Include="Core\Clusters\SingleServerClusterTests.cs" />
<Compile Include="SetUpFixture.cs" />
<Compile Include="Specifications\connection-string\TestRunner.cs" />
<Compile Include="Specifications\read-write-concern\DocumentTestRunner.cs" />
<Compile Include="Specifications\read-write-concern\ConnectionStringTestRunner.cs" />
<Compile Include="Specifications\server-discovery-and-monitoring\TestRunner.cs" />
<Compile Include="Specifications\server-selection\ServerSelectionTestRunner.cs" />
<Compile Include="Specifications\server-selection\RttTestRunner.cs" />
Expand Down Expand Up @@ -192,6 +194,7 @@
<Compile Include="Core\Misc\SemanticVersionTests.cs" />
<Compile Include="Core\Misc\InterlockedInt32Tests.cs" />
<Compile Include="Core\Misc\TimeSpanParserTests.cs" />
<Compile Include="ReadConcernTests.cs" />
<Compile Include="WriteConcernTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Core\Servers\ServerDescriptionTests.cs" />
Expand Down Expand Up @@ -259,6 +262,16 @@
<EmbeddedResource Include="Specifications\connection-string\tests\valid-unix_socket-relative.yml" />
<EmbeddedResource Include="Specifications\connection-string\tests\valid-warnings.json" />
<EmbeddedResource Include="Specifications\connection-string\tests\valid-warnings.yml" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\connection-string\read-concern.json" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\connection-string\read-concern.yml" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\connection-string\write-concern.json" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\connection-string\write-concern.yml" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\document\read-concern.json" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\document\read-concern.yml" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\document\write-concern.json" />
<EmbeddedResource Include="Specifications\read-write-concern\tests\document\write-concern.yml" />
<None Include="Specifications\read-write-concern\tests\Makefile" />
<None Include="Specifications\read-write-concern\tests\README.rst" />
<None Include="Specifications\server-discovery-and-monitoring\tests\Makefile" />
<None Include="Specifications\server-discovery-and-monitoring\tests\README.rst" />
<EmbeddedResource Include="Specifications\server-discovery-and-monitoring\tests\rs\discovery.json" />
Expand Down
Loading

0 comments on commit 6157640

Please sign in to comment.