418 lines
11 KiB
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
|