. "$BST_LIB" # BST-TIMEOUT: 900 # # MEASURED, then re-seated on the split. The single-file form of this suite -- # which also ran the ten ptest modules, eleven interpreter starts in all -- # reported `==BST-SUITE pyxdg elapsed=202s cases=116==` on the batch-1649 image # on 2026-08-28, and produced not one case line on a boot that had less room # (BRINTOS-1682 / BRINTOS-1742; see 99-pyxdg-ptest.test's header for the # arithmetic). The ptest modules now live in 99-pyxdg-ptest{,2,3}.test and what # is left here is TWO interpreter starts -- section 2's import and section 3's # payload -- so this file is the cheapest of the four. 900 is a backstop, not a # prediction of the runtime; the ==BST-SUITE== line is what settles that. # # pyxdg 0.28 (meta-openembedded meta-oe/recipes-gnome/pyxdg) -- the Python # implementation of the freedesktop.org specifications: base directories, # desktop entries, ini files, MIME types, icon themes and menus. It is a LIBRARY # and not a command, so there is no binary to run and nothing to compile: the # whole of the port is module content, and the whole of the question is whether # this image's python3 can load it and get the right answers. # # THE PORT NEEDED NO PATCH, NO AUTOCONF ANSWER AND NO OVERRIDE. meta-oe's recipe # is `inherit setuptools3` over a git checkout and nothing in it is # architecture-dependent. What the bbappend adds is the distribution's own test # suite as a ptest -- the ticket's stated preferred criterion -- and the two # runtime imports meta-oe under-declares (xml, fcntl). # # FOUR SECTIONS ACROSS FOUR FILES, AND THE MIDDLE TWO ARE DELIBERATELY # REDUNDANT WITH EACH OTHER: # # 1. what the port SHIPS -- filesystem facts, asserted before anything starts # the interpreter, so they hold on a boot where python3 cannot run at all. # 2. can this image's python3 import the package. # 3. THE FIXTURE-DRIVEN BATTERY: every parser the ticket names, driven over a # corpus staged in tmpfs with XDG_DATA_DIRS / XDG_CONFIG_DIRS pointed at # it, and an enumerated expected value for each answer. # 4. THE CRITERION: the distribution's own nine unittest modules, run in place # out of the installed ptest tree -- in 99-pyxdg-ptest.test, # 99-pyxdg-ptest2.test and 99-pyxdg-ptest3.test, one interpreter start per # module and so too expensive to share a boot with 1-3. Sections 1-3 are # this file. # # WHY BOTH 3 AND 4, when the ticket names 4 as preferred. Upstream's suite is # the better oracle for pyxdg's own semantics and it is what section 4 runs. It # is NOT sufficient here, for one reason that is a property of this image: # EIGHT of its cases go through the SYSTEM MIME DATABASE, which lives in the # shared-mime-info package, and this image does not ship it. Those eight are the # only coverage upstream has of Mime's glob table and magic matcher, so without # section 3 the whole of Mime.get_type_by_name / get_type_by_data / canonical / # inherits_from would go untested on this port -- while the suite reported # green, because run-ptest skips them by name. Section 3 stages its own globs2, # magic, aliases and subclasses and asserts sixteen enumerated answers over # them, which is coverage of the same code paths that owes the image nothing. # # EVERY EXPECTED VALUE IN SECTION 3 WAS MEASURED, NOT READ OFF THE SOURCE. The # control is an x86-64 run of the IDENTICAL payload against the identical pyxdg # checkout (SRCREV 1d23e483, the commit meta-oe's recipe pins), under `env -i` # with the XDG_* variables cleared -- so the fixture is the only data either arm # sees. Repeated three times, byte-identical each time: 78 tagged lines and # ALL-PYXDG-OK. Recorded 2026-08-27. # # TWO OF THOSE VALUES LOOK WRONG AND ARE NOT, so they are called out here rather # than left to surprise a reader: # - pyxdg/name-de is `Texteditor DE`, the de_DE translation, not `Texteditor`. # xdg.Locale.update() runs its argument through locale.normalize(), which # turns "de" into "de_DE.ISO8859-1", so the expansion is ["de_DE", "de"] and # the territory key wins. That is upstream's path through the stdlib. # - pyxdg/get-type2-name-wins and pyxdg/get-type2-contents are both image/png # and are NOT the same assertion: the first file's NAME says png and its # contents agree, the second is named `mystery` and only its contents say # so, so the second is the magic matcher answering alone. # # THE ORACLE WAS MUTATION-TESTED, and the record is the reason section 3 stays. # Eleven mutations were applied to the pyxdg source on the x86-64 control, one at # a time, and every one reddened the cases it should and no others: # # Locale.expand_languages -> [] 6 red (the locale getters and R3's # expansion case) # GlobDB ignores the `cs` flag 2 red (by-name-C, and upstream's # test_mime-parsers) # get_type_by_data -> None 2 red (by-data-png, by-data-fixture) # MIMEtype.inherits_from -> set() 1 red (inherits) # IconTheme.getInherits -> [] 2 red (theme-inherits, icon-inherited) # XMLMenuBuilder.parse_merge_file no-op 2 red (submenus, editors) # IniFile.write drops `Key[locale]` 1 red (roundtrip-locale) # IniFile.validate -> None 2 red (validate-broken, and upstream's # test_desktop) # strict get() returns "" not NoKeyError 2 red (strict-missing, test_desktop) # xdg_data_dirs drops XDG_DATA_HOME 2 red (data-dirs-len, -order) # xdg_data_dirs reversed 18 red (the precedence rule, and every # answer that depends on it) # # TWO OF THOSE ELEVEN REDDENED NOTHING IN SECTION 4, and that is the concrete # argument for keeping section 3 beside the criterion the ticket names: with icon # INHERITANCE broken, and with the menu MERGE broken, upstream's own nine modules # still reported ten green lines. Its test_icon does not assert an inherited # lookup and its test_menu prints the tree rather than asserting it. So the two # behaviours the ticket asks for by name -- "IconTheme lookup with inheritance" # and "Menu merging" -- are covered HERE and nowhere else. # # WHAT IS NOT ASSERTED, DELIBERATELY: any MIME type, icon or menu entry the # ROOTFS happens to carry. Every question here is answered out of the staged # fixture. An assertion against /usr/share would be an assertion about the # image's package list, which changes under this suite for reasons that have # nothing to do with pyxdg. require python3 pyxdg/present SITE=/usr/lib/python3.12/site-packages XDG=$SITE/xdg PT=/usr/lib/pyxdg/ptest # --------------------------------------- 1. what the port SHIPS: the files --- # The package is `packages = ['xdg']` and nothing else -- thirteen modules, and # asserting the SET rather than one entry point is what catches a packaging # change that silently drops half of them. Nothing here starts python3. check pyxdg/site-dir test -d $SITE check pyxdg/package-dir test -d $XDG check pyxdg/mod-init test -f $XDG/__init__.py check pyxdg/mod-basedirectory test -f $XDG/BaseDirectory.py check pyxdg/mod-config test -f $XDG/Config.py check pyxdg/mod-desktopentry test -f $XDG/DesktopEntry.py check pyxdg/mod-exceptions test -f $XDG/Exceptions.py check pyxdg/mod-icontheme test -f $XDG/IconTheme.py check pyxdg/mod-inifile test -f $XDG/IniFile.py check pyxdg/mod-locale test -f $XDG/Locale.py check pyxdg/mod-menu test -f $XDG/Menu.py check pyxdg/mod-menueditor test -f $XDG/MenuEditor.py check pyxdg/mod-mime test -f $XDG/Mime.py check pyxdg/mod-recentfiles test -f $XDG/RecentFiles.py check pyxdg/mod-util test -f $XDG/util.py # THE INSTALLED TEST SUITE -- the deliverable section 4 runs on. The three # fixture facts below are asserted individually because the bbappend copies the # tree with `cp -a` precisely to preserve them, and an install(1) loop that # replaced it would break exactly these two cases of upstream's test_mime and # nothing else, which is the kind of partial damage a reader later blames on the # arm. check pyxdg/ptest-dir test -d $PT/test check pyxdg/ptest-runptest test -f $PT/run-ptest check pyxdg/ptest-resources test -f $PT/test/resources.py check pyxdg/ptest-example-dir test -d $PT/test/example check pyxdg/ptest-menuspec-dir test -d $PT/test/menu-spec check pyxdg/ptest-symlink-kept test -L $PT/test/example/png_symlink check pyxdg/ptest-mode-kept test -x $PT/test/example/mystery_exe check pyxdg/ptest-subdir-kept test -d $PT/test/example/subdir # Nine test_*.py -- the whole of the distribution's test/. This bbappend prunes # none of them, so the count is the tarball's and a recipe that started pruning # reds here. The x86-64 control ran exactly these nine. check_eq pyxdg/ptest-count 9 "$(ls $PT/test/test_*.py 2>/dev/null | wc -l | tr -d ' ')" # ------------------------------------ 2. can this image's python3 import it --- # Separately from section 3's payload, because a failure here and a failure # there mean different things: this is the port, that is the port's behaviour. check_eq pyxdg/version "0.28" \ "$(python3 -c 'import xdg; print(xdg.__version__)' 2>&1)" # ------------------------ 3. the fixture-driven battery: ONE python3 spawn ---- # The payload measures everything in one interpreter and prints one tagged line # per value; this file names and compares them, so a single wrong answer is one # red case rather than one red suite. # # BRINTOS-WORKAROUND: brintos/glibc#11 revisit -- PIN-GATED, BRINTOS-2330: trigger is the pin, not this issue -- our glibc is brintium's gitlink 8f4ac10c on joel-dev, forked from wasm32 at 0ee15592 (2026-09-04); a fix on either branch need not be in the tree we build. Read that tree before removing. # when setenv(3) stops returning # EINVAL, the payload may set its own XDG_* variables again and this envp # hand-off, the argv[1] fixture root and the check on it can all go. # # THE ENVIRONMENT IS STAGED HERE AND NOT IN THE PAYLOAD, and that is a platform # fact rather than a style choice. setenv(3) on this arm returns EINVAL for # every name -- `os.environ["X"] = "1"` raises OSError [Errno 22] for a # brand-new variable as readily as for an existing one, and so do os.putenv and # os.unsetenv -- so a payload that set its own XDG_* variables died on its first # assignment and reported all seventy-eight measurements empty. Measured on the # batch-1649 image, 2026-08-28 -- brintos/glibc#11. Passed in # through execve's envp, which this image serves correctly, the same variables # arrive intact and nothing else about the fixture changes. # # The subshell exists to UNSET as well as to set: XDG_RUNTIME_DIR must be absent # for R1_runtime_fallback to measure get_runtime_dir(strict=False)'s fallback at # all, and a prefix assignment cannot unset anything. The payload checks the # result rather than trusting it, so a variable this block failed to place is a # named failure instead of seventy-eight silent empties. PXROOT=$(mktemp -d /tmp/bst-pyxdg.XXXXXX 2>/dev/null) [ -n "$PXROOT" ] || { PXROOT=/tmp/bst-pyxdg.$$; mkdir -p "$PXROOT"; } out=$( unset XDG_DATA_HOME XDG_DATA_DIRS XDG_CONFIG_HOME XDG_CONFIG_DIRS \ XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR HOME=$PXROOT/home XDG_DATA_HOME=$PXROOT/data-home XDG_DATA_DIRS=$PXROOT/data1:$PXROOT/data2 XDG_CONFIG_HOME=$PXROOT/config-home XDG_CONFIG_DIRS=$PXROOT/config1:$PXROOT/config2 XDG_CACHE_HOME=$PXROOT/cache export HOME XDG_DATA_HOME XDG_DATA_DIRS XDG_CONFIG_HOME XDG_CONFIG_DIRS \ XDG_CACHE_HOME python3 "$BST_DATA/pyxdg-selftest.py" "$PXROOT" 2>&1 ); rc=$? case "$out" in *ALL-PYXDG-OK*) all=1 ;; *) all=0 ;; esac if [ "$rc" -eq 0 ] && [ "$all" -eq 1 ]; then bst_ok pyxdg/all-ok elif bst_execfail "$out"; then bst_unrun pyxdg/all-ok "$out" else bst_notok pyxdg/all-ok "rc=$rc $(_bst_1line "$out")"; fi # Read the tagged lines into shell variables with no subprocess at all. The # payload's tags are already valid sh identifiers for exactly this reason: the # obvious alternative, one `awk` per value, would cost an exec per lookup and an # exec on this arm is a fresh wasm module instantiation at 2-3 s -- seventy-eight # of them would be the whole of this suite's runtime, spent on parsing. # # The eval's right-hand side is `${line#* }`, expanded at eval time from $line, # so no value's content can reach the shell as syntax however it is quoted. _oifs=$IFS IFS=' ' for line in $out; do case "$line" in R[0-9]*_*\ *) eval "PX_${line%% *}=\${line#* }" ;; esac done IFS=$_oifs # The import itself, from inside the payload's own process -- the same question # section 2 asks from outside, and the answer that tells a reader whether every # below is a real measurement or the wreckage of a failed import. check_eq pyxdg/import 'ok' "$PX_R0_import" # --- BaseDirectory: resolution against a controlled XDG_* environment. # # These constants are computed at MODULE IMPORT time, which is why the payload # sets the environment before its first xdg import and why nothing here can be # re-measured by a second call. data-dirs-order is the spec's precedence written # out: XDG_DATA_HOME first, then XDG_DATA_DIRS in order, and it is what makes # pyxdg/not-shadowed below a real assertion rather than a coincidence. # # save-config-mode is 0o700 and that is the spec's requirement, not a umask # artifact: BaseDirectory.save_config_path passes 0o700 to makedirs explicitly. # runtime-fallback exercises get_runtime_dir(strict=False), which is this # image's condition -- the selftest runner exports no XDG_RUNTIME_DIR. check_eq pyxdg/data-home 'ok' "$PX_R1_data_home" check_eq pyxdg/config-home 'ok' "$PX_R1_config_home" check_eq pyxdg/data-dirs-len '3' "$PX_R1_data_dirs_len" check_eq pyxdg/data-dirs-order 'dh:d1:d2' "$PX_R1_data_dirs_order" check_eq pyxdg/config-dirs-order 'ch:c1:c2' "$PX_R1_config_dirs_order" check_eq pyxdg/load-data-paths-count '2' "$PX_R1_load_data_paths_count" check_eq pyxdg/load-data-paths-first 'd1' "$PX_R1_load_data_paths_first" check_eq pyxdg/save-config-path 'ok' "$PX_R1_save_config_path" check_eq pyxdg/save-config-exists 'ok' "$PX_R1_save_config_exists" check_eq pyxdg/save-config-mode '0o700' "$PX_R1_save_config_mode" check_eq pyxdg/load-nothing '0' "$PX_R1_load_nothing" check_eq pyxdg/runtime-fallback 'ok' "$PX_R1_runtime_fallback" # --- IniFile: parsing, the locale-aware getters, and the ROUND TRIP. # # roundtrip is the load-bearing case: the file is written out and re-parsed, and # every key of every group compared. That oracle cannot pass on a writer that # drops a key or mangles a `Key[locale]` suffix, which a reader-only assertion # would never see. roundtrip-locale then re-reads the localised key from the # REWRITTEN file specifically, because the suffix is the part a writer loses. # # get-locale-none and get-locale-c are the same call with an empty language # list; get-locale-de is the same call after Locale.update("de"). Asserting all # three is what distinguishes "the locale lookup works" from "there is no locale # lookup and the untranslated value is always returned". check_eq pyxdg/groups 'Group A,Group B' "$PX_R2_groups" check_eq pyxdg/get 'value' "$PX_R2_get" check_eq pyxdg/get-other-group 'other' "$PX_R2_get_other_group" check_eq pyxdg/get-list 'one|two|three' "$PX_R2_get_list" check_eq pyxdg/get-locale-none 'plain' "$PX_R2_get_locale_none" check_eq pyxdg/get-locale-de 'deutsch' "$PX_R2_get_locale_de" check_eq pyxdg/get-locale-c 'plain' "$PX_R2_get_locale_c" check_eq pyxdg/get-missing '' "$PX_R2_get_missing" check_eq pyxdg/strict-missing 'NoKeyError' "$PX_R2_strict_missing" check_eq pyxdg/roundtrip 'identical' "$PX_R2_roundtrip" check_eq pyxdg/roundtrip-locale 'deutsch' "$PX_R2_roundtrip_locale" check_eq pyxdg/parse-garbage 'ParsingError' "$PX_R2_parse_garbage" # --- DesktopEntry: field lookup, localisation, and the documented validation. # # not-shadowed is the base-directory precedence rule observed through # DesktopEntry: a second gedit.desktop with a different Name sits in the LATER # data dir, and the spec says the first match wins and nothing merges. A pyxdg # that concatenated or preferred the last would show up here and nowhere else. # # validate-broken and validate-good are a PAIR and neither is meaningful alone. # broken.desktop is a valid ini file that is an invalid desktop entry -- # Type=Application with no Exec, plus an unregistered key without the X- prefix # -- so a validate() that accepted everything would pass validate-good while # being worthless. name-de is the locale.normalize() surprise the header # describes. check_eq pyxdg/name 'Text Editor' "$PX_R3_name" check_eq pyxdg/type 'Application' "$PX_R3_type" check_eq pyxdg/exec 'gedit %U' "$PX_R3_exec" check_eq pyxdg/generic 'Editor' "$PX_R3_generic" check_eq pyxdg/categories 'GNOME|Utility|TextEditor' "$PX_R3_categories" check_eq pyxdg/keywords 'Plaintext|Write' "$PX_R3_keywords" check_eq pyxdg/mimetypes 'text/plain' "$PX_R3_mimetypes" check_eq pyxdg/terminal 'False' "$PX_R3_terminal" check_eq pyxdg/x-extension 'yes' "$PX_R3_x_extension" check_eq pyxdg/name-de-DE 'Texteditor DE' "$PX_R3_name_de_DE" check_eq pyxdg/name-de 'Texteditor DE' "$PX_R3_name_de" check_eq pyxdg/name-fr 'Editeur de texte' "$PX_R3_name_fr" check_eq pyxdg/name-ja 'Text Editor' "$PX_R3_name_ja" check_eq pyxdg/name-c 'Text Editor' "$PX_R3_name_c" check_eq pyxdg/expand-de-DE 'de_DE|de' "$PX_R3_expand_de_DE" check_eq pyxdg/not-shadowed 'ok' "$PX_R3_not_shadowed" check_eq pyxdg/broken-parses 'Broken' "$PX_R3_broken_parses" check_eq pyxdg/validate-broken 'ValidationError' "$PX_R3_validate_broken" check_eq pyxdg/validate-good 'ok' "$PX_R3_validate_good" check_eq pyxdg/missing-key '' "$PX_R3_missing_key" # --- Mime: type lookup by glob and by magic, over the payload's own database. # # THIS IS THE SECTION THE IMAGE CANNOT PROVIDE. shared-mime-info is not on this # rootfs, so /usr/share/mime does not exist and upstream's own eight system-database # cases are skipped by run-ptest in section 4. Everything here reads a globs2, # a magic, an aliases and a subclasses staged by the payload, which is why these # answers are the same on any machine and do not move when the image's package # list does. # # by-name-c and by-name-C are one case split in two: both globs carry the `cs` # case-sensitivity flag, so a matcher that lower-cased the name would return # text/x-csrc for both and only the second case would notice. by-name-weights # resolves `readme2.txt` against a weight-10 `readme*` and a weight-20 # `readme2*` in DIFFERENT data dirs, so it asserts the merge and the weight # order together. by-data-fixture matches a signature that exists in no real # MIME database anywhere, which is the point: it can only come from the file the # payload wrote. check_eq pyxdg/by-name-py 'text/x-python' "$PX_R4_by_name_py" check_eq pyxdg/by-name-c 'text/x-csrc' "$PX_R4_by_name_c" check_eq pyxdg/by-name-C 'text/x-c++src' "$PX_R4_by_name_C" check_eq pyxdg/by-name-literal 'text/x-makefile' "$PX_R4_by_name_literal" check_eq pyxdg/by-name-merged 'image/jpeg' "$PX_R4_by_name_merged" check_eq pyxdg/by-name-weights 'text/x-readme2' "$PX_R4_by_name_weights" check_eq pyxdg/by-name-none '' "$PX_R4_by_name_none" check_eq pyxdg/by-data-png 'image/png' "$PX_R4_by_data_png" check_eq pyxdg/by-data-fixture 'application/x-brintos-fixture' "$PX_R4_by_data_fixture" check_eq pyxdg/by-data-none '' "$PX_R4_by_data_none" check_eq pyxdg/get-type2-name-wins 'image/png' "$PX_R4_get_type2_name_wins" check_eq pyxdg/get-type2-contents 'image/png' "$PX_R4_get_type2_contents" check_eq pyxdg/get-type2-dir 'inode/directory' "$PX_R4_get_type2_dir" check_eq pyxdg/get-type2-missing 'application/octet-stream' "$PX_R4_get_type2_missing" check_eq pyxdg/canonical 'application/xml' "$PX_R4_canonical" check_eq pyxdg/inherits 'text/plain' "$PX_R4_inherits" check_eq pyxdg/comment 'Python script' "$PX_R4_comment" check_eq pyxdg/is-text 'True' "$PX_R4_is_text" check_eq pyxdg/is-not-text 'False' "$PX_R4_is_not_text" # --- IconTheme: lookup with inheritance and size matching. # # icon-34-threshold is the Threshold rule and nothing else: there is no 34x34 # directory, and 32x32/apps declares Threshold=4, so an implementation that only # matched sizes exactly returns nothing here. icon-scalable-64 is the # MinSize..MaxSize band of a Scalable directory answering a size no Fixed # directory carries. # # icon-inherited is the whole of the inheritance assertion: bst-parent-only # exists ONLY under brintos-parent, and the lookup is made against # brintos-child, so a hit means the Inherits chain was walked. icon-absent is # its control -- a theme search that returned SOMETHING for every name would # pass the five cases above and be useless. check_eq pyxdg/theme-name 'Child' "$PX_R5_theme_name" check_eq pyxdg/theme-inherits 'brintos-parent' "$PX_R5_theme_inherits" check_eq pyxdg/theme-dirs '16x16/apps|32x32/apps|scalable/apps' "$PX_R5_theme_dirs" check_eq pyxdg/icon-16 'brintos-child/16x16/apps/bst-icon.png' "$PX_R5_icon_16" check_eq pyxdg/icon-32 'brintos-child/32x32/apps/bst-icon.png' "$PX_R5_icon_32" check_eq pyxdg/icon-34-threshold 'brintos-child/32x32/apps/bst-icon.png' "$PX_R5_icon_34_threshold" check_eq pyxdg/icon-scalable-64 'brintos-child/scalable/apps/bst-scalable.svg' "$PX_R5_icon_scalable_64" check_eq pyxdg/icon-inherited 'brintos-parent/48x48/apps/bst-parent-only.png' "$PX_R5_icon_inherited" check_eq pyxdg/icon-absent '' "$PX_R5_icon_absent" # --- Menu: the merge. # # submenus is the assertion the ticket asks for. Accessories is declared in # applications.menu and Editors in fragment.menu, which the first pulls in with # ; only a builder that performed the merge sees both under one root. # The two entry lists then confirm the rules were applied # per-submenu after merging rather than to the whole tree -- Calculator carries # Utility and not TextEditor, so it must appear in one and not the other. check_eq pyxdg/root 'Applications' "$PX_R6_root" check_eq pyxdg/submenus 'Accessories|Editors' "$PX_R6_submenus" check_eq pyxdg/accessories 'Calculator|Text Editor' "$PX_R6_accessories" check_eq pyxdg/editors 'Text Editor' "$PX_R6_editors" # --- and the version the package reports of itself, from inside the payload. check_eq pyxdg/version '0.28' "$PX_R7_version" # ------------- 4. THE CRITERION: the distribution's own unittest modules ------ # NOT IN THIS FILE. The ticket names upstream's suite as this port's preferred # pass criterion, so the bbappend ships it (pyxdg-ptest) and it is run in place # -- by 99-pyxdg-ptest.test, 99-pyxdg-ptest2.test and 99-pyxdg-ptest3.test, # which between them run all ten of its logical modules and carry the two skips. # # WHY THIS SUBJECT IS ITS OWN FILE, and it is a harness bound rather than a # taste. brintos_local_verify ends a boot when the HOST guest process grows past # 2048 MiB/min averaged over 120 s (BRINTOS-1682) while this runtime grows # ~9000 MiB/min whatever the guest does, and brintos-selftest replays a suite's # output only when the suite ENDS (BRINTOS-1742) -- so a suite removed mid-run # loses every case it had already passed. One boot is worth roughly 85-100 s of # guest work and an interpreter start on this arm costs ~18 s. Measured on the # batch-1649 image, 2026-08-28: the single-file form of this suite reported # `==BST-SUITE pyxdg elapsed=202s cases=116==` on a boot that had room for it, # and on the round's own verify it produced ==BST-BEGIN== and not one case line, # on its shared boot AND on the harness's own solo re-run. Eleven interpreter # starts do not fit in one boot. Split by subject they do: 2 starts in # 99-pyxdg.test, 3 here in 99-pyxdg-ptest.test, 4 in -ptest2 and 2 in -ptest3. # NO ASSERTION IS DROPPED -- the ten module case ids are unchanged and the sets # are disjoint; what is added is each file's own ran/lines bookkeeping pair. # # What stays here is everything that does not need the ptest tree: the eight # fixture facts about that tree in section 1 above (its shape is asserted here, # its behaviour there) and sections 2 and 3, which are two interpreter starts.