public async Task A120_SkipAudit()
        {
            var tn = GetConfig().GetValue <string>("EventHubPoisonMessageTable");

            PoisonMessagePersistence.DefaultTableName = tn;

            var cs  = GetConfig().GetValue <string>("AzureWebJobsStorage");
            var cst = await PoisonMessagePersistence.GetPoisonMessageSkippedTable(cs);

            var smc = (await GetSkippedMessages(cst)).Count;

            var pp = new PoisonMessagePersistence(new PoisonMessageCreatePersistenceArgs
            {
                Config  = GetConfig(),
                Context = ResilientEventHubProcessorTest.CreatePartitionContext(),
                Logger  = TestSetUp.CreateLogger(),
                Options = ResilientEventHubProcessorTest.CreateOptions()
            });

            var ed = CreateEventData("200", 2);

            await pp.SkipAuditAsync(ed, "Explicit audit.");

            var smca = (await GetSkippedMessages(cst)).Count;

            Assert.AreEqual(smc + 1, smca);

            var msgs = await PoisonMessagePersistence.GetAllMessagesAsync(cst);

            var msg = msgs.Last();

            Assert.AreEqual("path-eventhub", msg.PartitionKey);
            Assert.IsTrue(msg.RowKey.EndsWith("consumergroup-0"));
            Assert.AreEqual("200", msg.Body);
            Assert.AreEqual("Explicit audit.", msg.Exception);
            Assert.AreEqual("200", msg.Offset);
            Assert.AreEqual(2, msg.SequenceNumber);
            Assert.AreEqual(false, msg.SkipMessage);
            Assert.AreEqual("ns.class", msg.FunctionType);
            Assert.AreEqual("testfunc", msg.FunctionName);
            Assert.IsNotNull(msg.SkippedTimeUtc);
        }
        public async Task A100_EndToEnd()
        {
            var tn = GetConfig().GetValue <string>("EventHubPoisonMessageTable");

            PoisonMessagePersistence.DefaultTableName = tn;

            var cs = GetConfig().GetValue <string>("AzureWebJobsStorage");
            var ct = await PoisonMessagePersistence.GetPoisonMessageTable(cs);

            var cst = await PoisonMessagePersistence.GetPoisonMessageSkippedTable(cs);

            var smc = (await GetSkippedMessages(cst)).Count;

            // Make sure there are no messages to begin with.
            var msgs = await PoisonMessagePersistence.GetAllMessagesAsync(ct);

            foreach (var m in msgs)
            {
                await ct.ExecuteAsync(TableOperation.Delete(m));
            }

            var pp = new PoisonMessagePersistence(new PoisonMessageCreatePersistenceArgs
            {
                Config  = GetConfig(),
                Context = ResilientEventHubProcessorTest.CreatePartitionContext(),
                Logger  = TestSetUp.CreateLogger(),
                Options = ResilientEventHubProcessorTest.CreateOptions()
            });

            var ed = CreateEventData("100", 1);

            // Checking and removing with unknown is a-ok.
            Assert.AreEqual(PoisonMessageAction.NotPoison, await pp.CheckAsync(ed));
            await pp.RemoveAsync(ed, PoisonMessageAction.NotPoison);

            Assert.AreEqual(smc, (await GetSkippedMessages(cst)).Count);

            // Add an event as poison.
            await pp.SetAsync(ed, new DivideByZeroException("My bad."));

            Assert.AreEqual(PoisonMessageAction.PoisonRetry, await pp.CheckAsync(ed));
            Assert.AreEqual(smc, (await GetSkippedMessages(cst)).Count);

            msgs = await PoisonMessagePersistence.GetAllMessagesAsync(ct);

            Assert.AreEqual(1, msgs.Count());

            var msg = msgs.First();

            Assert.AreEqual("path-eventhub", msg.PartitionKey);
            Assert.AreEqual("consumergroup-0", msg.RowKey);
            Assert.AreEqual("100", msg.Body);
            Assert.AreEqual("System.DivideByZeroException: My bad.", msg.Exception);
            Assert.AreEqual("100", msg.Offset);
            Assert.AreEqual(1, msg.SequenceNumber);
            Assert.AreEqual(false, msg.SkipMessage);
            Assert.AreEqual("ns.class", msg.FunctionType);
            Assert.AreEqual("testfunc", msg.FunctionName);

            // Update to skip.
            await PoisonMessagePersistence.SkipMessageAsync(ct, msg.PartitionKey, msg.RowKey);

            Assert.AreEqual(PoisonMessageAction.PoisonSkip, await pp.CheckAsync(ed));
            Assert.AreEqual(smc, (await GetSkippedMessages(cst)).Count);

            msgs = await PoisonMessagePersistence.GetAllMessagesAsync(ct);

            Assert.AreEqual(1, msgs.Count());

            msg = msgs.First();
            Assert.AreEqual("path-eventhub", msg.PartitionKey);
            Assert.AreEqual("consumergroup-0", msg.RowKey);
            Assert.AreEqual("100", msg.Body);
            Assert.AreEqual("System.DivideByZeroException: My bad.", msg.Exception);
            Assert.AreEqual("100", msg.Offset);
            Assert.AreEqual(1, msg.SequenceNumber);
            Assert.AreEqual(true, msg.SkipMessage);
            Assert.AreEqual("ns.class", msg.FunctionType);
            Assert.AreEqual("testfunc", msg.FunctionName);
            Assert.IsNull(msg.SkippedTimeUtc);

            // Remove the poison as no longer poison.
            await pp.RemoveAsync(ed, PoisonMessageAction.NotPoison);

            Assert.AreEqual(PoisonMessageAction.NotPoison, await pp.CheckAsync(ed));
            Assert.AreEqual(smc, (await GetSkippedMessages(cst)).Count);

            msgs = await PoisonMessagePersistence.GetAllMessagesAsync(ct);

            Assert.AreEqual(0, msgs.Count());

            // Create a new poison message.
            ed = CreateEventData("200", 2);
            await pp.SetAsync(ed, new DivideByZeroException("My bad."));

            Assert.AreEqual(PoisonMessageAction.PoisonRetry, await pp.CheckAsync(ed));
            Assert.AreEqual(smc, (await GetSkippedMessages(cst)).Count);

            msgs = await PoisonMessagePersistence.GetAllMessagesAsync(ct);

            Assert.AreEqual(1, msgs.Count());
            msg = msgs.First();

            // Remove the poison as skipped (poison).
            await pp.RemoveAsync(ed, PoisonMessageAction.PoisonSkip);

            Assert.AreEqual(PoisonMessageAction.NotPoison, await pp.CheckAsync(ed));

            var sms = await GetSkippedMessages(cst);

            Assert.AreEqual(smc + 1, sms.Count);

            var sm = sms.Where(pm => pm.PartitionKey == msg.PartitionKey && pm.RowKey.EndsWith(msg.RowKey)).OrderByDescending(pm => pm.RowKey).FirstOrDefault();

            Assert.IsNotNull(sm.SkippedTimeUtc);
        }