. "$BST_LIB" # BST-TIMEOUT: 300 # measured 73s (141 cases); the runner's default bound is 60 # wbxml2 (libwbxml 0.10.8) -- the WBXML binary-XML codec and its two converters, # wbxml2xml and xml2wbxml (meta-oe recipes-support/opensync). See # wbxml2_%.bbappend for what the port adds. # # --------------------------------------------------------------------------- # WHAT IS ACTUALLY BEING TESTED # # The deliverable is three packages: wbxml2-staticdev (/usr/lib/libwbxml2.a), # wbxml2-dev (seventeen headers + libwbxml2.pc) and wbxml2-tools (the two # converters). The two converters exercise ONE path through the library -- read # a whole file, convert it, write a whole file -- and always with default # parameters, so the version selector, the string table, the anonymous-document # option, the three XML generation shapes, the charset entry points, base64, the # language tables, the buffer/list primitives and every failure path would ship # entirely unexercised if the CLI were the whole of the coverage. # # So data/wbxml2-probe (src/wbxml2_probe.c) is cross-linked against THE VERY # ARCHIVE THAT SHIPS and drives the library directly. The CLI round trip below # is kept as well, because it is the only thing that proves the two INSTALLED # BINARIES work -- an archive can be perfect while the tools package is empty. # # --------------------------------------------------------------------------- # WHY THE ORACLE IS A NATIVE CAPTURE # # WBXML fixes the wire format but not libwbxml's choices within it: which # strings go to the string table, how an attribute value is split across a # token and an inline string, how the generator indents. None of that is # specified anywhere we could assert against a priori. So the expected values # are a NATIVE x86_64 capture -- data/wbxml2-native.txt, produced by the same # probe source against the same 0.10.8 source the recipe builds, checked # identical across three runs. # # The question this suite answers is therefore exactly "does the wasm32 build # agree, row for row, with the same source built natively" -- the porting # question and nothing more. wbxml2/native-identical is that assertion; the # per-area rows below exist so a reader sees WHICH area moved without re-running # anything. # # --------------------------------------------------------------------------- # THE TWO ROWS THAT LOOK WRONG AND ARE PINNED THAT WAY ON PURPOSE # # 1. DRMREL DOES NOT ROUND TRIP, ON EITHER ARCHITECTURE. Decoding a DRMREL 1.0 # document regenerates element names as their NAMESPACE URI -- # where the input had -- which is # not well-formed XML, and re-encoding it fails. It reproduces byte for byte # on the x86_64 control, in a table-driven code path with no libc, kernel or # wasm32 surface anywhere near it: an upstream libwbxml defect, not a porting # gap. The suite pins the observed answer so the port stays green while # libwbxml behaves as it does today and goes red the moment it changes -- # the only honest signal a port can give about someone else's bug. # # 2. base64 OF THE EMPTY STRING RETURNS NULL rather than the empty string. Same # story: identical on the control, pinned as observed. # # Neither is attributed to a platform issue, and neither is left unexplained. # # --------------------------------------------------------------------------- # AND THE ONE THAT IS A PROPERTY OF THE BUILD RATHER THAN THE PLATFORM # # wbxml_charset_conv() answers WBXML_ERROR_NO_CHARSET_CONV (12) for anything # outside the US-ASCII/UTF-8 fast path, because HAVE_ICONV is never defined by # libwbxml's cmake build on ANY platform -- there is no probe for it and no # #cmakedefine line for it. That is asserted here rather than merely noted, # because the day it became true would be the day iconv_open reached glibc's # gconv loader, which is a dlopen on an image that has no dynamic loader. lib=/usr/lib/libwbxml2.a hdr=/usr/include/wbxml.h cfghdr=/usr/include/wbxml_config.h pc=/usr/lib/pkgconfig/libwbxml2.pc x2w=/usr/bin/xml2wbxml w2x=/usr/bin/wbxml2xml shipped=$BST_DATA/wbxml2-probe control=$BST_DATA/wbxml2-native.txt tmp=${TMPDIR:-/tmp} probe=$tmp/bst-wbxml2-probe.$$ work=$tmp/bst-wbxml2-work.$$ if [ ! -f "$lib" ]; then bst_skip wbxml2/present "no $lib on this image" exit 0 fi bst_ok wbxml2/present check wbxml2/header-present test -f "$hdr" check wbxml2/config-header test -f "$cfghdr" check wbxml2/pkgconfig test -f "$pc" check wbxml2/probe-present test -f "$shipped" check wbxml2/control-present test -f "$control" sz=$(wc -c < "$lib" 2>/dev/null || echo 0) if [ "$sz" -gt 100000 ]; then bst_ok wbxml2/archive-nonempty else bst_notok wbxml2/archive-nonempty "libwbxml2.a is $sz bytes"; fi # The shipped header states the version and which document languages were # compiled in. A build that dropped one would still link and still round trip # WML, and only fail on the language it silently lost. check_out wbxml2/header-version '"0.10.8"' grep WBXML_LIB_VERSION "$cfghdr" for f in WML WTA SI SL CO PROV EMN DRMREL SYNCML WV AIRSYNC CONML; do if grep -q "define WBXML_SUPPORT_$f\$" "$cfghdr" 2>/dev/null; then bst_ok "wbxml2/lang-$f" else bst_notok "wbxml2/lang-$f" "WBXML_SUPPORT_$f not defined in $cfghdr" fi done # The static build must NOT have left the verbose logging on. if grep -q '^#define WBXML_LIB_VERBOSE' "$cfghdr" 2>/dev/null; then bst_notok wbxml2/quiet "WBXML_LIB_VERBOSE is on in a release image" else bst_ok wbxml2/quiet fi # --------------------------------------------------------------------------- # The two converters. Their presence is the runtime proof that the tools half of # the recipe produced something: FILES:${PN}-tools is "${bindir}", so a build # whose executables failed to link ships an empty package and goes red here. for t in "$x2w" "$w2x"; do n=${t##*/} if [ -x "$t" ]; then bst_ok "wbxml2/$n-present" out=$("$t" 2>&1); rc=$? if bst_execfail "$out"; then bst_unrun "wbxml2/$n-usage" "$out" else case "$out" in *"libwbxml 0.10.8"*) bst_ok "wbxml2/$n-usage" ;; *) bst_notok "wbxml2/$n-usage" "rc=$rc $(_bst_1line "$out")" ;; esac fi else bst_notok "wbxml2/$n-present" "no $t" bst_notok "wbxml2/$n-usage" "no $t" fi done # The CLI round trip, on target files: xml -> wbxml -> xml -> wbxml. The second # encoding must reproduce the first BYTE FOR BYTE, which is the deterministic # offline criterion this port is accepted on. Byte identity of the wire form is # the assertion rather than identity of the XML, because the decoder is free to # choose its own indentation and does. if mkdir -p "$work" 2>/dev/null; then bst_ok wbxml2/work-dir { printf '\n' printf '\n' printf '\n' printf ' \n' printf '

