import std/[os, strutils, tables, unittest] import ../src/muslkit const sampleIndex = """ C:Q1aaa= P:openssl-libs-static V:3.3.7-r1 A:x86_64 S:13040623 T:Toolkit for Transport Layer Security (TLS) (static library) L:Apache-2.0 o:openssl C:Q1bbb= P:openssl-dev V:3.3.7-r1 A:x86_64 S:3000 T:TLS toolkit (development files) D:libcrypto3=3.3.7-r1 pkgconfig p:openssl3-dev=3.3.7-r1 pc:libssl=3.3.7 C:Q1ccc= P:libcrypto3 V:3.3.7-r1 A:x86_64 S:2000 T:crypto library D:so:libc.musl-x86_64.so.1 p:so:libcrypto.so.3=3 C:Q1ddd= P:musl V:1.2.5-r11 A:x86_64 S:400 T:the musl c library p:so:libc.musl-x86_64.so.1=1 C:Q1eee= P:pkgconf V:2.3.0-r0 A:x86_64 S:100 T:pkg-config compatible p:pkgconfig=2.3.0-r0 """ suite "index parsing": let idx = parseIndex(sampleIndex, "main") test "records and fields": check idx.packages.len == 5 let p = idx.packages["openssl-libs-static"] check p.version == "3.3.7-r1" check p.size == 13040623 check p.repo == "main" check p.description.endsWith("(static library)") test "provides are indexed": check idx.find("pkgconfig") == "pkgconf" check idx.find("so:libcrypto.so.3") == "libcrypto3" check idx.find("openssl3-dev") == "openssl-dev" check idx.find("nope") == "" test "version constraints are stripped": check stripConstraint("musl=1.2.5-r11") == "musl" check stripConstraint("so:libssl.so.3=3") == "so:libssl.so.3" check stripConstraint("cmd>=2") == "cmd" check stripConstraint("plain") == "plain" test "conflicts are recognized": check isConflict("!busybox") check not isConflict("busybox") suite "resolution": let idx = parseIndex(sampleIndex, "main") test "dependencies come before dependents": let order = idx.resolve(["openssl-dev"]) let names = block: var s: seq[string] for p in order: s.add p.name s check names[^1] == "openssl-dev" check "libcrypto3" in names check "musl" in names # reached through so:libc.musl-x86_64.so.1 check "pkgconf" in names # reached through the pkgconfig provide check names.find("libcrypto3") < names.find("openssl-dev") test "a package is visited once": let order = idx.resolve(["openssl-dev", "libcrypto3", "openssl-dev"]) var seen: CountTable[string] for p in order: seen.inc p.name for name, n in seen: check n == 1 test "--no-deps stops at the request": let order = idx.resolve(["openssl-dev"], withDeps = false) check order.len == 1 check order[0].name == "openssl-dev" test "an unsatisfiable request names its requester": expect KeyError: discard parseIndex("C:Q1\nP:lonely\nV:1\nD:ghost\n").resolve(["lonely"]) test "merge lets a later repo shadow an earlier one": var a = parseIndex("C:Q1\nP:foo\nV:1\n", "main") a.merge parseIndex("C:Q1\nP:foo\nV:2\n", "community") check a.packages["foo"].version == "2" check a.packages["foo"].repo == "community" suite "sysroot manifest": let root = getTempDir() / "muslkit-test-root" removeDir root test "record then read back": record(root, [Pkg(name: "zlib-static", version: "1.3.2-r0", repo: "main")]) record(root, [Pkg(name: "openssl-libs-static", version: "3.3.7-r1", repo: "main")]) let entries = readManifest(root) check entries.len == 2 check installed(root, "zlib-static") check not installed(root, "absent") test "re-recording replaces rather than duplicates": record(root, [Pkg(name: "zlib-static", version: "1.3.3-r0", repo: "main")]) let entries = readManifest(root) check entries.len == 2 for e in entries: if e.name == "zlib-static": check e.version == "1.3.3-r0" test "static libs are found and sorted": createDir root / "usr" / "lib" for name in ["libz.a", "libcrypto.a"]: writeFile(root / "usr" / "lib" / name, "") let libs = staticLibs(root) check libs.len == 2 check libs[0].extractFilename == "libcrypto.a" removeDir root suite "flags": let root = getTempDir() / "muslkit-test-flags" removeDir root createDir root / "usr" / "lib" test "plain sysroot": let f = nimFlags(root).join(" ") check ("--passC:-I" & root & "/usr/include") in f check "--passL:-static" in f check "dynlibOverride" notin f test "openssl archives switch on the static-TLS workarounds": for name in ["libssl.a", "libcrypto.a"]: writeFile(root / "usr" / "lib" / name, "") let f = nimFlags(root, ["z"]).join(" ") check "--dynlibOverride:ssl" in f check "--dynlibOverride:crypto" in f # OpenSSL 3 dropped the symbol Nim's wrapper still names check "-DSSL_get_peer_certificate=SSL_get1_peer_certificate" in f check "--passL:-lz" in f test "cc flags and pkg-config env": check ccFlags(root, ["ssl"]) == @["-I" & root & "/usr/include", "-L" & root & "/usr/lib", "-static", "-lssl"] check pkgConfigEnv(root)[0] == "PKG_CONFIG_SYSROOT_DIR=" & root test "nimcfg carries the compiler and the flags": let cfg = nimCfg(root, "/tmp/zigcc") check "--cc:clang" in cfg check "--clang.exe:\"/tmp/zigcc\"" in cfg check "--passL:-static" in cfg test "zigcc script targets the right triple": let s = zigccScript("aarch64-linux-musl") check "zig cc -target aarch64-linux-musl" in s check "\"$@\"" in s removeDir root suite "remote": test "urls are built from mirror, branch, repo and arch": let r = initRemote(branch = "edge", arch = "aarch64") check r.repoUrl("community") == "https://dl-cdn.alpinelinux.org/alpine/edge/community/aarch64" check apkFile(Pkg(name: "zlib-static", version: "1.3.2-r0")) == "zlib-static-1.3.2-r0.apk"