Skip to content

Commit 71a250a

Browse files
committed
Require native parser in extension PHPUnit suites
1 parent 6978176 commit 71a250a

3 files changed

Lines changed: 128 additions & 6 deletions

File tree

.github/workflows/mysql-parser-extension-tests.yml

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ on:
55
paths:
66
- '.github/workflows/mysql-parser-extension-tests.yml'
77
- 'packages/mysql-on-sqlite/**'
8+
- 'packages/php-ext-wp-mysql-parser/**'
89
pull_request:
910
paths:
1011
- '.github/workflows/mysql-parser-extension-tests.yml'
1112
- 'packages/mysql-on-sqlite/**'
13+
- 'packages/php-ext-wp-mysql-parser/**'
1214
workflow_dispatch:
1315

1416
concurrency:
@@ -73,17 +75,25 @@ jobs:
7375
fwrite( STDERR, "Native lexer is not available.\n" );
7476
exit( 1 );
7577
}
76-
$tokens = $lexer->remaining_tokens();
77-
$parser = new WP_MySQL_Parser( new WP_Parser_Grammar( include "src/mysql/mysql-grammar.php" ), $tokens );
78+
$tokens = $lexer->native_token_stream();
79+
$rules = include "src/mysql/mysql-grammar.php";
80+
$grammar = new WP_Parser_Grammar( $rules );
81+
$parser = new WP_MySQL_Parser( $grammar, $tokens );
82+
if ( ! ( $parser instanceof WP_MySQL_Native_Parser ) ) {
83+
fwrite( STDERR, "Native parser is not available.\n" );
84+
exit( 1 );
85+
}
7886
$ast = $parser->parse();
79-
if ( ! $ast instanceof WP_Parser_Node || "query" !== $ast->rule_name ) {
87+
if ( ! $ast instanceof WP_MySQL_Native_Parser_Node || "query" !== $ast->rule_name ) {
8088
fwrite( STDERR, "Native parser did not produce the expected query AST.\n" );
8189
exit( 1 );
8290
}
8391
'
8492
working-directory: packages/mysql-on-sqlite
8593

86-
- name: Run PHPUnit tests with parser extension
94+
- name: Run full PHPUnit suite with parser extension
95+
env:
96+
WP_SQLITE_REQUIRE_NATIVE_PARSER_EXTENSION: '1'
8797
run: php -d extension="$GITHUB_WORKSPACE/packages/php-ext-wp-mysql-parser/target/debug/libwp_mysql_parser.so" ./vendor/bin/phpunit -c ./phpunit.xml.dist
8898
working-directory: packages/mysql-on-sqlite
8999

@@ -142,6 +152,10 @@ jobs:
142152
}
143153
$driver = new WP_PDO_MySQL_On_SQLite( "mysql-on-sqlite:path=:memory:;dbname=wp;" );
144154
$parser = $driver->create_parser( "SELECT 1" );
155+
if ( ! ( $parser instanceof WP_MySQL_Native_Parser ) ) {
156+
fwrite( STDERR, "SQLite driver did not create a native parser.\n" );
157+
exit( 1 );
158+
}
145159
$parser->next_query();
146160
$ast = $parser->get_query_ast();
147161
if ( ! ( $ast instanceof WP_MySQL_Native_Parser_Node ) ) {
@@ -171,6 +185,8 @@ jobs:
171185
}
172186
'
173187
174-
- name: Run PHPUnit tests with SQLite driver using parser extension
188+
- name: Run full PHPUnit suite with SQLite driver using parser extension
189+
env:
190+
WP_SQLITE_REQUIRE_NATIVE_PARSER_EXTENSION: '1'
175191
run: php -d extension="$GITHUB_WORKSPACE/packages/php-ext-wp-mysql-parser/target/debug/libwp_mysql_parser.so" ./vendor/bin/phpunit -c ./phpunit.xml.dist
176192
working-directory: packages/mysql-on-sqlite

.github/workflows/wp-tests-phpunit-native-extension-setup.sh

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,35 @@ add_volume_to_service cli "$EXTENSION_INI_VOLUME"
113113