round trip on target

\n' printf '

emcraft

\n' printf '
\n' printf '
\n' } > "$work/in.xml" 2>/dev/null if [ -x "$x2w" ] && [ -x "$w2x" ] && "$x2w" -o "$work/a.wbxml" "$work/in.xml" > "$work/log" 2>&1 && "$w2x" -o "$work/b.xml" "$work/a.wbxml" >> "$work/log" 2>&1 && "$x2w" -o "$work/c.wbxml" "$work/b.xml" >> "$work/log" 2>&1; then bst_ok wbxml2/cli-roundtrip-ran if cmp -s "$work/a.wbxml" "$work/c.wbxml"; then bst_ok wbxml2/cli-roundtrip-stable else bst_notok wbxml2/cli-roundtrip-stable \ "re-encoded wbxml differs from the first encoding" fi # The encoded form must be a WBXML document and must be SMALLER than the # XML it came from -- binary XML that grew has tokenised nothing. head=$(od -An -N4 -tx1 < "$work/a.wbxml" 2>/dev/null | tr -d ' \n') check_eq wbxml2/cli-wire-header "03046a00" "$head" xsz=$(wc -c < "$work/in.xml" 2>/dev/null || echo 0) wsz=$(wc -c < "$work/a.wbxml" 2>/dev/null || echo 0) if [ "$wsz" -gt 0 ] && [ "$wsz" -lt "$xsz" ]; then bst_ok wbxml2/cli-encoded-smaller else bst_notok wbxml2/cli-encoded-smaller "wbxml $wsz vs xml $xsz" fi # The decoded document must carry the payload text and the DOCTYPE back. check_out wbxml2/cli-decoded-text 'round trip on target' cat "$work/b.xml" check_out wbxml2/cli-decoded-dtd 'WML 1.1//EN' cat "$work/b.xml" check_out wbxml2/cli-decoded-attr 'title="brintOS"' cat "$work/b.xml" else log=$(cat "$work/log" 2>/dev/null) if bst_execfail "$log"; then bst_unrun wbxml2/cli-roundtrip-ran "$log" else bst_notok wbxml2/cli-roundtrip-ran "$(_bst_1line "$log")" fi for c in cli-roundtrip-stable cli-wire-header cli-encoded-smaller \ cli-decoded-text cli-decoded-dtd cli-decoded-attr; do bst_notok "wbxml2/$c" "round trip did not run" done fi # A file that is not XML must be REFUSED, with the library's own message and # its own error code -- not accepted, and not a crash. printf 'this is not xml at all\n' > "$work/bad.xml" 2>/dev/null out=$("$x2w" -o "$work/bad.wbxml" "$work/bad.xml" 2>&1); rc=$? if bst_execfail "$out"; then bst_unrun wbxml2/cli-rejects-nonxml "$out" elif [ "$rc" -ne 0 ]; then bst_ok wbxml2/cli-rejects-nonxml else bst_notok wbxml2/cli-rejects-nonxml "accepted non-XML input (rc=0)" fi case "$out" in *"Parsing of XML Document Failed"*) bst_ok wbxml2/cli-rejects-message ;; *) bst_notok wbxml2/cli-rejects-message "$(_bst_1line "$out")" ;; esac # Truncated WBXML must be refused by the decoder for the same reason. printf '\003\004\152\000\177' > "$work/trunc.wbxml" 2>/dev/null out=$("$w2x" -o "$work/trunc.xml" "$work/trunc.wbxml" 2>&1); rc=$? if bst_execfail "$out"; then bst_unrun wbxml2/cli-rejects-truncated "$out" elif [ "$rc" -ne 0 ]; then bst_ok wbxml2/cli-rejects-truncated else bst_notok wbxml2/cli-rejects-truncated "accepted a truncated document" fi else bst_notok wbxml2/work-dir "cannot create $work" for c in cli-roundtrip-ran cli-roundtrip-stable cli-wire-header \ cli-encoded-smaller cli-decoded-text cli-decoded-dtd \ cli-decoded-attr cli-rejects-nonxml cli-rejects-message \ cli-rejects-truncated; do bst_notok "wbxml2/$c" "no work dir" done fi # --------------------------------------------------------------------------- # The library probe. data/ installs mode 0644 and the rootfs is read-only at # browser runtime, so stage it somewhere writable and set the bit there. if cp "$shipped" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then bst_ok wbxml2/probe-stage # stdout only: the library writes one diagnostic to stderr (see # probe-stderr-diag below) and the interleaving of two streams is not # something a byte-identity comparison may depend on. out=$("$probe" 2>/dev/null); rc=$? else bst_notok wbxml2/probe-stage "cannot stage $shipped" out=''; rc=127 fi if bst_execfail "$out"; then bst_unrun wbxml2/probe-ran "$out" elif [ -n "$out" ]; then bst_ok wbxml2/probe-ran else bst_notok wbxml2/probe-ran "probe printed nothing (rc=$rc)" fi check_eq wbxml2/probe-exit 0 "$rc" got=$(printf '%s\n' "$out" | grep '^W-') want=$(grep '^W-' "$control" 2>/dev/null) ngot=$(printf '%s\n' "$got" | grep -c '^W-') nwant=$(printf '%s\n' "$want" | grep -c '^W-') check_eq wbxml2/row-count "$nwant" "$ngot" # The whole-output assertion. Nothing is excluded from it: every row the probe # prints is a property of the library, and the probe deliberately prints no # value that depends on the host (no sizeof, no pointer, no time). if [ -n "$want" ] && [ "$got" = "$want" ]; then bst_ok wbxml2/native-identical else first=$(printf '%s\n' "$want" | while IFS= read -r w; do n=${w%% *} g=$(printf '%s\n' "$got" | grep "^$n " || echo "") [ "$g" = "$w" ] || { printf '%s: want [%s] got [%s]' "$n" "${w#* }" "${g#* }"; break; } done) bst_notok wbxml2/native-identical "$(_bst_1line "${first:-row counts differ}")" fi # w -> that row's value, from the TARGET run w() { printf '%s\n' "$got" | while IFS= read -r l; do case "$l" in "W-$1 "*) printf '%s\n' "${l#W-$1 }"; break ;; esac done } # ---- the library identifies itself as what the recipe built ---------------- check_eq wbxml2/probe-version "0.10.8" "$(w VERSION)" check_eq wbxml2/probe-strtbl "1" "$(w HAS-STRTBL)" # ---- language tables: the public ids are fixed by the WAP specs ------------- check_eq wbxml2/lt-wml11-pubid "4" "$(w LT-WML11-publicid)" check_eq wbxml2/lt-wml12-pubid "9" "$(w LT-WML12-publicid)" check_eq wbxml2/lt-wml13-pubid "10" "$(w LT-WML13-publicid)" check_eq wbxml2/lt-si10-pubid "5" "$(w LT-SI10-publicid)" check_eq wbxml2/lt-sl10-pubid "6" "$(w LT-SL10-publicid)" check_eq wbxml2/lt-co10-pubid "7" "$(w LT-CO10-publicid)" check_eq wbxml2/lt-prov10-pubid "11" "$(w LT-PROV10-publicid)" check_eq wbxml2/lt-emn10-pubid "13" "$(w LT-EMN10-publicid)" check_eq wbxml2/lt-drmrel-pubid "14" "$(w LT-DRMREL-publicid)" check_eq wbxml2/lt-conml-pubid "143" "$(w LT-CONML-publicid)" check_eq wbxml2/lt-unknown-absent "0" "$(w LT-UNKNOWN-found)" check_eq wbxml2/lt-wml11-root "wml" "$(w LT-WML11-root)" check_eq wbxml2/lt-drmrel-root "o-ex:rights" "$(w LT-DRMREL-root)" check_eq wbxml2/tbl-search-wml11 "4" "$(w TBL-search-wml11)" check_eq wbxml2/tbl-search-bogus "0" "$(w TBL-search-bogus)" check_eq wbxml2/tbl-search-root "5" "$(w TBL-search-root-si)" check_eq wbxml2/tbl-pubid-wml13 "10" "$(w TBL-pubid-wml13)" # WML 1.1 is token 0x27 on code page 0,

