Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CosmosClientOptions: Fixes a bug causing ConsistentPrefix to be convert to BoundedStaleness #2198

Merged
merged 5 commits into from
Feb 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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