Search code examples
c#specflowmasstransitxunit.net

Clean up on abort Tests run using MassTransit Azure Service Bus


I have built of a suite of end-to-end tests for a group of event-driven services developed using MassTransit that communicates through azure service bus. The tests are developed using XUnit and SpecFlow and use an azure service bus. They run OK.

In my shared context that my specflow scenarios use,

private IBusControl? Bus { get; set; }

public async Task SetupBusAsync()
{
    Bus = MassTransit.Bus.Factory.CreateUsingAzureServiceBus(config =>
    {
         config.Host(<connection string goes here>);
         config.AutoDeleteOnIdle = TimeSpan.FromMinutes(5);
    });
    await Bus.StartAsync();
}

public async Task StopBusAsync()
{
    await Bus!.StopAsync();
}

public async Task SetupConsumer<TEventType>(<skipped>)
where TEventType : class
{
    var handle = Bus!.ConnectReceiveEndpoint(endpoint =>
                  endpoint.Handler<TEventType>(context =>
                  {
                     // Do something on the consumed message using a delegate
                  }));
    await handle.Ready;
}

I am facing an issue when these tests get aborted automatically or (almost always it is) manually for whatever reason, the current tests-run's service bus subscriptions don't get removed. I understand that the MassTransit bus is not stopped and ended abruptly in this case is the main reason. I tried setting AutoDeleteOnIdle and it doesn't help my case. Can anyone please suggest me a better approach to gracefully handle this scenario to remove the subscriptions that my tests create when the test-run is aborted?

Thank you!


Solution

  • In the MassTransit unit tests, I have a method called at fixture setup which deletes all topics and queues prior to running the test. That way, what's left after the test is available to review if needed. In a normal run, each test cleans up before it starts.

    async Task CleanupNamespace()
    {
        try
        {
            var managementClient = Configuration.GetManagementClient();
    
            var pageableTopics = managementClient.GetTopicsAsync();
            var topics = await pageableTopics.ToListAsync();
            while (topics.Count > 0)
            {
                foreach (var topic in topics)
                    await managementClient.DeleteTopicAsync(topic.Name);
    
                topics = await managementClient.GetTopicsAsync().ToListAsync();
            }
    
            var pageableQueues = managementClient.GetQueuesAsync();
            var queues = await pageableQueues.ToListAsync();
            while (queues.Count > 0)
            {
                foreach (var queue in queues)
                    await managementClient.DeleteQueueAsync(queue.Name);
    
                queues = await managementClient.GetQueuesAsync().ToListAsync();
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }