diff --git a/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs b/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs index 5c23191678..7ed8862878 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs @@ -466,7 +466,26 @@ public System.Text.Json.JsonSerializerOptions UseSystemTextJsonSerializerWithOpt /// The default value for this parameter is 'false'. /// internal bool EnableStreamPassThrough { get; set; } = false; - + + /// + /// Gets or sets a value indicating whether to use length-aware range comparators for EPK range comparisons. + /// Length-aware range comparators were introduced in Range class to handle EPK range comparisons correctly + /// in the case of a container's physical partition set consisting of fully and partially specified EPK values. + /// By default, length-aware range comparator is enabled. Refer to Range.cs in Msdata project for more details. + /// Range.LengthAwareMinComparer/LengthAwareMaxComparer. + /// Setting the value to false will disable length-aware range comparator and switch to using the regular + /// Range.MinComparer/MaxComparer. + /// + /// + /// The default value is true. + /// + internal bool UseLengthAwareRangeComparer { get; set; } = +#if !INTERNAL + true; +#else + false; +#endif + /// /// (Direct/TCP) Controls the amount of idle time after which unused connections are closed. /// diff --git a/Microsoft.Azure.Cosmos/src/DocumentClient.cs b/Microsoft.Azure.Cosmos/src/DocumentClient.cs index 2dc3f36f2b..f4fbcfca01 100644 --- a/Microsoft.Azure.Cosmos/src/DocumentClient.cs +++ b/Microsoft.Azure.Cosmos/src/DocumentClient.cs @@ -457,6 +457,7 @@ internal DocumentClient(Uri serviceEndpoint, /// This is distributed tracing flag /// This is the chaos interceptor used for fault injection /// A boolean flag indicating if stack trace optimization is enabled. + /// A boolean flag indicating if length-aware range comparators should be used for EPK range comparisons. /// /// The service endpoint can be obtained from the Azure Management Portal. /// If you are connecting using one of the Master Keys, these can be obtained along with the endpoint from the Azure Management Portal @@ -486,7 +487,8 @@ internal DocumentClient(Uri serviceEndpoint, RemoteCertificateValidationCallback remoteCertificateValidationCallback = null, CosmosClientTelemetryOptions cosmosClientTelemetryOptions = null, IChaosInterceptorFactory chaosInterceptorFactory = null, - bool enableAsyncCacheExceptionNoSharing = true) + bool enableAsyncCacheExceptionNoSharing = true, + bool useLengthAwareRangeComparer = false) { if (sendingRequestEventArgs != null) { @@ -514,6 +516,7 @@ internal DocumentClient(Uri serviceEndpoint, enableAsyncCacheExceptionNoSharing: this.enableAsyncCacheExceptionNoSharing); this.chaosInterceptorFactory = chaosInterceptorFactory; this.chaosInterceptor = chaosInterceptorFactory?.CreateInterceptor(this); + this.UseLengthAwareRangeComparer = useLengthAwareRangeComparer; this.Initialize( serviceEndpoint: serviceEndpoint, @@ -1101,7 +1104,7 @@ private async Task GetInitializationTaskAsync(IStoreClientFactory storeCli retryPolicy: this.retryPolicy, telemetryToServiceHelper: this.telemetryToServiceHelper, enableAsyncCacheExceptionNoSharing: this.enableAsyncCacheExceptionNoSharing); - this.partitionKeyRangeCache = new PartitionKeyRangeCache(this, this.GatewayStoreModel, this.collectionCache, this.GlobalEndpointManager, this.enableAsyncCacheExceptionNoSharing); + this.partitionKeyRangeCache = new PartitionKeyRangeCache(this, this.GatewayStoreModel, this.collectionCache, this.GlobalEndpointManager, this.UseLengthAwareRangeComparer, this.enableAsyncCacheExceptionNoSharing); this.ResetSessionTokenRetryPolicy = new ResetSessionTokenRetryPolicyFactory(this.sessionContainer, this.collectionCache, this.retryPolicy); gatewayStoreModel.SetCaches(this.partitionKeyRangeCache, this.collectionCache); @@ -1229,7 +1232,9 @@ internal ApiType ApiType get; private set; } - internal bool UseMultipleWriteLocations { get; private set; } + internal bool UseMultipleWriteLocations { get; private set; } + + internal bool UseLengthAwareRangeComparer { get; private set; } /// /// Gets the endpoint Uri for the service endpoint from the Azure Cosmos DB service. diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs index 4a1c518fb9..b1419eaff1 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs @@ -517,9 +517,9 @@ private static TryCatch TryCreatePassthroughQueryExecutionC isMinInclusive: true, isMaxInclusive: false))) .ToList(), + partitionKey: inputParameters.PartitionKey, queryPaginationOptions: new QueryExecutionOptions( pageSizeHint: inputParameters.MaxItemCount), - partitionKey: inputParameters.PartitionKey, containerQueryProperties: containerQueryProperties, maxConcurrency: inputParameters.MaxConcurrency, prefetchPolicy: PrefetchPolicy.PrefetchSinglePage, @@ -926,6 +926,7 @@ public static InputParameters Create( public bool EnableOptimisticDirectExecution { get; } public bool IsHybridSearchQueryPlanOptimizationDisabled { get; } public bool EnableDistributedQueryGatewayMode { get; } + public bool UseLengthAwareRangeComparer { get; } public InputParameters WithContinuationToken(CosmosElement token) { diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs index 18d8c59a0b..67b9c62016 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs @@ -15,13 +15,15 @@ public ContainerQueryProperties( IReadOnlyList> effectivePartitionKeyRanges, PartitionKeyDefinition partitionKeyDefinition, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy, - Cosmos.GeospatialType geospatialType) + Cosmos.GeospatialType geospatialType, + bool useLengthAwareRangeComparer) { this.ResourceId = resourceId; this.EffectiveRangesForPartitionKey = effectivePartitionKeyRanges; this.PartitionKeyDefinition = partitionKeyDefinition; this.VectorEmbeddingPolicy = vectorEmbeddingPolicy; - this.GeospatialType = geospatialType; + this.GeospatialType = geospatialType; + this.UseLengthAwareRangeComparer = useLengthAwareRangeComparer; } public string ResourceId { get; } @@ -34,6 +36,7 @@ public ContainerQueryProperties( public Cosmos.VectorEmbeddingPolicy VectorEmbeddingPolicy { get; } - public Cosmos.GeospatialType GeospatialType { get; } + public Cosmos.GeospatialType GeospatialType { get; } + public bool UseLengthAwareRangeComparer { get; } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/QueryRangeUtils.cs b/Microsoft.Azure.Cosmos/src/Query/Core/QueryRangeUtils.cs index 0f2fc818bc..087fb956cf 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/QueryRangeUtils.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/QueryRangeUtils.cs @@ -7,7 +7,8 @@ namespace Microsoft.Azure.Cosmos.Query.Core using System; using System.Collections.Generic; using System.Diagnostics; - using Microsoft.Azure.Cosmos.Query.Core.QueryClient; + using Microsoft.Azure.Cosmos.Query.Core.QueryClient; + using Microsoft.Azure.Cosmos.Routing; using Microsoft.Azure.Documents.Routing; internal static class QueryRangeUtils @@ -54,15 +55,8 @@ public static FeedRangeInternal LimitHpkFeedRangeToPartition(PartitionKey? parti bool minInclusive; String overlappingMax; bool maxInclusive; - - //LengthAwareComparer is the default Range comparer and flag is used to ovverride the default comparer to legacy Min/Max comparer. - IComparer> minComparer = IsLengthAwareComparisonEnabled - ? Documents.Routing.Range.LengthAwareMinComparer.Instance - : Documents.Routing.Range.MinComparer.Instance; - - IComparer> maxComparer = IsLengthAwareComparisonEnabled - ? Documents.Routing.Range.LengthAwareMaxComparer.Instance - : Documents.Routing.Range.MaxComparer.Instance; + + (IComparer> minComparer, IComparer> maxComparer) = RangeComparerProvider.GetComparers(containerQueryProperties.UseLengthAwareRangeComparer); if (minComparer.Compare( epkForPartitionKey, @@ -117,18 +111,14 @@ public static FeedRangeInternal LimitHpkFeedRangeToPartition(PartitionKey? parti /// /// The list of partition key ranges to trim /// The EPK ranges to use as boundaries + /// Whether to use length-aware range comparers /// A list of trimmed partition key ranges that fit within the provided ranges public static List LimitPartitionKeyRangesToProvidedRanges( List partitionKeyRanges, - IReadOnlyList> providedRanges) + IReadOnlyList> providedRanges, + bool useLengthAwareComparer = true) { - IComparer> minComparer = IsLengthAwareComparisonEnabled - ? Documents.Routing.Range.LengthAwareMinComparer.Instance - : Documents.Routing.Range.MinComparer.Instance; - - IComparer> maxComparer = IsLengthAwareComparisonEnabled - ? Documents.Routing.Range.LengthAwareMaxComparer.Instance - : Documents.Routing.Range.MaxComparer.Instance; + (IComparer> minComparer, IComparer> maxComparer) = RangeComparerProvider.GetComparers(useLengthAwareComparer); // Compute the overall min and max from providedRanges string overallMin = providedRanges[0].Min; diff --git a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs index 2f5b9f15c5..8f3c7ca366 100644 --- a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs +++ b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs @@ -85,7 +85,8 @@ public override async Task GetCachedContainerQueryProp effectivePartitionKeyRange, containerProperties.PartitionKey, containerProperties.VectorEmbeddingPolicy, - containerProperties.GeospatialConfig.GeospatialType); + containerProperties.GeospatialConfig.GeospatialType, + this.documentClient.UseLengthAwareRangeComparer); } public override async Task> TryGetPartitionedQueryExecutionInfoAsync( @@ -240,7 +241,7 @@ public override async Task> GetTargetPartitionKeyRangeBy forceRefresh, childTrace); - return QueryRangeUtils.LimitPartitionKeyRangesToProvidedRanges(ranges, providedRanges); + return QueryRangeUtils.LimitPartitionKeyRangesToProvidedRanges(ranges, providedRanges, this.clientContext.ClientOptions.UseLengthAwareRangeComparer); } } diff --git a/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs b/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs index 0014ed843a..f348414a9d 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs @@ -88,7 +88,8 @@ internal static CosmosClientContext Create( remoteCertificateValidationCallback: ClientContextCore.SslCustomValidationCallBack(clientOptions.GetServerCertificateCustomValidationCallback()), cosmosClientTelemetryOptions: clientOptions.CosmosClientTelemetryOptions, chaosInterceptorFactory: clientOptions.ChaosInterceptorFactory, - enableAsyncCacheExceptionNoSharing: clientOptions.EnableAsyncCacheExceptionNoSharing); + enableAsyncCacheExceptionNoSharing: clientOptions.EnableAsyncCacheExceptionNoSharing, + useLengthAwareRangeComparer: clientOptions.UseLengthAwareRangeComparer); return ClientContextCore.Create( cosmosClient, diff --git a/Microsoft.Azure.Cosmos/src/Routing/CollectionRoutingMap.cs b/Microsoft.Azure.Cosmos/src/Routing/CollectionRoutingMap.cs index e88c090248..12e7f1c57c 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/CollectionRoutingMap.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/CollectionRoutingMap.cs @@ -38,7 +38,8 @@ private CollectionRoutingMap( Dictionary> rangeById, List orderedPartitionKeyRanges, string collectionUniqueId, - string changeFeedNextIfNoneMatch) + string changeFeedNextIfNoneMatch, + bool useLengthAwareRangeComparer) { this.rangeById = rangeById; this.orderedPartitionKeyRanges = orderedPartitionKeyRanges; @@ -71,18 +72,13 @@ private CollectionRoutingMap( } return range.Status == PartitionKeyRangeStatus.Offline ? CollectionRoutingMap.InvalidPkRangeId : pkId; }); - - //LengthAwareComparer is the default Range comparer and flag is used to ovverride the default comparer to legacy Min/Max comparer. - bool useLengthAwareComparer = ConfigurationManager.IsLengthAwareRangeComparatorEnabled(); - - this.comparers = useLengthAwareComparer - ? (Range.LengthAwareMinComparer.Instance, Range.LengthAwareMaxComparer.Instance) - : (Range.MinComparer.Instance, Range.MaxComparer.Instance); + this.comparers = RangeComparerProvider.GetComparers(useLengthAwareRangeComparer); } public static CollectionRoutingMap TryCreateCompleteRoutingMap( IEnumerable> ranges, string collectionUniqueId, + bool useLengthAwareRangeComparer, string changeFeedNextIfNoneMatch = null) { Dictionary> rangeById = @@ -102,7 +98,7 @@ public static CollectionRoutingMap TryCreateCompleteRoutingMap( return null; } - return new CollectionRoutingMap(rangeById, orderedRanges, collectionUniqueId, changeFeedNextIfNoneMatch); + return new CollectionRoutingMap(rangeById, orderedRanges, collectionUniqueId, changeFeedNextIfNoneMatch, useLengthAwareRangeComparer); } public string CollectionUniqueId { get; private set; } @@ -212,7 +208,8 @@ public ServiceIdentity TryGetInfoByPartitionKeyRangeId(string partitionKeyRangeI public CollectionRoutingMap TryCombine( IEnumerable> ranges, - string changeFeedNextIfNoneMatch) + string changeFeedNextIfNoneMatch, + bool useLengthAwareComparer) { HashSet newGoneRanges = new HashSet(ranges.SelectMany(tuple => tuple.Item1.Parents ?? Enumerable.Empty())); newGoneRanges.UnionWith(this.goneRanges); @@ -239,7 +236,7 @@ public CollectionRoutingMap TryCombine( return null; } - return new CollectionRoutingMap(newRangeById, newOrderedRanges, this.CollectionUniqueId, changeFeedNextIfNoneMatch); + return new CollectionRoutingMap(newRangeById, newOrderedRanges, this.CollectionUniqueId, changeFeedNextIfNoneMatch, useLengthAwareComparer); } private class MinPartitionKeyTupleComparer : IComparer> diff --git a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyRangeCache.cs b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyRangeCache.cs index 8a31c924fb..52a13a5c58 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyRangeCache.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyRangeCache.cs @@ -30,13 +30,15 @@ internal class PartitionKeyRangeCache : IRoutingMapProvider, ICollectionRoutingM private readonly ICosmosAuthorizationTokenProvider authorizationTokenProvider; private readonly IStoreModel storeModel; private readonly CollectionCache collectionCache; - private readonly IGlobalEndpointManager endpointManager; + private readonly IGlobalEndpointManager endpointManager; + private readonly bool useLengthAwareRangeComparer; public PartitionKeyRangeCache( ICosmosAuthorizationTokenProvider authorizationTokenProvider, IStoreModel storeModel, CollectionCache collectionCache, - IGlobalEndpointManager endpointManager, + IGlobalEndpointManager endpointManager, + bool useLengthAwareRangeComparer, bool enableAsyncCacheExceptionNoSharing = true) { this.routingMapCache = new AsyncCacheNonBlocking( @@ -45,7 +47,8 @@ public PartitionKeyRangeCache( this.authorizationTokenProvider = authorizationTokenProvider; this.storeModel = storeModel; this.collectionCache = collectionCache; - this.endpointManager = endpointManager; + this.endpointManager = endpointManager; + this.useLengthAwareRangeComparer = useLengthAwareRangeComparer; } public virtual async Task> TryGetOverlappingRangesAsync( @@ -241,12 +244,13 @@ private async Task GetRoutingMapForCollectionAsync( HashSet goneRanges = new HashSet(ranges.SelectMany(range => range.Parents ?? Enumerable.Empty())); routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( tuples.Where(tuple => !goneRanges.Contains(tuple.Item1.Id)), - string.Empty, + string.Empty, + false, changeFeedNextIfNoneMatch); } else { - routingMap = previousRoutingMap.TryCombine(tuples, changeFeedNextIfNoneMatch); + routingMap = previousRoutingMap.TryCombine(tuples, changeFeedNextIfNoneMatch, this.useLengthAwareRangeComparer); } if (routingMap == null) diff --git a/Microsoft.Azure.Cosmos/src/Routing/RangeComparerProvider.cs b/Microsoft.Azure.Cosmos/src/Routing/RangeComparerProvider.cs new file mode 100644 index 0000000000..ac54e7fad5 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Routing/RangeComparerProvider.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Routing +{ + using System.Collections.Generic; + using Microsoft.Azure.Documents.Routing; + + internal class RangeComparerProvider + { + /// + /// Gets the minimum and maximum range comparers based on the current configuration. + /// + /// Tuple of (minComparer, maxComparer) + public static (IComparer> minComparer, IComparer> maxComparer) GetComparers(bool useLengthAwareComparison) + { + return ( + useLengthAwareComparison ? Range.LengthAwareMinComparer.Instance : Range.MinComparer.Instance, + useLengthAwareComparison ? Range.LengthAwareMaxComparer.Instance : Range.MaxComparer.Instance + ); + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs index e3a0233461..379de2faba 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs @@ -2175,7 +2175,7 @@ public async Task ItemEpkQuerySingleKeyRangeValidation() //new List> { new Documents.Routing.Range("AA", "AA", true, true) }, containerResponse.Resource.PartitionKey, vectorEmbeddingPolicy: null, - containerResponse.Resource.GeospatialConfig.GeospatialType); + containerResponse.Resource.GeospatialConfig.GeospatialType, false); // There should only be one range since the EPK option is set. List partitionKeyRanges = await CosmosQueryExecutionContextFactory.GetTargetPartitionKeyRangesAsync( diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedToken/QueryFeedTokenTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedToken/QueryFeedTokenTests.cs index 74a8cf6f7c..2bf1d9ea4b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedToken/QueryFeedTokenTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedToken/QueryFeedTokenTests.cs @@ -57,7 +57,7 @@ public async Task GetTargetPartitionKeyRangesAsyncWithFeedRange() effectivePartitionKeyRanges: null, containerResponse.Resource.PartitionKey, vectorEmbeddingPolicy: null, - containerResponse.Resource.GeospatialConfig.GeospatialType); + containerResponse.Resource.GeospatialConfig.GeospatialType, false); IReadOnlyList feedTokens = await container.GetFeedRangesAsync(); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs index 74b12a9e04..26513b7160 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs @@ -180,9 +180,9 @@ private void Init() { Tuple.Create(new PartitionKeyRange{ Id = "0", MinInclusive = "", MaxExclusive = "FF"}, (ServiceIdentity)null) }, - string.Empty); + string.Empty, false); - this.partitionKeyRangeCache = new Mock(null, null, null, null, false); + this.partitionKeyRangeCache = new Mock(null, null, null, null, false, false); this.partitionKeyRangeCache.Setup( m => m.TryLookupAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncBatcherTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncBatcherTests.cs index 763598e64c..b00048da4f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncBatcherTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncBatcherTests.cs @@ -799,7 +799,7 @@ private class ClientWithSplitDetection : MockDocumentClient public ClientWithSplitDetection() { - this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false); + this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false, false); this.partitionKeyRangeCache.Setup( m => m.TryGetOverlappingRangesAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncContainerExecutorTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncContainerExecutorTests.cs index d77afc627a..a814cd9834 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncContainerExecutorTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncContainerExecutorTests.cs @@ -62,7 +62,7 @@ public async Task RetryOnSplit() { Tuple.Create(new PartitionKeyRange{ Id = "0", MinInclusive = "", MaxExclusive = "FF"}, (ServiceIdentity)null) }, - string.Empty); + string.Empty, false); mockContainer.Setup(x => x.GetRoutingMapAsync(It.IsAny())).Returns(Task.FromResult(routingMap)); BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(mockContainer.Object, mockedContext.Object, 20, BatchAsyncContainerExecutorCache.DefaultMaxBulkRequestBodySizeInBytes); TransactionalBatchOperationResult result = await executor.AddAsync(itemBatchOperation, NoOpTrace.Singleton); @@ -120,7 +120,7 @@ public async Task RetryOnNameStale() { Tuple.Create(new PartitionKeyRange{ Id = "0", MinInclusive = "", MaxExclusive = "FF"}, (ServiceIdentity)null) }, - string.Empty); + string.Empty, false); mockContainer.Setup(x => x.GetRoutingMapAsync(It.IsAny())).Returns(Task.FromResult(routingMap)); BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(mockContainer.Object, mockedContext.Object, 20, BatchAsyncContainerExecutorCache.DefaultMaxBulkRequestBodySizeInBytes); TransactionalBatchOperationResult result = await executor.AddAsync(itemBatchOperation, NoOpTrace.Singleton); @@ -178,7 +178,7 @@ public async Task RetryOn429() { Tuple.Create(new PartitionKeyRange{ Id = "0", MinInclusive = "", MaxExclusive = "FF"}, (ServiceIdentity)null) }, - string.Empty); + string.Empty, false); mockContainer.Setup(x => x.GetRoutingMapAsync(It.IsAny())).Returns(Task.FromResult(routingMap)); BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(mockContainer.Object, mockedContext.Object, 20, BatchAsyncContainerExecutorCache.DefaultMaxBulkRequestBodySizeInBytes); TransactionalBatchOperationResult result = await executor.AddAsync(itemBatchOperation, NoOpTrace.Singleton); @@ -235,7 +235,7 @@ public async Task DoesNotRecalculatePartitionKeyRangeOnNoSplits() { Tuple.Create(new PartitionKeyRange{ Id = "0", MinInclusive = "", MaxExclusive = "FF"}, (ServiceIdentity)null) }, - string.Empty); + string.Empty, false); mockContainer.Setup(x => x.GetRoutingMapAsync(It.IsAny())).Returns(Task.FromResult(routingMap)); BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(mockContainer.Object, mockedContext.Object, 20, BatchAsyncContainerExecutorCache.DefaultMaxBulkRequestBodySizeInBytes); TransactionalBatchOperationResult result = await executor.AddAsync(itemBatchOperation, NoOpTrace.Singleton); @@ -377,7 +377,7 @@ private class ClientWithSplitDetection : MockDocumentClient public ClientWithSplitDetection() { - this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false); + this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false, false); this.partitionKeyRangeCache.Setup( m => m.TryGetOverlappingRangesAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncOperationContextTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncOperationContextTests.cs index a5bd3b374e..e3d7348150 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncOperationContextTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchAsyncOperationContextTests.cs @@ -297,7 +297,7 @@ private class ClientWithSplitDetection : MockDocumentClient public ClientWithSplitDetection() { - this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false); + this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false, false); this.partitionKeyRangeCache.Setup( m => m.TryGetOverlappingRangesAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BulkPartitionKeyRangeGoneRetryPolicyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BulkPartitionKeyRangeGoneRetryPolicyTests.cs index fe75375e6d..6c9cbd2e1b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BulkPartitionKeyRangeGoneRetryPolicyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BulkPartitionKeyRangeGoneRetryPolicyTests.cs @@ -145,7 +145,7 @@ private class ClientWithSplitDetection : MockDocumentClient public ClientWithSplitDetection() { - this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false); + this.partitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false, false); this.partitionKeyRangeCache.Setup( m => m.TryGetOverlappingRangesAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/PartitionSynchronizerCoreTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/PartitionSynchronizerCoreTests.cs index 140e8bb098..2e0dd999a6 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/PartitionSynchronizerCoreTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/PartitionSynchronizerCoreTests.cs @@ -63,6 +63,7 @@ public async Task HandlePartitionGoneAsync_PKRangeBasedLease_Split() Mock.Of(), new Mock(false).Object, this.endpointManager, + false, false); List resultingRanges = new List() @@ -128,6 +129,7 @@ public async Task HandlePartitionGoneAsync_EpkBasedLease_Split() Mock.Of(), new Mock(false).Object, this.endpointManager, + false, false); List resultingRanges = new List() @@ -198,6 +200,7 @@ public async Task HandlePartitionGoneAsync_PKRangeBasedLease_Merge() Mock.Of(), new Mock(false).Object, this.endpointManager, + false, false); List resultingRanges = new List() @@ -258,6 +261,7 @@ public async Task HandlePartitionGoneAsync_EpkBasedLease_Merge() Mock.Of(), new Mock(false).Object, this.endpointManager, + false, false); List resultingRanges = new List() @@ -308,6 +312,7 @@ public async Task CreateMissingLeases_NoLeases() Mock.Of(), new Mock(false).Object, this.endpointManager, + false, false); List resultingRanges = new List() @@ -355,6 +360,7 @@ public async Task CreateMissingLeases_SomePKRangeLeases() Mock.Of(), new Mock(false).Object, this.endpointManager, + false, false); List resultingRanges = new List() @@ -408,6 +414,7 @@ public async Task CreateMissingLeases_SomePKRangeAndEPKLeases() Mock.Of(), new Mock(false).Object, this.endpointManager, + false, false); List resultingRanges = new List() diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CollectionRoutingMapTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CollectionRoutingMapTest.cs index cb7baf2de5..ed0f12b209 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CollectionRoutingMapTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CollectionRoutingMapTest.cs @@ -55,7 +55,7 @@ public void TestCollectionRoutingMap() serviceIdentity3), - }, string.Empty); + }, string.Empty, false); Assert.AreEqual("0", routingMap.OrderedPartitionKeyRanges[0].Id); Assert.AreEqual("1", routingMap.OrderedPartitionKeyRanges[1].Id); @@ -131,10 +131,8 @@ public void TestCollectionRoutingMapWithLengthAwareRangeComparators(bool isRouti { try { - // Arrange: Set environment variable to "true" since the default is only true for Preview. - Environment.SetEnvironmentVariable(ConfigurationManager.UseLengthAwareRangeComparator, "true"); - - CollectionRoutingMap routingMap = this.GenerateRoutingMap(isRoutingMapFullySpecified); + // Arrange: Set useLengthAwareComparer flag to "true" since the default is only true for Preview. + CollectionRoutingMap routingMap = this.GenerateRoutingMap(isRoutingMapFullySpecified, true); // Test scenario 1.1: Input EPK is partial and falls on the boundary between two overlapping ranges. // The LengthAware comparators are able to correctly compare partial and full EPK ranges.Routing map is hybrid of fully specified and partially specified EPK ranges. @@ -250,10 +248,10 @@ public void TestCollectionRoutingMapWithLengthAwareRangeComparators(bool isRouti public void TestLegacyComparatorsUsedWhenLengthAwareComparatorFlagIsFalse() { try - { - // Arrange: Set environment variable to force legacy comparator usage. - Environment.SetEnvironmentVariable(ConfigurationManager.UseLengthAwareRangeComparator, "false"); - CollectionRoutingMap routingMap = this.GenerateRoutingMap(false); + { + + // Arrange: Set useLengthAwareComparer to false to force legacy comparator usage. + CollectionRoutingMap routingMap = this.GenerateRoutingMap(false, false); // Test scenario: Input EPK is partial and falls on the boundary between two overlapping ranges. @@ -275,7 +273,7 @@ public void TestLegacyComparatorsUsedWhenLengthAwareComparatorFlagIsFalse() } } - private CollectionRoutingMap GenerateRoutingMap(bool isFullySpecified) + private CollectionRoutingMap GenerateRoutingMap(bool isFullySpecified, bool useLengthAwareComparer) { IEnumerable> partitionKeyRangeTuples = new[] { @@ -404,7 +402,8 @@ string PadTo64(string value) CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( partitionKeyRangeTuples, - string.Empty); + string.Empty, + useLengthAwareComparer); return routingMap; } @@ -419,7 +418,7 @@ public void TestInvalidRoutingMap() Tuple.Create(new PartitionKeyRange {Id = "1", MinInclusive = "0000000020", MaxExclusive = "0000000030"}, (ServiceIdentity)null), Tuple.Create(new PartitionKeyRange { Id = "2", MinInclusive = "0000000025", MaxExclusive = "0000000035"}, (ServiceIdentity)null), }, - string.Empty); + string.Empty, false); } [TestMethod] @@ -431,7 +430,7 @@ public void TestIncompleteRoutingMap() Tuple.Create(new PartitionKeyRange{ Id = "2", MinInclusive = "", MaxExclusive = "0000000030"}, (ServiceIdentity)null), Tuple.Create(new PartitionKeyRange{ Id = "3", MinInclusive = "0000000031", MaxExclusive = "FF"}, (ServiceIdentity)null), }, - string.Empty); + string.Empty, false); Assert.IsNull(routingMap); @@ -441,7 +440,7 @@ public void TestIncompleteRoutingMap() Tuple.Create(new PartitionKeyRange{Id = "2", MinInclusive = "", MaxExclusive = "0000000030"}, (ServiceIdentity)null), Tuple.Create(new PartitionKeyRange{Id = "3", MinInclusive = "0000000030", MaxExclusive = "FF"}, (ServiceIdentity)null), }, - string.Empty); + string.Empty, false); Assert.IsNotNull(routingMap); } @@ -456,7 +455,7 @@ public void TestGoneRanges() Tuple.Create(new PartitionKeyRange{ Id = "3", MinInclusive = "0000000030", MaxExclusive = "0000000032", Parents = new Collection{"5"}}, (ServiceIdentity)null), Tuple.Create(new PartitionKeyRange{ Id = "4", MinInclusive = "0000000032", MaxExclusive = "FF"}, (ServiceIdentity)null), }, - string.Empty); + string.Empty, false); Assert.IsTrue(routingMap.IsGone("1")); Assert.IsTrue(routingMap.IsGone("0")); @@ -501,7 +500,7 @@ public void TestTryCombineRanges() MinInclusive = "0000000070", MaxExclusive = "FF"}, (ServiceIdentity)null), - }, string.Empty); + }, string.Empty, false); CollectionRoutingMap newRoutingMap = routingMap.TryCombine( new[] @@ -522,7 +521,7 @@ public void TestTryCombineRanges() MaxExclusive = "0000000030"}, (ServiceIdentity)null), }, - null); + null, false); Assert.IsNotNull(newRoutingMap); @@ -561,7 +560,7 @@ public void TestTryCombineRanges() MaxExclusive = "0000000030"}, (ServiceIdentity)null), }, - null); + null, false); Assert.IsNotNull(newRoutingMap); @@ -576,7 +575,7 @@ public void TestTryCombineRanges() MaxExclusive = "0000000002"}, (ServiceIdentity)null), }, - null); + null, false); Assert.IsNull(newRoutingMap); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs index aa088340fd..61787f537f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs @@ -60,7 +60,7 @@ public GatewayAddressCacheTests() } }; - this.partitionKeyRangeCache = new Mock(null, null, null, null, false); + this.partitionKeyRangeCache = new Mock(null, null, null, null, false, false); this.partitionKeyRangeCache .Setup(m => m.TryGetOverlappingRangesAsync( It.IsAny(), @@ -806,7 +806,7 @@ public async Task GlobalAddressResolver_OpenConnectionsToAllReplicasAsync_WhenIn .Returns(Task.FromResult(containerProperties)); string exceptionMessage = "Failed to lookup partition key ranges."; - Mock partitionKeyRangeCache = new(null, null, null, null, false); + Mock partitionKeyRangeCache = new(null, null, null, null, false, false); partitionKeyRangeCache .Setup(m => m.TryGetOverlappingRangesAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayStoreModelTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayStoreModelTest.cs index 1a52543ee2..ba3eaaeb81 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayStoreModelTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayStoreModelTest.cs @@ -290,7 +290,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( dsr, ConsistencyLevel.Session, new Mock().Object, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(new SessionContainer("testhost"), gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: Mock.Of()); @@ -317,7 +317,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( dsrQueryPlan, ConsistencyLevel.Session, new Mock().Object, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(new SessionContainer("testhost"), gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: Mock.Of()); @@ -371,7 +371,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( dsr, ConsistencyLevel.Session, new Mock().Object, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(new SessionContainer("testhost"), gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: Mock.Of()); @@ -401,7 +401,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( dsrNoSessionToken, ConsistencyLevel.Session, sessionContainer, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(new SessionContainer("testhost"), gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: globalEndpointManager.Object); @@ -442,7 +442,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( It.IsAny(), NoOpTrace.Singleton)).Returns(Task.FromResult(containerProperties)); - Mock mockPartitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false); + Mock mockPartitionKeyRangeCache = new Mock(MockBehavior.Strict, null, null, null, null, false, false); mockPartitionKeyRangeCache.Setup(x => x.TryGetPartitionKeyRangeByIdAsync( containerProperties.ResourceId, partitionKeyRangeId, @@ -489,7 +489,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( dsrSprocExecute, ConsistencyLevel.Session, new Mock().Object, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(new SessionContainer("testhost"), gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: Mock.Of()); @@ -528,7 +528,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( dsrNoSessionToken, ConsistencyLevel.Session, sessionContainer, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(new SessionContainer("testhost"), gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: globalEndpointManager.Object); @@ -1005,7 +1005,7 @@ public async Task GatewayStoreModel_AvoidGlobalSessionToken() isThinClientEnabled: false); Mock clientCollectionCache = new Mock(new SessionContainer("testhost"), storeModel, null, null, null, false); - Mock partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache.Object, endpointManager, false); + Mock partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache.Object, endpointManager, false, false); sessionContainer.SetSessionToken( ResourceId.NewDocumentCollectionId(42, 129).DocumentCollectionId.ToString(), @@ -1103,7 +1103,7 @@ Task sendFunc(HttpRequestMessage request) Mock clientCollectionCache = new Mock(new SessionContainer("testhost"), storeModel, null, null, null, false); - Mock partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache.Object, endpointManager, false); + Mock partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache.Object, endpointManager, false, false); storeModel.SetCaches(partitionKeyRangeCache.Object, clientCollectionCache.Object); INameValueCollection headers = new RequestNameValueCollection(); @@ -1171,7 +1171,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( documentServiceRequestToChild, ConsistencyLevel.Session, sessionContainer, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(sessionContainer, gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: globalEndpointManager.Object); @@ -1237,7 +1237,7 @@ await GatewayStoreModel.ApplySessionTokenAsync( documentServiceRequestToChild, ConsistencyLevel.Session, sessionContainer, - partitionKeyRangeCache: new Mock(null, null, null, null, false).Object, + partitionKeyRangeCache: new Mock(null, null, null, null, false, false).Object, clientCollectionCache: new Mock(sessionContainer, gatewayStoreModel, null, null, null, false).Object, globalEndpointManager: globalEndpointManager.Object); @@ -1297,7 +1297,7 @@ public async Task ThinClient_ProcessMessageAsync_Success_ShouldReturnDocumentSer storeModel, clientCollectionCache, endpointManager, - false).Object; + false, false).Object; storeModel.SetCaches(partitionKeyRangeCache, clientCollectionCache); @@ -1378,7 +1378,7 @@ public async Task ThinClient_ProcessMessageAsync_WithUnsupportedOperations_Shoul storeModel, clientCollectionCache, multiEndpointMgr, - false).Object; + false, false).Object; storeModel.SetCaches(partitionKeyRangeCache, clientCollectionCache); @@ -1469,7 +1469,7 @@ public async Task ThinClient_ProcessMessageAsync_404_ShouldThrowDocumentClientEx storeModel, clientCollectionCache, endpointManager, - false).Object; + false, false).Object; storeModel.SetCaches(partitionKeyRangeCache, clientCollectionCache); @@ -1553,12 +1553,12 @@ public async Task ThinClient_PartitionLevelFailoverEnabled_ResolvesPartitionKeyR storeModel, mockCollectionCache.Object, endpointManager, - false); + false, false); PartitionKeyRange pkRange = new PartitionKeyRange { Id = "0", MinInclusive = "", MaxExclusive = "FF" }; List pkRanges = new List { pkRange }; IEnumerable> rangeTuples = pkRanges.Select(r => Tuple.Create(r, (ServiceIdentity)null)); - CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(rangeTuples, "testCollectionRid"); + CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(rangeTuples, "testCollectionRid", false); mockPartitionKeyRangeCache .Setup(c => c.TryLookupAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) @@ -1725,7 +1725,7 @@ static async Task messageHandler(HttpRequestMessage request isThinClientEnabled: false); ClientCollectionCache clientCollectionCache = new Mock(new SessionContainer("testhost"), storeModel, null, null, null, false).Object; - PartitionKeyRangeCache partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache, endpointManager, false).Object; + PartitionKeyRangeCache partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache, endpointManager, false, false).Object; storeModel.SetCaches(partitionKeyRangeCache, clientCollectionCache); await executeWithGatewayStoreModel(storeModel); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeCacheTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeCacheTest.cs index 41b53d293a..6f47751e42 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeCacheTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeCacheTest.cs @@ -98,7 +98,7 @@ public async Task TryGetOverlappingRangesAsync_WithFreshContainer_ShouldNotAddSa .Returns(new ValueTask(authToken)); // Act. - PartitionKeyRangeCache partitionKeyRangeCache = new(mockTokenProvider.Object, mockStoreModel.Object, mockCollectioNCache.Object, endpointManager, enableAsyncCacheExceptionNoSharing: false); + PartitionKeyRangeCache partitionKeyRangeCache = new(mockTokenProvider.Object, mockStoreModel.Object, mockCollectioNCache.Object, endpointManager, useLengthAwareRangeComparer: false, enableAsyncCacheExceptionNoSharing: false); IReadOnlyList partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( containerRId, FeedRangeEpk.FullRange.Range, @@ -207,7 +207,7 @@ public async Task TryGetOverlappingRangesAsync_WhenGatewayThrowsServiceUnavailab mockTokenProvider.Setup(x => x.GetUserAuthorizationTokenAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new ValueTask(authToken)); - PartitionKeyRangeCache partitionKeyRangeCache = new(mockTokenProvider.Object, mockStoreModel.Object, mockCollectioNCache.Object, mockedEndpointManager.Object, enableAsyncCacheExceptionNoSharing: false); + PartitionKeyRangeCache partitionKeyRangeCache = new(mockTokenProvider.Object, mockStoreModel.Object, mockCollectioNCache.Object, mockedEndpointManager.Object, useLengthAwareRangeComparer: false, enableAsyncCacheExceptionNoSharing: false); if (shouldSucceed) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeHandlerTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeHandlerTests.cs index e2a83f73aa..e7e95afbfc 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeHandlerTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/PartitionKeyRangeHandlerTests.cs @@ -660,13 +660,14 @@ public async Task PartitionKeyRangeGoneTracePlumbingTest() collectionCache.Setup(c => c.ResolveCollectionAsync(It.IsAny(), default, trace)) .ReturnsAsync(containerProperties); - CollectionRoutingMap collectionRoutingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(new List>(), collectionRid); + CollectionRoutingMap collectionRoutingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(new List>(), collectionRid, false); Mock partitionKeyRangeCache = new Mock( MockBehavior.Strict, new Mock().Object, new Mock().Object, collectionCache.Object, endpointManager, + false, false); partitionKeyRangeCache.Setup(c => c.TryLookupAsync(collectionRid, null, It.IsAny(), trace)) .ReturnsAsync(collectionRoutingMap); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs index b751ac3dc8..e47cbc470a 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs @@ -1325,7 +1325,8 @@ public override Task GetCachedContainerQueryProperties }, new PartitionKeyDefinition(), vectorEmbeddingPolicy: null, - Cosmos.GeospatialType.Geometry)); + Cosmos.GeospatialType.Geometry, + false)); } public override Task GetClientDisableOptimisticDirectExecutionAsync() diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OrderByQueryPartitionRangePageAsyncEnumeratorTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OrderByQueryPartitionRangePageAsyncEnumeratorTests.cs index 6c189e92e7..b7d7927c59 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OrderByQueryPartitionRangePageAsyncEnumeratorTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OrderByQueryPartitionRangePageAsyncEnumeratorTests.cs @@ -58,15 +58,15 @@ protected override Task>> CreateEnum IAsyncEnumerator> enumerator = new TracingAsyncEnumerator>( OrderByQueryPartitionRangePageAsyncEnumerator.Create( - queryDataSource: documentContainer, + queryDataSource: documentContainer, containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), sqlQuerySpec: new Cosmos.Query.Core.SqlQuerySpec("SELECT * FROM c"), feedRangeState: new FeedRangeState(ranges[0], state), partitionKey: null, queryPaginationOptions: new QueryExecutionOptions(pageSizeHint: 10), - filter: "filter", + filter: "filter", PrefetchPolicy.PrefetchSinglePage), - NoOpTrace.Singleton, + NoOpTrace.Singleton, cancellationToken); return Task.FromResult(enumerator); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FactoryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FactoryTests.cs index e7021a86f0..abffd707ca 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FactoryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FactoryTests.cs @@ -27,11 +27,11 @@ public void TestCreate() sqlQuerySpec: new SqlQuerySpec("SELECT * FROM c"), targetRanges: new List() { FeedRangeEpk.FullRange }, partitionKey: null, - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), allRanges: new List() { FeedRangeEpk.FullRange }, - queryInfo: new QueryInfo() { }, + queryInfo: new QueryInfo() { }, hybridSearchQueryInfo: null, - maxItemCount: 10, + maxItemCount: 10, isContinuationExpected: true, maxConcurrency: 10, requestContinuationToken: default); ; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FullPipelineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FullPipelineTests.cs index 1a5400f941..ba51c787ab 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FullPipelineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/FullPipelineTests.cs @@ -253,7 +253,7 @@ public async Task Tracing() numTraces++; } } - + rootTrace.SetWalkingStateRecursively(); Assert.AreEqual(numTraces, rootTrace.Children.Count); } @@ -296,12 +296,12 @@ public async Task OffsetLimitPageSize() private async Task TestPageSizeAsync(string query, int expectedPageSize, int expectedResults, MockInMemoryContainer inMemoryContainer, DocumentContainer documentContainer) { - IQueryPipelineStage queryPipelineStage = CreateQueryPipelineStage( + IQueryPipelineStage queryPipelineStage = CreateQueryPipelineStage( documentContainer, query, partitionKeyDefinition, null, - new QueryRequestOptions()); + new QueryRequestOptions()); List elements = new List(); while (await queryPipelineStage.MoveNextAsync(NoOpTrace.Singleton, cancellationToken: default)) @@ -316,7 +316,7 @@ private async Task TestPageSizeAsync(string query, int expectedPageSize, int exp Assert.AreEqual(expected: expectedResults, actual: elements.Count); } - private static IQueryPipelineStage CreateQueryPipelineStage( + private static IQueryPipelineStage CreateQueryPipelineStage( DocumentContainer documentContainer, string query, PartitionKeyDefinition partitionKeyDefinition, @@ -338,8 +338,8 @@ private static IQueryPipelineStage CreateQueryPipelineStage( properties: new Dictionary() { { "x-ms-query-partitionkey-definition", partitionKeyDefinition } }, partitionedQueryExecutionInfo: null, returnResultsInDeterministicOrder: null, - enableOptimisticDirectExecution: queryRequestOptions.EnableOptimisticDirectExecution, - isHybridSearchQueryPlanOptimizationDisabled: queryRequestOptions.IsHybridSearchQueryPlanOptimizationDisabled, + enableOptimisticDirectExecution: queryRequestOptions.EnableOptimisticDirectExecution, + isHybridSearchQueryPlanOptimizationDisabled: queryRequestOptions.IsHybridSearchQueryPlanOptimizationDisabled, enableDistributedQueryGatewayMode: queryRequestOptions.EnableDistributedQueryGatewayMode, testInjections: queryRequestOptions.TestSettings); @@ -372,30 +372,30 @@ private static IQueryPipelineStage CreateQueryPipelineStage( mockClient.Setup(x => x.TryGetPartitionedQueryExecutionInfoAsync( It.IsAny(), It.IsAny(), - It.IsAny(), + It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), - It.IsAny(), + It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(( - SqlQuerySpec sqlQuerySpec, - ResourceType resourceType, - PartitionKeyDefinition partitionKeyDefinition, - VectorEmbeddingPolicy vectorEmbeddingPolicy, - bool requireFormattableOrderByQuery, - bool isContinuationExpected, - bool allowNonValueAggregateQuery, - bool hasLogicalPartitionKey, - bool allowDCount, - bool useSystemPrefix, + .Returns(( + SqlQuerySpec sqlQuerySpec, + ResourceType resourceType, + PartitionKeyDefinition partitionKeyDefinition, + VectorEmbeddingPolicy vectorEmbeddingPolicy, + bool requireFormattableOrderByQuery, + bool isContinuationExpected, + bool allowNonValueAggregateQuery, + bool hasLogicalPartitionKey, + bool allowDCount, + bool useSystemPrefix, bool isHybridSearchQueryPlanOptimizationDisabled, - Cosmos.GeospatialType geospatialType, + Cosmos.GeospatialType geospatialType, CancellationToken cancellationToken) => { CosmosSerializerCore serializerCore = new(); @@ -423,11 +423,11 @@ private static IQueryPipelineStage CreateQueryPipelineStage( isContinuationExpected: true, allowNonValueAggregateQuery: true, useSystemPrefix: false, - correlatedActivityId: Guid.NewGuid()); - + correlatedActivityId: Guid.NewGuid()); + IQueryPipelineStage queryPipelineStage = CosmosQueryExecutionContextFactory.Create( documentContainer, - cosmosQueryContextCore, + cosmosQueryContextCore, inputParameters, NoOpTrace.Singleton); @@ -613,11 +613,11 @@ private static async Task CreatePipelineAsync( new SqlQuerySpec(query), feedRanges, partitionKey: null, - GetQueryPlan(query), - hybridSearchQueryInfo: null, + GetQueryPlan(query), + hybridSearchQueryInfo: null, allRanges: feedRanges, maxItemCount: pageSize, - containerQueryProperties: new ContainerQueryProperties(), + containerQueryProperties: new ContainerQueryProperties(), isContinuationExpected: true, maxConcurrency: 10, requestContinuationToken: state); @@ -631,13 +631,13 @@ private static QueryInfo GetQueryPlan(string query) { TryCatch info = QueryPartitionProviderTestInstance.Object.TryGetPartitionedQueryExecutionInfoInternal( JsonConvert.SerializeObject(new SqlQuerySpec(query)), - partitionKeyDefinition, + partitionKeyDefinition, vectorEmbeddingPolicy: null, requireFormattableOrderByQuery: true, isContinuationExpected: false, allowNonValueAggregateQuery: true, allowDCount: true, - hasLogicalPartitionKey: false, + hasLogicalPartitionKey: false, hybridSearchSkipOrderByRewrite: false, useSystemPrefix: false, geospatialType: Cosmos.GeospatialType.Geography); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs index 0d819b7bdd..47dd212109 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs @@ -80,7 +80,7 @@ public void MonadicCreate_NullContinuationToken() maxConcurrency: 10, nonStreamingOrderBy: false, continuationToken: null, - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); } @@ -103,7 +103,7 @@ public void MonadicCreate_NonCosmosArrayContinuationToken() maxConcurrency: 10, nonStreamingOrderBy: false, continuationToken: CosmosObject.Create(new Dictionary()), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Failed); Assert.IsTrue(monadicCreate.InnerMostException is MalformedContinuationTokenException); @@ -127,7 +127,7 @@ public void MonadicCreate_EmptyArrayContinuationToken() maxConcurrency: 10, nonStreamingOrderBy: false, continuationToken: CosmosArray.Create(new List()), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Failed); Assert.IsTrue(monadicCreate.InnerMostException is MalformedContinuationTokenException); @@ -151,7 +151,7 @@ public void MonadicCreate_NonParallelContinuationToken() maxConcurrency: 10, nonStreamingOrderBy: false, continuationToken: CosmosArray.Create(new List() { CosmosString.Create("asdf") }), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Failed); Assert.IsTrue(monadicCreate.InnerMostException is MalformedContinuationTokenException); @@ -194,7 +194,7 @@ public void MonadicCreate_SingleOrderByContinuationToken() { OrderByContinuationToken.ToCosmosElement(orderByContinuationToken) }), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); } @@ -241,7 +241,7 @@ public void MonadicCreate_SingleOrderByContinuationToken() { OrderByContinuationToken.ToCosmosElement(orderByContinuationToken) }), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); } @@ -304,7 +304,7 @@ public void MonadicCreate_MultipleOrderByContinuationToken() OrderByContinuationToken.ToCosmosElement(orderByContinuationToken1), OrderByContinuationToken.ToCosmosElement(orderByContinuationToken2) }), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); } @@ -348,7 +348,7 @@ public void MonadicCreate_OrderByWithResumeValues() { OrderByContinuationToken.ToCosmosElement(orderByContinuationToken) }), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); } @@ -392,7 +392,7 @@ public void MonadicCreate_OrderByWithResumeValues() { OrderByContinuationToken.ToCosmosElement(orderByContinuationToken) }), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); } @@ -446,7 +446,7 @@ public async Task TestFormattedFiltersForTargetPartitionWithContinuationTokenAsy maxConcurrency: 0, nonStreamingOrderBy: false, continuationToken: CosmosElement.Parse(continuationToken), - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); @@ -486,7 +486,7 @@ FROM c maxConcurrency: 10, nonStreamingOrderBy: nonStreamingOrderBy, continuationToken: null, - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); IQueryPipelineStage queryPipelineStage = monadicCreate.Result; @@ -537,7 +537,7 @@ FROM c maxConcurrency: 10, nonStreamingOrderBy: false, continuationToken: null, - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); Assert.IsTrue(monadicCreate.Succeeded); IQueryPipelineStage queryPipelineStage = monadicCreate.Result; @@ -601,7 +601,7 @@ FROM c maxConcurrency: 10, nonStreamingOrderBy: nonStreamingOrderBy, continuationToken: continuationToken, - containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), + containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), emitRawOrderByPayload: false); monadicQueryPipelineStage.ThrowIfFailed(); IQueryPipelineStage queryPipelineStage = monadicQueryPipelineStage.Result; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/ParallelCrossPartitionQueryPipelineStageTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/ParallelCrossPartitionQueryPipelineStageTests.cs index 248058d2ef..9a64210f4f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/ParallelCrossPartitionQueryPipelineStageTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/ParallelCrossPartitionQueryPipelineStageTests.cs @@ -148,12 +148,8 @@ public void MonadicCreate_MultipleParallelContinuationToken() containerQueryProperties: new Cosmos.Query.Core.QueryClient.ContainerQueryProperties(), maxConcurrency: 10, prefetchPolicy: PrefetchPolicy.PrefetchSinglePage, - continuationToken: CosmosArray.Create( - new List() - { - ParallelContinuationToken.ToCosmosElement(token1), - ParallelContinuationToken.ToCosmosElement(token2) - })); + continuationToken: CosmosArray.Create(new List() { ParallelContinuationToken.ToCosmosElement(token1), ParallelContinuationToken.ToCosmosElement(token2) })); + Assert.IsTrue(monadicCreate.Succeeded); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs index 01648d77d4..5bcdd9c489 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs @@ -335,7 +335,8 @@ public override Task GetCachedContainerQueryProperties }, SubpartitionTests.CreatePartitionKeyDefinition(), vectorEmbeddingPolicy: null, - Cosmos.GeospatialType.Geometry)); + Cosmos.GeospatialType.Geometry, + false)); } public override Task GetClientDisableOptimisticDirectExecutionAsync() diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/RetryHandlerTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/RetryHandlerTests.cs index ca52e5d356..81e2d35388 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/RetryHandlerTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/RetryHandlerTests.cs @@ -141,7 +141,7 @@ private class TestPartitionKeyRangeCache : PartitionKeyRangeCache private readonly IReadOnlyList overlappingRanges; public TestPartitionKeyRangeCache(IReadOnlyList overlappingRanges) - : base(null, null, null, null) // Pass nulls or mocks as needed for base constructor + : base(null, null, null, null, false, false) // Pass nulls or mocks as needed for base constructor { this.overlappingRanges = overlappingRanges; } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/IRoutingMapProviderExtensionsTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/IRoutingMapProviderExtensionsTest.cs index b4629fe063..a476fb66dd 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/IRoutingMapProviderExtensionsTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/IRoutingMapProviderExtensionsTest.cs @@ -1,223 +1,223 @@ -//------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------ - -namespace Microsoft.Azure.Cosmos.Tests.Routing -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading.Tasks; - using Microsoft.Azure.Cosmos.Routing; - using Microsoft.Azure.Cosmos.Tracing; - using Microsoft.Azure.Documents; - using Microsoft.Azure.Documents.Routing; - using Microsoft.VisualStudio.TestTools.UnitTesting; - - /// - /// Tests class. - /// - [TestClass] - public class IRoutingMapProviderExtensionsTest - { - private class MockRoutingMapProvider : IRoutingMapProvider - { - readonly CollectionRoutingMap routingMap; - - public MockRoutingMapProvider(IList ranges) - { - this.routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(ranges.Select(r => Tuple.Create(r, (ServiceIdentity)null)), ""); - } - - public Task> TryGetOverlappingRangesAsync( - string collectionIdOrNameBasedLink, - Range range, - ITrace trace, - bool forceRefresh = false) - { - return Task.FromResult(this.routingMap.GetOverlappingRanges(range)); - } - - public Task TryGetPartitionKeyRangeByIdAsync( - string collectionResourceId, - string partitionKeyRangeId, - ITrace trace, - bool forceRefresh = false) - { - return Task.FromResult(this.routingMap.TryGetRangeByPartitionKeyRangeId(partitionKeyRangeId)); - } - } - - private readonly MockRoutingMapProvider routingMapProvider = - new MockRoutingMapProvider( - new[] - { - new PartitionKeyRange{MinInclusive = "", MaxExclusive = "000A", Id="0"}, - new PartitionKeyRange{MinInclusive = "000A", MaxExclusive = "000D", Id="1"}, - new PartitionKeyRange{MinInclusive = "000D", MaxExclusive = "0012", Id="2"}, - new PartitionKeyRange{MinInclusive = "0012", MaxExclusive = "0015", Id="3"}, - new PartitionKeyRange{MinInclusive = "0015", MaxExclusive = "0020", Id="4"}, - new PartitionKeyRange{MinInclusive = "0020", MaxExclusive = "0040", Id="5"}, - new PartitionKeyRange{MinInclusive = "0040", MaxExclusive = "FF", Id="6"}, - }); - - /// - /// Tests case when input is not sorted. - /// - [TestMethod] - [Owner("padmaa")] - public async Task TestNonSortedRanges() - { - IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] { new Range("0B", "0B", true, true), new Range("0A", "0A", true, true) }, - NoOpTrace.Singleton); - - Assert.AreEqual("6", string.Join(",", ranges.Select(r => r.Id))); - } - - /// - /// Tests case when input contains overlapping ranges. - /// - [TestMethod] - [Owner("padmaa")] - [ExpectedException(typeof(ArgumentException))] - public async Task TestOverlappingRanges1() - { - await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] { new Range("0A", "0D", true, true), new Range("0B", "0E", true, true) }, - NoOpTrace.Singleton); - } - - /// - /// Tests case when input contains overlapping ranges. - /// - [TestMethod] - [Owner("padmaa")] - [ExpectedException(typeof(ArgumentException))] - public async Task TestOverlappingRanges2() - { - await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] { new Range("0A", "0D", true, true), new Range("0D", "0E", true, true) }, - NoOpTrace.Singleton); - } - - /// - /// Tests case with various overlapping options. - /// - [TestMethod] - [Owner("padmaa")] - public async Task TestDuplicates() - { - { - // Deep Copy Duplicate - IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] - { - new Range("", "FF", true, false), - // Duplicate - new Range("", "FF", true, false), - }, - NoOpTrace.Singleton); - - Assert.AreEqual("0,1,2,3,4,5,6", string.Join(",", ranges.Select(r => r.Id))); - } - - { - // Shallow Copy Duplicate - List> queryRanges = new List>() - { - new Range("", "FF", true, false), - }; - queryRanges.Add(queryRanges.Last()); - - IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - queryRanges, - NoOpTrace.Singleton); - - Assert.AreEqual("0,1,2,3,4,5,6", string.Join(",", ranges.Select(r => r.Id))); - } - } - - /// - /// Tests case with various overlapping options. - /// - [TestMethod] - [Owner("padmaa")] - public async Task TestGetOverlappingRanges() - { - IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] - { - new Range("000B", "000E", true, false), - new Range("000E", "000F", true, false), - new Range("000F", "0010", true, true), - new Range("0015", "0015", true, true) - }, - NoOpTrace.Singleton); - - Assert.AreEqual("1,2,4", string.Join(",", ranges.Select(r => r.Id))); - - // query for minimal point - ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] - { - new Range("", "", true, true), - }, - NoOpTrace.Singleton); - - Assert.AreEqual("0", string.Join(",", ranges.Select(r => r.Id))); - - // query for empty range - ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] - { - new Range("", "", true, false), - }, - NoOpTrace.Singleton); - - Assert.AreEqual("", string.Join(",", ranges.Select(r => r.Id))); - - // entire range - ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] - { - new Range("", "FF", true, false), - }, - NoOpTrace.Singleton); - - Assert.AreEqual("0,1,2,3,4,5,6", string.Join(",", ranges.Select(r => r.Id))); - - // matching range - ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] - { - new Range("0012", "0015", true, false), - }, - NoOpTrace.Singleton); - - Assert.AreEqual("3", string.Join(",", ranges.Select(r => r.Id))); - - // matching range and a little bit more. - ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( - "dbs/db1/colls/coll1", - new[] - { - new Range("0012", "0015", false, true), - }, - NoOpTrace.Singleton); - - Assert.AreEqual("3,4", string.Join(",", ranges.Select(r => r.Id))); - } - - } +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Tests.Routing +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.Routing; + using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Documents; + using Microsoft.Azure.Documents.Routing; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// Tests class. + /// + [TestClass] + public class IRoutingMapProviderExtensionsTest + { + private class MockRoutingMapProvider : IRoutingMapProvider + { + readonly CollectionRoutingMap routingMap; + + public MockRoutingMapProvider(IList ranges) + { + this.routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap(ranges.Select(r => Tuple.Create(r, (ServiceIdentity)null)), "", false); + } + + public Task> TryGetOverlappingRangesAsync( + string collectionIdOrNameBasedLink, + Range range, + ITrace trace, + bool forceRefresh = false) + { + return Task.FromResult(this.routingMap.GetOverlappingRanges(range)); + } + + public Task TryGetPartitionKeyRangeByIdAsync( + string collectionResourceId, + string partitionKeyRangeId, + ITrace trace, + bool forceRefresh = false) + { + return Task.FromResult(this.routingMap.TryGetRangeByPartitionKeyRangeId(partitionKeyRangeId)); + } + } + + private readonly MockRoutingMapProvider routingMapProvider = + new MockRoutingMapProvider( + new[] + { + new PartitionKeyRange{MinInclusive = "", MaxExclusive = "000A", Id="0"}, + new PartitionKeyRange{MinInclusive = "000A", MaxExclusive = "000D", Id="1"}, + new PartitionKeyRange{MinInclusive = "000D", MaxExclusive = "0012", Id="2"}, + new PartitionKeyRange{MinInclusive = "0012", MaxExclusive = "0015", Id="3"}, + new PartitionKeyRange{MinInclusive = "0015", MaxExclusive = "0020", Id="4"}, + new PartitionKeyRange{MinInclusive = "0020", MaxExclusive = "0040", Id="5"}, + new PartitionKeyRange{MinInclusive = "0040", MaxExclusive = "FF", Id="6"}, + }); + + /// + /// Tests case when input is not sorted. + /// + [TestMethod] + [Owner("padmaa")] + public async Task TestNonSortedRanges() + { + IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] { new Range("0B", "0B", true, true), new Range("0A", "0A", true, true) }, + NoOpTrace.Singleton); + + Assert.AreEqual("6", string.Join(",", ranges.Select(r => r.Id))); + } + + /// + /// Tests case when input contains overlapping ranges. + /// + [TestMethod] + [Owner("padmaa")] + [ExpectedException(typeof(ArgumentException))] + public async Task TestOverlappingRanges1() + { + await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] { new Range("0A", "0D", true, true), new Range("0B", "0E", true, true) }, + NoOpTrace.Singleton); + } + + /// + /// Tests case when input contains overlapping ranges. + /// + [TestMethod] + [Owner("padmaa")] + [ExpectedException(typeof(ArgumentException))] + public async Task TestOverlappingRanges2() + { + await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] { new Range("0A", "0D", true, true), new Range("0D", "0E", true, true) }, + NoOpTrace.Singleton); + } + + /// + /// Tests case with various overlapping options. + /// + [TestMethod] + [Owner("padmaa")] + public async Task TestDuplicates() + { + { + // Deep Copy Duplicate + IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] + { + new Range("", "FF", true, false), + // Duplicate + new Range("", "FF", true, false), + }, + NoOpTrace.Singleton); + + Assert.AreEqual("0,1,2,3,4,5,6", string.Join(",", ranges.Select(r => r.Id))); + } + + { + // Shallow Copy Duplicate + List> queryRanges = new List>() + { + new Range("", "FF", true, false), + }; + queryRanges.Add(queryRanges.Last()); + + IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + queryRanges, + NoOpTrace.Singleton); + + Assert.AreEqual("0,1,2,3,4,5,6", string.Join(",", ranges.Select(r => r.Id))); + } + } + + /// + /// Tests case with various overlapping options. + /// + [TestMethod] + [Owner("padmaa")] + public async Task TestGetOverlappingRanges() + { + IList ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] + { + new Range("000B", "000E", true, false), + new Range("000E", "000F", true, false), + new Range("000F", "0010", true, true), + new Range("0015", "0015", true, true) + }, + NoOpTrace.Singleton); + + Assert.AreEqual("1,2,4", string.Join(",", ranges.Select(r => r.Id))); + + // query for minimal point + ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] + { + new Range("", "", true, true), + }, + NoOpTrace.Singleton); + + Assert.AreEqual("0", string.Join(",", ranges.Select(r => r.Id))); + + // query for empty range + ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] + { + new Range("", "", true, false), + }, + NoOpTrace.Singleton); + + Assert.AreEqual("", string.Join(",", ranges.Select(r => r.Id))); + + // entire range + ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] + { + new Range("", "FF", true, false), + }, + NoOpTrace.Singleton); + + Assert.AreEqual("0,1,2,3,4,5,6", string.Join(",", ranges.Select(r => r.Id))); + + // matching range + ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] + { + new Range("0012", "0015", true, false), + }, + NoOpTrace.Singleton); + + Assert.AreEqual("3", string.Join(",", ranges.Select(r => r.Id))); + + // matching range and a little bit more. + ranges = await this.routingMapProvider.TryGetOverlappingRangesAsync( + "dbs/db1/colls/coll1", + new[] + { + new Range("0012", "0015", false, true), + }, + NoOpTrace.Singleton); + + Assert.AreEqual("3,4", string.Join(",", ranges.Select(r => r.Id))); + } + + } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionRoutingHelperTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionRoutingHelperTest.cs index 032b099a48..83db50eb99 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionRoutingHelperTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionRoutingHelperTest.cs @@ -102,7 +102,7 @@ public async Task TestAddFormattedContinuationToHeader() CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( - testData.RoutingMap.Select(range => Tuple.Create(range, (ServiceIdentity)null)), string.Empty); + testData.RoutingMap.Select(range => Tuple.Create(range, (ServiceIdentity)null)), string.Empty, false); RoutingMapProvider routingMapProvider = new RoutingMapProvider(routingMap); foreach (AddFormattedContinuationToHeaderTestUnit positiveTestData in testData.TestSet.Postive) @@ -221,7 +221,7 @@ public async Task TestGetPartitionRoutingInfo() CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( - testData.RoutingMap.Select(range => Tuple.Create(range, (ServiceIdentity)null)), string.Empty); + testData.RoutingMap.Select(range => Tuple.Create(range, (ServiceIdentity)null)), string.Empty, false); foreach (GetPartitionRoutingInfoTestCase testCase in testData.TestCases) { @@ -706,7 +706,7 @@ private static async Task PrefixPartitionKeyTestRunnerAsync( CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( rangesAndServiceIdentity, - collectionRid); + collectionRid, false); RoutingMapProvider routingMapProvider = new RoutingMapProvider(routingMap); TryCatch tryGetQueryPlan = @@ -747,7 +747,7 @@ private static async Task PrefixPartitionKeyChangeFeedTestRunnerAsync( CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( rangesAndServiceIdentity, - collectionRid); + collectionRid, false); RoutingMapProvider routingMapProvider = new RoutingMapProvider(routingMap); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs index 754287088e..ce0a02fa21 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs @@ -231,7 +231,7 @@ private void Init() using GlobalEndpointManager endpointManager = new(mockDocumentClient.Object, new ConnectionPolicy()); - this.partitionKeyRangeCache = new Mock(null, null, null, endpointManager, false); + this.partitionKeyRangeCache = new Mock(null, null, null, endpointManager, false, false); this.partitionKeyRangeCache.Setup( m => m.TryLookupAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/TestUtils.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/TestUtils.cs index ffdd8b98e7..47ea54d214 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/TestUtils.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/TestUtils.cs @@ -63,7 +63,7 @@ public static void SetupCachesInGatewayStoreModel( // Prepare mocked caches. Mock clientCollectionCache = new Mock(new SessionContainer("testhost"), storeModel, null, null, null, false); - Mock partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache.Object, endpointManager, false); + Mock partitionKeyRangeCache = new Mock(null, storeModel, clientCollectionCache.Object, endpointManager, false, false); ContainerProperties containerProperties = ContainerProperties.CreateWithResourceId("test"); containerProperties.PartitionKey = partitionKeyDefinition;