Пример #1
0
        public async Task ShouldRequestForAllPartitionKeyRanges()
        {
            List <string> expectedPKRanges = new List <string>()
            {
                "0", "1"
            };

            List <DocumentServiceLeaseCore> leases = expectedPKRanges.Select(pkRangeId => new DocumentServiceLeaseCore()
            {
                LeaseToken = pkRangeId
            }).ToList();

            Mock <FeedIteratorInternal> mockIterator = new Mock <FeedIteratorInternal>();

            mockIterator.Setup(i => i.ReadNextAsync(It.IsAny <ITrace>(), It.IsAny <CancellationToken>())).ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "0:1"));
            Mock <DocumentServiceLeaseContainer> mockContainer = new Mock <DocumentServiceLeaseContainer>();

            mockContainer.Setup(c => c.GetAllLeasesAsync()).ReturnsAsync(leases);

            List <string> requestedPKRanges = new List <string>();

            FeedIteratorInternal feedCreator(DocumentServiceLease lease, string continuationToken, bool startFromBeginning)
            {
                requestedPKRanges.Add(lease.CurrentLeaseToken);
                return(mockIterator.Object);
            }

            ChangeFeedEstimatorIterator remainingWorkEstimator = new ChangeFeedEstimatorIterator(
                ChangeFeedEstimatorIteratorTests.GetMockedContainer(),
                Mock.Of <ContainerInternal>(),
                mockContainer.Object,
                feedCreator,
                null);

            await remainingWorkEstimator.ReadNextAsync(default);
        public void ExtractLsnFromSessionToken_ShouldParseNewSessionTokenWithMultipleRegionalLsn()
        {
            string newTokenWithRegionalLsn = "0:-1#12345#Region1=1#Region2=2";
            string expectedLsn             = "12345";

            Assert.AreEqual(expectedLsn, ChangeFeedEstimatorIterator.ExtractLsnFromSessionToken(newTokenWithRegionalLsn));
        }
        public async Task ShouldReturnZeroWhenNoItems()
        {
            long globalLsnPKRange0 = 10;
            long globalLsnPKRange1 = 30;
            long expectedTotal     = 0;

            List <DocumentServiceLeaseCore> leases = new List <DocumentServiceLeaseCore>()
            {
                new DocumentServiceLeaseCore()
                {
                    LeaseToken = "0"
                },
                new DocumentServiceLeaseCore()
                {
                    LeaseToken = "1"
                }
            };

            Mock <FeedIterator> mockIteratorPKRange0 = new Mock <FeedIterator>();

            mockIteratorPKRange0.Setup(i => i.ReadNextAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "0:" + globalLsnPKRange0.ToString()));

            Mock <FeedIterator> mockIteratorPKRange1 = new Mock <FeedIterator>();

            mockIteratorPKRange1.Setup(i => i.ReadNextAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "1:" + globalLsnPKRange1.ToString()));

            Mock <DocumentServiceLeaseContainer> mockContainer = new Mock <DocumentServiceLeaseContainer>();

            mockContainer.Setup(c => c.GetAllLeasesAsync()).ReturnsAsync(leases);

            Func <string, string, bool, FeedIterator> feedCreator = (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) =>
            {
                if (partitionKeyRangeId == "0")
                {
                    return(mockIteratorPKRange0.Object);
                }

                return(mockIteratorPKRange1.Object);
            };

            ChangeFeedEstimatorIterator remainingWorkEstimator = new ChangeFeedEstimatorIterator(
                Mock.Of <ContainerInternal>(),
                Mock.Of <ContainerInternal>(),
                mockContainer.Object,
                feedCreator,
                null);

            long estimation = 0;

            while (remainingWorkEstimator.HasMoreResults)
            {
                FeedResponse <ChangeFeedProcessorState> response = await remainingWorkEstimator.ReadNextAsync(default(CancellationToken));

                estimation += response.Sum(e => e.EstimatedLag);
            }

            Assert.AreEqual(expectedTotal, estimation);
        }
        public void ExtractLsnFromSessionToken_ShouldParseNewSessionToken()
        {
            string newToken    = "0:-1#12345";
            string expectedLsn = "12345";

            Assert.AreEqual(expectedLsn, ChangeFeedEstimatorIterator.ExtractLsnFromSessionToken(newToken));
        }
        public async Task ShouldAggregateRUAndDiagnostics()
        {
            List <string> ranges = new List <string>()
            {
                "0", "1"
            };

            List <DocumentServiceLeaseCore> leases = ranges.Select(pkRangeId => new DocumentServiceLeaseCore()
            {
                LeaseToken = pkRangeId
            }).ToList();

            Mock <FeedIterator> mockIterator = new Mock <FeedIterator>();

            mockIterator.Setup(i => i.ReadNextAsync(It.IsAny <CancellationToken>())).ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "0:1"));
            Mock <DocumentServiceLeaseContainer> mockContainer = new Mock <DocumentServiceLeaseContainer>();

            mockContainer.Setup(c => c.GetAllLeasesAsync()).ReturnsAsync(leases);

            Func <string, string, bool, FeedIterator> feedCreator = (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) => mockIterator.Object;

            ChangeFeedEstimatorIterator remainingWorkEstimator = new ChangeFeedEstimatorIterator(
                Mock.Of <ContainerInternal>(),
                Mock.Of <ContainerInternal>(),
                mockContainer.Object,
                feedCreator,
                null);

            FeedResponse <ChangeFeedProcessorState> response = await remainingWorkEstimator.ReadNextAsync(default(CancellationToken));

            Assert.AreEqual(2, response.Headers.RequestCharge, "Should contain the sum of all RU charges for each partition read."); // Each request costs 1 RU

            Assert.AreEqual(2, response.Count, $"Should contain one result per range");
        }
        public async Task ShouldReturnAllLeasesInPages()
        {
            const int     pageSize = 1;
            List <string> ranges   = new List <string>()
            {
                "0", "1"
            };

            List <DocumentServiceLeaseCore> leases = ranges.Select(pkRangeId => new DocumentServiceLeaseCore()
            {
                LeaseToken = pkRangeId
            }).ToList();

            Mock <FeedIterator> mockIterator = new Mock <FeedIterator>();

            mockIterator.Setup(i => i.ReadNextAsync(It.IsAny <CancellationToken>())).ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "0:1"));
            Mock <DocumentServiceLeaseContainer> mockContainer = new Mock <DocumentServiceLeaseContainer>();

            mockContainer.Setup(c => c.GetAllLeasesAsync()).ReturnsAsync(leases);

            Func <string, string, bool, FeedIterator> feedCreator = (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) =>
            {
                return(mockIterator.Object);
            };

            ChangeFeedEstimatorIterator remainingWorkEstimator = new ChangeFeedEstimatorIterator(
                Mock.Of <ContainerInternal>(),
                Mock.Of <ContainerInternal>(),
                mockContainer.Object,
                feedCreator,
                new ChangeFeedEstimatorRequestOptions()
            {
                MaxItemCount = pageSize
            });                                                                       // Expect multiple pages

            FeedResponse <ChangeFeedProcessorState> firstResponse = await remainingWorkEstimator.ReadNextAsync(default(CancellationToken));

            Assert.IsTrue(remainingWorkEstimator.HasMoreResults);
            Assert.AreEqual(pageSize, firstResponse.Count);

            FeedResponse <ChangeFeedProcessorState> secondResponse = await remainingWorkEstimator.ReadNextAsync(default(CancellationToken));

            Assert.IsFalse(remainingWorkEstimator.HasMoreResults);
            Assert.AreEqual(pageSize, secondResponse.Count);
        }
        public async Task ReportsInstanceNameAndToken()
        {
            string        instanceName = Guid.NewGuid().ToString();
            string        leaseToken   = Guid.NewGuid().ToString();
            List <string> ranges       = new List <string>()
            {
                leaseToken
            };

            List <DocumentServiceLeaseCore> leases = new List <DocumentServiceLeaseCore>()
            {
                new DocumentServiceLeaseCore()
                {
                    LeaseToken = leaseToken,
                    Owner      = instanceName
                }
            };
            Mock <FeedIterator> mockIterator = new Mock <FeedIterator>();

            mockIterator.Setup(i => i.ReadNextAsync(It.IsAny <CancellationToken>())).ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "0:1"));
            Mock <DocumentServiceLeaseContainer> mockContainer = new Mock <DocumentServiceLeaseContainer>();

            mockContainer.Setup(c => c.GetAllLeasesAsync()).ReturnsAsync(leases);

            Func <string, string, bool, FeedIterator> feedCreator = (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) =>
            {
                return(mockIterator.Object);
            };

            ChangeFeedEstimatorIterator remainingWorkEstimator = new ChangeFeedEstimatorIterator(
                Mock.Of <ContainerInternal>(),
                Mock.Of <ContainerInternal>(),
                mockContainer.Object,
                feedCreator,
                null);

            FeedResponse <ChangeFeedProcessorState> firstResponse = await remainingWorkEstimator.ReadNextAsync(default(CancellationToken));

            ChangeFeedProcessorState remainingLeaseWork = firstResponse.First();

            Assert.AreEqual(instanceName, remainingLeaseWork.InstanceName);
            Assert.AreEqual(leaseToken, remainingLeaseWork.LeaseToken);
        }
        public async Task ShouldRequestForAllPartitionKeyRanges()
        {
            List <string> expectedPKRanges = new List <string>()
            {
                "0", "1"
            };

            List <DocumentServiceLeaseCore> leases = expectedPKRanges.Select(pkRangeId => new DocumentServiceLeaseCore()
            {
                LeaseToken = pkRangeId
            }).ToList();

            Mock <FeedIterator> mockIterator = new Mock <FeedIterator>();

            mockIterator.Setup(i => i.ReadNextAsync(It.IsAny <CancellationToken>())).ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "0:1"));
            Mock <DocumentServiceLeaseContainer> mockContainer = new Mock <DocumentServiceLeaseContainer>();

            mockContainer.Setup(c => c.GetAllLeasesAsync()).ReturnsAsync(leases);

            List <string> requestedPKRanges = new List <string>();

            Func <string, string, bool, FeedIterator> feedCreator = (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) =>
            {
                requestedPKRanges.Add(partitionKeyRangeId);
                return(mockIterator.Object);
            };

            ChangeFeedEstimatorIterator remainingWorkEstimator = new ChangeFeedEstimatorIterator(
                Mock.Of <ContainerInternal>(),
                Mock.Of <ContainerInternal>(),
                mockContainer.Object,
                feedCreator,
                null);

            await remainingWorkEstimator.ReadNextAsync(default(CancellationToken));

            CollectionAssert.AreEquivalent(expectedPKRanges, requestedPKRanges);
        }