Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wp-now: Update Playground and PHP WASM dependencies #350

Merged
merged 25 commits into from
Oct 17, 2024

Conversation

eliot-akira
Copy link
Contributor

@eliot-akira eliot-akira commented Aug 27, 2024

What?

This pull request is a continuation of #345 to update Playground dependencies from 0.6.16 to 1.0.2 and adapt existing code to work with breaking changes.

Resolves #319.

Why?

To keep up with upstream changes and benefit from new features and bug fixes.

How?

Update to new interface for PHP runtime instances, requests, and file system mount.

Based on similar logic in @wp-playground/wordpress (bootWordpress) and cli.

Further changes were necessary to pass all existing tests.

Testing Instructions

  • npx nx test wp-now

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Sep 2, 2024

Currently there are 3 failing tests, as seen in the CI logs.

They're about running PHP as CLI, and about WP-CLI.

 ❯ src/tests/wp-now.spec.ts  (46 tests | 3 failed | 1 skipped) 70720ms
   ❯ src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file
     → expected '' to match /8\.0/i
   ❯ src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file and change php version
     → expected '' to match /7\.4/i
   ❯ src/tests/wp-now.spec.ts > wp-cli command > wp-cli displays the version
     → Program terminated with exit(1)

There are also WASM errors associated with the PHP CLI tests, both:

RuntimeError: null function or function signature mismatch

That could be related to a similar error described in:


I'll copy the WASM error stack traces below for reference. They're slightly different, so might have different causes.

stderr | src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file

