55 lines
1.6 KiB
Swift
55 lines
1.6 KiB
Swift
import NIOCore
|
|
import NIOPosix
|
|
|
|
/// A fake server accepting connections and never answering.
|
|
///
|
|
/// A client connecting to it completes the TCP handshake and then waits forever for the first protocol byte — the shape of a database that hangs rather
|
|
/// than refuses. This is what the probe's deadline test connects to, proving the probe answers within its timeout instead of hanging alongside the server.
|
|
final class SilentPostgresServer {
|
|
|
|
// MARK: Properties
|
|
|
|
/// The port the server listens on, assigned by the system at bind time.
|
|
let port: Int
|
|
|
|
/// The listening channel the server accepts connections through.
|
|
private let channel: Channel
|
|
|
|
// MARK: Initializers
|
|
|
|
private init(
|
|
channel: Channel,
|
|
port: Int
|
|
) {
|
|
self.channel = channel
|
|
self.port = port
|
|
}
|
|
|
|
// MARK: Functions
|
|
|
|
/// Starts a server on the loopback interface, on a system-assigned port.
|
|
/// - Returns: the running server, ready to be connected to at ``port``.
|
|
static func start() async throws -> SilentPostgresServer {
|
|
let channel = try await ServerBootstrap(group: MultiThreadedEventLoopGroup.singleton)
|
|
.bind(host: "127.0.0.1", port: 0)
|
|
.get()
|
|
|
|
guard let port = channel.localAddress?.port else {
|
|
throw ChannelError.unknownLocalAddress
|
|
}
|
|
|
|
return .init(
|
|
channel: channel,
|
|
port: port
|
|
)
|
|
}
|
|
|
|
/// Stops the server, closing its listening channel.
|
|
func stop() async throws {
|
|
try await channel
|
|
.close()
|
|
.get()
|
|
}
|
|
|
|
}
|