nip/tests/test_npk_manifest.nim

253 lines
7.7 KiB
Nim

## Property-Based Tests for NPK Manifest - TDD Approach
##
## **Feature:** 01-nip-unified-storage-and-formats
## **Property 3:** Manifesttrip
## **Validates:** Requirements 6.4
##
## **Property Statement:**
## For any NPK manifest, parsing and regenerating SHALL produce semantically equivalent KDL
##
## **TDD Strategy:**
## This test is written FIRST to expose gaps in the implementation.
## Test failures will drive the implementation of parseNPKManifest and generateNPKManifest.
## We use a MAXIMALLY POPULATED manifest to ensure ALL fields are tested.
import std/[unittest, times, options, strutils]
import nip/npk_manifest
import nip/manifest_parser
# ============================================================================
# Helper: Create Maximally Populated NPK Manifest
# ============================================================================
proc createFullNPKManifest*(): NPKManifest =
## Creates a maximally populated NPKManifest instance for roundtrip testing.
## This ensures we test ALL fields, not just the minimal required ones.
##
## **Philosophy:** Test the hardest case first. If this passes, simpler cases will too.
result = NPKManifest(
name: "nexus-base-pkg",
version: parseSemanticVersion("1.2.3-alpha.1+build.2"),
buildDate: parse("2025-11-20T14:00:00Z", "yyyy-MM-dd'T'HH:mm:ss'Z'"),
metadata: PackageInfo(
description: "Core dependency package for NexusOS.",
license: "Dual-ACUL-EUPL-1.2",
homepage: some("https://nexus.os/base"),
author: some("Markus Maiwald"),
maintainer: some("team@nexus.os"),
tags: @["core", "utility", "system"]
),
provenance: ProvenanceInfo(
source: "https://nexus.os/sources/base-1.2.3.tar.gz",
sourceHash: "xxh3-source123456789abc",
upstream: some("https://upstream.project.org"),
buildTimestamp: parse("2025-11-20T14:00:00Z", "yyyy-MM-dd'T'HH:mm:ss'Z'"),
builder: some("build-bot@nexus.os")
),
buildConfig: BuildConfiguration(
configureFlags: @["--prefix=/usr", "--enable-shared"],
compilerFlags: @["-O3", "-fno-lto", "-march=native"],
compilerVersion: "gcc-13.2.0",
targetArchitecture: "x86_64",
libc: "glibc",
allocator: "jemalloc",
buildSystem: "meson"
),
dependencies: @[
Dependency(
name: "zlib",
version: "1.2.13",
buildHash: "xxh3-zlib-build-hash",
optional: false
),
Dependency(
name: "openssl",
version: "3.0.0",
buildHash: "xxh3-openssl-build-hash",
optional: false
),
Dependency(
name: "gui-tools",
version: "2.0.0",
buildHash: "xxh3-gui-build-hash",
optional: true
)
],
casChunks: @[
ChunkReference(
hash: "xxh3-chunk1-binary",
size: 1048576,
chunkType: Binary,
path: "bin/nexus-base"
),
ChunkReference(
hash: "xxh3-chunk2-library",
size: 524288,
chunkType: Library,
path: "lib/libnexus.so"
),
ChunkReference(
hash: "xxh3-chunk3-config",
size: 4096,
chunkType: Config,
path: "etc/nexus.conf"
)
],
install: InstallPaths(
programsPath: "/Programs/NexusBase/1.2.3",
binPath: "/Programs/NexusBase/1.2.3/bin",
libPath: "/Programs/NexusBase/1.2.3/lib",
sharePath: "/Programs/NexusBase/1.2.3/share",
etcPath: "/Programs/NexusBase/1.2.3/etc"
),
system: SystemIntegration(
services: @[
ServiceSpec(
name: "nexus-base",
serviceType: "systemd",
enable: true,
startOnBoot: true
)
],
users: @[
UserSpec(
name: "nexus",
uid: some(1000),
system: true,
shell: "/bin/false",
home: some("/var/lib/nexus")
)
],
groups: @[
GroupSpec(
name: "nexus",
gid: some(1000),
system: true
)
],
systemPaths: @["/usr/bin/nexus-base"]
),
buildHash: "xxh3-build-config-hash",
signature: SignatureInfo(
algorithm: "ed25519",
keyId: "packager-2024-key",
signature: "base64-encoded-signature-placeholder"
)
)
# ============================================================================
# Property Tests - Written FIRST to Drive Implementation
# ============================================================================
suite "NPK Manifest Roundtrip Property Tests (Task 6.1)":
test "Property 3: KDL Generation - Verify output structure":
## **Phase 1:** Test that generateNPKManifest produces valid KDL
## This will fail initially and show us what's missing
let manifest = createFullNPKManifest()
let kdl = generateNPKManifest(manifest)
# Basic sanity checks
check kdl.len > 0
check "package" in kdl
check manifest.name in kdl
# Print generated KDL for inspection
echo "\n=== Generated KDL (Phase 1) ===\n"
echo kdl
echo "=== End KDL ===\n"
test "Property 3: Full Roundtrip - ALL FIELDS":
## **Phase 2:** Full roundtrip test
## This is the MAIN test that will expose all gaps
##
## **Feature: 01-nip-unified-storage-and-formats, Property 3: Manifest Roundtrip**
## **Validates: Requirements 6.4**
let originalManifest = createFullNPKManifest()
# Step 1: Generate KDL
let kdlString = generateNPKManifest(originalManifest)
check kdlString.len > 0
# Step 2: Parse KDL back
let parsedManifest = parseNPKManifest(kdlString)
# Step 3: Verify ALL fields preserved
if parsedManifest.name != originalManifest.name:
echo "Name mismatch: ", parsedManifest.name, " != ", originalManifest.name
check parsedManifest.name == originalManifest.name
if parsedManifest.version != originalManifest.version:
echo "Version mismatch:"
echo " Parsed: ", parsedManifest.version
echo " Original: ", originalManifest.version
check parsedManifest.version == originalManifest.version
if parsedManifest.buildHash != originalManifest.buildHash:
echo "BuildHash mismatch: ", parsedManifest.buildHash, " != ", originalManifest.buildHash
check parsedManifest.buildHash == originalManifest.buildHash
# Step 4: Verify deterministic generation
let kdlString2 = generateNPKManifest(parsedManifest)
if kdlString != kdlString2:
echo "KDL strings don't match!"
echo "=== Original KDL ==="
echo kdlString
echo "=== Regenerated KDL ==="
echo kdlString2
check kdlString == kdlString2
suite "NPK Manifest Validation Tests":
test "Validate manifest with valid xxh3 hashes":
let validManifest = NPKManifest(
name: "valid-pkg",
version: parseSemanticVersion("1.0.0"),
buildDate: now(),
metadata: PackageInfo(
description: "Valid package",
license: "MIT"
),
provenance: ProvenanceInfo(
source: "https://example.com/valid.tar.gz",
sourceHash: "xxh3-valid123",
buildTimestamp: now()
),
buildConfig: BuildConfiguration(
compilerVersion: "gcc-13.2.0",
targetArchitecture: "x86_64",
libc: "musl",
allocator: "default",
buildSystem: "cmake"
),
install: InstallPaths(
programsPath: "/Programs/Valid/1.0.0",
binPath: "/Programs/Valid/1.0.0/bin",
libPath: "/Programs/Valid/1.0.0/lib",
sharePath: "/Programs/Valid/1.0.0/share",
etcPath: "/Programs/Valid/1.0.0/etc"
),
system: SystemIntegration(),
buildHash: "xxh3-build123",
signature: SignatureInfo(
algorithm: "ed25519",
keyId: "test-key",
signature: "test-signature"
)
)
let issues = validateNPKManifest(validManifest)
check issues.len == 0