184 lines
4.7 KiB
Nim
184 lines
4.7 KiB
Nim
## Test suite for comprehensive logging
|
|
## Task 38: Add comprehensive logging
|
|
|
|
import unittest, os, strutils, json, tables, times
|
|
import ../src/nimpak/logging
|
|
|
|
suite "Comprehensive Logging Tests":
|
|
|
|
var testLogDir: string
|
|
var logger: Logger
|
|
|
|
setup:
|
|
testLogDir = getTempDir() / "nip_logging_test_" & $epochTime().int
|
|
createDir(testLogDir)
|
|
|
|
teardown:
|
|
if logger.logFile.len > 0:
|
|
closeLogger(logger)
|
|
removeDir(testLogDir)
|
|
|
|
test "Logger initialization":
|
|
logger = initLogger(
|
|
component = "test",
|
|
minLevel = Debug,
|
|
outputs = {Console}
|
|
)
|
|
|
|
check logger.component == "test"
|
|
check logger.minLevel == Debug
|
|
check Console in logger.outputs
|
|
|
|
test "Log level filtering":
|
|
logger = initLogger(
|
|
component = "test",
|
|
minLevel = Warn,
|
|
outputs = {} # No output to avoid noise
|
|
)
|
|
|
|
# These should be filtered out
|
|
logger.log(Trace, "trace message")
|
|
logger.log(Debug, "debug message")
|
|
logger.log(Info, "info message")
|
|
|
|
# Only Warn and above should pass (but we're just testing level comparison)
|
|
check Trace < logger.minLevel
|
|
check Debug < logger.minLevel
|
|
check Info < logger.minLevel
|
|
check Warn >= logger.minLevel
|
|
check Error >= logger.minLevel
|
|
|
|
test "File logging":
|
|
let logPath = testLogDir / "test.log"
|
|
|
|
logger = initLogger(
|
|
component = "file-test",
|
|
minLevel = Info,
|
|
outputs = {LogOutput.File},
|
|
logFile = logPath
|
|
)
|
|
|
|
logger.log(Info, "Test message 1")
|
|
logger.log(Warn, "Test message 2")
|
|
|
|
closeLogger(logger)
|
|
|
|
check fileExists(logPath)
|
|
let content = readFile(logPath)
|
|
check content.contains("Test message 1")
|
|
check content.contains("Test message 2")
|
|
check content.contains("[file-test]")
|
|
|
|
test "JSON logging":
|
|
let jsonPath = testLogDir / "test.json"
|
|
|
|
logger = initLogger(
|
|
component = "json-test",
|
|
minLevel = Info,
|
|
outputs = {LogOutput.Json},
|
|
jsonFile = jsonPath
|
|
)
|
|
|
|
var ctx = initTable[string, string]()
|
|
ctx["package"] = "nginx"
|
|
ctx["version"] = "1.24.0"
|
|
|
|
logger.log(Info, "Installing package", ctx)
|
|
|
|
closeLogger(logger)
|
|
|
|
check fileExists(jsonPath)
|
|
let content = readFile(jsonPath)
|
|
let parsed = parseJson(content)
|
|
|
|
check parsed["level"].getStr() == "Info"
|
|
check parsed["component"].getStr() == "json-test"
|
|
check parsed["message"].getStr() == "Installing package"
|
|
check parsed["context"]["package"].getStr() == "nginx"
|
|
|
|
test "Context logging":
|
|
let logPath = testLogDir / "context.log"
|
|
|
|
logger = initLogger(
|
|
component = "ctx-test",
|
|
minLevel = Info,
|
|
outputs = {LogOutput.File},
|
|
logFile = logPath
|
|
)
|
|
|
|
var ctx = initTable[string, string]()
|
|
ctx["key1"] = "value1"
|
|
ctx["key2"] = "value2"
|
|
|
|
logger.log(Info, "Message with context", ctx)
|
|
|
|
closeLogger(logger)
|
|
|
|
let content = readFile(logPath)
|
|
check content.contains("key1: value1")
|
|
check content.contains("key2: value2")
|
|
|
|
test "Performance timing":
|
|
let logPath = testLogDir / "perf.log"
|
|
|
|
logger = initLogger(
|
|
component = "perf-test",
|
|
minLevel = Debug,
|
|
outputs = {LogOutput.File},
|
|
logFile = logPath
|
|
)
|
|
|
|
let timer = logger.startTimer("test-operation")
|
|
sleep(10) # 10ms delay
|
|
let duration = timer.stop()
|
|
|
|
check duration >= 10.0 # At least 10ms
|
|
|
|
closeLogger(logger)
|
|
|
|
let content = readFile(logPath)
|
|
check content.contains("test-operation")
|
|
|
|
test "Audit logging":
|
|
let logPath = testLogDir / "audit.log"
|
|
|
|
logger = initLogger(
|
|
component = "audit-test",
|
|
minLevel = Audit,
|
|
outputs = {LogOutput.File},
|
|
logFile = logPath
|
|
)
|
|
|
|
logger.auditPackageOp("install", "nginx", "1.24.0", success = true)
|
|
logger.auditCasOp("store", "xxh3-abc123def456", "NPK", success = true)
|
|
|
|
closeLogger(logger)
|
|
|
|
let content = readFile(logPath)
|
|
check content.contains("Package install: nginx")
|
|
check content.contains("CAS store")
|
|
check content.contains("success: true")
|
|
|
|
test "Log level parsing":
|
|
check parseLogLevel("trace") == Trace
|
|
check parseLogLevel("DEBUG") == Debug
|
|
check parseLogLevel("Info") == Info
|
|
check parseLogLevel("WARN") == Warn
|
|
check parseLogLevel("warning") == Warn
|
|
check parseLogLevel("error") == Error
|
|
check parseLogLevel("fatal") == Fatal
|
|
check parseLogLevel("audit") == Audit
|
|
check parseLogLevel("invalid") == Info # Default
|
|
|
|
test "Global logger":
|
|
initGlobalLogger(
|
|
component = "global-test",
|
|
minLevel = Info,
|
|
outputs = {} # No output
|
|
)
|
|
|
|
# These should not crash
|
|
info("Global info message")
|
|
warn("Global warn message")
|
|
error("Global error message")
|