is 0x20. check_eq wbxml2/tbl-tag-card "39" "$(w TBL-tag-card)" check_eq wbxml2/tbl-tag-p "32" "$(w TBL-tag-p)" check_eq wbxml2/tbl-tag-absent "0" "$(w TBL-tag-absent)" # ---- charsets: the IANA MIBenum values, and the compiled-out converter ------ check_eq wbxml2/cs-utf8 "106" "$(w CS-mib-utf8)" check_eq wbxml2/cs-ascii "3" "$(w CS-mib-ascii)" check_eq wbxml2/cs-8859-1 "4" "$(w CS-mib-8859-1)" check_eq wbxml2/cs-bogus "0" "$(w CS-mib-bogus-found)" check_eq wbxml2/cs-name "UTF-8" "$(w CS-name-106)" check_eq wbxml2/cs-fastpath-rc "0" "$(w CS-conv-ascii-utf8-rc)" check_eq wbxml2/cs-fastpath-out "plain ascii" "$(w CS-conv-ascii-utf8-out)" # 12 == WBXML_ERROR_NO_CHARSET_CONV. See the header comment: this is upstream's # configuration on every platform, and the answer that keeps gconv/dlopen out. check_eq wbxml2/cs-no-iconv "12" "$(w CS-conv-latin1-utf8-rc)" # ---- base64 --------------------------------------------------------------- check_eq wbxml2/b64-empty-null "(null)" "$(w B64-enc-0)" check_eq wbxml2/b64-foobar "Zm9vYmFy" "$(w B64-enc-6)" check_eq wbxml2/b64-pad1 "Zm9vYg==" "$(w B64-enc-4)" check_eq wbxml2/b64-pad2 "Zg==" "$(w B64-enc-1)" check_eq wbxml2/b64-roundtrip "1" "$(w B64-roundtrip-6)" check_eq wbxml2/b64-bin-len "344" "$(w B64-bin-enc-len)" check_eq wbxml2/b64-bin-round "1" "$(w B64-bin-roundtrip)" # ---- the error table ------------------------------------------------------ check_eq wbxml2/err-ok "No Error" "$(w ERR-0)" check_eq wbxml2/err-unknown "Unknown Error Code" "$(w ERR-9999)" check_eq wbxml2/err-eob "Unexpected End Of WBXML Buffer" "$(w ERR-19)" # ---- round trips, per language -------------------------------------------- # enc-rc 0, stable 1: the encoder and decoder are each other's inverse over the # wire form for this document. That is the port's headline criterion. for l in wml11 wml13 si10 sl10 co10 emn10 prov10; do check_eq "wbxml2/rt-$l-enc" "0" "$(w RT-$l-enc-rc)" check_eq "wbxml2/rt-$l-dec" "0" "$(w RT-$l-dec-rc)" check_eq "wbxml2/rt-$l-stable" "1" "$(w RT-$l-stable)" done # The exact wire bytes for two of them, so a silent re-tokenisation is caught # even if it happened to stay self-consistent. check_eq wbxml2/rt-wml11-hex \ "03046a007fe755036d61696e0036036272696e744f530001600368656c6c6f207762786d6c000160dc4ba103776170666f72756d00880103666f72756d0001010101" \ "$(w RT-wml11-enc-hex)" check_eq wbxml2/rt-sl10-hex \ "03066a00850a03656d6372616674008503736c000501" \ "$(w RT-sl10-enc-hex)" check_eq wbxml2/rt-wml11-len "66" "$(w RT-wml11-enc-len)" # DRMREL: decode succeeds, and what it produces cannot be re-encoded. Pinned as # observed -- an upstream defect that reproduces identically on x86_64. See the # header comment. check_eq wbxml2/rt-drmrel-enc "0" "$(w RT-drmrel-enc-rc)" check_eq wbxml2/rt-drmrel-dec "0" "$(w RT-drmrel-dec-rc)" check_eq wbxml2/rt-drmrel-reenc-rc "42" "$(w RT-drmrel-reenc-rc)" check_eq wbxml2/rt-drmrel-unstable "-2" "$(w RT-drmrel-stable)" # Character references and CDATA are RESOLVED by the decoder, so the regenerated # document is semantically equal and not byte-equal, and re-encoding it does not # reproduce the first wire form. Also pinned as observed, and also identical on # the control -- this one is correct behaviour rather than a defect. check_eq wbxml2/rt-text-enc "0" "$(w RT-text-enc-rc)" check_eq wbxml2/rt-text-reenc-rc "0" "$(w RT-text-reenc-rc)" check_eq wbxml2/rt-text-unstable "0" "$(w RT-text-stable)" # ---- the encoder's parameters actually reach the wire ---------------------- # byte 0 of a WBXML document is the version token. check_eq wbxml2/ver-10 "00046a00" "$(w VER-0-head)" check_eq wbxml2/ver-11 "01046a00" "$(w VER-1-head)" check_eq wbxml2/ver-12 "02046a00" "$(w VER-2-head)" check_eq wbxml2/ver-13 "03046a00" "$(w VER-3-head)" check_eq wbxml2/strtbl-differ "1" "$(w STRTBL-differ)" check_eq wbxml2/strtbl-on-len "66" "$(w STRTBL-on-len)" check_eq wbxml2/strtbl-off-len "65" "$(w STRTBL-off-len)" # ---- the three XML generation shapes are distinct -------------------------- gc=$(w GEN-0-len); gi=$(w GEN-1-len); gn=$(w GEN-2-len) check_eq wbxml2/gen-compact-len "234" "$gc" check_eq wbxml2/gen-canonical-len "234" "$gn" if [ -n "$gi" ] && [ "$gi" -gt "$gc" ]; then bst_ok wbxml2/gen-indent-longer else bst_notok wbxml2/gen-indent-longer "indent=$gi compact=$gc" fi # Forcing the language rewrites the DOCTYPE the decoder emits. case "$(w GEN-forcelang-xml)" in *"WML 1.3//EN"*) bst_ok wbxml2/gen-forcelang ;; *) bst_notok wbxml2/gen-forcelang "$(_bst_1line "$(w GEN-forcelang-xml)")" ;; esac # ---- failure paths report, rather than crash or accept --------------------- check_eq wbxml2/bad-empty "4" "$(w BAD-empty-rc)" check_eq wbxml2/bad-truncated "19" "$(w BAD-trunc-rc)" check_eq wbxml2/bad-publicid "33" "$(w BAD-pubid-rc)" check_eq wbxml2/bad-notxml "42" "$(w BAD-notxml-rc)" check_eq wbxml2/bad-malformed "42" "$(w BAD-malformed-rc)" # ---- primitives: buffers, the WBXML multibyte integer, lists --------------- check_eq wbxml2/buf-len "6" "$(w BUF-len)" check_eq wbxml2/buf-append "abcdefghi" "$(w BUF-cstr2)" check_eq wbxml2/buf-search "3" "$(w BUF-search-pos)" check_eq wbxml2/buf-hex "646566676869" "$(w BUF-hex)" # mb_uint_32 is the WBXML wire integer: 7 bits a byte, high bit set on all but # the last. 128 -> 81 00 and 16384 -> 81 80 00 are the carry boundaries. check_eq wbxml2/mbuint-0 "00" "$(w MBU-0-hex)" check_eq wbxml2/mbuint-127 "7f" "$(w MBU-2-hex)" check_eq wbxml2/mbuint-128 "8100" "$(w MBU-3-hex)" check_eq wbxml2/mbuint-16383 "ff7f" "$(w MBU-4-hex)" check_eq wbxml2/mbuint-16384 "818000" "$(w MBU-5-hex)" check_eq wbxml2/lst-len "3" "$(w LST-len-3)" check_eq wbxml2/lst-insert "three" "$(w LST-get-0)" check_eq wbxml2/lst-extract "three" "$(w LST-extract-0)" # ---- one diagnostic goes to stderr, and says so with the wrong name -------- # wbxml_errors_string() on an unknown code logs through the library's own # WBXML_ERROR macro, which prints the literal token PACKAGE_NAME because # wbxml_log.h never substitutes it. Cosmetic, upstream, identical natively -- # asserted because it is also the suite's proof that stderr reaches the console. if cp "$shipped" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then diag=$("$probe" 2>&1 >/dev/null) case "$diag" in *"Unknown error code 9999"*) bst_ok wbxml2/probe-stderr-diag ;; *) bst_notok wbxml2/probe-stderr-diag "$(_bst_1line "$diag")" ;; esac else bst_notok wbxml2/probe-stderr-diag "cannot stage $shipped" fi rm -f "$probe" rm -rf "$work"