02045c6f07
- New TMDO_Drift_Check compares every backfillable group of post / user / term / comment with native meta by value (first native row → safe unserialize → Type_Caster::to_db): miss / diff / extra per key, set-based SQL with BINARY exact matches, PHP comparison only for the remaining candidates. Serialized-vs-JSON and 50 vs 50.000000 are no longer drift; over-long text stored as NULL is not a miss; extra covers rows of other post types. Outcome per group goes to the wpdo_drift_status option; nothing else is written. - `wp tmdo drift-check <entity> [--group] [--sample=<n>] [--format]`. A new class instead of extending the post-only shadow verifier, which queries row by row and writes shadow_diffs. - Verify: DriftCheckTest; live suite drift; dev36 post miss=533 diff=2 extra=1 in 23 s (checker's 45 json false diffs gone), user/term/comment 0. - PR: PR-070
78 lines
2.8 KiB
PHP
78 lines
2.8 KiB
PHP
<?php
|
|
/**
|
|
* Suite: TMDO_Drift_Check on a real site (2.2 PR-070).
|
|
*
|
|
* - json groups (attachment / nav_menu_item) compare by value: a serialized
|
|
* native array and its JSON flat copy are not drift.
|
|
* - a flat value planted behind the checker's back shows up as exactly one
|
|
* diff / one extra, nothing else moves.
|
|
*
|
|
* @package WP_Data_Optimizer
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Run the drift check for one group and put the site's recorded status back.
|
|
*
|
|
* @param string $entity Entity type.
|
|
* @param string $group Group.
|
|
* @return array<string, mixed> Report.
|
|
*/
|
|
function tmdo_live_drift( string $entity, string $group ): array {
|
|
$status = get_option( TMDO_Drift_Check::OPTION, null );
|
|
try {
|
|
return TMDO_Drift_Check::run( $entity, $group );
|
|
} finally {
|
|
null === $status ? delete_option( TMDO_Drift_Check::OPTION ) : update_option( TMDO_Drift_Check::OPTION, $status );
|
|
}
|
|
}
|
|
|
|
TMDO_Live::test(
|
|
'drift-check reports no diff for json groups whose values match native',
|
|
static function () {
|
|
$checked = 0;
|
|
foreach ( array( 'attachment', 'nav_menu_item' ) as $group ) {
|
|
if ( ! in_array( $group, TMDO_Entity_Migration_Engine::backfillable_groups( 'post' ), true )
|
|
|| ! TMDO_Schema_Manager::table_exists( TMDO_Schema_Manager::get_table_name( 'post', $group ) ) ) {
|
|
continue;
|
|
}
|
|
$report = tmdo_live_drift( 'post', $group );
|
|
tmdo_live_assert_same( 0, $report['total']['diff'], "post/{$group} diff" );
|
|
++$checked;
|
|
}
|
|
if ( 0 === $checked ) {
|
|
throw new TMDO_Live_Skip( 'no attachment / nav_menu_item flat table on this site' );
|
|
}
|
|
}
|
|
);
|
|
|
|
TMDO_Live::test(
|
|
'drift-check counts a planted flat mismatch once and a flat-only value once',
|
|
static function () {
|
|
global $wpdb;
|
|
TMDO_Live_Fixtures::use_modes( array( 'user' => 'disabled' ) );
|
|
$field = TMDO_Live_Fixtures::field( 'user', 'login_count' );
|
|
$group = $field['group'];
|
|
$table = TMDO_Schema_Manager::get_table_name( 'user', $group );
|
|
|
|
$before = tmdo_live_drift( 'user', $group )['groups'][ $group ]['keys']['login_count'];
|
|
|
|
$mismatch = TMDO_Live_Fixtures::user();
|
|
$flat_only = TMDO_Live_Fixtures::user();
|
|
add_user_meta( $mismatch, 'login_count', '5' );
|
|
try {
|
|
$wpdb->insert( $table, array( 'user_id' => $mismatch, 'login_count' => 6 ) );
|
|
$wpdb->insert( $table, array( 'user_id' => $flat_only, 'login_count' => 9 ) );
|
|
|
|
$after = tmdo_live_drift( 'user', $group )['groups'][ $group ]['keys']['login_count'];
|
|
} finally {
|
|
$wpdb->query( $wpdb->prepare( "DELETE FROM `{$table}` WHERE user_id IN (%d, %d)", $mismatch, $flat_only ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
|
}
|
|
|
|
tmdo_live_assert_same( $before['diff'] + 1, $after['diff'], 'login_count diff +1' );
|
|
tmdo_live_assert_same( $before['extra'] + 1, $after['extra'], 'login_count extra +1' );
|
|
tmdo_live_assert_same( $before['miss'], $after['miss'], 'login_count miss unchanged' );
|
|
}
|
|
);
|