Automation driver sequence played in an automation test freezes the engine when garbage collecting

I’m struggling with setting up an automation test using the automation framework with latent commands that uses the automation driver to simulate input.

The test is supposed to go like this

  1. Spawn in enemy actor X
  2. Shoot with weapon and check if damage has been dealt
  3. Repeat with next enemy actor until all are checked

This works fine for around 30 seconds, but then the engine will completely freeze with no error or nothing, I have to quit it manually. I know it probably has something do with garbage collection because of the timing, and because Unreal Insights consistently shows that it freezes almost right after GC’ing every time.
It also must have something to do with input simulation using the automation driver, because if I remove that section, no freeze happens.

At first I thought it was my custom wrapper around the automation driver that would get GC’ed, but then I tried doing it the ‘standard way’ (without my wrapper object) and it keeps happening - so not sure what’s going on.

This should be all the relevant code:

ADD_LATENT_AUTOMATION_COMMAND(FEngineWaitLatentCommand(1.5f));
ADD_LATENT_AUTOMATION_COMMAND(FLatentGenericFunction( [=] () mutable
{
	/* SOME CODE HERE FOR SPAWNING ENEMY AND AIMING AT IT */
        
	// Simulate shooting with automation driver (this will freeze the engine - leaving it out solves it, so it's gotta be because of it)
	AsyncTask(ENamedThreads::GameThread, [=] () mutable
	{
		FAutomationDriverPtr Driver;
		FDriverSequencePtr Sequence;
		
		IAutomationDriverModule::Get().Enable();
		Driver = IAutomationDriverModule::Get().CreateDriver();
		Sequence = Driver->CreateSequence();

		Sequence->Actions().Press(EKeys::LeftMouseButton);
		Sequence->Actions().Release(EKeys::LeftMouseButton);
		Sequence->Actions().Press(EKeys::LeftMouseButton);
		Sequence->Actions().Release(EKeys::LeftMouseButton);

		AsyncTask(ENamedThreads::AnyHiPriThreadNormalTask, [=]
		{
			Sequence->Perform();

			AsyncTask(ENamedThreads::GameThread, [=]
			{
				IAutomationDriverModule::Get().Disable(); 
			});
		});
	});
	
	FTimerDelegate TimerCallback;
	TimerCallback.BindLambda( [=]
	{
		// Destroy enemy when we're done with it
		Enemy->Destroy();
	});

	FTimerHandle Handle;
	World->GetTimerManager().SetTimer(Handle, TimerCallback, 2.35f, false);
}));
ADD_LATENT_AUTOMATION_COMMAND(FEngineWaitLatentCommand(2.35f));

That code block gets repeated X times in RunTest() to set up latent commands for each enemy.

Here’s FLatentGenericFunction, in case that should matter:

class FLatentGenericFunction : public IAutomationLatentCommand
{

public:
	FLatentGenericFunction(TFunction<void()>&& InFunction)
		: Function(MoveTemp(InFunction)) { }
	
	virtual bool Update() override
	{
		Function();
		return true;
	}
	
protected:
	
	TFunction<void()> Function;
};

Does anyone have an idea of what could be going on?
Not sure if I am misunderstanding the way latent commands work and all the lambda stuff, or if there might be a bug in the automation driver.

Thanks in advance.

This is not an answer, but maybe more context for someone …

Mine locks up in:

FAsyncAutomationDriver::~FAsyncAutomationDriver()
{
	Application->SetFakeModifierKeys(FModifierKeysState());
}

because Application was already GCed.

… I should also add that it only happens if I use Driver->CreateSequence(); … if I don’t use input sequence everything gets cleaned up fine.

Thanks for taking a look. Interesting find. Will keep updated if I find a solution