Skip to content

Commit

Permalink
CosmosClientOptions: Fixes a bug causing ConsistentPrefix to be conve…
Browse files Browse the repository at this point in the history
…rt to BoundedStaleness (#2198)

* Fixes client option ConsistentPrefix mapping

* Fixed unit test
  • Loading branch information
j82w authored Feb 8, 2021
1 parent 540070c commit 804693a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 36 deletions.
16 changes: 1 addition & 15 deletions Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -715,21 +715,7 @@ internal ConnectionPolicy GetConnectionPolicy()
return null;
}

switch (this.ConsistencyLevel.Value)
{
case Cosmos.ConsistencyLevel.BoundedStaleness:
return Documents.ConsistencyLevel.BoundedStaleness;
case Cosmos.ConsistencyLevel.ConsistentPrefix:
return Documents.ConsistencyLevel.BoundedStaleness;
case Cosmos.ConsistencyLevel.Eventual:
return Documents.ConsistencyLevel.Eventual;
case Cosmos.ConsistencyLevel.Session:
return Documents.ConsistencyLevel.Session;
case Cosmos.ConsistencyLevel.Strong:
return Documents.ConsistencyLevel.Strong;
default:
throw new ArgumentException($"Unsupported ConsistencyLevel {this.ConsistencyLevel.Value}");
}
return (Documents.ConsistencyLevel)this.ConsistencyLevel.Value;
}

internal static string GetAccountEndpoint(string connectionString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,33 @@ public async Task CreateDropItemTest()
Assert.IsTrue(response.Diagnostics.GetClientElapsedTime() > TimeSpan.Zero);
}

[TestMethod]
public async Task ClientConsistencyTestAsync()
{
List<Cosmos.ConsistencyLevel> cosmosLevels = Enum.GetValues(typeof(Cosmos.ConsistencyLevel)).Cast<Cosmos.ConsistencyLevel>().ToList();

foreach(Cosmos.ConsistencyLevel consistencyLevel in cosmosLevels)
{
RequestHandlerHelper handlerHelper = new RequestHandlerHelper();
using CosmosClient cosmosClient = TestCommon.CreateCosmosClient(x =>
x.WithConsistencyLevel(consistencyLevel).AddCustomHandlers(handlerHelper));
Container consistencyContainer = cosmosClient.GetContainer(this.database.Id, this.Container.Id);

int requestCount = 0;
handlerHelper.UpdateRequestMessage = (request) =>
{
Assert.AreEqual(consistencyLevel.ToString(), request.Headers[HttpConstants.HttpHeaders.ConsistencyLevel]);
requestCount++;
};

ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();
ItemResponse<ToDoActivity> response = await consistencyContainer.CreateItemAsync<ToDoActivity>(item: testItem);
response = await consistencyContainer.ReadItemAsync<ToDoActivity>(testItem.id, new Cosmos.PartitionKey(testItem.pk));

Assert.AreEqual(2, requestCount);
}
}

[TestMethod]
public async Task NegativeCreateItemTest()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Microsoft.Azure.Cosmos.Tests
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -50,6 +51,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
int maxTcpConnectionsPerEndpoint = 65535;
Cosmos.PortReuseMode portReuseMode = Cosmos.PortReuseMode.PrivatePortPool;
IWebProxy webProxy = new TestWebProxy();
Cosmos.ConsistencyLevel consistencyLevel = Cosmos.ConsistencyLevel.ConsistentPrefix;

CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(
accountEndpoint: endpoint,
Expand Down Expand Up @@ -77,6 +79,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.IsFalse(clientOptions.LimitToEndpoint);
Assert.IsFalse(clientOptions.EnableTcpConnectionEndpointRediscovery);
Assert.IsNull(clientOptions.HttpClientFactory);
Assert.AreNotEqual(consistencyLevel, clientOptions.ConsistencyLevel);

//Verify GetConnectionPolicy returns the correct values for default
ConnectionPolicy policy = clientOptions.GetConnectionPolicy();
Expand All @@ -91,6 +94,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.IsTrue(policy.EnableEndpointDiscovery);
Assert.IsFalse(policy.EnableTcpConnectionEndpointRediscovery);
Assert.IsNull(policy.HttpClientFactory);
Assert.AreNotEqual(Cosmos.ConsistencyLevel.Session, clientOptions.ConsistencyLevel);

cosmosClientBuilder.WithApplicationRegion(region)
.WithConnectionModeGateway(maxConnections, webProxy)
Expand All @@ -100,7 +104,8 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
.WithApiType(apiType)
.WithThrottlingRetryOptions(maxRetryWaitTime, maxRetryAttemptsOnThrottledRequests)
.WithBulkExecution(true)
.WithSerializerOptions(cosmosSerializerOptions);
.WithSerializerOptions(cosmosSerializerOptions)
.WithConsistencyLevel(consistencyLevel);

cosmosClient = cosmosClientBuilder.Build(new MockDocumentClient());
clientOptions = cosmosClient.ClientOptions;
Expand All @@ -121,6 +126,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.AreEqual(cosmosSerializerOptions.Indented, clientOptions.SerializerOptions.Indented);
Assert.IsTrue(object.ReferenceEquals(webProxy, clientOptions.WebProxy));
Assert.IsTrue(clientOptions.AllowBulkExecution);
Assert.AreEqual(consistencyLevel, clientOptions.ConsistencyLevel);

//Verify GetConnectionPolicy returns the correct values
policy = clientOptions.GetConnectionPolicy();
Expand All @@ -133,6 +139,7 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
Assert.IsTrue(policy.UseMultipleWriteLocations);
Assert.AreEqual(maxRetryAttemptsOnThrottledRequests, policy.RetryOptions.MaxRetryAttemptsOnThrottledRequests);
Assert.AreEqual((int)maxRetryWaitTime.TotalSeconds, policy.RetryOptions.MaxRetryWaitTimeInSeconds);
Assert.AreEqual((Documents.ConsistencyLevel)consistencyLevel, clientOptions.GetDocumentsConsistencyLevel());

IReadOnlyList<string> preferredLocations = new List<string>() { Regions.AustraliaCentral, Regions.AustraliaCentral2 };
//Verify Direct Mode settings
Expand Down Expand Up @@ -170,6 +177,32 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated()
CollectionAssert.AreEqual(preferredLocations.ToArray(), policy.PreferredLocations.ToArray());
}

