. "$BST_LIB" # BST-TIMEOUT: 2400 # TWO python3 starts and three loads of the 8.5 MB magic # # database are the cost. # # # # One start is the probe; the other is a bare `import # # magic' at the shell, which is what a caller gets. Inside # # the probe the detect_from_* helpers load the database # # twice (a MAGIC_MIME and a MAGIC_NONE handle) and the # # direct open/load case once more, each through the # # malloc+read() loader 50-file.test budgets 300s for; the # # file(1) calls in section 7 are a dozen more execs, each # # re-reading the same database. 1800 was the budget with # # no database load inside the probe. # # python3-file-magic 0.4.1 (file-magic on PyPI; meta-openembedded/meta-python # recipes-devtools/python/python3-file-magic_0.4.1.bb, `inherit pypi # setuptools3', PyPI sdist) on the wasm32-hwjs glibc image. # # ============================================================================ # WHAT THE PACKAGE IS. # ============================================================================ # # The `file' project's OWN Python binding -- one module, magic.py, 361 lines as # released and 368 as shipped here (a 7-line preload in _init, see below) -- # and it is a ctypes interface to libmagic and nothing else. It opens the # shared libmagic at MODULE SCOPE (line 31 here), declares the restype/argtypes of # fourteen `magic_*' entry points, and wraps them in a Magic class plus three # convenience functions (detect_from_filename, detect_from_content, # detect_from_fobj) that each return a FileMagic namedtuple of # (mime_type, encoding, name). # # ============================================================================ # THE MODULE WORKS ON THIS IMAGE SINCE BRINTOS-2269, AND IS DRIVEN HERE. # ============================================================================ # # BRINTOS-2210 landed this port with the module unreachable, behind two gaps # that each sufficed to stop it: no _ctypes (libffi could not call, and its # closure allocator could not even be linked -- hwjs-cc#15, # linux-in-the-browser#180) and no shared libmagic (the package-shared flip was # off). BRINTOS-1740 closed the second; BRINTOS-2269 closed the first, with a # libffi whose ffi_call works through a table of statically typed trampolines, # _ctypes built into the interpreter, and a find_library that can answer on # this arm. The red witnesses that asserted both refusals verbatim are # INVERTED below rather than deleted, as they were written to be. # # WHAT THE PROBE MEASURES IS THE REAL MODULE OVER THE REAL LIBRARY. It loads # this package's magic.py by path -- a bare `import magic' is python-magic's # package on this image, see section 1 -- and reports the library object # magic.py itself opened: a ctypes.CDLL named /usr/lib/libmagic.so.1 with a # non-zero handle. A suite built on a faked ctypes handle would measure the # fake and stay green while the port shipped dead; these cases are what rule # that out. # # ============================================================================ # THE THREE detect_from_* HELPERS DO NOT ALL AGREE, AND THAT IS LIBMAGIC. # ============================================================================ # # BRINTOS-2210's requirement 4 said detect_from_content agrees with # detect_from_filename over the same bytes. It does not, on any arm, and the # suite asserts what libmagic actually does -- measured on an x86-64 control # running the byte-identical magic.py against host libmagic 5.45, the version # this image builds (BRINTOS-2269, 2026-09-18), and matching on target: # # gzip detect_from_content cannot reach the stream trailer, so its name # lacks ", original size modulo 2^32 43"; detect_from_fobj goes # through magic_descriptor, which fstats, and sides with the path. # empty the path says inode/x-empty -- a verdict about the directory entry -- # and both the buffer and the descriptor say application/x-empty. # # Every other fixture agrees across all three. A MISSING PATH RAISES # ValueError, not magic.error: libmagic returns its error text where a type # would go, the text has no '; ', and _create_filemagic's split fails. P=python3-file-magic bst_ok $P/suite-canary require python3 $P/python3-present require file $P/file-present SITE=/usr/lib/python3.12/site-packages DI=$SITE/file_magic-0.4.1.dist-info PKGLIST=/var/lib/dpkg/info/python3-file-magic.list PROBE=$BST_DATA/python3-file-magic-probe.py tmp=${TMPDIR:-/tmp} W=$tmp/bst-file-magic.$$ mkdir -p "$W" || { bst_notok $P/workdir "cannot create $W"; exit 0; } # --- 1. what shipped -------------------------------------------------------- # IT IS ONE MODULE FILE, NOT A PACKAGE DIRECTORY -- setup.py declares # `py_modules=['magic']'. Asserted both ways round: a release that grew a # package directory would still satisfy every source-level case in the probe. # # Asserted against THIS PACKAGE'S OWN FILE LIST, not the directory: python3-magic # (python-magic 0.4.27, 99-python3-magic) installs a `magic/' package directory # beside this magic.py, and a package directory wins the import. So on an image # carrying both, a bare `import magic' is python-magic's -- which is why the # probe loads this package's magic.py by path (section 8). check $P/site-packages-dir test -d "$SITE" check $P/module-file test -s "$SITE/magic.py" check_eq $P/no-package-dir "" \ "$(grep "^$SITE/magic/" /var/lib/dpkg/info/python3-file-magic.list 2>/dev/null)" # The byte-exact identity of what landed: the sdist the SRC_URI pins plus the # layer's one patch, which loads liblzma and libbz2 before libmagic in _init # (libmagic.so records no NEEDED list, hwjs-cc#128). The patch is also asserted # by content, so a sha mismatch says which way the file moved. check_eq $P/module-sha256 \ "d6d1e16e250e6324567e6bf5b21db49923adbf0d787417415aa52901ad3bdff1" \ "$(sha256sum "$SITE/magic.py" 2>/dev/null | cut -d' ' -f1)" check_out $P/module-preload "for dep in ('lzma', 'bz2'):" cat "$SITE/magic.py" check $P/pycache-dir test -d "$SITE/__pycache__" check $P/pycache-magic test -s "$SITE/__pycache__/magic.cpython-312.pyc" # --- 2. the dist-info ------------------------------------------------------- # THE DIRECTORY IS NAMED FOR THE PyPI DISTRIBUTION, NOT THE IMPORT NAME, and the # two differ here: `file_magic-0.4.1.dist-info' against `magic.py'. A reader # looking for a "file_magic" module on this rootfs will not find one. check $P/dist-info-dir test -d "$DI" check $P/dist-info-metadata test -f "$DI/METADATA" check_out $P/dist-info-name "Name: file-magic" cat "$DI/METADATA" check_out $P/dist-info-version "Version: 0.4.1" cat "$DI/METADATA" check_out $P/dist-info-summary "Python front end for libmagic" cat "$DI/METADATA" check_eq $P/dist-info-top-level "magic" "$(cat "$DI/top_level.txt" 2>/dev/null)" check_out $P/dist-info-purelib "Root-Is-Purelib: true" cat "$DI/WHEEL" check $P/dist-info-license test -s "$DI/LICENSE" # THE VERSION IN setup.py IS 0.4.0 AND THE ONE THAT SHIPS IS 0.4.1. The sdist's # PKG-INFO carries 0.4.1 and setuptools prefers it, so the recipe's filename, # the dist-info and METADATA all agree at 0.4.1 while setup.py disagrees with # all three. Recorded because it is the first thing a reader auditing the # version will trip on; nothing here depends on setup.py. # --- 3. the console script that cannot run ---------------------------------- # UPSTREAM PACKAGING DEFECT, NOT A PLATFORM GAP, and the one case in this suite # that would be red on x86-64 too. file-magic 0.4.1's entry_points.txt declares # # [console_scripts] # realpython = example.__main__:main # # and the sdist ships NO `example' module -- py_modules is ['magic'] alone. So # `inherit setuptools3' faithfully generates /usr/bin/realpython, it lands on # this image's PATH, and it fails on its own import line for a reason that has # nothing to do with ctypes. It is left in place rather than removed by a # bbappend: it is upstream's packaging, it fails cleanly and immediately, and it # is a #! script rather than a wasm module, so the image's exec census -- which # enumerates by wasm magic -- never attempts it and no census case can go red # for it. Asserted here so the dead entry point is on the record. # # We file nothing upstream for this: docs/conventions/no-public-upstream-reports. check $P/script-present test -f /usr/bin/realpython check $P/script-executable test -x /usr/bin/realpython check_out $P/script-imports-example "from example.__main__ import main" \ cat /usr/bin/realpython check $P/script-example-absent test ! -e "$SITE/example" # RED WITNESS: the script is dead on arrival, and this says so in its own words. check_eq $P/script-refused \ "ModuleNotFoundError: No module named 'example'" \ "$(/usr/bin/realpython 2>&1 | tail -1)" # --- 4. dpkg status and the dependency set ---------------------------------- sed -n '/^Package: python3-file-magic$/,/^$/p' /var/lib/dpkg/status > "$W/st" 2>/dev/null check $P/pkg-known test -s "$W/st" check_out $P/pkg-installed "Status: install ok installed" cat "$W/st" grep '^Depends:' "$W/st" > "$W/dep" 2>/dev/null || : > "$W/dep" check $P/pkg-depends-line test -s "$W/dep" # THE FOUR DEPENDENCIES, EACH ASSERTED SEPARATELY, measured off the built .deb: # Depends: file, python3-core, python3-ctypes, python3-threading # # `file' is the interesting one and it is what makes this port's dependency # graph honest: the binding needs the LIBRARY, and the only thing on this image # that provides libmagic is the `file' package (BRINTOS-1844), already here. # # python3-ctypes packages the pure-Python half of ctypes; the C half, _ctypes, # is built into the interpreter itself on this arm (every stdlib extension is), # so python3-ctypes is the whole of what the dependency needs to deliver. for _d in file python3-core python3-ctypes python3-threading; do check_out $P/pkg-depends-$_d "$_d" cat "$W/dep" done # ...and the package really is only those four. A fifth would mean the recipe # grew a dependency this suite has not reasoned about. check_eq $P/pkg-depends-exact \ "Depends: file, python3-core, python3-ctypes, python3-threading" \ "$(cat "$W/dep")" # --- 5. from a shell: what a caller gets ------------------------------------ # INVERTED WITNESSES. Until BRINTOS-2269 both answered # `ModuleNotFoundError: No module named '_ctypes''. `import magic' here is # whichever package wins the name on this image (section 1); the module under # test is driven by path in section 8. check_eq $P/pkg-import "ok" "$(python3 -c 'import magic; print("ok")' 2>&1 | tail -1)" check_eq $P/ctypes-import "ok" "$(python3 -c 'import ctypes; print("ok")' 2>&1 | tail -1)" # --- 6. GAP 2 is closed: the shared libmagic ------------------------------- # INVERTED WITNESS. Until BRINTOS-1740's flip this rootfs carried libmagic.a # and no libmagic.so, and this case asserted the absence. The soname is what # find_library answers with (section 8). check $P/shared-libmagic test -e /usr/lib/libmagic.so.1 check $P/file-binary test -x /usr/bin/file check $P/magic-db test -s /usr/share/misc/magic.mgc # --- 7. libmagic through file(1), the reference half ----------------------- # Every value below is `file -i' and `file -b' over the corpus the probe then # drives through the module, and each is one half of the FileMagic tuple # detect_from_filename returns. Until BRINTOS-2269 this section stood in for # the module (requirement 3 was met "at one remove" here); it stays as the # reference: a module answer that disagreed with file(1) over the same bytes # would be a fault in the Python path, not in libmagic. # # The corpus is written from literal bytes rather than pointed at the rootfs, # for 50-file.test's reason: a wasm32-hwjs rootfs contains no ELF at all, so a # test classifying an image binary would be asserting something about # HardwareJS packaging instead of about libmagic. printf '\177ELF\001\001\001\000\000\000\000\000\000\000\000\000\001\000\003\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\064\000\000\000\000\000\050\000\000\000\000\000' > "$W/elf.o" printf 'plain ascii text here\n' > "$W/ascii.txt" printf 'na\303\257ve caf\303\251 \342\200\224 \317\200\n' > "$W/utf8.txt" : > "$W/empty" # The gzip stream is a fixture rather than generated on target: its trailer # carries the original size and its header the compression level and OS byte, # all of which appear in the answer, so generating it here would make the # expected string depend on the guest's gzip rather than on libmagic. gz=$BST_DATA/file-sample.gz check $P/fixture-gz test -s "$gz" # The mime_type and encoding halves, as one string per fixture -- `file -b -i' # is exactly what magic.py splits on '; '. check_eq $P/mime-elf "application/x-object; charset=binary" "$(file -b -i "$W/elf.o")" check_eq $P/mime-gzip "application/gzip; charset=binary" "$(file -b -i "$gz")" check_eq $P/mime-utf8 "text/plain; charset=utf-8" "$(file -b -i "$W/utf8.txt")" check_eq $P/mime-ascii "text/plain; charset=us-ascii" "$(file -b -i "$W/ascii.txt")" check_eq $P/mime-empty "inode/x-empty; charset=binary" "$(file -b -i "$W/empty")" # The `name' half -- the MAGIC_NONE handle's answer. check_eq $P/name-elf "ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV)" "$(file -b "$W/elf.o")" check_eq $P/name-gzip "gzip compressed data, max compression, from Unix, original size modulo 2^32 43" "$(file -b "$gz")" check_eq $P/name-utf8 "Unicode text, UTF-8 text" "$(file -b "$W/utf8.txt")" check_eq $P/name-ascii "ASCII text" "$(file -b "$W/ascii.txt")" check_eq $P/name-empty "empty" "$(file -b "$W/empty")" # The ticket also names a PNG header. It is not in 50-file.test's corpus, so it # is built here and asserted through the same two calls -- an 8-byte signature # plus a 13-byte IHDR for a 1x1 8-bit RGB image, which is all libmagic reads. printf '\211PNG\r\n\032\n\000\000\000\015IHDR\000\000\000\001\000\000\000\001\010\002\000\000\000\220wS\336' > "$W/one.png" check_eq $P/mime-png "image/png; charset=binary" "$(file -b -i "$W/one.png")" check_eq $P/name-png "PNG image data, 1 x 1, 8-bit/color RGB, non-interlaced" "$(file -b "$W/one.png")" # CONTENT, NOT EXTENSION -- the property a half-loaded magic DB silently loses, # and the one that would make every value above meaningless if it were broken. cp "$gz" "$W/misnamed.txt" check_eq $P/content-not-suffix "application/gzip; charset=binary" \ "$(file -b -i "$W/misnamed.txt")" # --- 8. the probe ----------------------------------------------------------- if [ ! -f "$PROBE" ]; then bst_notok $P/probe-present "$PROBE did not ship" rm -rf "$W" exit 0 fi bst_ok $P/probe-present bst_probe $P/probe-run "$W/probe" 1800 python3 "$PROBE" "$W" "$gz" OUT="$W/probe" pv() { grep "^$1=" "$OUT" 2>/dev/null | head -n 1 | cut -d= -f2-; } if [ -s "$OUT" ]; then bst_ok $P/probe-output else bst_notok $P/probe-output "the probe emitted nothing -- python3 did not start, or died before its first line; every CASE below is unscorable" fi check_eq $P/probe-complete "yes" "$(pv probe_done)" check_eq $P/probe-count "87" "$(pv emitted_count)" # The probe read the SAME copy this suite has been asserting against. check_eq $P/probe-site-dir "$SITE" "$(pv site_dir)" check_eq $P/probe-module-found "yes" "$(pv module_found)" check_eq $P/probe-module-sha256 \ "d6d1e16e250e6324567e6bf5b21db49923adbf0d787417415aa52901ad3bdff1" \ "$(pv module_sha256)" check_eq $P/probe-module-bytes "11004" "$(pv module_bytes)" check_eq $P/probe-module-lines "368" "$(pv module_lines)" # ------------------------------------------- the two gaps, from inside python -- # INVERTED WITNESSES, all four: each answered the `_ctypes' refusal until # BRINTOS-2269. check_eq $P/probe-ctypes-import "imported" "$(pv ctypes_import)" check_eq $P/probe-ctypes-util "imported" "$(pv ctypes_util_import)" check_eq $P/probe-magic-import "imported" "$(pv magic_import)" # _ctypes is compiled into the interpreter, as every stdlib extension is here. check_eq $P/probe-ctypes-builtin "present" "$(pv ctypes_builtin)" check_eq $P/probe-ctypes-pkg-present "yes" "$(pv ctypes_pkg_present)" # find_library answers with the soname's PATH on this arm: ldconfig cannot read # a wasm shared object and dlopen does not search a bare name. check_eq $P/probe-find-library "/usr/lib/libmagic.so.1" "$(pv find_library_magic)" # Which package a bare `import magic' reaches -- python-magic's while it is # installed beside this one. if [ -f /var/lib/dpkg/info/python3-magic.list ]; then want_by_name="$SITE/magic/__init__.py" else want_by_name="$SITE/magic.py" fi check_eq $P/probe-import-by-name "$want_by_name" "$(pv magic_import_file)" for _m in threading collections os sys; do check_eq $P/stdlib-$_m "ok" "$(pv stdlib_$_m)" done # ------------------------------------------ the module, loaded and not faked -- check_eq $P/fm-load "ok" "$(pv fm_load)" check_eq $P/fm-lib-type "ctypes.CDLL" "$(pv fm_lib_type)" check_eq $P/fm-lib-name "/usr/lib/libmagic.so.1" "$(pv fm_lib_name)" check_eq $P/fm-lib-handle "nonzero" "$(pv fm_lib_handle)" check_eq $P/fm-ctypes-file "/usr/lib/python3.12/ctypes/__init__.py" "$(pv fm_ctypes_file)" check_eq $P/fm-open-foreign "yes" "$(pv fm_open_is_foreign)" # ------------------------- requirement 3: detect_from_filename, six fixtures -- # mime_type|encoding|name -- the same halves section 7 asserts through file(1). check_eq $P/fn-elf "application/x-object|binary|ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV)" "$(pv fn_elf)" check_eq $P/fn-gzip "application/gzip|binary|gzip compressed data, max compression, from Unix, original size modulo 2^32 43" "$(pv fn_gzip)" check_eq $P/fn-utf8 "text/plain|utf-8|Unicode text, UTF-8 text" "$(pv fn_utf8)" check_eq $P/fn-ascii "text/plain|us-ascii|ASCII text" "$(pv fn_ascii)" check_eq $P/fn-empty "inode/x-empty|binary|empty" "$(pv fn_empty)" check_eq $P/fn-png "image/png|binary|PNG image data, 1 x 1, 8-bit/color RGB, non-interlaced" "$(pv fn_one)" # -------------- requirement 4: detect_from_content, the MEASURED relationship -- # Not agreement -- see the header. gzip loses the trailer, empty is # application/x-empty; the other four agree with the path. check_eq $P/ct-elf "application/x-object|binary|ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV)" "$(pv ct_elf)" check_eq $P/ct-gzip "application/gzip|binary|gzip compressed data, max compression, from Unix" "$(pv ct_gzip)" check_eq $P/ct-utf8 "text/plain|utf-8|Unicode text, UTF-8 text" "$(pv ct_utf8)" check_eq $P/ct-ascii "text/plain|us-ascii|ASCII text" "$(pv ct_ascii)" check_eq $P/ct-empty "application/x-empty|binary|empty" "$(pv ct_empty)" check_eq $P/ct-png "image/png|binary|PNG image data, 1 x 1, 8-bit/color RGB, non-interlaced" "$(pv ct_one)" # ------------------------- requirement 5: detect_from_fobj, an open handle -- # Through magic_descriptor: the path's answer for gzip, the buffer's for empty. check_eq $P/fo-elf "application/x-object|binary|ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV)" "$(pv fo_elf)" check_eq $P/fo-gzip "application/gzip|binary|gzip compressed data, max compression, from Unix, original size modulo 2^32 43" "$(pv fo_gzip)" check_eq $P/fo-utf8 "text/plain|utf-8|Unicode text, UTF-8 text" "$(pv fo_utf8)" check_eq $P/fo-ascii "text/plain|us-ascii|ASCII text" "$(pv fo_ascii)" check_eq $P/fo-empty "application/x-empty|binary|empty" "$(pv fo_empty)" check_eq $P/fo-png "image/png|binary|PNG image data, 1 x 1, 8-bit/color RGB, non-interlaced" "$(pv fo_one)" # ------------------------- requirement 6: a path that does not exist raises -- check_eq $P/fn-missing-raises \ "ValueError: cannot open \`/no/such/file-magic-fixture' (No such file or directory)" \ "$(pv fn_missing)" # ----------------- requirement 7: magic.open / load / close, driven directly -- check_eq $P/r7-open "Magic" "$(pv r7_open)" check_eq $P/r7-load "0" "$(pv r7_load)" check_eq $P/r7-file "image/png" "$(pv r7_file)" check_eq $P/r7-buffer "image/png" "$(pv r7_buffer)" check_eq $P/r7-descriptor "image/png" "$(pv r7_descriptor)" check_eq $P/r7-setflags "0" "$(pv r7_setflags)" check_eq $P/r7-file-none "PNG image data, 1 x 1, 8-bit/color RGB, non-interlaced" "$(pv r7_file_none)" # libmagic 5.45's default bytes_max, then set and read back through c_int # pointers -- a value that round-trips through byref() both ways. check_eq $P/r7-getparam "7340032" "$(pv r7_getparam_bytes_max)" check_eq $P/r7-setparam "0" "$(pv r7_setparam)" check_eq $P/r7-getparam-after "4096" "$(pv r7_getparam_after)" check_eq $P/r7-error-clean "None" "$(pv r7_error_clean)" check_eq $P/r7-setflags-error "0" "$(pv r7_setflags_error)" # With MAGIC_ERROR set, a missing file is None plus errno/error, not a type. check_eq $P/r7-file-missing "None" "$(pv r7_file_missing)" check_eq $P/r7-errno "2" "$(pv r7_errno)" check_eq $P/r7-error \ "cannot stat \`/no/such/file-magic-fixture' (No such file or directory)" \ "$(pv r7_error)" check_eq $P/r7-close "ok" "$(pv r7_close)" check_eq $P/r7-load-bad "-1" "$(pv r7_load_bad)" check_eq $P/r7-load-bad-error "yes" "$(pv r7_load_bad_error_set)" # ------------------------------------------------ the shipped API, by source -- # What landed really is file-magic 0.4.1's API and not some other module named # magic.py, read from the source: the surface the calls above exercise. check_eq $P/probe-ast-parse "ok" "$(pv ast_parse)" # `import ctypes' is the first import -- until BRINTOS-2269 nothing past it ran. check_eq $P/ast-ctypes-line "7" "$(pv ast_import_ctypes_line)" check_eq $P/ast-threading-line "8" "$(pv ast_import_threading_line)" check_eq $P/ast-imports "collections,ctypes,ctypes.util,threading" "$(pv ast_imports)" # THE LOAD AT MODULE SCOPE, at line 31: not a lazy loader, no import-time guard, # so the module is all-or-nothing. check_eq $P/ast-module-scope-init "yes" "$(pv ast_module_scope_init)" check_eq $P/ast-module-scope-init-line "31" "$(pv ast_module_scope_init_line)" # ...and the library it asks for by name, which is what ties this port to the # `file' recipe rather than to some other provider of a libmagic. check_eq $P/ast-find-library-arg "magic" "$(pv ast_find_library_arg)" check_eq $P/ast-funcs \ "_create_filemagic,_detect_make,_init,detect_from_content,detect_from_filename,detect_from_fobj,open" \ "$(pv ast_funcs)" check_eq $P/ast-classes "Magic,MagicDetect,error,magic_set" "$(pv ast_classes)" check_eq $P/ast-detect-funcs \ "detect_from_content,detect_from_filename,detect_from_fobj" \ "$(pv ast_detect_funcs)" check_eq $P/ast-magic-methods \ "buffer,check,close,compile,descriptor,errno,error,file,getparam,list,load,setflags,setparam" \ "$(pv ast_magic_methods)" # THE FOURTEEN libmagic ENTRY POINTS THE MODULE BINDS, each resolved by dlsym # against libmagic.so.1 when the module loads (fm-load above). check_eq $P/ast-libmagic-symbols \ "magic_buffer,magic_check,magic_close,magic_compile,magic_descriptor,magic_errno,magic_error,magic_file,magic_getparam,magic_list,magic_load,magic_open,magic_setflags,magic_setparam" \ "$(pv ast_libmagic_symbols)" check_eq $P/ast-libmagic-symbol-count "14" "$(pv ast_libmagic_symbol_count)" # FileMagic's FIELD ORDER. All three detect_from_* helpers return this # namedtuple, and the order is NOT the order _create_filemagic passes its # keyword arguments in -- a caller unpacking positionally gets # (mime_type, encoding, name). check_eq $P/ast-filemagic-fields "mime_type,encoding,name" "$(pv ast_filemagic_fields)" # The flag constants, as literals. check_eq $P/const-none "0" "$(pv const_MAGIC_NONE)" check_eq $P/const-mime-type "16" "$(pv const_MAGIC_MIME_TYPE)" check_eq $P/const-mime-encoding "1024" "$(pv const_MAGIC_MIME_ENCODING)" check_eq $P/const-mime "1040" "$(pv const_MAGIC_MIME)" check_eq $P/const-continue "32" "$(pv const_MAGIC_CONTINUE)" check_eq $P/const-error "512" "$(pv const_MAGIC_ERROR)" check_eq $P/const-raw "256" "$(pv const_MAGIC_RAW)" check_eq $P/const-compress "4" "$(pv const_MAGIC_COMPRESS)" check_eq $P/const-symlink "2" "$(pv const_MAGIC_SYMLINK)" check_eq $P/const-devices "8" "$(pv const_MAGIC_DEVICES)" # MAGIC_MIME really is MIME_TYPE|MIME_ENCODING, computed by the probe rather # than restated here. It is the flag detect_from_* opens with, and the reason # one call yields both halves of the answer. check_eq $P/const-mime-composite "yes" "$(pv const_mime_is_composite)" rm -rf "$W"