RuntimeError: null function or function signature mismatch
    at php_auto_globals_create_get (wasm://wasm/php.wasm-0380e0be:1:6470748)
    at php_hash_environment (wasm://wasm/php.wasm-0380e0be:1:6417625)
    at dynCall_i (wasm://wasm/php.wasm-0380e0be:1:7251146)
    at ret.<computed> (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29057:22)
    at t.wasmExports.<computed> (file://~/playground-tools/node_modules/@php-wasm/universal/index.js:522:18)
    at invoke_i (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29675:14)
    at php_request_startup (wasm://wasm/php.wasm-0380e0be:1:2685484)
    at dynCall_i (wasm://wasm/php.wasm-0380e0be:1:7251146)
    at ret.<computed> (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29057:22)
    at t.wasmExports.<computed> (file://~/playground-tools/node_modules/@php-wasm/universal/index.js:522:18)
    at invoke_i (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29675:14)
    at do_cli (wasm://wasm/php.wasm-0380e0be:1:7284591)
    at dynCall_iii (wasm://wasm/php.wasm-0380e0be:1:7250788)
    at ret.<computed> (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29057:22)
    at t.wasmExports.<computed> (file://~/playground-tools/node_modules/@php-wasm/universal/index.js:522:18)
    at invoke_iii (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29598:14) {
  cause: Error: 
      at Object.Asyncify.handleSleep (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29857:45)
      at _wasm_poll_socket (file://~/playground-tools/node_modules/@php-wasm/node/index.js:28922:21)
      at php_pollfd_for (wasm://wasm/php.wasm-0380e0be:1:633716)
      at php_network_connect_socket (wasm://wasm/php.wasm-0380e0be:1:3934833)
      at php_tcp_sockop_set_option (wasm://wasm/php.wasm-0380e0be:1:6332023)
      at php_openssl_sockop_set_option (wasm://wasm/php.wasm-0380e0be:1:6373167)
      at _php_stream_set_option (wasm://wasm/php.wasm-0380e0be:1:252064)
      at dynCall_iiiii (wasm://wasm/php.wasm-0380e0be:1:7250364)
      at ret.<computed> (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29057:22)
      at t.wasmExports.<computed> (file://~/playground-tools/node_modules/@php-wasm/universal/index.js:522:18)
      at invoke_iiiii (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29609:14)
      at _php_stream_xport_create (wasm://wasm/php.wasm-0380e0be:1:1105389)
      at zif_stream_socket_client (wasm://wasm/php.wasm-0380e0be:1:5252366)
      at ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER (wasm://wasm/php.wasm-0380e0be:1:7683052)
      at execute_ex (wasm://wasm/php.wasm-0380e0be:1:7135045)
      at zend_execute (wasm://wasm/php.wasm-0380e0be:1:2359117)
}

stderr | src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file and change php version

RuntimeError: null function or function signature mismatch
    at php_auto_globals_create_get (wasm://wasm/php.wasm-039ec376:1:6739627)
    at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8576690)
    at php_hash_environment (wasm://wasm/php.wasm-039ec376:1:6669088)
    at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8452698)
    at dynCall_i (wasm://wasm/php.wasm-039ec376:1:7679921)
    at ret.<computed> (file://~/playground-tools/node_modules/@php-wasm/node/index.js:36486:22)
    at t.wasmExports.<computed> (file://~/playground-tools/node_modules/@php-wasm/universal/index.js:522:18)
    at invoke_i (file://~/playground-tools/node_modules/@php-wasm/node/index.js:37035:14)
    at php_request_startup (wasm://wasm/php.wasm-039ec376:1:2843395)
    at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8448590)
    at dynCall_i (wasm://wasm/php.wasm-039ec376:1:7679921)
    at ret.<computed> (file://~/playground-tools/node_modules/@php-wasm/node/index.js:36486:22)
    at t.wasmExports.<computed> (file://~/playground-tools/node_modules/@php-wasm/universal/index.js:522:18)
    at invoke_i (file://~/playground-tools/node_modules/@php-wasm/node/index.js:37035:14)
    at do_cli (wasm://wasm/php.wasm-039ec376:1:7715417)
    at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8448901) {
  cause: Error: 
      at Object.Asyncify.handleSleep (file://~/playground-tools/node_modules/@php-wasm/node/index.js:37272:45)
      at _wasm_poll_socket (file://~/playground-tools/node_modules/@php-wasm/node/index.js:36351:21)
      at php_pollfd_for (wasm://wasm/php.wasm-039ec376:1:622857)
      at php_network_connect_socket (wasm://wasm/php.wasm-039ec376:1:4156375)
      at php_tcp_sockop_set_option (wasm://wasm/php.wasm-039ec376:1:6572034)
      at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8570026)
      at php_openssl_sockop_set_option (wasm://wasm/php.wasm-039ec376:1:6613667)
      at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8538339)
      at _php_stream_set_option (wasm://wasm/php.wasm-039ec376:1:264442)
      at _php_stream_xport_create (wasm://wasm/php.wasm-039ec376:1:1195532)
      at zif_stream_socket_client (wasm://wasm/php.wasm-039ec376:1:5474793)
      at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8561025)
      at ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER (wasm://wasm/php.wasm-039ec376:1:8131754)
      at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8581554)
      at execute_ex (wasm://wasm/php.wasm-039ec376:1:7554683)
      at null.<anonymous> (wasm://wasm/php.wasm-039ec376:1:8591528)
}

I checked the called php_ functions to ensure they're listed in the ASYNCIFY_IMPORTS in the Dockerfile for compiling PHP to WASM. They all seem to be there, but I might have missed something.


I saw that a similar update of Playground and PHP-WASM dependencies happened in:

The project includes a vendored and patched wp-now. Looks like they had to implement a tricky workaround to make WP-CLI work, but I'm hoping that won't be necessary to copy over; otherwise that would probably be better as a separate PR for the Playground repo, as a prerequisite for this one.

One difference I noticed is setting up TLS root certificates.

I'll try that and some other relevant changes, and see if it helps with passing the remaining tests.

@adamziel
Copy link
Collaborator

adamziel commented Sep 6, 2024

@sejas poke for the reviews! :-)

@adamziel
Copy link
Collaborator

adamziel commented Sep 6, 2024

As for the unreachable errors, it might require a PR similar to WordPress/wordpress-playground#1716 that adds all the C functions from the stack trace to the Dockerfile. See https://wordpress.github.io/wordpress-playground/developers/architecture/wasm-asyncify/#asyncify-crashes

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Sep 7, 2024

OK, down to 2 failing tests, both about PHP CLI and WASM errors.

it might require a PR that..adds all the C functions from the stack trace to the Dockerfile.

I need help with solving the WASM part - as far as I can see, all the C functions are already listed in ASYNCIFY_IMPORTS in the Dockerfile of @php-wasm/compile here. I'll go through them again to make sure I didn't miss anything.


For the WP-CLI test that was failing before, I ported the changes in executeWpCli from the fork of wp-now in Automattic/studio:

It includes a somewhat gnarly workaround to make WP-CLI work. Some of this might be suitable to move upstream as shared logic in @wp-playground/wordpress or cli.

One part I had to comment out, about SQLite command. Maybe this could be left for another PR to more fully develop the WP-CLI integration, which is (I think) not yet part of the public interface of wp-now.

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Sep 7, 2024

Here are the functions listed in the WASM error stacks (below). I combined and sorted them alphabetically, then checked each against the Dockerfile in @php-wasm/compile/php.

  • _php_stream_set_option
  • _php_stream_xport_create
  • _wasm_poll_socket
  • dynCall_iiiii
  • execute_ex
  • php_network_connect_socket
  • php_openssl_sockop_set_option
  • php_pollfd_for
  • php_tcp_sockop_set_option
  • zend_execute
  • zif_stream_socket_client

The missing one is _wasm_poll_socket. Looks like it may belong with the other _wasm_* functions in the Dockerfile as part of EXPORTED_FUNCTIONS instead of ASYNCIFY_IMPORT.

I can create a PR for this - but it might be better to try locally first, and see if it actually solves the issue. I guess in my local playground repo I'll recompile PHP-WASM with the change, then link the NPM package(s) to playground-tools and see if the tests pass.

There's an ongoing PR that updates the same Dockerfile, adds a number of C functions to the Asyncify list, and recompiles all versions of PHP WASM.

This could be the quickest solution to ask if they can add _wasm_poll_socket to EXPORTED_FUNCTIONS as part of their work.


...
cause: Error:
at Object.Asyncify.handleSleep (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29857:45)
at _wasm_poll_socket (file://~/playground-tools/node_modules/@php-wasm/node/index.js:28922:21)
at php_pollfd_for (wasm://wasm/php.wasm-0381a85e:1:634630)
at php_network_connect_socket (wasm://wasm/php.wasm-0381a85e:1:3939767)
at php_tcp_sockop_set_option (wasm://wasm/php.wasm-0381a85e:1:6339293)
at php_openssl_sockop_set_option (wasm://wasm/php.wasm-0381a85e:1:6381905)
at _php_stream_set_option (wasm://wasm/php.wasm-0381a85e:1:252625)
at dynCall_iiiii (wasm://wasm/php.wasm-0381a85e:1:7262168)
at ret.<computed> (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29057:22)
at t.wasmExports.<computed> (file://~/playground-tools/node_modules/@php-wasm/universal/index.js:522:18)
at invoke_iiiii (file://~/playground-tools/node_modules/@php-wasm/node/index.js:29609:14)
at _php_stream_xport_create (wasm://wasm/php.wasm-0381a85e:1:1106649)
at zif_stream_socket_client (wasm://wasm/php.wasm-0381a85e:1:5257722)
at ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER (wasm://wasm/php.wasm-0381a85e:1:7695829)
at execute_ex (wasm://wasm/php.wasm-0381a85e:1:7146849)
at zend_execute (wasm://wasm/php.wasm-0381a85e:1:2361792)

...
cause: Error:
at Object.Asyncify.handleSleep (file://~/playground-tools/node_modules/@php-wasm/node/index.js:37272:45)
at _wasm_poll_socket (file://~/playground-tools/node_modules/@php-wasm/node/index.js:36351:21)
at php_pollfd_for (wasm://wasm/php.wasm-039fea6e:1:623826)
at php_network_connect_socket (wasm://wasm/php.wasm-039fea6e:1:4162312)
at php_tcp_sockop_set_option (wasm://wasm/php.wasm-039fea6e:1:6583506)
at null.<anonymous> (wasm://wasm/php.wasm-039fea6e:1:8588223)
at php_openssl_sockop_set_option (wasm://wasm/php.wasm-039fea6e:1:6626546)
at null.<anonymous> (wasm://wasm/php.wasm-039fea6e:1:8556536)
at _php_stream_set_option (wasm://wasm/php.wasm-039fea6e:1:265054)
at _php_stream_xport_create (wasm://wasm/php.wasm-039fea6e:1:1196959)
at zif_stream_socket_client (wasm://wasm/php.wasm-039fea6e:1:5481212)
at null.<anonymous> (wasm://wasm/php.wasm-039fea6e:1:8579222)
at ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER (wasm://wasm/php.wasm-039fea6e:1:8148852)
at null.<anonymous> (wasm://wasm/php.wasm-039fea6e:1:8600108)
at execute_ex (wasm://wasm/php.wasm-039fea6e:1:7570728)
at null.<anonymous> (wasm://wasm/php.wasm-039fea6e:1:8610440)

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Sep 11, 2024

Next steps to complete this PR:

  • In my local playground repo, add _wasm_poll_socket to the Dockerfile as part of EXPORTED_FUNCTIONS. Recompile PHP-WASM with the change. This takes a while.
    npm run recompile:php:node
    • Building all packages with npm run build fails:
      NX   Error: write EPIPE
      [NX Daemon Server] - Server stopped because: "Stopping the daemon the set of ignored files changed (native)"
      
      ✅ Solved by removing the cache folder:
      rm -rf node_modules/.cache
      npm run build
    • The task php-wasm-node:build:package-json fails for several PHP versions.
      ✘ [ERROR] Could not resolve "../../public/php_8_3.js"
      
          packages/php-wasm/node/src/lib/get-php-loader-module.ts:10:23:
            10 │       return await import(`../../public/php_8_3.js`);
               ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~
      
      ✅ Solved by compiling each version:
      for f in 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3; do
        npm run recompile:php:node:$f
      done
  • Link Copy built NPM package(s) to playground-tools/node_modules.
    • npm link doesn't work, it links to uncompiled source.
    • Manually creating symlinks to @php-wasm packages doesn't work. Modules importing each other lead to symlinks (created by npm or nx) within playground/node_modules with uncompiled source.
    • ✅ Just copy built packages from dist.
      cd playground-tools/node_modules/@php-wasm
      for f in *; do
        if [ -d "$f" ]; then
          echo "$f"
          rsync -r --delete ../../../playground/dist/packages/php-wasm/"$f"/ "$f"
        fi
      done
  • ❌ Confirm WASM errors are resolved and all tests pass.
    npx nx test wp-now
  • Create PR for the change in playground repo.
  • When that's merged (and maybe also wordpress-playground#1716), update PHP-WASM dependencies in this PR.

Even after adding _wasm_poll_socket to PHP-WASM, the same two tests are failing with the same WASM errors. ..Oh, I see there are several functions I missed in the error stack trace (from above cause: Error).

  • do_cli
  • dynCall_i
  • invoke_i
  • php_auto_globals_create_get
  • php_hash_environment
  • php_request_startup

I added these to ASYNCIFY_ONLY and recompiled PHP-WASM, but still getting the same WASM errors. I cleared Docker cache with docker builder prune and recompiled again, same result. I noticed playground#1716 was merged, but I'm getting the same result after pull and another recompile.

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Sep 11, 2024

By the way, I'm finding it helpful to use Bun to run functions during development, without having to build the project or run the test suite every time.

In a parent directory, a quick script to try things:

import path from 'node:path'
import getWpNowConfig, { WPNowMode } from './playground-tools/packages/wp-now/src/config'
import { executePHP } from './playground-tools/packages/wp-now/src/execute-php'
import { executeWPCli } from './playground-tools/packages/wp-now/src/execute-wp-cli'

const options = await getWpNowConfig({
  path: path.join(import.meta.dir, 'test'),
  port: 3000,
  reset: true,
})

console.log(
  await executeWPCli(['cli', 'version'])
)

await executePHP(['php', '--version'], options)

await executePHP(['php', `--help`], options)

await executePHP(['php', `-r`, `echo 'hi';`], {
  ...options,
  mode: WPNowMode.INDEX,
})

await executePHP(
  ['php', `-r`, `echo json_encode( scandir('${options.documentRoot}') );`],
  options,
)

This last CLI command throws a different error than in the tests. Maybe the stack trace contains a hint about how to solve it.

  WASM ERROR
  call_indirect to a null table entry (evaluating 'original(...args)') 

29056 |       for (let [x, original] of Object.entries(exports)) {
29057 |         if (typeof original == "function") {
29058 |           ret[x] = (...args) => {
29059 |             Asyncify.exportCallStack.push(x);
29060 |             try {
29061 |               return original(...args);
                             ^
RuntimeError: call_indirect to a null table entry (evaluating 'original(...args)')
      at php.wasm.wasm-function[php_auto_globals_create_get]
      at php.wasm.wasm-function[php_hash_environment]
      at php.wasm.wasm-function[dynCall_i]
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:29061:22
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:556:18
      at invoke_i (~/playground-tools/node_modules/@php-wasm/node/index.js:29679:14)
      at php.wasm.wasm-function[php_request_startup]
      at php.wasm.wasm-function[dynCall_i]
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:29061:22
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:556:18
      at invoke_i (~/playground-tools/node_modules/@php-wasm/node/index.js:29679:14)
      at php.wasm.wasm-function[do_cli]
      at php.wasm.wasm-function[dynCall_iii]
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:29061:22
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:556:18
      at invoke_iii (~/playground-tools/node_modules/@php-wasm/node/index.js:29602:14)
      at php.wasm.wasm-function[run_cli]
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:29061:22
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:556:18
      at ccall (~/playground-tools/node_modules/@php-wasm/node/index.js:29256:15)
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:1229:47
      at cli (~/playground-tools/node_modules/@php-wasm/universal/index.js:1220:13)
      at ~/playground-tools/packages/wp-now/src/execute-php.ts:40:13

29856 |   PHPLoader.debug = "debug" in PHPLoader ? PHPLoader.debug : true;
29857 |   if (PHPLoader.debug && typeof Asyncify !== "undefined") {
29858 |     const originalHandleSleep = Asyncify.handleSleep;
29859 |     Asyncify.handleSleep = function(startAsync) {
29860 |       if (!ABORT) {
29861 |         Module["lastAsyncifyStackSource"] = new Error();
                                                    ^
error: Error
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:29861:45
      at php.wasm.wasm-function[php_pollfd_for] (native:1:1)
      at php.wasm.wasm-function[php_network_connect_socket] (native:1:1)
      at php.wasm.wasm-function[php_tcp_sockop_set_option] (native:1:1)
      at php.wasm.wasm-function[php_openssl_sockop_set_option] (native:1:1)
      at php.wasm.wasm-function[_php_stream_set_option] (native:1:1)
      at php.wasm.wasm-function[dynCall_iiiii] (native:1:1)
      at 13211 (native:1:1)
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:33821:11
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:19:6
      at invoke_iiiii (~/playground-tools/node_modules/@php-wasm/node/index.js:34416:13)
      at php.wasm.wasm-function[_php_stream_xport_create] (native:1:1)
      at php.wasm.wasm-function[zif_stream_socket_client] (native:1:1)
      at php.wasm.wasm-function[ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER] (native:1:1)
      at php.wasm.wasm-function[execute_ex] (native:1:1)
      at php.wasm.wasm-function[zend_execute] (native:1:1)
      at php.wasm.wasm-function[zend_execute_scripts] (native:1:1)
      at php.wasm.wasm-function[dynCall_iiiii] (native:1:1)
      at 13211 (native:1:1)
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:33821:11
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:19:6
      at invoke_iiiii (~/playground-tools/node_modules/@php-wasm/node/index.js:34416:13)
      at php.wasm.wasm-function[php_execute_script] (native:1:1)
      at php.wasm.wasm-function[dynCall_ii] (native:1:1)
      at 13214 (native:1:1)
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:33821:11
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:19:6
      at invoke_ii (~/playground-tools/node_modules/@php-wasm/node/index.js:34428:13)
      at php.wasm.wasm-function[wasm_sapi_handle_request] (native:1:1)
      at 9847 (native:1:1)
      at ~/playground-tools/node_modules/@php-wasm/node/index.js:33821:11
      at ~/playground-tools/node_modules/@php-wasm/universal/index.js:19:6

Here's the complete list of wasm-functions from above, checked against the Dockerfile for PHP-WASM.

  • _php_stream_set_option
  • _php_stream_xport_create
  • _wasm_poll_socket
  • do_cli
  • dynCall_i
  • dynCall_ii
  • dynCall_iii
  • dynCall_iiiii
  • execute_ex
  • invoke_i
  • invoke_iii
  • invoke_iiiii
  • php_auto_globals_create_get
  • php_hash_environment
  • php_request_startup
  • php_execute_script
  • php_network_connect_socket
  • php_openssl_sockop_set_option
  • php_pollfd_for
  • php_tcp_sockop_set_option
  • run_cli
  • wasm_sapi_handle_request
  • ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER
  • zend_execute
  • zend_execute_scripts
  • zif_stream_socket_client

In my fork of playground, I added:

  • _wasm_poll_socket to EXPORTED_FUNCTIONS
  • missing php_* functions to ASYNCIFY_ONLY (not ASYNCIFY_IMPORTS which is a much shorter list)

For some reason that doesn't solve it.

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Sep 11, 2024

All tests pass when PHP CLI is run in "index" mode.

Other modes (playground, plugin, theme, wordpress) fail with WASM error. That makes me think, maybe the issue is not with missing functions but in the way the PHP instance is set up before calling the CLI.

Copy link
Collaborator

@sejas sejas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eliot-akira, excellent work! Huge kudos for your perseverance and dedication in troubleshooting all the errors. I truly admire your effort.

After implementing the changes to the WP-CLI test, I can confirm that all tests pass when running the command npx nx test wp-now.

Changes

packages/wp-now/src/tests/wp-now.spec.ts

...

/**
 * Test wp-cli command.
 */
describe('wp-cli command', () => {
	beforeAll(async () => {
		await downloadWithTimer('wp-cli', downloadWPCLI);
	});

	afterAll(() => {
		fs.removeSync(getWpCliTmpPath());
	});

	/**
	 * Test wp-cli displays the version.
	 * We don't need the WordPress context for this test.
	 */
	test('wp-cli displays the version', async () => {
		const { stdout } = await executeWPCli([ '--version' ], {projectPath: '.'});
		expect(stdout).toMatch(/WP-CLI (\d\.?)+/i);
	});
});

Tests

❯ npx nx test wp-now

> nx run wp-now:test

 RUN  v0.31.1 /Users/macbookpro/Documents/projects-m3.nosync/playground-tools/packages/wp-now
 ✓ src/tests/add-trailing-slash.spec.ts  (3 tests) 4ms
 ✓ src/wp-playground-wordpress/tests/is-valid-wordpress-version.test.ts  (1 test) 2ms
 ✓ src/wp-playground-wordpress/tests/get-plugin-file.spec.ts  (3 tests) 2ms
 ✓ src/tests/github-codespaces.spec.ts  (2 tests) 2ms
 ✓ src/tests/execute-php.spec.ts  (4 tests) 222ms
stdout | unknown test
Downloading wordpress...
Downloading sqlite...
stdout | unknown test
sqlite downloaded.
sqlite: 891.667ms
stdout | unknown test
wordpress downloaded.
wordpress: 3.856s
 ✓ src/tests/wp-now.spec.ts  (46 tests | 1 skipped) 54354ms
 Test Files  6 passed (6)
      Tests  58 passed | 1 skipped (59)
   Start at  10:55:11
   Duration  54.86s (transform 116ms, setup 0ms, collect 586ms, tests 54.59s, environment 834ms, prepare 185ms)

 ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target test for project wp-now (55s)

I also tested wp-now common functionality and I could run a WordPress site and create a new post by running: npx nx build wp-now && node dist/packages/wp-now/cli.js start

I left a few comments, and I think we are close to merge it.

I couldn't reproduce the WASM errors you mentioned. Can you share some testing steps to reproduce them?

packages/wp-now/src/tests/wp-now.spec.ts Outdated Show resolved Hide resolved
packages/wp-now/src/execute-wp-cli.ts Show resolved Hide resolved
packages/wp-now/src/execute-wp-cli.ts Outdated Show resolved Hide resolved
packages/wp-now/src/wp-now.ts Outdated Show resolved Hide resolved
packages/wp-now/src/tests/wp-now.spec.ts Outdated Show resolved Hide resolved
packages/wp-now/src/execute-wp-cli.ts Outdated Show resolved Hide resolved
@eliot-akira
Copy link
Contributor Author

eliot-akira commented Sep 12, 2024

OK, I applied the suggested changes. Thank you for the review. I ported some useful changes from the Studio fork of wp-now, including support for rewrite rules and file not found action; and improvements to php.ini setup and rotate runtime instances with shared init steps.

Getting closer.. All tests passing, except:

I couldn't reproduce the WASM errors you mentioned.

I temporarily "solved" it by forcing PHP CLI to run in index mode. But any other mode throws.

I'll remove that patch so the CI shows the errors again. I'm not sure how to solve this one, as far as I could tell, adding functions to PHP-WASM and recompiling didn't eliminate the error.

@sejas
Copy link
Collaborator

sejas commented Sep 12, 2024

Thanks for the quick updates! 🙏
I'll check the errors to find a solution. I'll keep you updated.

@adamziel
Copy link
Collaborator

Poke @sejas :)

@eliot-akira
Copy link
Contributor Author

I updated Playground dependencies to the newest version 1.0.2.

The WASM error stack trace looks the same as before. I'll try again to solve it, apparently it happens with any wp-now mode other than index.

stderr | src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file
RuntimeError: null function or function signature mismatch
    at php_auto_globals_create_get (wasm://wasm/php.wasm-0372e072:1:6312604)
    ...

stderr | src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file and change php version
RuntimeError: null function or function signature mismatch
    at php_auto_globals_create_get (wasm://wasm/php.wasm-0390d672:1:6582750)
    ...

Strangely, the CI step typecheck is failing for an unrelated file.

image

On my local machine it's passing.

image

@sejas
Copy link
Collaborator

sejas commented Oct 16, 2024

@eliot-akira , thanks for upgrading to 1.0.2.

I tested it in my laptop. I'm getting the same errors you mentioned, and one more error about compressing (Test starting different modes > startServer > startServer compresses the html file). I need to debug it a bit more.

Currently these are the errors I get when running the wp-now tests npx nx test wp-now:

Full error trace

❯ npx nx test wp-now                             

nx run wp-now:test

RUN v0.31.1 /Users/macbookpro/Documents/projects-m3.nosync/playground-tools/packages/wp-now
✓ src/wp-playground-wordpress/tests/is-valid-wordpress-version.test.ts (1 test) 6ms
✓ src/tests/add-trailing-slash.spec.ts (3 tests) 4ms
✓ src/wp-playground-wordpress/tests/get-plugin-file.spec.ts (3 tests) 3ms
✓ src/tests/github-codespaces.spec.ts (2 tests) 3ms
✓ src/tests/execute-php.spec.ts (4 tests) 441ms
stdout | unknown test
Downloading wordpress...
Downloading sqlite...
stdout | unknown test
sqlite downloaded.
sqlite: 1.056s
stdout | unknown test
wordpress downloaded.
wordpress: 5.044s
stderr | src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file
RuntimeError: null function or function signature mismatch
at php_auto_globals_create_get (wasm://wasm/php.wasm-0372e072:1:6312604)
at php_hash_environment (wasm://wasm/php.wasm-0372e072:1:6259481)
at dynCall_i (wasm://wasm/php.wasm-0372e072:1:7084092)
at ret. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:92342:22)
at t.wasmExports. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/universal/index.js:556:18)
at invoke_i (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:92961:14)
at php_request_startup (wasm://wasm/php.wasm-0372e072:1:2610200)
at dynCall_i (wasm://wasm/php.wasm-0372e072:1:7084092)
at ret. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:92342:22)
at t.wasmExports. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/universal/index.js:556:18)
at invoke_i (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:92961:14)
at do_cli (wasm://wasm/php.wasm-0372e072:1:7116695)
at dynCall_iii (wasm://wasm/php.wasm-0372e072:1:7083734)
at ret. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:92342:22)
at t.wasmExports. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/universal/index.js:556:18)
at invoke_iii (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:92884:14)
stderr | src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file and change php version
RuntimeError: null function or function signature mismatch
at php_auto_globals_create_get (wasm://wasm/php.wasm-0390d672:1:6582750)
at null. (wasm://wasm/php.wasm-0390d672:1:8400512)
at php_hash_environment (wasm://wasm/php.wasm-0390d672:1:6512206)
at null. (wasm://wasm/php.wasm-0390d672:1:8277676)
at dynCall_i (wasm://wasm/php.wasm-0390d672:1:7514405)
at ret. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:99769:22)
at t.wasmExports. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/universal/index.js:556:18)
at invoke_i (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:100319:14)
at php_request_startup (wasm://wasm/php.wasm-0390d672:1:2766633)
at null. (wasm://wasm/php.wasm-0390d672:1:8273290)
at dynCall_i (wasm://wasm/php.wasm-0390d672:1:7514405)
at ret. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:99769:22)
at t.wasmExports. (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/universal/index.js:556:18)
at invoke_i (file:///Users/macbookpro/Documents/projects-m3.nosync/playground-tools/node_modules/@php-wasm/node/index.js:100319:14)
at do_cli (wasm://wasm/php.wasm-0390d672:1:7549060)
at null. (wasm://wasm/php.wasm-0390d672:1:8273601)
❯ src/tests/wp-now.spec.ts (46 tests | 3 failed | 1 skipped) 80778ms
❯ src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file
→ expected '' to match /8.0/i
❯ src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file and change php version
→ expected '' to match /7.4/i
❯ src/tests/wp-now.spec.ts > Test starting different modes > startServer > startServer compresses the html file
→ expected null to be 'gzip' // Object.is equality
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯
FAIL src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file
AssertionError: expected '' to match /8.0/i
❯ src/tests/wp-now.spec.ts:664:19
662| process.argv = ['node', 'wp-now', 'php', filePath];
663| await runCli();
664| expect(output).toMatch(/8.0/i);
| ^
665| expect(processExitMock).toHaveBeenCalledWith(0);
666| });
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯
FAIL src/tests/wp-now.spec.ts > Test starting different modes > validate php comand arguments passed through yargs > php should execute a file and change php version
AssertionError: expected '' to match /7.4/i
❯ src/tests/wp-now.spec.ts:679:19
677| ];
678| await runCli();
679| expect(output).toMatch(/7.4/i);
| ^
680| expect(processExitMock).toHaveBeenCalledWith(0);
681| });
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯
FAIL src/tests/wp-now.spec.ts > Test starting different modes > startServer > startServer compresses the html file
AssertionError: expected null to be 'gzip' // Object.is equality
❯ src/tests/wp-now.spec.ts:718:48
716| ])('startServer compresses the %s file', async (_, file) => {
717| const req = await fetch(${options.absoluteUrl}${file});
718| expect(req.headers.get('content-encoding')).toBe('gzip');
| ^
719| });
720|

  • Expected - 0
  • Received + 1
  • 'gzip'
  • null
    ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯
    Test Files 1 failed | 5 passed (6)
    Tests 3 failed | 55 passed | 1 skipped (59)
    Start at 17:04:02
    Duration 81.61s (transform 152ms, setup 0ms, collect 1.01s, tests 81.23s, environment 1.68s, prepare 263ms)

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

NX Ran target test for project wp-now (1m)

✖    1/1 failed
✔    0/1 succeeded [0 read from cache]

Screenshot 2024-10-16 at 17 06 01

What is weird is that in CI it seems to (fail)(https://github.com/WordPress/playground-tools/actions/runs/11314731564/job/31465056405?pr=350) onwordpress-playground-block:typecheck. And in my laptop the typcheck passes correctly.

> nx run wordpress-playground-block:typecheck

Error: packages/wordpress-playground-block/src/components/playground-preview/download-zipped-package.ts(9,2): error TS7006: Parameter 'codeEditorMode' implicitly has an 'any' type.
Warning: run-commands command "tsc -p packages/wordpress-playground-block/tsconfig.lib.json --noEmit" exited with non-zero status code

While in my local machine, those typecheck pass:

Screenshot 2024-10-16 at 17 13 10

@sejas
Copy link
Collaborator

sejas commented Oct 16, 2024

I've updated executePHP to work only on index mode. I think it's a good solution because users will probably use wp-now php on sites that already exist. Ideally in the future we could remove the modes and just setup the WordPress folders the first time the users starts a site. (2dbb1a5)

I also fixed the tests that were checking if express was compressing files before sending them in the request. (a73938c)

Let's see if the nx run wordpress-playground-block:typecheck pass this time 🤞

@sejas
Copy link
Collaborator

sejas commented Oct 17, 2024

It seems the CI rebases from trunk, that's why we didn't get the error in our local machines.
I fixed the typecheck here 1235519

Copy link
Collaborator

@sejas sejas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it in Playground, theme and plugin modes.
It works as expected. Great work @eliot-akira 🥳

❯ npx nx build wp-now && node dist/packages/wp-now/cli.js start

> nx run wp-now:"build:bundle"


> nx run wp-now:"build:package-json"


> nx run wp-now:build  [local cache]


 ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target build for project wp-now and 2 tasks it depends on (472ms)
 
   Nx read the output from the cache instead of running the command for 1 out of 3 tasks.
 
Starting the server......
directory: /Users/macbookpro/Documents/projects-m3.nosync/playground-tools
mode: playground
php: 8.0
wp: 6.6.2 (resolved from alias: latest)
WordPress 6.6.2 folder already exists. Skipping download.
SQLite folder already exists. Skipping download.
Server running at http://localhost:8881

@sejas sejas merged commit 3382daa into WordPress:trunk Oct 17, 2024
2 checks passed
@eliot-akira
Copy link
Contributor Author

eliot-akira commented Oct 17, 2024

Whew, that was a tough one. 😄 Thank you for seeing it through!

@sejas
Copy link
Collaborator

sejas commented Oct 17, 2024

Thank YOU @eliot-akira for working hard on it 🙏 .

I couldn't publish the release yet, I got some errors in the build process. I created a PR #359 but I think I also caught a bug in wordpress-playground repo.

adamziel pushed a commit that referenced this pull request Oct 25, 2024
<!-- Thanks for contributing to WordPress Playground Tools! -->

## What?

<!-- In a few words, what is the PR actually doing? Include screenshots
or screencasts if applicable -->

It updates the correct path of `jspi/PHP_*` to be included in the VS
Code extension after upgrading the Playground dependencies on
#350

## Why?

<!-- Why is this PR necessary? What problem is it solving? Reference any
existing previous issue(s) or PR(s), but please add a short summary
here, too -->

The paths to wasm files have changed in the new version.

## How?

<!-- How is your PR addressing the issue at hand? What are the
implementation details? -->

Updating the project bundle step.

## Testing Instructions

<!-- Please include step by step instructions on how to test this PR.
-->
<!-- 1. Check out the branch. -->
<!-- 2. Run a command. -->
<!-- 3. etc. -->

* Run `npx nx run vscode-extension:build:bundle`
* Observe the command finishes successfully : ` > NX Successfully ran
target build:bundle for project vscode-extension (501ms)`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

wp-now: update Blueprints library dependency
3 participants