public void ValidateSerialization_AllFields() { DocumentServiceLeaseCore originalLease = new DocumentServiceLeaseCore { LeaseId = "id", ETag = "etag", LeaseToken = "0", Owner = "owner", ContinuationToken = "continuation", LeasePartitionKey = "pk", Timestamp = DateTime.Now - TimeSpan.FromSeconds(5), Properties = new Dictionary <string, string> { { "key", "value" } } }; string json = JsonConvert.SerializeObject(originalLease); DocumentServiceLeaseCore lease = JsonConvert.DeserializeObject <DocumentServiceLeaseCore>(json); Assert.AreEqual(originalLease.Id, lease.Id); Assert.AreEqual(originalLease.ETag, lease.ETag); Assert.AreEqual(originalLease.LeaseToken, lease.LeaseToken); Assert.AreEqual(originalLease.Owner, lease.Owner); Assert.AreEqual(originalLease.ContinuationToken, lease.ContinuationToken); Assert.AreEqual(originalLease.Timestamp, lease.Timestamp); Assert.AreEqual(originalLease.PartitionKey, lease.PartitionKey); Assert.AreEqual(originalLease.Properties["key"], lease.Properties["key"]); }
public async Task NextReadHasUpdatedContinuation() { int itemCount = 5; string pkRangeId = "0"; string etag = Guid.NewGuid().ToString(); DateTime startTime = DateTime.UtcNow; DocumentServiceLeaseCore documentServiceLeaseCore = new DocumentServiceLeaseCore() { LeaseToken = pkRangeId }; ResponseMessage firstResponse = new ResponseMessage(System.Net.HttpStatusCode.OK); firstResponse.Headers.ETag = etag; ResponseMessage secondResponse = new ResponseMessage(System.Net.HttpStatusCode.OK); int responseCount = 0; Func <Action <RequestMessage>, bool> validateEnricher = (Action <RequestMessage> enricher) => { RequestMessage requestMessage = new RequestMessage(); enricher(requestMessage); return(responseCount++ == 0 || requestMessage.Headers.IfNoneMatch == etag); }; Mock <ContainerInternal> containerMock = new Mock <ContainerInternal>(); Mock <CosmosClientContext> mockContext = new Mock <CosmosClientContext>(); mockContext.SetupSequence(c => c.ProcessResourceOperationStreamAsync( It.IsAny <string>(), It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document), It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed), It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount), It.Is <ContainerInternal>(o => o == containerMock.Object), It.IsAny <FeedRange>(), It.IsAny <Stream>(), It.Is <Action <RequestMessage> >(enricher => validateEnricher(enricher)), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>() ) ) .ReturnsAsync(firstResponse) .ReturnsAsync(secondResponse); containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object); containerMock.Setup(c => c.LinkUri).Returns("http://localhot"); ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create( lease: documentServiceLeaseCore, continuationToken: null, maxItemCount: itemCount, container: containerMock.Object, startTime: startTime, startFromBeginning: false); await iterator.ReadNextAsync(); await iterator.ReadNextAsync(); Assert.AreEqual(2, responseCount); }
public void ValidateSerialization_AllFields() { DocumentServiceLeaseCore originalLease = new DocumentServiceLeaseCore { LeaseId = "id", ETag = "etag", LeaseToken = "0", Owner = "owner", ContinuationToken = "continuation", Timestamp = DateTime.Now - TimeSpan.FromSeconds(5), Properties = new Dictionary <string, string> { { "key", "value" } } }; byte[] buffer = new byte[4096]; BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream1 = new MemoryStream(buffer); MemoryStream stream2 = new MemoryStream(buffer); formatter.Serialize(stream1, originalLease); var lease = (DocumentServiceLeaseCore)formatter.Deserialize(stream2); Assert.AreEqual(originalLease.Id, lease.Id); Assert.AreEqual(originalLease.ETag, lease.ETag); Assert.AreEqual(originalLease.LeaseToken, lease.LeaseToken); Assert.AreEqual(originalLease.Owner, lease.Owner); Assert.AreEqual(originalLease.ContinuationToken, lease.ContinuationToken); Assert.AreEqual(originalLease.Timestamp, lease.Timestamp); Assert.AreEqual(originalLease.Properties["key"], lease.Properties["key"]); }
public void ValidateProperties() { string id = "id"; string etag = "etag"; string partitionId = "0"; string owner = "owner"; string continuationToken = "continuation"; DateTime timestamp = DateTime.Now - TimeSpan.FromSeconds(5); string key = "key"; string value = "value"; DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore { LeaseId = id, ETag = etag, LeaseToken = partitionId, Owner = owner, ContinuationToken = continuationToken, Timestamp = timestamp, Properties = new Dictionary <string, string> { { "key", "value" } }, }; Assert.AreEqual(id, lease.Id); Assert.AreEqual(etag, lease.ETag); Assert.AreEqual(partitionId, lease.LeaseToken); Assert.AreEqual(owner, lease.Owner); Assert.AreEqual(continuationToken, lease.ContinuationToken); Assert.AreEqual(timestamp, lease.Timestamp); Assert.AreEqual(value, lease.Properties[key]); Assert.AreEqual(etag, lease.ConcurrencyToken); }
public async Task RetriesOnPreconditionFailed() { string itemId = "1"; Cosmos.PartitionKey partitionKey = new Cosmos.PartitionKey("1"); DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); Mock <ContainerCore> mockedItems = new Mock <ContainerCore>(); mockedItems.Setup(i => i.ReadItemStreamAsync( It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk.Equals(partitionKey)), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => { return(new ResponseMessage(HttpStatusCode.OK) { Content = new CosmosJsonDotNetSerializer().ToStream(leaseToUpdate) }); }); mockedItems.SetupSequence(i => i.ReplaceItemStreamAsync( It.IsAny <Stream>(), It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk.Equals(partitionKey)), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .Returns(() => { return(Task.FromResult(new ResponseMessage(HttpStatusCode.PreconditionFailed))); }) .Returns(() => { return(Task.FromResult(new ResponseMessage(HttpStatusCode.OK) { Content = new CosmosJsonDotNetSerializer().ToStream(leaseToUpdate) })); }); var updater = new DocumentServiceLeaseUpdaterCosmos(DocumentServiceLeaseUpdaterCosmosTests.GetMockedContainer(mockedItems)); var updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, partitionKey, serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); Mock.Get(mockedItems.Object) .Verify(items => items.ReplaceItemStreamAsync( It.IsAny <Stream>(), It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk.Equals(partitionKey)), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); Mock.Get(mockedItems.Object) .Verify(items => items.ReadItemStreamAsync(It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk.Equals(partitionKey)), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once); }
public async Task ThrowsAfterMaxRetries() { string itemId = "1"; object partitionKey = "1"; DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); Mock <CosmosItems> mockedItems = new Mock <CosmosItems>(); mockedItems.Setup(i => i.ReadItemAsync <DocumentServiceLeaseCore>( It.Is <object>((pk) => pk == partitionKey), It.Is <string>((id) => id == itemId), It.IsAny <CosmosItemRequestOptions>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => { var itemResponse = new Mock <CosmosItemResponse <DocumentServiceLeaseCore> >(); itemResponse.Setup(i => i.Resource).Returns(leaseToUpdate); return(itemResponse.Object); }); mockedItems.Setup(i => i.ReplaceItemAsync <DocumentServiceLeaseCore>( It.Is <object>((pk) => pk == partitionKey), It.Is <string>((id) => id == itemId), It.Is <DocumentServiceLeaseCore>((lease) => lease == leaseToUpdate), It.IsAny <CosmosItemRequestOptions>(), It.IsAny <CancellationToken>())) .Throws(new CosmosException(string.Empty, HttpStatusCode.PreconditionFailed, 0, string.Empty, 0)); var updater = new DocumentServiceLeaseUpdaterCosmos(DocumentServiceLeaseUpdaterCosmosTests.GetMockedContainer(mockedItems.Object)); var updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, partitionKey, serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); }
public async Task HandlePartitionGoneAsync_PKRangeBasedLease_Merge() { string continuation = Guid.NewGuid().ToString(); Documents.Routing.Range <string> range = new Documents.Routing.Range <string>("", "BB", true, false); DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseToken = "0", ContinuationToken = continuation, Owner = Guid.NewGuid().ToString(), FeedRange = new FeedRangeEpk(range) }; Mock <Routing.PartitionKeyRangeCache> pkRangeCache = new Mock <Routing.PartitionKeyRangeCache>( Mock.Of <Documents.IAuthorizationTokenProvider>(), Mock.Of <Documents.IStoreModel>(), Mock.Of <Common.CollectionCache>()); List <Documents.PartitionKeyRange> resultingRanges = new List <Documents.PartitionKeyRange>() { new Documents.PartitionKeyRange() { Id = "2", MinInclusive = "", MaxExclusive = "FF" } }; pkRangeCache.Setup(p => p.TryGetOverlappingRangesAsync( It.IsAny <string>(), It.Is <Documents.Routing.Range <string> >(r => r.Min == range.Min && r.Max == range.Max), It.IsAny <ITrace>(), It.Is <bool>(b => b == true))) .ReturnsAsync(resultingRanges); Mock <DocumentServiceLeaseManager> leaseManager = new Mock <DocumentServiceLeaseManager>(); PartitionSynchronizerCore partitionSynchronizerCore = new PartitionSynchronizerCore( Mock.Of <ContainerInternal>(), Mock.Of <DocumentServiceLeaseContainer>(), leaseManager.Object, 1, pkRangeCache.Object, Guid.NewGuid().ToString()); await partitionSynchronizerCore.HandlePartitionGoneAsync(lease); leaseManager.Verify(l => l.CreateLeaseIfNotExistAsync( It.IsAny <Documents.PartitionKeyRange>(), It.IsAny <string>()), Times.Never); leaseManager.Verify(l => l.CreateLeaseIfNotExistAsync( It.IsAny <FeedRangeEpk>(), It.IsAny <string>()), Times.Once); leaseManager.Verify(l => l.CreateLeaseIfNotExistAsync( It.Is <FeedRangeEpk>(epKRange => epKRange.Range.Min == range.Min && epKRange.Range.Max == range.Max), It.Is <string>(c => c == continuation)), Times.Once); }
public async Task ShouldSetFeedRangePartitionKeyRange() { int itemCount = 5; string pkRangeId = "0"; string etag = Guid.NewGuid().ToString(); DateTime startTime = DateTime.UtcNow; DocumentServiceLeaseCore documentServiceLeaseCore = new DocumentServiceLeaseCore() { LeaseToken = pkRangeId }; Mock <ContainerInternal> containerMock = new Mock <ContainerInternal>(); Mock <CosmosClientContext> mockContext = new Mock <CosmosClientContext>(); mockContext.Setup(c => c.ProcessResourceOperationStreamAsync( It.IsAny <string>(), It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document), It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed), It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount), It.Is <ContainerInternal>(o => o == containerMock.Object), It.Is <FeedRange>(fr => fr is FeedRangePartitionKeyRange), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>() ) ).ReturnsAsync(new ResponseMessage(System.Net.HttpStatusCode.OK)); containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object); containerMock.Setup(c => c.LinkUri).Returns("http://localhot"); ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create( lease: documentServiceLeaseCore, continuationToken: null, maxItemCount: itemCount, container: containerMock.Object, startTime: startTime, startFromBeginning: false); ResponseMessage response = await iterator.ReadNextAsync(); Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode); mockContext.Verify(c => c.ProcessResourceOperationStreamAsync( It.IsAny <string>(), It.Is <Documents.ResourceType>(rt => rt == Documents.ResourceType.Document), It.Is <Documents.OperationType>(rt => rt == Documents.OperationType.ReadFeed), It.Is <ChangeFeedRequestOptions>(cfo => cfo.PageSizeHint == itemCount), It.Is <ContainerInternal>(o => o == containerMock.Object), It.Is <FeedRange>(fr => fr is FeedRangePartitionKeyRange), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>() ), Times.Once); }
public async Task RetriesOnPreconditionFailed() { string itemId = "1"; Cosmos.PartitionKey partitionKey = new Cosmos.PartitionKey("1"); DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); Mock <CosmosContainerCore> mockedItems = new Mock <CosmosContainerCore>(); mockedItems.Setup(i => i.ReadItemAsync <DocumentServiceLeaseCore>( It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.Is <string>((id) => id == itemId), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => { var itemResponse = new Mock <ItemResponse <DocumentServiceLeaseCore> >(); itemResponse.Setup(i => i.Resource).Returns(leaseToUpdate); return(itemResponse.Object); }); mockedItems.SetupSequence(i => i.ReplaceItemAsync <DocumentServiceLeaseCore>( It.Is <string>((id) => id == itemId), It.Is <DocumentServiceLeaseCore>((lease) => lease == leaseToUpdate), It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .Throws(new CosmosException(string.Empty, HttpStatusCode.PreconditionFailed, 0, string.Empty, 0)) .Returns(() => { var itemResponse = new Mock <ItemResponse <DocumentServiceLeaseCore> >(); itemResponse.Setup(i => i.Resource).Returns(leaseToUpdate); return(Task.FromResult(itemResponse.Object)); }); var updater = new DocumentServiceLeaseUpdaterCosmos(DocumentServiceLeaseUpdaterCosmosTests.GetMockedContainer(mockedItems)); var updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, partitionKey, serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); Assert.AreEqual("newHost", updatedLease.Owner); Mock.Get(mockedItems.Object) .Verify(items => items.ReplaceItemAsync(It.Is <string>((id) => id == itemId), It.Is <DocumentServiceLeaseCore>((lease) => lease == leaseToUpdate), It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); Mock.Get(mockedItems.Object) .Verify(items => items.ReadItemAsync <DocumentServiceLeaseCore>(It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.Is <string>((id) => id == itemId), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once); }
public async Task ReleaseCompletes() { DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions { HostName = Guid.NewGuid().ToString() }; DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseId = Guid.NewGuid().ToString(), LeaseToken = "0", Owner = Guid.NewGuid().ToString(), FeedRange = new FeedRangePartitionKeyRange("0") }; Mock <DocumentServiceLeaseUpdater> mockUpdater = new Mock <DocumentServiceLeaseUpdater>(); Func <Func <DocumentServiceLease, DocumentServiceLease>, bool> validateUpdater = (Func <DocumentServiceLease, DocumentServiceLease> updater) => { DocumentServiceLease afterUpdateLease = updater(lease); return(afterUpdateLease.Owner == null); }; mockUpdater.Setup(c => c.UpdateLeaseAsync( It.IsAny <DocumentServiceLease>(), It.IsAny <string>(), It.IsAny <PartitionKey>(), It.Is <Func <DocumentServiceLease, DocumentServiceLease> >(f => validateUpdater(f)))) .ReturnsAsync(lease); ResponseMessage leaseResponse = new ResponseMessage(System.Net.HttpStatusCode.OK) { Content = new CosmosJsonDotNetSerializer().ToStream(lease) }; Mock <ContainerInternal> mockedContainer = new Mock <ContainerInternal>(); mockedContainer.Setup(c => c.ReadItemStreamAsync( It.Is <string>(id => id == lease.LeaseId), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(leaseResponse); DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( Mock.Of <ContainerInternal>(), mockedContainer.Object, mockUpdater.Object, options, Mock.Of <RequestOptionsFactory>()); await documentServiceLeaseManagerCosmos.ReleaseAsync(lease); }
public async Task PopulateMissingRange() { DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions { HostName = Guid.NewGuid().ToString() }; DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseToken = "0", Owner = Guid.NewGuid().ToString() }; Mock <DocumentServiceLeaseUpdater> mockUpdater = new Mock <DocumentServiceLeaseUpdater>(); Func <Func <DocumentServiceLease, DocumentServiceLease>, bool> validateUpdater = (Func <DocumentServiceLease, DocumentServiceLease> updater) => { // Simulate dirty read from db DocumentServiceLease afterUpdateLease = updater(lease); return(afterUpdateLease.FeedRange != null); }; mockUpdater.Setup(c => c.UpdateLeaseAsync( It.IsAny <DocumentServiceLease>(), It.IsAny <string>(), It.IsAny <PartitionKey>(), It.Is <Func <DocumentServiceLease, DocumentServiceLease> >(f => validateUpdater(f)))) .ReturnsAsync(lease); Mock <ContainerInternal> containerMock = new Mock <ContainerInternal>(); Mock <CosmosClientContext> mockContext = new Mock <CosmosClientContext>(); containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object); containerMock.Setup(c => c.LinkUri).Returns("http://localhot"); containerMock.Setup(c => c.GetCachedRIDAsync(It.IsAny <bool>(), It.IsAny <CancellationToken>())).ReturnsAsync("test"); MockDocumentClient mockDocumentClient = new MockDocumentClient(); mockContext.Setup(c => c.DocumentClient).Returns(mockDocumentClient); DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( containerMock.Object, Mock.Of <ContainerInternal>(), mockUpdater.Object, options, Mock.Of <RequestOptionsFactory>()); DocumentServiceLease afterAcquire = await documentServiceLeaseManagerCosmos.AcquireAsync(lease); Assert.IsNotNull(afterAcquire.FeedRange); }
public void ValidateSerialization_NullFields() { DocumentServiceLeaseCore originalLease = new DocumentServiceLeaseCore(); string json = JsonConvert.SerializeObject(originalLease); DocumentServiceLeaseCore lease = JsonConvert.DeserializeObject <DocumentServiceLeaseCore>(json); Assert.IsNull(lease.Id); Assert.IsNull(lease.ETag); Assert.IsNull(lease.LeaseToken); Assert.IsNull(lease.Owner); Assert.IsNull(lease.ContinuationToken); Assert.IsNull(lease.PartitionKey); Assert.AreEqual(new DocumentServiceLeaseCore().Timestamp, lease.Timestamp); Assert.IsTrue(lease.Properties.Count == 0); }
public async Task ReleaseWhen404WithSomeSubstatusDoesThrow() { DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions { HostName = Guid.NewGuid().ToString() }; DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseId = Guid.NewGuid().ToString(), LeaseToken = "0", Owner = Guid.NewGuid().ToString(), FeedRange = new FeedRangePartitionKeyRange("0") }; Mock <DocumentServiceLeaseUpdater> mockUpdater = new Mock <DocumentServiceLeaseUpdater>(); ResponseMessage leaseResponse = new ResponseMessage(System.Net.HttpStatusCode.NotFound); leaseResponse.Headers.SubStatusCode = Documents.SubStatusCodes.ReadSessionNotAvailable; Mock <ContainerInternal> mockedContainer = new Mock <ContainerInternal>(); mockedContainer.Setup(c => c.ReadItemStreamAsync( It.Is <string>(id => id == lease.LeaseId), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(leaseResponse); DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( Mock.Of <ContainerInternal>(), mockedContainer.Object, mockUpdater.Object, options, Mock.Of <RequestOptionsFactory>()); CosmosException cosmosException = await Assert.ThrowsExceptionAsync <CosmosException>(() => documentServiceLeaseManagerCosmos.ReleaseAsync(lease)); Assert.AreEqual(System.Net.HttpStatusCode.NotFound, cosmosException.StatusCode); Assert.AreEqual((int)Documents.SubStatusCodes.ReadSessionNotAvailable, cosmosException.SubStatusCode); mockUpdater.Verify(c => c.UpdateLeaseAsync( It.IsAny <DocumentServiceLease>(), It.IsAny <string>(), It.IsAny <PartitionKey>(), It.IsAny <Func <DocumentServiceLease, DocumentServiceLease> >()), Times.Never); }
public void ValidateSerialization_AllFields() { DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseId = "id" }; LeaseLostException originalException = new LeaseLostException(lease, new Exception("foo"), true); string serialized = JsonConvert.SerializeObject(originalException); LeaseLostException deserializedException = JsonConvert.DeserializeObject <LeaseLostException>(serialized); Assert.AreEqual(originalException.Message, deserializedException.Message); Assert.AreEqual(originalException.InnerException.Message, deserializedException.InnerException.Message); Assert.AreEqual(originalException.Lease.Id, deserializedException.Lease.Id); Assert.AreEqual(originalException.IsGone, deserializedException.IsGone); }
public async Task ThrowsOnNotFoundReplace() { string itemId = "1"; Cosmos.PartitionKey partitionKey = new Cosmos.PartitionKey("1"); DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); Mock <CosmosContainerCore> mockedItems = new Mock <CosmosContainerCore>(); mockedItems.Setup(i => i.ReadItemAsync <DocumentServiceLeaseCore>( It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.Is <string>((id) => id == itemId), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => { var itemResponse = new Mock <ItemResponse <DocumentServiceLeaseCore> >(); itemResponse.Setup(i => i.Resource).Returns(leaseToUpdate); return(itemResponse.Object); }); mockedItems.SetupSequence(i => i.ReplaceItemAsync <DocumentServiceLeaseCore>( It.Is <string>((id) => id == itemId), It.Is <DocumentServiceLeaseCore>((lease) => lease == leaseToUpdate), It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .Returns(() => { var itemResponse = new Mock <ItemResponse <DocumentServiceLeaseCore> >(); itemResponse.Setup(i => i.StatusCode).Returns(HttpStatusCode.NotFound); return(Task.FromResult(itemResponse.Object)); }) .Returns(() => { var itemResponse = new Mock <ItemResponse <DocumentServiceLeaseCore> >(); itemResponse.Setup(i => i.Resource).Returns(leaseToUpdate); return(Task.FromResult(itemResponse.Object)); }); var updater = new DocumentServiceLeaseUpdaterCosmos(DocumentServiceLeaseUpdaterCosmosTests.GetMockedContainer(mockedItems)); var updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, partitionKey, serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); }
public async Task UpdatesLease() { string itemId = "1"; Cosmos.PartitionKey partitionKey = new Cosmos.PartitionKey("1"); DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); Stream leaseStream = new CosmosJsonDotNetSerializer().ToStream(leaseToUpdate); Mock <ContainerCore> mockedItems = new Mock <ContainerCore>(); mockedItems.Setup(i => i.ReplaceItemStreamAsync( It.IsAny <Stream>(), It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk.Equals(partitionKey)), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .ReturnsAsync((Stream stream, string id, PartitionKey pk, ItemRequestOptions options, CancellationToken cancellationToken) => { return(new ResponseMessage(HttpStatusCode.OK) { Content = stream }); }); var updater = new DocumentServiceLeaseUpdaterCosmos(DocumentServiceLeaseUpdaterCosmosTests.GetMockedContainer(mockedItems)); var updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, partitionKey, serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); Assert.AreEqual("newHost", updatedLease.Owner); Mock.Get(mockedItems.Object) .Verify(items => items.ReplaceItemStreamAsync( It.IsAny <Stream>(), It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk.Equals(partitionKey)), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once); Mock.Get(mockedItems.Object) .Verify(items => items.ReadItemStreamAsync( It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>((pk) => pk.Equals(partitionKey)), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Never); }
public async Task RetriesIfCannotFind() { string itemId = "1"; object partitionKey = "1"; List <KeyValuePair <string, DocumentServiceLease> > state = new List <KeyValuePair <string, DocumentServiceLease> >(); DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); ConcurrentDictionary <string, DocumentServiceLease> container = new ConcurrentDictionary <string, DocumentServiceLease>(state); DocumentServiceLeaseUpdaterInMemory updater = new DocumentServiceLeaseUpdaterInMemory(container); DocumentServiceLease updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, partitionKey, serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); }
public async Task CreatesPartitionKeyBasedLease(int factoryType) { RequestOptionsFactory requestOptionsFactory = GetRequestOptionsFactory(factoryType); string continuation = Guid.NewGuid().ToString(); DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions { HostName = Guid.NewGuid().ToString() }; Documents.PartitionKeyRange partitionKeyRange = new Documents.PartitionKeyRange() { Id = "0", MinInclusive = "", MaxExclusive = "FF" }; Mock <DocumentServiceLeaseUpdater> mockUpdater = new Mock <DocumentServiceLeaseUpdater>(); Mock <ContainerInternal> mockedContainer = new Mock <ContainerInternal>(); mockedContainer.Setup(c => c.CreateItemStreamAsync( It.IsAny <Stream>(), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync((Stream stream, PartitionKey partitionKey, ItemRequestOptions options, CancellationToken token) => new ResponseMessage(System.Net.HttpStatusCode.OK) { Content = stream }); DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( Mock.Of <ContainerInternal>(), mockedContainer.Object, mockUpdater.Object, options, requestOptionsFactory); DocumentServiceLease afterAcquire = await documentServiceLeaseManagerCosmos.CreateLeaseIfNotExistAsync(partitionKeyRange, continuation); DocumentServiceLeaseCore pkRangeBasedLease = (DocumentServiceLeaseCore)afterAcquire; Assert.IsNotNull(pkRangeBasedLease); Assert.AreEqual(continuation, afterAcquire.ContinuationToken); Assert.AreEqual(partitionKeyRange.Id, pkRangeBasedLease.CurrentLeaseToken); ValidateRequestOptionsFactory(requestOptionsFactory, pkRangeBasedLease); }
public async Task UpdatesLease() { string itemId = "1"; Cosmos.PartitionKey partitionKey = new Cosmos.PartitionKey("1"); DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); Mock <ContainerCore> mockedItems = new Mock <ContainerCore>(); mockedItems.Setup(i => i.ReplaceItemAsync <DocumentServiceLeaseCore>( It.Is <DocumentServiceLeaseCore>((lease) => lease == leaseToUpdate), It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => { var itemResponse = new Mock <ItemResponse <DocumentServiceLeaseCore> >(); itemResponse.Setup(i => i.Resource).Returns(leaseToUpdate); return(itemResponse.Object); }); var updater = new DocumentServiceLeaseUpdaterCosmos(DocumentServiceLeaseUpdaterCosmosTests.GetMockedContainer(mockedItems)); var updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, partitionKey, serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); Assert.AreEqual("newHost", updatedLease.Owner); Mock.Get(mockedItems.Object) .Verify(items => items.ReplaceItemAsync( It.Is <DocumentServiceLeaseCore>((lease) => lease == leaseToUpdate), It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>(pk => pk == partitionKey), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once); Mock.Get(mockedItems.Object) .Verify(items => items.ReadItemAsync <DocumentServiceLeaseCore>( It.Is <string>((id) => id == itemId), It.Is <Cosmos.PartitionKey>((pk) => pk == partitionKey), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Never); }
public async Task ReleaseWhenNotExistDoesNotThrow() { DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions { HostName = Guid.NewGuid().ToString() }; DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseId = Guid.NewGuid().ToString(), LeaseToken = "0", Owner = Guid.NewGuid().ToString(), FeedRange = new FeedRangePartitionKeyRange("0") }; Mock <DocumentServiceLeaseUpdater> mockUpdater = new Mock <DocumentServiceLeaseUpdater>(); ResponseMessage leaseResponse = new ResponseMessage(System.Net.HttpStatusCode.NotFound); Mock <ContainerInternal> mockedContainer = new Mock <ContainerInternal>(); mockedContainer.Setup(c => c.ReadItemStreamAsync( It.Is <string>(id => id == lease.LeaseId), It.IsAny <PartitionKey>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>())).ReturnsAsync(leaseResponse); DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( Mock.Of <ContainerInternal>(), mockedContainer.Object, mockUpdater.Object, options, Mock.Of <RequestOptionsFactory>()); await documentServiceLeaseManagerCosmos.ReleaseAsync(lease); mockUpdater.Verify(c => c.UpdateLeaseAsync( It.IsAny <DocumentServiceLease>(), It.IsAny <string>(), It.IsAny <PartitionKey>(), It.IsAny <Func <DocumentServiceLease, DocumentServiceLease> >()), Times.Never); }
public void ValidateSerialization_NullFields() { DocumentServiceLeaseCore originalLease = new DocumentServiceLeaseCore(); byte[] buffer = new byte[4096]; BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream1 = new MemoryStream(buffer); MemoryStream stream2 = new MemoryStream(buffer); formatter.Serialize(stream1, originalLease); var lease = (DocumentServiceLeaseCore)formatter.Deserialize(stream2); Assert.IsNull(lease.Id); Assert.IsNull(lease.ETag); Assert.IsNull(lease.LeaseToken); Assert.IsNull(lease.Owner); Assert.IsNull(lease.ContinuationToken); Assert.AreEqual(new DocumentServiceLeaseCore().Timestamp, lease.Timestamp); Assert.IsTrue(lease.Properties.Count == 0); }
public void ValidateSerialization_AllFields() { DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseId = "id" }; LeaseLostException originalException = new LeaseLostException(lease, new Exception("foo"), true); byte[] buffer = new byte[4096]; BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream1 = new MemoryStream(buffer); MemoryStream stream2 = new MemoryStream(buffer); formatter.Serialize(stream1, originalException); LeaseLostException deserializedException = (LeaseLostException)formatter.Deserialize(stream2); Assert.AreEqual(originalException.Message, deserializedException.Message); Assert.AreEqual(originalException.InnerException.Message, deserializedException.InnerException.Message); Assert.AreEqual(originalException.Lease.Id, deserializedException.Lease.Id); Assert.AreEqual(originalException.IsGone, deserializedException.IsGone); }
public async Task AcquireCompletes() { DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions { HostName = Guid.NewGuid().ToString() }; DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() { LeaseToken = "0", Owner = Guid.NewGuid().ToString(), FeedRange = new FeedRangePartitionKeyRange("0") }; Mock <DocumentServiceLeaseUpdater> mockUpdater = new Mock <DocumentServiceLeaseUpdater>(); Func <Func <DocumentServiceLease, DocumentServiceLease>, bool> validateUpdater = (Func <DocumentServiceLease, DocumentServiceLease> updater) => { DocumentServiceLease afterUpdateLease = updater(lease); return(options.HostName == afterUpdateLease.Owner); }; mockUpdater.Setup(c => c.UpdateLeaseAsync( It.IsAny <DocumentServiceLease>(), It.IsAny <string>(), It.IsAny <PartitionKey>(), It.Is <Func <DocumentServiceLease, DocumentServiceLease> >(f => validateUpdater(f)))) .ReturnsAsync(lease); DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( Mock.Of <ContainerInternal>(), Mock.Of <ContainerInternal>(), mockUpdater.Object, options, Mock.Of <RequestOptionsFactory>()); DocumentServiceLease afterAcquire = await documentServiceLeaseManagerCosmos.AcquireAsync(lease); Assert.AreEqual(options.HostName, afterAcquire.Owner); }
public async Task UpdatesLease() { string itemId = "1"; string partitionKey = "1"; List <KeyValuePair <string, DocumentServiceLease> > state = new List <KeyValuePair <string, DocumentServiceLease> >() { new KeyValuePair <string, DocumentServiceLease>(itemId, new DocumentServiceLeaseCore()) }; DocumentServiceLeaseCore leaseToUpdate = new DocumentServiceLeaseCore(); ConcurrentDictionary <string, DocumentServiceLease> container = new ConcurrentDictionary <string, DocumentServiceLease>(state); DocumentServiceLeaseUpdaterInMemory updater = new DocumentServiceLeaseUpdaterInMemory(container); DocumentServiceLease updatedLease = await updater.UpdateLeaseAsync(leaseToUpdate, itemId, new Cosmos.PartitionKey(partitionKey), serverLease => { serverLease.Owner = "newHost"; return(serverLease); }); Assert.AreEqual("newHost", updatedLease.Owner); }
public void ValidateJsonSerialization_PKRangeLease() { DocumentServiceLeaseCore originalLease = new DocumentServiceLeaseCore { LeaseId = "id", ETag = "etag", LeaseToken = "0", Owner = "owner", ContinuationToken = "continuation", Timestamp = DateTime.Now - TimeSpan.FromSeconds(5), LeasePartitionKey = "partitionKey", Properties = new Dictionary <string, string> { { "key", "value" } }, FeedRange = new FeedRangePartitionKeyRange("0") }; string serialized = JsonConvert.SerializeObject(originalLease); DocumentServiceLease documentServiceLease = JsonConvert.DeserializeObject <DocumentServiceLease>(serialized); if (documentServiceLease is DocumentServiceLeaseCore documentServiceLeaseCore) { Assert.AreEqual(originalLease.LeaseId, documentServiceLeaseCore.LeaseId); Assert.AreEqual(originalLease.ETag, documentServiceLeaseCore.ETag); Assert.AreEqual(originalLease.LeaseToken, documentServiceLeaseCore.LeaseToken); Assert.AreEqual(originalLease.Owner, documentServiceLeaseCore.Owner); Assert.AreEqual(originalLease.PartitionKey, documentServiceLeaseCore.PartitionKey); Assert.AreEqual(originalLease.ContinuationToken, documentServiceLeaseCore.ContinuationToken); Assert.AreEqual(originalLease.Timestamp, documentServiceLeaseCore.Timestamp); Assert.AreEqual(originalLease.Properties["key"], documentServiceLeaseCore.Properties["key"]); Assert.AreEqual(originalLease.FeedRange.ToJsonString(), documentServiceLeaseCore.FeedRange.ToJsonString()); } else { Assert.Fail(); } }
public async Task EtagPassesContinuation() { int itemCount = 5; string pkRangeId = "0"; string etag = Guid.NewGuid().ToString(); DateTime startTime = DateTime.UtcNow; DocumentServiceLeaseCore documentServiceLeaseCore = new DocumentServiceLeaseCore() { LeaseToken = pkRangeId }; ResponseMessage responseMessage = new ResponseMessage(System.Net.HttpStatusCode.OK); responseMessage.Headers.ETag = etag; Mock <ContainerInternal> containerMock = new Mock <ContainerInternal>(); Mock <CosmosClientContext> mockContext = new Mock <CosmosClientContext>(); mockContext.Setup(x => x.OperationHelperAsync <ResponseMessage>( It.Is <string>(str => str.Contains("Change Feed Processor")), It.IsAny <RequestOptions>(), It.IsAny <Func <ITrace, Task <ResponseMessage> > >(), It.Is <TraceComponent>(tc => tc == TraceComponent.ChangeFeed), It.IsAny <TraceLevel>())) .Returns <string, RequestOptions, Func <ITrace, Task <ResponseMessage> >, TraceComponent, TraceLevel>( (operationName, requestOptions, func, comp, level) => { using (ITrace trace = Trace.GetRootTrace(operationName, comp, level)) { return(func(trace)); } }); mockContext.Setup(c => c.ProcessResourceOperationStreamAsync( It.IsAny <string>(), It.IsAny <Documents.ResourceType>(), It.IsAny <Documents.OperationType>(), It.IsAny <ChangeFeedRequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <FeedRange>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.Is <ITrace>(t => !(t is NoOpTrace)), It.IsAny <CancellationToken>() ) ).ReturnsAsync(responseMessage); containerMock.Setup(c => c.ClientContext).Returns(mockContext.Object); containerMock.Setup(c => c.LinkUri).Returns("http://localhot"); ChangeFeedPartitionKeyResultSetIteratorCore iterator = ChangeFeedPartitionKeyResultSetIteratorCore.Create( lease: documentServiceLeaseCore, continuationToken: null, maxItemCount: itemCount, container: containerMock.Object, startTime: startTime, startFromBeginning: false); ResponseMessage response = await iterator.ReadNextAsync(); Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.AreEqual(etag, response.Headers.ContinuationToken); }