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_handle_larger_than_pagesize_number_of_failedmessages()
        {
            const int multiplier = 2;

            using (var session = documentStore.OpenSession())
            {
                for (var i = 0; i < SplitFailedMessageDocumentsMigration.PageSize * multiplier; i++)
                {
                    var scenarioInfo = new PreSplitScenario();
                    scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue, PreSplitScenario.Subscriber1Endpoint);
                    scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber2InputQueue, PreSplitScenario.Subscriber2Endpoint);

                    session.Store(scenarioInfo.FailedMessage);
                }

                session.SaveChanges();
            }

            // Act
            documentStore.WaitForIndexing();
            var migration       = CreateMigration();
            var migrationResult = migration.Apply(documentStore);

            Console.WriteLine($"Migration Result: {migrationResult}");
            documentStore.WaitForIndexing();

            // Assert
            using (var session = documentStore.OpenSession())
            {
                RavenQueryStatistics stats;
                // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
                session.Query <FailedMessage>().Customize(q => q.WaitForNonStaleResultsAsOfNow()).Statistics(out stats).Take(0).ToArray();

                var expectedCount = SplitFailedMessageDocumentsMigration.PageSize * multiplier * multiplier;

                Assert.AreEqual(expectedCount, stats.TotalResults, $"There should be {expectedCount} failed messages after split");
            }
        }
        public void Should_combined_attempts_from_the_same_endpoint_v5_and_later()
        {
            // Arrange
            var scenarioInfo = new PreSplitScenario();

            scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue, PreSplitScenario.Subscriber1Endpoint);
            scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue, PreSplitScenario.Subscriber1Endpoint, true);
            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, "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");
            }
        }
        public void Should_split_retryissued_failuremessages_from_two_logical_subscribers_after_retrying()
        {
            // Arrange
            var scenarioInfo = new PreSplitScenario(FailedMessageStatus.RetryIssued);

            scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue, PreSplitScenario.Subscriber1Endpoint);
            scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber2InputQueue, PreSplitScenario.Subscriber2Endpoint);
            scenarioInfo.AddV5ProcessingAttempt(PreSplitScenario.Subscriber1InputQueue, PreSplitScenario.Subscriber1Endpoint, true);
            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");
            }
        }