public async Task FeedToken_EPK_HandleSplits() { List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>() { FeedTokenTests.BuildTokenForRange("A", "C", "token1"), FeedTokenTests.BuildTokenForRange("C", "F", "token2") }; FeedTokenEPKRange feedTokenEPKRange = new FeedTokenEPKRange(Guid.NewGuid().ToString(), new Documents.Routing.Range <string>(compositeContinuationTokens[0].Range.Min, compositeContinuationTokens[1].Range.Min, true, false), compositeContinuationTokens); MultiRangeMockDocumentClient documentClient = new MultiRangeMockDocumentClient(); Mock <CosmosClientContext> cosmosClientContext = new Mock <CosmosClientContext>(); cosmosClientContext.Setup(c => c.ClientOptions).Returns(new CosmosClientOptions()); cosmosClientContext.Setup(c => c.DocumentClient).Returns(documentClient); Mock <ContainerCore> containerCore = new Mock <ContainerCore>(); containerCore .Setup(c => c.ClientContext).Returns(cosmosClientContext.Object); Assert.AreEqual(2, feedTokenEPKRange.CompositeContinuationTokens.Count); ResponseMessage split = new ResponseMessage(HttpStatusCode.Gone); split.Headers.SubStatusCode = Documents.SubStatusCodes.PartitionKeyRangeGone; Assert.IsTrue(await feedTokenEPKRange.ShouldRetryAsync(containerCore.Object, split)); // verify token state // Split should have updated initial and created a new token at the end Assert.AreEqual(3, feedTokenEPKRange.CompositeContinuationTokens.Count); CompositeContinuationToken[] continuationTokens = feedTokenEPKRange.CompositeContinuationTokens.ToArray(); // First token is split Assert.AreEqual(compositeContinuationTokens[0].Token, continuationTokens[0].Token); Assert.AreEqual(documentClient.AvailablePartitionKeyRanges[0].MinInclusive, continuationTokens[0].Range.Min); Assert.AreEqual(documentClient.AvailablePartitionKeyRanges[0].MaxExclusive, continuationTokens[0].Range.Max); // Second token remains the same Assert.AreEqual(compositeContinuationTokens[1].Token, continuationTokens[1].Token); Assert.AreEqual(compositeContinuationTokens[1].Range.Min, continuationTokens[1].Range.Min); Assert.AreEqual(compositeContinuationTokens[1].Range.Max, continuationTokens[1].Range.Max); // New third token Assert.AreEqual(compositeContinuationTokens[0].Token, continuationTokens[2].Token); Assert.AreEqual(documentClient.AvailablePartitionKeyRanges[1].MinInclusive, continuationTokens[2].Range.Min); Assert.AreEqual(documentClient.AvailablePartitionKeyRanges[1].MaxExclusive, continuationTokens[2].Range.Max); }
public async Task FeedToken_EPK_ShouldRetry() { List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>() { FeedTokenTests.BuildTokenForRange("A", "C", "token1"), FeedTokenTests.BuildTokenForRange("C", "F", "token2") }; FeedTokenEPKRange feedTokenEPKRange = new FeedTokenEPKRange(Guid.NewGuid().ToString(), new Documents.Routing.Range <string>(compositeContinuationTokens[0].Range.Min, compositeContinuationTokens[1].Range.Min, true, false), compositeContinuationTokens); ContainerCore containerCore = Mock.Of <ContainerCore>(); Assert.IsFalse(await feedTokenEPKRange.ShouldRetryAsync(containerCore, new ResponseMessage(HttpStatusCode.OK))); // A 304 on a multi Range token should cycle on all available ranges before stopping retrying Assert.IsTrue(await feedTokenEPKRange.ShouldRetryAsync(containerCore, new ResponseMessage(HttpStatusCode.NotModified))); feedTokenEPKRange.UpdateContinuation(Guid.NewGuid().ToString()); Assert.IsTrue(await feedTokenEPKRange.ShouldRetryAsync(containerCore, new ResponseMessage(HttpStatusCode.NotModified))); feedTokenEPKRange.UpdateContinuation(Guid.NewGuid().ToString()); Assert.IsFalse(await feedTokenEPKRange.ShouldRetryAsync(containerCore, new ResponseMessage(HttpStatusCode.NotModified))); }