Files
container/Sources/ContainerTestSupport/ContainerFixture+NetworkHelpers.swift
T

92 lines
3.3 KiB
Swift

//===----------------------------------------------------------------------===//
// Copyright © 2026 Apple Inc. and the container project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
import AsyncHTTPClient
import ContainerResource
import Foundation
// MARK: - Network inspect output
public struct NetworkInspectOutput: Codable {
public struct Status: Codable {
public let ipv4Subnet: String?
public let ipv4Gateway: String?
public let ipv6Subnet: String?
}
public let id: String
public let configuration: NetworkConfiguration
public let status: Status
}
// MARK: - Network lifecycle helpers
extension ContainerFixture {
/// Creates a named network, throwing on failure.
public func doNetworkCreate(_ name: String, args: [String] = []) throws {
var arguments = ["network", "create"]
arguments += args
arguments.append(name)
try run(arguments).check()
}
/// Deletes a named network, throwing on failure.
public func doNetworkDelete(_ name: String) throws {
try run(["network", "delete", name]).check()
}
/// Deletes a named network, silently ignoring errors.
public func doNetworkDeleteIfExists(_ name: String) {
_ = try? run(["network", "delete", name])
}
/// Inspects a network and returns decoded output.
public func inspectNetwork(_ name: String) throws -> NetworkInspectOutput {
let result = try run(["network", "inspect", name]).check()
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let networks = try decoder.decode([NetworkInspectOutput].self, from: result.outputData)
guard let network = networks.first else {
throw CommandError.executionFailed("network inspect returned empty array")
}
return network
}
/// Returns an `HTTPClient` for use in network connectivity tests.
public func makeHTTPClient() -> HTTPClient {
HTTPClient(eventLoopGroupProvider: .singleton)
}
/// Polls `url` via HTTP GET until it returns a 2xx status.
///
/// Useful after a container reaches `running` state, since that only proves
/// the container's init process is up — a server inside may still be starting.
public func waitForHTTPOk(
_ url: String, using client: HTTPClient, attempts: Int = 10, delay: Duration = .seconds(1)
) async throws {
try await retry(attempts: attempts, delay: delay) {
do {
var req = HTTPClientRequest(url: url)
req.method = .GET
let resp = try await client.execute(req, timeout: .seconds(3))
return resp.status.code >= 200 && resp.status.code < 300
} catch {
return false
}
}
}
}