# BST-TIMEOUT: 900 # ptest-runner's own run is DURATION: 13 on this host and # testwolfcrypt adds its 37 vector suites on top; 900 is # headroom for a loaded host rather than a measured need. # The suite is cheap because upstream's unit.test is ONE # binary, not mbedtls's 139 — the cost here is arithmetic, # not module instantiation. . "$BST_LIB" # 76-wolfssl.test — wolfSSL 5.7.2 (meta-networking recipes-connectivity/wolfssl) # on wasm32-hwjs, closed on the package's own upstream test suite, which # OpenEmbedded packages as a ptest. # # Numbered into the 76 slot beside 76-openssl and 76-mbedtls, this image's other # general-purpose TLS-and-crypto libraries. The three are alternatives, not # layers: openssl is what most software links, mbedtls is what fits where openssl # does not, and wolfSSL is the one built for the small end — the same X.509, TLS # record layer and primitive set, in a library an order of magnitude smaller. # # THE ORACLE IS A NATIVE x86_64 CONTROL of the identical source (SRCREV 00e42151 # plus the recipe's nine CVE patches), configured with the recipe's own line # --disable-shared --enable-reproducible-build --enable-singlethreaded, and then # ALSO --disable-sha224 --disable-sha3: wolfSSL keys those two defaults off the # host CPU ("default: enabled on x86_64/amd64/aarch64"), so a stock native build # runs 19 cases a wasm32 build does not, and turning them off makes the control # case-for-case comparable. Staged into the SAME ptest layout the target runs and # driven by the SAME run-ptest under dash, that control reported 877 cases, # 162 passed / 709 skipped, and exactly one failure — the same one, the same # number. The target matched it with a zero-row diff. # # THE ONE EXPECTED RED IS test_wolfSSL_CTX_load_verify_locations, AND IT IS NOT # THIS PORT'S. The case loads every PEM CA under certs/external with # WOLFSSL_LOAD_FLAG_PEM_CA_ONLY, and two of the seven roots wolfSSL 5.7.2 ships # there — baltimore-cybertrust-root.pem and the first certificate in # ca_collection.pem — carry notAfter=May 12 23:59:00 2025 GMT. The release # predates their expiry; the calendar has since passed it, so the load fails and # takes the case with it. It fails identically on x86_64 today, which is what the # control is for. Left FAILING rather than skipped, per the project's # attributed-red rule: a suite made green by skipping a failing case is the thing # that rule forbids, and this one flips green on its own if the fixture is ever # refreshed. # # WHY THE SUITE RUNS AT ALL: SINGLE_THREADED. pthread_create does not work on this # guest (linux-in-the-browser#85 — per-task park slots are a K7+ milestone). With # threads left on, unit.test runs 600 cases clean and then dies inside # test_wolfSSL_SESSION, the first case that stands up a live TLS peer, with # glibc's "The futex facility returned an unexpected error code." and rc 127 — # so the remaining 277 cases are unreachable and the suite cannot complete. # The bbappend selects upstream's own --enable-singlethreaded arm, which gates # HAVE_IO_TESTS_DEPENDENCIES and SuiteTest off and makes those cases report # themselves as `skipped` in upstream's own listing. The in-memory TLS handshakes # (HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) are unaffected and still run, so the TLS # half of the library is exercised without a socket. p=/usr/lib/wolfssl/ptest # ------------------------------------------------------------- packaging --- # check_rc with `test` is an ash builtin and forks nothing, unlike check/check_out # whose command substitution does — so the presence half of this file is free on # an arm where every exec is a fresh wasm module instantiation. check_rc wolfssl/lib-static 0 test -f /usr/lib/libwolfssl.a check_rc wolfssl/header-ssl 0 test -f /usr/include/wolfssl/ssl.h check_rc wolfssl/header-wolfcrypt 0 test -f /usr/include/wolfssl/wolfcrypt/sha256.h check_rc wolfssl/header-openssl-compat 0 test -f /usr/include/wolfssl/openssl/ssl.h check_rc wolfssl/pkgconfig 0 test -f /usr/lib/pkgconfig/wolfssl.pc check_rc wolfssl/config-tool 0 test -x /usr/bin/wolfssl-config # No shared object on a distro that is static-only by policy. Pinned as a # positive: one appearing here means the distro-wide --disable-shared stopped # reaching this recipe, and ${PN}'s packaging would have changed with it. if [ -e /usr/lib/libwolfssl.so ]; then bst_notok wolfssl/static-only "a shared libwolfssl shipped on a static-only distro" else bst_ok wolfssl/static-only fi # --------------------------------------------------------- ptest payload --- check_rc wolfssl/ptest-runptest 0 test -x "$p/run-ptest" check_rc wolfssl/ptest-unittest 0 test -x "$p/test/unit.test" check_rc wolfssl/ptest-wolfcrypt 0 test -x "$p/test/testwolfcrypt" check_rc wolfssl/ptest-certs 0 test -f "$p/certs/client-key.der" check_rc wolfssl/ptest-certs-external 0 test -d "$p/certs/external" # The cipher-suite .conf files SuiteTest reads. They ship whether or not # SINGLE_THREADED compiles SuiteTest out, so a count that drops is a packaging # regression rather than a configuration one. nconf=0 for f in "$p"/tests/*.conf; do [ -f "$f" ] && nconf=$((nconf+1)); done if [ "$nconf" -ge 40 ]; then bst_ok wolfssl/ptest-confs else bst_notok wolfssl/ptest-confs "only $nconf tests/*.conf, expected at least 40"; fi # ------------------------------------------------ the tool, against control --- # wolfssl-config is the only file a target shell can run from ${PN}; it is what a # consumer's build system asks where the library is. check_out wolfssl/tool-version "5.7.2" wolfssl-config --version check_out wolfssl/tool-libs "-lwolfssl" wolfssl-config --libs # -------------------------------------- upstream's crypto vectors (added) --- # testwolfcrypt is upstream's own primitive-level suite, built from the same tree # and added to the ptest directory by this layer's bbappend (meta-networking # packages only unit.test). It matters here because the SINGLE_THREADED arm skips # 709 of unit.test's 877 cases, so without this the primitives would be nearly # unexercised: 37 suites of published vectors — MD5/SHA/SHA-2, HMAC, the TLS 1.2 # and 1.3 KDFs, AES and AES-GCM, ChaCha20-Poly1305, RSA, DH, ECC. The native # control ran all 37 green. if [ ! -x "$p/test/testwolfcrypt" ]; then bst_notok wolfssl/wolfcrypt-vectors "testwolfcrypt is not in the ptest payload" else wc_out=$(cd "$p" && ./test/testwolfcrypt 2>&1) wc_rc=$? wc_n=$(printf '%s\n' "$wc_out" | grep -c 'test passed!') if [ "$wc_rc" -eq 0 ] && [ "$wc_n" -ge 37 ]; then bst_ok wolfssl/wolfcrypt-vectors else bst_notok wolfssl/wolfcrypt-vectors "rc=$wc_rc, $wc_n/37 vector suites passed"; fi case "$wc_out" in *"Test complete"*) bst_ok wolfssl/wolfcrypt-complete ;; *) bst_notok wolfssl/wolfcrypt-complete "testwolfcrypt did not reach 'Test complete'" ;; esac fi # ------------------------------------------------- upstream's own test suite --- # THE GATE. ptest-runner is the harness the ticket closes on, driving # meta-networking's run-ptest unmodified. -t is set well past ptest-runner's 300 s # DEFAULT_TIMEOUT; it bounds nothing in practice (relative timers do not fire, # linux-in-the-browser#120), so a tight value would be an assertion about nothing. if [ ! -x /usr/bin/ptest-runner ]; then bst_notok wolfssl/ptest-suite "no ptest-runner on the image -- the suite cannot be run" else out=$(/usr/bin/ptest-runner -t 20000 wolfssl 2>&1) # ptest-runner's own framing. run-ptest exits 0 whatever the cases did (its # NUM_FAILS greps for "Failed", which unit.test never prints), so FAIL: 0 is a # statement about the harness having run, not about the suite's verdict — the # verdict is the PASS:/FAIL: line and the per-case parse below. case "$out" in *"TOTAL: 1 FAIL: 0"*) bst_ok wolfssl/ptest-harness ;; *) bst_notok wolfssl/ptest-harness "ptest-runner did not report TOTAL: 1 FAIL: 0" ;; esac # run-ptest redirects unit.test's whole transcript into a mktemp directory and # prints where; nothing per-case reaches ptest-runner's stdout. Read it back # from the path it names rather than re-running the binary, so the cases scored # below are the ones the harness itself just ran. log=$(printf '%s\n' "$out" | sed -n 's/^Wolfssl ptest logs are stored in //p' | head -1) if [ -z "$log" ] || [ ! -f "$log" ]; then bst_notok wolfssl/ptest-transcript "run-ptest named no readable transcript" else bst_ok wolfssl/ptest-transcript # The run reached upstream's own end-of-suite line. This is what goes red if # SINGLE_THREADED is ever lost: the futex abort kills unit.test at case 601 # and nothing after it is reached. case "$(cat "$log")" in *"End API Tests"*) bst_ok wolfssl/suite-complete ;; *) bst_notok wolfssl/suite-complete "unit.test did not reach 'End API Tests' -- run truncated" ;; esac npass=$(grep -c ': passed' "$log") nskip=$(grep -c ': skipped' "$log") nlast=$(grep -oE '^ *[0-9]+: ' "$log" | tr -d ' :' | sort -n | tail -1) # Bounded from below, not pinned: upstream adds cases between releases and a # pinned equality would go false on a rebase that changed nothing here. The # measured figures on 2026-08-08 were 877 / 162 / 709, identical to control. if [ "${nlast:-0}" -ge 877 ]; then bst_ok wolfssl/suite-cases else bst_notok wolfssl/suite-cases "highest case index $nlast, expected at least 877"; fi if [ "$npass" -ge 160 ]; then bst_ok wolfssl/suite-passcount else bst_notok wolfssl/suite-passcount "only $npass cases passed, expected at least 160 ($nskip skipped)"; fi # The SINGLE_THREADED pin. test_wolfSSL_SESSION is the case that killed the # process outright when threads were on; upstream reports it `skipped` under # the single-threaded arm. Pinned so a rebase that quietly drops the # PACKAGECONFIG is one red here rather than a truncated run nobody reads. if grep -qE 'test_wolfSSL_SESSION +: *skipped' "$log"; then bst_ok wolfssl/singlethreaded-pin else bst_notok wolfssl/singlethreaded-pin "test_wolfSSL_SESSION is not reported skipped -- the SINGLE_THREADED arm was lost (linux-in-the-browser#85)" fi # The failure set, scored as a set rather than a count: exactly one case is # expected to fail and it is named. A second red shows up here as a distinct # case, so a real regression is never hidden behind the expected one. fails=$(sed -n '/^FAILURES:/,/^$/p' "$log" | grep -oE '[0-9]+: [A-Za-z0-9_]+' | sed 's/^[0-9]*: //') nfail=$(printf '%s\n' "$fails" | grep -c '[A-Za-z]') unexpected=$(printf '%s\n' "$fails" | grep -v '^test_wolfSSL_CTX_load_verify_locations$' | grep '[A-Za-z]') if [ -z "$unexpected" ]; then bst_ok wolfssl/suite-no-new-reds else bst_notok wolfssl/suite-no-new-reds "unexpected failing case(s): $(printf '%s' "$unexpected" | tr '\n' ' ')"; fi # The attributed red itself, carried as a case so it is visible in every # report rather than only in prose. Expired upstream fixture, reproduced on # the native x86_64 control; see the header. if [ "$nfail" -eq 0 ]; then bst_ok wolfssl/c-load-verify-locations else bst_notok wolfssl/c-load-verify-locations "upstream fixture certs/external carries two roots that expired 2025-05-12; the native x86_64 control fails this case identically" fi fi fi