private void SetProcessingResult(PaymentStatus status) { MockProcessor.Setup(x => x.SubmitAsync(It.IsAny <ProcessOrder>())) .Returns(Task.FromResult(new PaymentResult(status) { TransactionId = "888" })); }
public async Task Catches_Too_Many_Records_Exception_And_Retries_With_Reduced_Batch_Size() { var largeRange = new BlockRange(0, 10); //expect the batch size to be reduced by half var smallerRange = new BlockRange(0, 5); //expect max of 10 blocks to be requested MockProgressService .Setup(s => s.GetNextBlockRangeToProcessAsync(MaxBlocksPerBatch)) .ReturnsAsync(largeRange); // mock a too-many-records exception MockProcessor .Setup(p => p.ProcessAsync(largeRange, It.IsAny <CancellationToken>())) .ThrowsAsync(new TooManyRecordsException()); //expect max of 5 blocks to be requested MockProgressService .Setup(s => s.GetNextBlockRangeToProcessAsync(5)) .ReturnsAsync(smallerRange); // mock a successfull process attempt MockProcessor .Setup(p => p.ProcessAsync(smallerRange, It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); // expect progress to be updated MockProgressService .Setup(s => s.SaveLastBlockProcessedAsync(smallerRange.To)) .Returns(Task.CompletedTask); var processedRange = await Service.ProcessOnceAsync(); Assert.Equal(smallerRange, processedRange.Value); Assert.Equal((ulong)5, Service.MaxNumberOfBlocksPerBatch); MockProcessor.Verify(); MockProgressService.Verify(); }
public async Task Requests_Range_Processes_And_Records_Progress() { var range = new BlockRange(0, 10); MockProgressService .Setup(s => s.GetNextBlockRangeToProcessAsync(MaxBlocksPerBatch)) .ReturnsAsync(range); MockProcessor .Setup(p => p.ProcessAsync(range, It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); MockProgressService .Setup(s => s.SaveLastBlockProcessedAsync(range.To)) .Returns(Task.CompletedTask); var processedRange = await Service.ProcessLatestBlocksAsync(); Assert.Equal(range, processedRange); MockProcessor.Verify(); MockProgressService.Verify(); }
public async Task Catches_Too_Many_Records_Exception_Will_Throw_If_Max_Blocks_Reaches_One() { var largeRange = new BlockRange(0, 10); var rangesAttempted = new List <BlockRange>(); MockProgressService .Setup(s => s.GetNextBlockRangeToProcessAsync(It.IsAny <uint>())) .Returns <uint>((newMax) => Task.FromResult(new BlockRange?(new BlockRange(0, newMax)))); // mock a too-many-records exception for every call MockProcessor .Setup(p => p.ProcessAsync(It.IsAny <BlockRange>(), It.IsAny <CancellationToken>())) .Callback <BlockRange, CancellationToken>((range, token) => rangesAttempted.Add(range)) .ThrowsAsync(new TooManyRecordsException()); await Assert.ThrowsAsync <TooManyRecordsException>(async() => await Service.ProcessOnceAsync()); Assert.Equal(10, rangesAttempted[0].To.Value); Assert.Equal(5, rangesAttempted[1].To.Value); Assert.Equal(2, rangesAttempted[2].To.Value); Assert.Equal(1, rangesAttempted[3].To.Value); Assert.Equal((uint)1, Service.MaxNumberOfBlocksPerBatch); }
public async Task Processes_Ranges_And_Waits_Until_Next_Range_Is_Available() { var mockWaitStategy = new Mock <IWaitStrategy>(); Service.WaitForBlockStrategy = mockWaitStategy.Object; var waits = new List <uint>(); var cancellationSource = new CancellationTokenSource(); var range1 = new BlockRange(0, 9); var nullRange = new BlockRange?(); var range2 = new BlockRange(10, 19); var rangeQueue = new Queue <BlockRange?>(); //initial range to process rangeQueue.Enqueue(range1); //simulate being up to date for 3 iterations rangeQueue.Enqueue(nullRange); rangeQueue.Enqueue(nullRange); rangeQueue.Enqueue(nullRange); //simulate new range becoming available rangeQueue.Enqueue(range2); //get next range from queue MockProgressService .Setup(s => s.GetNextBlockRangeToProcessAsync(MaxBlocksPerBatch)) .ReturnsAsync(() => rangeQueue.Dequeue()); //process range 1 MockProcessor .Setup(p => p.ProcessAsync(range1, It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); //when range is null expect wait strategy to be invoked mockWaitStategy .Setup(s => s.Apply(It.IsAny <uint>())) .Callback <uint>((attemptCount) => waits.Add(attemptCount)) .Returns(Task.CompletedTask); //process range 2 MockProcessor .Setup(p => p.ProcessAsync(range2, It.IsAny <CancellationToken>())) .Returns(Task.CompletedTask); //update progress range 1 MockProgressService .Setup(s => s.SaveLastBlockProcessedAsync(range1.To)) .Returns(Task.CompletedTask); //update progress range 2 MockProgressService .Setup(s => s.SaveLastBlockProcessedAsync(range2.To)) .Returns(Task.CompletedTask); //short circuit callback used to exit process var shortCircuit = new Action <uint, BlockRange>((rangesProcessed, lastRange) => { if (lastRange.Equals(range2)) { cancellationSource.Cancel(); } }); var blocksProcessed = await Service.ProcessContinuallyAsync( cancellationSource.Token, shortCircuit); Assert.Equal((ulong)20, blocksProcessed); Assert.Equal(3, waits.Count); //wait strategy is sent an attempt count so it can adjust wait time accordingly Assert.True(waits.SequenceEqual(new uint[] { 1, 2, 3 })); MockProcessor.Verify(); MockProgressService.Verify(); }