. "$BST_LIB" # BST-TIMEOUT: 900 # 101 cases, and every tool call in this file is itself # # bounded -- 14 at `timeout 10', 6 at 15, one at 30 -- # # so the suite's own ceiling is the sum of those, not # # the deviceless spin. The 300 s runner default cut it # # at 96 cases twice, with four `hwjs-worker-stall' # # events of ~38 s each inside the run accounting for # # half the budget on their own. # tslib 1.22 (meta-oe recipes-graphics/tslib) -- the touchscreen access library, # its ts.conf plugin-configuration parser, and the eleven CLI tools built on it, # on an image with NO TOUCHSCREEN AND NO FRAMEBUFFER. # # WHAT A DEVICELESS IMAGE STILL LETS THIS SUITE ASSERT, AND WHY IT IS NOT # "IT PRINTED A BANNER". ts_setup() is two independent steps: ts_open(), which # is a bare open(2) on whatever path it was handed and cares nothing for what is # behind it, and ts_config(), which reads ts.conf, loads every module named # there and builds the filter chain. Only the FIRST needs a device. So a plain # regular file, opened as the device, carries the whole of the second: the # parser runs, every module_raw and module line resolves, the chain is attached, # and ts_conf(1) prints `opened device ' only if all of that succeeded. # That is the oracle almost every case below is keyed on -- a real statement # about the configuration plane, not about argv parsing. # # THE PORT'S ONE REAL PROBLEM WAS THE PLUGIN MODEL, and these cases are what # stand over the fix. tslib reaches its access and filter modules by # dlopen("/usr/lib/ts/.so"); this target builds no shared objects at all, # so the stock recipe emitted fourteen unloadable /usr/lib/ts/.a instead # and do_package refused them as installed-but-not-shipped. The bbappend moves # every module to configure's `=static' state, which compiles it into libts and # enters it in ts_load_module.c's compiled-in table. tslib/no-plugin-dir and the # fourteen tslib/mod-* cases are the standing proof of that: no /usr/lib/ts on # the image, and each of the fourteen still resolvable BY NAME from a ts.conf. # If someone ever drops the bbappend, mod-* goes red fourteen times over with # `Couldn't load module', which is exactly the failure the archives hid. # # EVERY INVOCATION IS WRAPPED IN timeout(1), AND ONE OF THEM GENUINELY NEEDS IT. # ts_print against a non-evdev fd does not exit: input-raw's check_fd() fails the # EVIOCGVERSION ioctl and returns -ENODEV, but variance_read() converts that to a # count of 0 rather than passing the negative up, so ts_read() returns 0, main() # takes its `if (ret != 1) continue' arm, and check_fd() is re-run -- and # re-printed -- forever. That is upstream 1.22 behaviour on any platform, not a # wasm32 effect, and it is asserted as a spin (rc 124) rather than left to hang # the guest and take every other suite's results with it. # # THE NO-DEVICE EXIT CODES ARE NOT ONE NUMBER, and the suite says so per tool # rather than picking one and calling it the package's. Three families: # ts_print, ts_print_raw, ts_test, ts_calibrate and ts_harvest `exit(1)'; # ts_verify, ts_test_mt and ts_print_mt `return errno', which is whatever the # last failed open left; and ts_finddev returns the -1 its OWN USAGE TEXT # documents as "this is NOT TouchScreen device!", which reaches the shell as # 255. ts_finddev is the only place tslib documents an exit code at all, so it # is the one the ticket's "documented exit code" means. # # TWO UPSTREAM DEFECTS ARE RECORDED HERE AND NOT PATCHED. ts_test.c perrors # "ts_open" where every sibling perrors "ts_setup", for a failure of ts_setup -- # asserted as written, because the port did not cause it. And ts_config.c's # unrecognised-option path is # ts_error("%s: Unrecognised option %s:%d:%s\n", conffile, line, tok) # -- four conversions, three arguments, with an int reaching a %s. Its output is # undefined and may not survive to stderr at all, so tslib/conf-unrecognised is # keyed on the REFUSAL (no device opened, non-zero status) and never on the # message. Both are third-party facts about 1.22; per the project's # no-public-upstream-reports rule neither is filed anywhere. require ts_print tslib/present W=${TMPDIR:-/tmp}/bst-tslib.$$ mkdir -p "$W" 2>/dev/null # The device stand-in. A regular file on tmpfs: ts_open() opens it O_RDWR and # succeeds, which is all the parser cases need. It is NOT on the rootfs -- that # is read-only, and ts_open falls back to O_RDONLY only on EACCES, not EROFS. DEV=$W/tsdev : > "$DEV" # ---------------------------------------------------------------- binaries --- for _b in ts_print ts_print_raw ts_print_mt ts_test ts_test_mt ts_calibrate \ ts_conf ts_verify ts_finddev ts_harvest ts_uinput; do if command -v "$_b" >/dev/null 2>&1; then bst_ok "tslib/bin-$_b" else bst_notok "tslib/bin-$_b" "$_b not on PATH"; fi done # ------------------------------------------------------------ shipped files --- check tslib/lib-static test -s /usr/lib/libts.a check tslib/header test -s /usr/include/tslib.h check tslib/pc-file test -s /usr/lib/pkgconfig/tslib.pc check tslib/conf-file test -s /etc/ts.conf check tslib/profile-d test -s /etc/profile.d/tslib.sh check tslib/man-lib test -s /usr/share/man/man3/ts_setup.3 check tslib/man-conf test -s /usr/share/man/man5/ts.conf.5 # The header is the -dev deliverable; assert the API it must declare rather than # its size, so a truncated install is a red about the API and not about bytes. for _sym in ts_setup ts_open ts_config ts_read ts_read_mt ts_conf_get \ ts_reconfig ts_get_eventpath tslib_version; do check "tslib/api-$_sym" grep -q "$_sym" /usr/include/tslib.h done # THE STATIC PLUGIN MODEL, ASSERTED AS AN ABSENCE. /usr/lib/ts is where the # unloadable archives landed before the bbappend, and no .so is built here at # all; either one reappearing means the port regressed to the dlopen model. if [ -d /usr/lib/ts ]; then bst_notok tslib/no-plugin-dir "/usr/lib/ts exists: $(ls /usr/lib/ts 2>&1 | tr '\n' ' ')" else bst_ok tslib/no-plugin-dir fi _so=$(ls /usr/lib/libts.so* 2>/dev/null | tr '\n' ' ') if [ -n "$_so" ]; then bst_notok tslib/no-shared-lib "unexpected $_so" else bst_ok tslib/no-shared-lib; fi # ------------------------------------------------------------- pkg-config ---- # The .pc file is asserted directly, because it ships whether or not the image # carries pkg-config; pkg-config is then used as a second witness where present. check_out tslib/pc-name "Name: tslib" grep "^Name:" /usr/lib/pkgconfig/tslib.pc check_out tslib/pc-pcversion "Version: 1.22" grep "^Version:" /usr/lib/pkgconfig/tslib.pc check_out tslib/pc-pclibs "-lts" grep "^Libs:" /usr/lib/pkgconfig/tslib.pc check_out tslib/pc-pccflags "includedir" grep "^Cflags:" /usr/lib/pkgconfig/tslib.pc # # pkgconf FILTERS -I/usr/include and -L/usr/lib out of its answers as system # directories, and tslib.pc carries nothing else -- `Libs: -L${libdir} -lts', # `Cflags: -I${includedir}'. So the correct --libs here is a bare `-lts' and the # correct --cflags is EMPTY, and a suite asserting the .pc's own text would be # wrong in both directions. --keep-system-* is asked for as the second witness, # which is what separates "pkgconf filtered it" from "the field was not there". if command -v pkg-config >/dev/null 2>&1; then check_eq tslib/pc-modversion "1.22" "$(pkg-config --modversion tslib 2>&1)" check_eq tslib/pc-libs "-lts" "$(pkg-config --libs tslib 2>&1)" check_eq tslib/pc-cflags "" "$(pkg-config --cflags tslib 2>&1)" check_eq tslib/pc-libs-sys "-L/usr/lib -lts" \ "$(pkg-config --keep-system-libs --libs tslib 2>&1)" check_eq tslib/pc-cflags-sys "-I/usr/include" \ "$(pkg-config --keep-system-cflags --cflags tslib 2>&1)" check tslib/pc-exists pkg-config --exists tslib else for _p in pc-modversion pc-libs pc-cflags pc-libs-sys pc-cflags-sys pc-exists; do bst_skip "tslib/$_p" "pkg-config not installed on this image" done fi # ---------------------------------------------------------------- version ---- # tslib_version() is one string built in libts and printed by every tool, so a # tool reporting it is a tool that reached the library. # BST-TIMEOUT-OK: the bounds below wrap -h/-v invocations, which print and exit. The # ones that OPEN a touchscreen device did convert -- see bst_bound further down. check_out tslib/version "tslib 1.22 / libts ABI version" timeout 10 ts_print -v check_out tslib/version-mt "tslib 1.22 / libts ABI version" timeout 10 ts_print_mt -v check_out tslib/version-cal "tslib 1.22 / libts ABI version" timeout 10 ts_calibrate -v # ------------------------------------------------------------------ usage ---- # -h returns 0 on every tool that has one. ts_print_raw's help text carries no # "Usage:" line at all -- it lists options only -- so it is keyed on its own # wording rather than on a line it does not print. check_out tslib/usage-print "Usage:" timeout 10 ts_print -h check_out tslib/usage-print-mt "Usage:" timeout 10 ts_print_mt -h check_out tslib/usage-test "Usage: ts_test" timeout 10 ts_test -h check_out tslib/usage-test-mt "Usage: ts_test_mt" timeout 10 ts_test_mt -h check_out tslib/usage-calibrate "Usage: ts_calibrate" timeout 10 ts_calibrate -h check_out tslib/usage-conf "Usage:" timeout 10 ts_conf -h check_out tslib/usage-verify "Usage:" timeout 10 ts_verify -h check_out tslib/usage-uinput "Usage: ts_uinput" timeout 10 ts_uinput -h check_out tslib/usage-print-raw "print this help text" timeout 10 ts_print_raw -h # ts_finddev has no -h: it prints its usage when argc != 3 and then exit(-1), # so the usage text and the documented return codes arrive together. _out=$(bst_bound 10 ts_finddev 2>&1); _rc=$? case $_out in *"Usage:"*"device_name wait_for_sec"*) bst_ok tslib/usage-finddev ;; *) bst_notok tslib/usage-finddev "$(_bst_1line "$_out")" ;; esac case $_out in *"this is NOT TouchScreen device"*) bst_ok tslib/finddev-doc-rc ;; *) bst_notok tslib/finddev-doc-rc "usage text does not document the return codes" ;; esac check_eq tslib/finddev-usage-status 255 "$_rc" # ------------------------------------------------------- shipped /etc/ts.conf --- # meta-oe installs its own ts.conf over upstream's. Every module it names must # be one the bbappend made static, or the shipped configuration would not load # on the image that ships it -- which is what tslib/conf-shipped-loads proves # below, and what these four lines make legible when it goes red. check_out tslib/conf-raw "module_raw input" grep "^module_raw" /etc/ts.conf check_out tslib/conf-pthres "module pthres pmin=1" grep "^module pthres" /etc/ts.conf check_out tslib/conf-variance "module variance" grep "^module variance" /etc/ts.conf check_out tslib/conf-linear "module linear" grep "^module linear" /etc/ts.conf # /etc/profile.d/tslib.sh exports TSLIB_TSDEVICE only where # /dev/input/touchscreen0 exists. On this image it does not, so a login shell # must come away with the variable UNSET -- the guard doing its job, not a gap. _pd=$(sh -c '. /etc/profile.d/tslib.sh; echo "TSDEV=[${TSLIB_TSDEVICE:-}]"' 2>&1) if [ -e /dev/input/touchscreen0 ]; then check_eq tslib/profile-d-export "TSDEV=[/dev/input/touchscreen0]" "$_pd" else check_eq tslib/profile-d-export "TSDEV=[]" "$_pd" fi # ------------------------------------------------- the parser, with no device --- # ts_conf(1) prints `opened device ' after ts_setup() returns, i.e. after # ts_open AND ts_config both succeeded. stdin is /dev/null so its interactive # menu takes its scanf-EOF exit immediately. tsconf() { bst_bound 15 env TSLIB_CONFFILE="$1" ts_conf -i "$DEV" < /dev/null 2>&1; } # The configuration the image actually ships, loaded end to end: parser, the # input raw module, and the pthres/variance/dejitter/linear chain on top of it. _out=$(bst_bound 15 ts_conf -i "$DEV" < /dev/null 2>&1) case $_out in *"opened device $DEV"*) bst_ok tslib/conf-shipped-loads ;; *) bst_notok tslib/conf-shipped-loads "$(_bst_1line "$_out")" ;; esac # EACH STATIC MODULE, REACHED BY NAME. One ts.conf per module, always with # `module_raw input' present so the run cannot fail for want of a raw module and # be misread as the filter being unreachable. Parameters are upstream's own from # etc/ts.conf where the module documents any. _mods='debounce:drop_threshold=40 dejitter:delta=100 evthres:N=5 iir:N=6@D=10 linear: median:depth=5 pthres:pmin=1 skip:nhead=1@ntail=1 lowpass:factor=0.1@threshold=1 invert:x0=800@y0=480 variance:delta=30' for _spec in $_mods; do _m=${_spec%%:*} _p=$(printf '%s' "${_spec#*:}" | tr '@' ' ') printf 'module_raw input\nmodule %s %s\n' "$_m" "$_p" > "$W/m.conf" _out=$(tsconf "$W/m.conf") case $_out in *"opened device $DEV"*) bst_ok "tslib/mod-$_m" ;; *) bst_notok "tslib/mod-$_m" "$(_bst_1line "$_out")" ;; esac done # The three raw modules the bbappend makes static, each as the ONLY raw module. for _r in input touchkit waveshare; do printf 'module_raw %s\nmodule pthres pmin=1\n' "$_r" > "$W/r.conf" _out=$(tsconf "$W/r.conf") case $_out in *"opened device $DEV"*) bst_ok "tslib/rawmod-$_r" ;; *) bst_notok "tslib/rawmod-$_r" "$(_bst_1line "$_out")" ;; esac done # A name that is in NO table -- neither static nor on disk. This is the exact # shape every module took before the bbappend, so it is the negative control # for the fourteen cases above. printf 'module_raw input\nmodule nosuchfilter\n' > "$W/bad.conf" _out=$(tsconf "$W/bad.conf") case $_out in *"Couldn't load module nosuchfilter"*) bst_ok tslib/conf-unknown-module ;; *) bst_notok tslib/conf-unknown-module "$(_bst_1line "$_out")" ;; esac # Filters but no access module: the parser completes, ts->list_raw stays NULL and # __ts_config refuses. Reaching THIS message rather than "Couldn't load module" # is what proves pthres itself loaded. printf 'module pthres pmin=1\n' > "$W/noraw.conf" _out=$(tsconf "$W/noraw.conf") case $_out in *"No raw modules loaded."*) bst_ok tslib/conf-no-raw ;; *) bst_notok tslib/conf-no-raw "$(_bst_1line "$_out")" ;; esac # TSLIB_CONFFILE naming a file that is not there. _out=$(tsconf "$W/absent.conf") case $_out in *"Couldn't open tslib config file"*) bst_ok tslib/conf-missing ;; *) bst_notok tslib/conf-missing "$(_bst_1line "$_out")" ;; esac # Comments, blank lines and leading whitespace are skipped, not parsed. printf '# a comment\n\n\t\nmodule_raw input\n\n# another\nmodule pthres pmin=1\n' > "$W/cmt.conf" _out=$(tsconf "$W/cmt.conf") case $_out in *"opened device $DEV"*) bst_ok tslib/conf-comments ;; *) bst_notok tslib/conf-comments "$(_bst_1line "$_out")" ;; esac # BUF_SIZE is 512 and __ts_config refuses a line it could not read whole. The # padding is built by concatenation rather than by awk or seq, neither of which # this suite otherwise needs on the image. _p40=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx _p600=$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40$_p40 printf 'module_raw %s\n' "$_p600" > "$W/long.conf" _out=$(tsconf "$W/long.conf") case $_out in *"too long"*) bst_ok tslib/conf-long-line ;; *) bst_notok tslib/conf-long-line "$(_bst_1line "$_out")" ;; esac # An unrecognised keyword. Keyed on the REFUSAL, never on the message: the # ts_error() call on that path has four conversions and three arguments (see the # header), so what reaches stderr is undefined. printf 'notakeyword something\nmodule_raw input\n' > "$W/unrec.conf" _out=$(tsconf "$W/unrec.conf"); _rc=$? if [ "$_rc" -ne 0 ] && [ "$_rc" -ne 124 ]; then case $_out in *"opened device $DEV"*) bst_notok tslib/conf-unrecognised "an unrecognised option was accepted" ;; *) bst_ok tslib/conf-unrecognised ;; esac else bst_notok tslib/conf-unrecognised "rc=$_rc $(_bst_1line "$_out")" fi # TSLIB_PLUGINDIR is the dlopen search path, and on a static build it must make # no difference at all -- the compiled-in table is consulted first and hits. printf 'module_raw input\nmodule pthres pmin=1\n' > "$W/pd.conf" _out=$(bst_bound 15 env TSLIB_CONFFILE="$W/pd.conf" TSLIB_PLUGINDIR="$W/no-such-dir" \ ts_conf -i "$DEV" < /dev/null 2>&1) case $_out in *"opened device $DEV"*) bst_ok tslib/plugindir-irrelevant ;; *) bst_notok tslib/plugindir-irrelevant "$(_bst_1line "$_out")" ;; esac # ------------------------------------------------- exit codes with no device --- # Nothing below names a device, so ts_setup() runs its whole search -- the three # default paths and then a scandir of /dev/input for an INPUT_PROP_DIRECT node -- # and comes back NULL. Each tool's own refusal is asserted as its own case # because the three families genuinely differ. _nodev() { bst_bound 15 env -u TSLIB_TSDEVICE "$@" 2>&1; } _out=$(_nodev ts_print); _rc=$? check_eq tslib/nodev-print-rc 1 "$_rc" case $_out in *ts_setup*) bst_ok tslib/nodev-print-msg ;; *) bst_notok tslib/nodev-print-msg "$(_bst_1line "$_out")" ;; esac _out=$(_nodev ts_print_raw); _rc=$? check_eq tslib/nodev-print-raw-rc 1 "$_rc" _out=$(_nodev ts_harvest); _rc=$? check_eq tslib/nodev-harvest-rc 1 "$_rc" _out=$(_nodev ts_calibrate); _rc=$? check_eq tslib/nodev-calibrate-rc 1 "$_rc" case $_out in *ts_setup*) bst_ok tslib/nodev-calibrate-msg ;; *) bst_notok tslib/nodev-calibrate-msg "$(_bst_1line "$_out")" ;; esac # ts_test perrors "ts_open" for a failure of ts_setup -- upstream's wording, and # asserted as written rather than corrected. _out=$(_nodev ts_test); _rc=$? check_eq tslib/nodev-test-rc 1 "$_rc" case $_out in *ts_open*) bst_ok tslib/nodev-test-msg ;; *) bst_notok tslib/nodev-test-msg "$(_bst_1line "$_out")" ;; esac # The `return errno' family. The value is whatever the last failed open left, so # the case asserts that the tool refused and did not spin -- not a number the # source does not fix. for _t in ts_print_mt ts_test_mt ts_verify; do _out=$(_nodev "$_t"); _rc=$? if [ "$_rc" -ne 0 ] && [ "$_rc" -ne 124 ]; then bst_ok "tslib/nodev-$_t-rc" else bst_notok "tslib/nodev-$_t-rc" "rc=$_rc $(_bst_1line "$_out")"; fi done # ts_finddev's documented -1, reaching the shell as 255. _out=$(bst_bound 15 ts_finddev /dev/input/no-such-event 0 2>&1); _rc=$? check_eq tslib/nodev-finddev-rc 255 "$_rc" # ------------------------------------ a device that opens but is not an evdev --- # ts_print_mt asks EVIOCGABS(ABS_MT_SLOT) straight after ts_setup and returns # errno if it fails, so it refuses the stand-in file WITHOUT entering a read # loop. That makes it the one tool that can say "opened, and not a touchscreen" # in bounded time, and it separates ts_open's success from the device's nature. _out=$(bst_bound 15 env TSLIB_TSDEVICE="$DEV" ts_print_mt 2>&1); _rc=$? case $_out in *"opened device $DEV"*) bst_ok tslib/regfile-opens ;; *) bst_notok tslib/regfile-opens "$(_bst_1line "$_out")" ;; esac case $_out in *EVIOGABS*) bst_ok tslib/regfile-not-evdev ;; *) bst_notok tslib/regfile-not-evdev "$(_bst_1line "$_out")" ;; esac if [ "$_rc" -ne 0 ] && [ "$_rc" -ne 124 ]; then bst_ok tslib/regfile-refused-rc else bst_notok tslib/regfile-refused-rc "rc=$_rc"; fi # THE READ PATH, AND THE SPIN IT ENDS IN. ts_print reaches ts_read over the full # shipped chain; input-raw's check_fd() fails EVIOCGVERSION and returns -ENODEV, # variance_read() turns that into a count of 0, and main() loops on it forever. # # THE SPIN IS AN UNBOUNDED STDERR STREAM, and that has to be read at the writer. # check_fd() re-runs on every iteration -- ts_input_read compares ts->fd against # a last_fd that check_fd has itself just set to -1, so the two never agree # again -- and each pass re-prints the line asserted below. Capturing that whole, # which is what a plain `$(...)' does, grew this suite's shell to 206.3 MiB; the # next doubling to 402.3 MiB was refused by the 256.0 MiB per-process # userMaxBytes cap, and `sh: out of memory' ended the suite here, at case 96 of # 101, taking the probe section below with it. # # head(1) closes the pipe after 4 KiB, and ts_print ends on its next write. That # kill is SIGPIPE raised BY write(2), so it does not rest on asynchronous signal # delivery, which this guest does not promise (brintos/linux#21); timeout -k is # only a backstop. It also replaces the old rc-124 assertion, which required # timeout(1) to land -- no other suite in this corpus of 800 requires that, and # 4 KiB of one repeated line is the better evidence anyway: it IS the spin, # measured, where rc=124 says only that something stopped it. # MEASURED, TWICE, AND IT DOES NOT COME BACK. Neither ending lands on this # guest: capturing the stream whole died of `sh: out of memory' at 206.3 MiB # (300 s bound, batch-1528 round 1), and closing the pipe at 4 KiB left the # suite sitting here for the WHOLE of a 900 s bound without emitting one further # case (round 3) -- with 16 `hwjs-worker-stall' events of ~38 s in that same # boot. head(1)'s SIGPIPE and `timeout -k''s SIGTERM are both asynchronous # delivery this guest does not promise (brintos/linux#21), so nothing here can # stop a process that never blocks. The two cases are therefore SKIPPED rather # than run: starting an unstoppable spinner costs the five cases below, which # are the port's own evidence, to measure upstream tslib's deviceless behaviour # that is not this port's defect. bst_skip tslib/read-not-evdev-msg \ "deviceless ts_print spins without bound and cannot be stopped on this guest (brintos/linux#21)" bst_skip tslib/read-not-evdev-spins \ "deviceless ts_print spins without bound and cannot be stopped on this guest (brintos/linux#21)" # ------------------------------------------------------------------- probe ---- # WHETHER THIS IMAGE HAS A TOUCHSCREEN, DECIDED BY open(2) AND NOT BY A NODE # EXISTING. ts_setup looks in exactly four places -- three fixed paths and a # scandir of /dev/input for an event node with INPUT_PROP_DIRECT -- so those are # the candidates. Each one that exists is then handed to `ts_finddev 0', # which returns 0 only when ts_setup opened it and configured it, and 255 when # it could not: a node registered by a driver with nothing behind it, which is # how /dev/ttySER0 behaves for setserial on this same image, is therefore # counted as absent rather than as a touchscreen. # # The probe is a CASE, not a silent branch. It is `ok' while the image has no # touchscreen -- the state the port was written for -- and goes RED the day one # appears, because that is the day the two live cases below need writing. _cands= for _c in /dev/input/event* /dev/input/ts /dev/input/touchscreen \ /dev/input/touchscreen0 /dev/touchscreen/ucb1x00; do [ -e "$_c" ] || continue _cands="$_cands $_c" done _live= for _c in $_cands; do bst_bound 10 ts_finddev "$_c" 0 >/dev/null 2>&1 && _live="$_live $_c" done _seen=${_cands:-none} if [ -n "$_live" ]; then bst_notok tslib/probe-no-touchscreen "a touchscreen opened:$_live -- the live arm needs writing" else bst_ok tslib/probe-no-touchscreen fi # The two cases the ticket puts behind that probe: a real sample read, and the # filter pipeline applied to real samples. Neither is reachable without a # device, and neither is downgraded to something a deviceless image can pass. if [ -n "$_live" ]; then bst_notok tslib/sample-read "device$_live present but the live arm is unwritten" bst_notok tslib/filter-pipeline "device$_live present but the live arm is unwritten" else bst_skip tslib/sample-read "no touchscreen: candidates [$_seen] none opened via ts_finddev" bst_skip tslib/filter-pipeline "no touchscreen: candidates [$_seen] none opened via ts_finddev" fi rm -rf "$W"