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

[Internal] LocalQuorum: Refactors override (i.e. strong) to allow from any account consistency #3753

Merged
merged 1 commit into from
Mar 10, 2023
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
9 changes: 1 addition & 8 deletions Microsoft.Azure.Cosmos/src/ValidationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public static bool IsValidConsistencyLevelOverwrite(
{
if (isLocalQuorumConsistency &&
ValidationHelpers.IsLocalQuorumConsistency(
backendConsistency: backendConsistency,
desiredConsistency: desiredConsistency,
operationType: operationType,
resourceType: resourceType))
Expand Down Expand Up @@ -109,21 +108,15 @@ private static bool IsValidConsistencyLevelOverwrite(
/// <summary>
/// Condition to check Quorum(i.e. Strong) read with either an eventual consistency account or a consistent prefix account.
/// </summary>
/// <param name="backendConsistency"></param>
/// <param name="desiredConsistency"></param>
/// <param name="operationType"></param>
/// <param name="resourceType"></param>
/// <returns>true/false</returns>
private static bool IsLocalQuorumConsistency(Documents.ConsistencyLevel backendConsistency,
private static bool IsLocalQuorumConsistency(
Documents.ConsistencyLevel desiredConsistency,
OperationType? operationType,
ResourceType? resourceType)
{
if (backendConsistency != Documents.ConsistencyLevel.Eventual && backendConsistency != Documents.ConsistencyLevel.ConsistentPrefix)
{
return false;
}

if (desiredConsistency != Documents.ConsistencyLevel.Strong)
{
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,81 @@

namespace Microsoft.Azure.Cosmos.Tests
{
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class ValidationHelpersTest
{
[TestMethod]
[DataRow(true, ConsistencyLevel.Eventual, ConsistencyLevel.Strong)]
[DataRow(true, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong)]
[DataRow(false, ConsistencyLevel.Eventual, ConsistencyLevel.BoundedStaleness)]
[DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.BoundedStaleness)]
[DataRow(false, ConsistencyLevel.Session, ConsistencyLevel.Strong)]
[DataRow(false, ConsistencyLevel.BoundedStaleness, ConsistencyLevel.Strong)]
public void TestIsValidConsistencyLevelOverwrite(bool isValidConsistencyLevelOverwrite,
ConsistencyLevel backendConsistencyLevel,
ConsistencyLevel desiredConsistencyLevel)
[DataRow(true)]
[DataRow(false)]
public void TestIsValidConsistencyLevelOverwrite_AllCombinations(
bool isValidConsistencyLevelOverwrite)
{
bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel,
desiredConsistencyLevel,
true,
Documents.OperationType.Read,
Documents.ResourceType.Document);
ConsistencyLevel[] allConsistencies = Enum.GetValues<ConsistencyLevel>();

// All overrides when target is 'Strong' are VALID
ConsistencyLevel desiredConsistencyLevel = ConsistencyLevel.Strong;
foreach (ConsistencyLevel backendConsistencyLevel in allConsistencies)
{
if (backendConsistencyLevel == desiredConsistencyLevel)
{
continue;
}

foreach (KeyValuePair<Documents.OperationType, bool> entry in ValidationHelpersTest.GetPerOperationExpectations())
{
bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel,
desiredConsistencyLevel,
isValidConsistencyLevelOverwrite,
(Documents.OperationType)entry.Key,
Documents.ResourceType.Document);

Assert.AreEqual(isValidConsistencyLevelOverwrite, result);
Assert.AreEqual(isValidConsistencyLevelOverwrite && entry.Value, result,
$"({isValidConsistencyLevelOverwrite}, {backendConsistencyLevel}, {desiredConsistencyLevel}) ({entry.Key}, {entry.Value})");
}
}
}

[TestMethod]
[DataRow(false, ConsistencyLevel.Eventual, ConsistencyLevel.Strong)]
[DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong)]
public void TestIsValidConsistencyLevelOverwrite_OnlyWhenSpecifyingExplicitOverwrite(bool isValidConsistencyLevelOverwrite,
[DataRow(ConsistencyLevel.Eventual, ConsistencyLevel.BoundedStaleness)]
[DataRow(ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.BoundedStaleness)]
[DataRow(ConsistencyLevel.Session, ConsistencyLevel.BoundedStaleness)]
public void TestIsValidConsistencyLevelOverwrite_BoundedPromotionsRejected(
ConsistencyLevel backendConsistencyLevel,
ConsistencyLevel desiredConsistencyLevel)
{
bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel,
desiredConsistencyLevel,
false,
Documents.OperationType.Read,
Documents.ResourceType.Document);
foreach (KeyValuePair<Documents.OperationType, bool> entry in ValidationHelpersTest.GetPerOperationExpectations())
{
bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel,
desiredConsistencyLevel,
true,
(Documents.OperationType)entry.Key,
Documents.ResourceType.Document);

Assert.AreEqual(isValidConsistencyLevelOverwrite, result);
Assert.AreEqual(false, result,
$"({backendConsistencyLevel}, {desiredConsistencyLevel}) ({entry.Key}, {entry.Value})");
}
}

[TestMethod]
[DataRow(true, ConsistencyLevel.Eventual, ConsistencyLevel.Strong, Documents.OperationType.Read)]
[DataRow(true, ConsistencyLevel.Eventual, ConsistencyLevel.Strong, Documents.OperationType.ReadFeed)]
[DataRow(true, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.Query)]
[DataRow(true, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.SqlQuery)]
[DataRow(false, ConsistencyLevel.Eventual, ConsistencyLevel.Strong, Documents.OperationType.QueryPlan)]
[DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.Create)]
[DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.Batch)]
public void TestIsValidConsistencyLevelOverwrite_OnlyAllowedForCertainOperationTypes(
bool isValidConsistencyLevelOverwrite,
ConsistencyLevel backendConsistencyLevel,
ConsistencyLevel desiredConsistencyLevel,
dynamic operationType)
private static Dictionary<Documents.OperationType, bool> GetPerOperationExpectations()
{
bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel,
desiredConsistencyLevel,
true,
(Documents.OperationType) operationType,
Documents.ResourceType.Document);
Dictionary<Documents.OperationType, bool> perOperationOverride = new Dictionary<Documents.OperationType, bool>();

foreach (Documents.OperationType operationType in Enum.GetValues<Documents.OperationType>())
{
perOperationOverride.Add(
operationType,
Documents.OperationTypeExtensions.IsReadOperation(operationType)
&& operationType != Documents.OperationType.Head
&& operationType != Documents.OperationType.HeadFeed
&& operationType != Documents.OperationType.QueryPlan);
}

Assert.AreEqual(isValidConsistencyLevelOverwrite, result);
return perOperationOverride;
}
}
}