public void ThrowExceptionAsHandlerWorks() { using var mocker = AutoMockHelper.Create( builderAction: builder => { builder.RegisterInstance(new StateRecoveryOptions { StateRecoveryStrategy = StateRecoveryStrategy.FromStateHolder }); builder.RegisterType <StateAccessor>() .AsImplementedInterfaces() .SingleInstance(); }); var state = new TestState(); mocker.Create <StateAccessor>().State = state; mocker.Mock <IEventSaver>() .Setup(x => x.SaveEventAsync(It.IsAny <IEvent>())) .Returns(Task.CompletedTask); mocker.Mock <IStateHolder>() .Setup(x => x.DeepCopy(It.IsAny <IState>())) .Returns(state); mocker.Mock <IEventHandlerFactory>() .SetupSequence(x => x.Create(It.IsAny <IEventContext>())) .Returns(new ExceptionHandler()); var flow = mocker.Create <MasterEventHandlerFLow>(); flow.Activate(); Assert.ThrowsAsync <Exception>(() => flow.OnNewEventReceived(new TestEvent())); state.Version.Should().Be(0); }
public void DeactivateAndSavingState() { using var mocker = AutoMockHelper.Create( builderAction: builder => { builder.RegisterInstance(new StateSavingOptions { SaveWhenDeactivateAsync = true }); }); mocker.Mock <IEventHandledNotificationFlow>() .Setup(x => x.Deactivate()); mocker.Mock <IStateSavingFlow>() .Setup(x => x.Deactivate()); mocker.Mock <IEventHandlerFLow>() .Setup(x => x.Deactivate()); var testState = new TestState(); mocker.Mock <IStateAccessor>() .SetupGet(x => x.State) .Returns(testState); mocker.Mock <IStateSavingFlow>() .Setup(x => x.SaveStateAsync(testState)) .Returns(Task.CompletedTask); IClaptrap claptrap = mocker.Create <ClaptrapActor>(); claptrap.DeactivateAsync(); }
public void Deactivate_WithoutActivated() { using var mocker = AutoMockHelper.Create(); var flow = mocker.Create <EventHandledNotificationFlow>(); flow.Deactivate(); }
public void RemoveFactory() { const string typeCode = "testCode"; using var mocker = AutoMockHelper.Create(); var store = mocker.Create <ClaptrapDesignStore>(); var actorIdentity = new TestClaptrapIdentity("123", typeCode); var design = new ClaptrapDesign { ClaptrapTypeCode = typeCode }; store.AddOrReplace(design); store.AddOrReplaceFactory(typeCode, (identity, sourceDesign) => new ClaptrapDesign { StateDataType = typeof(int) }); var claptrapDesign = store.FindDesign(actorIdentity); claptrapDesign.StateDataType.Should().Be(typeof(int)); store.RemoveFactory(typeCode); claptrapDesign = store.FindDesign(actorIdentity); claptrapDesign.Should().Be(design); }
public void WindowVersionLimit2() { using var mocker = AutoMockHelper.Create(builderAction: builder => { builder.RegisterInstance(new StateSavingOptions { SavingWindowVersionLimit = 2 }); }); var laterState = new TestState { Version = 1000 }; // setup only once, it means that this function can not be invoke twice mocker.Mock <IStateSaver>() .SetupSequence(x => x.SaveAsync(laterState)) .Returns(Task.CompletedTask); var stateSavingFlow = mocker.Create <StateSavingFlow>(); stateSavingFlow.Activate(); // add two, by only save the later one stateSavingFlow.OnNewStateCreated(new TestState()); stateSavingFlow.OnNewStateCreated(laterState); }
public void ExceptionAdnContinue() { using var mocker = AutoMockHelper.Create(builderAction: builder => { builder.RegisterInstance(new StateSavingOptions { SavingWindowVersionLimit = 1 }); }); var laterState = new TestState { Version = 1000 }; mocker.Mock <IStateSaver>() .SetupSequence(x => x.SaveAsync(It.IsAny <IState>())) .Returns(Task.FromException(new Exception("something error while save state"))) .Returns(Task.CompletedTask); var stateSavingFlow = mocker.Create <StateSavingFlow>(); stateSavingFlow.Activate(); // first will not save as there is a exception thrown stateSavingFlow.OnNewStateCreated(new TestState()); // later one will be save as it is ok stateSavingFlow.OnNewStateCreated(laterState); }
public async Task HandleVersionOlderEvent() { IState state = new TestState { Version = 1000 }; using var mocker = AutoMockHelper.Create( builderAction: builder => { builder.RegisterType <StateAccessor>() .AsImplementedInterfaces() .SingleInstance(); builder.RegisterBuildCallback(scope => scope.Resolve <IStateAccessor>().State = state); }); var flow = mocker.Create <MinionEventHandlerFLow>(); flow.Activate(); await flow.OnNewEventReceived(new TestEvent { Version = 1 }); state.Version.Should().Be(1000, "do nothing as event version 1 lte state next version 1000 , skip the event"); await flow.OnNewEventReceived(new TestEvent { Version = 1000 }); state.Version.Should().Be(1000, "do nothing as event version 1000 lte state next version 1000 , skip the event"); }
public void CreateMinion() { var actorIdentity = TestClaptrapIdentity.Instance; var claptrapDesignStore = new ClaptrapDesignStore(); var masterDesign = new ClaptrapDesign { ClaptrapOptions = new ClaptrapOptions { MinionActivationOptions = new MinionActivationOptions(), EventLoadingOptions = new EventLoadingOptions(), StateRecoveryOptions = new StateRecoveryOptions(), StateSavingOptions = new StateSavingOptions() }, ClaptrapTypeCode = actorIdentity.TypeCode, EventHandlerDesigns = ImmutableDictionary <string, IClaptrapEventHandlerDesign> .Empty, StateHolderFactoryType = typeof(NoChangeStateHolderFactory), StateDataType = typeof(TestStateData), EventHandlerFactoryFactoryType = typeof(EventHandlerFactoryFactory), InitialStateDataFactoryType = typeof(DefaultInitialStateDataFactory) }; claptrapDesignStore.AddOrReplace(masterDesign); var minionDesign = new ClaptrapDesign { ClaptrapOptions = new ClaptrapOptions { MinionActivationOptions = new MinionActivationOptions(), EventLoadingOptions = new EventLoadingOptions(), StateRecoveryOptions = new StateRecoveryOptions(), StateSavingOptions = new StateSavingOptions() }, ClaptrapTypeCode = actorIdentity.TypeCode, EventHandlerDesigns = ImmutableDictionary <string, IClaptrapEventHandlerDesign> .Empty, StateHolderFactoryType = typeof(NoChangeStateHolderFactory), StateDataType = typeof(TestStateData), EventHandlerFactoryFactoryType = typeof(EventHandlerFactoryFactory), InitialStateDataFactoryType = typeof(DefaultInitialStateDataFactory), ClaptrapMasterDesign = masterDesign }; claptrapDesignStore.AddOrReplace(minionDesign); using var mocker = AutoMockHelper.Create(builderAction: builder => { builder.RegisterInstance(claptrapDesignStore) .AsImplementedInterfaces() .SingleInstance(); }); mocker.Mock <IClaptrapModuleProvider>() .Setup(x => x.GetClaptrapSharedModules(actorIdentity)) .Returns(Enumerable.Empty <IClaptrapSharedModule>()); mocker.Mock <IClaptrapModuleProvider>() .Setup(x => x.GetClaptrapMinionModules(actorIdentity)) .Returns(Enumerable.Empty <IClaptrapMinionModule>()); var actorFactory = mocker.Create <ClaptrapFactory>(); var actor = actorFactory.Create(actorIdentity); actor.Should().NotBeNull(); }
public void Create() { using var mocker = AutoMockHelper.Create(); var actorIdentity = new TestClaptrapIdentity(Guid.NewGuid().ToString(), "typeCode"); var testEvent = new TestEvent { EventTypeCode = "eventType" }; var eventContext = new EventContext(testEvent, new TestState { Identity = actorIdentity }); mocker.Mock <IClaptrapDesignStore>() .Setup(x => x.FindDesign(actorIdentity)) .Returns(new ClaptrapDesign { EventHandlerDesigns = new Dictionary <string, IClaptrapEventHandlerDesign> { { testEvent.EventTypeCode, new ClaptrapEventHandlerDesign { EventHandlerType = typeof(TestHandler) } } } }); var eventHandlerFactory = mocker.Create <DesignBaseEventHandlerFactory>(); var eventHandler = eventHandlerFactory.Create(eventContext); eventHandler.Should().NotBeNull(); }
public async Task RestoreStateWithSomeEvents() { using var mocker = AutoMockHelper.Create(); var state = new TestState(); mocker.Mock <IStateLoader>() .Setup(x => x.GetStateSnapshotAsync()) .ReturnsAsync(state); mocker.Mock <IEventLoader>() .SetupSequence(x => x.GetEventsAsync(It.IsAny <long>(), It.IsAny <long>())) .ReturnsAsync(AllEvents()) .ReturnsAsync(Enumerable.Empty <IEvent>()); mocker.Mock <IEventHandlerFactory>() .Setup(x => x.Create(It.IsAny <IEventContext>())) .Returns(new TestHandler()); mocker.Mock <IStateAccessor>() .SetupProperty(x => x.State); var restorer = mocker.Create <StateRestorer>(); await restorer.RestoreAsync(); state.Version.Should().Be(3);
public async Task HandleVersionMoreThanNextVersionEvent() { IState state = new TestState { Version = 1000 }; using var mocker = AutoMockHelper.Create( builderAction: builder => { builder.RegisterType <StateAccessor>() .AsImplementedInterfaces() .SingleInstance(); builder.RegisterBuildCallback(scope => scope.Resolve <IStateAccessor>().State = state); builder.RegisterInstance(new EventLoadingOptions { LoadingCountInOneBatch = 1000 }); }); mocker.Mock <IStateHolder>() .Setup(x => x.DeepCopy(It.IsAny <IState>())) .Returns(state); mocker.Mock <IEventHandlerFactory>() .Setup(x => x.Create(It.IsAny <IEventContext>())) .Returns(new TestHandler()); mocker.Mock <IStateSavingFlow>() .Setup(x => x.OnNewStateCreated(It.IsAny <IState>())); mocker.Mock <IEventLoader>() .Setup(x => x.GetEventsAsync(It.IsAny <long>(), It.IsAny <long>())) .Returns <long, long>((left, right) => Task.FromResult(Enumerable .Range((int)left, (int)right - (int)left) .Select(i => new TestEvent { Version = i, }).Cast <IEvent>())) .Callback <long, long>((left, right) => Console.WriteLine($"left {left} right {right}")); var flow = mocker.Create <MinionEventHandlerFLow>(); flow.Activate(); await flow.OnNewEventReceived(new TestEvent { Version = 1002 }); state.Version.Should().Be(1002, "do nothing as event version 1002 gt state next version 1000 , read event from event store"); await flow.OnNewEventReceived(new TestEvent { Version = 2000 }); state.Version.Should().Be(2000, "do nothing as event version 2000 gt state next version 1000 , read event from event store"); }
public void NotFound() { using var mocker = AutoMockHelper.Create(); var claptrapDesignStore = mocker.Create<ClaptrapDesignStore>(); var actorIdentity = new TestClaptrapIdentity("123", "testCode"); Assert.Throws<ClaptrapDesignNotFoundException>(() => claptrapDesignStore.FindDesign(actorIdentity)); }
public void AllNull() { using var mocker = AutoMockHelper.Create(); var validator = mocker.Create <ClaptrapDesignStoreValidator>(); var(isOk, errorMessage) = validator.Validate(new[] { new ClaptrapDesign() }); isOk.Should().Be(false); errorMessage.Should().NotBeNullOrEmpty(); Console.WriteLine(errorMessage); }
public async Task ConcurrentMixOrder() { const int targetVersion = 10000; IState state = new TestState { Version = 500 }; using var mocker = AutoMockHelper.Create( builderAction: builder => { builder.RegisterType <StateAccessor>() .AsImplementedInterfaces() .SingleInstance(); builder.RegisterBuildCallback(scope => scope.Resolve <IStateAccessor>().State = state); builder.RegisterInstance(new EventLoadingOptions { LoadingCountInOneBatch = 1000 }); }); var sourceEvents = Enumerable.Range(0, targetVersion + 1).Select(x => new TestEvent { Version = x }).ToArray(); var sendingEvents = sourceEvents.ToList(); Shuffle(sendingEvents); mocker.Mock <IEventLoader>() .Setup(x => x.GetEventsAsync(It.IsAny <long>(), It.IsAny <long>())) .Returns <long, long>((left, right) => Task.FromResult(sourceEvents .Skip((int)left) .Take((int)(right - left)) .Cast <IEvent>())) .Callback <long, long>((left, right) => Console.WriteLine($"left {left} right {right}")); mocker.Mock <IStateHolder>() .Setup(x => x.DeepCopy(It.IsAny <IState>())) .Returns(state); mocker.Mock <IEventHandlerFactory>() .Setup(x => x.Create(It.IsAny <IEventContext>())) .Returns(new TestHandler()); mocker.Mock <IStateSavingFlow>() .Setup(x => x.OnNewStateCreated(It.IsAny <IState>())); var flow = mocker.Create <MinionEventHandlerFLow>(); flow.Activate(); await Task.WhenAll(sendingEvents.Select(flow.OnNewEventReceived)); state.Version.Should().Be(targetVersion); }
public async Task Success() { using var mocker = AutoMockHelper.Create(builderAction: builder => { }); var context = new EventNotifierContext(); mocker.Mock <IEventNotifierHandler>() .Setup(x => x.Notify(context)) .Returns(Task.CompletedTask); var notifier = mocker.Create <CompoundEventNotifier>(); await notifier.Notify(context); }
public async Task HandleEventConcurrently(int count) { using var mocker = AutoMockHelper.Create( builderAction: builder => { builder.RegisterInstance(new StateRecoveryOptions()); builder.RegisterType <StateAccessor>() .AsImplementedInterfaces() .SingleInstance(); }); var state = new TestState { Data = new TestStateData { Counter = 0 } }; mocker.Create <StateAccessor>().State = state; var savedEvents = new ConcurrentBag <IEvent>(); mocker.Mock <IEventSaver>() .Setup(x => x.SaveEventAsync(It.IsAny <IEvent>())) .Returns(Task.CompletedTask) .Callback <IEvent>(e => savedEvents.Add(e)); mocker.Mock <IStateHolder>() .Setup(x => x.DeepCopy(It.IsAny <IState>())) .Returns(state); mocker.Mock <IEventHandlerFactory>() .Setup(x => x.Create(It.IsAny <IEventContext>())) .Returns(new TestHandler()); mocker.Mock <IEventHandledNotificationFlow>() .Setup(x => x.OnNewEventHandled(It.IsAny <IEventNotifierContext>())); mocker.Mock <IStateSavingFlow>() .Setup(x => x.OnNewStateCreated(It.IsAny <IState>())); var flow = mocker.Create <MasterEventHandlerFLow>(); flow.Activate(); await Task.WhenAll(Enumerable.Range(0, count).Select(x => flow.OnNewEventReceived(new TestEvent()))); state.Version.Should().Be(count); ((TestStateData)state.Data).Counter.Should().Be(count); savedEvents.Count.Should().Be(count); savedEvents .Select(x => x.Version) .OrderBy(x => x) .Should() .BeEquivalentTo(Enumerable.Range(Defaults.EventStartingVersion, count)); }
public async Task DeactivateAsync() { using var mocker = AutoMockHelper.Create(); mocker.Mock <IEventHandledNotificationFlow>() .Setup(x => x.Deactivate()); mocker.Mock <IStateSavingFlow>() .Setup(x => x.Deactivate()); mocker.Mock <IEventHandlerFLow>() .Setup(x => x.Deactivate()); IClaptrap claptrap = mocker.Create <ClaptrapActor>(); await claptrap.DeactivateAsync(); }
public void ExceptionAndContinue() { using var mocker = AutoMockHelper.Create(builderAction: builder => { }); var context = new EventNotifierContext(); mocker.Mock <IEventNotifierHandler>() .Setup(x => x.Notify(context)) .Throws(new ArgumentNullException()); var notifier = mocker.Create <CompoundEventNotifier>(); Assert.ThrowsAsync <ArgumentNullException>(() => notifier.Notify(context)); }
public void NothingAdded() { var serviceCollection = new ServiceCollection().AddLogging(logging => logging.AddConsole()); var buildServiceProvider = serviceCollection.BuildServiceProvider(); var loggerFactory = buildServiceProvider.GetRequiredService <ILoggerFactory>(); using var mocker = AutoMockHelper.Create(); var containerBuilder = new ContainerBuilder(); var builder = new AutofacClaptrapBootstrapperBuilder(loggerFactory, containerBuilder); var claptrapBootstrapper = builder.Build(); claptrapBootstrapper.Should().NotBeNull(); }
public void NotSave() { using var mocker = AutoMockHelper.Create(builderAction: builder => { // there is no saving windows set, it will save nothing builder.RegisterInstance(new StateSavingOptions()); }); var stateSavingFlow = mocker.Create <StateSavingFlow>(); stateSavingFlow.Activate(); stateSavingFlow.OnNewStateCreated(new TestState()); }
public void Remove() { using var mocker = AutoMockHelper.Create(); var claptrapDesignStore = mocker.Create<ClaptrapDesignStore>(); const string typeCode = "testCode"; var design = new ClaptrapDesign { ClaptrapTypeCode = typeCode }; claptrapDesignStore.AddOrReplace(design); claptrapDesignStore.Remove(x => x.ClaptrapTypeCode == typeCode); claptrapDesignStore.ToArray().Should().BeEmpty(); }
public void DesignFound() { using var mocker = AutoMockHelper.Create(); var claptrapDesignStore = mocker.Create<ClaptrapDesignStore>(); const string typeCode = "testCode"; var design = new ClaptrapDesign { ClaptrapTypeCode = typeCode }; claptrapDesignStore.AddOrReplace(design); var claptrapDesign = claptrapDesignStore.FindDesign(new TestClaptrapIdentity("456", typeCode)); claptrapDesign.Should().Be(design); }
public void Add(string typeCode) { using var mocker = AutoMockHelper.Create(); var claptrapDesignStore = mocker.Create<ClaptrapDesignStore>(); var actorIdentity = new TestClaptrapIdentity("123", typeCode); var design = new ClaptrapDesign { ClaptrapTypeCode = typeCode }; claptrapDesignStore.AddOrReplace(design); var claptrapDesign = claptrapDesignStore.FindDesign(actorIdentity); claptrapDesign.Should().Be(design); }
public async Task HandleEventAsyncWithInterceptorException() { using var mocker = AutoMockHelper.Create(); var testEvent = new TestEvent(); mocker.Mock <IClaptrapLifetimeInterceptor>() .Setup(x => x.HandlingEventAsync(testEvent)) .Returns(Task.FromException <Exception>(new Exception())); mocker.Mock <IClaptrap>() .Setup(x => x.HandleEventAsync(testEvent)) .Returns(Task.CompletedTask); var claptrap = mocker.Create <AopClaptrap>(); await claptrap.HandleEventAsync(testEvent); }
public async Task ActivateAsync() { using var mocker = AutoMockHelper.Create(); mocker.Mock <IEventHandledNotificationFlow>() .Setup(x => x.Activate()); mocker.Mock <IStateSavingFlow>() .Setup(x => x.Activate()); mocker.Mock <IEventHandlerFLow>() .Setup(x => x.Activate()); mocker.Mock <IStateRestorer>() .Setup(x => x.RestoreAsync()) .Returns(Task.CompletedTask); IClaptrap claptrap = mocker.Create <ClaptrapActor>(); await claptrap.ActivateAsync(); }
public async Task DeactivateAsync() { using var mocker = AutoMockHelper.Create(); mocker.Mock <IClaptrapLifetimeInterceptor>() .Setup(x => x.DeactivatingAsync()) .Returns(Task.CompletedTask); mocker.Mock <IClaptrapLifetimeInterceptor>() .Setup(x => x.DeactivatedAsync()) .Returns(Task.CompletedTask); mocker.Mock <IClaptrap>() .Setup(x => x.DeactivateAsync()) .Returns(Task.CompletedTask); var claptrap = mocker.Create <AopClaptrap>(); await claptrap.DeactivateAsync(); }
public void DesignNotFound() { var actorIdentity = TestClaptrapIdentity.Instance; var claptrapDesignStore = new ClaptrapDesignStore(); using var mocker = AutoMockHelper.Create(builderAction: builder => { builder.RegisterInstance(claptrapDesignStore) .AsImplementedInterfaces() .SingleInstance(); }); var actorFactory = mocker.Create <ClaptrapFactory>(); Assert.Throws <ClaptrapDesignNotFoundException>(() => actorFactory.Create(actorIdentity)); }
public void OnNewEventHandled() { using var mocker = AutoMockHelper.Create(); mocker.Mock <IEventNotifier>() .Setup(x => x.Notify(It.IsAny <IEventNotifierContext>())) .Returns(Task.CompletedTask); var flow = mocker.Create <EventHandledNotificationFlow>(); flow.Activate(); flow.OnNewEventHandled(new EventNotifierContext { Event = new TestEvent(), CurrentState = new TestState(), OldState = new TestState() }); }
public void OnNewEventHandled_NotifierException() { using var mocker = AutoMockHelper.Create(); mocker.Mock <IEventNotifier>() .Setup(x => x.Notify(It.IsAny <IEventNotifierContext>())) .Returns(Task.FromException(new Exception("failed to send notification"))); var flow = mocker.Create <EventHandledNotificationFlow>(); flow.Activate(); flow.OnNewEventHandled(new EventNotifierContext { Event = new TestEvent(), CurrentState = new TestState(), OldState = new TestState() }); }
public void WindowVersionLimitTime1Seconds() { using var mocker = AutoMockHelper.Create(builderAction: builder => { builder.RegisterInstance(new StateSavingOptions { SavingWindowTime = TimeSpan.FromSeconds(1) }); }); var stateSavingFlow = mocker.Create <StateSavingFlow>(); stateSavingFlow.Activate(); stateSavingFlow.OnNewStateCreated(new TestState()); // there will be nothing saved since it deactivate with 1 sec }