public async Task Should_create_separate_scope_for_each_customer() { await InputQueueSendEndpoint.Send(new UpdateOrder { CustomerId = "A", OrderId = "123", OrderStatus = "Pending" }); await InputQueueSendEndpoint.Send(new UpdateOrder { CustomerId = "B", OrderId = "456", OrderStatus = "Pending" }); await InputQueueSendEndpoint.Send(new UpdateOrder { CustomerId = "A", OrderId = "456", OrderStatus = "Processed" }); await InputQueueSendEndpoint.Send(new UpdateOrder { CustomerId = "C", OrderId = "789", OrderStatus = "Pending" }); await InputQueueSendEndpoint.Send(new UpdateOrder { CustomerId = "A", OrderId = "123", OrderStatus = "Processed" }); await _updated; var orderInventory = _container.Resolve <ILifetimeScopeRegistry <string> >().GetLifetimeScope("A").Resolve <IOrderInventory>(); Assert.AreEqual(2, orderInventory.Count); orderInventory = _container.Resolve <ILifetimeScopeRegistry <string> >().GetLifetimeScope("B").Resolve <IOrderInventory>(); Assert.AreEqual(1, orderInventory.Count); }
public async Task Should_be_able_to_observe_its_own_event_fault() { Task <ConsumeContext <Fault <Start> > > faulted = ConnectPublishHandler <Fault <Start> >(); var message = new Initialize(); await InputQueueSendEndpoint.Send(message); Guid?saga = await _repository.ShouldContainSaga(x => x.CorrelationId == message.CorrelationId && GetCurrentState(x) == _machine.WaitingToStart, TimeSpan.FromSeconds(8)); Assert.IsTrue(saga.HasValue); await InputQueueSendEndpoint.Send(new Start(message.CorrelationId)); await faulted; saga = await _repository.ShouldContainSaga(x => x.CorrelationId == message.CorrelationId && GetCurrentState(x) == _machine.WaitingToStart && x.StartAttempts == 1, TimeSpan.FromSeconds(8)); Assert.IsTrue(saga.HasValue); }
public async Task A_correlated_message_should_update_inner_saga_dependency() { Guid sagaId = NewId.NextGuid(); var message = new InitiateSimpleSaga(sagaId); await InputQueueSendEndpoint.Send(message); Guid?foundId = await _sagaRepository.Value.ShouldContainSaga(message.CorrelationId, TestTimeout); foundId.HasValue.ShouldBe(true); var propertyValue = "expected saga property value"; var updateInnerProperty = new UpdateSagaDependency(sagaId, propertyValue); await InputQueueSendEndpoint.Send(updateInnerProperty); foundId = await _sagaRepository.Value.ShouldContainSaga( x => x.CorrelationId == sagaId && x.Completed && x.Dependency.SagaInnerDependency.Name == propertyValue, TestTimeout); foundId.HasValue.ShouldBe(true); }
public async Task A_correlated_message_should_find_the_correct_saga() { Guid sagaId = NewId.NextGuid(); var message = new InitiateSimpleSaga(sagaId); await InputQueueSendEndpoint.Send(message); Guid?foundId = await _sagaRepository.ShouldContainSaga(message.CorrelationId, TestTimeout); foundId.HasValue.ShouldBe(true); var nextMessage = new CompleteSimpleSaga { CorrelationId = sagaId }; await InputQueueSendEndpoint.Send(nextMessage); foundId = await _sagaRepository.ShouldContainSaga(x => x.CorrelationId == sagaId && x.Completed, TestTimeout); foundId.HasValue.ShouldBe(true); }
public async Task Should_observe_the_fault_message() { var message = new Initialize(); Task <ConsumeContext <Fault <Start> > > faultReceived = ConnectPublishHandler <Fault <Start> >(x => message.CorrelationId == x.Message.Message.CorrelationId); await InputQueueSendEndpoint.Send(message); Guid?saga = await _repository.ShouldContainSagaInState(message.CorrelationId, _machine, _machine.WaitingToStart, TestTimeout); await InputQueueSendEndpoint.Send(new Start(message.CorrelationId)); ConsumeContext <Fault <Start> > fault = await faultReceived; Assert.AreEqual(message.CorrelationId, fault.Message.Message.CorrelationId); saga = await _repository.ShouldContainSagaInState(message.CorrelationId, _machine, _machine.FailedToStart, TestTimeout); Assert.IsTrue(saga.HasValue); }
public async Task Should_receive_the_published_message() { var message = new Start(); await InputQueueSendEndpoint.Send(message); ConsumeContext <StartupComplete> received = await _handled; Assert.AreEqual(message.CorrelationId, received.Message.TransactionId); Assert.IsTrue(received.InitiatorId.HasValue, "The initiator should be copied from the CorrelationId"); Assert.AreEqual(message.CorrelationId, received.InitiatorId.Value, "The initiator should be the saga CorrelationId"); Assert.AreEqual(InputQueueAddress, received.SourceAddress, "The published message should have the input queue source address"); Guid?saga = await _repository.ShouldContainSaga(x => x.CorrelationId == message.CorrelationId && Equals(x.CurrentState, _machine.Running), TestTimeout); Assert.IsTrue(saga.HasValue); }
public async Task Should_have_the_state_machine() { var correlationId = Guid.NewGuid(); await InputQueueSendEndpoint.Send(new GirlfriendYelling { CorrelationId = correlationId }); Guid?sagaId = await _repository.Value.ShouldContainSaga(correlationId, TestTimeout); Assert.IsTrue(sagaId.HasValue); await InputQueueSendEndpoint.Send(new GotHitByACar { CorrelationId = correlationId }); sagaId = await _repository.Value.ShouldContainSaga(x => x.CorrelationId == correlationId && x.CurrentState == _machine.Dead.Name, TestTimeout); Assert.IsTrue(sagaId.HasValue); var instance = await GetSaga(correlationId); Assert.IsTrue(instance.Screwed); }
public async Task Should_cancel_the_message() { var faulted = ConnectPublishHandler <Fault <PingMessage> >(); await InputQueueSendEndpoint.Send(new PingMessage()); await _pingReceived.Task; LogContext.Debug?.Log("Ping was received"); await _scheduledMessage.Task; LogContext.Debug?.Log("Pong was scheduled"); await faulted; await Task.Delay(1000); AdvanceTime(TimeSpan.FromSeconds(20)); Assert.That(async() => await _pongReceived.Task.OrTimeout(s: 5), Throws.TypeOf <TimeoutException>()); }
public async Task Should_deliver_both_messages() { var accountId = NewId.NextGuid(); Task <ConsumeContext <AccountOpened> > opened = ConnectPublishHandler <AccountOpened>(x => x.Message.AccountId == accountId); Task <ConsumeContext <AccountDefaulted> > defaulted = ConnectPublishHandler <AccountDefaulted>(x => x.Message.AccountId == accountId); Task <ConsumeContext <AccountClosed> > closed = ConnectPublishHandler <AccountClosed>(x => x.Message.AccountId == accountId); await InputQueueSendEndpoint.Send <OpenAccount>(new { AccountId = accountId }); await opened; await Task.Delay(1000); AdvanceTime(TimeSpan.FromDays(30)); await defaulted; AdvanceTime(TimeSpan.FromDays(60)); await closed; }
public async Task Receiving_A_GroupsUnassignedFromUserUnsuccessfully_During_UnassigningGroupFromUser_State_The_Saga_Will_Move_On_PartiallyCompleted_State() { var newUserId = Guid.NewGuid(); Host.ConnectReceiveEndpoint(UsersHandlerEndpoint, e => { Handler(e, new MessageHandler <CreateUser>( ctx => { return(ctx.Publish(new UserCreatedSuccessfully(ctx.Message.CorrelationId, newUserId))); })); Handler(e, new MessageHandler <UnassignGroupsFromUser>( ctx => { return(ctx.Publish(new GroupsUnassignedFromUserUnsuccessfully(ctx.Message.CorrelationId, new List <Guid>(), "boom"))); })); }); Host.ConnectReceiveEndpoint(GroupsHandlerEndpoint, e => { Handler(e, new MessageHandler <AssignUserToGroup>( ctx => { return(ctx.Publish(new UserAssignedToGroupUnsuccessfully(ctx.Message.CorrelationId, Guid.Empty, "Group assignment failed!"))); })); }); var command = CreateProvisionNewUserSingleGroupCommand(); await InputQueueSendEndpoint.Send(command); var sagaId = await ShouldContainSaga(command.CorrelationId, _saga.PartiallyCompleted); var instance = _sagaRepository[sagaId.Value].Instance; Assert.AreEqual(nameof(ProvisionUserWithSingleGroupSaga), instance.SagaType); Assert.AreEqual(command.CorrelationId, instance.ParentCorrelationId); Assert.AreEqual(command.User.UserName, instance.User.UserName); }
public async Task Should_store_and_retrieve_the_message_data_from_blob_storage() { var dataDictionary = new DataDictionary() { Values = new Dictionary <string, string>() { { "First", "1st" }, { "Second", "2nd" } } }; await InputQueueSendEndpoint.Send <DataMessage>(new { InVar.CorrelationId, Dictionary = dataDictionary }); ConsumeContext <DataMessage> consumeContext = await _handler; Assert.That(consumeContext.Message.Dictionary.HasValue, Is.True); Assert.That(_data.Values, Is.EqualTo(dataDictionary.Values)); }
public async Task Should_cancel_the_message() { Task <ConsumeContext <Fault <PingMessage> > > faulted = await ConnectPublishHandler <Fault <PingMessage> >(); await InputQueueSendEndpoint.Send(new PingMessage()); await _pingReceived.Task; LogContext.Debug?.Log("Ping was received"); await _scheduledMessage.Task; LogContext.Debug?.Log("Pong was scheduled"); await faulted; await InMemoryTestHarness.Consumed.Any <CancelScheduledMessage>(); await AdvanceTime(TimeSpan.FromSeconds(20)); Assert.That(async() => await _pongReceived.Task.OrTimeout(s: 3), Throws.TypeOf <TimeoutException>()); }
public async Task Verify_consumed_message_contains_property() { ITestArrayMessage message = new TestArrayMessage { Data = new TestBaseClass[] { new TestConcreteClass() } }; await InputQueueSendEndpoint.Send(message); await Task.WhenAny(_handled, _faulted); if (_faulted.IsCompleted) { Assert.Fail("Should not faulted"); } ConsumeContext <ITestArrayMessage> context = await _handled; Assert.That(context.Message.Data, Is.Not.Null); Assert.That(context.Message.Data.Length, Is.EqualTo(1)); Assert.IsInstanceOf <TestConcreteClass>(context.Message.Data[0]); }
public async Task Should_reach_the_saga() { Task <ConsumeContext <CreateCompleted> > createCompleted = await ConnectPublishHandler <CreateCompleted>(); Task <ConsumeContext <FinallyCompleted> > finallyCompleted = await ConnectPublishHandler <FinallyCompleted>(); var values = new { InVar.CorrelationId }; await InputQueueSendEndpoint.Send <Create>(values); ConsumeContext <CreateCompleted> createContext = await createCompleted; ConsumeContext <FinallyCompleted> finallyContext = await finallyCompleted; createCompleted = await ConnectPublishHandler <CreateCompleted>(); finallyCompleted = await ConnectPublishHandler <FinallyCompleted>(); values = new { InVar.CorrelationId }; await InputQueueSendEndpoint.Send <Create>(values); createContext = await createCompleted; finallyContext = await finallyCompleted; }
public async Task Should_reschedule_the_message_with_a_new_token_id() { var correlationId = Guid.NewGuid(); var startCommand = new StartCommand(correlationId); await InputQueueSendEndpoint.Send(startCommand); ConsumeContext <MessageRescheduled> rescheduledEvent = await _rescheduled; var sagaInstance = _repository[correlationId].Instance; Assert.NotNull(rescheduledEvent.Message.NewScheduleTokenId); Assert.AreEqual(sagaInstance.CorrelationId, rescheduledEvent.Message.CorrelationId); Assert.AreEqual(sagaInstance.ScheduleId, rescheduledEvent.Message.NewScheduleTokenId); await InputQueueSendEndpoint.Send(new StopCommand(correlationId)); var saga = await _repository.ShouldNotContainSaga(correlationId, TestTimeout); Assert.IsNull(saga); }
public async Task Should_have_removed_the_state_machine() { Guid correlationId = Guid.NewGuid(); await InputQueueSendEndpoint.Send(new GirlfriendYelling { CorrelationId = correlationId }); var saga = await GetSagaRetry(correlationId, TestTimeout); Assert.IsNotNull(saga); await InputQueueSendEndpoint.Send(new SodOff { CorrelationId = correlationId }); saga = await GetNoSagaRetry(correlationId, TestTimeout); Assert.IsNull(saga); }
private async Task SetupStateMachine( Guid sagaId, Guid customerId, String toState) { if (String.IsNullOrEmpty(toState)) { return; } await MoveStateMachineForward(BuildStartMessage(), x => x.AwaitingDetails); var awaitingDetailsId = await _Repository.ShouldContainSagaInState( sagaId, _Machine, x => x.AwaitingDetails, _TestTimeout); Assert.IsNotNull(awaitingDetailsId, "Error, expected state machine in AwaitingDetails state"); if (toState == _Machine.AwaitingDetails.Name) { return; } // ...and more stuff to move to later states, depending on // where I want my test's starting point to be... async Task MoveStateMachineForward <T>( T message, Func <ProcessStateMachine, Automatonymous.State> targetState) where T : class { await InputQueueSendEndpoint.Send(message); var foundSagaId = await _Repository.ShouldContainSagaInState( sagaId, _Machine, targetState, _TestTimeout); Assert.IsTrue(foundSagaId.HasValue); } IStartProcess BuildStartMessage() { return(new StartProcessMessage(sagaId, customerId)); } }
public async Task Should_provide_the_outbox() { var fault = ConnectPublishHandler <Fault <PingMessage> >(); await InputQueueSendEndpoint.Send(new PingMessage()); var consumeContext = await ConsumeContext; Assert.That(consumeContext.TryGetPayload <InMemoryOutboxConsumeContext <PingMessage> >(out var outboxConsumeContext), "Is ConsumerConsumeContext"); var publishEndpoint = await PublishEndpoint; var sendEndpointProvider = await SendEndpointProvider; Assert.That(publishEndpoint, Is.TypeOf <InMemoryOutboxConsumeContext <PingMessage> >()); Assert.That(sendEndpointProvider, Is.TypeOf <InMemoryOutboxConsumeContext <PingMessage> >()); Assert.That(ReferenceEquals(publishEndpoint, sendEndpointProvider), "ReferenceEquals(publishEndpoint, sendEndpointProvider)"); Assert.That(ReferenceEquals(outboxConsumeContext, sendEndpointProvider), "ReferenceEquals(outboxConsumeContext, sendEndpointProvider)"); await fault; Assert.That(InMemoryTestHarness.Published.Select <ServiceDidIt>().Any(), Is.False, "Outbox Did Not Intercept!"); }
public async Task Should_have_removed_the_state_machine() { Guid correlationId = Guid.NewGuid(); await InputQueueSendEndpoint.Send(new GirlfriendYelling { CorrelationId = correlationId }); Guid?sagaId = await _repository.Value.ShouldContainSaga(correlationId, TestTimeout); Assert.IsTrue(sagaId.HasValue); await InputQueueSendEndpoint.Send(new SodOff { CorrelationId = correlationId }); sagaId = await _repository.Value.ShouldNotContainSaga(correlationId, TestTimeout); Assert.IsFalse(sagaId.HasValue); }
public async Task Should_handle_the_response() { Task <ConsumeContext <MemberRegistrationFailed> > handler = await ConnectPublishHandler <MemberRegistrationFailed>(); var memberId = NewId.NextGuid(); await InputQueueSendEndpoint.Send <RegisterMember>(new { memberId, Name = "Frank" }); ConsumeContext <MemberRegistrationFailed> registered = await handler; Guid?saga = await _repository.ShouldContainSagaInState(memberId, _machine, x => x.Registered, TestTimeout); Assert.IsTrue(saga.HasValue); var sagaInstance = _repository[saga.Value].Instance; Assert.That(sagaInstance.Name, Is.EqualTo("Frank")); }
public async Task Should_cancel_when_the_order_is_submitted() { Task <ConsumeContext <CartRemoved> > handler = SubscribeHandler <CartRemoved>(); CartItemAdded cartItemAdded = new CartItemAddedCommand { MemberNumber = Guid.NewGuid().ToString() }; await InputQueueSendEndpoint.Send(cartItemAdded); Guid?saga = await _repository.ShouldContainSaga(x => x.MemberNumber == cartItemAdded.MemberNumber && GetCurrentState(x) == _machine.Active, TestTimeout); Assert.IsTrue(saga.HasValue); await InputQueueSendEndpoint.Send(new OrderSubmittedEvent(cartItemAdded.MemberNumber)); ConsumeContext <CartRemoved> removed = await handler; await Task.Delay(3000); }
public async Task Should_receive_the_published_message() { Task <ConsumeContext <StartupComplete> > messageReceived = await ConnectPublishHandler <StartupComplete>(); var message = new Start("Joe"); await InputQueueSendEndpoint.Send(message); ConsumeContext <StartupComplete> received = await messageReceived; Assert.AreEqual(message.CorrelationId, received.Message.TransactionId); Assert.IsTrue(received.InitiatorId.HasValue, "The initiator should be copied from the CorrelationId"); Assert.AreEqual(received.InitiatorId.Value, message.CorrelationId, "The initiator should be the saga CorrelationId"); Assert.AreEqual(received.SourceAddress, InputQueueAddress, "The published message should have the input queue source address"); Guid?saga = await _repository.ShouldContainSagaInState(message.CorrelationId, _machine, _machine.Running, TestTimeout); Assert.IsTrue(saga.HasValue); }
public async Task Should_handle_the_big_load() { Guid[] sagaIds = new Guid[200]; for (int i = 0; i < 200; i++) { Guid correlationId = Guid.NewGuid(); InputQueueSendEndpoint.Send(new GirlfriendYelling { CorrelationId = correlationId }); sagaIds[i] = correlationId; } for (int i = 0; i < 200; i++) { Guid?sagaId = await _repository.Value.ShouldContainSaga(sagaIds[i], TestTimeout); Assert.IsTrue(sagaId.HasValue); } }
public async Task If_Update_succeeds_Sync_process_is_set_to_success() { // Arrange var ar = new ArchiveRecord { ArchiveRecordId = "3245", Security = new ArchiveRecordSecurity { MetadataAccessToken = new List <string> { "BAR" }, PrimaryDataFulltextAccessToken = new List <string> { "BAR" }, PrimaryDataDownloadAccessToken = new List <string> { "BAR" } } }; var mutationId = 124; indexManager.Setup(e => e.UpdateArchiveRecord(It.IsAny <ConsumeContext <IUpdateArchiveRecord> >())); // Act await InputQueueSendEndpoint.Send <IUpdateArchiveRecord>(new { ArchiveRecord = ar, MutationId = mutationId }); // Wait for the results await updateArchiveReocrdTask; var context = await archiveRecordUpdatedTask; // Assert context.Message.ActionSuccessful.Should().Be(true); context.Message.MutationId.Should().Be(mutationId); context.Message.ErrorMessage.Should().Be(null); }
public async Task Should_not_be_in_final_state() { var correlationId = NewId.NextGuid(); await InputQueueSendEndpoint.Send(new RehersalBegins { CorrelationId = correlationId }); var saga = await GetSagaRetry(correlationId, TestTimeout); Assert.IsNotNull(saga); await Task.WhenAll( InputQueueSendEndpoint.Send(new Bass { CorrelationId = correlationId, Name = "John" }), InputQueueSendEndpoint.Send(new Baritone { CorrelationId = correlationId, Name = "Mark" }), InputQueueSendEndpoint.Send(new Tenor { CorrelationId = correlationId, Name = "Anthony" }), InputQueueSendEndpoint.Send(new Countertenor { CorrelationId = correlationId, Name = "Tom" }) ); // Because concurrency exception's happened without retry middleware configured, we aren't in our final state/ var instance = await GetSaga(correlationId); Assert.IsTrue(!instance.CurrentState.Equals("Harmony")); }
public async Task Should_not_capture_all_events_single_saga() { var correlationId = Guid.NewGuid(); await InputQueueSendEndpoint.Send(new RehersalBegins { CorrelationId = correlationId }); Guid?sagaId = await _repository.Value.ShouldContainSaga(correlationId, TestTimeout); Assert.IsTrue(sagaId.HasValue); await Task.WhenAll( InputQueueSendEndpoint.Send(new Bass { CorrelationId = correlationId, Name = "John" }), InputQueueSendEndpoint.Send(new Baritone { CorrelationId = correlationId, Name = "Mark" }), InputQueueSendEndpoint.Send(new Tenor { CorrelationId = correlationId, Name = "Anthony" }), InputQueueSendEndpoint.Send(new Countertenor { CorrelationId = correlationId, Name = "Tom" }) ); sagaId = await _repository.Value.ShouldContainSaga(x => x.CorrelationId == correlationId && x.CurrentState == _machine.Warmup.Name, TestTimeout); Assert.IsTrue(sagaId.HasValue); }
public async Task Should_handle_the_response() { Task <ConsumeContext <MemberRegistered> > handler = await ConnectPublishHandler <MemberRegistered>(); var memberNumber = Guid.NewGuid().ToString(); await InputQueueSendEndpoint.Send <RegisterMember>(new { MemberNumber = memberNumber, Name = "Frank", Address = "123 American Way" }); ConsumeContext <MemberRegistered> registered = await handler; Guid?saga = await _repository.ShouldContainSagaInState(x => x.MemberNumber == memberNumber, _machine, x => x.Registered, TestTimeout); Assert.IsTrue(saga.HasValue); var sagaInstance = _repository[saga.Value].Instance; Assert.IsFalse(sagaInstance.ValidateAddressRequestId.HasValue); }
public async Task Should_work_as_expected() { Task <ConsumeContext <TestStarted> > started = ConnectPublishHandler <TestStarted>(); Task <ConsumeContext <TestUpdated> > updated = ConnectPublishHandler <TestUpdated>(); var correlationId = NewId.NextGuid(); await InputQueueSendEndpoint.Send(new StartTest { CorrelationId = correlationId, TestKey = "Unique" }); await started; await InputQueueSendEndpoint.Send(new UpdateTest { TestId = correlationId, TestKey = "Unique" }); await updated; }
public async Task Should_receive_using_the_first_consumer() { const string name = "Joe"; await InputQueueSendEndpoint.Send(new SimpleMessageClass(name)); var lastConsumer = await SimpleConsumer.LastConsumer; lastConsumer.ShouldNotBe(null); var last = await lastConsumer.Last; last.Name .ShouldBe(name); var wasDisposed = await lastConsumer.Dependency.WasDisposed; wasDisposed .ShouldBe(true); //Dependency was not disposed"); lastConsumer.Dependency.SomethingDone .ShouldBe(true); //Dependency was disposed before consumer executed"); }
public async Task Should_return_the_header_value_from_the_transport() { var message = new BagOfCrap { CommandId = NewId.NextGuid(), ItemNumber = "27" }; const string headerName = "Random-Header"; const string headerValue = "SomeValue"; await InputQueueSendEndpoint.Send(message, x => x.Headers.Set(headerName, headerValue)); ConsumeContext <Command> context = await _handled; Assert.That(context.ReceiveContext.ContentType, Is.EqualTo(RawJsonMessageSerializer.RawJsonContentType), $"unexpected content-type {context.ReceiveContext.ContentType}"); Assert.That(context.Message.CommandId, Is.EqualTo(message.CommandId)); Assert.That(context.Message.ItemNumber, Is.EqualTo(message.ItemNumber)); Assert.That(context.Headers.Get <string>(headerName), Is.EqualTo(headerValue)); }