From 310517fd2951bb60b5ca4c2fa0e864493e745017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sun, 24 Sep 2023 13:19:31 +0200 Subject: [PATCH 1/4] Auto-parse event bodies + test --- app/workers/functions.php | 3 +- .../Functions/FunctionsCustomServerTest.php | 112 ++++++++++++++++++ tests/resources/functions/php-event/index.php | 8 ++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 tests/resources/functions/php-event/index.php diff --git a/app/workers/functions.php b/app/workers/functions.php index 619d33387a..20eda492bd 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -363,7 +363,8 @@ $server->job() path: '/', method: 'POST', headers: [ - 'user-agent' => 'Appwrite/' . APP_VERSION_STABLE + 'user-agent' => 'Appwrite/' . APP_VERSION_STABLE, + 'content-type' => 'application/json' ], ); Console::success('Triggered function: ' . $events[0]); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 60b7f7542e..553db47960 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1231,4 +1231,116 @@ class FunctionsCustomServerTest extends Scope $this->assertArrayHasKey('base', $runtime); $this->assertArrayHasKey('supports', $runtime); } + + + public function testEventTrigger() + { + $timeout = 5; + $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-event/code.tar.gz"; + $this->packageCode('php-event'); + + $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'functionId' => ID::unique(), + 'name' => 'Test PHP Event executions', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'events' => [ + 'users.*.create', + ], + 'timeout' => $timeout, + ]); + + $functionId = $function['body']['$id'] ?? ''; + + $this->assertEquals(201, $function['headers']['status-code']); + + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'entrypoint' => 'index.php', + 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'activate' => true + ]); + + $deploymentId = $deployment['body']['$id'] ?? ''; + $this->assertEquals(202, $deployment['headers']['status-code']); + + // Poll until deployment is built + while (true) { + $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/deployments/' . $deploymentId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + if ( + $deployment['headers']['status-code'] >= 400 + || \in_array($deployment['body']['status'], ['ready', 'failed']) + ) { + break; + } + + \sleep(1); + } + + $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); + + $this->assertEquals(200, $deployment['headers']['status-code']); + + // Create user to trigger event + $user = $this->client->call(Client::METHOD_POST, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'userId' => 'unique()', + 'name' => 'Event User' + ]); + + $userId = $user['body']['$id']; + + $this->assertEquals(201, $user['headers']['status-code']); + + // Wait for execution to occur + sleep(15); + + $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'async' => false + ]); + + $execution = $executions['body']['executions'][0]; + + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertEquals('completed', $execution['status']); + $this->assertEquals(204, $execution['responseStatusCode']); + $this->assertStringContainsString($userId, $execution['logs']); + $this->assertStringContainsString('Event User', $execution['logs']); + + // Cleanup : Delete function + $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], []); + + $this->assertEquals(204, $response['headers']['status-code']); + + // Cleanup : Delete user + $response = $this->client->call(Client::METHOD_DELETE, '/users/' . $userId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], []); + + $this->assertEquals(204, $response['headers']['status-code']); + } } diff --git a/tests/resources/functions/php-event/index.php b/tests/resources/functions/php-event/index.php new file mode 100644 index 0000000000..550fd57729 --- /dev/null +++ b/tests/resources/functions/php-event/index.php @@ -0,0 +1,8 @@ +log($context->req->body['$id']); + $context->log($context->req->body['name']); + + return $context->res->empty(); +}; From fee30e0239f9b8ec5dfcf931018cc8f212834c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sun, 24 Sep 2023 14:34:27 +0200 Subject: [PATCH 2/4] Remove unnessessary test code --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 553db47960..0ca55f3929 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1313,9 +1313,7 @@ class FunctionsCustomServerTest extends Scope $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'async' => false - ]); + ], $this->getHeaders())); $execution = $executions['body']['executions'][0]; From 303c8a16ca6ab219d9e54437e08cb35256bd7dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sun, 24 Sep 2023 14:38:33 +0200 Subject: [PATCH 3/4] Fix test --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 0ca55f3929..fd66f94025 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1294,6 +1294,9 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $deployment['headers']['status-code']); + // Wait a little for activation to finish + sleep(5); + // Create user to trigger event $user = $this->client->call(Client::METHOD_POST, '/users', array_merge([ 'content-type' => 'application/json', From a6aa38f1d829361530affca498cabbdf45a62068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 25 Sep 2023 09:55:55 +0200 Subject: [PATCH 4/4] Fix test --- .../Services/Functions/FunctionsCustomServerTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index fd66f94025..cdc9ec846f 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -32,8 +32,8 @@ class FunctionsCustomServerTest extends Scope 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'events' => [ - 'users.*.create', - 'users.*.delete', + 'buckets.*.create', + 'buckets.*.delete', ], 'schedule' => '0 0 1 1 *', 'timeout' => 10, @@ -50,8 +50,8 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(true, $dateValidator->isValid($response1['body']['$updatedAt'])); $this->assertEquals('', $response1['body']['deployment']); $this->assertEquals([ - 'users.*.create', - 'users.*.delete', + 'buckets.*.create', + 'buckets.*.delete', ], $response1['body']['events']); $this->assertEquals('0 0 1 1 *', $response1['body']['schedule']); $this->assertEquals(10, $response1['body']['timeout']); @@ -191,8 +191,8 @@ class FunctionsCustomServerTest extends Scope 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'events' => [ - 'users.*.create', - 'users.*.delete', + 'buckets.*.create', + 'buckets.*.delete', ], 'schedule' => '0 0 1 1 *', 'timeout' => 10,