. "$BST_LIB" # BST-TIMEOUT: 1800 # THREE python3 starts: `import msgpack', `import # # msgpack._cmsgpack', and the probe, which takes one start # # for ~300 measurements. With the extension answering the # # probe's work is milliseconds. The bound is sized for the # # other case: if the extension is refused, msgpack falls # # back to its pure-Python codec and the probe still runs to # # its end, packing and unpacking ten vectors of 65535 or # # 65536 elements in a per-element Python loop -- twice the # # volume 99-python3-u-msgpack-python measured at 247s here. # # python3-msgpack 1.0.7 (meta-openembedded meta-python # recipes-devtools/python/python3-msgpack_1.0.7.bb, `inherit pypi setuptools3 # ptest') on the wasm32-hwjs glibc image. BRINTOS-2475. # # The reference MessagePack serialiser for Python: a Cython extension, # msgpack._cmsgpack, generated as C++ and compiled here as a wasm side module, # plus a complete pure-Python codec in msgpack/fallback.py. # # WHICH CODEC ANSWERS IS THE FIRST QUESTION. msgpack/__init__.py wraps the # extension import in `except ImportError' and silently uses the fallback, so # every behavioural case below passes on either codec. The implementation cases # are what make this a port of the extension rather than of fallback.py: # `cext-import' imports it directly and carries the loader's message on a # refusal; `packer-module'/`unpacker-module'/`unpackb-module' read the package's # own choice; and `depth-1024' checks it by behaviour -- the C unpacker's stack # is a fixed MSGPACK_EMBED_STACK_SIZE of 1024, so 1024-deep nesting decodes, # while the fallback is bounded by the interpreter's recursion limit and refuses # it (measured 994 on the x86-64 control). # # THE EXPECTED BYTES ARE THE SPECIFICATION'S (msgpack/msgpack spec.md), at both # sides of every size boundary. Short encodings are hex literals here; for a # vector whose payload is a long constant run the probe builds the spec's bytes # from format byte, big-endian length and payload, and `spec-*' asserts packb # produced exactly those, with `len-*' and `pfx-*' carrying the part the spec # fixes. Every literal was derived by an independent encoder written from the # spec table and agreed with the x86-64 control on both codecs. # # THREE OF THE TICKET'S ERROR-PATH EXPECTATIONS ARE NOT WHAT THE SOURCE DOES, # and are asserted as the source does them: # - an unknown extension type does NOT raise. unpackb's default ext_hook is # ExtType, so type 5 decodes to ExtType(5, data) (`unknown-ext'). What does # raise is a NEGATIVE unregistered type, because ExtType accepts 0..127 # (`err-negative-ext-code', ValueError). # - there is no nesting limit tied to max_buffer_size. Depth is bounded by the # C unpacker's stack (StackError past 1024) and, on the pack side, by # DEFAULT_RECURSE_LIMIT=511 (ValueError at 512). max_buffer_size is a # streaming Unpacker option and raises BufferFull (`err-buffer-full'); # unpackb does not accept it at all. # - a map key of an unhashable type raises ValueError, not TypeError, under the # default strict_map_key=True, because the key-type check runs before the # dict insert. With strict_map_key=False it is the insert's TypeError. P=python3-msgpack # linux-in-the-browser#177: the harness can drop a suite's first result line and # counts it as a pass, so a nothing-case takes that position. Remove with #177. bst_ok $P/suite-canary require python3 $P/python3-present SITE=/usr/lib/python3.12/site-packages PKG=$SITE/msgpack SO=$PKG/_cmsgpack.cpython-312.so DI=$SITE/msgpack-1.0.7.dist-info PKGLIST=/var/lib/dpkg/info/python3-msgpack.list PROBE=$BST_DATA/python3-msgpack-probe.py tmp=${TMPDIR:-/tmp} W=$tmp/bst-msgpack.$$ mkdir -p "$W" || { bst_notok $P/workdir "cannot create $W"; exit 0; } # --------------------------------------------------------------- packaging --- check $P/site-packages-dir test -d "$SITE" check $P/package-dir test -d "$PKG" check $P/init-file test -f "$PKG/__init__.py" check $P/fallback-file test -f "$PKG/fallback.py" check $P/ext-file test -f "$PKG/ext.py" check $P/exceptions-file test -f "$PKG/exceptions.py" check $P/extension-present test -f "$SO" check $P/extension-nonempty test -s "$SO" # No platform triple in the name: poky's python3 reports an empty EXT_SUFFIX # triple on this arm, and the import resolves through EXTENSION_SUFFIXES. check_eq $P/extension-name "_cmsgpack.cpython-312.so" \ "$(cd "$PKG" 2>/dev/null && echo _cmsgpack.cpython-312*.so)" check $P/no-bin-script test ! -e /usr/bin/msgpack check $P/dist-info-dir test -d "$DI" check $P/dist-info-metadata test -f "$DI/METADATA" check_out $P/dist-info-version "Version: 1.0.7" cat "$DI/METADATA" check_out $P/dist-info-name "Name: msgpack" cat "$DI/METADATA" # The wheel says it is architecture-specific -- the opposite of every # pure-Python port here. check_out $P/dist-info-not-purelib "Root-Is-Purelib: false" cat "$DI/WHEEL" # The list is copied to tmpfs first: a top-level stdin redirect on the virtiofs # root makes dup2(2) return 513 and ends the suite silently (brintos/linux#73). cat "$PKGLIST" > "$W/pkgf" 2>/dev/null || : > "$W/pkgf" check $P/pkg-list-present test -s "$W/pkgf" check_eq $P/pkg-one-so "1" "$(grep -c '\.so$' "$W/pkgf" 2>/dev/null)" # Everything the runtime package ships, by kind. MANIFEST.in recursive-includes # the Cython and C++ sources and headers and setuptools installs them as package # data, so the 1 MB generated _cmsgpack.cpp lands on target beside the module # built from it. Upstream's packaging, pinned so a change to it is seen. _bad="" while IFS= read -r _f; do [ -f "$_f" ] || continue case "$_f" in "$PKG"/*.py|"$PKG"/__pycache__/*.pyc) ;; "$SO") ;; "$PKG"/*.pyx|"$PKG"/*.h|"$PKG"/_cmsgpack.cpp) ;; "$DI"/COPYING|"$DI"/METADATA|"$DI"/RECORD|"$DI"/WHEEL|"$DI"/top_level.txt) ;; *) _bad="$_bad $_f" ;; esac done < "$W/pkgf" check_eq $P/pkg-only-expected "" "$_bad" check_eq $P/pkg-ships-cpp-source "present" \ "$(if [ -f "$PKG/_cmsgpack.cpp" ]; then echo present; else echo absent; fi)" sed -n '/^Package: python3-msgpack$/,/^$/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" check_out $P/pkg-arch "Architecture: wasm32" cat "$W/st" check_eq $P/no-ptest-package "absent" \ "$(if grep -q '^Package: python3-msgpack-ptest$' /var/lib/dpkg/status 2>/dev/null; \ then echo present; else echo absent; fi)" # RDEPENDS is python3-io alone, and it is enough: ext.py imports `datetime' at # module scope, which poky's manifest puts in the datetime split, and python3-io # reaches that split through netclient -> email. grep '^Depends:' "$W/st" > "$W/dep" 2>/dev/null || : > "$W/dep" check_out $P/pkg-depends-core "python3-core" cat "$W/dep" check_out $P/pkg-depends-io "python3-io" cat "$W/dep" check $P/datetime-split python3 -c 'import datetime' # ------------------------------------------------------------------ import --- check $P/import python3 -c 'import msgpack' # The direct import. A refusal here is the loader's, and the package would hide # it behind the fallback; this case is the one that does not. check $P/import-cext python3 -c 'import msgpack._cmsgpack' # ------------------------------------------------------------------- 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" 1500 python3 "$PROBE" OUT="$W/probe" pv() { grep "^$1=" "$OUT" 2>/dev/null | head -n 1 | cut -d= -f2-; } # The word `unscorable' is parsed by brintos_local_verify (BRINTOS-1644). 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 # A trap inside a dlopen'd extension ends the interpreter rather than raising, # so the last key printed names where it stopped. check_eq $P/probe-complete "yes" "$(pv probe_done)" [ "$(pv probe_done)" = "yes" ] || \ bst_notok $P/probe-last-key "last key emitted: '$(tail -n 1 "$OUT" 2>/dev/null | cut -d= -f1)'" check_eq $P/probe-count "300" "$(pv emitted_count)" # ------------------------------------------------------------ the identity --- check_eq $P/import-ok "yes" "$(pv import_ok)" check_eq $P/version "1.0.7" "$(pv version)" check_eq $P/version-tuple "1.0.7" "$(pv version_tuple)" check_eq $P/dist-version "1.0.7" "$(pv dist_version)" check_eq $P/module-answered "$PKG/__init__.py" "$(pv module_file)" check_eq $P/purepython-unset "" "$(pv purepython_env)" # ------------------------------------------------------ the implementation --- check_eq $P/cext-import "ok" "$(pv cext_import)" check_eq $P/cext-answered "$SO" "$(pv cext_file)" check_eq $P/packer-module "msgpack._cmsgpack" "$(pv packer_module)" check_eq $P/unpacker-module "msgpack._cmsgpack" "$(pv unpacker_module)" check_eq $P/unpackb-module "msgpack._cmsgpack" "$(pv unpackb_module)" check_eq $P/cext-is-packer "yes" "$(pv cext_is_packer)" check_eq $P/fallback-unloaded "no" "$(pv fallback_loaded)" check_eq $P/depth-1024 "returned" "$(pv depth_1024)" check_eq $P/depth-1025 "StackError" "$(pv depth_1025)" # ==================================================================== SPEC == check_eq $P/enc-fixint-min "00" "$(pv enc_fixint_min)" check_eq $P/rt-fixint-min "yes" "$(pv rt_fixint_min)" check_eq $P/enc-fixint-max "7f" "$(pv enc_fixint_max)" check_eq $P/rt-fixint-max "yes" "$(pv rt_fixint_max)" check_eq $P/enc-uint8-min "cc80" "$(pv enc_uint8_min)" check_eq $P/rt-uint8-min "yes" "$(pv rt_uint8_min)" check_eq $P/enc-uint8-max "ccff" "$(pv enc_uint8_max)" check_eq $P/rt-uint8-max "yes" "$(pv rt_uint8_max)" check_eq $P/enc-uint16-min "cd0100" "$(pv enc_uint16_min)" check_eq $P/rt-uint16-min "yes" "$(pv rt_uint16_min)" check_eq $P/enc-uint16-max "cdffff" "$(pv enc_uint16_max)" check_eq $P/rt-uint16-max "yes" "$(pv rt_uint16_max)" check_eq $P/enc-uint32-min "ce00010000" "$(pv enc_uint32_min)" check_eq $P/rt-uint32-min "yes" "$(pv rt_uint32_min)" check_eq $P/enc-uint32-max "ceffffffff" "$(pv enc_uint32_max)" check_eq $P/rt-uint32-max "yes" "$(pv rt_uint32_max)" check_eq $P/enc-uint64-min "cf0000000100000000" "$(pv enc_uint64_min)" check_eq $P/rt-uint64-min "yes" "$(pv rt_uint64_min)" check_eq $P/enc-uint64-max "cfffffffffffffffff" "$(pv enc_uint64_max)" check_eq $P/rt-uint64-max "yes" "$(pv rt_uint64_max)" check_eq $P/enc-negfixint-max "ff" "$(pv enc_negfixint_max)" check_eq $P/rt-negfixint-max "yes" "$(pv rt_negfixint_max)" check_eq $P/enc-negfixint-min "e0" "$(pv enc_negfixint_min)" check_eq $P/rt-negfixint-min "yes" "$(pv rt_negfixint_min)" check_eq $P/enc-int8-max "d0df" "$(pv enc_int8_max)" check_eq $P/rt-int8-max "yes" "$(pv rt_int8_max)" check_eq $P/enc-int8-min "d080" "$(pv enc_int8_min)" check_eq $P/rt-int8-min "yes" "$(pv rt_int8_min)" check_eq $P/enc-int16-max "d1ff7f" "$(pv enc_int16_max)" check_eq $P/rt-int16-max "yes" "$(pv rt_int16_max)" check_eq $P/enc-int16-min "d18000" "$(pv enc_int16_min)" check_eq $P/rt-int16-min "yes" "$(pv rt_int16_min)" check_eq $P/enc-int32-max "d2ffff7fff" "$(pv enc_int32_max)" check_eq $P/rt-int32-max "yes" "$(pv rt_int32_max)" check_eq $P/enc-int32-min "d280000000" "$(pv enc_int32_min)" check_eq $P/rt-int32-min "yes" "$(pv rt_int32_min)" check_eq $P/enc-int64-max "d3ffffffff7fffffff" "$(pv enc_int64_max)" check_eq $P/rt-int64-max "yes" "$(pv rt_int64_max)" check_eq $P/enc-int64-min "d38000000000000000" "$(pv enc_int64_min)" check_eq $P/rt-int64-min "yes" "$(pv rt_int64_min)" check_eq $P/enc-nil "c0" "$(pv enc_nil)" check_eq $P/rt-nil "yes" "$(pv rt_nil)" check_eq $P/enc-false "c2" "$(pv enc_false)" check_eq $P/rt-false "yes" "$(pv rt_false)" check_eq $P/enc-true "c3" "$(pv enc_true)" check_eq $P/rt-true "yes" "$(pv rt_true)" check_eq $P/enc-float32-one "ca3f800000" "$(pv enc_float32_one)" check_eq $P/rt-float32-one "yes" "$(pv rt_float32_one)" check_eq $P/enc-float32-onehalf "ca3fc00000" "$(pv enc_float32_onehalf)" check_eq $P/rt-float32-onehalf "yes" "$(pv rt_float32_onehalf)" check_eq $P/enc-float64-one "cb3ff0000000000000" "$(pv enc_float64_one)" check_eq $P/rt-float64-one "yes" "$(pv rt_float64_one)" check_eq $P/enc-float64-half "cb3fe0000000000000" "$(pv enc_float64_half)" check_eq $P/rt-float64-half "yes" "$(pv rt_float64_half)" check_eq $P/enc-float64-neg "cbc000000000000000" "$(pv enc_float64_neg)" check_eq $P/rt-float64-neg "yes" "$(pv rt_float64_neg)" check_eq $P/enc-fixstr-empty "a0" "$(pv enc_fixstr_empty)" check_eq $P/rt-fixstr-empty "yes" "$(pv rt_fixstr_empty)" check_eq $P/enc-fixstr-utf8 "a6c3a9c3a8c3aa" "$(pv enc_fixstr_utf8)" check_eq $P/rt-fixstr-utf8 "yes" "$(pv rt_fixstr_utf8)" check_eq $P/enc-bin8-empty "c400" "$(pv enc_bin8_empty)" check_eq $P/rt-bin8-empty "yes" "$(pv rt_bin8_empty)" check_eq $P/enc-bin8-two "c40200ff" "$(pv enc_bin8_two)" check_eq $P/rt-bin8-two "yes" "$(pv rt_bin8_two)" check_eq $P/enc-fixarray-empty "90" "$(pv enc_fixarray_empty)" check_eq $P/rt-fixarray-empty "yes" "$(pv rt_fixarray_empty)" check_eq $P/enc-fixarray-max "9fc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0" "$(pv enc_fixarray_max)" check_eq $P/rt-fixarray-max "yes" "$(pv rt_fixarray_max)" check_eq $P/enc-array16-min "dc0010c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0" "$(pv enc_array16_min)" check_eq $P/rt-array16-min "yes" "$(pv rt_array16_min)" check_eq $P/enc-fixmap-empty "80" "$(pv enc_fixmap_empty)" check_eq $P/rt-fixmap-empty "yes" "$(pv rt_fixmap_empty)" check_eq $P/enc-fixmap-one "81a16101" "$(pv enc_fixmap_one)" check_eq $P/rt-fixmap-one "yes" "$(pv rt_fixmap_one)" check_eq $P/enc-fixext1 "d40501" "$(pv enc_fixext1)" check_eq $P/rt-fixext1 "yes" "$(pv rt_fixext1)" check_eq $P/enc-fixext2 "d5050101" "$(pv enc_fixext2)" check_eq $P/rt-fixext2 "yes" "$(pv rt_fixext2)" check_eq $P/enc-fixext4 "d60501010101" "$(pv enc_fixext4)" check_eq $P/rt-fixext4 "yes" "$(pv rt_fixext4)" check_eq $P/enc-fixext8 "d7050101010101010101" "$(pv enc_fixext8)" check_eq $P/rt-fixext8 "yes" "$(pv rt_fixext8)" check_eq $P/enc-fixext16 "d80501010101010101010101010101010101" "$(pv enc_fixext16)" check_eq $P/rt-fixext16 "yes" "$(pv rt_fixext16)" check_eq $P/enc-ext8-zero "c70005" "$(pv enc_ext8_zero)" check_eq $P/rt-ext8-zero "yes" "$(pv rt_ext8_zero)" check_eq $P/enc-ext8-three "c70305010101" "$(pv enc_ext8_three)" check_eq $P/rt-ext8-three "yes" "$(pv rt_ext8_three)" check_eq $P/enc-ext8-seventeen "c711050101010101010101010101010101010101" "$(pv enc_ext8_seventeen)" check_eq $P/rt-ext8-seventeen "yes" "$(pv rt_ext8_seventeen)" check_eq $P/spec-fixstr-max "yes" "$(pv spec_fixstr_max)" check_eq $P/len-fixstr-max "32" "$(pv len_fixstr_max)" check_eq $P/pfx-fixstr-max "bf6161616161" "$(pv pfx_fixstr_max)" check_eq $P/rt-fixstr-max "yes" "$(pv rt_fixstr_max)" check_eq $P/spec-str8-min "yes" "$(pv spec_str8_min)" check_eq $P/len-str8-min "34" "$(pv len_str8_min)" check_eq $P/pfx-str8-min "d92061616161" "$(pv pfx_str8_min)" check_eq $P/rt-str8-min "yes" "$(pv rt_str8_min)" check_eq $P/spec-str8-max "yes" "$(pv spec_str8_max)" check_eq $P/len-str8-max "257" "$(pv len_str8_max)" check_eq $P/pfx-str8-max "d9ff61616161" "$(pv pfx_str8_max)" check_eq $P/rt-str8-max "yes" "$(pv rt_str8_max)" check_eq $P/spec-str16-min "yes" "$(pv spec_str16_min)" check_eq $P/len-str16-min "259" "$(pv len_str16_min)" check_eq $P/pfx-str16-min "da0100616161" "$(pv pfx_str16_min)" check_eq $P/rt-str16-min "yes" "$(pv rt_str16_min)" check_eq $P/spec-str16-max "yes" "$(pv spec_str16_max)" check_eq $P/len-str16-max "65538" "$(pv len_str16_max)" check_eq $P/pfx-str16-max "daffff616161" "$(pv pfx_str16_max)" check_eq $P/rt-str16-max "yes" "$(pv rt_str16_max)" check_eq $P/spec-str32-min "yes" "$(pv spec_str32_min)" check_eq $P/len-str32-min "65541" "$(pv len_str32_min)" check_eq $P/pfx-str32-min "db0001000061" "$(pv pfx_str32_min)" check_eq $P/rt-str32-min "yes" "$(pv rt_str32_min)" check_eq $P/spec-bin8-max "yes" "$(pv spec_bin8_max)" check_eq $P/len-bin8-max "257" "$(pv len_bin8_max)" check_eq $P/pfx-bin8-max "c4ff01010101" "$(pv pfx_bin8_max)" check_eq $P/rt-bin8-max "yes" "$(pv rt_bin8_max)" check_eq $P/spec-bin16-min "yes" "$(pv spec_bin16_min)" check_eq $P/len-bin16-min "259" "$(pv len_bin16_min)" check_eq $P/pfx-bin16-min "c50100010101" "$(pv pfx_bin16_min)" check_eq $P/rt-bin16-min "yes" "$(pv rt_bin16_min)" check_eq $P/spec-bin16-max "yes" "$(pv spec_bin16_max)" check_eq $P/len-bin16-max "65538" "$(pv len_bin16_max)" check_eq $P/pfx-bin16-max "c5ffff010101" "$(pv pfx_bin16_max)" check_eq $P/rt-bin16-max "yes" "$(pv rt_bin16_max)" check_eq $P/spec-bin32-min "yes" "$(pv spec_bin32_min)" check_eq $P/len-bin32-min "65541" "$(pv len_bin32_min)" check_eq $P/pfx-bin32-min "c60001000001" "$(pv pfx_bin32_min)" check_eq $P/rt-bin32-min "yes" "$(pv rt_bin32_min)" check_eq $P/spec-array16-max "yes" "$(pv spec_array16_max)" check_eq $P/len-array16-max "65538" "$(pv len_array16_max)" check_eq $P/pfx-array16-max "dcffffc0c0c0" "$(pv pfx_array16_max)" check_eq $P/rt-array16-max "yes" "$(pv rt_array16_max)" check_eq $P/spec-array32-min "yes" "$(pv spec_array32_min)" check_eq $P/len-array32-min "65541" "$(pv len_array32_min)" check_eq $P/pfx-array32-min "dd00010000c0" "$(pv pfx_array32_min)" check_eq $P/rt-array32-min "yes" "$(pv rt_array32_min)" check_eq $P/spec-fixmap-max "yes" "$(pv spec_fixmap_max)" check_eq $P/len-fixmap-max "121" "$(pv len_fixmap_max)" check_eq $P/pfx-fixmap-max "8fa66b303030" "$(pv pfx_fixmap_max)" check_eq $P/rt-fixmap-max "yes" "$(pv rt_fixmap_max)" check_eq $P/spec-map16-min "yes" "$(pv spec_map16_min)" check_eq $P/len-map16-min "131" "$(pv len_map16_min)" check_eq $P/pfx-map16-min "de0010a66b30" "$(pv pfx_map16_min)" check_eq $P/rt-map16-min "yes" "$(pv rt_map16_min)" check_eq $P/spec-map16-max "yes" "$(pv spec_map16_max)" check_eq $P/len-map16-max "524283" "$(pv len_map16_max)" check_eq $P/pfx-map16-max "deffffa66b30" "$(pv pfx_map16_max)" check_eq $P/rt-map16-max "yes" "$(pv rt_map16_max)" check_eq $P/spec-map32-min "yes" "$(pv spec_map32_min)" check_eq $P/len-map32-min "524293" "$(pv len_map32_min)" check_eq $P/pfx-map32-min "df00010000a6" "$(pv pfx_map32_min)" check_eq $P/rt-map32-min "yes" "$(pv rt_map32_min)" check_eq $P/spec-ext8-max "yes" "$(pv spec_ext8_max)" check_eq $P/len-ext8-max "258" "$(pv len_ext8_max)" check_eq $P/pfx-ext8-max "c7ff05010101" "$(pv pfx_ext8_max)" check_eq $P/rt-ext8-max "yes" "$(pv rt_ext8_max)" check_eq $P/spec-ext16-min "yes" "$(pv spec_ext16_min)" check_eq $P/len-ext16-min "260" "$(pv len_ext16_min)" check_eq $P/pfx-ext16-min "c80100050101" "$(pv pfx_ext16_min)" check_eq $P/rt-ext16-min "yes" "$(pv rt_ext16_min)" check_eq $P/spec-ext16-max "yes" "$(pv spec_ext16_max)" check_eq $P/len-ext16-max "65539" "$(pv len_ext16_max)" check_eq $P/pfx-ext16-max "c8ffff050101" "$(pv pfx_ext16_max)" check_eq $P/rt-ext16-max "yes" "$(pv rt_ext16_max)" check_eq $P/spec-ext32-min "yes" "$(pv spec_ext32_min)" check_eq $P/len-ext32-min "65542" "$(pv len_ext32_min)" check_eq $P/pfx-ext32-min "c90001000005" "$(pv pfx_ext32_min)" check_eq $P/rt-ext32-min "yes" "$(pv rt_ext32_min)" check_eq $P/rt-true-type "bool" "$(pv rt_true_type)" check_eq $P/enc-true-not-one "yes" "$(pv enc_true_not_one)" # ------------------------------------------------ the timestamp extension --- # Type -1: 32-bit seconds; 64-bit nanoseconds<<34|seconds; 96-bit for a negative # or >34-bit second count. check_eq $P/enc-ts32 "d6ff5e0be100" "$(pv enc_ts32)" check_eq $P/enc-ts64 "d7ff773594005e0be100" "$(pv enc_ts64)" check_eq $P/enc-ts96-negative "c70cff00000000ffffffffffffffff" "$(pv enc_ts96_negative)" check_eq $P/enc-ts96-past34bits "c70cff000000000000000400000000" "$(pv enc_ts96_past34bits)" check_eq $P/unpack-ts-mode0 "Timestamp(seconds=1577836800, nanoseconds=0)" "$(pv unpack_ts_mode0)" check_eq $P/unpack-ts-mode1 "1577836800.0" "$(pv unpack_ts_mode1)" check_eq $P/unpack-ts-mode2 "1577836800000000000" "$(pv unpack_ts_mode2)" check_eq $P/unpack-ts-mode3 "datetime.datetime(2020, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)" "$(pv unpack_ts_mode3)" check_eq $P/err-ts-mode4 "ValueError" "$(pv err_ts_mode4)" check_eq $P/enc-datetime-opt "d6ff5e0be100" "$(pv enc_datetime_opt)" check_eq $P/err-datetime-default "TypeError" "$(pv err_datetime_default)" check_eq $P/err-datetime-naive "ValueError" "$(pv err_datetime_naive)" check_eq $P/err-ts-bad-length "ValueError" "$(pv err_ts_bad_length)" check_eq $P/err-ts-nanoseconds "ValueError" "$(pv err_ts_nanoseconds)" # ------------------------------------------------------ nested round trip --- check_eq $P/rt-nested "yes" "$(pv rt_nested)" check_eq $P/rt-nested-order "yes" "$(pv rt_nested_keys)" check_eq $P/rt-nested-bool-types "bool,bool" "$(pv rt_nested_bool_types)" check_eq $P/rt-nested-ext-type "ExtType" "$(pv rt_nested_ext_type)" check_eq $P/rt-nested-ts-type "Timestamp" "$(pv rt_nested_ts_type)" # ------------------------------------------------------------- the options --- check_eq $P/opt-strict-map-key-default "ValueError" "$(pv opt_strict_map_key_default)" check_eq $P/opt-strict-map-key-off "{1: None}" "$(pv opt_strict_map_key_off)" check_eq $P/opt-strict-map-key-bytes "bytes:6b" "$(pv opt_strict_map_key_bytes)" check_eq $P/opt-use-bin-type-default "c4026162" "$(pv opt_use_bin_type_default)" check_eq $P/opt-use-bin-type-off "a26162" "$(pv opt_use_bin_type_off)" # The pre-2.0 spec has no str8, so a 32-byte str goes straight to raw16. check_eq $P/opt-use-bin-type-off-str32 "da0020" "$(pv opt_use_bin_type_off_str32)" check_eq $P/opt-raw-default "'ab'" "$(pv opt_raw_default)" check_eq $P/opt-raw-on "b'ab'" "$(pv opt_raw_on)" check_eq $P/opt-raw-on-invalid-utf8 "bytes:ff" "$(pv opt_raw_on_invalid_utf8)" check_eq $P/opt-use-list-off "(1, (2,))" "$(pv opt_use_list_off)" check_eq $P/opt-strict-types-tuple "TypeError" "$(pv opt_strict_types_tuple)" check_eq $P/opt-tuple-default "920102" "$(pv opt_tuple_default)" check_eq $P/opt-default-hook "920102" "$(pv opt_default_hook)" check_eq $P/opt-object-hook "[('a', 1)]" "$(pv opt_object_hook)" check_eq $P/opt-object-pairs-hook "[('b', 1), ('a', 2)]" "$(pv opt_object_pairs_hook)" check_eq $P/opt-both-hooks "TypeError" "$(pv opt_both_hooks)" check_eq $P/opt-ext-hook "tuple:5:01" "$(pv opt_ext_hook)" check_eq $P/opt-max-str-len "ValueError" "$(pv opt_max_str_len)" check_eq $P/opt-max-bin-len "ValueError" "$(pv opt_max_bin_len)" check_eq $P/opt-max-array-len "ValueError" "$(pv opt_max_array_len)" check_eq $P/opt-autoreset-off "0102" "$(pv opt_autoreset_off)" check_eq $P/opt-autoreset-reset "" "$(pv opt_autoreset_reset)" # --------------------------------------------------------------- streaming --- # The same bytes fed one at a time must yield the same objects as one buffer, # and a partial object must yield nothing rather than a short result. check_eq $P/stream-whole-count "8" "$(pv stream_whole_count)" check_eq $P/stream-whole-equal "yes" "$(pv stream_whole_equal)" check_eq $P/stream-bytewise-equal "yes" "$(pv stream_bytewise_equal)" check_eq $P/stream-file-like "[1, 2, 'a']" "$(pv stream_file_like)" check_eq $P/stream-tell "3" "$(pv stream_tell)" check_eq $P/stream-partial-next "StopIteration" "$(pv stream_partial_next)" check_eq $P/stream-partial-unpack "OutOfData" "$(pv stream_partial_unpack)" check_eq $P/stream-partial-completed "'abcde'" "$(pv stream_partial_completed)" check_eq $P/err-buffer-full "BufferFull" "$(pv err_buffer_full)" check_eq $P/stream-pack "81a161920102" "$(pv stream_pack)" check_eq $P/stream-unpack "{'a': [1, 2]}" "$(pv stream_unpack)" check_eq $P/alias-dumps "yes" "$(pv alias_dumps)" check_eq $P/alias-loads "yes" "$(pv alias_loads)" check_eq $P/alias-dump "yes" "$(pv alias_dump)" check_eq $P/alias-load "yes" "$(pv alias_load)" # ------------------------------------------------------------- error paths --- # The exception CLASS is asserted; the message differs between the two codecs # and is carried in each `_text' key for reading a red. for _pair in \ truncated-uint16:ValueError truncated-empty:ValueError \ truncated-float64:ValueError declared-str8:ValueError \ declared-bin32:ValueError declared-array:ValueError \ declared-map:ValueError declared-ext8:ValueError \ unhashable-key:ValueError unhashable-key-lax:TypeError \ reserved-c1:FormatError extra-data:ExtraData \ negative-ext-code:ValueError invalid-utf8:UnicodeDecodeError \ unpackb-str:TypeError pack-uint-overflow:OverflowError \ pack-int-overflow:OverflowError pack-unsupported:TypeError \ ext-code-high:ValueError ext-code-negative:ValueError \ ext-code-type:TypeError ext-data-type:TypeError; do _l=${_pair%%:*}; _k=err_$(printf '%s' "$_l" | tr - _) _got=$(pv "$_k") if [ "$_got" = "${_pair#*:}" ]; then bst_ok $P/err-$_l else bst_notok $P/err-$_l "want:'${_pair#*:}' got:'$_got' ($(pv "${_k}_text"))" fi done check_eq $P/extra-data-unpacked "1" "$(pv extra_data_unpacked)" check_eq $P/extra-data-extra "02" "$(pv extra_data_extra)" check_eq $P/unknown-ext "ExtType:5:01" "$(pv unknown_ext)" check_eq $P/pack-depth-511 "returned" "$(pv pack_depth_511)" check_eq $P/pack-depth-512 "ValueError" "$(pv pack_depth_512)" check_eq $P/exc-format-error "True,True" "$(pv exc_format_error)" check_eq $P/exc-stack-error "True,True" "$(pv exc_stack_error)" check_eq $P/exc-extra-data "True" "$(pv exc_extra_data)" check_eq $P/exc-buffer-full "True" "$(pv exc_buffer_full)" check_eq $P/exc-out-of-data "True" "$(pv exc_out_of_data)" # ---------------------------------------------------------- module closure --- check_eq $P/closure-datetime "yes" "$(pv datetime_imported)" rm -rf "$W"