chore: initial snapshot of 2meet-data-optimizer v0.1.0
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Integration test: WPDO_Post_Migration::benchmark_query() (v2.10.2).
|
||||
*
|
||||
* Verifies the benchmark method produces sensible timing comparison
|
||||
* between wp_postmeta JOIN and flat-table JOIN for the same logical query.
|
||||
*
|
||||
* Tests focus on the API contract (input → output shape) since wall-clock
|
||||
* timing is non-deterministic. Real performance numbers come from running
|
||||
* `wp wpdo post-benchmark` on dev10 production data.
|
||||
*/
|
||||
class PostBenchmarkTest extends TestCase {
|
||||
|
||||
private const POSTS = 'wp_itest_posts';
|
||||
private const POSTMETA = 'wp_itest_postmeta';
|
||||
private const FLAT = 'wp_itest_wpdo_post_wc_product';
|
||||
|
||||
public static function setUpBeforeClass(): void {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! class_exists( 'WPDO_Schema_Manager' ) ) {
|
||||
require_once WPDO_PLUGIN_DIR . 'includes/engine/class-tmdo-schema-manager.php';
|
||||
}
|
||||
if ( ! class_exists( 'WPDO_Post_Migration' ) ) {
|
||||
require_once WPDO_PLUGIN_DIR . 'includes/migration/class-tmdo-post-migration.php';
|
||||
}
|
||||
|
||||
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::POSTS . '`' );
|
||||
$wpdb->query(
|
||||
'CREATE TABLE `' . self::POSTS . '` (
|
||||
ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
post_type varchar(20) NOT NULL DEFAULT \'post\',
|
||||
post_status varchar(20) NOT NULL DEFAULT \'publish\',
|
||||
PRIMARY KEY (ID),
|
||||
KEY post_type (post_type)
|
||||
) DEFAULT CHARACTER SET utf8mb4'
|
||||
);
|
||||
|
||||
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::POSTMETA . '`' );
|
||||
$wpdb->query(
|
||||
'CREATE TABLE `' . self::POSTMETA . '` (
|
||||
meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
post_id bigint(20) unsigned NOT NULL DEFAULT 0,
|
||||
meta_key varchar(255) DEFAULT NULL,
|
||||
meta_value longtext,
|
||||
PRIMARY KEY (meta_id),
|
||||
KEY post_id (post_id),
|
||||
KEY meta_key (meta_key(191))
|
||||
) DEFAULT CHARACTER SET utf8mb4'
|
||||
);
|
||||
|
||||
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::FLAT . '`' );
|
||||
$wpdb->query(
|
||||
'CREATE TABLE `' . self::FLAT . '` (
|
||||
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
post_id bigint(20) unsigned NOT NULL,
|
||||
_price decimal(18,6) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_post_id (post_id),
|
||||
KEY idx__price (_price)
|
||||
) DEFAULT CHARACTER SET utf8mb4'
|
||||
);
|
||||
|
||||
// Seed 50 products with _price = 10..59 in both tables.
|
||||
for ( $i = 1; $i <= 50; $i++ ) {
|
||||
$wpdb->insert( self::POSTS, array( 'ID' => $i, 'post_type' => 'product', 'post_status' => 'publish' ) );
|
||||
$price = (string) ( 10 + $i );
|
||||
$wpdb->insert( self::POSTMETA, array( 'post_id' => $i, 'meta_key' => '_price', 'meta_value' => $price ) );
|
||||
$wpdb->insert( self::FLAT, array( 'post_id' => $i, '_price' => $price ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void {
|
||||
global $wpdb;
|
||||
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::POSTS . '`' );
|
||||
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::POSTMETA . '`' );
|
||||
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::FLAT . '`' );
|
||||
}
|
||||
|
||||
// ── benchmark_query() ────────────────────────────────────────────────────
|
||||
|
||||
public function test_benchmark_returns_expected_shape(): void {
|
||||
$result = WPDO_Post_Migration::benchmark_query(
|
||||
'product',
|
||||
'_price',
|
||||
'>=',
|
||||
'30',
|
||||
self::FLAT,
|
||||
5
|
||||
);
|
||||
|
||||
$this->assertArrayHasKey( 'samples', $result );
|
||||
$this->assertArrayHasKey( 'postmeta_avg_ms', $result );
|
||||
$this->assertArrayHasKey( 'flat_avg_ms', $result );
|
||||
$this->assertArrayHasKey( 'speedup', $result );
|
||||
$this->assertArrayHasKey( 'postmeta_rows', $result );
|
||||
$this->assertArrayHasKey( 'flat_rows', $result );
|
||||
|
||||
$this->assertSame( 5, $result['samples'] );
|
||||
$this->assertGreaterThan( 0.0, $result['postmeta_avg_ms'] );
|
||||
$this->assertGreaterThan( 0.0, $result['flat_avg_ms'] );
|
||||
}
|
||||
|
||||
public function test_benchmark_finds_same_rows_via_both_paths(): void {
|
||||
// _price >= 30 should match products 20..50 (i.e. 31 rows).
|
||||
$result = WPDO_Post_Migration::benchmark_query(
|
||||
'product',
|
||||
'_price',
|
||||
'>=',
|
||||
'30',
|
||||
self::FLAT,
|
||||
3
|
||||
);
|
||||
|
||||
// Both paths must return the same count — verifies router correctness.
|
||||
$this->assertSame( $result['postmeta_rows'], $result['flat_rows'] );
|
||||
$this->assertGreaterThan( 0, $result['postmeta_rows'] );
|
||||
}
|
||||
|
||||
public function test_benchmark_speedup_is_positive_number(): void {
|
||||
$result = WPDO_Post_Migration::benchmark_query(
|
||||
'product',
|
||||
'_price',
|
||||
'=',
|
||||
'25',
|
||||
self::FLAT,
|
||||
3
|
||||
);
|
||||
|
||||
$this->assertIsFloat( $result['speedup'] );
|
||||
$this->assertGreaterThan( 0.0, $result['speedup'] );
|
||||
}
|
||||
|
||||
public function test_benchmark_rejects_zero_samples(): void {
|
||||
$this->expectException( InvalidArgumentException::class );
|
||||
WPDO_Post_Migration::benchmark_query( 'product', '_price', '=', '25', self::FLAT, 0 );
|
||||
}
|
||||
|
||||
public function test_benchmark_rejects_invalid_compare(): void {
|
||||
$this->expectException( InvalidArgumentException::class );
|
||||
WPDO_Post_Migration::benchmark_query( 'product', '_price', 'BOGUS', '25', self::FLAT, 3 );
|
||||
}
|
||||
|
||||
public function test_benchmark_throws_when_flat_table_missing(): void {
|
||||
$this->expectException( RuntimeException::class );
|
||||
WPDO_Post_Migration::benchmark_query(
|
||||
'product',
|
||||
'_price',
|
||||
'=',
|
||||
'25',
|
||||
'wp_itest_nonexistent_flat',
|
||||
3
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user