NIOAsyncTestingEventLoop

An EventLoop that is thread safe and whose execution is fully controlled by the user.

AsyncTestingEventLoop.swift:65
iOS
13.0+
macOS
10.15+
tvOS
13.0+
watchOS
6.0+
final class NIOAsyncTestingEventLoop

Unlike more complex EventLoops, such as SelectableEventLoop, the NIOAsyncTestingEventLoop has no proper eventing mechanism. Instead, reads and writes are fully controlled by the entity that instantiates the NIOAsyncTestingEventLoop. This property makes NIOAsyncTestingEventLoop of limited use for many application purposes, but highly valuable for testing and other kinds of mocking. Unlike EmbeddedEventLoop, NIOAsyncTestingEventLoop is fully thread-safe and safe to use from within a Swift concurrency context.

Unlike EmbeddedEventLoop, NIOAsyncTestingEventLoop does require that user tests appropriately enforce thread safety. Used carefully it is possible to safely operate the event loop without explicit synchronization, but it is recommended to use executeInContext in any case where it’s necessary to ensure that the event loop is not making progress.

Time is controllable on an NIOAsyncTestingEventLoop. It begins at NIODeadline.uptimeNanoseconds(0) and may be advanced by a fixed amount by using advanceTime(by:), or advanced to a point in time with advanceTime(to:).

If users wish to perform multiple tasks at once on an NIOAsyncTestingEventLoop, it is recommended that they use executeInContext to perform the operations. For example:

await loop.executeInContext {
    // All three of these will be queued up simultaneously, and no other code can
    // get between them.
    loop.execute { firstTask() }
    loop.execute { secondTask() }
    loop.execute { thirdTask() }
}

There is a tricky requirement around waiting for EventLoopFutures when working with this event loop. Simply calling .wait() from the test thread will never complete. This is because wait calls loop.execute under the hood, and that callback cannot execute without calling loop.run().