//===----------------------------------------------------------------------===//
// Copyright © 2025-2026 Apple Inc. and the Containerization 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 ArgumentParser
import Containerization
import ContainerizationEXT4
import ContainerizationError
import ContainerizationExtras
import ContainerizationOCI
import ContainerizationOS
import Crypto
import Foundation
import Logging
import SystemPackage

extension IntegrationSuite {
    func testProcessTrue() async throws {
        let id = "test-process-true"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/true"]
            config.memoryInBytes = 250_000_000
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }
    }

    func testProcessFalse() async throws {
        let id = "test-process-false"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/false"]
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 1 else {
            throw IntegrationError.assert(msg: "process status \(status) != 1")
        }
    }

    final class DiscardingWriter: @unchecked Sendable, Writer {
        var count: Int = 0

        func write(_ data: Data) throws {
            count += data.count
        }

        func close() throws {
            return
        }
    }

    final class BufferWriter: Writer {
        // `data` isn't used concurrently.
        nonisolated(unsafe) var data = Data()

        func write(_ data: Data) throws {
            guard data.count > 0 else {
                return
            }
            self.data.append(data)
        }

        func close() throws {
            return
        }
    }

    final class StdinBuffer: ReaderStream {
        let data: Data

        init(data: Data) {
            self.data = data
        }

        func stream() -> AsyncStream<Data> {
            let (stream, cont) = AsyncStream<Data>.makeStream()
            cont.yield(self.data)
            cont.finish()
            return stream
        }
    }

    final class ChunkedStdinBuffer: ReaderStream {
        let chunks: [Data]
        let delayMs: Int

        init(chunks: [Data], delayMs: Int = 0) {
            self.chunks = chunks
            self.delayMs = delayMs
        }

        func stream() -> AsyncStream<Data> {
            let chunks = self.chunks
            let delayMs = self.delayMs
            return AsyncStream { cont in
                Task {
                    for chunk in chunks {
                        if delayMs > 0 {
                            try? await Task.sleep(for: .milliseconds(delayMs))
                        }
                        cont.yield(chunk)
                    }
                    cont.finish()
                }
            }
        }
    }

    func testProcessEchoHi() async throws {
        let id = "test-process-echo-hi"
        let bs = try await bootstrap(id)

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/echo", "hi"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 1")
            }

            guard String(data: buffer.data, encoding: .utf8) == "hi\n" else {
                throw IntegrationError.assert(
                    msg: "process should have returned on stdout 'hi' != '\(String(data: buffer.data, encoding: .utf8)!)'")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testProcessNoExecutable() async throws {
        let id = "test-process-no-executable"
        let bs = try await bootstrap(id)

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["foobarbaz"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let _ = try await container.wait()
            try await container.stop()

            throw IntegrationError.assert(msg: "process didn't throw 'no executable' error")
        } catch {
            try? await container.stop()
            guard let err = error as? ContainerizationError,
                err.isCode(.internalError), err.description.contains("failed to find target executable")
            else {
                throw error
            }
        }
    }

    func testMultipleConcurrentProcesses() async throws {
        let id = "test-concurrent-processes"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            try await withThrowingTaskGroup(of: Void.self) { group in
                for i in 0...80 {
                    let exec = try await container.exec("exec-\(i)") { config in
                        config.arguments = ["/bin/true"]
                    }

                    group.addTask {
                        try await exec.start()
                        let status = try await exec.wait()
                        if status.exitCode != 0 {
                            throw IntegrationError.assert(msg: "process status \(status) != 0")
                        }
                        try await exec.delete()
                    }
                }

                try await group.waitForAll()

                try await container.stop()
            }
        } catch {
            throw error
        }
    }

    func testMultipleConcurrentProcessesOutputStress() async throws {
        let id = "test-concurrent-processes-output-stress"
        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let buffer = BufferWriter()
            let exec = try await container.exec("expected-value") { config in
                config.arguments = [
                    "sh",
                    "-c",
                    "dd if=/dev/random of=/tmp/bytes bs=1M count=20 status=none ; sha256sum /tmp/bytes",
                ]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            if status.exitCode != 0 {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            let output = String(data: buffer.data, encoding: .utf8)!
            let expected = String(output.split(separator: " ").first!)
            try await withThrowingTaskGroup(of: Void.self) { group in
                for i in 0...80 {
                    let idx = i
                    group.addTask {
                        let buffer = BufferWriter()
                        let exec = try await container.exec("exec-\(idx)") { config in
                            config.arguments = ["cat", "/tmp/bytes"]
                            config.stdout = buffer
                        }
                        try await exec.start()

                        let status = try await exec.wait()
                        if status.exitCode != 0 {
                            throw IntegrationError.assert(msg: "process \(idx) status \(status) != 0")
                        }

                        var hasher = SHA256()
                        hasher.update(data: buffer.data)
                        let hash = hasher.finalize().digestString.trimmingDigestPrefix
                        guard hash == expected else {
                            throw IntegrationError.assert(
                                msg: "process \(idx) output \(hash) != expected \(expected)")
                        }
                        try await exec.delete()
                    }
                }

                try await group.waitForAll()
            }
            try await exec.delete()

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        }
    }

    func testProcessUser() async throws {
        let id = "test-process-user"

        let bs = try await bootstrap(id)
        var buffer = BufferWriter()
        var container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/usr/bin/id"]
            config.process.user = .init(uid: 1, gid: 1, additionalGids: [1])
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        var status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        var expected = "uid=1(bin) gid=1(bin) groups=1(bin)"
        guard String(data: buffer.data, encoding: .utf8) == "\(expected)\n" else {
            throw IntegrationError.assert(
                msg: "process should have returned on stdout '\(expected)' != '\(String(data: buffer.data, encoding: .utf8)!)'")
        }

        buffer = BufferWriter()
        container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/usr/bin/id"]
            // Try some uid that doesn't exist. This is supported.
            config.process.user = .init(uid: 40000, gid: 40000)
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        expected = "uid=40000 gid=40000 groups=40000"
        guard String(data: buffer.data, encoding: .utf8) == "\(expected)\n" else {
            throw IntegrationError.assert(
                msg: "process should have returned on stdout '\(expected)' != '\(String(data: buffer.data, encoding: .utf8)!)'")
        }

        buffer = BufferWriter()
        container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/usr/bin/id"]
            // Try some uid that doesn't exist. This is supported.
            config.process.user = .init(username: "40000:40000")
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        expected = "uid=40000 gid=40000 groups=40000"
        guard String(data: buffer.data, encoding: .utf8) == "\(expected)\n" else {
            throw IntegrationError.assert(
                msg: "process should have returned on stdout '\(expected)' != '\(String(data: buffer.data, encoding: .utf8)!)'")
        }

        buffer = BufferWriter()
        container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/usr/bin/id"]
            // Now for our final trick, try and run a username that doesn't exist.
            config.process.user = .init(username: "thisdoesntexist")
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        do {
            try await container.start()
        } catch {
            return
        }
        throw IntegrationError.assert(msg: "container start should have failed")
    }

    // Ensure if we ask for a terminal we set TERM.
    func testProcessTtyEnvvar() async throws {
        let id = "test-process-tty-envvar"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["env"]
            config.process.terminal = true
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let str = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(
                msg: "failed to convert standard output to a UTF8 string")
        }

        let homeEnvvar = "TERM=xterm"
        guard str.contains(homeEnvvar) else {
            throw IntegrationError.assert(
                msg: "process should have TERM environment variable defined")
        }
    }

    // Make sure we set HOME by default if we can find it in /etc/passwd in the guest.
    func testProcessHomeEnvvar() async throws {
        let id = "test-process-home-envvar"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["env"]
            config.process.user = .init(uid: 0, gid: 0)
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let str = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(
                msg: "failed to convert standard output to a UTF8 string")
        }

        let homeEnvvar = "HOME=/root"
        guard str.contains(homeEnvvar) else {
            throw IntegrationError.assert(
                msg: "process should have HOME environment variable defined")
        }
    }

    func testProcessCustomHomeEnvvar() async throws {
        let id = "test-process-custom-home-envvar"

        let bs = try await bootstrap(id)
        let customHomeEnvvar = "HOME=/tmp/custom/home"
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sh", "-c", "echo HOME=$HOME"]
            config.process.environmentVariables.append(customHomeEnvvar)
            config.process.user = .init(uid: 0, gid: 0)
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard output.contains(customHomeEnvvar) else {
            throw IntegrationError.assert(msg: "process should have preserved custom HOME environment variable, expected \(customHomeEnvvar), got: \(output)")
        }
    }

    func testHostname() async throws {
        let id = "test-container-hostname"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/hostname"]
            config.hostname = "foo-bar"
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }
        let expected = "foo-bar"

        guard String(data: buffer.data, encoding: .utf8) == "\(expected)\n" else {
            throw IntegrationError.assert(
                msg: "process should have returned on stdout '\(expected)' != '\(String(data: buffer.data, encoding: .utf8)!)'")
        }
    }

    func testHostnameDefaultsToContainerID() async throws {
        let id = "test-container-hostname-default"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/hostname"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard String(data: buffer.data, encoding: .utf8) == "\(id)\n" else {
            throw IntegrationError.assert(
                msg: "hostname should default to container id '\(id)', got '\(String(data: buffer.data, encoding: .utf8)!)'")
        }
    }

    func testHostsFile() async throws {
        let id = "test-container-hosts-file"

        let bs = try await bootstrap(id)
        let entry = Hosts.Entry.localHostIPV4(comment: "Testaroo")
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat", "/etc/hosts"]
            config.hosts = Hosts(entries: [entry])
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        let expected = entry.rendered
        guard String(data: buffer.data, encoding: .utf8) == "\(expected)\n" else {
            throw IntegrationError.assert(
                msg: "process should have returned on stdout '\(expected)' != '\(String(data: buffer.data, encoding: .utf8)!)'")
        }
    }

    func testProcessStdin() async throws {
        let id = "test-container-stdin"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat"]
            config.process.stdin = StdinBuffer(data: "Hello from test".data(using: .utf8)!)
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }
        let expected = "Hello from test"

        guard String(data: buffer.data, encoding: .utf8) == "\(expected)" else {
            throw IntegrationError.assert(
                msg: "process should have returned on stdout '\(expected)' != '\(String(data: buffer.data, encoding: .utf8)!)'")
        }
    }

    func testMounts() async throws {
        let id = "test-cat-mount"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            let directory = try createMountDirectory()
            config.process.arguments = ["/bin/cat", "/mnt/hi.txt"]
            config.mounts.append(.share(source: directory.path, destination: "/mnt"))
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        let value = String(data: buffer.data, encoding: .utf8)
        guard value == "hello" else {
            throw IntegrationError.assert(
                msg: "process should have returned from file 'hello' != '\(String(data: buffer.data, encoding: .utf8)!)")

        }
    }

    #if os(macOS)
    func testNestedVirtualizationEnabled() async throws {
        let id = "test-nested-virt"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/true"]
            config.virtualization = true
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()
        } catch {
            if let err = error as? ContainerizationError {
                if err.code == .unsupported {
                    throw SkipTest(reason: err.message)
                }
            }
        }

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }
    }

    func testContainerManagerCreate() async throws {
        let id = "test-container-manager"

        let bs = try await bootstrap(id)

        var manager = try ContainerManager(vmm: bs.vmm)
        defer {
            try? manager.delete(id)
        }

        let buffer = BufferWriter()
        let container = try await manager.create(
            id,
            image: bs.image,
            rootfs: bs.rootfs
        ) { config in
            config.process.arguments = ["/bin/echo", "ContainerManager test"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        let output = String(data: buffer.data, encoding: .utf8)
        guard output == "ContainerManager test\n" else {
            throw IntegrationError.assert(
                msg: "process should have returned 'ContainerManager test' != '\(output ?? "nil")'")
        }
    }

    func testContainerStopIdempotency() async throws {
        let id = "test-container-stop-idempotency"

        let bs = try await bootstrap(id)

        var manager = try ContainerManager(vmm: bs.vmm)
        defer {
            try? manager.delete(id)
        }

        let buffer = BufferWriter()
        let container = try await manager.create(
            id,
            image: bs.image,
            rootfs: bs.rootfs
        ) { config in
            config.process.arguments = ["/bin/echo", "please stop me"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        try await container.stop()
        try await container.stop()

        let output = String(data: buffer.data, encoding: .utf8)
        guard output == "please stop me\n" else {
            throw IntegrationError.assert(
                msg: "process should have returned 'ContainerManager test' != '\(output ?? "nil")'")
        }
    }

    func testContainerReuse() async throws {
        let id = "test-container-reuse"

        let bs = try await bootstrap(id)

        var manager = try ContainerManager(vmm: bs.vmm)
        defer {
            try? manager.delete(id)
        }

        let buffer = BufferWriter()
        let container = try await manager.create(
            id,
            image: bs.image,
            rootfs: bs.rootfs
        ) { config in
            config.process.arguments = ["/bin/echo", "ContainerManager test"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        var status = try await container.wait()
        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }
        try await container.stop()

        try await container.create()
        try await container.start()

        // Wait for completion.. again.
        status = try await container.wait()
        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        let output = String(data: buffer.data, encoding: .utf8)
        let expected = "ContainerManager test\nContainerManager test\n"
        guard output == expected else {
            throw IntegrationError.assert(
                msg: "process should have returned '\(expected)' != '\(output ?? "nil")'")
        }
    }

    func testContainerDevConsole() async throws {
        let id = "test-container-devconsole"

        let bs = try await bootstrap(id)

        var manager = try ContainerManager(vmm: bs.vmm)
        defer {
            try? manager.delete(id)
        }

        let buffer = BufferWriter()
        let container = try await manager.create(
            id,
            image: bs.image,
            rootfs: bs.rootfs
        ) { config in
            // We mount devtmpfs by default, and while this includes creating
            // /dev/console typically that'll be pointing to /dev/hvc0 (the
            // virtio serial console). This is just a character device, so a trivial
            // way to check that our bind mounted console setup worked is by just
            // parsing `mount`'s output and looking for /dev/console as it wouldn't
            // be there normally without our dance.
            config.process.arguments = ["mount"]
            config.process.terminal = true
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()
        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let str = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(
                msg: "failed to convert standard output to a UTF8 string")
        }

        let devConsole = "/dev/console"
        guard str.contains(devConsole) else {
            throw IntegrationError.assert(
                msg: "process should have \(devConsole) in `mount` output")
        }
    }

    #endif

    func testContainerStatistics() async throws {
        let id = "test-container-statistics"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "infinity"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let stats = try await container.statistics()

            guard stats.id == id else {
                throw IntegrationError.assert(msg: "stats container ID '\(stats.id)' != '\(id)'")
            }

            guard let process = stats.process, process.current > 0 else {
                throw IntegrationError.assert(msg: "process count should be > 0, got \(stats.process?.current ?? 0)")
            }

            guard let memory = stats.memory, memory.usageBytes > 0 else {
                throw IntegrationError.assert(msg: "memory usage should be > 0, got \(stats.memory?.usageBytes ?? 0)")
            }

            guard let cpu = stats.cpu, cpu.usageUsec > 0 else {
                throw IntegrationError.assert(msg: "CPU usage should be > 0, got \(stats.cpu?.usageUsec ?? 0)")
            }

            print("Container statistics:")
            print("  Processes: \(process.current)")
            print("  Memory: \(memory.usageBytes) bytes")
            print("  CPU: \(cpu.usageUsec) usec")
            print("  Networks: \(stats.networks?.count ?? 0) interfaces")

            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCgroupLimits() async throws {
        let id = "test-cgroup-limits"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "infinity"]
            config.cpus = 2
            config.memoryInBytes = 512.mib()
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Start an exec with sleep infinity
            let sleepExec = try await container.exec("sleep-exec") { config in
                config.arguments = ["sleep", "infinity"]
            }
            try await sleepExec.start()

            // Verify we have 3 PIDs in cgroup.procs: init, exec sleep, and cat itself
            let procsBuffer = BufferWriter()
            let procsExec = try await container.exec("check-procs") { config in
                config.arguments = ["cat", "/sys/fs/cgroup/cgroup.procs"]
                config.stdout = procsBuffer
            }
            try await procsExec.start()
            var status = try await procsExec.wait()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "check-procs status \(status) != 0")
            }
            try await procsExec.delete()

            guard let procsContent = String(data: procsBuffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to parse cgroup.procs")
            }
            let pids = procsContent.split(separator: "\n").filter { !$0.isEmpty }
            guard pids.count == 3 else {
                throw IntegrationError.assert(msg: "expected 3 PIDs in cgroup.procs, got \(pids.count): \(procsContent)")
            }

            // Verify memory limit
            let memoryBuffer = BufferWriter()
            let memoryExec = try await container.exec("check-memory") { config in
                config.arguments = ["cat", "/sys/fs/cgroup/memory.max"]
                config.stdout = memoryBuffer
            }
            try await memoryExec.start()
            status = try await memoryExec.wait()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "check-memory status \(status) != 0")
            }
            try await memoryExec.delete()

            guard let memoryLimit = String(data: memoryBuffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) else {
                throw IntegrationError.assert(msg: "failed to parse memory.max")
            }
            let expectedMemory = "\(512.mib())"
            guard memoryLimit == expectedMemory else {
                throw IntegrationError.assert(msg: "memory.max \(memoryLimit) != expected \(expectedMemory)")
            }

            // Verify CPU limit
            let cpuBuffer = BufferWriter()
            let cpuExec = try await container.exec("check-cpu") { config in
                config.arguments = ["cat", "/sys/fs/cgroup/cpu.max"]
                config.stdout = cpuBuffer
            }
            try await cpuExec.start()
            status = try await cpuExec.wait()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "check-cpu status \(status) != 0")
            }
            try await cpuExec.delete()

            guard let cpuLimit = String(data: cpuBuffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) else {
                throw IntegrationError.assert(msg: "failed to parse cpu.max")
            }
            let expectedCpu = "200000 100000"  // 2 CPUs: quota=200000, period=100000
            guard cpuLimit == expectedCpu else {
                throw IntegrationError.assert(msg: "cpu.max '\(cpuLimit)' != expected '\(expectedCpu)'")
            }

            try await sleepExec.delete()

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testMemoryEventsOOMKill() async throws {
        let id = "test-memory-events-oom-kill"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "infinity"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Run a process that will exceed the memory limit and get OOM-killed
            let exec = try await container.exec("oom-trigger") { config in
                // First set a 2MB memory limit on the container's cgroup, then allocate more
                config.arguments = [
                    "sh",
                    "-c",
                    "echo 2097152 > /sys/fs/cgroup/memory.max && dd if=/dev/zero of=/dev/null bs=100M",
                ]
            }

            try await exec.start()
            let status = try await exec.wait()
            if status.exitCode == 0 {
                throw IntegrationError.assert(msg: "expected exit code > 0")
            }
            try await exec.delete()

            let stats = try await container.statistics(categories: .memoryEvents)

            guard let events = stats.memoryEvents else {
                throw IntegrationError.assert(msg: "expected memoryEvents to be present")
            }

            print("Memory events for container \(id):")
            print("  low: \(events.low)")
            print("  high: \(events.high)")
            print("  max: \(events.max)")
            print("  oom: \(events.oom)")
            print("  oomKill: \(events.oomKill)")

            guard events.oomKill > 0 else {
                throw IntegrationError.assert(msg: "expected oomKill > 0, got \(events.oomKill)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testNoSerialConsole() async throws {
        let id = "test-no-serial-console"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/true"]
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }
    }

    func testUnixSocketIntoGuest() async throws {
        let id = "test-unixsocket-into-guest"

        let bs = try await bootstrap(id)

        let hostSocketPath = try createHostUnixSocket()

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.sockets = [
                UnixSocketConfiguration(
                    source: URL(filePath: hostSocketPath),
                    destination: URL(filePath: "/tmp/test.sock"),
                    direction: .into
                )
            ]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Execute ls -l to check the socket exists and is indeed a socket
            let lsExec = try await container.exec("ls-socket") { config in
                config.arguments = ["ls", "-l", "/tmp/test.sock"]
                config.stdout = buffer
            }

            try await lsExec.start()
            let status = try await lsExec.wait()
            try await lsExec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls command failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert ls output to UTF8")
            }

            // Socket files in ls -l output start with 's'
            guard output.hasPrefix("s") else {
                throw IntegrationError.assert(
                    msg: "expected socket file (starting with 's'), got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    // NOTE: Once upon a time our guest agent created any proxied unix sockets at
    // a path that contained the container ID in it. The problem here is if the container
    // ID is comically long we exceed the max length of a unix domain socket path.
    func testUnixSocketIntoGuestLongContainerID() async throws {
        let id = "test-unixsocket-long-id-" + String(repeating: "a", count: 40)

        let bs = try await bootstrap(id)

        let hostSocketPath = try createHostUnixSocket()

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.sockets = [
                UnixSocketConfiguration(
                    source: URL(filePath: hostSocketPath),
                    destination: URL(filePath: "/tmp/test.sock"),
                    direction: .into
                )
            ]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let lsExec = try await container.exec("ls-socket") { config in
                config.arguments = ["ls", "-l", "/tmp/test.sock"]
                config.stdout = buffer
            }

            try await lsExec.start()
            let status = try await lsExec.wait()
            try await lsExec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls command failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert ls output to UTF8")
            }

            guard output.hasPrefix("s") else {
                throw IntegrationError.assert(
                    msg: "expected socket file (starting with 's'), got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testNonClosureConstructor() async throws {
        let id = "test-container-non-closure-constructor"

        let bs = try await bootstrap(id)
        let config = LinuxContainer.Configuration(
            process: LinuxProcessConfiguration(arguments: ["/bin/true"])
        )
        let container = try LinuxContainer(
            id,
            rootfs: bs.rootfs,
            vmm: bs.vmm,
            configuration: config
        )

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }
    }

    private func createHostUnixSocket() throws -> String {
        let dir = FileManager.default.uniqueTemporaryDirectory(create: true)
        let socketPath = dir.appendingPathComponent("test.sock").path

        let socket = try Socket(type: UnixType(path: socketPath))
        try socket.listen()

        return socketPath
    }

    private func createMountDirectory() throws -> URL {
        let dir = FileManager.default.uniqueTemporaryDirectory(create: true)
        try "hello".write(to: dir.appendingPathComponent("hi.txt"), atomically: true, encoding: .utf8)
        return dir
    }

    func testUnixSocketIntoGuestSymlink() async throws {
        let id = "test-unixsocket-into-guest-symlink"

        let bs = try await bootstrap(id)

        let hostSocketPath = try createHostUnixSocket()

        let buffer = BufferWriter()
        // Use /var/run/test.sock. Alpine has /var/run -> /run symlink
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.sockets = [
                UnixSocketConfiguration(
                    source: URL(filePath: hostSocketPath),
                    destination: URL(filePath: "/var/run/test.sock"),
                    direction: .into
                )
            ]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let lsExec = try await container.exec("ls-socket") { config in
                config.arguments = ["ls", "-l", "/var/run/test.sock"]
                config.stdout = buffer
            }

            try await lsExec.start()
            let status = try await lsExec.wait()
            try await lsExec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls command failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert ls output to UTF8")
            }

            // Socket files in ls -l output start with 's'
            guard output.hasPrefix("s") else {
                throw IntegrationError.assert(
                    msg: "expected socket file (starting with 's'), got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testBootLogFileHandle() async throws {
        let id = "test-bootlog-filehandle"

        let bs = try await bootstrap(id)

        // Create a pipe to capture boot log data
        let pipe = Pipe()
        let bootLog = BootLog.fileHandle(pipe.fileHandleForWriting)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/echo", "test complete"]
            config.bootLog = bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            try pipe.fileHandleForWriting.close()
            let bootLogData = try pipe.fileHandleForReading.readToEnd()
            guard let bootLogData = bootLogData, bootLogData.count > 0 else {
                throw IntegrationError.assert(
                    msg: "expected to receive boot log data from pipe, but got no data")
            }

            guard let bootLogString = String(data: bootLogData, encoding: .utf8) else {
                throw IntegrationError.assert(
                    msg: "failed to convert boot log data to UTF8 string")
            }

            guard bootLogString.count > 100 else {
                throw IntegrationError.assert(
                    msg: "boot log output smaller than expected: got \(bootLogString.count)")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testLargeStdioOutput() async throws {
        let id = "test-large-stdout-stderr-output"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let stdoutBuffer = DiscardingWriter()
            let stderrBuffer = DiscardingWriter()

            let exec = try await container.exec("large-output") { config in
                config.arguments = [
                    "sh",
                    "-c",
                    """
                    dd if=/dev/zero bs=1M count=250 status=none && \
                    dd if=/dev/zero bs=1M count=250 status=none >&2
                    """,
                ]
                config.stdout = stdoutBuffer
                config.stderr = stderrBuffer
            }

            let started = Date().timeIntervalSinceReferenceDate

            try await exec.start()
            let status = try await exec.wait()

            let lasted = Date().timeIntervalSinceReferenceDate - started
            print("Test \(id) finished process ingesting stdio in \(lasted)")

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec process status \(status) != 0")
            }

            try await exec.delete()

            let expectedSize = 250 * 1024 * 1024
            guard stdoutBuffer.count == expectedSize else {
                throw IntegrationError.assert(
                    msg: "stdout size \(stdoutBuffer.count) != expected \(expectedSize)")
            }

            guard stderrBuffer.count == expectedSize else {
                throw IntegrationError.assert(
                    msg: "stderr size \(stderrBuffer.count) != expected \(expectedSize)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testProcessDeleteIdempotency() async throws {
        let id = "test-process-delete-idempotency"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Create an exec process
            let exec = try await container.exec("test-exec") { config in
                config.arguments = ["/bin/true"]
            }

            try await exec.start()
            let status = try await exec.wait()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec process status \(status) != 0")
            }

            // Call delete twice to verify idempotency
            try await exec.delete()
            try await exec.delete()  // Should be a no-op

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testMultipleExecsWithoutDelete() async throws {
        let id = "test-multiple-execs-without-delete"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Create 3 exec processes without deleting them
            let exec1 = try await container.exec("exec-1") { config in
                config.arguments = ["/bin/true"]
            }
            try await exec1.start()
            let status1 = try await exec1.wait()
            guard status1.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec1 process status \(status1) != 0")
            }

            let exec2 = try await container.exec("exec-2") { config in
                config.arguments = ["/bin/true"]
            }
            try await exec2.start()
            let status2 = try await exec2.wait()
            guard status2.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec2 process status \(status2) != 0")
            }

            let exec3 = try await container.exec("exec-3") { config in
                config.arguments = ["/bin/true"]
            }
            try await exec3.start()
            let status3 = try await exec3.wait()
            guard status3.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec3 process status \(status3) != 0")
            }

            // Stop should handle cleanup of all exec processes gracefully
            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testNonExistentBinary() async throws {
        let id = "test-non-existent-binary"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["foo-bar-baz"]
            config.bootLog = bs.bootLog
        }

        try await container.create()
        do {
            try await container.start()
        } catch {
            return
        }
        try await container.stop()
        throw IntegrationError.assert(msg: "container start should have failed")
    }

    // MARK: - Capability Tests

    func testCapabilitiesSysAdmin() async throws {
        let id = "test-capabilities-sysadmin"

        let bs = try await bootstrap(id)

        // First test: without CAP_SYS_ADMIN (should be denied)
        let bufferDenied = BufferWriter()
        let containerWithoutSysAdmin = try LinuxContainer("\(id)-denied", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.capabilities = LinuxCapabilities()
            config.process.arguments = ["/bin/sh", "-c", "mount -t tmpfs tmpfs /tmp || echo 'mount failed as expected'"]
            config.process.stdout = bufferDenied
            config.bootLog = bs.bootLog
        }

        try await containerWithoutSysAdmin.create()
        try await containerWithoutSysAdmin.start()

        var status = try await containerWithoutSysAdmin.wait()
        try await containerWithoutSysAdmin.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container should have run successfully, got exit code \(status.exitCode)")
        }

        guard let outputDenied = String(data: bufferDenied.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard outputDenied.contains("mount failed as expected") else {
            throw IntegrationError.assert(msg: "expected mount failure message, got: \(outputDenied)")
        }

        // Second test: with CAP_SYS_ADMIN (should succeed)
        let containerWithSysAdmin = try LinuxContainer("\(id)-allowed", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.capabilities = LinuxCapabilities(capabilities: [.sysAdmin])
            config.process.arguments = ["/bin/sh", "-c", "mount -t tmpfs tmpfs /tmp"]
            config.bootLog = bs.bootLog
        }

        try await containerWithSysAdmin.create()
        try await containerWithSysAdmin.start()

        status = try await containerWithSysAdmin.wait()
        try await containerWithSysAdmin.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container with CAP_SYS_ADMIN should mount successfully, got exit code \(status.exitCode)")
        }
    }

    func testCapabilitiesNetAdmin() async throws {
        let id = "test-capabilities-netadmin"

        let bs = try await bootstrap(id)

        // First test: without CAP_NET_ADMIN (should be denied)
        let bufferDenied = BufferWriter()
        let containerWithoutNetAdmin = try LinuxContainer("\(id)-denied", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.capabilities = LinuxCapabilities()
            config.process.arguments = ["/bin/sh", "-c", "ip link set lo down 2>/dev/null || echo 'network operation denied as expected'"]
            config.process.stdout = bufferDenied
            config.bootLog = bs.bootLog
        }

        try await containerWithoutNetAdmin.create()
        try await containerWithoutNetAdmin.start()

        var status = try await containerWithoutNetAdmin.wait()
        try await containerWithoutNetAdmin.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container should handle network denial gracefully, got exit code \(status.exitCode)")
        }

        guard let outputDenied = String(data: bufferDenied.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard outputDenied.contains("network operation denied as expected") else {
            throw IntegrationError.assert(msg: "expected network denial message, got: \(outputDenied)")
        }

        // Second test: with CAP_NET_ADMIN (should succeed)
        let bufferAllowed = BufferWriter()
        let containerWithNetAdmin = try LinuxContainer("\(id)-allowed", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.capabilities = LinuxCapabilities(capabilities: [.netAdmin])
            config.process.arguments = ["/bin/sh", "-c", "ip link set lo down && ip link set lo up"]
            config.process.stdout = bufferAllowed
            config.bootLog = bs.bootLog
        }

        try await containerWithNetAdmin.create()
        try await containerWithNetAdmin.start()

        status = try await containerWithNetAdmin.wait()
        try await containerWithNetAdmin.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container with CAP_NET_ADMIN should perform network operations, got exit code \(status.exitCode)")
        }
    }

    func testCapabilitiesOCIDefault() async throws {
        let id = "test-capabilities-OCI-default"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            // Use default capability set
            config.process.capabilities = .defaultOCICapabilities
            config.process.arguments = ["/bin/sh", "-c", "echo 'Running with OCI default capabilities'"]
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container with OCI default capabilities should run, got exit code \(status.exitCode)")
        }
    }

    func testCapabilitiesAllCapabilities() async throws {
        let id = "test-capabilities-all"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.capabilities = .allCapabilities
            config.process.arguments = ["/bin/sh", "-c", "mount -t tmpfs tmpfs /tmp && ip link set lo down"]
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container with all capabilities should perform all operations, got exit code \(status.exitCode)")
        }
    }

    func testCapabilitiesFileOwnership() async throws {
        let id = "test-capabilities-chown"

        let bs = try await bootstrap(id)

        // First test: without CAP_CHOWN
        let bufferDenied = BufferWriter()
        let containerWithoutChown = try LinuxContainer("\(id)-denied", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.capabilities = LinuxCapabilities()
            config.process.arguments = ["/bin/sh", "-c", "touch /tmp/testfile && chown 1000:1000 /tmp/testfile 2>/dev/null || echo 'chown denied as expected'"]
            config.process.stdout = bufferDenied
            config.bootLog = bs.bootLog
        }

        try await containerWithoutChown.create()
        try await containerWithoutChown.start()

        var status = try await containerWithoutChown.wait()
        try await containerWithoutChown.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container should handle chown denial gracefully, got exit code \(status.exitCode)")
        }

        guard let outputDenied = String(data: bufferDenied.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard outputDenied.contains("chown denied as expected") else {
            throw IntegrationError.assert(msg: "expected chown denial message, got: \(outputDenied)")
        }

        // Second test: with CAP_CHOWN
        let bufferAllowed = BufferWriter()
        let containerWithChown = try LinuxContainer("\(id)-allowed", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.capabilities = LinuxCapabilities(capabilities: [.chown])
            config.process.arguments = ["/bin/sh", "-c", "touch /tmp/testfile && chown 1000:1000 /tmp/testfile"]
            config.process.stdout = bufferAllowed
            config.bootLog = bs.bootLog
        }

        try await containerWithChown.create()
        try await containerWithChown.start()

        status = try await containerWithChown.wait()
        try await containerWithChown.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "container with CAP_CHOWN should succeed, got exit code \(status.exitCode)")
        }
    }

    func testDefaultMaskedAndReadonlyPaths() async throws {
        let id = "test-masked-readonly-defaults"

        // A default container (default capabilities + default masked/readonly
        // paths) must have the OCI standard set enforced by vmexec without any
        // opt-in. Probe from inside the guest:
        //   1. readonlyPaths: writing under /proc/sys fails with EROFS. EROFS
        //      (not EPERM) proves the read-only remount rather than a mere
        //      capability denial — the default (restricted) caps already lack
        //      CAP_SYS_ADMIN, so a writable /proc/sys would fail with EPERM.
        //      The write is wrapped in a brace group so the shell's redirection
        //      failure ("can't create ...: Read-only file system") is captured:
        //      a trailing `2>&1` on the command misses it, because the failing
        //      `>` redirection aborts before `2>&1` is applied.
        //   2. maskedPaths: at least one default-masked path is mounted over
        //      (visible in /proc/self/mountinfo). Checked via mountinfo rather
        //      than reading the target, since some masked paths (e.g.
        //      /proc/kcore) require CAP_SYS_RAWIO to read and would appear empty
        //      even if masking were broken, yielding a false pass.
        let probe = """
            set -u
            rerr=$( { echo x > /proc/sys/kernel/hostname; } 2>&1 )
            case "$rerr" in
                *"Read-only file system"*) ;;
                *) echo "RO-FAIL: writing /proc/sys expected EROFS, got: ${rerr:-<write succeeded>}"; exit 1 ;;
            esac
            masked=0
            for p in /proc/kcore /proc/keys /proc/scsi /proc/sched_debug /sys/firmware /sys/devices/virtual/powercap; do
                grep -q " $p " /proc/self/mountinfo && masked=$((masked + 1))
            done
            if [ "$masked" -eq 0 ]; then
                echo "MASK-FAIL: no default masked path mounted"
                cat /proc/self/mountinfo
                exit 1
            fi
            echo "MASKED-RO-OK masked=$masked"
            """

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            // Intentionally leave config.maskedPaths / readonlyPaths /
            // process.capabilities untouched — the point is that the defaults
            // are secure out of the box.
            config.process.arguments = ["/bin/sh", "-c", probe]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        let output = String(data: buffer.data, encoding: .utf8) ?? "<non-utf8 output>"
        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "default masked/readonly enforcement failed (exit \(status.exitCode)): \(output)")
        }
        guard output.contains("MASKED-RO-OK") else {
            throw IntegrationError.assert(msg: "expected MASKED-RO-OK sentinel, got: \(output)")
        }
    }

    func testStat() async throws {
        let id = "test-stat"

        let bs = try await bootstrap(id)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        func assertExec(_ container: LinuxContainer, id: String, cmd: String) async throws {
            let exec = try await container.exec(id) { config in
                config.arguments = ["sh", "-c", cmd]
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "\(id) failed with exit code \(status.exitCode)")
            }
        }

        do {
            try await container.create()
            try await container.start()

            // regular file: "regular file" is exactly 12 bytes
            try await assertExec(container, id: "create-regular-file", cmd: "echo -n 'regular file' > /tmp/regular-file.txt")
            // directory
            try await assertExec(container, id: "create-dir", cmd: "mkdir /tmp/test-dir")
            // relative symlink so stat() resolves the target within the same directory
            try await assertExec(container, id: "create-symlink", cmd: "ln -s regular-file.txt /tmp/test-link")
            // FIFO
            try await assertExec(container, id: "create-fifo", cmd: "mkfifo /tmp/test-fifo")

            let vsock = try await container.dialVsock(port: 1024)
            let vminitd = try await Vminitd(connection: vsock, group: Self.eventLoop)

            let root = URL(filePath: container.root)

            // --- regular file ---
            let regularStat = try await vminitd.stat(path: root.appending(path: "tmp/regular-file.txt"))
            guard (regularStat.mode & UInt32(S_IFMT)) == S_IFREG else {
                throw IntegrationError.assert(msg: "regular file: expected S_IFREG, got mode 0x\(String(regularStat.mode, radix: 16))")
            }
            guard regularStat.size == 12 else {
                throw IntegrationError.assert(msg: "regular file: expected size 12, got \(regularStat.size)")
            }
            guard regularStat.ino > 0 else {
                throw IntegrationError.assert(msg: "regular file: expected non-zero inode, got \(regularStat.ino)")
            }
            guard regularStat.nlink >= 1 else {
                throw IntegrationError.assert(msg: "regular file: expected nlink >= 1, got \(regularStat.nlink)")
            }

            // --- directory ---
            let dirStat = try await vminitd.stat(path: root.appending(path: "tmp/test-dir"))
            guard (dirStat.mode & UInt32(S_IFMT)) == S_IFDIR else {
                throw IntegrationError.assert(msg: "directory: expected S_IFDIR, got mode 0x\(String(dirStat.mode, radix: 16))")
            }
            // A directory always has at least 2 hard links (. and its entry in the parent)
            guard dirStat.nlink >= 2 else {
                throw IntegrationError.assert(msg: "directory: expected nlink >= 2, got \(dirStat.nlink)")
            }

            // --- symlink ---
            // stat(2) follows symlinks, so the result reflects the target regular file
            let symlinkStat = try await vminitd.stat(path: root.appending(path: "tmp/test-link"))
            guard (symlinkStat.mode & UInt32(S_IFMT)) == S_IFREG else {
                throw IntegrationError.assert(msg: "symlink (followed): expected S_IFREG, got mode 0x\(String(symlinkStat.mode, radix: 16))")
            }
            guard symlinkStat.size == regularStat.size else {
                throw IntegrationError.assert(msg: "symlink (followed): expected size \(regularStat.size), got \(symlinkStat.size)")
            }

            // --- FIFO ---
            let fifoStat = try await vminitd.stat(path: root.appending(path: "tmp/test-fifo"))
            guard (fifoStat.mode & UInt32(S_IFMT)) == S_IFIFO else {
                throw IntegrationError.assert(msg: "FIFO: expected S_IFIFO, got mode 0x\(String(fifoStat.mode, radix: 16))")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyIn() async throws {
        let id = "test-copy-in"

        let bs = try await bootstrap(id)

        // Create a temp file on the host with known content
        let testContent = "Hello from the host! This is a copyIn test."
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("test-input.txt")
        try testContent.write(to: hostFile, atomically: true, encoding: .utf8)

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy the file into the container
            try await container.copyIn(
                from: hostFile,
                to: URL(filePath: "/tmp/copied-file.txt")
            )

            // Verify the file exists and has correct content
            let exec = try await container.exec("verify-copy") { config in
                config.arguments = ["cat", "/tmp/copied-file.txt"]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "cat command failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            guard output == testContent else {
                throw IntegrationError.assert(
                    msg: "copied file content mismatch: expected '\(testContent)', got '\(output)'")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyInFileToExistingDirectory() async throws {
        let id = "test-copy-in-file-to-dir"

        let bs = try await bootstrap(id)

        let testContent = "copy into an existing guest directory"
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("host-file.txt")
        try testContent.write(to: hostFile, atomically: true, encoding: .utf8)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let mkdir = try await container.exec("create-copy-target") { config in
                config.arguments = ["mkdir", "-p", "/tmp/copy-target"]
            }
            try await mkdir.start()
            let mkdirStatus = try await mkdir.wait()
            try await mkdir.delete()

            guard mkdirStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "mkdir failed with status \(mkdirStatus)")
            }

            try await container.copyIn(
                from: hostFile,
                to: URL(filePath: "/tmp/copy-target")
            )

            let buffer = BufferWriter()
            let verify = try await container.exec("verify-copy-target") { config in
                config.arguments = ["cat", "/tmp/copy-target/host-file.txt"]
                config.stdout = buffer
            }
            try await verify.start()
            let verifyStatus = try await verify.wait()
            try await verify.delete()

            guard verifyStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "cat copied file failed with status \(verifyStatus)")
            }
            guard String(data: buffer.data, encoding: .utf8) == testContent else {
                throw IntegrationError.assert(msg: "copied file should land under the existing destination directory")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyInFileToMissingDirectoryFails() async throws {
        let id = "test-copy-in-file-missing-dir"

        let bs = try await bootstrap(id)

        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("host-file.txt")
        try "missing destination directory".write(to: hostFile, atomically: true, encoding: .utf8)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            do {
                try await container.copyIn(
                    from: hostFile,
                    to: URL(filePath: "/tmp/missing-copy-target/")
                )
                throw IntegrationError.assert(msg: "copyIn should fail when copying a file to a missing destination directory")
            } catch let error as ContainerizationError where error.code == .invalidArgument {
                guard error.description.contains("destination directory does not exist") else {
                    throw IntegrationError.assert(msg: "unexpected copyIn error: \(error)")
                }
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyInDirectoryOverExistingFileFails() async throws {
        let id = "test-copy-in-dir-over-file"

        let bs = try await bootstrap(id)

        let hostDir = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("host-dir")
        try FileManager.default.createDirectory(at: hostDir, withIntermediateDirectories: true)
        try "directory content".write(to: hostDir.appendingPathComponent("file.txt"), atomically: true, encoding: .utf8)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let createFile = try await container.exec("create-existing-file") { config in
                config.arguments = ["sh", "-c", "echo -n existing > /tmp/existing-file"]
            }
            try await createFile.start()
            let createStatus = try await createFile.wait()
            try await createFile.delete()

            guard createStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "failed to create existing file, status \(createStatus)")
            }

            do {
                try await container.copyIn(
                    from: hostDir,
                    to: URL(filePath: "/tmp/existing-file")
                )
                throw IntegrationError.assert(msg: "copyIn should fail when copying a directory over an existing file")
            } catch let error as ContainerizationError where error.code == .invalidArgument {
                guard error.description.contains("cannot copy directory over existing file") else {
                    throw IntegrationError.assert(msg: "unexpected copyIn error: \(error)")
                }
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyOut() async throws {
        let id = "test-copy-out"

        let bs = try await bootstrap(id)

        let testContent = "Hello from the guest! This is a copyOut test."
        let hostDestination = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("test-output.txt")

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Create a file inside the container
            let exec = try await container.exec("create-file") { config in
                config.arguments = ["sh", "-c", "echo -n '\(testContent)' > /tmp/guest-file.txt"]
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "failed to create file in guest, status \(status)")
            }

            // Copy the file out of the container
            try await container.copyOut(
                from: URL(filePath: "/tmp/guest-file.txt"),
                to: hostDestination
            )

            // Verify the file was copied correctly
            let copiedContent = try String(contentsOf: hostDestination, encoding: .utf8)

            guard copiedContent == testContent else {
                throw IntegrationError.assert(
                    msg: "copied file content mismatch: expected '\(testContent)', got '\(copiedContent)'")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyLargeFile() async throws {
        let id = "test-copy-large-file"

        let bs = try await bootstrap(id)

        // Create a 10MB file on the host with a repeating pattern
        let fileSize = 10 * 1024 * 1024
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("large-file.bin")

        // Generate data with a repeating pattern
        let pattern = Data("ContainerizationCopyTest".utf8)
        var testData = Data(capacity: fileSize)
        while testData.count < fileSize {
            testData.append(pattern)
        }
        testData = testData.prefix(fileSize)
        try testData.write(to: hostFile)

        let hostDestination = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("large-file-out.bin")

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy large file into the container
            try await container.copyIn(
                from: hostFile,
                to: URL(filePath: "/tmp/large-file.bin")
            )

            // Copy it back out
            try await container.copyOut(
                from: URL(filePath: "/tmp/large-file.bin"),
                to: hostDestination
            )

            // Verify the content matches
            let copiedData = try Data(contentsOf: hostDestination)

            guard copiedData.count == testData.count else {
                throw IntegrationError.assert(
                    msg: "file size mismatch: expected \(testData.count), got \(copiedData.count)")
            }

            guard copiedData == testData else {
                throw IntegrationError.assert(msg: "file content mismatch after round-trip copy")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyInDirectory() async throws {
        let id = "test-copy-in-dir"

        let bs = try await bootstrap(id)

        // Create a temp directory with files, a subdirectory, and a symlink.
        let hostDir = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("test-dir")
        try FileManager.default.createDirectory(at: hostDir, withIntermediateDirectories: true)
        try "file1 content".write(to: hostDir.appendingPathComponent("file1.txt"), atomically: true, encoding: .utf8)

        let subDir = hostDir.appendingPathComponent("subdir")
        try FileManager.default.createDirectory(at: subDir, withIntermediateDirectories: true)
        try "file2 content".write(to: subDir.appendingPathComponent("file2.txt"), atomically: true, encoding: .utf8)

        try FileManager.default.createSymbolicLink(
            at: hostDir.appendingPathComponent("link.txt"),
            withDestinationURL: hostDir.appendingPathComponent("file1.txt")
        )

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy the directory into the container.
            try await container.copyIn(
                from: hostDir,
                to: URL(filePath: "/tmp/copied-dir")
            )

            // Verify file1.txt exists with correct content.
            let buffer1 = BufferWriter()
            let exec1 = try await container.exec("verify-file1") { config in
                config.arguments = ["cat", "/tmp/copied-dir/file1.txt"]
                config.stdout = buffer1
            }
            try await exec1.start()
            let status1 = try await exec1.wait()
            try await exec1.delete()

            guard status1.exitCode == 0 else {
                throw IntegrationError.assert(msg: "cat file1.txt failed with status \(status1)")
            }
            guard String(data: buffer1.data, encoding: .utf8) == "file1 content" else {
                throw IntegrationError.assert(msg: "file1.txt content mismatch")
            }

            // Verify subdir/file2.txt exists with correct content.
            let buffer2 = BufferWriter()
            let exec2 = try await container.exec("verify-file2") { config in
                config.arguments = ["cat", "/tmp/copied-dir/subdir/file2.txt"]
                config.stdout = buffer2
            }
            try await exec2.start()
            let status2 = try await exec2.wait()
            try await exec2.delete()

            guard status2.exitCode == 0 else {
                throw IntegrationError.assert(msg: "cat subdir/file2.txt failed with status \(status2)")
            }
            guard String(data: buffer2.data, encoding: .utf8) == "file2 content" else {
                throw IntegrationError.assert(msg: "subdir/file2.txt content mismatch")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyOutDirectory() async throws {
        let id = "test-copy-out-dir"

        let bs = try await bootstrap(id)

        let hostDestination = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("copied-out-dir")

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Create a directory structure inside the container.
            let exec = try await container.exec("create-dir") { config in
                config.arguments = [
                    "sh", "-c",
                    "mkdir -p /tmp/guest-dir/subdir && echo -n 'guest file1' > /tmp/guest-dir/file1.txt && echo -n 'guest file2' > /tmp/guest-dir/subdir/file2.txt",
                ]
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "failed to create directory in guest, status \(status)")
            }

            // Copy the directory out of the container.
            try await container.copyOut(
                from: URL(filePath: "/tmp/guest-dir"),
                to: hostDestination
            )

            // Verify file1.txt was copied correctly.
            let file1Content = try String(contentsOf: hostDestination.appendingPathComponent("file1.txt"), encoding: .utf8)
            guard file1Content == "guest file1" else {
                throw IntegrationError.assert(
                    msg: "file1.txt content mismatch: expected 'guest file1', got '\(file1Content)'")
            }

            // Verify subdir/file2.txt was copied correctly.
            let file2Content = try String(
                contentsOf: hostDestination.appendingPathComponent("subdir").appendingPathComponent("file2.txt"),
                encoding: .utf8
            )
            guard file2Content == "guest file2" else {
                throw IntegrationError.assert(
                    msg: "subdir/file2.txt content mismatch: expected 'guest file2', got '\(file2Content)'")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyEmptyFile() async throws {
        let id = "test-copy-empty-file"

        let bs = try await bootstrap(id)

        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("empty.txt")
        try Data().write(to: hostFile)

        let hostDestination = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("empty-out.txt")

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy empty file in.
            try await container.copyIn(
                from: hostFile,
                to: URL(filePath: "/tmp/empty.txt")
            )

            // Verify it exists and is empty in the guest.
            let buffer = BufferWriter()
            let exec = try await container.exec("verify-empty") { config in
                config.arguments = ["stat", "-c", "%s", "/tmp/empty.txt"]
                config.stdout = buffer
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "stat failed with status \(status)")
            }
            let sizeStr = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
            guard sizeStr == "0" else {
                throw IntegrationError.assert(msg: "empty file should have size 0, got '\(sizeStr ?? "nil")'")
            }

            // Copy it back out.
            try await container.copyOut(
                from: URL(filePath: "/tmp/empty.txt"),
                to: hostDestination
            )

            let copiedData = try Data(contentsOf: hostDestination)
            guard copiedData.isEmpty else {
                throw IntegrationError.assert(msg: "round-tripped empty file should be empty, got \(copiedData.count) bytes")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyEmptyDirectory() async throws {
        let id = "test-copy-empty-dir"

        let bs = try await bootstrap(id)

        let hostDir = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("empty-dir")
        try FileManager.default.createDirectory(at: hostDir, withIntermediateDirectories: true)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy empty directory in.
            try await container.copyIn(
                from: hostDir,
                to: URL(filePath: "/tmp/empty-dir")
            )

            // Verify it exists and is a directory.
            let buffer = BufferWriter()
            let exec = try await container.exec("verify-empty-dir") { config in
                config.arguments = ["sh", "-c", "test -d /tmp/empty-dir && ls -a /tmp/empty-dir | wc -l"]
                config.stdout = buffer
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "empty dir check failed with status \(status)")
            }

            // ls -a shows . and .. so count should be 2 for an empty dir.
            let countStr = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
            guard countStr == "2" else {
                throw IntegrationError.assert(msg: "empty dir should have 2 entries (. and ..), got '\(countStr ?? "nil")'")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyBinaryFile() async throws {
        let id = "test-copy-binary"

        let bs = try await bootstrap(id)

        // Create a file with all 256 byte values to test binary safety.
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("binary.bin")
        var binaryData = Data(count: 256 * 64)
        for i in 0..<binaryData.count {
            binaryData[i] = UInt8(i % 256)
        }
        try binaryData.write(to: hostFile)

        let hostDestination = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("binary-out.bin")

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            try await container.copyIn(
                from: hostFile,
                to: URL(filePath: "/tmp/binary.bin")
            )

            try await container.copyOut(
                from: URL(filePath: "/tmp/binary.bin"),
                to: hostDestination
            )

            let copiedData = try Data(contentsOf: hostDestination)

            guard copiedData.count == binaryData.count else {
                throw IntegrationError.assert(
                    msg: "binary file size mismatch: expected \(binaryData.count), got \(copiedData.count)")
            }
            guard copiedData == binaryData else {
                throw IntegrationError.assert(msg: "binary file content mismatch after round-trip")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyMultipleFiles() async throws {
        let id = "test-copy-multiple"

        let bs = try await bootstrap(id)

        let tmpDir = FileManager.default.uniqueTemporaryDirectory(create: true)
        let files = (0..<5).map { i in
            (
                host: tmpDir.appendingPathComponent("file\(i).txt"),
                guest: URL(filePath: "/tmp/multi/file\(i).txt"),
                content: "Content of file \(i) with some padding: \(String(repeating: "x", count: i * 1000))"
            )
        }

        for file in files {
            try file.content.write(to: file.host, atomically: true, encoding: .utf8)
        }

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy all files in sequentially.
            for file in files {
                try await container.copyIn(
                    from: file.host,
                    to: file.guest,
                    createParents: true
                )
            }

            // Verify each file.
            for (i, file) in files.enumerated() {
                let buffer = BufferWriter()
                let exec = try await container.exec("verify-\(i)") { config in
                    config.arguments = ["cat", file.guest.path]
                    config.stdout = buffer
                }
                try await exec.start()
                let status = try await exec.wait()
                try await exec.delete()

                guard status.exitCode == 0 else {
                    throw IntegrationError.assert(msg: "cat file\(i).txt failed with status \(status)")
                }
                let output = String(data: buffer.data, encoding: .utf8)
                guard output == file.content else {
                    throw IntegrationError.assert(msg: "file\(i).txt content mismatch")
                }
            }

            // Copy all files back out and verify.
            for (i, file) in files.enumerated() {
                let outPath = tmpDir.appendingPathComponent("out-file\(i).txt")
                try await container.copyOut(
                    from: file.guest,
                    to: outPath
                )
                let copiedContent = try String(contentsOf: outPath, encoding: .utf8)
                guard copiedContent == file.content else {
                    throw IntegrationError.assert(msg: "file\(i).txt round-trip content mismatch")
                }
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyDirectoryRoundTrip() async throws {
        let id = "test-copy-dir-rt"

        let bs = try await bootstrap(id)

        // Create a directory tree with varied content: nested dirs, different sizes, binary data.
        let hostDir = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("dir-rt")
        try FileManager.default.createDirectory(at: hostDir, withIntermediateDirectories: true)

        // Top-level files.
        try "top level".write(to: hostDir.appendingPathComponent("root.txt"), atomically: true, encoding: .utf8)
        try Data(repeating: 0xAB, count: 4096).write(to: hostDir.appendingPathComponent("binary.bin"))

        // Nested 3 levels deep.
        let deep = hostDir.appendingPathComponent("a").appendingPathComponent("b").appendingPathComponent("c")
        try FileManager.default.createDirectory(at: deep, withIntermediateDirectories: true)
        try "deep file".write(to: deep.appendingPathComponent("deep.txt"), atomically: true, encoding: .utf8)

        // Empty subdirectory.
        let emptySubdir = hostDir.appendingPathComponent("empty-sub")
        try FileManager.default.createDirectory(at: emptySubdir, withIntermediateDirectories: true)

        // File with special characters in content (not name).
        try "line1\nline2\ttab\r\nwindows\0null".write(
            to: hostDir.appendingPathComponent("special.txt"), atomically: true, encoding: .utf8)

        let hostDestination = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("dir-rt-out")

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy in.
            try await container.copyIn(
                from: hostDir,
                to: URL(filePath: "/tmp/dir-rt")
            )

            // Copy back out.
            try await container.copyOut(
                from: URL(filePath: "/tmp/dir-rt"),
                to: hostDestination
            )

            // Verify root.txt.
            let rootContent = try String(contentsOf: hostDestination.appendingPathComponent("root.txt"), encoding: .utf8)
            guard rootContent == "top level" else {
                throw IntegrationError.assert(msg: "root.txt mismatch: '\(rootContent)'")
            }

            // Verify binary.bin.
            let binaryContent = try Data(contentsOf: hostDestination.appendingPathComponent("binary.bin"))
            guard binaryContent == Data(repeating: 0xAB, count: 4096) else {
                throw IntegrationError.assert(msg: "binary.bin mismatch")
            }

            // Verify deep nested file.
            let deepOut =
                hostDestination
                .appendingPathComponent("a")
                .appendingPathComponent("b")
                .appendingPathComponent("c")
                .appendingPathComponent("deep.txt")
            let deepContent = try String(contentsOf: deepOut, encoding: .utf8)
            guard deepContent == "deep file" else {
                throw IntegrationError.assert(msg: "deep.txt mismatch: '\(deepContent)'")
            }

            // Verify empty subdirectory exists.
            var isDir: ObjCBool = false
            let emptySubdirExists = FileManager.default.fileExists(
                atPath: hostDestination.appendingPathComponent("empty-sub").path,
                isDirectory: &isDir
            )
            guard emptySubdirExists && isDir.boolValue else {
                throw IntegrationError.assert(msg: "empty-sub directory should exist after round trip")
            }

            // Verify special characters file.
            let specialContent = try String(
                contentsOf: hostDestination.appendingPathComponent("special.txt"), encoding: .utf8)
            guard specialContent == "line1\nline2\ttab\r\nwindows\0null" else {
                throw IntegrationError.assert(msg: "special.txt mismatch")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyInCreateParents() async throws {
        let id = "test-copy-parents"

        let bs = try await bootstrap(id)

        let testContent = "create parents test"
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("parents-test.txt")
        try testContent.write(to: hostFile, atomically: true, encoding: .utf8)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy to a deeply nested path that doesn't exist yet.
            try await container.copyIn(
                from: hostFile,
                to: URL(filePath: "/tmp/a/b/c/d/e/file.txt"),
                createParents: true
            )

            // Verify the file got there.
            let buffer = BufferWriter()
            let exec = try await container.exec("verify-parents") { config in
                config.arguments = ["cat", "/tmp/a/b/c/d/e/file.txt"]
                config.stdout = buffer
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "cat failed with status \(status)")
            }
            guard String(data: buffer.data, encoding: .utf8) == testContent else {
                throw IntegrationError.assert(msg: "content mismatch after copy with createParents")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyFilePermissions() async throws {
        let id = "test-copy-perms"

        let bs = try await bootstrap(id)

        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("perms-test.sh")
        try "#!/bin/sh\necho hello".write(to: hostFile, atomically: true, encoding: .utf8)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Copy with executable permissions.
            try await container.copyIn(
                from: hostFile,
                to: URL(filePath: "/tmp/perms-test.sh"),
                mode: 0o755
            )

            // Verify the file is executable by running it.
            let buffer = BufferWriter()
            let exec = try await container.exec("run-script") { config in
                config.arguments = ["/tmp/perms-test.sh"]
                config.stdout = buffer
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "script execution failed with status \(status)")
            }
            let output = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
            guard output == "hello" else {
                throw IntegrationError.assert(msg: "script output mismatch: '\(output ?? "nil")'")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testCopyLargeDirectory() async throws {
        let id = "test-copy-large-dir"

        let bs = try await bootstrap(id)

        // Create a directory with many files to stress the archive path.
        let hostDir = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("large-dir")
        try FileManager.default.createDirectory(at: hostDir, withIntermediateDirectories: true)

        let fileCount = 100
        for i in 0..<fileCount {
            let content = "File \(i): \(String(repeating: String(i), count: 512))"
            try content.write(
                to: hostDir.appendingPathComponent("file-\(String(format: "%03d", i)).txt"),
                atomically: true,
                encoding: .utf8
            )
        }

        let hostDestination = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("large-dir-out")

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            try await container.copyIn(
                from: hostDir,
                to: URL(filePath: "/tmp/large-dir")
            )

            // Verify file count in the guest.
            let buffer = BufferWriter()
            let exec = try await container.exec("count-files") { config in
                config.arguments = ["sh", "-c", "ls /tmp/large-dir/*.txt | wc -l"]
                config.stdout = buffer
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls | wc -l failed with status \(status)")
            }
            let countStr = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
            guard countStr == "\(fileCount)" else {
                throw IntegrationError.assert(msg: "expected \(fileCount) files in guest, got '\(countStr ?? "nil")'")
            }

            // Copy back out.
            try await container.copyOut(
                from: URL(filePath: "/tmp/large-dir"),
                to: hostDestination
            )

            // Spot-check a few files.
            for i in [0, fileCount / 2, fileCount - 1] {
                let expectedContent = "File \(i): \(String(repeating: String(i), count: 512))"
                let actualContent = try String(
                    contentsOf: hostDestination.appendingPathComponent("file-\(String(format: "%03d", i)).txt"),
                    encoding: .utf8
                )
                guard actualContent == expectedContent else {
                    throw IntegrationError.assert(msg: "file-\(String(format: "%03d", i)).txt content mismatch after round trip")
                }
            }

            // Verify total file count on host.
            let outFiles = try FileManager.default.contentsOfDirectory(atPath: hostDestination.path)
            guard outFiles.count == fileCount else {
                throw IntegrationError.assert(
                    msg: "expected \(fileCount) files on host after copyOut, got \(outFiles.count)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testReadOnlyRootfs() async throws {
        let id = "test-readonly-rootfs"

        let bs = try await bootstrap(id)
        var rootfs = bs.rootfs
        rootfs.options.append("ro")
        let container = try LinuxContainer(id, rootfs: rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["touch", "/testfile"]
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        // touch should fail on a read-only rootfs
        guard status.exitCode != 0 else {
            throw IntegrationError.assert(msg: "touch should have failed on read-only rootfs")
        }
    }

    func testReadOnlyRootfsHostsFileWritten() async throws {
        let id = "test-readonly-rootfs-hosts"

        let bs = try await bootstrap(id)
        var rootfs = bs.rootfs
        rootfs.options.append("ro")
        let buffer = BufferWriter()
        let entry = Hosts.Entry.localHostIPV4(comment: "ReadOnlyTest")
        let container = try LinuxContainer(id, rootfs: rootfs, vmm: bs.vmm) { config in
            // Verify /etc/hosts was written before rootfs was remounted read-only
            config.process.arguments = ["cat", "/etc/hosts"]
            config.process.stdout = buffer
            config.hosts = Hosts(entries: [entry])
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "cat /etc/hosts failed with status \(status)")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard output.contains("ReadOnlyTest") else {
            throw IntegrationError.assert(msg: "expected /etc/hosts to contain our entry, got: \(output)")
        }
    }

    func testReadOnlyRootfsDNSConfigured() async throws {
        let id = "test-readonly-rootfs-dns"

        let bs = try await bootstrap(id)
        var rootfs = bs.rootfs
        rootfs.options.append("ro")
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: rootfs, vmm: bs.vmm) { config in
            // Verify /etc/resolv.conf was written before rootfs was remounted read-only
            config.process.arguments = ["cat", "/etc/resolv.conf"]
            config.process.stdout = buffer
            config.dns = DNS(nameservers: ["8.8.8.8", "8.8.4.4"])
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "cat /etc/resolv.conf failed with status \(status)")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard output.contains("8.8.8.8") && output.contains("8.8.4.4") else {
            throw IntegrationError.assert(msg: "expected /etc/resolv.conf to contain DNS servers, got: \(output)")
        }
    }

    func testLargeStdinInput() async throws {
        let id = "test-large-stdin-input"

        let bs = try await bootstrap(id)

        let inputSize = 128 * 1024
        let inputData = Data(repeating: 0x41, count: inputSize)  // 'A' repeated

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat"]
            config.process.stdin = StdinBuffer(data: inputData)
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            guard buffer.data.count == inputSize else {
                throw IntegrationError.assert(
                    msg: "output size \(buffer.data.count) != input size \(inputSize)")
            }

            guard buffer.data == inputData else {
                throw IntegrationError.assert(msg: "output data does not match input data")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testExecLargeStdinInput() async throws {
        let id = "test-exec-large-stdin-input"
        let bs = try await bootstrap(id)

        let inputSize = 128 * 1024
        let inputData = Data(repeating: 0x42, count: inputSize)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let buffer = BufferWriter()
            let exec = try await container.exec("large-stdin-exec") { config in
                config.arguments = ["cat"]
                config.stdin = StdinBuffer(data: inputData)
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec status \(status) != 0")
            }

            guard buffer.data.count == inputSize else {
                throw IntegrationError.assert(msg: "output size \(buffer.data.count) != \(inputSize)")
            }

            guard buffer.data == inputData else {
                throw IntegrationError.assert(msg: "output data mismatch")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testExecCustomPathResolution() async throws {
        let id = "test-exec-custom-path"
        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Create a script in a non-standard directory
            let setup = try await container.exec("setup") { config in
                config.arguments = [
                    "sh", "-c",
                    "mkdir -p /tmp/custom-bin && printf '#!/bin/sh\\necho CUSTOM_PATH_OK' > /tmp/custom-bin/mytest && chmod +x /tmp/custom-bin/mytest",
                ]
            }
            try await setup.start()
            let setupStatus = try await setup.wait()
            try await setup.delete()
            guard setupStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "setup failed: \(setupStatus)")
            }

            // Exec bare command with custom PATH — this exercises ExecCommand.swift
            let buffer = BufferWriter()
            let exec = try await container.exec("custom-path") { config in
                config.arguments = ["mytest"]
                config.environmentVariables = ["PATH=/tmp/custom-bin"]
                config.stdout = buffer
            }
            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec with custom PATH failed: \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to read output")
            }
            guard output.contains("CUSTOM_PATH_OK") else {
                throw IntegrationError.assert(msg: "expected CUSTOM_PATH_OK, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testStdinExplicitClose() async throws {
        let id = "test-stdin-explicit-close"
        let bs = try await bootstrap(id)

        let inputData = "explicit close test\n".data(using: .utf8)!
        let buffer = BufferWriter()

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let exec = try await container.exec("stdin-close-exec") { config in
                config.arguments = ["head", "-n", "1"]
                config.stdin = StdinBuffer(data: inputData)
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec status \(status) != 0")
            }

            guard buffer.data == inputData else {
                throw IntegrationError.assert(msg: "output mismatch")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testStdinBinaryData() async throws {
        let id = "test-stdin-binary-data"
        let bs = try await bootstrap(id)

        var inputData = Data()
        for i: UInt8 in 0...255 {
            inputData.append(contentsOf: [UInt8](repeating: i, count: 256))
        }

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat"]
            config.process.stdin = StdinBuffer(data: inputData)
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            guard buffer.data == inputData else {
                throw IntegrationError.assert(msg: "binary data mismatch")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testStdinMultipleChunks() async throws {
        let id = "test-stdin-multiple-chunks"
        let bs = try await bootstrap(id)

        let chunks = (0..<10).map { i in
            Data(repeating: UInt8(0x30 + i), count: 10 * 1024)
        }
        let expectedData = chunks.reduce(Data()) { $0 + $1 }

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat"]
            config.process.stdin = ChunkedStdinBuffer(chunks: chunks, delayMs: 10)
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            guard buffer.data == expectedData else {
                throw IntegrationError.assert(msg: "chunked data mismatch")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testStdinVeryLarge() async throws {
        let id = "test-stdin-very-large"
        let bs = try await bootstrap(id)

        let inputSize = 10 * 1024 * 1024
        let inputData = Data(repeating: 0x58, count: inputSize)

        let stdout = DiscardingWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["wc", "-c"]
            config.process.stdin = StdinBuffer(data: inputData)
            config.process.stdout = stdout
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            guard stdout.count > 0 else {
                throw IntegrationError.assert(msg: "no output from wc")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    #if os(macOS)
    @available(macOS 26.0, *)
    func testInterfaceMTU() async throws {
        let id = "test-interface-mtu"
        let bs = try await bootstrap(id)

        let customMTU: UInt32 = 1400
        var network = try VmnetNetwork()
        defer {
            try? network.releaseInterface(id)
        }

        guard let interface = try network.createInterface(id, mtu: customMTU) else {
            throw IntegrationError.assert(msg: "failed to create network interface")
        }

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.interfaces = [interface]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Check the MTU of eth0
            let exec = try await container.exec("check-mtu") { config in
                config.arguments = ["ip", "link", "show", "eth0"]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip link show failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            // Output should contain "mtu 1400"
            guard output.contains("mtu \(customMTU)") else {
                throw IntegrationError.assert(
                    msg: "expected MTU \(customMTU) in output, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    #endif

    func testSingleFileMount() async throws {
        let id = "test-single-file-mount"

        let bs = try await bootstrap(id)

        // Create a temp file with known content
        let testContent = "Hello from single file mount!"
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("config.txt")
        try testContent.write(to: hostFile, atomically: true, encoding: .utf8)

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat", "/etc/myconfig.txt"]
            // Mount a single file using virtiofs share
            config.mounts.append(.share(source: hostFile.path, destination: "/etc/myconfig.txt"))
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            guard output == testContent else {
                throw IntegrationError.assert(
                    msg: "expected '\(testContent)', got '\(output)'")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testSingleFileMountReadOnly() async throws {
        let id = "test-single-file-mount-readonly"

        let bs = try await bootstrap(id)

        // Create a temp file with known content
        let testContent = "Read-only file content"
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("readonly.txt")
        try testContent.write(to: hostFile, atomically: true, encoding: .utf8)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            // Mount a single file as read-only
            config.mounts.append(.share(source: hostFile.path, destination: "/etc/readonly.txt", options: ["ro"]))
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // First verify we can read the file
            let readBuffer = BufferWriter()
            let readExec = try await container.exec("read-file") { config in
                config.arguments = ["cat", "/etc/readonly.txt"]
                config.stdout = readBuffer
            }
            try await readExec.start()
            var status = try await readExec.wait()
            try await readExec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "read status \(status) != 0")
            }

            guard String(data: readBuffer.data, encoding: .utf8) == testContent else {
                throw IntegrationError.assert(msg: "file content mismatch")
            }

            // Now try to write to the file - should fail
            let writeExec = try await container.exec("write-file") { config in
                config.arguments = ["sh", "-c", "echo 'modified' > /etc/readonly.txt"]
            }
            try await writeExec.start()
            status = try await writeExec.wait()
            try await writeExec.delete()

            // Write should fail on a read-only mount
            guard status.exitCode != 0 else {
                throw IntegrationError.assert(msg: "write should have failed on read-only mount")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testSingleFileMountWriteBack() async throws {
        let id = "test-single-file-mount-write-back"

        let bs = try await bootstrap(id)

        // Create a temp file with initial content
        let initialContent = "initial content"
        let hostFile = FileManager.default.uniqueTemporaryDirectory(create: true)
            .appendingPathComponent("writeable.txt")
        try initialContent.write(to: hostFile, atomically: true, encoding: .utf8)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            // Mount a single file (writable by default)
            config.mounts.append(.share(source: hostFile.path, destination: "/etc/writeable.txt"))
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Write new content from inside the container
            let newContent = "modified from container"
            let writeExec = try await container.exec("write-file") { config in
                config.arguments = ["sh", "-c", "echo -n '\(newContent)' > /etc/writeable.txt"]
            }
            try await writeExec.start()
            let status = try await writeExec.wait()
            try await writeExec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "write status \(status) != 0")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()

            let hostContent = try String(contentsOf: hostFile, encoding: .utf8)
            guard hostContent == newContent else {
                throw IntegrationError.assert(
                    msg: "expected '\(newContent)' on host, got '\(hostContent)'")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testSingleFileMountSymlink() async throws {
        let id = "test-single-file-mount-symlink"

        let bs = try await bootstrap(id)

        // Create a temp directory with a real file and a symlink to it
        let tempDir = FileManager.default.uniqueTemporaryDirectory(create: true)
        let realFile = tempDir.appendingPathComponent("realfile.txt")
        let symlinkFile = tempDir.appendingPathComponent("symlink.txt")

        let initialContent = "content via symlink"
        try initialContent.write(to: realFile, atomically: true, encoding: .utf8)
        try FileManager.default.createSymbolicLink(at: symlinkFile, withDestinationURL: realFile)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            // Mount the symlink (should resolve to real file)
            config.mounts.append(.share(source: symlinkFile.path, destination: "/etc/config.txt"))
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Read the file to verify content
            let readBuffer = BufferWriter()
            let readExec = try await container.exec("read-file") { config in
                config.arguments = ["cat", "/etc/config.txt"]
                config.stdout = readBuffer
            }
            try await readExec.start()
            var status = try await readExec.wait()
            try await readExec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "read status \(status) != 0")
            }

            guard String(data: readBuffer.data, encoding: .utf8) == initialContent else {
                throw IntegrationError.assert(msg: "content mismatch on read")
            }

            // Write new content from container
            let newContent = "modified via symlink mount"
            let writeExec = try await container.exec("write-file") { config in
                config.arguments = ["sh", "-c", "echo -n '\(newContent)' > /etc/config.txt"]
            }
            try await writeExec.start()
            status = try await writeExec.wait()
            try await writeExec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "write status \(status) != 0")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()

            // Verify the REAL file (not symlink) was modified on the host
            let hostContent = try String(contentsOf: realFile, encoding: .utf8)
            guard hostContent == newContent else {
                throw IntegrationError.assert(
                    msg: "expected '\(newContent)' in real file, got '\(hostContent)'")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testRLimitOpenFiles() async throws {
        let id = "test-rlimit-open-files"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sh", "-c", "ulimit -n"]
            config.process.rlimits = [
                LinuxRLimit(kind: .openFiles, hard: 2048, soft: 1024)
            ]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let output = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        // ulimit -n returns the soft limit
        guard output == "1024" else {
            throw IntegrationError.assert(msg: "expected soft limit '1024', got '\(output)'")
        }
    }

    func testRLimitMultiple() async throws {
        let id = "test-rlimit-multiple"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            // Read /proc/self/limits to verify multiple rlimits are set
            config.process.arguments = ["cat", "/proc/self/limits"]
            config.process.rlimits = [
                LinuxRLimit(kind: .openFiles, hard: 4096, soft: 2048),
                LinuxRLimit(kind: .stackSize, hard: 16_777_216, soft: 8_388_608),
                LinuxRLimit(kind: .coreFileSize, hard: 0, soft: 0),
            ]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        // Parse /proc/self/limits and verify the values
        // Format: "Limit Name                Soft Limit           Hard Limit           Units"
        let lines = output.split(separator: "\n")

        // Helper to find and verify a limit line
        func verifyLimit(name: String, expectedSoft: String, expectedHard: String) throws {
            guard let line = lines.first(where: { $0.contains(name) }) else {
                throw IntegrationError.assert(msg: "limit '\(name)' not found in output")
            }
            let parts = line.split(whereSeparator: { $0.isWhitespace }).map(String.init)
            // The line format varies, but soft and hard are typically the last numeric values before units
            guard parts.contains(expectedSoft) && parts.contains(expectedHard) else {
                throw IntegrationError.assert(
                    msg: "limit '\(name)' expected soft=\(expectedSoft) hard=\(expectedHard), got: \(line)")
            }
        }

        try verifyLimit(name: "Max open files", expectedSoft: "2048", expectedHard: "4096")
        try verifyLimit(name: "Max stack size", expectedSoft: "8388608", expectedHard: "16777216")
        try verifyLimit(name: "Max core file size", expectedSoft: "0", expectedHard: "0")
    }

    func testRLimitExec() async throws {
        let id = "test-rlimit-exec"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Exec a process with rlimits set
            let buffer = BufferWriter()
            let exec = try await container.exec("rlimit-exec") { config in
                config.arguments = ["sh", "-c", "ulimit -n"]
                config.rlimits = [
                    LinuxRLimit(kind: .openFiles, hard: 512, soft: 256)
                ]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec status \(status) != 0")
            }

            guard let output = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) else {
                throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
            }

            guard output == "256" else {
                throw IntegrationError.assert(msg: "expected soft limit '256', got '\(output)'")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testDuplicateVirtiofsMount() async throws {
        let id = "test-duplicate-virtiofs-mount"

        let bs = try await bootstrap(id)

        // Create a temp directory with a file
        let sharedDir = FileManager.default.uniqueTemporaryDirectory(create: true)
        try "shared content".write(to: sharedDir.appendingPathComponent("data.txt"), atomically: true, encoding: .utf8)

        let buffer1 = BufferWriter()
        let buffer2 = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            // Mount the same source directory to two different destinations
            config.mounts.append(.share(source: sharedDir.path, destination: "/mnt1"))
            config.mounts.append(.share(source: sharedDir.path, destination: "/mnt2"))
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Verify both mounts work. Read from /mnt1, then /mnt2
            let exec1 = try await container.exec("read-mnt1") { config in
                config.arguments = ["cat", "/mnt1/data.txt"]
                config.stdout = buffer1
            }
            try await exec1.start()
            var status = try await exec1.wait()
            try await exec1.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "read from /mnt1 failed with status \(status)")
            }

            guard String(data: buffer1.data, encoding: .utf8) == "shared content" else {
                throw IntegrationError.assert(msg: "unexpected content from /mnt1")
            }

            let exec2 = try await container.exec("read-mnt2") { config in
                config.arguments = ["cat", "/mnt2/data.txt"]
                config.stdout = buffer2
            }
            try await exec2.start()
            status = try await exec2.wait()
            try await exec2.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "read from /mnt2 failed with status \(status)")
            }

            guard String(data: buffer2.data, encoding: .utf8) == "shared content" else {
                throw IntegrationError.assert(msg: "unexpected content from /mnt2")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testDuplicateVirtiofsMountViaSymlink() async throws {
        let id = "test-duplicate-virtiofs-mount-symlink"

        let bs = try await bootstrap(id)

        // Create a temp directory with a file, and a symlink to the same directory
        let tempDir = FileManager.default.uniqueTemporaryDirectory(create: true)
        let realDir = tempDir.appendingPathComponent("realdir")
        let symlinkDir = tempDir.appendingPathComponent("symlinkdir")

        try FileManager.default.createDirectory(at: realDir, withIntermediateDirectories: true)
        try "symlink test content".write(to: realDir.appendingPathComponent("file.txt"), atomically: true, encoding: .utf8)
        try FileManager.default.createSymbolicLink(at: symlinkDir, withDestinationURL: realDir)

        let buffer1 = BufferWriter()
        let buffer2 = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.mounts.append(.share(source: realDir.path, destination: "/mnt1"))
            config.mounts.append(.share(source: symlinkDir.path, destination: "/mnt2"))
            config.bootLog = bs.bootLog
        }

        do {
            // This should succeed as the symlink should resolve to the same directory
            try await container.create()
            try await container.start()

            let exec1 = try await container.exec("read-mnt1") { config in
                config.arguments = ["cat", "/mnt1/file.txt"]
                config.stdout = buffer1
            }
            try await exec1.start()
            var status = try await exec1.wait()
            try await exec1.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "read from /mnt1 failed with status \(status)")
            }

            guard String(data: buffer1.data, encoding: .utf8) == "symlink test content" else {
                throw IntegrationError.assert(msg: "unexpected content from /mnt1")
            }

            // Verify mount via symlink works now
            let exec2 = try await container.exec("read-mnt2") { config in
                config.arguments = ["cat", "/mnt2/file.txt"]
                config.stdout = buffer2
            }
            try await exec2.start()
            status = try await exec2.wait()
            try await exec2.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "read from /mnt2 failed with status \(status)")
            }

            guard String(data: buffer2.data, encoding: .utf8) == "symlink test content" else {
                throw IntegrationError.assert(msg: "unexpected content from /mnt2")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testWritableLayer() async throws {
        let id = "test-writable-layer"

        let bs = try await bootstrap(id)

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(FilePath(writableLayerPath.absolutePath()), minDiskSize: 512.mib())
        try filesystem.close()
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            // Write a file, then read it back to verify writes work
            config.process.arguments = ["/bin/sh", "-c", "echo 'writable layer test' > /tmp/testfile && cat /tmp/testfile"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard output.trimmingCharacters(in: .whitespacesAndNewlines) == "writable layer test" else {
            throw IntegrationError.assert(msg: "unexpected output: \(output)")
        }
    }

    // Validates the on-disk structure of a journaled EXT4 image on the host before
    // attempting a container mount. This catches geometry mismatches (superblock block
    // count vs. physical file size) and missing journal metadata without requiring
    // e2fsck to be present in the container image.
    //
    // Uses raw values for internal constants because integration tests cannot use
    // @testable import: CompatFeature.hasJournal = 0x4, EXT4.JournalInode = 8.
    private func verifyJournalFilesystem(
        at path: URL,
        minDiskSize: UInt64,
        expectedMountOpts: UInt32
    ) throws {
        let attrs = try FileManager.default.attributesOfItem(atPath: path.absolutePath())
        guard let fileSize = attrs[.size] as? UInt64 else {
            throw IntegrationError.assert(msg: "could not read file size for \(path.lastPathComponent)")
        }
        let reader = try EXT4.EXT4Reader(blockDevice: FilePath(path.absolutePath()))
        let sb = reader.superBlock
        let blocksCount = UInt64(sb.blocksCountLow) | (UInt64(sb.blocksCountHigh) << 32)
        let blockSize = UInt64(sb.blockSize)
        guard fileSize == blocksCount * blockSize else {
            throw IntegrationError.assert(
                msg: "geometry mismatch: fileSize=\(fileSize), blocksCount=\(blocksCount), blockSize=\(blockSize)")
        }
        guard fileSize > minDiskSize else {
            throw IntegrationError.assert(
                msg: "journal did not grow the image: fileSize=\(fileSize), minDiskSize=\(minDiskSize)")
        }
        guard sb.featureCompat & 0x4 != 0 else {
            throw IntegrationError.assert(
                msg: "COMPAT_HAS_JOURNAL not set in featureCompat (0x\(String(sb.featureCompat, radix: 16)))")
        }
        guard sb.journalInum == 8 else {
            throw IntegrationError.assert(msg: "journalInum=\(sb.journalInum), expected 8")
        }
        guard sb.defaultMountOpts == expectedMountOpts else {
            throw IntegrationError.assert(
                msg: "defaultMountOpts=0x\(String(sb.defaultMountOpts, radix: 16)), expected 0x\(String(expectedMountOpts, radix: 16)))")
        }
    }

    func testWritableLayerJournalWriteback() async throws {
        let id = "test-writable-layer-journal-writeback"
        let bs = try await bootstrap(id)

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(
            FilePath(writableLayerPath.absolutePath()),
            minDiskSize: 512.mib(),
            journal: .init(defaultMode: .writeback)
        )
        try filesystem.close()
        // 0x0060 = data=writeback | barrier
        try verifyJournalFilesystem(at: writableLayerPath, minDiskSize: 512.mib(), expectedMountOpts: 0x0060)
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sh", "-c", "echo 'journal writeback' > /tmp/testfile && cat /tmp/testfile"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()
        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }
        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }
        guard output.trimmingCharacters(in: .whitespacesAndNewlines) == "journal writeback" else {
            throw IntegrationError.assert(msg: "unexpected output: \(output)")
        }
    }

    func testWritableLayerJournalOrdered() async throws {
        let id = "test-writable-layer-journal-ordered"
        let bs = try await bootstrap(id)

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(
            FilePath(writableLayerPath.absolutePath()),
            minDiskSize: 512.mib(),
            journal: .init(defaultMode: .ordered)
        )
        try filesystem.close()
        // 0x0040 = data=ordered | barrier
        try verifyJournalFilesystem(at: writableLayerPath, minDiskSize: 512.mib(), expectedMountOpts: 0x0040)
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sh", "-c", "echo 'journal ordered' > /tmp/testfile && cat /tmp/testfile"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()
        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }
        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }
        guard output.trimmingCharacters(in: .whitespacesAndNewlines) == "journal ordered" else {
            throw IntegrationError.assert(msg: "unexpected output: \(output)")
        }
    }

    func testWritableLayerJournalData() async throws {
        let id = "test-writable-layer-journal-data"
        let bs = try await bootstrap(id)

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(
            FilePath(writableLayerPath.absolutePath()),
            minDiskSize: 512.mib(),
            journal: .init(defaultMode: .journal)
        )
        try filesystem.close()
        // 0x0020 = data=journal | barrier
        try verifyJournalFilesystem(at: writableLayerPath, minDiskSize: 512.mib(), expectedMountOpts: 0x0020)
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sh", "-c", "echo 'journal data' > /tmp/testfile && cat /tmp/testfile"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()
        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }
        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }
        guard output.trimmingCharacters(in: .whitespacesAndNewlines) == "journal data" else {
            throw IntegrationError.assert(msg: "unexpected output: \(output)")
        }
    }

    func testWritableLayerPreservesLowerLayer() async throws {
        let id = "test-writable-layer-preserves-lower"

        let bs = try await bootstrap(id)

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(FilePath(writableLayerPath.absolutePath()), minDiskSize: 512.mib())
        try filesystem.close()
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        // Get the size of /bin/sh before any modifications
        let buffer1 = BufferWriter()
        let container1 = try LinuxContainer("\(id)-1", rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            // Modify a file in /bin. This should go in the writable layer.
            config.process.arguments = ["/bin/sh", "-c", "ls -la /bin/sh && echo 'modified' > /bin/test-file"]
            config.process.stdout = buffer1
            config.bootLog = bs.bootLog
        }

        try await container1.create()
        try await container1.start()
        let status1 = try await container1.wait()
        try await container1.stop()

        guard status1.exitCode == 0 else {
            throw IntegrationError.assert(msg: "first container failed with status \(status1)")
        }

        // Now run a second container with the SAME rootfs but without the writable layer
        // The /bin/test-file should NOT exist because it was written to the writable layer
        let buffer2 = BufferWriter()
        let container2 = try LinuxContainer("\(id)-2", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sh", "-c", "test -f /bin/test-file && echo 'exists' || echo 'not-exists'"]
            config.process.stdout = buffer2
            config.bootLog = bs.bootLog
        }

        try await container2.create()
        try await container2.start()
        let status2 = try await container2.wait()
        try await container2.stop()

        guard status2.exitCode == 0 else {
            throw IntegrationError.assert(msg: "second container failed with status \(status2)")
        }

        guard let output2 = String(data: buffer2.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard output2.trimmingCharacters(in: .whitespacesAndNewlines) == "not-exists" else {
            throw IntegrationError.assert(msg: "expected 'not-exists' but got: \(output2)")
        }
    }

    func testWritableLayerReadsFromLower() async throws {
        let id = "test-writable-layer-reads-lower"

        let bs = try await bootstrap(id)

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(FilePath(writableLayerPath.absolutePath()), minDiskSize: 512.mib())
        try filesystem.close()
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            config.process.arguments = ["head", "-1", "/etc/passwd"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        // Alpine's first line of /etc/passwd should be root
        guard output.hasPrefix("root:") else {
            throw IntegrationError.assert(msg: "expected /etc/passwd to start with 'root:', got: \(output)")
        }
    }

    func testWritableLayerWithReadOnlyLower() async throws {
        let id = "test-writable-layer-ro-lower"

        let bs = try await bootstrap(id)
        var rootfs = bs.rootfs
        rootfs.options.append("ro")

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(FilePath(writableLayerPath.absolutePath()), minDiskSize: 512.mib())
        try filesystem.close()
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            // Even though lower layer is ro, writes should succeed via overlay
            config.process.arguments = ["/bin/sh", "-c", "echo 'overlay write test' > /tmp/test && cat /tmp/test"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard output.trimmingCharacters(in: .whitespacesAndNewlines) == "overlay write test" else {
            throw IntegrationError.assert(msg: "unexpected output: \(output)")
        }
    }

    func testWritableLayerSize() async throws {
        let id = "test-writable-layer-size"

        let bs = try await bootstrap(id)

        // Create a 1 GiB writable layer
        let expectedSizeBytes: UInt64 = 1.gib()
        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(FilePath(writableLayerPath.absolutePath()), minDiskSize: expectedSizeBytes)
        try filesystem.close()
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            // Use df to check the available space on the root filesystem
            // The overlay will report the size of the upper layer's backing store
            config.process.arguments = ["/bin/sh", "-c", "df -B1 / | tail -1 | awk '{print $2}'"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard let reportedSize = UInt64(output.trimmingCharacters(in: .whitespacesAndNewlines)) else {
            throw IntegrationError.assert(msg: "failed to parse df output as UInt64: \(output)")
        }

        // The reported size should be close to our expected size (within 10%)
        let minExpected: UInt64 = (expectedSizeBytes * 90) / 100
        let maxExpected: UInt64 = (expectedSizeBytes * 110) / 100

        guard reportedSize >= minExpected && reportedSize <= maxExpected else {
            throw IntegrationError.assert(msg: "expected size ~\(expectedSizeBytes) bytes, but df reported \(reportedSize) bytes")
        }
    }

    func testWritableLayerWithDNSAndHosts() async throws {
        let id = "test-writable-layer-dns-hosts"

        let bs = try await bootstrap(id)

        let writableLayerPath = Self.testDir.appending(component: "\(id)-writable.ext4")
        try? FileManager.default.removeItem(at: writableLayerPath)
        let filesystem = try EXT4.Formatter(FilePath(writableLayerPath.absolutePath()), minDiskSize: 512.mib())
        try filesystem.close()
        let writableLayer = Mount.block(
            format: "ext4",
            source: writableLayerPath.absolutePath(),
            destination: "/",
            options: []
        )

        let buffer = BufferWriter()
        let dnsEntry = "8.8.8.8"
        let hostsEntry = Hosts.Entry.localHostIPV4(comment: "WritableLayerTest")
        let container = try LinuxContainer(id, rootfs: bs.rootfs, writableLayer: writableLayer, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sh", "-c", "cat /etc/resolv.conf && echo '---' && cat /etc/hosts"]
            config.process.stdout = buffer
            config.dns = DNS(nameservers: [dnsEntry])
            config.hosts = Hosts(entries: [hostsEntry])
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process failed with status \(status)")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        guard output.contains(dnsEntry) else {
            throw IntegrationError.assert(msg: "expected /etc/resolv.conf to contain \(dnsEntry), got: \(output)")
        }

        guard output.contains("WritableLayerTest") else {
            throw IntegrationError.assert(msg: "expected /etc/hosts to contain our entry, got: \(output)")
        }
    }

    func testFrozenExt4Clone() async throws {
        let id = "test-frozen-ext4-clone"
        let bs = try await bootstrap(id)

        let diskImageURL = Self.testDir.appending(component: "\(id)-data.ext4")
        try? FileManager.default.removeItem(at: diskImageURL)

        let filesystem = try EXT4.Formatter(FilePath(diskImageURL.absolutePath()), minDiskSize: 64.mib())
        try filesystem.close()

        let cloneImageURL = Self.testDir.appending(component: "\(id)-data-clone.ext4")
        try? FileManager.default.removeItem(at: cloneImageURL)

        let writerContainer = try LinuxContainer("\(id)-writer", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.mounts.append(
                Mount.block(
                    format: "ext4",
                    source: diskImageURL.absolutePath(),
                    destination: "/data"
                ))
            config.bootLog = bs.bootLog
        }

        do {
            try await writerContainer.create()
            try await writerContainer.start()

            try await writerContainer.filesystemOperation(operation: .freeze, path: "/data")

            let writeExec = try await writerContainer.exec("write-hello") { config in
                config.arguments = ["/bin/sh", "-c", "echo hello > /data/hello.txt"]
            }
            try await writeExec.start()
            let writeStatus = try await writeExec.wait()
            try await writeExec.delete()
            guard writeStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "write exec failed with status \(writeStatus)")
            }

            try FileManager.default.copyItem(at: diskImageURL, to: cloneImageURL)

            try await writerContainer.filesystemOperation(operation: .thaw, path: "/data")

            try await writerContainer.kill(.kill)
            _ = try await writerContainer.wait()
            try await writerContainer.stop()
        } catch {
            try? await writerContainer.filesystemOperation(operation: .thaw, path: "/data")
            try? await writerContainer.stop()
            throw error
        }

        let verifyContainer = try LinuxContainer("\(id)-reader", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.mounts.append(
                Mount.block(
                    format: "ext4",
                    source: cloneImageURL.absolutePath(),
                    destination: "/data"
                ))
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await verifyContainer.create()
            try await verifyContainer.start()

            let mountBuffer = BufferWriter()
            let mountExec = try await verifyContainer.exec("verify-mount") { config in
                config.arguments = ["/bin/sh", "-c", "grep ' /data ' /proc/mounts"]
                config.stdout = mountBuffer
            }
            try await mountExec.start()
            var status = try await mountExec.wait()
            try await mountExec.delete()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "failed to verify /data mount, status \(status)")
            }

            let mountOutput = String(decoding: mountBuffer.data, as: UTF8.self)
            guard mountOutput.contains(" /data ") && mountOutput.contains(" ext4 ") else {
                throw IntegrationError.assert(msg: "expected ext4 mount at /data, got: \(mountOutput)")
            }

            let lsBuffer = BufferWriter()
            let lsExec = try await verifyContainer.exec("verify-no-hello") { config in
                config.arguments = ["ls", "-1", "/data"]
                config.stdout = lsBuffer
            }
            try await lsExec.start()
            status = try await lsExec.wait()
            try await lsExec.delete()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls /data failed with status \(status)")
            }

            let lsOutput = String(decoding: lsBuffer.data, as: UTF8.self)
            let listedFiles = Set(lsOutput.split(whereSeparator: \.isNewline).map(String.init))
            guard !listedFiles.contains("hello.txt") else {
                throw IntegrationError.assert(msg: "expected cloned /data to not contain hello.txt, got: \(lsOutput)")
            }

            try await verifyContainer.kill(.kill)
            _ = try await verifyContainer.wait()
            try await verifyContainer.stop()
        } catch {
            try? await verifyContainer.stop()
            throw error
        }
    }

    func testTrimExt4Clone() async throws {
        let id = "test-trim-ext4-clone"
        let bs = try await bootstrap(id)

        let diskImageURL = Self.testDir.appending(component: "\(id)-data.ext4")
        try? FileManager.default.removeItem(at: diskImageURL)

        let filesystem = try EXT4.Formatter(FilePath(diskImageURL.absolutePath()), minDiskSize: 64.mib())
        try filesystem.close()

        let cloneImageURL = Self.testDir.appending(component: "\(id)-data-clone.ext4")
        try? FileManager.default.removeItem(at: cloneImageURL)

        let writerContainer = try LinuxContainer("\(id)-writer", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.mounts.append(
                Mount.block(
                    format: "ext4",
                    source: diskImageURL.absolutePath(),
                    destination: "/data"
                ))
            config.bootLog = bs.bootLog
        }

        do {
            try await writerContainer.create()
            try await writerContainer.start()

            let writeExec = try await writerContainer.exec("write-temp") { config in
                config.arguments = [
                    "/bin/sh",
                    "-c",
                    "dd if=/dev/zero of=/data/trim.dat bs=1M count=8 status=none && sync && rm /data/trim.dat && sync",
                ]
            }
            try await writeExec.start()
            let writeStatus = try await writeExec.wait()
            try await writeExec.delete()
            guard writeStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "trim setup exec failed with status \(writeStatus)")
            }

            try await writerContainer.filesystemOperation(operation: .trim, path: "/data")

            try FileManager.default.copyItem(at: diskImageURL, to: cloneImageURL)

            try await writerContainer.kill(.kill)
            _ = try await writerContainer.wait()
            try await writerContainer.stop()
        } catch {
            try? await writerContainer.stop()
            throw error
        }

        let verifyContainer = try LinuxContainer("\(id)-reader", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.mounts.append(
                Mount.block(
                    format: "ext4",
                    source: cloneImageURL.absolutePath(),
                    destination: "/data"
                ))
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await verifyContainer.create()
            try await verifyContainer.start()

            let mountBuffer = BufferWriter()
            let mountExec = try await verifyContainer.exec("verify-mount") { config in
                config.arguments = ["/bin/sh", "-c", "grep ' /data ' /proc/mounts"]
                config.stdout = mountBuffer
            }
            try await mountExec.start()
            var status = try await mountExec.wait()
            try await mountExec.delete()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "failed to verify /data mount, status \(status)")
            }

            let mountOutput = String(decoding: mountBuffer.data, as: UTF8.self)
            guard mountOutput.contains(" /data ") && mountOutput.contains(" ext4 ") else {
                throw IntegrationError.assert(msg: "expected ext4 mount at /data, got: \(mountOutput)")
            }

            let lsBuffer = BufferWriter()
            let lsExec = try await verifyContainer.exec("verify-no-hello") { config in
                config.arguments = ["ls", "-1", "/data"]
                config.stdout = lsBuffer
            }
            try await lsExec.start()
            status = try await lsExec.wait()
            try await lsExec.delete()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls /data failed with status \(status)")
            }

            let lsOutput = String(decoding: lsBuffer.data, as: UTF8.self)
            let listedFiles = Set(lsOutput.split(whereSeparator: \.isNewline).map(String.init))
            guard !listedFiles.contains("trim.dat") else {
                throw IntegrationError.assert(msg: "expected cloned /data to not contain trim.dat, got: \(lsOutput)")
            }

            try await verifyContainer.kill(.kill)
            _ = try await verifyContainer.wait()
            try await verifyContainer.stop()
        } catch {
            try? await verifyContainer.stop()
            throw error
        }
    }

    func testUseInitBasic() async throws {
        let id = "test-use-init-basic"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/echo", "hello from init"]
            config.process.stdout = buffer
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard String(data: buffer.data, encoding: .utf8) == "hello from init\n" else {
            throw IntegrationError.assert(
                msg: "expected 'hello from init', got '\(String(data: buffer.data, encoding: .utf8) ?? "nil")'")
        }
    }

    func testUseInitExitCodePropagation() async throws {
        let id = "test-use-init-exit-code"

        let bs = try await bootstrap(id)

        // Test exit code 0
        var container = try LinuxContainer("\(id)-success", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/true"]
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()
        var status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "expected exit code 0, got \(status.exitCode)")
        }

        // Test non-zero exit code
        container = try LinuxContainer("\(id)-failure", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/false"]
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()
        status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 1 else {
            throw IntegrationError.assert(msg: "expected exit code 1, got \(status.exitCode)")
        }

        // Test custom exit code
        container = try LinuxContainer("\(id)-custom", rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sh", "-c", "exit 42"]
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()
        status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 42 else {
            throw IntegrationError.assert(msg: "expected exit code 42, got \(status.exitCode)")
        }
    }

    func testUseInitSignalForwarding() async throws {
        let id = "test-use-init-signal"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "300"]
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            try await Task.sleep(for: .milliseconds(100))

            try await container.kill(.term)

            let status = try await container.wait(timeoutInSeconds: 5)
            try await container.stop()

            // SIGTERM should result in exit code 128 + 15 = 143
            guard status.exitCode == 143 else {
                throw IntegrationError.assert(msg: "expected exit code 143 (SIGTERM), got \(status.exitCode)")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testUseInitZombieReaping() async throws {
        let id = "test-use-init-zombie-reaping"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            // This script creates an orphaned process that init must reap.
            // The subshell exits immediately, orphaning the sleep process.
            // Init should reap it when it exits.
            config.process.arguments = [
                "/bin/sh", "-c",
                """
                # Create orphans: subshell exits before its children
                (/bin/sleep 0.1 &)
                (/bin/sleep 0.1 &)
                # Wait for orphans to complete
                /bin/sleep 0.3
                # Check for zombie processes (Z state)
                zombies=$(ps -eo stat 2>/dev/null | grep -c '^Z' || echo 0)
                echo "zombie_count:$zombies"
                """,
            ]
            config.process.stdout = buffer
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            // Should report 0 zombies
            guard output.contains("zombie_count:0") else {
                throw IntegrationError.assert(msg: "expected zero zombies, got: \(output)")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testUseInitWithTerminal() async throws {
        let id = "test-use-init-terminal"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sh", "-c", "tty && echo 'has tty'"]
            config.process.terminal = true
            config.process.stdout = buffer
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert output to UTF8")
        }

        guard output.contains("has tty") else {
            throw IntegrationError.assert(msg: "expected 'has tty' in output, got: \(output)")
        }
    }

    func testUseInitWithStdin() async throws {
        let id = "test-use-init-stdin"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat"]
            config.process.stdin = StdinBuffer(data: "input through init\n".data(using: .utf8)!)
            config.process.stdout = buffer
            config.useInit = true
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard String(data: buffer.data, encoding: .utf8) == "input through init\n" else {
            throw IntegrationError.assert(
                msg: "expected 'input through init', got '\(String(data: buffer.data, encoding: .utf8) ?? "nil")'")
        }
    }

    #if os(macOS)
    @available(macOS 26.0, *)
    func testNetworkingDisabled() async throws {
        let id = "test-networking-disabled"
        let bs = try await bootstrap(id)

        let network = try VmnetNetwork()
        var manager = try ContainerManager(vmm: bs.vmm, network: network)
        defer {
            try? manager.delete(id)
        }

        let buffer = BufferWriter()
        let container = try await manager.create(
            id,
            image: bs.image,
            rootfs: bs.rootfs,
            networking: false
        ) { config in
            config.process.arguments = ["ls", "-1", "/sys/class/net/"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls /sys/class/net/ failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            // With networking disabled check we don't have an eth0.
            let interfaces = output.trimmingCharacters(in: .whitespacesAndNewlines)
                .split(separator: "\n")
                .map { $0.trimmingCharacters(in: .whitespaces) }

            guard !interfaces.contains("eth0") else {
                throw IntegrationError.assert(
                    msg: "expected no 'eth0' interface")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testNetworkingEnabled() async throws {
        let id = "test-networking-enabled"
        let bs = try await bootstrap(id)

        let network = try VmnetNetwork()
        var manager = try ContainerManager(vmm: bs.vmm, network: network)
        defer {
            try? manager.delete(id)
        }

        let buffer = BufferWriter()
        let container = try await manager.create(
            id,
            image: bs.image,
            rootfs: bs.rootfs
        ) { config in
            config.process.arguments = ["ls", "-1", "/sys/class/net/"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ls /sys/class/net/ failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            // With networking enabled (default), eth0 should be present alongside lo
            let interfaces = Set(
                output.trimmingCharacters(in: .whitespacesAndNewlines)
                    .split(separator: "\n")
                    .map { $0.trimmingCharacters(in: .whitespaces) }
            )
            guard interfaces.contains("lo") else {
                throw IntegrationError.assert(msg: "expected 'lo' interface, got: \(interfaces)")
            }
            guard interfaces.contains("eth0") else {
                throw IntegrationError.assert(msg: "expected 'eth0' interface, got: \(interfaces)")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testNetworkingEnabledIPv6() async throws {
        let id = "test-networking-enabled-ipv6"
        let bs = try await bootstrap(id)

        let network = try VmnetNetwork()
        var manager = try ContainerManager(vmm: bs.vmm, network: network)
        defer {
            try? manager.delete(id)
        }

        let buffer = BufferWriter()
        let container = try await manager.create(
            id,
            image: bs.image,
            rootfs: bs.rootfs
        ) { config in
            config.process.arguments = ["ip", "-6", "addr", "show", "eth0", "scope", "global"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip -6 addr show failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            guard output.contains("inet6 fd") else {
                throw IntegrationError.assert(
                    msg: "expected a global-scope IPv6 address on eth0, got: \(output)")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testIPv6AddressAdd() async throws {
        let id = "test-ipv6-address"
        let bs = try await bootstrap(id)

        // Pin the v6 prefix so the allocator's first allocation yields fd00::2.
        var network = try VmnetNetwork(prefixV6: try CIDRv6("fd00::/64"))
        defer {
            try? network.releaseInterface(id)
        }

        guard let interface = try network.createInterface(id) else {
            throw IntegrationError.assert(msg: "failed to create network interface")
        }

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.interfaces = [interface]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Check that the IPv6 address was assigned to eth0.
            let exec = try await container.exec("check-ipv6") { config in
                config.arguments = ["ip", "-6", "addr", "show", "eth0"]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip -6 addr show failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            guard output.contains("fd00::2") else {
                throw IntegrationError.assert(
                    msg: "expected fd00::2 in output, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testIPv6DefaultRoute() async throws {
        let id = "test-ipv6-default-route"
        let bs = try await bootstrap(id)

        // Pin the network's v6 prefix so the gateway is deterministically fd00::1
        // and the allocator's first allocation yields fd00::2.
        var network = try VmnetNetwork(prefixV6: try CIDRv6("fd00::/64"))
        defer {
            try? network.releaseInterface(id)
        }

        guard let interface = try network.createInterface(id) else {
            throw IntegrationError.assert(msg: "failed to create network interface")
        }

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.interfaces = [interface]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Inspect IPv6 routes inside the container.
            let exec = try await container.exec("check-v6-route") { config in
                config.arguments = ["ip", "-6", "route", "show"]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip -6 route show failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            // The default v6 route must point at the gateway we configured, on eth0.
            guard output.contains("default via fd00::1 dev eth0") else {
                throw IntegrationError.assert(
                    msg: "expected 'default via fd00::1 dev eth0' in v6 routes, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testIPv6GatewayOutsideSubnet() async throws {
        let id = "test-ipv6-gateway-outside-subnet"
        let bs = try await bootstrap(id)

        // Address in fd00::/120, gateway in fd01::/120 — subnets don't overlap, so the
        // LinuxContainer wiring must add a /128 link route to the gateway before the
        // default route. The two prefixes are independent so we drive this directly
        // via NATInterface rather than the VmnetNetwork allocator (which always
        // derives the gateway from the network's own prefix).
        let interface = NATInterface(
            ipv4Address: try CIDRv4("192.0.2.2/24"),
            ipv4Gateway: try IPv4Address("192.0.2.1"),
            ipv6Address: try CIDRv6("fd00::2/120"),
            ipv6Gateway: try IPv6Address("fd01::1"))

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.interfaces = [interface]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let exec = try await container.exec("check-v6-routes") { config in
                config.arguments = ["ip", "-6", "route", "show"]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip -6 route show failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            // Both the link-scoped route to the gateway AND the default via that gateway
            // must be present. Without the link route, the kernel would refuse the default.
            // Match the link route on a line that starts with the gateway address (no "via")
            // so it can't be satisfied by a substring of the default-via line.
            let lines = output.split(separator: "\n").map(String.init)
            let hasLinkRoute = lines.contains { $0.hasPrefix("fd01::1 ") && $0.contains("dev eth0") && !$0.contains("via") }
            guard hasLinkRoute else {
                throw IntegrationError.assert(
                    msg: "expected an on-link route 'fd01::1 ... dev eth0' (no 'via') in v6 routes, got: \(output)")
            }
            guard output.contains("default via fd01::1 dev eth0") else {
                throw IntegrationError.assert(
                    msg: "expected 'default via fd01::1 dev eth0' in v6 routes, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testIPv6OnlyDefaultRoute() async throws {
        let id = "test-ipv6-only-default-route"
        let bs = try await bootstrap(id)

        // Construct a NATInterface with a nil IPv4 gateway and a v6 gateway, so
        // LinuxContainer takes the no-v4-gateway branch in setupInterface. The v4
        // address comes from TEST-NET-1; nothing in the test traffics over v4.
        let interface = NATInterface(
            ipv4Address: try CIDRv4("192.0.2.2/24"),
            ipv4Gateway: nil,
            ipv6Address: try CIDRv6("fd00::2/64"),
            ipv6Gateway: try IPv6Address("fd00::1"))

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.interfaces = [interface]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let exec = try await container.exec("check-v6-route") { config in
                config.arguments = ["ip", "-6", "route", "show"]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip -6 route show failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            guard output.contains("default via fd00::1 dev eth0") else {
                throw IntegrationError.assert(
                    msg: "expected 'default via fd00::1 dev eth0' in v6 routes when ipv4Gateway is nil, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testIPv6OnlyGatewayOutsideSubnet() async throws {
        let id = "test-ipv6-only-gateway-outside-subnet"
        let bs = try await bootstrap(id)

        // No v4 gateway AND v6 gateway is outside the v6 subnet. Exercises
        // setupInterface's "no v4 gateway, but v6 link route required before
        // v6 default route" branch — the exact bug the helper extraction fixed.
        let interface = NATInterface(
            ipv4Address: try CIDRv4("192.0.2.2/24"),
            ipv4Gateway: nil,
            ipv6Address: try CIDRv6("fd00::2/120"),
            ipv6Gateway: try IPv6Address("fd01::1"))

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.interfaces = [interface]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let exec = try await container.exec("check-v6-routes") { config in
                config.arguments = ["ip", "-6", "route", "show"]
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip -6 route show failed with status \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert output to UTF8")
            }

            // Both the on-link route to the gateway AND the default via it must be present.
            // Without the link route the kernel rejects the default — that was the bug.
            let lines = output.split(separator: "\n").map(String.init)
            let hasLinkRoute = lines.contains { $0.hasPrefix("fd01::1 ") && $0.contains("dev eth0") && !$0.contains("via") }
            guard hasLinkRoute else {
                throw IntegrationError.assert(
                    msg: "expected an on-link route 'fd01::1 ... dev eth0' (no 'via') in v6 routes, got: \(output)")
            }
            guard output.contains("default via fd01::1 dev eth0") else {
                throw IntegrationError.assert(
                    msg: "expected 'default via fd01::1 dev eth0' in v6 routes, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    @available(macOS 26.0, *)
    func testIPv6DualStack() async throws {
        let id = "test-ipv6-dual-stack"
        let bs = try await bootstrap(id)

        // Pin the network's v6 prefix so the gateway is deterministically fd00::1
        // and the allocator's first allocation yields fd00::2.
        var network = try VmnetNetwork(prefixV6: try CIDRv6("fd00::/64"))
        defer {
            try? network.releaseInterface(id)
        }

        guard let interface = try network.createInterface(id) else {
            throw IntegrationError.assert(msg: "failed to create network interface")
        }

        // Capture the v4 address vmnet allocated so we can assert it ends up on eth0.
        let expectedV4 = interface.ipv4Address.address.description

        let addrBuffer = BufferWriter()
        let routeBuffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.interfaces = [interface]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // `ip addr show` (no family flag) lists both v4 and v6.
            let addrExec = try await container.exec("check-dual-stack-addr") { config in
                config.arguments = ["ip", "addr", "show", "eth0"]
                config.stdout = addrBuffer
            }
            try await addrExec.start()
            let addrStatus = try await addrExec.wait()
            try await addrExec.delete()

            guard addrStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip addr show failed with status \(addrStatus)")
            }

            guard let addrOutput = String(data: addrBuffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert addr output to UTF8")
            }

            guard addrOutput.contains(expectedV4) else {
                throw IntegrationError.assert(
                    msg: "expected v4 address \(expectedV4) on eth0, got: \(addrOutput)")
            }
            guard addrOutput.contains("fd00::2") else {
                throw IntegrationError.assert(
                    msg: "expected v6 address fd00::2 on eth0, got: \(addrOutput)")
            }

            // The dual-stack default routes must both be installed.
            let routeExec = try await container.exec("check-dual-stack-route") { config in
                config.arguments = ["ip", "-6", "route", "show"]
                config.stdout = routeBuffer
            }
            try await routeExec.start()
            let routeStatus = try await routeExec.wait()
            try await routeExec.delete()

            guard routeStatus.exitCode == 0 else {
                throw IntegrationError.assert(msg: "ip -6 route show failed with status \(routeStatus)")
            }

            guard let routeOutput = String(data: routeBuffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert route output to UTF8")
            }

            guard routeOutput.contains("default via fd00::1 dev eth0") else {
                throw IntegrationError.assert(
                    msg: "expected 'default via fd00::1 dev eth0' in v6 routes, got: \(routeOutput)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    #endif

    func testSysctl() async throws {
        let id = "test-container-sysctl"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.sysctl = [
                "net.core.somaxconn": "4096"
            ]
            config.process.arguments = ["cat", "/proc/sys/net/core/somaxconn"]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            let output = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
            guard output == "4096" else {
                throw IntegrationError.assert(
                    msg: "sysctl net.core.somaxconn should be '4096', got '\(output ?? "nil")'")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testSysctlMultiple() async throws {
        let id = "test-container-sysctl-multiple"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.sysctl = [
                "net.core.somaxconn": "2048",
                "net.ipv4.ip_forward": "1",
            ]
            config.process.arguments = [
                "/bin/sh", "-c",
                "cat /proc/sys/net/core/somaxconn && cat /proc/sys/net/ipv4/ip_forward",
            ]
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process status \(status) != 0")
            }

            let output = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
            let lines = output?.split(separator: "\n").map { $0.trimmingCharacters(in: .whitespaces) }
            guard lines == ["2048", "1"] else {
                throw IntegrationError.assert(
                    msg: "expected sysctls ['2048', '1'], got '\(output ?? "nil")'")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testNoNewPrivileges() async throws {
        let id = "test-no-new-privileges"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat", "/proc/self/status"]
            config.process.noNewPrivileges = true
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        // /proc/self/status contains "NoNewPrivs:\t1" when the bit is set
        guard output.contains("NoNewPrivs:\t1") else {
            throw IntegrationError.assert(msg: "expected NoNewPrivs to be 1, got: \(output)")
        }
    }

    func testNoNewPrivilegesDisabled() async throws {
        let id = "test-no-new-privileges-disabled"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["cat", "/proc/self/status"]
            // noNewPrivileges defaults to false
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        guard let output = String(data: buffer.data, encoding: .utf8) else {
            throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
        }

        // When noNewPrivileges is not set, NoNewPrivs should be 0
        guard output.contains("NoNewPrivs:\t0") else {
            throw IntegrationError.assert(msg: "expected NoNewPrivs to be 0, got: \(output)")
        }
    }

    func testWorkingDirCreated() async throws {
        let id = "test-working-dir-created"
        let bs = try await bootstrap(id)

        let buffer = BufferWriter()
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/pwd"]
            config.process.workingDirectory = "/does/not/exist"
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let status = try await container.wait()
            try await container.stop()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "process with non-existent workingDir failed: \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) else {
                throw IntegrationError.assert(msg: "failed to read stdout")
            }

            guard output == "/does/not/exist" else {
                throw IntegrationError.assert(msg: "expected cwd '/does/not/exist', got '\(output)'")
            }
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testWorkingDirExecCreated() async throws {
        let id = "test-working-dir-exec-created"
        let bs = try await bootstrap(id)

        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/sleep", "1000"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let buffer = BufferWriter()
            let exec = try await container.exec("cwd-exec") { config in
                config.arguments = ["/bin/pwd"]
                config.workingDirectory = "/a/b/c/d"
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec with non-existent workingDir failed: \(status)")
            }

            guard let output = String(data: buffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) else {
                throw IntegrationError.assert(msg: "failed to read stdout")
            }

            guard output == "/a/b/c/d" else {
                throw IntegrationError.assert(msg: "expected cwd '/a/b/c/d', got '\(output)'")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testNoNewPrivilegesExec() async throws {
        let id = "test-no-new-privileges-exec"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "100"]
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            // Exec a process with noNewPrivileges set
            let buffer = BufferWriter()
            let exec = try await container.exec("nnp-exec") { config in
                config.arguments = ["cat", "/proc/self/status"]
                config.noNewPrivileges = true
                config.stdout = buffer
            }

            try await exec.start()
            let status = try await exec.wait()
            try await exec.delete()

            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "exec status \(status) != 0")
            }

            guard let output = String(data: buffer.data, encoding: .utf8) else {
                throw IntegrationError.assert(msg: "failed to convert stdout to UTF8")
            }

            guard output.contains("NoNewPrivs:\t1") else {
                throw IntegrationError.assert(msg: "expected NoNewPrivs to be 1 in exec, got: \(output)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    func testVMResourceOverhead() async throws {
        let id = "test-vm-resource-overhead"

        let bs = try await bootstrap(id)
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["sleep", "infinity"]
            config.cpus = 2
            config.memoryInBytes = 256.mib()
            config.cpuOverhead = 2
            config.memoryOverhead = 1024.mib()
            config.bootLog = bs.bootLog
        }

        do {
            try await container.create()
            try await container.start()

            let cpuBuffer = BufferWriter()
            let cpuExec = try await container.exec("check-nproc") { config in
                config.arguments = ["nproc"]
                config.stdout = cpuBuffer
            }
            try await cpuExec.start()
            var status = try await cpuExec.wait()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "nproc status \(status) != 0")
            }
            try await cpuExec.delete()

            guard let cpuStr = String(data: cpuBuffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines),
                let cpuCount = Int(cpuStr)
            else {
                throw IntegrationError.assert(msg: "failed to parse nproc output")
            }
            let expectedCpus = 4
            guard cpuCount == expectedCpus else {
                throw IntegrationError.assert(msg: "nproc \(cpuCount) != expected \(expectedCpus)")
            }

            let memBuffer = BufferWriter()
            let memExec = try await container.exec("check-meminfo") { config in
                config.arguments = ["sh", "-c", "grep MemTotal /proc/meminfo | awk '{print $2}'"]
                config.stdout = memBuffer
            }
            try await memExec.start()
            status = try await memExec.wait()
            guard status.exitCode == 0 else {
                throw IntegrationError.assert(msg: "meminfo status \(status) != 0")
            }
            try await memExec.delete()

            guard let memStr = String(data: memBuffer.data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines),
                let memTotalKiB = UInt64(memStr)
            else {
                throw IntegrationError.assert(msg: "failed to parse MemTotal")
            }
            let memTotalBytes = memTotalKiB * 1024
            let expectedMin: UInt64 = 1024.mib()
            guard memTotalBytes > expectedMin else {
                throw IntegrationError.assert(
                    msg: "MemTotal \(memTotalBytes) should exceed \(expectedMin)")
            }

            try await container.kill(.kill)
            try await container.wait()
            try await container.stop()
        } catch {
            try? await container.stop()
            throw error
        }
    }

    // Verify that mounts are sorted by destination path depth so that a
    // higher-level mount (e.g. /mnt) doesn't shadow a deeper mount
    // (e.g. /mnt/deep/nested). Both directories are separate virtiofs
    // shares; the sort ensures /mnt is mounted first and /mnt/deep/nested
    // on top of it.
    func testMountsSortedByDepth() async throws {
        let id = "test-mount-sort-depth"

        let bs = try await bootstrap(id)
        let buffer = BufferWriter()

        // Create two separate mount directories with distinct files.
        let deepDir = FileManager.default.uniqueTemporaryDirectory(create: true)
        try "deep-content".write(to: deepDir.appendingPathComponent("deep.txt"), atomically: true, encoding: .utf8)

        let shallowDir = FileManager.default.uniqueTemporaryDirectory(create: true)
        try "shallow-content".write(to: shallowDir.appendingPathComponent("shallow.txt"), atomically: true, encoding: .utf8)

        // Add deeper mount first, then shallower mount. Without sorting the
        // shallower mount would shadow the deeper one.
        let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in
            config.process.arguments = ["/bin/cat", "/mnt/deep/nested/deep.txt"]
            config.mounts.append(.share(source: deepDir.path, destination: "/mnt/deep/nested"))
            config.mounts.append(.share(source: shallowDir.path, destination: "/mnt"))
            config.process.stdout = buffer
            config.bootLog = bs.bootLog
        }

        try await container.create()
        try await container.start()

        let status = try await container.wait()
        try await container.stop()

        guard status.exitCode == 0 else {
            throw IntegrationError.assert(msg: "process status \(status) != 0")
        }

        let value = String(data: buffer.data, encoding: .utf8)
        guard value == "deep-content" else {
            throw IntegrationError.assert(
                msg: "expected 'deep-content' but got '\(value ?? "<nil>")'")
        }
    }
}
