nip/tests/test_container_management.nim

418 lines
11 KiB
Nim

## NEXTER Container Management Tests
##
## Tests for container lifecycle management including stopping, status checking,
## logs, and restart functionality.
import std/[unittest, os, tempfiles, options, strutils, times, tables]
import nip/container_management
import nip/container_startup
import nip/nexter_manifest
import nip/manifest_parser
# Helper to create a test manifest
proc createTestManifest(name: string, version: string): NEXTERManifest =
let buildDate = parse("2025-11-28T12:00:00Z", "yyyy-MM-dd'T'HH:mm:ss'Z'")
return NEXTERManifest(
name: name,
version: parseSemanticVersion(version),
buildDate: buildDate,
metadata: ContainerInfo(
description: "Test container",
license: "MIT"
),
provenance: ProvenanceInfo(
source: "https://example.com/source.tar.gz",
sourceHash: "xxh3-source-hash",
buildTimestamp: buildDate
),
buildConfig: BuildConfiguration(
configureFlags: @[],
compilerFlags: @[],
compilerVersion: "gcc-13",
targetArchitecture: "x86_64",
libc: "musl",
allocator: "jemalloc",
buildSystem: "custom"
),
base: BaseConfig(
baseImage: some("alpine"),
baseVersion: some("3.18")
),
environment: initTable[string, string](),
casChunks: @[],
namespace: ContainerNamespace(
isolationType: "full",
capabilities: @[],
mounts: @[],
devices: @[]
),
startup: StartupConfig(
command: @["/bin/sh"],
workingDir: "/",
user: none(string),
entrypoint: none(string)
),
buildHash: "xxh3-build-hash",
signature: SignatureInfo(
algorithm: "ed25519",
keyId: "test-key",
signature: "test-sig"
)
)
suite "Container Manager Creation Tests":
test "Create container manager":
## Verify container manager can be created
let manifest = createTestManifest("mgmt-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test-container", process, config)
check manager.containerName == "test-container"
check manager.process.pid == 1234
check manager.logs.len == 0
test "Container manager has creation timestamp":
## Verify creation timestamp is set
let manifest = createTestManifest("time-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let beforeCreate = now()
let manager = createContainerManager("test", process, config)
let afterCreate = now()
check manager.createdAt >= beforeCreate
check manager.createdAt <= afterCreate
suite "Container Status Tests":
test "Get container status - running":
## Verify status for running container
let manifest = createTestManifest("status-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let status = getContainerStatus(manager)
# Status will be Stopped since PID 1234 doesn't exist, but that's OK for testing
check status in [Running, Stopped]
test "Check if container is running":
## Verify running status check
let manifest = createTestManifest("running-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let isRunning = isContainerRunning(manager)
# Will be false since PID doesn't exist, but that's OK for testing
check isRunning in [true, false]
test "Get container stats":
## Verify container stats retrieval
let manifest = createTestManifest("stats-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let stats = getContainerStats(manager)
check stats.name == "test"
check stats.pid == 1234
check stats.uptime >= 0
suite "Container Logs Tests":
test "Add log entry":
## Verify log entries can be added
let manifest = createTestManifest("log-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
var manager = createContainerManager("test", process, config)
manager.addLog(Info, "Test log message")
check manager.logs.len == 1
check manager.logs[0] == "Test log message"
test "Get container logs":
## Verify logs can be retrieved
let manifest = createTestManifest("getlog-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
var manager = createContainerManager("test", process, config)
manager.addLog(Info, "Message 1")
manager.addLog(Warning, "Message 2")
manager.addLog(Error, "Message 3")
let logs = getContainerLogs(manager)
check logs.len == 3
check "Message 1" in logs
check "Message 2" in logs
check "Message 3" in logs
test "Get last N logs":
## Verify last N logs can be retrieved
let manifest = createTestManifest("lastlog-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
var manager = createContainerManager("test", process, config)
for i in 1..10:
manager.addLog(Info, "Message " & $i)
let lastLogs = getLastLogs(manager, 3)
check lastLogs.len == 3
check "Message 8" in lastLogs
check "Message 9" in lastLogs
check "Message 10" in lastLogs
test "Clear container logs":
## Verify logs can be cleared
let manifest = createTestManifest("clear-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
var manager = createContainerManager("test", process, config)
manager.addLog(Info, "Message 1")
manager.addLog(Info, "Message 2")
check manager.logs.len == 2
manager.clearContainerLogs()
check manager.logs.len == 0
suite "Container Uptime Tests":
test "Get container uptime":
## Verify uptime calculation
let manifest = createTestManifest("uptime-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let uptime = getContainerUptime(manager)
check uptime >= 0
test "Get formatted uptime":
## Verify uptime formatting
let manifest = createTestManifest("uptime-fmt-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let uptimeStr = getContainerUptimeFormatted(manager)
check uptimeStr.len > 0
check "s" in uptimeStr or "m" in uptimeStr or "h" in uptimeStr or "d" in uptimeStr
suite "Container Formatting Tests":
test "Format container manager":
## Verify manager formatting
let manifest = createTestManifest("fmt-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let formatted = $manager
check "Container" in formatted
check "test" in formatted
check "1234" in formatted
test "Format container stats":
## Verify stats formatting
let manifest = createTestManifest("stats-fmt-test", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let stats = getContainerStats(manager)
let formatted = $stats
check "Container Stats" in formatted
check "test" in formatted
check "1234" in formatted
suite "Container Management Property Tests":
test "Property: Manager preserves container name":
## Verify container name is preserved
for i in 1..5:
let name = "container-" & $i
let manifest = createTestManifest(name, "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1000 + i,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager(name, process, config)
check manager.containerName == name
test "Property: Logs are accumulated":
## Verify logs accumulate correctly
let manifest = createTestManifest("prop-log", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
var manager = createContainerManager("test", process, config)
for i in 1..20:
manager.addLog(Info, "Log " & $i)
check manager.logs.len == 20
check getLastLogs(manager, 5).len == 5
test "Property: Uptime is monotonically increasing":
## Verify uptime increases over time
let manifest = createTestManifest("prop-uptime", "1.0.0")
let config = createStartupConfig(manifest)
let process = ContainerProcess(
pid: 1234,
startTime: now(),
status: Running,
exitCode: none[int](),
output: "",
error: ""
)
let manager = createContainerManager("test", process, config)
let uptime1 = getContainerUptime(manager)
sleep(100)
let uptime2 = getContainerUptime(manager)
check uptime2 >= uptime1