114114
cat > "$WP_DIR/native-verify-extension.php" <<'EOF'
115115
<?php
116-
require '/var/www/src/wp-content/plugins/sqlite-database-integration/wp-includes/database/load.php';
116+
require_once '/var/www/src/wp-content/plugins/sqlite-database-integration/wp-includes/database/load.php';
117117
118118
$lexer = new WP_MySQL_Lexer( 'SELECT 1' );
119119
if ( ! ( $lexer instanceof WP_MySQL_Native_Lexer ) ) {
120120
fwrite( STDERR, "Native lexer is not available in the WordPress PHP test container.\n" );
121121
exit( 1 );
122122
}
123123
124+
$tokens = $lexer->native_token_stream();
125+
$rules = include '/var/www/src/wp-content/plugins/sqlite-database-integration/wp-includes/database/mysql/mysql-grammar.php';
126+
$grammar = new WP_Parser_Grammar( $rules );
127+
$parser = new WP_MySQL_Parser( $grammar, $tokens );
128+
if ( ! ( $parser instanceof WP_MySQL_Native_Parser ) ) {
129+
fwrite( STDERR, "WordPress PHP test container did not select the native parser.\n" );
130+
exit( 1 );
131+
}
132+
133+
$parser_ast = $parser->parse();
134+
if ( ! ( $parser_ast instanceof WP_MySQL_Native_Parser_Node ) ) {
135+
fwrite( STDERR, "Native parser did not produce a native-backed AST in the WordPress PHP test container.\n" );
136+
exit( 1 );
137+
}
138+
124139
$driver = new WP_PDO_MySQL_On_SQLite( 'mysql-on-sqlite:path=:memory:;dbname=wp;' );
125140
$parser = $driver->create_parser( 'SELECT 1' );
141+
if ( ! ( $parser instanceof WP_MySQL_Native_Parser ) ) {
142+
fwrite( STDERR, "WordPress PHP test container SQLite driver did not create a native parser.\n" );
143+
exit( 1 );
144+
}
126145
$parser->next_query();
127146
$ast = $parser->get_query_ast();
128147
@@ -157,5 +176,31 @@ if ( $same_first !== $first || ! in_array( $synthetic, $same_first->get_children
157176
}
158177
EOF
159178

179+
node - "$WP_DIR/tests/phpunit/includes/bootstrap.php" <<'NODE'
180+
const fs = require( 'fs' );
181+
182+
const file = process.argv[2];
183+
const marker = "require_once ABSPATH . 'wp-settings.php';";
184+
const guard = [
185+
'/*',
186+
' * Native parser CI guard. This file is generated by the SQLite integration workflow.',
187+
' */',
188+
"require_once dirname( __DIR__, 3 ) . '/native-verify-extension.php';",
189+
].join( '\n' );
190+
191+
let contents = fs.readFileSync( file, 'utf8' );
192+
193+
if ( contents.includes( guard ) ) {
194+
process.exit( 0 );
195+
}
196+
197+
if ( ! contents.includes( marker ) ) {
198+
throw new Error( `Unable to find WordPress bootstrap marker in ${ file }.` );
199+
}
200+
201+
contents = contents.replace( marker, `${ marker }\n\n${ guard }` );
202+
fs.writeFileSync( file, contents );
203+
NODE
204+
160205
node tools/local-env/scripts/docker.js run --rm php php -m | grep -qx 'wp_mysql_parser'
161206
node tools/local-env/scripts/docker.js run --rm php php /var/www/native-verify-extension.php

packages/mysql-on-sqlite/tests/bootstrap.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,67 @@
99
define( 'WP_SQLITE_UNSAFE_ENABLE_UNSUPPORTED_VERSIONS', true );
1010
}
1111

12+
if ( '1' === getenv( 'WP_SQLITE_REQUIRE_NATIVE_PARSER_EXTENSION' ) ) {
13+
if ( ! class_exists( 'WP_MySQL_Native_Lexer', false ) || ! class_exists( 'WP_MySQL_Native_Parser', false ) ) {
14+
fwrite( STDERR, "Native MySQL parser extension is required for this PHPUnit run.\n" );
15+
exit( 1 );
16+
}
17+
18+
$native_parser_lexer = new WP_MySQL_Lexer( 'SELECT 1' );
19+
if ( ! ( $native_parser_lexer instanceof WP_MySQL_Native_Lexer ) ) {
20+
fwrite( STDERR, "WP_MySQL_Lexer did not resolve to the native implementation.\n" );
21+
exit( 1 );
22+
}
23+
24+
$native_parser_tokens = $native_parser_lexer->native_token_stream();
25+
$native_parser_rules = include __DIR__ . '/../src/mysql/mysql-grammar.php';
26+
$native_parser_grammar = new WP_Parser_Grammar( $native_parser_rules );
27+
$native_parser = new WP_MySQL_Parser( $native_parser_grammar, $native_parser_tokens );
28+
if ( ! ( $native_parser instanceof WP_MySQL_Native_Parser ) ) {
29+
fwrite( STDERR, "WP_MySQL_Parser did not resolve to the native implementation.\n" );
30+
exit( 1 );
31+
}
32+
33+
$native_parser_ast = $native_parser->parse();
34+
if ( ! ( $native_parser_ast instanceof WP_MySQL_Native_Parser_Node ) ) {
35+
fwrite( STDERR, "Native parser did not produce a native-backed AST.\n" );
36+
exit( 1 );
37+
}
38+
39+
$native_parser_driver = new WP_PDO_MySQL_On_SQLite( 'mysql-on-sqlite:path=:memory:;dbname=wp;' );
40+
$native_parser_driver_parser = $native_parser_driver->create_parser( 'SELECT 1' );
41+
if ( ! ( $native_parser_driver_parser instanceof WP_MySQL_Native_Parser ) ) {
42+
fwrite( STDERR, "WP_PDO_MySQL_On_SQLite did not create a native parser.\n" );
43+
exit( 1 );
44+
}
45+
46+
$native_parser_driver_parser->next_query();
47+
$native_parser_driver_ast = $native_parser_driver_parser->get_query_ast();
48+
if ( ! ( $native_parser_driver_ast instanceof WP_MySQL_Native_Parser_Node ) ) {
49+
fwrite( STDERR, "WP_PDO_MySQL_On_SQLite did not produce a native-backed AST.\n" );
50+
exit( 1 );
51+
}
52+
53+
$native_parser_driver_child = $native_parser_driver_ast->get_first_child_node();
54+
if ( ! ( $native_parser_driver_child instanceof WP_MySQL_Native_Parser_Node ) ) {
55+
fwrite( STDERR, "WP_PDO_MySQL_On_SQLite did not produce native-backed child AST nodes.\n" );
56+
exit( 1 );
57+
}
58+
59+
unset(
60+
$native_parser_ast,
61+
$native_parser,
62+
$native_parser_grammar,
63+
$native_parser_rules,
64+
$native_parser_tokens,
65+
$native_parser_lexer,
66+
$native_parser_driver,
67+
$native_parser_driver_parser,
68+
$native_parser_driver_ast,
69+
$native_parser_driver_child
70+
);
71+
}
72+
1273
// Configure the test environment.
1374
error_reporting( E_ALL );
1475
define( 'FQDB', ':memory:' );

0 commit comments

Comments
 (0)