public void Should_split_archived_failuremessages_from_two_logical_subscribers()
        {
            // Arrange
            var scenarioInfo = new PreSplitScenario(FailedMessageStatus.Archived);

            scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue);
            scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber2InputQueue);
            using (var session = documentStore.OpenSession())
            {
                session.Store(scenarioInfo.FailedMessage);
                session.SaveChanges();
            }

            // Act
            var migration = CreateMigration();

            migration.Apply(documentStore);

            // Assert
            using (var session = documentStore.OpenSession())
            {
                var failedMessages = session.Query <FailedMessage>().ToArray();

                Assert.AreEqual(2, failedMessages.Length, "There should be 2 failed messages");

                var firstAttemptFailure = failedMessages.SingleOrDefault(f => f.UniqueMessageId == scenarioInfo.ProcessingAttempts[0].ExpectedUniqueMessageId);
                Assert.IsNotNull(firstAttemptFailure, "Attempt for Subscriber 1 not found");
                Assert.AreEqual(firstAttemptFailure.Status, FailedMessageStatus.Unresolved, "Attempt for Subscriber 1 is not marked Unresolved");


                var secondAttemptFailure = failedMessages.SingleOrDefault(f => f.UniqueMessageId == scenarioInfo.ProcessingAttempts[1].ExpectedUniqueMessageId);
                Assert.IsNotNull(secondAttemptFailure, "Attempt for Subscriber 2 not found");
                Assert.AreEqual(secondAttemptFailure.Status, FailedMessageStatus.Unresolved, "Attempt for Subscriber 2 is not marked Unresolved");
            }
        }
        public void Split_failuremessages_should_have_failure_groups()
        {
            // Arrange

            var scenarios = new List <PreSplitScenario>();

            using (var session = documentStore.OpenSession())
            {
                foreach (FailedMessageStatus status in Enum.GetValues(typeof(FailedMessageStatus)))
                {
                    var scenarioInfo = new PreSplitScenario(status);
                    scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue);
                    scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber2InputQueue);
                    scenarioInfo.AddGroup("GroupId", "Fake Group Title", "Fake Group Type");
                    scenarios.Add(scenarioInfo);

                    session.Store(scenarioInfo.FailedMessage);
                }

                session.SaveChanges();
            }
            AddClassifier(new ExceptionTypeAndStackTraceFailureClassifier());
            AddClassifier(new MessageTypeFailureClassifier());

            var attempts = scenarios.SelectMany(s => s.ProcessingAttempts.Select(pa => new { s.OriginalFailedMessageStatus, pa.ExpectedUniqueMessageId, EndpointName = pa.Attempt.Headers.ProcessingEndpointName() })).ToList();

            // Act
            var migration = CreateMigration();

            migration.Apply(documentStore);

            // Assert

            FailedMessage[] failedMessages;

            using (var session = documentStore.OpenSession())
            {
                failedMessages = session.Query <FailedMessage>().ToArray();
            }

            Assert.IsNotEmpty(failedMessages, "No Failed Messages Found");

            foreach (var failedMessage in failedMessages)
            {
                var attempt = attempts.SingleOrDefault(a => a.ExpectedUniqueMessageId == failedMessage.UniqueMessageId);

                Assert.IsNotNull(attempt, "Could not find attempt for a failed message");

                Assert.AreEqual(2, failedMessage.FailureGroups.Count, "A FailedMessage does not have all expected Failure Groups");

                var expectedPrefix = string.Format(SplitFailedMessageDocumentsMigration.GroupPrefixFormat, attempt.EndpointName);

                var nonMatchingGroups = failedMessage.FailureGroups.Where(x => x.Title.StartsWith(expectedPrefix) == false).ToArray();

                Assert.IsFalse(nonMatchingGroups.Any(), $"All groups should start with the prefix: {expectedPrefix}");
            }
        }
        public void Should_split_attempts_from_the_same_endpoint_with_v4_and_later_instance()
        {
            // Arrange
            var scenarioInfo = new PreSplitScenario();

            scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue);
            scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue, PreSplitScenario.Subscriber1Endpoint);
            scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber2InputQueue, PreSplitScenario.Subscriber2Endpoint);

            using (var session = documentStore.OpenSession())
            {
                session.Store(scenarioInfo.FailedMessage);
                session.SaveChanges();
            }

            // Act
            var migration = CreateMigration();

            migration.Apply(documentStore);

            // Assert
            using (var session = documentStore.OpenSession())
            {
                var failedMessages = session.Query <FailedMessage>().ToArray();

                Assert.AreEqual(2, failedMessages.Length, "Expected FailedMessage Records is incorrect");
            }
        }
        public void Should_combine_attempts_from_the_same_endpoint_v4()
        {
            // Arrange
            var scenarioInfo = new PreSplitScenario();

            scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue);
            scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue, true);
            scenarioInfo.AddV4ProcessingAttempt(PreSplitScenario.Subscriber2InputQueue);

            using (var session = documentStore.OpenSession())
            {
                session.Store(scenarioInfo.FailedMessage);
                session.SaveChanges();
            }

            // Act
            var migration = CreateMigration();

            migration.Apply(documentStore);

            // Assert
            using (var session = documentStore.OpenSession())
            {
                var failedMessages = session.Query <FailedMessage>().ToArray();

                Assert.AreEqual(2, failedMessages.Length, "There should be 2 failed message for subscriber 1 and subscriber 2");

                var subscriber1FailedMessage = failedMessages.FirstOrDefault(fm => fm.ProcessingAttempts.Count == 2);
                var subscriber2FailedMessage = failedMessages.FirstOrDefault(fm => fm.ProcessingAttempts.Count == 1);

                Assert.IsNotNull(subscriber1FailedMessage, "Subscriber 1 should have 2 attempts");
                Assert.IsNotNull(subscriber2FailedMessage, "Subscriber 1 should have 1 attempt");

                Assert.IsTrue(subscriber1FailedMessage.ProcessingAttempts.All(pa => pa.FailureDetails.AddressOfFailingEndpoint == PreSplitScenario.Subscriber1InputQueue), "Subscriber 1 message has mismatched failed queues");
                Assert.IsTrue(subscriber2FailedMessage.ProcessingAttempts.All(pa => pa.FailureDetails.AddressOfFailingEndpoint == PreSplitScenario.Subscriber2InputQueue), "Subscriber 2 message has mismatched failed queues");
            }
        }