# BST-TIMEOUT: 900 # One probe exec that decodes 517 images out of 125 files # # through libXcursor, plus one gawk join over its output and # # a handful of dpkg queries. Under the 46-68x wall-clock # # factor this platform carries (linux-in-the-browser#117) # # that is minutes. The bound is a LOAD bound: it must fire # # when the guest is starved, not when the package regressed. . "$BST_LIB" # xcursor-themes 1.0.7 -- the default cursor themes for libXcursor: handhelds, # redglass and whiteglass. # # THIS SUITE CLOSES A ROUND TRIP, which is what makes it worth more than a # file-presence check. The build ENCODED: the native x86-64 xcursorgen read 487 # PNGs and wrote 517 images into 125 cursor files. This DECODES: the wasm32 # libXcursor on this image (BRINTOS-2335) reads the same files back. The # expectation -- /usr/libexec/xcursor-themes-tests/EXPECT -- comes from NEITHER # end: it is the themes' own .cfg text, plus the source PNGs decoded and # premultiplied independently in Python at build time, reproducing xcursorgen's # div_255 rounding and its ARGB packing. So a disagreement here is a statement # about this arm rather than about either parser agreeing with itself. # # WHAT AN ARGB OR STRIDE ERROR LOOKS LIKE, AND WHICH FIGURE CATCHES IT. The # ticket asks for the first and last pixel of a decoded frame against literals. # They are asserted -- but every corner of every cursor in this package is # transparent, measured: first and last come back 0x00000000 for all 517 images, # so 0 against 0 cannot catch a channel swap. Three figures that can are carried # beside them: # # * sumR / sumG / sumB, per-channel totals over the whole image. A red/blue # transposition exchanges sumR and sumB, which differ on 317 of the 517 # images; a green/blue one exchanges sumG and sumB, which differ on 80. Both # counts were measured on 1.0.7, and between them no swap passes the set. # * the pixel AT THE HOTSPOT, which is inside the drawn shape rather than in # the transparent margin. # * w and h separately, against a theme that has NON-SQUARE cursors -- # redglass's watch frames are 14x16 out of a 16px PNG. A stride error on a # square image can cancel; on a 14x16 one it cannot. # # THE ROOTFS IS THE SUBJECT, NOT ${D}. The census ran at do_install and refused # the build on any difference, so its fails=0 is asserted below as evidence that # the checks RAN. What this suite adds is everything that can go wrong after # them: a FILES glob that stopped claiming a cursor, a package split, an image # that shipped a different .deb than the CENSUS came from. # # WRITTEN TO EXEC AS LITTLE AS POSSIBLE. On this arm a process's memory is not # returned when it exits and /bin/sh alone is a 16 MB wasm module, so the 517 # images are decoded by ONE exec and compared by one gawk pass; the per-theme and # per-literal cases below cost no exec at all. S=xcursor-themes ICONS=/usr/share/icons TD=/usr/libexec/xcursor-themes-tests PROBE=$TD/xcursor-themes-probe PKGVER=1.0.7 t=${TMPDIR:-/tmp}/bst-xct.$$ mkdir -p "$t" 2>/dev/null # brintos/linux#96 drops the first result line of a suite. This case exists to # be the line that is lost; every assertion below it is then reported. bst_ok $S/suite-canary require gawk $S/gawk-present if [ -d "$ICONS" ]; then bst_ok $S/icons-root; else bst_notok $S/icons-root "$ICONS is not a directory" return 2>/dev/null || exit 0; fi if [ -x "$PROBE" ]; then bst_ok $S/probe-installed; else bst_notok $S/probe-installed "$PROBE is missing or not executable -- xcursor-themes-tests did not land" return 2>/dev/null || exit 0; fi if [ -f "$TD/EXPECT" ]; then bst_ok $S/expect-shipped; else bst_notok $S/expect-shipped "$TD/EXPECT is missing -- the port shipped no expectation, so there is nothing to decode against" return 2>/dev/null || exit 0; fi if [ -f "$TD/CENSUS" ]; then bst_ok $S/census-shipped; else bst_notok $S/census-shipped "$TD/CENSUS is missing"; fi # ---------------------------------------------------------------- the decode # bst_probe rather than a plain run: a probe that wedges must not take the # suite's remaining cases with it, and what it had already printed is kept. # $ICONS is absolute, which the probe requires and checks -- a relative entry on # XCURSOR_PATH resolves against the cwd and turns every by-name lookup into a # NULL indistinguishable from a missing theme. bst_probe $S/probe-runs "$t/probe.out" 600 "$PROBE" "$ICONS" "$t" if [ -s "$t/probe.out" ]; then bst_ok $S/probe-produced-output; else bst_notok $S/probe-produced-output "the probe printed nothing" return 2>/dev/null || exit 0; fi # The terminator. Without it the counts below are taken off a truncated capture, # and a short decode would read as a clean one. XP_END=$(sed -n 's/^PROBE-END //p' "$t/probe.out") if [ -n "$XP_END" ]; then bst_ok $S/probe-reached-end; else bst_notok $S/probe-reached-end "no PROBE-END line -- the probe did not run to completion, so nothing below is a complete result"; fi check_eq $S/probe-no-fatal "" "$(sed -n 's/^PROBE-END fatal=/fatal=/p' "$t/probe.out")" # --------------------------------------------------------------- the join # One gawk pass: every field of every PROBE-IMAGE line against the EXPECT line # for the same theme/cursor/index, plus the per-cursor image counts and the link # set. `png' and `cfgdelay' are expectation-side only -- the probe cannot see # which PNG a cursor came from, or whether the cfg named a delay -- so they are # skipped by name rather than counted as unjoined. gawk -v E="$TD/EXPECT" ' function kv(start, i,a) { delete f; for (i = start; i <= NF; i++) { split($i, a, "="); f[a[1]] = a[2] } } BEGIN { while ((getline l < E) > 0) { n = split(l, g, " ") if (g[1] == "EXPECT-IMAGE") { k = g[2] " " g[3] " " g[4] for (i = 5; i <= n; i++) { split(g[i], a, "="); if (a[1] != "png" && a[1] != "cfgdelay") e[k " " a[1]] = a[2] } ek[k] = 1 } else if (g[1] == "EXPECT-CURSOR") { split(g[4], a, "="); ec[g[2] " " g[3]] = a[2] } else if (g[1] == "EXPECT-LINK") { el[g[2] " " g[3]] = g[5] } else if (g[1] == "EXPECT-COUNT") { for (i = 2; i <= n; i++) { split(g[i], a, "="); xc[a[1]] = a[2] } } } } /^PROBE-IMAGE / { kv(5); k = $2 " " $3 " " $4; pk[k] = 1 for (x in f) { if ((k " " x) in e) { cmp++ if (e[k " " x] != f[x]) { bad++; if (!ex) ex = k " " x " got=" f[x] " want=" e[k " " x] } } else unj = unj " " x } next } /^PROBE-CURSOR / { split($4, a, "="); pc[$2 " " $3] = 1 if (ec[$2 " " $3] != a[2]) { cbad++; if (!cex) cex = $2 " " $3 " images=" a[2] " want=" ec[$2 " " $3] } else cok++ next } /^PROBE-LINK / { pl[$2 " " $3] = 1 if (!(($2 " " $3) in el)) { lextra++; if (!lex) lex = $2 " " $3 " is in the rootfs and not in EXPECT" } else if ($5 != el[$2 " " $3]) { ldangle++; if (!lex) lex = $2 " " $3 " -> " $5 " want -> " el[$2 " " $3] } else if ($6 != "resolves=1") { ldangle++; if (!lex) lex = $2 " " $3 " " $6 } else lok++ next } /^PROBE-LOADFAIL /{ lf++; if (!lfex) lfex = $0; next } /^PROBE-ENTRY / { oddity++; if (!oex) oex = $0; next } /^PROBE-THEME / { if ($3 ~ /^files=/) { split($3, a, "="); split($4, b, "=") print "XT_T_" $2 "_FILES=\047" a[2] "\047" print "XT_T_" $2 "_LINKS=\047" b[2] "\047" } else { themebad++; if (!tex) tex = $0 } next } /^PROBE-MISS / { split($2, a, " "); m = $2; r = $5; sub(/^result=/, "", r) gsub(/-/, "_", m); print "XT_MISS_" m "=\047" r "\047"; next } /^PROBE-LIB / { n = split($0, g, " ") v = ""; for (i = 4; i <= n; i++) v = v (v == "" ? "" : " ") g[i] k = $2 "_" $3 "_" g[4]; gsub(/[^A-Za-z0-9_]/, "_", k) print "XT_LIB_" k "=\047" v "\047"; next } /^PROBE-PATH / { print "XT_PATH=\047" $2 "\047"; next } /^PROBE-SHAPE / { print "XT_SHAPE=\047" $2 " " $3 " " $4 "\047"; next } /^PROBE-SETUP / { print "XT_SETUP=\047" $2 " " $3 "\047"; next } END { for (k in ek) if (!(k in pk)) { miss++; if (!mex) mex = k } for (k in pk) if (!(k in ek)) { extra++; if (!mex) mex = k " is decoded and not declared" } for (k in ec) if (!(k in pc)) { cmiss++; if (!cex) cex = k " declared and not decoded" } for (k in el) if (!(k in pl)) { lmiss++; if (!lex) lex = k " declared and not in the rootfs" } printf "XT_CMP=\047%d\047\nXT_BAD=\047%d\047\nXT_MISS=\047%d\047\nXT_EXTRA=\047%d\047\n", cmp+0, bad+0, miss+0, extra+0 printf "XT_COK=\047%d\047\nXT_CBAD=\047%d\047\nXT_CMISS=\047%d\047\n", cok+0, cbad+0, cmiss+0 printf "XT_LOK=\047%d\047\nXT_LMISS=\047%d\047\nXT_LEXTRA=\047%d\047\nXT_LDANGLE=\047%d\047\n", lok+0, lmiss+0, lextra+0, ldangle+0 printf "XT_LOADFAIL=\047%d\047\nXT_ODDITY=\047%d\047\nXT_THEMEBAD=\047%d\047\nXT_UNJOINED=\047%s\047\n", lf+0, oddity+0, themebad+0, unj printf "XT_EX=\047%s\047\nXT_CEX=\047%s\047\nXT_LEX=\047%s\047\nXT_MEX=\047%s\047\n", ex, cex, lex, mex printf "XT_LFEX=\047%s\047\nXT_OEX=\047%s\047\nXT_TEX=\047%s\047\n", lfex, oex, tex printf "XT_X_THEMES=\047%s\047\nXT_X_CURSORS=\047%s\047\nXT_X_LINKS=\047%s\047\nXT_X_IMAGES=\047%s\047\n", xc["themes"], xc["cursors"], xc["links"], xc["images"] }' "$t/probe.out" > "$t/f1" . "$t/f1" # Every declared image was compared, and every comparison agreed. The first is # what refuses a run that compared 400 of 517 and reported no differences over # the other 117 -- a figure never compared is not a figure that agreed. check_eq $S/images-compared "8272" "${XT_CMP:-x}" check_eq $S/images-agree 0 "${XT_BAD:-x}" check_eq $S/images-none-missing 0 "${XT_MISS:-x}" check_eq $S/images-none-extra 0 "${XT_EXTRA:-x}" check_eq $S/images-first-difference "" "${XT_EX-unset}" check_eq $S/fields-all-joined "" "${XT_UNJOINED-unset}" check_eq $S/cursors-decoded 125 "${XT_COK:-x}" check_eq $S/cursors-image-counts 0 "${XT_CBAD:-x}" check_eq $S/cursors-none-missing 0 "${XT_CMISS:-x}" check_eq $S/cursors-first-difference "" "${XT_CEX-unset}" check_eq $S/no-load-failures 0 "${XT_LOADFAIL:-x}" check_eq $S/load-failure-detail "" "${XT_LFEX-unset}" check_eq $S/no-odd-entries 0 "${XT_ODDITY:-x}" check_eq $S/odd-entry-detail "" "${XT_OEX-unset}" check_eq $S/every-theme-opened 0 "${XT_THEMEBAD:-x}" check_eq $S/theme-open-detail "" "${XT_TEX-unset}" # ------------------------------------------------------------- the link set # The hazard BRINTOS-1386 asked to check rather than assume: every alias in # these themes is a symlink, and one pointing at a name the theme does not build # is a dangling link no "the directory exists" check would notice. Asserted # three ways -- the target string against the theme's own declaration (inside the # join), resolution through the link (the probe's stat(2), which FOLLOWS the # chain), and the counts here. check_eq $S/links-resolve 31 "${XT_LOK:-x}" check_eq $S/links-none-dangling 0 "${XT_LDANGLE:-x}" check_eq $S/links-none-missing 0 "${XT_LMISS:-x}" check_eq $S/links-none-extra 0 "${XT_LEXTRA:-x}" check_eq $S/links-first-difference "" "${XT_LEX-unset}" # --------------------------------------------------------- the per-theme shape # Typed literals, not read from EXPECT: a corrupted expectation cannot make # these green. handhelds and redglass carry the same 37 cursors and 9 aliases; # whiteglass carries 51 and 13. check_eq $S/handhelds-files 37 "${XT_T_handhelds_FILES:-x}" check_eq $S/handhelds-links 9 "${XT_T_handhelds_LINKS:-x}" check_eq $S/redglass-files 37 "${XT_T_redglass_FILES:-x}" check_eq $S/redglass-links 9 "${XT_T_redglass_LINKS:-x}" check_eq $S/whiteglass-files 51 "${XT_T_whiteglass_FILES:-x}" check_eq $S/whiteglass-links 13 "${XT_T_whiteglass_LINKS:-x}" check_eq $S/expect-themes 3 "${XT_X_THEMES:-x}" check_eq $S/expect-cursors 125 "${XT_X_CURSORS:-x}" check_eq $S/expect-links 31 "${XT_X_LINKS:-x}" check_eq $S/expect-images 517 "${XT_X_IMAGES:-x}" # ------------------------------------------------------ the pinned literals # Four images, typed out in full, one per interesting shape. These are what the # ticket asks for: the assertion is against what the theme IS -- the numbers its # .cfg declares and the pixels its PNG holds -- rather than against what the # library happens to return. They duplicate part of the join deliberately, so # that a build shipping a self-consistent but WRONG pair of probe and EXPECT # still reddens here. # # delay=50 on the two that declare none is not a typo and not a default this # suite invented: xcursorgen substitutes 50 ms when a cfg line omits the field # (xcursorgen.c:93). Measured on a native x86-64 build of this same source, # where all 467 images whose cfg omits it carry 50. XT_L1=$(sed -n 's/^PROBE-IMAGE handhelds left_ptr 0 //p' "$t/probe.out") check_eq $S/literal-handhelds-left_ptr \ "size=12 w=16 h=16 xhot=1 yhot=1 delay=50 first=0x00000000 last=0x00000000 hot=0x67404040 sum=0xd799f2ec opaque=0 nonzero=137 sumA=12473 sumR=7827 sumG=1772 sumB=1772" \ "${XT_L1:-unset}" # redglass/watch frame 0: the animated case AND the non-square one. 14x16 out of # a 16px PNG, so a stride error cannot cancel the way it can on a square image, # and delay=200 is a value the cfg states rather than xcursorgen's default. XT_L2=$(sed -n 's/^PROBE-IMAGE redglass watch 0 //p' "$t/probe.out") check_eq $S/literal-redglass-watch-frame0 \ "size=12 w=14 h=16 xhot=8 yhot=8 delay=200 first=0x00000000 last=0x00000000 hot=0xd1292929 sum=0xffbecebe opaque=8 nonzero=140 sumA=23763 sumR=11438 sumG=4286 sumB=4286" \ "${XT_L2:-unset}" # The largest image in the package, and the one whose channel sums are all equal # -- whiteglass is grey, so this one is asserted for its geometry and its alpha # rather than as a channel-order guard. The guard is the 317/80 spread across the # whole set, above. XT_L3=$(sed -n 's/^PROBE-IMAGE whiteglass left_ptr 4 //p' "$t/probe.out") check_eq $S/literal-whiteglass-left_ptr-48 \ "size=48 w=64 h=64 xhot=6 yhot=6 delay=50 first=0x00000000 last=0x00000000 hot=0x48000000 sum=0x018e8d29 opaque=0 nonzero=1711 sumA=170908 sumR=91177 sumG=91177 sumB=91177" \ "${XT_L3:-unset}" # The two animations, by image count. redglass/watch is 8 frames at each of 5 # nominal sizes; left_ptr_watch is 2 at each. whiteglass's left_ptr_watch is NOT # animated -- 5 images, one per size -- which is a difference between the themes # rather than a fault, and is pinned so that it stays visible. check_eq $S/anim-redglass-watch "images=40" "$(sed -n 's/^PROBE-CURSOR redglass watch //p' "$t/probe.out")" check_eq $S/anim-redglass-left_ptr_watch "images=10" "$(sed -n 's/^PROBE-CURSOR redglass left_ptr_watch //p' "$t/probe.out")" check_eq $S/anim-whiteglass-left_ptr_watch "images=5" "$(sed -n 's/^PROBE-CURSOR whiteglass left_ptr_watch //p' "$t/probe.out")" check_eq $S/handhelds-single-size "images=1" "$(sed -n 's/^PROBE-CURSOR handhelds left_ptr //p' "$t/probe.out")" # ------------------------------------------------- resolution by name # XcursorLibraryLoadImages with XCURSOR_PATH pointing at the installed tree: # the path a client actually takes, and the one the ticket names. The figures # are the MATCHER's, and each is a decision worth pinning: # # * an exact nominal-size hit returns that size; # * handhelds declares only size 12, so asking for 48 there returns 12 -- the # nearest-size arm, not a miss; # * asking redglass/watch for 12 returns EIGHT images, the frames at that # nominal size, where a non-animated cursor returns one; # * whiteglass/hand2 declares 10,16,22,32,48 rather than the usual set, so 24 # resolves to 22 -- a literal that would move if the cfg changed. check_eq $S/lib-handhelds-exact "asked=12 nimage=1 chosen=12 w=16 h=16" "${XT_LIB_handhelds_left_ptr_asked_12:-unset}" check_eq $S/lib-handhelds-nearest "asked=48 nimage=1 chosen=12 w=16 h=16" "${XT_LIB_handhelds_left_ptr_asked_48:-unset}" check_eq $S/lib-redglass-exact "asked=24 nimage=1 chosen=24 w=32 h=32" "${XT_LIB_redglass_left_ptr_asked_24:-unset}" check_eq $S/lib-redglass-animated "asked=12 nimage=8 chosen=12 w=14 h=16" "${XT_LIB_redglass_watch_asked_12:-unset}" check_eq $S/lib-whiteglass-exact "asked=48 nimage=1 chosen=48 w=64 h=64" "${XT_LIB_whiteglass_left_ptr_asked_48:-unset}" # THROUGH THE ALIASES, including the two-hop one. whiteglass ships # `pointer -> hand' and `hand -> hand2', so `pointer' is two symlinks from the # file it names. Both must resolve to the SAME images as hand2 itself, which is # what says the library follows the chain rather than stopping at the first link. check_eq $S/lib-alias-one-hop "asked=24 nimage=1 chosen=22 w=32 h=37" "${XT_LIB_whiteglass_hand_asked_24:-unset}" check_eq $S/lib-alias-two-hop "asked=24 nimage=1 chosen=22 w=32 h=37" "${XT_LIB_whiteglass_pointer_asked_24:-unset}" check_eq $S/lib-alias-agree "${XT_LIB_whiteglass_hand_asked_24:-a}" "${XT_LIB_whiteglass_pointer_asked_24:-b}" check_eq $S/lib-alias-handhelds "asked=12 nimage=1 chosen=12 w=16 h=16" "${XT_LIB_handhelds_top_left_arrow_asked_12:-unset}" # --------------------------------------------------------- the error paths # Each is the library's DOCUMENTED result, asserted as a result rather than as # "it did not crash". XcursorLibraryLoadImages falls back to the theme named # "default" when the one asked for does not have the cursor (library.c:321), so # each NULL below is also a statement that no `default' theme is installed to # absorb the miss. check_eq $S/neg-name-absent "NULL" "${XT_MISS_name_absent:-unset}" check_eq $S/neg-theme-absent "NULL" "${XT_MISS_theme_absent:-unset}" check_eq $S/neg-null-name "NULL" "${XT_MISS_null_name:-unset}" # A theme whose index.theme names an inherited theme that is not installed. The # probe writes that theme under its own scratch directory at run time -- this # package ships no index.theme at all (see below), so the inherit chain has no # positive case here and its failure arm is tested without fabricating a file # into the package. check_eq $S/neg-inherit-missing "NULL" "${XT_MISS_inherit_missing:-unset}" # AND THE UNBOUNDED-LOOKUP CASE, which is the one that could hang rather than # answer: an index.theme naming ITSELF. library.c breaks that explicitly (the # "Detect and break self reference loop early on" arm, bounded also by # MAX_INHERITS_DEPTH 32); this is what says the break is present on this arm. # The suite reaching its end at all is half the assertion. check_eq $S/neg-inherit-self "NULL" "${XT_MISS_inherit_self:-unset}" # XCURSOR_CORE_THEME is a magic name: XcursorScanTheme returns a sentinel rather # than a file and XcursorLibraryLoadImages turns it into NULL (library.c:241, # :324). Reached only for a name in the core set, so the shape ids are asserted # beside it -- left_ptr and xterm are core shapes, and a name no theme defines # is -1. check_eq $S/neg-core-theme "NULL" "${XT_MISS_core_theme:-unset}" check_eq $S/shape-ids "left_ptr=68 xterm=152 bst-absent=-1" "${XT_SHAPE:-unset}" # Both scratch themes were created. Without this, the two cases above would pass # by looking up a theme that was never there -- the same NULL for the wrong # reason. check_eq $S/neg-scratch-created "ghost=0 self=0" "${XT_SETUP:-unset}" check_eq $S/xcursor-path "$t:$ICONS" "${XT_PATH:-unset}" # ------------------------------------------------------- no index.theme # 1.0.7 ships none and generates none, so the ABSENCE is asserted. Fabricating # one would be the only thing in this port that a native build of the same # version does not produce. A release that starts shipping one turns this red, # which is the prompt to decide how to package it -- the same reading, and the # same reason, as xcursor-transparent-theme's `no-index-theme-upstream'. # Scoped to the three themes this package owns, NOT to $ICONS: that root is # shared, and hicolor-icon-theme ships /usr/share/icons/hicolor/index.theme, so # a sweep of the whole tree answers a question about somebody else's package. check_eq $S/no-index-theme-upstream 0 \ "$(find "$ICONS/handhelds" "$ICONS/redglass" "$ICONS/whiteglass" \ -name index.theme 2>/dev/null | wc -l)" # ------------------------------------------------------------ the packaging # What "ported" means here, stated against the package database rather than the # directory: the .deb installed, and it owns the files the recipe promised. if command -v dpkg >/dev/null 2>&1; then if dpkg -s xcursor-themes >/dev/null 2>&1; then bst_ok $S/pkg-installed else bst_notok $S/pkg-installed "dpkg does not know xcursor-themes" fi check_eq $S/pkg-version "$PKGVER-r0" \ "$(dpkg -s xcursor-themes 2>/dev/null | sed -n 's/^Version: //p')" if dpkg -s xcursor-themes-tests >/dev/null 2>&1; then bst_ok $S/pkg-tests-installed else bst_notok $S/pkg-tests-installed "dpkg does not know xcursor-themes-tests" fi # The arm's, not `all': xorg-data-common.inc does not inherit allarch, so the # payload being architecture-independent and the PACKAGE being so are two # different claims and only the first is true here. Same reading as xbitmaps. check_eq $S/pkg-architecture "wasm32" \ "$(dpkg -s xcursor-themes 2>/dev/null | sed -n 's/^Architecture: //p')" # A third independent view of the same set: the recipe's census, the directory # the probe walked, and now the package database. This is the one that catches # a rootfs assembled from a different .deb than the CENSUS came from. XT_DPKG_CUR=$(dpkg -L xcursor-themes 2>/dev/null | grep -c "^$ICONS/[a-z]*/cursors/.") check_eq $S/pkg-owns-every-entry 156 "$XT_DPKG_CUR" check_out $S/pkg-owns-left_ptr "$ICONS/whiteglass/cursors/left_ptr" dpkg -L xcursor-themes check_out $S/pkg-owns-probe "$TD/xcursor-themes-probe" dpkg -L xcursor-themes-tests # The probe is in -tests, never in the data package: an image may take the # themes without it. if dpkg -L xcursor-themes 2>/dev/null | grep -q "^$TD/"; then bst_notok $S/pkg-probe-not-in-data "xcursor-themes owns files under $TD -- the probe belongs to xcursor-themes-tests" else bst_ok $S/pkg-probe-not-in-data fi else bst_skip $S/pkg-installed "no dpkg on this image" fi # -------------------------------------------------------- the build-time record # The census refused the build on any difference, so its fails=0 and its # MATCHED==517 are a statement that the checks RAN rather than that the recipe # merely installed something. Read off the shipped report, which is the same file # the build wrote. check_eq $S/census-clean 0 "$(sed -n 's/^CENSUS-END fails=//p' "$TD/CENSUS")" check_eq $S/census-matched "CENSUS-MATCHED images=517" "$(grep '^CENSUS-MATCHED' "$TD/CENSUS")" check_eq $S/census-count "CENSUS-COUNT themes=3 cursors=125 links=31 images=517" "$(grep '^CENSUS-COUNT' "$TD/CENSUS")" # The lines a reader should not have to take the booleans' word for. echo "xct-evidence join compared=${XT_CMP:-?} mismatch=${XT_BAD:-?} missing=${XT_MISS:-?} extra=${XT_EXTRA:-?}" echo "xct-evidence decode $(sed -n 's/^PROBE-END //p' "$t/probe.out")" echo "xct-evidence themes handhelds=${XT_T_handhelds_FILES:-?}/${XT_T_handhelds_LINKS:-?} redglass=${XT_T_redglass_FILES:-?}/${XT_T_redglass_LINKS:-?} whiteglass=${XT_T_whiteglass_FILES:-?}/${XT_T_whiteglass_LINKS:-?} (files/links)" echo "xct-evidence path ${XT_PATH:-?}" echo "xct-evidence census $(grep '^CENSUS-COUNT' "$TD/CENSUS") $(grep '^CENSUS-MATCHED' "$TD/CENSUS")" rm -rf "$t"