public async Task GetTargetRangeFromContinuationTokenNonExistentContainer()
        {
            List <Range <string> > providedRanges = new List <Range <string> > {
                new Range <string>(
                    PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                    PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                    isMinInclusive: true,
                    isMaxInclusive: false)
            };

            //Not empty
            Range <string> range = new Range <string>("A", "B", true, false);
            List <CompositeContinuationToken> suppliedTokens = new List <CompositeContinuationToken>
            {
                new CompositeContinuationToken {
                    Range = range
                }
            };

            IReadOnlyList <PartitionKeyRange> overlappingRanges = new List <PartitionKeyRange> {
                new PartitionKeyRange {
                    Id = "0", MinInclusive = "A", MaxExclusive = "B"
                },
                new PartitionKeyRange {
                    Id = "1", MinInclusive = "B", MaxExclusive = "C"
                }
            }.AsReadOnly();

            Mock <IRoutingMapProvider> routingMapProvider = new Mock <IRoutingMapProvider>();

            routingMapProvider
            .SetupSequence(m => m.TryGetOverlappingRangesAsync(
                               It.IsAny <string>(),
                               It.Is <Range <string> >(x => x.Min == range.Min),
                               It.IsAny <ITrace>(),
                               It.IsAny <bool>()))
            .Returns(Task.FromResult((IReadOnlyList <PartitionKeyRange>)overlappingRanges.Skip(1).ToList()))
            .Returns(Task.FromResult((IReadOnlyList <PartitionKeyRange>)null));

            PartitionRoutingHelper partitionRoutingHelper = new PartitionRoutingHelper();
            ResolvedRangeInfo      resolvedRangeInfo      = await partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRangeAsync(
                providedRanges,
                routingMapProvider.Object,
                CollectionId,
                range,
                suppliedTokens,
                NoOpTrace.Singleton,
                RntdbEnumerationDirection.Reverse);

            Assert.IsNotNull(resolvedRangeInfo);
            Assert.IsNull(resolvedRangeInfo.ResolvedRange);
            Assert.IsNull(resolvedRangeInfo.ContinuationTokens);
        }
