public void Publish_MultipleSubscribedMessageTypes_AllMessagesReceived()
        {
            // Arrange
            TestMessageType1  msg1     = new TestMessageType1("Msg1", 1, 1.2);
            TestMessageType2  msg2     = new TestMessageType2("Msg2", 2);
            TestMessageType3  msg3     = new TestMessageType3("Msg3", 3);
            TestMessageType4  msg4     = new TestMessageType4("Msg4", 4);
            TestEventConsumer consumer = GetTestConsumer();

            // Act
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                msg1
            });
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                msg2
            });
            GetTestPublisher().Publish(AggregateType34, AggregateType34, new List <IDomainEvent> {
                msg3
            });
            GetTestPublisher().Publish(AggregateType34, AggregateType34, new List <IDomainEvent> {
                msg4
            });

            // Allow time for messages to process
            int count = 10;

            while (consumer.TotalMessageCount() < 4 && count > 0)
            {
                Thread.Sleep(1000);
                count--;
            }

            ShowTestResults();

            // Assert
            Assert.That(GetDbContext().Messages.Count(),
                        Is.EqualTo(4), "Number of messages produced");
            Assert.That(GetDbContext().Messages.Count(msg => msg.Published == 0),
                        Is.EqualTo(0), "Number of unpublished messages");
            foreach (Type eventType in consumer.GetEventTypes())
            {
                TestEventConsumer.EventStatistics eventStatistics = consumer.GetEventStatistics(eventType);
                Assert.That(eventStatistics.MessageCount,
                            Is.EqualTo(1), $"Number of {eventType.Name} messages received by consumer");
                Assert.That(eventStatistics.ReceivedMessages.Count,
                            Is.EqualTo(1), $"Number of received {eventType.Name} messages");
            }

            Assert.That(consumer.TotalMessageCount(),
                        Is.EqualTo(4), "Total number of messages received by consumer");
            Assert.That(GetDbContext().ReceivedMessages.Count(msg => msg.MessageId != null),
                        Is.EqualTo(4), "Number of received messages");
            msg1.AssertGoodMessageReceived(consumer.GetEventStatistics(typeof(TestMessageType1)).ReceivedMessages[0]);
            msg2.AssertGoodMessageReceived(consumer.GetEventStatistics(typeof(TestMessageType2)).ReceivedMessages[0]);
            msg3.AssertGoodMessageReceived(consumer.GetEventStatistics(typeof(TestMessageType3)).ReceivedMessages[0]);
            msg4.AssertGoodMessageReceived(consumer.GetEventStatistics(typeof(TestMessageType4)).ReceivedMessages[0]);

            GetTestMessageInterceptor()?.AssertCounts(4, 4, 4, 4, 4, 4);
        }
        protected void ShowTestResults()
        {
            TestContext.WriteLine("Test Config");
            TestContext.WriteLine("  Connection String: {0}", TestSettings.ConnectionStrings.EventuateTramDbConnection);
            TestContext.WriteLine("  Kafka server:      {0}", TestSettings.KafkaBootstrapServers);
            TestContext.WriteLine("  Schema:            {0}", EventuateDatabaseSchemaName);
            TestContext.WriteLine("  Dispatcher Id:     {0}", _subscriberId);
            TestContext.WriteLine("  Aggregate Type 12: {0}", AggregateType12);
            TestContext.WriteLine("  Aggregate Type 34: {0}", AggregateType34);

            TestContext.WriteLine("Test Results");
            TestContext.WriteLine("  N Messages in DB:  {0}", _dbContext.Messages.Count());
            TestContext.WriteLine("  Unpublished Count: {0}", _dbContext.Messages.Count(msg => msg.Published == 0));
            TestContext.WriteLine("  N Received in DB:  {0}", _dbContext.ReceivedMessages.Count(msg => msg.MessageId != null));
            foreach (Type eventType in _testEventConsumer.GetEventTypes())
            {
                TestContext.WriteLine($"  Received {eventType.Name}   {_testEventConsumer.GetEventStatistics(eventType).MessageCount}");
            }
            TestContext.WriteLine("  Exception Count:   {0}", _testEventConsumer.ExceptionCount);

            if (_interceptor != null)
            {
                TestContext.WriteLine("Message Interceptor Counts");
                TestContext.WriteLine("  Pre Send:     {0}", _interceptor.PreSendCount);
                TestContext.WriteLine("  Post Send:    {0}", _interceptor.PostSendCount);
                TestContext.WriteLine("  Pre Receive:  {0}", _interceptor.PreReceiveCount);
                TestContext.WriteLine("  Post Receive: {0}", _interceptor.PostReceiveCount);
                TestContext.WriteLine("  Pre Handle:   {0}", _interceptor.PreHandleCount);
                TestContext.WriteLine("  Post Handle:  {0}", _interceptor.PostHandleCount);
            }
        }
        public void Publish_SubscriberThrowsExceptionOnFirstOfMultipleMessages_MessagesHandlingStops()
        {
            // Arrange
            TestMessageType1  badmsg1  = new TestMessageType1("ThrowException", 1, 1.2);
            TestMessageType2  msg2A    = new TestMessageType2("Msg2a", 1);
            TestMessageType2  msg2B    = new TestMessageType2("Msg2b", 2);
            TestEventConsumer consumer = GetTestConsumer();

            // Act
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                badmsg1
            });
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                msg2A
            });
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                msg2B
            });

            // Allow time for messages to process
            int count = 10;

            TestEventConsumer.EventStatistics type2Statistics = consumer.GetEventStatistics(typeof(TestMessageType2));
            while (type2Statistics.MessageCount < 2 && count > 0)
            {
                Thread.Sleep(1000);
                count--;
            }

            ShowTestResults();

            // Assert
            Assert.That(GetDbContext().Messages.Count(),
                        Is.EqualTo(3), "Number of messages produced");
            Assert.That(GetDbContext().Messages.Count(msg => msg.Published == 0),
                        Is.EqualTo(0), "Number of unpublished messages");
            Assert.That(GetDbContext().ReceivedMessages.Count(msg => msg.MessageId != null),
                        Is.EqualTo(0), "Number of received messages");
            Assert.That(consumer.TotalMessageCount(),
                        Is.EqualTo(1), "Total number of messages received by consumer");
            Assert.That(consumer.GetEventStatistics(typeof(TestMessageType1)).MessageCount,
                        Is.EqualTo(1), "Number of Type 1 messages received by consumer");
            Assert.That(consumer.GetEventStatistics(typeof(TestMessageType2)).MessageCount,
                        Is.EqualTo(0), "Number of Type 2 messages received by consumer");
        }
        public void Publish_CustomEventTypeName_CorrectEventTypeHeader()
        {
            // Arrange
            TestMessageType2  msg2     = new TestMessageType2("Msg2", 2);
            TestEventConsumer consumer = GetTestConsumer();

            // Act
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                msg2
            });

            // Allow time for messages to process
            int count = 10;

            TestEventConsumer.EventStatistics type2Statistics = consumer.GetEventStatistics(typeof(TestMessageType2));
            while (type2Statistics.MessageCount < 1 && count > 0)
            {
                Thread.Sleep(1000);
                count--;
            }

            ShowTestResults();

            // Assert
            Assert.That(GetDbContext().Messages.Count(),
                        Is.EqualTo(1), "Number of messages produced");
            Assert.That(GetDbContext().Messages.Count(msg => msg.Published == 0),
                        Is.EqualTo(0), "Number of unpublished messages");
            Assert.That(GetDbContext().ReceivedMessages.Count(msg => msg.MessageId != null),
                        Is.EqualTo(1), "Number of received messages");
            Assert.That(type2Statistics.MessageCount,
                        Is.EqualTo(1), "Number of Type 2 messages received by consumer");
            Assert.That(type2Statistics.ReceivedMessages.Count,
                        Is.EqualTo(1), "Number of received type 2 messages");

            msg2.AssertGoodMessageReceived(type2Statistics.ReceivedMessages[0]);
            Assert.That(type2Statistics.ReceivedMessages[0].Message.GetHeader(EventMessageHeaders.EventType),
                        Is.EqualTo(TestMessageType2.EventTypeName), "Event type header");

            GetTestMessageInterceptor()?.AssertCounts(1, 1, 1, 1, 1, 1);
        }
        public void Publish_SubscribedMessageTypeAndUnsubscribedMessageType_ReceivedOnlySubscribedMessageType()
        {
            // Arrange
            TestMessageType1            msg1 = new TestMessageType1("Msg1", 1, 1.2);
            TestMessageUnsubscribedType unsubscribedMessage = new TestMessageUnsubscribedType("Msg3");
            TestEventConsumer           consumer            = GetTestConsumer();

            // Act
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                unsubscribedMessage
            });
            // Send a following message to identify when we're done
            GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                msg1
            });

            // Allow time for messages to process
            int count = 10;

            TestEventConsumer.EventStatistics type1Statistics = consumer.GetEventStatistics(typeof(TestMessageType1));
            while (type1Statistics.MessageCount < 1 && count > 0)
            {
                Thread.Sleep(1000);
                count--;
            }

            ShowTestResults();

            // Assert
            Assert.That(GetDbContext().Messages.Count(),
                        Is.EqualTo(2), "Number of messages produced");
            Assert.That(GetDbContext().Messages.Count(msg => msg.Published == 0),
                        Is.EqualTo(0), "Number of unpublished messages");
            Assert.That(GetDbContext().ReceivedMessages.Count(msg => msg.MessageId != null),
                        Is.EqualTo(2), "Number of received messages");
            Assert.That(consumer.TotalMessageCount(),
                        Is.EqualTo(1), "Total number of messages received by consumer");

            GetTestMessageInterceptor()?.AssertCounts(2, 2, 2, 2, 2, 2);
        }
        public void Send1000Message_Within1Minute()
        {
            // Arrange
            TestMessageType1  msg1     = new TestMessageType1("Msg1", 1, 1.2);
            TestEventConsumer consumer = GetTestConsumer();

            TestEventConsumer.EventStatistics type1Statistics = consumer.GetEventStatistics(
                typeof(TestMessageType1));

            // Act
            for (int x = 0; x < 1000; x++)
            {
                GetTestPublisher().Publish(AggregateType12, AggregateType12, new List <IDomainEvent> {
                    msg1
                });
            }

            // Allow time for messages to process
            int count = 300;

            while (type1Statistics.MessageCount < 1000 && count > 0)
            {
                Thread.Sleep(1000);
                count--;
            }

            ShowTestResults();

            // Assert
            Assert.AreEqual(1000, GetDbContext().Messages.Count(), "Expect 1000 messages produced");
            Assert.AreEqual(1000, type1Statistics.MessageCount, "Received by consumer count must be 1000");
            Assert.AreEqual(0, GetDbContext().Messages.Count(msg => msg.Published == 0), "No unpublished messages");
            Assert.AreEqual(1000, GetDbContext().ReceivedMessages.Count(msg => msg.MessageId != null), "Expect 1000 messages received");
            Assert.Less(type1Statistics.GetDuration().TotalSeconds, 60.0, "Time to send 1000 messages");

            TestContext.WriteLine("Performance Test completed in {0} seconds",
                                  type1Statistics.GetDuration().TotalSeconds);
        }