- The PR-079 live router cases ran the HivePress rating sort on the whole site with an unqualified DECIMAL: native rounds 4.5 to 5 and orders its many ties by chance, so the id order passed or failed with the query plan. They now send DECIMAL(10,1), as the HivePress Rating field does, and compare each position's native sort key and found_posts; the flat-first / GROUP BY assertions stay. - Verify: live router 18/18 twice; all suites 56/56 - PR: PR-089b
Live test suite
Tests that must run inside a real WordPress site, because the stubbed
tests/integration bootstrap cannot reproduce:
- WP core meta flows (
update_metadata()reads the old value throughget_metadata_raw()before writing — the shadow_read write-loss bug lives there) - the SQL that
WP_Queryactually builds, and hook priorities - HivePress / WooCommerce behaviour (
pre_get_postssort clauses, empty-key meta reads, direct-SQL stock updates)
Never run against a production site. Suites create and delete fixtures
(tmdo_live_* users, tmdo-live-* terms). Entity modes are overridden in
process through pre_option_wpdo_bridge_modes; nothing is written to
wpdo_bridge_modes or wpdo_hook_bus_enabled.
The reference site is dev36 (HivePress + Marketplace + WooCommerce), with this
plugin symlinked from the plugins-dev worktree while developing.
Run
wp --path=/var/www/Studio/wp-local-dev36 eval-file tests/live/run.php <suite> [<suite> ...]
Exit code 0 when every test passed, 1 otherwise. Output per test:
| Status | Meaning |
|---|---|
| PASS / FAIL | normal |
| XFAIL | known bug, test marked xfail with the PR that fixes it; not counted as a failure |
| XPASS | an xfail test passed — counted as a failure so the fixing PR removes the marker |
| SKIP | the site does not register the key / taxonomy the test needs |
Suites
| Suite | Covers |
|---|---|
shadow_write |
writes in shadow_read reach native meta (user, term, HivePress listing) |
serialized |
array meta values are stored serialized in flat tables, never "Array" |
resync |
dual_write / shadow_read: flat follows native after every write (4 entities × 2 modes: update, same value, delete, refused writes, stale flat, key rename by meta_id) |
router |
a routed WP_Query returns the same ids, in order, as native (OR, several post types, untyped numeric compares, named orderby, LIKE, keys of two groups, NOT EXISTS with the status/date copy route, meta orderby: HivePress sort shape, named clause, meta_key + meta_value_num); routed SQL has no GROUP BY |
rest |
anonymous GET of the public listings endpoints returns no protected or credential-like field (1.1.1) |
drift |
TMDO_Drift_Check: json groups show no false diff; a planted flat mismatch / flat-only value counts exactly once (1.2.0) |
zero_side_effect |
zone tables that were never created are never queried on save / delete |
Tools (tools/)
Benchmark and data-flow helpers used for the 2026-09-26 dev36 integration test.
Output files go to the current directory (qbench) or $TMDO_LIVE_OUT
(default /tmp, run_batch.sh), never into the repo.
| Tool | Use |
|---|---|
seed.php |
wp eval-file seed.php <vendors|listings|requests|reviews|products|orders|terms> <n> [tag] — seed through real HivePress / WC APIs |
run_batch.sh |
run_batch.sh <tag> [divisor] — parallel seeding batch (TMDO_LIVE_WP_PATH, TMDO_LIVE_OUT) |
clone.sql |
bench only: clone hp_listing rows to reach large scale (sed "s/__K__/<n>/" clone.sql | wp db query) |
checker.php |
wp eval-file checker.php [entity] — native vs flat consistency per registered key (SQL only) |
qbench.php / qdiff.php |
run 16 WP_Query shapes, then diff two runs (native vs routed): result sets, order, latency, SQL errors |
mut.php |
data-flow mutations through HivePress models, WC CRUD and core APIs; prints native / flat / API values |
fe.sh + zz-s36-probe.php |
front-end search probe (TMDO_LIVE_URL). Copy the probe into wp-content/mu-plugins/ only for the run and remove it afterwards; it only answers requests carrying X-S36-Probe: 1 |