public BootstrapperCore(PartitionSynchronizer synchronizer, DocumentServiceLeaseStore leaseStore, TimeSpan lockTime, TimeSpan sleepTime) { if (synchronizer == null) { throw new ArgumentNullException(nameof(synchronizer)); } if (leaseStore == null) { throw new ArgumentNullException(nameof(leaseStore)); } if (lockTime <= TimeSpan.Zero) { throw new ArgumentException("should be positive", nameof(lockTime)); } if (sleepTime <= TimeSpan.Zero) { throw new ArgumentException("should be positive", nameof(sleepTime)); } this.synchronizer = synchronizer; this.leaseStore = leaseStore; this.lockTime = lockTime; this.sleepTime = sleepTime; }
public async Task Controller_ShouldCopyParentLeaseProperties_IfPartitionSplitHappened() { //arrange Dictionary <string, string> customProperties = new Dictionary <string, string> { { "key", "value" } }; DocumentServiceLease lease = Mock.Of <DocumentServiceLease>(l => l.CurrentLeaseToken == PartitionId && l.Properties == customProperties); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(); DocumentServiceLease leaseChild1 = this.CreateMockLease(); DocumentServiceLease leaseChild2 = this.CreateMockLease(); Mock.Get(synchronizer) .Setup(s => s.HandlePartitionGoneAsync(It.Is <DocumentServiceLease>(l => l.CurrentLeaseToken == PartitionId && l.ContinuationToken == LastContinuationToken))) .ReturnsAsync((new[] { leaseChild1, leaseChild2 }, true)); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedRangeGoneException("message", LastContinuationToken))); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(manager => manager.AcquireAsync(lease) == Task.FromResult(lease)); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer, Mock.Of <ChangeFeedProcessorHealthMonitor>()); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(leaseChild1) .VerifySet(l => l.Properties = customProperties, Times.Once); Mock.Get(leaseChild2) .VerifySet(l => l.Properties = customProperties, Times.Once); }
public PartitionControllerTests() { this.lease = Mock.Of <DocumentServiceLease>(); Mock.Get(this.lease) .Setup(l => l.CurrentLeaseToken) .Returns("partitionId"); this.partitionProcessor = MockPartitionProcessor(); this.leaseRenewer = MockRenewer(); this.observer = Mock.Of <ChangeFeedObserver>(); this.partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(this.lease) == new PartitionSupervisorCore(this.lease, this.observer, this.partitionProcessor, this.leaseRenewer)); this.leaseManager = Mock.Of <DocumentServiceLeaseManager>(); Mock.Get(this.leaseManager).Reset(); // Reset implicit/by default setup of properties. Mock.Get(this.leaseManager) .Setup(manager => manager.AcquireAsync(this.lease)) .ReturnsAsync(this.lease); Mock.Get(this.leaseManager) .Setup(manager => manager.ReleaseAsync(this.lease)) .Returns(Task.CompletedTask); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); this.synchronizer = Mock.Of <PartitionSynchronizer>(); this.sut = new PartitionControllerCore(leaseContainer, this.leaseManager, this.partitionSupervisorFactory, this.synchronizer); }
public async Task Controller_ShouldDeleteParentLease_IfChildLeasesCreatedByAnotherHost() { //arrange DocumentServiceLease lease = this.CreateMockLease(PartitionId); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(); Mock.Get(synchronizer) .Setup(s => s.HandlePartitionGoneAsync(lease)) .ReturnsAsync((new DocumentServiceLease[] { }, true)); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedRangeGoneException("message", LastContinuationToken))); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(manager => manager.AcquireAsync(lease) == Task.FromResult(lease) ); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer, Mock.Of <ChangeFeedProcessorHealthMonitor>()); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); //assert await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(leaseManager).Verify(manager => manager.DeleteAsync(lease), Times.Once); }
public async Task Controller_ShouldPassLastKnownContinuationTokenToSynchronizer_IfPartitionSplitHappened() { //arrange DocumentServiceLease lease = Mock.Of <DocumentServiceLease>(l => l.CurrentLeaseToken == PartitionId && l.ContinuationToken == InitialContinuationToken); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(); Mock.Get(synchronizer) .Setup(s => s.HandlePartitionGoneAsync(It.Is <DocumentServiceLease>(l => l.CurrentLeaseToken == PartitionId && l.ContinuationToken == LastContinuationToken))) .ReturnsAsync((new[] { this.CreateMockLease(), this.CreateMockLease() }, true)); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedRangeGoneException("message", LastContinuationToken))); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(manager => manager.AcquireAsync(lease) == Task.FromResult(lease)); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer, Mock.Of <ChangeFeedProcessorHealthMonitor>()); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); //assert await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(synchronizer).VerifyAll(); }
private async Task <IPartitionManager> BuildPartitionManagerAsync(ILeaseManager leaseManager) { this.leaseDocumentClient = this.leaseDocumentClient ?? this.leaseCollectionLocation.CreateDocumentClient(); DocumentCollection leaseCollection = await this.leaseDocumentClient.GetDocumentCollectionAsync(this.leaseCollectionLocation).ConfigureAwait(false); string leaseStoreCollectionLink = leaseCollection.SelfLink; string collectionSelfLink = this.feedCollectionLocation.GetCollectionSelfLink(); var factory = new CheckpointerObserverFactory(this.observerFactory, this.changeFeedProcessorOptions.CheckpointFrequency); var synchronizer = new PartitionSynchronizer(this.feedDocumentClient, collectionSelfLink, leaseManager, this.changeFeedProcessorOptions.DegreeOfParallelism, this.changeFeedProcessorOptions.QueryPartitionsMaxBatchSize); var leaseStore = new LeaseStore(this.leaseDocumentClient, this.leaseCollectionLocation, this.GetLeasePrefix(), leaseStoreCollectionLink); var bootstrapper = new Bootstrapper(synchronizer, leaseStore, this.lockTime, this.sleepTime); var partitionObserverFactory = new PartitionSupervisorFactory( factory, leaseManager, this.partitionProcessorFactory ?? new PartitionProcessorFactory(this.feedDocumentClient, this.changeFeedProcessorOptions, leaseManager, collectionSelfLink), this.changeFeedProcessorOptions); var partitionController = new PartitionController(leaseManager, partitionObserverFactory, synchronizer); if (this.loadBalancingStrategy == null) { this.loadBalancingStrategy = new EqualPartitionsBalancingStrategy(this.hostName, this.changeFeedProcessorOptions.MinPartitionCount, this.changeFeedProcessorOptions.MaxPartitionCount, this.changeFeedProcessorOptions.LeaseExpirationInterval); } var partitionLoadBalancer = new PartitionLoadBalancer(partitionController, leaseManager, this.loadBalancingStrategy, this.changeFeedProcessorOptions.LeaseAcquireInterval); return(new PartitionManager(bootstrapper, partitionController, partitionLoadBalancer)); }
public async Task SplitPartitionAsync_ShouldReturnOnlyNewLeases_IfSplitWasAlreadyPerformed() { const string lastKnowToken = "last know token"; IEnumerable <PartitionKeyRange> keyRanges = new[] { new PartitionKeyRange { Id = "20", Parents = new Collection <string>(new[] { "10" }) }, new PartitionKeyRange { Id = "30", Parents = new Collection <string>(new[] { "10" }) } }; var lease = Mock.Of <ILease>(l => l.PartitionId == "10" && l.ContinuationToken == lastKnowToken); var keyRangeResponse = Mock.Of <IFeedResponse <PartitionKeyRange> >(r => r.GetEnumerator() == keyRanges.GetEnumerator()); IChangeFeedDocumentClient documentClient = Mock.Of <IChangeFeedDocumentClient>(c => c.ReadPartitionKeyRangeFeedAsync(It.IsAny <string>(), It.IsAny <FeedOptions>()) == Task.FromResult(keyRangeResponse)); var lease20 = Mock.Of <ILease>(); ILeaseManager leaseManager = Mock.Of <ILeaseManager>(m => m.CreateLeaseIfNotExistAsync("20", lastKnowToken) == Task.FromResult(lease20) && m.CreateLeaseIfNotExistAsync("30", lastKnowToken) == Task.FromResult <ILease>(null)); var sut = new PartitionSynchronizer(documentClient, "collectionlink", leaseManager, 1, int.MaxValue); IEnumerable <ILease> result = await sut.SplitPartitionAsync(lease); Assert.NotNull(result); Assert.Equal(new[] { lease20 }, result); }
public async Task Controller_ShouldDeleteParentLease_IfChildLeaseAcquireThrows() { //arrange DocumentServiceLease lease = this.CreateMockLease(PartitionId); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(); DocumentServiceLease leaseChild2 = this.CreateMockLease(); Mock.Get(synchronizer) .Setup(s => s.SplitPartitionAsync(lease)) .ReturnsAsync(new[] { this.CreateMockLease(), leaseChild2 }); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedSplitException("message", LastContinuationToken))); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(manager => manager.AcquireAsync(lease) == Task.FromResult(lease) && manager.AcquireAsync(leaseChild2) == Task.FromException <DocumentServiceLease>(new LeaseLostException()) ); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); //assert await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(leaseManager).Verify(manager => manager.DeleteAsync(lease), Times.Once); }
public async Task Controller_ShouldSignalSynchronizerSplitPartition_IfPartitionSplitHappened() { //arrange DocumentServiceLease lease = CreateMockLease(PartitionId); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(); Mock.Get(synchronizer) .Setup(s => s.SplitPartitionAsync(lease)) .ReturnsAsync(new[] { CreateMockLease(), CreateMockLease() }); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedSplitException("message", LastContinuationToken))); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(manager => manager.AcquireAsync(lease) == Task.FromResult(lease)); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); //assert await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(synchronizer).VerifyAll(); }
public async Task Controller_ShouldIgnoreProcessingChildPartition_IfPartitionAlreadyAdded() { //arrange DocumentServiceLease lease = this.CreateMockLease(PartitionId); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(); DocumentServiceLease leaseChild1 = this.CreateMockLease(); DocumentServiceLease leaseChild2 = this.CreateMockLease(); Mock.Get(synchronizer) .Setup(s => s.HandlePartitionGoneAsync(It.Is <DocumentServiceLease>(l => l.CurrentLeaseToken == PartitionId && l.ContinuationToken == LastContinuationToken))) .ReturnsAsync((new[] { leaseChild1, leaseChild2 }, true)); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedRangeGoneException("message", LastContinuationToken))); PartitionSupervisor partitionSupervisor1 = Mock.Of <PartitionSupervisor>(); Mock.Get(partitionSupervisor1).Setup(o => o.RunAsync(It.IsAny <CancellationToken>())).Returns <CancellationToken>(token => Task.Delay(TimeSpan.FromHours(1), token)); PartitionSupervisor partitionSupervisor2 = Mock.Of <PartitionSupervisor>(); Mock.Get(partitionSupervisor2).Setup(o => o.RunAsync(It.IsAny <CancellationToken>())).Returns <CancellationToken>(token => Task.Delay(TimeSpan.FromHours(1), token)); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor && f.Create(leaseChild1) == partitionSupervisor1 && f.Create(leaseChild2) == partitionSupervisor2); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(manager => manager.AcquireAsync(lease) == Task.FromResult(lease)); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer, Mock.Of <ChangeFeedProcessorHealthMonitor>()); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); await sut.AddOrUpdateLeaseAsync(leaseChild2).ConfigureAwait(false); await sut.AddOrUpdateLeaseAsync(leaseChild2).ConfigureAwait(false); await sut.AddOrUpdateLeaseAsync(leaseChild2).ConfigureAwait(false); await sut.AddOrUpdateLeaseAsync(leaseChild2).ConfigureAwait(false); await sut.AddOrUpdateLeaseAsync(leaseChild2).ConfigureAwait(false); //assert await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(leaseManager) .Verify(manager => manager.AcquireAsync(leaseChild2), Times.Once); Mock.Get(leaseManager) .Verify(manager => manager.UpdatePropertiesAsync(leaseChild2), Times.Exactly(5)); Mock.Get(partitionSupervisorFactory) .Verify(f => f.Create(leaseChild2), Times.Once); }
public async Task Controller_ShouldRunProcessingOnChildPartitions_IfHappyPath() { //arrange DocumentServiceLease lease = CreateMockLease(PartitionId); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(); DocumentServiceLease leaseChild1 = CreateMockLease(); DocumentServiceLease leaseChild2 = CreateMockLease(); Mock.Get(synchronizer) .Setup(s => s.SplitPartitionAsync(It.Is <DocumentServiceLease>(l => l.CurrentLeaseToken == PartitionId && l.ContinuationToken == LastContinuationToken))) .ReturnsAsync(new[] { leaseChild1, leaseChild2 }); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedSplitException("message", LastContinuationToken))); var partitionSupervisor1 = Mock.Of <PartitionSupervisor>(); Mock.Get(partitionSupervisor1).Setup(o => o.RunAsync(It.IsAny <CancellationToken>())).Returns <CancellationToken>(token => Task.Delay(TimeSpan.FromHours(1), token)); var partitionSupervisor2 = Mock.Of <PartitionSupervisor>(); Mock.Get(partitionSupervisor2).Setup(o => o.RunAsync(It.IsAny <CancellationToken>())).Returns <CancellationToken>(token => Task.Delay(TimeSpan.FromHours(1), token)); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor && f.Create(leaseChild1) == partitionSupervisor1 && f.Create(leaseChild2) == partitionSupervisor2); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(manager => manager.AcquireAsync(lease) == Task.FromResult(lease)); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); //assert await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(leaseManager).Verify(manager => manager.AcquireAsync(leaseChild1), Times.Once); Mock.Get(leaseManager).Verify(manager => manager.AcquireAsync(leaseChild2), Times.Once); Mock.Get(partitionSupervisorFactory).Verify(f => f.Create(leaseChild1), Times.Once); Mock.Get(partitionSupervisorFactory).Verify(f => f.Create(leaseChild2), Times.Once); Mock.Get(partitionSupervisor1).Verify(p => p.RunAsync(It.IsAny <CancellationToken>()), Times.Once); Mock.Get(partitionSupervisor2).Verify(p => p.RunAsync(It.IsAny <CancellationToken>()), Times.Once); }
private IPartitionManager BuildPartitionManager(ILeaseStoreManager leaseStoreManager) { string feedCollectionSelfLink = this.feedCollectionLocation.GetCollectionSelfLink(); var factory = new CheckpointerObserverFactory(this.observerFactory, this.changeFeedProcessorOptions.CheckpointFrequency); var synchronizer = new PartitionSynchronizer( this.feedDocumentClient, feedCollectionSelfLink, leaseStoreManager, leaseStoreManager, this.changeFeedProcessorOptions.DegreeOfParallelism, this.changeFeedProcessorOptions.QueryPartitionsMaxBatchSize); var bootstrapper = new Bootstrapper(synchronizer, leaseStoreManager, this.lockTime, this.sleepTime); var partitionSuperviserFactory = new PartitionSupervisorFactory( factory, leaseStoreManager, this.partitionProcessorFactory ?? new PartitionProcessorFactory(this.feedDocumentClient, this.changeFeedProcessorOptions, leaseStoreManager, feedCollectionSelfLink), this.changeFeedProcessorOptions); if (this.loadBalancingStrategy == null) { this.loadBalancingStrategy = new EqualPartitionsBalancingStrategy( this.HostName, this.changeFeedProcessorOptions.MinPartitionCount, this.changeFeedProcessorOptions.MaxPartitionCount, this.changeFeedProcessorOptions.LeaseExpirationInterval); } IPartitionController partitionController = new PartitionController(leaseStoreManager, leaseStoreManager, partitionSuperviserFactory, synchronizer); if (this.healthMonitor == null) { this.healthMonitor = new TraceHealthMonitor(); } partitionController = new HealthMonitoringPartitionControllerDecorator(partitionController, this.healthMonitor); var partitionLoadBalancer = new PartitionLoadBalancer( partitionController, leaseStoreManager, this.loadBalancingStrategy, this.changeFeedProcessorOptions.LeaseAcquireInterval); return(new PartitionManager(bootstrapper, partitionController, partitionLoadBalancer)); }
public async Task Controller_ShouldKeepParentLease_IfSplitThrows() { //arrange DocumentServiceLease lease = this.CreateMockLease(PartitionId); PartitionSynchronizer synchronizer = Mock.Of <PartitionSynchronizer>(s => s.HandlePartitionGoneAsync(lease) == Task.FromException <(IEnumerable <DocumentServiceLease>, bool)>(new InvalidOperationException())); PartitionSupervisor partitionSupervisor = Mock.Of <PartitionSupervisor>(o => o.RunAsync(It.IsAny <CancellationToken>()) == Task.FromException(new FeedRangeGoneException("message", LastContinuationToken))); PartitionSupervisorFactory partitionSupervisorFactory = Mock.Of <PartitionSupervisorFactory>(f => f.Create(lease) == partitionSupervisor); DocumentServiceLeaseManager leaseManager = Mock.Of <DocumentServiceLeaseManager>(); DocumentServiceLeaseContainer leaseContainer = Mock.Of <DocumentServiceLeaseContainer>(); PartitionControllerCore sut = new PartitionControllerCore(leaseContainer, leaseManager, partitionSupervisorFactory, synchronizer, Mock.Of <ChangeFeedProcessorHealthMonitor>()); await sut.InitializeAsync().ConfigureAwait(false); //act await sut.AddOrUpdateLeaseAsync(lease).ConfigureAwait(false); //assert await sut.ShutdownAsync().ConfigureAwait(false); Mock.Get(leaseManager).Verify(manager => manager.DeleteAsync(lease), Times.Never); }
public async Task SplitPartitionAsync_ShouldThrow_IfPKRangesReturn0() { const string lastKnowToken = "last know token"; const string collectionLink = "collectionLink"; IEnumerable <PartitionKeyRange> keyRanges = Enumerable.Empty <PartitionKeyRange>(); var lease = Mock.Of <ILease>(l => l.PartitionId == "10" && l.ContinuationToken == lastKnowToken); var keyRangeResponse = Mock.Of <IFeedResponse <PartitionKeyRange> >(r => r.GetEnumerator() == keyRanges.GetEnumerator()); IChangeFeedDocumentClient documentClient = Mock.Of <IChangeFeedDocumentClient>(c => c.ReadPartitionKeyRangeFeedAsync(It.IsAny <string>(), It.IsAny <FeedOptions>()) == Task.FromResult(keyRangeResponse)); var lease20 = Mock.Of <ILease>(); ILeaseManager leaseManager = Mock.Of <ILeaseManager>(m => m.CreateLeaseIfNotExistAsync("20", lastKnowToken) == Task.FromResult(lease20)); var leaseContainer = Mock.Of <ILeaseContainer>(); var sut = new PartitionSynchronizer(documentClient, collectionLink, leaseContainer, leaseManager, 1, int.MaxValue); Exception exception = await Record.ExceptionAsync(async() => await sut.SplitPartitionAsync(lease)); Assert.IsAssignableFrom <InvalidOperationException>(exception); }