Example #2
0
        public async Task GetTargetRangeFromContinuationTokenWhenNotEmpty()
        {
            List <Range <string> > providedRanges = new List <Range <string> > {
                new Range <string>(
                    PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                    PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                    isMinInclusive: true,
                    isMaxInclusive: false)
            };

            //Not empty
            Range <string> range = new Range <string>("A", "B", true, false);
            List <CompositeContinuationToken> suppliedTokens = new List <CompositeContinuationToken>
            {
                new CompositeContinuationToken {
                    Range = range
                }
            };

            IReadOnlyList <PartitionKeyRange> overlappingRanges = new List <PartitionKeyRange> {
                new PartitionKeyRange {
                    Id = "0", MinInclusive = "A", MaxExclusive = "B"
                },
                new PartitionKeyRange {
                    Id = "1", MinInclusive = "B", MaxExclusive = "C"
                }
            }.AsReadOnly();
            Mock <IRoutingMapProvider> routingMapProvider = new Mock <IRoutingMapProvider>();

            routingMapProvider.Setup(m => m.TryGetOverlappingRangesAsync(
                                         It.IsAny <string>(),
                                         It.Is <Range <string> >(x => x.Min == range.Min),
                                         It.IsAny <bool>()
                                         )).Returns(Task.FromResult((IReadOnlyList <PartitionKeyRange>)overlappingRanges.Take(1).ToList())).Verifiable();

            //Reverse
            PartitionRoutingHelper partitionRoutingHelper = new PartitionRoutingHelper();
            ResolvedRangeInfo      resolvedRangeInfo      = await partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRangeAsync(
                providedRanges,
                routingMapProvider.Object,
                CollectionId,
                range,
                suppliedTokens,
                RntdbEnumerationDirection.Reverse);

            Assert.AreEqual(overlappingRanges.First().Id, resolvedRangeInfo.ResolvedRange.Id);
            CollectionAssert.AreEqual(suppliedTokens, resolvedRangeInfo.ContinuationTokens);
            routingMapProvider.Verify();
        }
        public async Task GetTargetRangeFromContinuationTokenOnSplit()
        {
            const string Token = "token";

            List <Range <string> > providedRanges = new List <Range <string> > {
                new Range <string>(
                    PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                    PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                    isMinInclusive: true,
                    isMaxInclusive: false)
            };

            Range <string> rangeFromContinuationToken        = new Range <string>("A", "C", true, false);
            List <CompositeContinuationToken> suppliedTokens = new List <CompositeContinuationToken>
            {
                new CompositeContinuationToken {
                    Token = Token, Range = rangeFromContinuationToken
                }
            };

            IReadOnlyList <PartitionKeyRange> overlappingRanges = new List <PartitionKeyRange> {
                new PartitionKeyRange {
                    Id = "2", MinInclusive = "A", MaxExclusive = "B"
                },
                new PartitionKeyRange {
                    Id = "3", MinInclusive = "B", MaxExclusive = "C"
                },
                new PartitionKeyRange {
                    Id = "1", MinInclusive = "C", MaxExclusive = "D"
                }
            }.AsReadOnly();
            IReadOnlyList <PartitionKeyRange> replacedRanges     = overlappingRanges.Take(2).ToList().AsReadOnly();
            Mock <IRoutingMapProvider>        routingMapProvider = new Mock <IRoutingMapProvider>();

            routingMapProvider.Setup(m => m.TryGetOverlappingRangesAsync(
                                         It.IsAny <string>(),
                                         It.Is <Range <string> >(x => x.Min == rangeFromContinuationToken.Min),
                                         It.IsAny <ITrace>(),
                                         It.Is <bool>(x => x == false)
                                         )).Returns(Task.FromResult((IReadOnlyList <PartitionKeyRange>)overlappingRanges.Take(1).ToList())).Verifiable();
            routingMapProvider.Setup(m => m.TryGetOverlappingRangesAsync(
                                         It.IsAny <string>(),
                                         It.Is <Range <string> >(x => x.Min == rangeFromContinuationToken.Min && x.Max == rangeFromContinuationToken.Max),
                                         It.IsAny <ITrace>(),
                                         It.Is <bool>(x => x == true)
                                         )).Returns(Task.FromResult(replacedRanges)).Verifiable();

            //Reverse
            PartitionRoutingHelper partitionRoutingHelper = new PartitionRoutingHelper();
            ResolvedRangeInfo      resolvedRangeInfo      = await partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRangeAsync(
                providedRanges,
                routingMapProvider.Object,
                CollectionId,
                rangeFromContinuationToken,
                suppliedTokens,
                NoOpTrace.Singleton,
                RntdbEnumerationDirection.Reverse);

            routingMapProvider.Verify();
            Assert.IsTrue(replacedRanges.Last().Equals(resolvedRangeInfo.ResolvedRange));
            List <PartitionKeyRange> reversedReplacedRanges = new List <PartitionKeyRange>(replacedRanges);

            reversedReplacedRanges.Reverse();
            Assert.AreEqual(replacedRanges.Count, resolvedRangeInfo.ContinuationTokens.Count);
            Assert.AreEqual(resolvedRangeInfo.ContinuationTokens[0].Token, Token);

            for (int i = 0; i < resolvedRangeInfo.ContinuationTokens.Count; i++)
            {
                Assert.IsTrue(reversedReplacedRanges[i].ToRange().Equals(resolvedRangeInfo.ContinuationTokens[i].Range));
            }

            //Forward
            partitionRoutingHelper = new PartitionRoutingHelper();
            resolvedRangeInfo      = await partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRangeAsync(
                providedRanges,
                routingMapProvider.Object,
                CollectionId,
                rangeFromContinuationToken,
                suppliedTokens,
                NoOpTrace.Singleton,
                RntdbEnumerationDirection.Forward);

            routingMapProvider.Verify();
            Assert.IsTrue(replacedRanges.First().Equals(resolvedRangeInfo.ResolvedRange));
            Assert.AreEqual(replacedRanges.Count, resolvedRangeInfo.ContinuationTokens.Count);
            Assert.AreEqual(resolvedRangeInfo.ContinuationTokens[0].Token, Token);

            for (int i = 0; i < resolvedRangeInfo.ContinuationTokens.Count; i++)
            {
                Assert.IsTrue(replacedRanges[i].ToRange().Equals(resolvedRangeInfo.ContinuationTokens[i].Range));
            }
        }