nandi/nimstaticpublic Fork 0
rawtest
Commits
Clone
git clone https://git.rickub.com/nandi/nimstatic.git
git clone ssh://git@rickub.com/nandi/nimstatic.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

test_nimstatic.nim · 246 lines · 8.0 KBNim Blame HistoryRaw
temp: raw size probe 159b56c nandi 7h ago1import std/[os, sequtils, strutils, tables, unittest]
2import ../src/nimstatic
3
4const sampleIndex = """
5C:Q1aaa=
6P:openssl-libs-static
7V:3.3.7-r1
8A:x86_64
9S:13040623
10T:Toolkit for Transport Layer Security (TLS) (static library)
11L:Apache-2.0
12o:openssl
13
14C:Q1bbb=
15P:openssl-dev
16V:3.3.7-r1
17A:x86_64
18S:3000
19T:TLS toolkit (development files)
20D:libcrypto3=3.3.7-r1 pkgconfig
21p:openssl3-dev=3.3.7-r1 pc:libssl=3.3.7
22
23C:Q1ccc=
24P:libcrypto3
25V:3.3.7-r1
26A:x86_64
27S:2000
28T:crypto library
29D:so:libc.musl-x86_64.so.1
30p:so:libcrypto.so.3=3
31
32C:Q1ddd=
33P:musl
34V:1.2.5-r11
35A:x86_64
36S:400
37T:the musl c library
38p:so:libc.musl-x86_64.so.1=1
39
40C:Q1eee=
41P:pkgconf
42V:2.3.0-r0
43A:x86_64
44S:100
45T:pkg-config compatible
46p:pkgconfig=2.3.0-r0
47"""
48
49suite "index parsing":
50 let idx = parseIndex(sampleIndex, "main")
51
52 test "records and fields":
53 check idx.packages.len == 5
54 let p = idx.packages["openssl-libs-static"]
55 check p.version == "3.3.7-r1"
56 check p.size == 13040623
57 check p.repo == "main"
58 check p.description.endsWith("(static library)")
59
60 test "provides are indexed":
61 check idx.find("pkgconfig") == "pkgconf"
62 check idx.find("so:libcrypto.so.3") == "libcrypto3"
63 check idx.find("openssl3-dev") == "openssl-dev"
64 check idx.find("nope") == ""
65
66 test "version constraints are stripped":
67 check stripConstraint("musl=1.2.5-r11") == "musl"
68 check stripConstraint("so:libssl.so.3=3") == "so:libssl.so.3"
69 check stripConstraint("cmd>=2") == "cmd"
70 check stripConstraint("plain") == "plain"
71
72 test "conflicts are recognized":
73 check isConflict("!busybox")
74 check not isConflict("busybox")
75
76suite "resolution":
77 let idx = parseIndex(sampleIndex, "main")
78
79 test "dependencies come before dependents":
80 let order = idx.resolve(["openssl-dev"])
81 let names = block:
82 var s: seq[string]
83 for p in order: s.add p.name
84 s
85 check names[^1] == "openssl-dev"
86 check "libcrypto3" in names
87 check "musl" in names # reached through so:libc.musl-x86_64.so.1
88 check "pkgconf" in names # reached through the pkgconfig provide
89 check names.find("libcrypto3") < names.find("openssl-dev")
90
91 test "a package is visited once":
92 let order = idx.resolve(["openssl-dev", "libcrypto3", "openssl-dev"])
93 var seen: CountTable[string]
94 for p in order: seen.inc p.name
95 for name, n in seen: check n == 1
96
97 test "--no-deps stops at the request":
98 let order = idx.resolve(["openssl-dev"], withDeps = false)
99 check order.len == 1
100 check order[0].name == "openssl-dev"
101
102 test "an unsatisfiable request names its requester":
103 expect KeyError:
104 discard parseIndex("C:Q1\nP:lonely\nV:1\nD:ghost\n").resolve(["lonely"])
105
106 test "merge lets a later repo shadow an earlier one":
107 var a = parseIndex("C:Q1\nP:foo\nV:1\n", "main")
108 a.merge parseIndex("C:Q1\nP:foo\nV:2\n", "community")
109 check a.packages["foo"].version == "2"
110 check a.packages["foo"].repo == "community"
111
112suite "sysroot manifest":
113 let root = getTempDir() / "nimstatic-test-root"
114 removeDir root
115
116 test "record then read back":
117 record(root, [Pkg(name: "zlib-static", version: "1.3.2-r0", repo: "main")])
118 record(root, [Pkg(name: "openssl-libs-static", version: "3.3.7-r1", repo: "main")])
119 let entries = readManifest(root)
120 check entries.len == 2
121 check installed(root, "zlib-static")
122 check not installed(root, "absent")
123
124 test "re-recording replaces rather than duplicates":
125 record(root, [Pkg(name: "zlib-static", version: "1.3.3-r0", repo: "main")])
126 let entries = readManifest(root)
127 check entries.len == 2
128 for e in entries:
129 if e.name == "zlib-static": check e.version == "1.3.3-r0"
130
131 test "static libs are found and sorted":
132 createDir root / "usr" / "lib"
133 for name in ["libz.a", "libcrypto.a"]:
134 writeFile(root / "usr" / "lib" / name, "")
135 let libs = staticLibs(root)
136 check libs.len == 2
137 check libs[0].extractFilename == "libcrypto.a"
138
139 removeDir root
140
141suite "flags":
142 let root = getTempDir() / "nimstatic-test-flags"
143 removeDir root
144 createDir root / "usr" / "lib"
145
146 test "plain sysroot":
147 let f = nimFlags(root).join(" ")
148 check ("--passC:-I" & root & "/usr/include") in f
149 check "--passL:-static" in f
150 check "dynlibOverride" notin f
151
152 test "openssl archives switch on the static-TLS workarounds":
153 for name in ["libssl.a", "libcrypto.a"]:
154 writeFile(root / "usr" / "lib" / name, "")
155 let f = nimFlags(root, overridesIn(root), ["z"]).join(" ")
156 check "--dynlibOverride:ssl" in f
157 check "--dynlibOverride:crypto" in f
158 # OpenSSL 3 dropped the symbol Nim's wrapper still names
159 check "-DSSL_get_peer_certificate=SSL_get1_peer_certificate" in f
160 check "--passL:-lz" in f
161
162 test "cc flags and pkg-config env":
163 check ccFlags(root, ["ssl"]) == @["-I" & root & "/usr/include",
164 "-L" & root & "/usr/lib",
165 "-static", "-lssl"]
166 check pkgConfigEnv(root)[0] == "PKG_CONFIG_SYSROOT_DIR=" & root
167
168 test "an override with no archive in the sysroot is dropped":
169 # Asking Nim not to dlopen a library we cannot link would break the build.
170 let f = nimFlags(root, ["ghost"]).join(" ")
171 check "--dynlibOverride:ghost" notin f
172
173 test "libssl links before libcrypto":
174 let f = nimFlags(root, ["crypto", "ssl"]).join(" ")
175 check f.find("libssl.a") < f.find("libcrypto.a")
176
177 test "nimcfg carries the compiler and the flags":
178 let cfg = nimCfg(root, "/tmp/zigcc")
179 check "--cc:clang" in cfg
180 check "--clang.exe:\"/tmp/zigcc\"" in cfg
181 check "--passL:-static" in cfg
182
183 test "zigcc script targets the right triple":
184 let s = zigccScript("aarch64-linux-musl")
185 check "zig cc -target aarch64-linux-musl" in s
186 check "\"$@\"" in s
187
188 removeDir root
189
190suite "remote":
191 test "urls are built from mirror, branch, repo and arch":
192 let r = initRemote(branch = "edge", arch = "aarch64")
193 check r.repoUrl("community") ==
194 "https://dl-cdn.alpinelinux.org/alpine/edge/community/aarch64"
195 check apkFile(Pkg(name: "zlib-static", version: "1.3.2-r0")) ==
196 "zlib-static-1.3.2-r0.apk"
197
198suite "detection":
199 test "sonames reduce to library names":
200 check libFromSoname("libssl.so.3") == "ssl"
201 check libFromSoname("libpcre2-8.so.0") == "pcre2-8"
202 check libFromSoname("libcrypto.so(.3|.1.1|.10|)") == "crypto"
203 check libFromSoname("notalib") == ""
204 check libFromSoname("libnoso") == ""
205
206 test "link libraries come off the link command, once each":
207 let cmd = "gcc -o app a.o b.o -pthread -lm -lm -lrt -lpcre -ldl"
208 check linkLibs(cmd) == @["m", "rt", "pcre", "dl"]
209
210 test "dynlib candidates are found in generated C":
211 let c = """
212 static char* sslCandidates[] = {"libssl.so.3", "libssl.so.1.1"};
213 static char* cryptoCandidates[] = {"libcrypto.so(.3|.1.1|)"};
214 const char* unrelated = "libera chat";
215 """
216 check dynlibsIn(c) == @["ssl", "crypto"]
217
218 test "inspect maps libraries to packages and flags the rest":
219 let cache = getTempDir() / "nimstatic-test-cache"
220 removeDir cache
221 createDir cache
222 writeFile(cache / "app.json", """{"linkcmd": "gcc -o app a.o -lm -lsqlite3"}""")
223 writeFile(cache / "app.c", """char* c[] = {"libssl.so.3", "libmystery.so.1"};""")
224 let d = inspect(cache)
225
226 # libc's own are never requested
227 check not d.needs.anyIt(it.lib == "m")
228 check d.needs.anyIt(it.lib == "sqlite3" and not it.dynlib)
229 check d.needs.anyIt(it.lib == "ssl" and it.dynlib)
230 check "openssl-libs-static" in packages(d)
231 check "sqlite-static" in packages(d)
232 check d.unmapped == @["mystery"]
233 # only dlopen'd libraries need the override
234 check dynlibOverrides(d) == @["ssl"]
235 removeDir cache
236
237 test "--map overrides the built-in table":
238 let cache = getTempDir() / "nimstatic-test-cache2"
239 removeDir cache
240 createDir cache
241 writeFile(cache / "app.json", """{"linkcmd": "gcc -o app a.o"}""")
242 writeFile(cache / "app.c", """char* c[] = {"libmystery.so.1"};""")
243 let d = inspect(cache, {"mystery": "mystery-static"}.toTable)
244 check packages(d) == @["mystery-static"]
245 check d.unmapped.len == 0
246 removeDir cache