Пример #1
0
        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"]);
        }
Пример #2
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #15
0
        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);
            });
        }
Пример #16
0
        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);
        }
Пример #23
0
        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);
        }
Пример #24
0
        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();
            }
        }
Пример #26
0
        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);
        }