370 lines
11 KiB
Nim
370 lines
11 KiB
Nim
## Tests for NPK Package Format Handler
|
|
##
|
|
## This module tests the NPK package creation, validation, and conversion
|
|
## functionality to ensure proper package format handling.
|
|
|
|
import unittest, os, times, options
|
|
import ../src/nimpak/types
|
|
import ../src/nimpak/packages
|
|
import ../src/nimpak/cas
|
|
|
|
|
|
suite "NPK Package Format Handler":
|
|
|
|
setup:
|
|
let testDir = getTempDir() / "nimpak_test_packages"
|
|
let sourceDir = testDir / "source"
|
|
let casDir = testDir / "cas"
|
|
|
|
# Clean up any existing test directory
|
|
if dirExists(testDir):
|
|
removeDir(testDir)
|
|
|
|
# Create test directory structure
|
|
createDir(sourceDir)
|
|
createDir(sourceDir / "bin")
|
|
createDir(sourceDir / "share" / "man")
|
|
|
|
# Create test files
|
|
writeFile(sourceDir / "bin" / "testapp", "#!/bin/bash\necho 'Hello World'\n")
|
|
writeFile(sourceDir / "share" / "man" / "testapp.1", ".TH TESTAPP 1\n.SH NAME\ntestapp - test application\n")
|
|
writeFile(sourceDir / "README.md", "# Test Application\nThis is a test application.\n")
|
|
|
|
# Initialize CAS manager
|
|
let casManager = initCasManager(casDir, casDir / "system")
|
|
|
|
teardown:
|
|
let testDir = getTempDir() / "nimpak_test_packages"
|
|
if dirExists(testDir):
|
|
removeDir(testDir)
|
|
|
|
test "create NPK package from Fragment":
|
|
let fragment = Fragment(
|
|
id: PackageId(
|
|
name: "testapp",
|
|
version: "1.0.0",
|
|
stream: Stable
|
|
),
|
|
source: Source(
|
|
url: "https://example.com/testapp-1.0.0.tar.gz",
|
|
hash: "blake2b-abc123def456",
|
|
hashAlgorithm: "blake2b",
|
|
sourceMethod: Http,
|
|
timestamp: now()
|
|
),
|
|
dependencies: @[],
|
|
buildSystem: Custom,
|
|
metadata: PackageMetadata(
|
|
description: "Test application for NPK testing",
|
|
license: "MIT",
|
|
maintainer: "test@example.com",
|
|
tags: @["test", "cli"],
|
|
runtime: RuntimeProfile(
|
|
libc: Musl,
|
|
allocator: System,
|
|
systemdAware: false,
|
|
reproducible: true,
|
|
tags: @["test"]
|
|
)
|
|
),
|
|
acul: AculCompliance(
|
|
required: false,
|
|
membership: "",
|
|
attribution: "",
|
|
buildLog: ""
|
|
)
|
|
)
|
|
|
|
let sourceDir = getTempDir() / "nimpak_test_packages" / "source"
|
|
let result = createNpkPackage(fragment, sourceDir)
|
|
|
|
check result.isOk
|
|
let npk = result.get()
|
|
check npk.metadata.id.name == "testapp"
|
|
check npk.metadata.id.version == "1.0.0"
|
|
check npk.files.len == 3 # bin/testapp, share/man/testapp.1, README.md
|
|
check npk.manifest.totalSize > 0
|
|
check npk.manifest.merkleRoot.len > 0
|
|
check npk.signature.isNone # No signature by default
|
|
|
|
test "validate NPK package":
|
|
let fragment = Fragment(
|
|
id: PackageId(name: "testapp", version: "1.0.0", stream: Stable),
|
|
source: Source(
|
|
url: "https://example.com/testapp-1.0.0.tar.gz",
|
|
hash: "blake2b-abc123def456",
|
|
hashAlgorithm: "blake2b",
|
|
sourceMethod: Http,
|
|
timestamp: now()
|
|
),
|
|
dependencies: @[],
|
|
buildSystem: Custom,
|
|
metadata: PackageMetadata(
|
|
description: "Test application",
|
|
license: "MIT",
|
|
maintainer: "test@example.com",
|
|
tags: @[],
|
|
runtime: RuntimeProfile(
|
|
libc: Musl,
|
|
allocator: System,
|
|
systemdAware: false,
|
|
reproducible: true,
|
|
tags: @[]
|
|
)
|
|
),
|
|
acul: AculCompliance(required: false, membership: "", attribution:, buildLog: "")
|
|
)
|
|
|
|
let sourceDir = getTempDir() / "nimpak_test_packages" / "source"
|
|
let createResult = createNpkPackage(fragment, sourceDir)
|
|
check createResult.isOk
|
|
|
|
let npk = createResult.get()
|
|
let validation = validateNpkPackage(npk)
|
|
|
|
check validation.valid == true
|
|
check validation.errors.len == 0
|
|
|
|
test "validate invalid NPK package":
|
|
# Create invalid package with empty name
|
|
let invalidFragment = Fragment(
|
|
id: PackageId(name: "", version: "", stream: Stable), # Invalid: empty name and version
|
|
source: Source(
|
|
url: "", # Invalid: empty URL
|
|
hash: "", # Invalid: empty hash
|
|
hashAlgorithm: "blake2b",
|
|
sourceMethod: Http,
|
|
timestamp: now()
|
|
),
|
|
dependencies: @[],
|
|
buildSystem: Custom,
|
|
metadata: PackageMetadata(
|
|
description: "Invalid test package",
|
|
license: "MIT",
|
|
maintainer: "test@example.com",
|
|
tags: @[],
|
|
runtime: RuntimeProfile(
|
|
libc: Musl,
|
|
allocator: System,
|
|
systemdAware: false,
|
|
reproducible: true,
|
|
tags: @[]
|
|
)
|
|
),
|
|
acul: AculCompliance(required: false, membership: "", attribution: "", buildLog: "")
|
|
)
|
|
|
|
let npk = NpkPackage(
|
|
metadata: invalidFragment,
|
|
files: @[], # No files
|
|
manifest: PackageManifest(
|
|
files: @[],
|
|
totalSize: 0,
|
|
created: now(),
|
|
merkleRoot: "" # Invalid: empty merkle root
|
|
),
|
|
signature: none(Signature)
|
|
)
|
|
|
|
let validation = validateNpkPackage(npk)
|
|
|
|
check validation.valid == false
|
|
check validation.errors.len > 0
|
|
|
|
# Check specific validation errors
|
|
let errorFields = validation.errors.mapIt(it.field)
|
|
check "metadata.id.name" in errorFields
|
|
check "metadata.id.version" in errorFields
|
|
check "metadata.source.url" in errorFields
|
|
check "metadata.source.hash" in errorFields
|
|
check "manifest.merkleRoot" in errorFields
|
|
|
|
test "serialize NPK to KDL format":
|
|
let fragment = Fragment(
|
|
id: PackageId(name: "testapp", version: "1.0.0", stream: Stable),
|
|
source: Source(
|
|
url: "https://example.com/testapp-1.0.0.tar.gz",
|
|
hash: "blake2b-abc123def456",
|
|
hashAlgorithm: "blake2b",
|
|
sourceMethod: Http,
|
|
timestamp: now()
|
|
),
|
|
dependencies: @[
|
|
PackageId(name: "libtest", version: "2.0.0", stream: Stable)
|
|
],
|
|
buildSystem: Custom,
|
|
metadata: PackageMetadata(
|
|
description: "Test application",
|
|
license: "MIT",
|
|
maintainer: "test@example.com",
|
|
tags: @["test", "cli"],
|
|
runtime: RuntimeProfile(
|
|
libc: Musl,
|
|
allocator: System,
|
|
systemdAware: false,
|
|
reproducible: true,
|
|
tags: @["test"]
|
|
)
|
|
),
|
|
acul: AculCompliance(
|
|
required: true,
|
|
membership: "NexusOS-Community",
|
|
attribution: "Original: testapp, Packaged: NexusOS",
|
|
buildLog: ""
|
|
)
|
|
)
|
|
|
|
let sourceDir = getTempDir() / "nimpak_test_packages" / "source"
|
|
let createResult = createNpkPackage(fragment, sourceDir)
|
|
check createResult.isOk
|
|
|
|
let npk = createResult.get()
|
|
let kdlContent = serializeToKdl(npk)
|
|
|
|
# Check KDL content contains expected elements
|
|
check "package \"testapp\"" in kdlContent
|
|
check "version \"1.0.0\"" in kdlContent
|
|
check "stream \"Stable\"" in kdlContent
|
|
check "method \"Http\"" in kdlContent
|
|
check "libc \"Musl\"" in kdlContent
|
|
check "libtest \"2.0.0\"" in kdlContent
|
|
check "required true" in kdlContent
|
|
check "membership \"NexusOS-Community\"" in kdlContent
|
|
|
|
test "sign and verify NPK package":
|
|
let fragment = Fragment(
|
|
id: PackageId(name: "testapp", version: "1.0.0", stream: Stable),
|
|
source: Source(
|
|
url: "https://example.com/testapp-1.0.0.tar.gz",
|
|
hash: "blake2b-abc123def456",
|
|
hashAlgorithm: "blake2b",
|
|
sourceMethod: Http,
|
|
timestamp: now()
|
|
),
|
|
dependencies: @[],
|
|
buildSystem: Custom,
|
|
metadata: PackageMetadata(
|
|
description: "Test application",
|
|
license: "MIT",
|
|
maintainer: "test@example.com",
|
|
tags: @[],
|
|
runtime: RuntimeProfile(
|
|
libc: Musl,
|
|
allocator: System,
|
|
systemdAware: false,
|
|
reproducible: true,
|
|
tags: @[]
|
|
)
|
|
),
|
|
acul: AculCompliance(required: false, membership: "", attribution: "", buildLog: "")
|
|
)
|
|
|
|
let sourceDir = getTempDir() / "nimpak_test_packages" / "source"
|
|
let createResult = createNpkPackage(fragment, sourceDir)
|
|
check createResult.isOk
|
|
|
|
var npk = createResult.get()
|
|
check npk.signature.isNone
|
|
|
|
# Sign the package
|
|
let privateKey = @[0x01'u8, 0x02'u8, 0x03'u8] # Placeholder key
|
|
let signResult = signNpkPackage(npk, "test-key-id", privateKey)
|
|
check signResult.isOk
|
|
check npk.signature.isSome
|
|
|
|
let signature = npk.signature.get()
|
|
check signature.keyId == "test-key-id"
|
|
check signature.algorithm == "ed25519"
|
|
|
|
# Verify the signature
|
|
let publicKey = @[0x04'u8, 0x05'u8, 0x06'u8] # Placeholder key
|
|
let verifyResult = verifyNpkSignature(npk, publicKey)
|
|
check verifyResult.isOk
|
|
# Note: This will be true with placeholder implementation
|
|
|
|
test "create and load NPK archive":
|
|
let fragment = Fragment(
|
|
id: PackageId(name: "testapp", version: "1.0.0", stream: Stable),
|
|
source: Source(
|
|
url: "https://example.com/testapp-1.0.0.tar.gz",
|
|
hash: "blake2b-abc123def456",
|
|
hashAlgorithm: "blake2b",
|
|
sourceMethod: Http,
|
|
timestamp: now()
|
|
),
|
|
dependencies: @[],
|
|
buildSystem: Custom,
|
|
metadata: PackageMetadata(
|
|
description: "Test application",
|
|
license: "MIT",
|
|
maintainer: "test@example.com",
|
|
tags: @[],
|
|
runtime: RuntimeProfile(
|
|
libc: Musl,
|
|
allocator: System,
|
|
systemdAware: false,
|
|
reproducible: true,
|
|
tags: @[]
|
|
)
|
|
),
|
|
acul: AculCompliance(required: false, membership: "", attribution: "", buildLog: "")
|
|
)
|
|
|
|
let sourceDir = getTempDir() / "nimpak_test_packages" / "source"
|
|
let createResult = createNpkPackage(fragment, sourceDir)
|
|
check createResult.isOk
|
|
|
|
let npk = createResult.get()
|
|
let archivePath = getTempDir() / "nimpak_test_packages" / "testapp-1.0.0.npk"
|
|
|
|
# Create archive
|
|
let archiveResult = createNpkArchive(npk, archivePath)
|
|
check archiveResult.isOk
|
|
check dirExists(archivePath) # Currently creates directory, will be tar.gz later
|
|
check fileExists(archivePath / "package.kdl")
|
|
check fileExists(archivePath / "manifest.json")
|
|
|
|
# Load archive (will fail with current placeholder implementation)
|
|
let loadResult = loadNpkArchive(archivePath)
|
|
check loadResult.isErr # Expected to fail until KDL parsing is implemented
|
|
|
|
test "get NPK package info":
|
|
let fragment = Fragment(
|
|
id: PackageId(name: "testapp", version: "1.0.0", stream: Stable),
|
|
source: Source(
|
|
url: "https://example.com/testapp-1.0.0.tar.gz",
|
|
hash: "blake2b-abc123def456",
|
|
hashAlgorithm: "blake2b",
|
|
sourceMethod: Http,
|
|
timestamp: now()
|
|
),
|
|
dependencies: @[],
|
|
buildSystem: Custom,
|
|
metadata: PackageMetadata(
|
|
description: "Test application",
|
|
license: "MIT",
|
|
maintainer: "test@example.com",
|
|
tags: @[],
|
|
runtime: RuntimeProfile(
|
|
libc: Musl,
|
|
allocator: System,
|
|
systemdAware: false,
|
|
reproducible: true,
|
|
tags: @[]
|
|
)
|
|
),
|
|
acul: AculCompliance(required: false, membership: "", attribution: "", buildLog: "")
|
|
)
|
|
|
|
let sourceDir = getTempDir() / "nimpak_test_packages" / "source"
|
|
let createResult = createNpkPackage(fragment, sourceDir)
|
|
check createResult.isOk
|
|
|
|
let npk = createResult.get()
|
|
let info = getNpkInfo(npk)
|
|
|
|
check "NPK Package: testapp v1.0.0" in info
|
|
check "Stream: Stable" in info
|
|
check "Files: 3" in info
|
|
check "Signed: No" in info
|