Skip to content

Asyncify: Test all network functions and all ways to trigger a function call #273

Closed as not planned
@adamziel

Description

@adamziel

Description

As explained in #251 and #253, all PHP code paths leading to an asynchronous network call must be listed in php-wasm/compile/Dockerfile. In the longer term, we'll move from Asyncify to JSPI API that has a much simpler configuration, but for now we'll need to maintain the ASYNCIFY_ONLY list.

Finding them manually would be tedious or impossible, so #253 introduced a test suite that detects and auto-adds any missing code paths. That test suite should cover the following two concepts as exhaustively as possible:

Network functions

PHP functions directly responsible for triggering a network call like file_get_contents, fsockopen, mysql_connect should be listed here:

const topOfTheStack: Array<string> = [
// http:// stream handler
`file_get_contents(${js['httpUrl']});`,
`$fp = fopen(${js['httpUrl']}, "r");
fread($fp, 1024);
fclose($fp);`,
// `getimgsize(${js['httpUrl']});`,
// Network functions from https://www.php.net/manual/en/book.network.php
`$fp = fsockopen(${js['host']}, ${js['port']});
fwrite($fp, "GET / HTTP/1.1\\r\\n\\r\\n");
fread($fp, 10);
fclose($fp);`,
`gethostbyname(${js['httpUrl']});`,
// @TODO:
// https:// stream handler
// MySQL functions from https://www.php.net/manual/en/book.mysql.php
// PDO functions from https://www.php.net/manual/en/book.pdo.php
// Sockets functions from https://www.php.net/manual/en/book.sockets.php
];

A bunch of them already is, but there's also a TODO comment listing the missing ones

Function calls

Different ways of calling the network functions like a direct function call, method call, reflections API are covered by specific test cases here:

test('Direct call', () => assertNoCrash(` ${networkCall}`));
describe('Function calls', () => {
test('Simple call', () =>
assertNoCrash(`function top() { ${networkCall} } top();`));
test('Via call_user_func', () =>
assertNoCrash(
`function top() { ${networkCall} } call_user_func('top'); `
));
test('Via call_user_func_array', () =>
assertNoCrash(
`function top() { ${networkCall} } call_user_func_array('top', array());`
));
});
describe('Class method calls', () => {

The initial list is nice, but we should also cover destructors, shutdown functions, serializable interface, and anything else you can think of.

Rebuilding PHP

After adding a test case, run

node --stack-trace-limit=100 ./node_modules/.bin/nx test php-wasm-node --test-name-pattern='asyncify'

If all the tests are green, good. If they're not, you may auto-fix the Dockerfile and rebuild PHP using this command:

npm run fix-asyncify

This takes some time so you may want to add all your test cases first and then run fix-asyncify just once at the end. Once it completes, all your new tests should pass.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions