# BST-TIMEOUT: 600 # 185 s measured (==BST-SUITE, local verify, 2026-08-08); the # 44 cases are cheap but one of them runs upstream's `benchmark`, # which makes 3.78 M lookups — 3.6 s native, ~180 s here. The # 60 s default is nowhere near. . "$BST_LIB" # 81-geoip.test — GeoIP 1.6.12 (MaxMind's LEGACY C API, meta-networking # recipes-support/geoip) on wasm32-hwjs, closed on the package's own upstream # test suite, which OpenEmbedded packages as a ptest. # # It is numbered into the 81 slot beside 81-libmaxminddb, its successor library # and closest kin, following this tree's subject grouping rather than clustering # by "is a ptest port". The two answer the same question from different eras: # libmaxminddb reads the modern MMDB format, geoip reads the .dat format that # preceded it, and geoiplookup(1)/geoiplookup6(1) are how a target shell reaches # the latter. # # THE PACKAGED PTEST, AS meta-networking SHIPS IT, CANNOT FAIL EXCEPT BY # CRASHING — and repairing that is most of this port. Upstream's # test/Makefile.am lists `TESTS = test-geoip test-geoip-invalid-file`, the only # two programs in the tree that assert anything. The recipe's do_configure_ptest # seds `noinst_PROGRAMS` (the eight demo programs) to `test_PROGRAMS` and # do_install_ptest installs those, so the shipped ptest carries NEITHER member # of TESTS, and its run-ptest runs two of the eight it does carry. Measured: # `benchmark` prints lookup rates and returns 0 whatever it measured (a missing # database is a printf, and the function returns), and `test-geoip-city` prints # one tab-separated row per address and returns 0 unconditionally. A geolocation # answered WRONGLY — the only interesting way this library fails — could not turn # the packaged suite red. # # The bbappend installs the two real tests and their fixtures and this layer's # run-ptest runs them, so the gate below is worth ~616 assertions: each of the 61 # addresses in country_test.txt checked four ways (code/code3 x by-addr/by-name) # against its expected country over both the filesystem and the memory-cache open # mode, the 61 in country_test2.txt, the database-info string, the NULL-query # contract, and that a non-database file opens to NULL rather than to garbage. # # THE ORACLE IS A NATIVE x86_64 CONTROL of the identical source (SRCREV # 4b526e73; the recipe carries no patch series), autoreconf'd the way # autotools.bbclass does it and configured --disable-shared like the distro, # with the recipe's ptest seds and this bbappend's install applied — i.e. the # same layout the target runs. It reported 4/4 PASS under both dash and busybox # ash. Every expected string below was read off that run, never off a spec. require geoiplookup geoip/present ptestdir=/usr/lib/geoip/ptest tests=$ptestdir/tests share=/usr/share/GeoIP # ------------------------------------------------------------- packaging --- # check_rc with `test` is an ash builtin and forks nothing, unlike check/check_out # whose command substitution does — so the presence half of this file is free on # an arm where every exec is a fresh wasm module instantiation. check_rc geoip/lib-static 0 test -f /usr/lib/libGeoIP.a check_rc geoip/header-geoip 0 test -f /usr/include/GeoIP.h check_rc geoip/header-geoipcity 0 test -f /usr/include/GeoIPCity.h check_rc geoip/pkgconfig 0 test -f /usr/lib/pkgconfig/geoip.pc check_rc geoip/tool-geoiplookup 0 test -x /usr/bin/geoiplookup check_rc geoip/tool-geoiplookup6 0 test -x /usr/bin/geoiplookup6 # No libGeoIP.so on a distro that configures --disable-shared image-wide. Pinned # as a positive because the recipe's own EXTRA_OECONF asks for --disable-static: # libtool resolves the pair by re-enabling static (build_old_libs is the negation # of build_libtool_libs), and a shared object appearing here would mean that # resolution stopped holding and the archive above may be the stale one. if [ -e /usr/lib/libGeoIP.so ] || [ -e /usr/lib/libGeoIP.so.1 ]; then bst_notok geoip/static-only "a shared libGeoIP shipped on a --disable-shared distro" else bst_ok geoip/static-only fi # The four 2018-12-05 databases the recipe installs, plus the GeoIPCity.dat # symlink do_install creates — which is not decoration: test-geoip-city opens # "../data/GeoIPCity.dat", seded to $share/GeoIPCity.dat, and there is no file of # that name to open without it. check_rc geoip/db-country 0 test -f "$share/GeoIP.dat" check_rc geoip/db-countryv6 0 test -f "$share/GeoIPv6.dat" check_rc geoip/db-city 0 test -f "$share/GeoLiteCity.dat" check_rc geoip/db-cityv6 0 test -f "$share/GeoLiteCityv6.dat" check_rc geoip/db-city-symlink 0 test -L "$share/GeoIPCity.dat" # --------------------------------------------------------- ptest payload --- check_rc geoip/ptest-runptest 0 test -x "$ptestdir/run-ptest" check_rc geoip/ptest-testdir 0 test -d "$tests" # The ten programs the ptest carries. Named rather than counted: the four # run-ptest drives are the gate, and the other six are what a later reader will # reach for when a lookup family needs isolating, so one silently absent costs # coverage without costing a case. for b in test-geoip test-geoip-invalid-file benchmark test-geoip-city \ test-geoip-region test-geoip-org test-geoip-domain \ test-geoip-asnum test-geoip-isp test-geoip-netspeed; do check_rc "geoip/prog-$b" 0 test -x "$tests/$b" done # The fixtures the two real tests read. do_configure_ptest seds SRCDIR from # $(top_srcdir) to $(testdir), so these paths ARE what the binaries have compiled # in; a missing one is not a missing file but a test that exits 1 at its first # fopen. The first is upstream's own 3960-byte fixture database, deliberately not # the 1.2 MB one in $share: test-geoip asserts its GeoIP_database_info string # exactly, and only the fixture carries the expected GEO-106 20160621 build. check_rc geoip/fixture-srcdir-db 0 test -f "$tests/data/GeoIP.dat" check_rc geoip/fixture-country-test 0 test -f "$tests/test/country_test.txt" check_rc geoip/fixture-country-test2 0 test -f "$tests/test/country_test2.txt" check_rc geoip/fixture-readme 0 test -f "$tests/README.md" check_rc geoip/fixture-city-test 0 test -f "$tests/city_test.txt" # meta-networking's run-ptest writes `[ $? == 0 ]`. `==` is a bash extension to # test(1); busybox ash accepts it, which is why it survived on the images this # ptest has run on, but under dash it is not a wrong verdict on one case but on # all of them — measured natively, the stock script reports FAIL for all four # programs while every one of them exited 0. This layer ships `=`. Pinned so a # future rebase that quietly restores upstream's copy is a red here rather than a # suite that goes green-to-red the day /bin/sh changes. # # Anchored on the `if` LINE, not on the string anywhere in the file: the shipped # run-ptest explains this fix in a comment that necessarily quotes the bad form, # and a bare `grep '== 0'` matches that comment. Measured — the first gate run # came back red on this case against a run-ptest whose code reads `[ $? = 0 ]`. if grep -qE '^[[:space:]]*if \[ \$\? == 0 \]' "$ptestdir/run-ptest" 2>/dev/null; then bst_notok geoip/ptest-runptest-posix "run-ptest uses the bash-only \`[ \$? == 0 ]\`; under dash it reports FAIL for every program regardless of exit status" else bst_ok geoip/ptest-runptest-posix fi # ------------------------------------------------ the tool, against control --- # geoiplookup(1) is what makes this port visible from a target shell, and it is # the one path the ptest does not touch. Every expected string here was measured # on the native x86_64 control against the SAME 2018-12-05 databases that ship. # Literal dotted quads only: a name would reach gethostbyname, and this guest has # no resolver. check_out geoip/lookup-country-us "GeoIP Country Edition: US, United States" geoiplookup 8.8.8.8 check_out geoip/lookup-country-es "GeoIP Country Edition: ES, Spain" geoiplookup 80.24.24.24 check_out geoip/lookup-country-au "GeoIP Country Edition: AU, Australia" geoiplookup 1.1.1.1 # RFC1918 space is in no database; "not found" is the library's answer, and it is # a different code path from a lookup that hits. check_out geoip/lookup-private "IP Address not found" geoiplookup 10.0.0.1 # The database-info string is a straight read of the file header, so it separates # "the database shipped" from "the database is readable". check_out geoip/lookup-dbinfo "GEO-106FREE 20180327 Build 1" geoiplookup -v 8.8.8.8 # -i prints the netmask arithmetic: the range the answer covers, derived by # walking the binary tree and reconstructing the prefix. This is the one case # here that exercises 32-bit integer arithmetic rather than a table read. check_out geoip/lookup-netmask "network: 8.8.0.0 - 8.11.255.255" geoiplookup -i 8.8.8.8 # The city edition is the port's real payload: one record carries country, # region, region name, city, postal code, latitude, longitude, metro and area # code. The two floats are printf("%f") of doubles decoded from the file, so this # case is also a statement about this arm's double formatting. check_out geoip/lookup-city \ "US, NY, New York, Syracuse, 13201, 43.048100, -76.147400, 555, 315" \ geoiplookup -f "$share/GeoLiteCity.dat" 24.24.24.24 # A record with no city: 8.8.8.8 resolves to country-level coordinates with N/A # in the four string fields. Kept because it is the shape a caller must handle, # and because a decoder that invented a city here would pass every case above. check_out geoip/lookup-city-na \ "US, N/A, N/A, N/A, N/A, 37.750999, -97.821999, 0, 0" \ geoiplookup -f "$share/GeoLiteCity.dat" 8.8.8.8 check_out geoip/lookup-v6 "GeoIP Country V6 Edition: US, United States" \ geoiplookup6 -f "$share/GeoIPv6.dat" 2001:4860:4860::8888 # ------------------------------------------------- upstream's own test suite --- # THE GATE. ptest-runner is the harness the ticket closes on. -t is set well past # ptest-runner's own 300 s DEFAULT_TIMEOUT because `benchmark` alone is 3.6 s # native and this arm is far slower; it does not bound anything here anyway # (relative timers do not fire, brintos/linux#48), so a tight value would be an # assertion about nothing. GEOIP_PROGS="test-geoip test-geoip-invalid-file benchmark test-geoip-city" if [ ! -x /usr/bin/ptest-runner ]; then bst_notok geoip/ptest-suite "no ptest-runner on the image -- the suite cannot be run" for c in $GEOIP_PROGS; do bst_notok "geoip/case-$c" "suite not run: no ptest-runner" done else out=$(/usr/bin/ptest-runner -t 20000 geoip 2>&1) # Per-program verdicts. `case` is a builtin, so all four comparisons together # cost no forks. run-ptest prints the program with its ./ prefix. for c in $GEOIP_PROGS; do case "$out" in *"PASS: ./$c"*) bst_ok "geoip/case-$c" ;; *"FAIL: ./$c"*) bst_notok "geoip/case-$c" "upstream program failed on target; the native x86_64 control passes it" ;; *) bst_notok "geoip/case-$c" "program not reported at all -- run-ptest did not reach it" ;; esac done # ptest-runner's own framing: one ptest, zero failures. Checked in addition to # the loop because the two fail differently — a program renamed or dropped from # run-ptest shows up above, a harness that never ran shows up here. case "$out" in *"TOTAL: 1 FAIL: 0"*) bst_ok geoip/ptest-suite ;; *) bst_notok geoip/ptest-suite "ptest-runner did not report TOTAL: 1 FAIL: 0" ;; esac fi