using XFEEDToolBox.Core.Execution; using XFEEDToolBox.Core.Models; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public sealed class TradePauseMutationBarrierTests { private sealed class Production:ITradeCommandDriver,ITradeRunMenuRecovery { public int Preflights,Releases,Mutations;public Func? Allowed; public Task PreflightAsync(CancellationToken token){Preflights++;return Task.CompletedTask;} public Task ReleaseAllAsync(){Releases++;return Task.CompletedTask;} public Task ServiceDockedAsync(DockedServiceRequest request,Func before,CancellationToken token){Mutations++;return Task.CompletedTask;} public Task ExecuteAsync(TradeAction action,Func before,CancellationToken token){Mutations++;return Task.CompletedTask;} public IDisposable EnterRunningMenuRecovery(Func running,CancellationToken token){Allowed=running;return new Lease();} } private sealed class Lease:IDisposable{public void Dispose(){}} [Test]public async Task EveryFinancialTravelAndServiceMutationWaitsForCancellationWithoutForwarding() { var production=new Production();var barrier=new TradePauseMutationBarrier(production,production); using var stop=new CancellationTokenSource(); var operations=new[]{TradeActionKind.Buy,TradeActionKind.Sell,TradeActionKind.Travel} .Select(kind=>barrier.ExecuteAsync(new(kind,new TradeLeg(),null),_=>Task.CompletedTask,stop.Token)).ToList(); operations.Add(barrier.ServiceDockedAsync(new(1,1),_=>Task.CompletedTask,stop.Token)); Check.That(operations.All(value=>!value.IsCompleted));Check.Equal(0,production.Mutations); Check.Equal(1,barrier.BlockedBuys);Check.Equal(1,barrier.BlockedSells);Check.Equal(1,barrier.BlockedTravels);Check.Equal(1,barrier.BlockedServices); stop.Cancel();foreach(var task in operations){try{await task;throw new InvalidOperationException("Mutation barrier completed as a fake success.");}catch(OperationCanceledException){}} Check.Equal(0,production.Mutations);Check.Equal(0,TradePauseMutationBarrier.ForwardedMutations); } [Test]public async Task ProductionPreflightAndTrueRunnerPredicateAreRetained() { var production=new Production();var barrier=new TradePauseMutationBarrier(production,production);var running=false; await barrier.PreflightAsync(default);using var scope=barrier.EnterRunningMenuRecovery(()=>running,default); Check.Equal(1,production.Preflights);Check.That(!production.Allowed!());running=true;Check.That(production.Allowed!()); running=false;Check.That(!production.Allowed!());await barrier.ReleaseAllAsync();Check.Equal(1,production.Releases);Check.Equal(0,production.Mutations); } [Test]public async Task ARejectedPreInputCheckCannotReachAnyMutationOrReportFakeCompletion() { var production=new Production();var barrier=new TradePauseMutationBarrier(production,production); try{await barrier.ExecuteAsync(new(TradeActionKind.Buy,new(),null),_=>throw new InvalidOperationException("real safety refusal"),default);throw new Exception("Refusal was ignored.");} catch(InvalidOperationException error){Check.Equal("real safety refusal",error.Message);} Check.Equal(0,production.Mutations);Check.Equal(0,barrier.BlockedBuys);Check.That(!barrier.FirstMutationHeld.IsCompleted); } }