[TestMethod]
public void VerifyConsisentencyLevels()
{
List<Cosmos.ConsistencyLevel> cosmosLevels = Enum.GetValues(typeof(Cosmos.ConsistencyLevel)).Cast<Cosmos.ConsistencyLevel>().ToList();
List<Documents.ConsistencyLevel> documentLevels = Enum.GetValues(typeof(Documents.ConsistencyLevel)).Cast<Documents.ConsistencyLevel>().ToList();
CollectionAssert.AreEqual(cosmosLevels, documentLevels, new EnumComparer(), "Document consistency level is different from cosmos consistency level");

foreach (Cosmos.ConsistencyLevel consistencyLevel in cosmosLevels)
{
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
ConsistencyLevel = consistencyLevel
};

Assert.AreEqual((int)consistencyLevel, (int)cosmosClientOptions.GetDocumentsConsistencyLevel());
Assert.AreEqual(consistencyLevel.ToString(), cosmosClientOptions.GetDocumentsConsistencyLevel().ToString());
}

CosmosClientOptions cosmosClientOptionsNull = new CosmosClientOptions()
{
ConsistencyLevel = null
};

Assert.IsNull(cosmosClientOptionsNull.GetDocumentsConsistencyLevel());
}

[TestMethod]
public void VerifyPortReuseModeIsSyncedWithDirect()
{
Expand Down Expand Up @@ -442,5 +475,19 @@ public bool IsBypassed(Uri host)
return false;
}
}

private class EnumComparer : IComparer
{
public int Compare(object x, object y)
{
if ((int)x == (int)y &&
string.Equals(x.ToString(), y.ToString()))
{
return 0;
}

return 1;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -222,30 +222,33 @@ public async Task QueryRequestOptionsSessionToken()
[TestMethod]
public async Task ConsistencyLevelClient()
{
Cosmos.ConsistencyLevel clientLevel = Cosmos.ConsistencyLevel.Eventual;
using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(
accountConsistencyLevel: Cosmos.ConsistencyLevel.Strong,
customizeClientBuilder: builder => builder.WithConsistencyLevel(clientLevel));

TestHandler testHandler = new TestHandler((request, cancellationToken) =>
List<Cosmos.ConsistencyLevel> cosmosLevels = Enum.GetValues(typeof(Cosmos.ConsistencyLevel)).Cast<Cosmos.ConsistencyLevel>().ToList();
foreach(Cosmos.ConsistencyLevel clientLevel in cosmosLevels)
{
Assert.AreEqual(clientLevel.ToString(), request.Headers[HttpConstants.HttpHeaders.ConsistencyLevel]);
return TestHandler.ReturnSuccess();
});
using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(
accountConsistencyLevel: Cosmos.ConsistencyLevel.Strong,
customizeClientBuilder: builder => builder.WithConsistencyLevel(clientLevel));

RequestInvokerHandler invoker = new RequestInvokerHandler(client, requestedClientConsistencyLevel: client.ClientOptions.ConsistencyLevel)
{
InnerHandler = testHandler
};
TestHandler testHandler = new TestHandler((request, cancellationToken) =>
{
Assert.AreEqual(clientLevel.ToString(), request.Headers[HttpConstants.HttpHeaders.ConsistencyLevel]);
return TestHandler.ReturnSuccess();
});

RequestMessage requestMessage = new RequestMessage(HttpMethod.Get, new System.Uri("https://dummy.documents.azure.com:443/dbs"))
{
ResourceType = ResourceType.Document
};
requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]");
requestMessage.OperationType = OperationType.Read;
RequestInvokerHandler invoker = new RequestInvokerHandler(client, requestedClientConsistencyLevel: client.ClientOptions.ConsistencyLevel)
{
InnerHandler = testHandler
};

await invoker.SendAsync(requestMessage, new CancellationToken());
RequestMessage requestMessage = new RequestMessage(HttpMethod.Get, new System.Uri("https://dummy.documents.azure.com:443/dbs"))
{
ResourceType = ResourceType.Document
};
requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]");
requestMessage.OperationType = OperationType.Read;

await invoker.SendAsync(requestMessage, new CancellationToken());
}
}

[TestMethod]
Expand Down

0 comments on commit 804693a

Please sign in to comment.