appwrite/tests/e2e/Services/Functions/FunctionsCustomServerTest.php

1989 lines
76 KiB
PHP
Raw Normal View History

2020-05-05 20:37:59 +00:00
<?php
namespace Tests\E2E\Services\Functions;
use Appwrite\Functions\Specification;
2020-05-05 20:37:59 +00:00
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
2024-09-19 19:21:00 +00:00
use Utopia\CLI\Console;
2023-12-20 10:55:09 +00:00
use Utopia\Database\Document;
2022-12-14 15:42:25 +00:00
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Role;
2023-12-20 10:55:09 +00:00
use Utopia\Database\Query;
2023-03-01 12:00:54 +00:00
use Utopia\Database\Validator\Datetime as DatetimeValidator;
2024-09-04 18:52:01 +00:00
use Utopia\System\System;
2020-05-05 20:37:59 +00:00
2020-12-08 22:24:22 +00:00
class FunctionsCustomServerTest extends Scope
2020-05-05 20:37:59 +00:00
{
use FunctionsBase;
use ProjectCustom;
use SideServer;
2024-09-19 19:21:00 +00:00
public function testCreateFunction(): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$function = $this->createFunction([
2022-08-14 10:33:36 +00:00
'functionId' => ID::unique(),
2020-12-10 17:47:32 +00:00
'name' => 'Test',
'runtime' => 'php-8.0',
2023-08-11 13:34:57 +00:00
'entrypoint' => 'index.php',
2020-12-10 17:47:32 +00:00
'events' => [
2023-09-25 07:55:55 +00:00
'buckets.*.create',
'buckets.*.delete',
2020-12-10 17:47:32 +00:00
],
'timeout' => 10,
]);
2025-02-11 12:50:54 +00:00
$functionId = $function['body']['$id'] ?? '';
2020-12-10 17:47:32 +00:00
2022-12-19 11:21:09 +00:00
$dateValidator = new DatetimeValidator();
2024-09-19 19:21:00 +00:00
$this->assertEquals(201, $function['headers']['status-code']);
$this->assertNotEmpty($function['body']['$id']);
$this->assertEquals('Test', $function['body']['name']);
$this->assertEquals('php-8.0', $function['body']['runtime']);
$this->assertEquals(true, $dateValidator->isValid($function['body']['$createdAt']));
$this->assertEquals(true, $dateValidator->isValid($function['body']['$updatedAt']));
$this->assertEquals('', $function['body']['deployment']);
2020-12-10 17:47:32 +00:00
$this->assertEquals([
2023-09-25 07:55:55 +00:00
'buckets.*.create',
'buckets.*.delete',
2024-09-19 19:21:00 +00:00
], $function['body']['events']);
2024-09-19 21:10:04 +00:00
$this->assertEmpty($function['body']['schedule']);
2024-09-19 19:21:00 +00:00
$this->assertEquals(10, $function['body']['timeout']);
2024-09-19 19:21:00 +00:00
$variable = $this->createVariable($functionId, [
2022-08-03 13:32:50 +00:00
'key' => 'funcKey1',
'value' => 'funcValue1',
]);
2024-09-19 19:21:00 +00:00
$variable2 = $this->createVariable($functionId, [
2022-08-03 13:32:50 +00:00
'key' => 'funcKey2',
'value' => 'funcValue2',
]);
2024-09-19 19:21:00 +00:00
$variable3 = $this->createVariable($functionId, [
2022-08-03 13:32:50 +00:00
'key' => 'funcKey3',
'value' => 'funcValue3',
]);
2022-08-03 13:35:11 +00:00
2022-08-03 13:32:50 +00:00
$this->assertEquals(201, $variable['headers']['status-code']);
$this->assertEquals(201, $variable2['headers']['status-code']);
$this->assertEquals(201, $variable3['headers']['status-code']);
2020-12-10 17:47:32 +00:00
return [
'functionId' => $functionId,
];
}
/**
2024-09-19 19:21:00 +00:00
* @depends testCreateFunction
2020-12-10 17:47:32 +00:00
*/
2024-09-19 19:21:00 +00:00
public function testListFunctions(array $data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
// Test search id
$functions = $this->listFunctions([
2021-09-21 08:22:13 +00:00
'search' => $data['functionId']
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
$this->assertCount(1, $functions['body']['functions']);
$this->assertEquals($functions['body']['functions'][0]['name'], 'Test');
2021-09-21 08:22:13 +00:00
2024-09-19 19:21:00 +00:00
// Test pagination limit
$functions = $this->listFunctions([
2023-12-20 10:55:09 +00:00
'queries' => [
Query::limit(1)->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
$this->assertCount(1, $functions['body']['functions']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
// Test pagination offset
$functions = $this->listFunctions([
2023-12-20 10:55:09 +00:00
'queries' => [
Query::offset(1)->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
$this->assertCount(0, $functions['body']['functions']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
// Test filter enabled
$functions = $this->listFunctions([
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('enabled', [true])->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
$this->assertCount(1, $functions['body']['functions']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
// Test filter disabled
$functions = $this->listFunctions([
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('enabled', [false])->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
$this->assertCount(0, $functions['body']['functions']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
// Test search name
$functions = $this->listFunctions([
2021-09-21 08:22:13 +00:00
'search' => 'Test'
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
$this->assertCount(1, $functions['body']['functions']);
$this->assertEquals($functions['body']['functions'][0]['$id'], $data['functionId']);
2021-09-21 08:22:13 +00:00
2024-09-19 19:21:00 +00:00
// Test search runtime
2024-09-20 08:15:05 +00:00
$functions = $this->listFunctions([
2021-09-21 08:22:13 +00:00
'search' => 'php-8.0'
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
$this->assertCount(1, $functions['body']['functions']);
$this->assertEquals($functions['body']['functions'][0]['$id'], $data['functionId']);
2021-09-21 08:22:13 +00:00
2021-09-23 07:01:10 +00:00
/**
* Test pagination
*/
2024-09-19 21:10:04 +00:00
$this->setupFunction([
2022-08-14 10:33:36 +00:00
'functionId' => ID::unique(),
'name' => 'Test 2',
'runtime' => 'php-8.0',
2023-08-11 13:34:57 +00:00
'entrypoint' => 'index.php',
'events' => [
2023-09-25 07:55:55 +00:00
'buckets.*.create',
'buckets.*.delete',
],
'timeout' => 10,
]);
2022-08-03 13:32:50 +00:00
2024-09-19 19:21:00 +00:00
$functions = $this->listFunctions();
2020-12-10 17:47:32 +00:00
$this->assertEquals($functions['headers']['status-code'], 200);
2022-02-27 09:57:09 +00:00
$this->assertEquals($functions['body']['total'], 2);
$this->assertIsArray($functions['body']['functions']);
$this->assertCount(2, $functions['body']['functions']);
$this->assertEquals($functions['body']['functions'][0]['name'], 'Test');
$this->assertEquals($functions['body']['functions'][1]['name'], 'Test 2');
2024-09-20 08:41:34 +00:00
$functions1 = $this->listFunctions([
2023-12-20 10:55:09 +00:00
'queries' => [
Query::cursorAfter(new Document(['$id' => $functions['body']['functions'][0]['$id']]))->toString(),
],
]);
2024-09-20 08:41:34 +00:00
$this->assertEquals($functions1['headers']['status-code'], 200);
$this->assertCount(1, $functions1['body']['functions']);
$this->assertEquals($functions1['body']['functions'][0]['name'], 'Test 2');
2024-09-20 08:41:34 +00:00
$functions2 = $this->listFunctions([
2023-12-20 10:55:09 +00:00
'queries' => [
Query::cursorBefore(new Document(['$id' => $functions['body']['functions'][1]['$id']]))->toString(),
],
]);
2024-09-20 08:41:34 +00:00
$this->assertEquals($functions2['headers']['status-code'], 200);
$this->assertCount(1, $functions2['body']['functions']);
$this->assertEquals($functions2['body']['functions'][0]['name'], 'Test');
/**
* Test for FAILURE
*/
2024-09-19 19:21:00 +00:00
$functions = $this->listFunctions([
2023-12-20 10:55:09 +00:00
'queries' => [
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
],
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($functions['headers']['status-code'], 400);
2020-12-10 17:47:32 +00:00
return $data;
}
/**
2024-09-19 19:21:00 +00:00
* @depends testListFunctions
2020-12-10 17:47:32 +00:00
*/
2024-09-19 19:21:00 +00:00
public function testGetFunction(array $data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$function = $this->getFunction($data['functionId']);
2020-12-10 17:47:32 +00:00
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals($function['body']['name'], 'Test');
2022-02-28 15:17:44 +00:00
2020-12-10 17:47:32 +00:00
/**
* Test for FAILURE
*/
2024-09-19 19:21:00 +00:00
$function = $this->getFunction('x');
2020-12-10 17:47:32 +00:00
$this->assertEquals($function['headers']['status-code'], 404);
return $data;
}
/**
2024-09-19 19:21:00 +00:00
* @depends testGetFunction
2020-12-10 17:47:32 +00:00
*/
2024-09-19 19:21:00 +00:00
public function testUpdateFunction($data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([
2020-12-10 17:47:32 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Test1',
'events' => [
'users.*.update.name',
'users.*.update.email',
2020-12-10 17:47:32 +00:00
],
2021-04-23 15:08:18 +00:00
'schedule' => '0 0 1 1 *',
2023-08-16 06:19:42 +00:00
'timeout' => 15,
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2020-12-10 17:47:32 +00:00
]);
2022-12-19 11:21:09 +00:00
$dateValidator = new DatetimeValidator();
2024-09-19 20:29:18 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $function['headers']['status-code']);
$this->assertNotEmpty($function['body']['$id']);
$this->assertEquals('Test1', $function['body']['name']);
$this->assertEquals(true, $dateValidator->isValid($function['body']['$createdAt']));
$this->assertEquals(true, $dateValidator->isValid($function['body']['$updatedAt']));
$this->assertEquals('', $function['body']['deployment']);
2020-12-10 17:47:32 +00:00
$this->assertEquals([
'users.*.update.name',
'users.*.update.email',
2024-09-19 19:21:00 +00:00
], $function['body']['events']);
$this->assertEquals('0 0 1 1 *', $function['body']['schedule']);
$this->assertEquals(15, $function['body']['timeout']);
2023-09-05 11:55:02 +00:00
2024-09-19 19:21:00 +00:00
// Create a variable for later tests
$variable = $this->createVariable($data['functionId'], [
2023-09-05 11:55:02 +00:00
'key' => 'GLOBAL_VARIABLE',
'value' => 'Global Variable Value',
2024-03-06 17:34:21 +00:00
]);
2023-09-05 11:55:02 +00:00
$this->assertEquals(201, $variable['headers']['status-code']);
2020-12-10 17:47:32 +00:00
return $data;
}
public function testCreateDeploymentFromCLI()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
'functionId' => ID::unique(),
'name' => 'Test',
'execute' => [Role::user($this->getUser()['$id'])->toString()],
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'events' => [
'users.*.create',
'users.*.delete',
],
2024-09-19 11:35:52 +00:00
'schedule' => '0 0 1 1 *', // Once a year
'timeout' => 10,
]);
2024-09-20 08:41:34 +00:00
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
'x-sdk-language' => 'cli',
], [
'entrypoint' => 'index.php',
2024-09-19 11:35:52 +00:00
'code' => $this->packageFunction('php'),
'activate' => true
]);
$this->assertEquals(202, $deployment['headers']['status-code']);
2024-09-19 20:29:18 +00:00
$deploymentId = $deployment['body']['$id'] ?? '';
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId, $deploymentId) {
$deployment = $this->getDeployment($functionId, $deploymentId);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $deployment['headers']['status-code']);
2024-09-19 20:29:18 +00:00
$this->assertEquals('ready', $deployment['body']['status']);
2024-09-19 19:21:00 +00:00
$this->assertEquals('cli', $deployment['body']['type']);
}, 500000, 1000);
}
2024-09-19 19:21:00 +00:00
public function testCreateFunctionAndDeploymentFromTemplate()
2024-08-14 12:14:07 +00:00
{
2024-09-19 11:35:52 +00:00
$starterTemplate = $this->getTemplate('starter');
$this->assertEquals(200, $starterTemplate['headers']['status-code']);
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$phpRuntime = array_values(array_filter($starterTemplate['body']['runtimes'], function ($runtime) {
return $runtime['name'] === 'php-8.0';
}))[0];
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
// If this fails, the template has variables, and this test needs to be updated
$this->assertEmpty($starterTemplate['body']['variables']);
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$function = $this->createFunction(
[
'functionId' => ID::unique(),
'name' => $starterTemplate['body']['name'],
'runtime' => 'php-8.0',
'execute' => $starterTemplate['body']['permissions'],
'entrypoint' => $phpRuntime['entrypoint'],
'events' => $starterTemplate['body']['events'],
'schedule' => $starterTemplate['body']['cron'],
'timeout' => $starterTemplate['body']['timeout'],
'commands' => $phpRuntime['commands'],
'scopes' => $starterTemplate['body']['scopes'],
'templateRepository' => $starterTemplate['body']['providerRepositoryId'],
'templateOwner' => $starterTemplate['body']['providerOwner'],
'templateRootDirectory' => $phpRuntime['providerRootDirectory'],
'templateVersion' => $starterTemplate['body']['providerVersion'],
]
);
2024-08-14 12:14:07 +00:00
$this->assertEquals(201, $function['headers']['status-code']);
$this->assertNotEmpty($function['body']['$id']);
2025-02-11 12:50:54 +00:00
$functionId = $function['body']['$id'] ?? '';
2024-09-19 20:29:18 +00:00
2024-09-19 11:35:52 +00:00
$deployments = $this->listDeployments($functionId);
2024-08-14 12:14:07 +00:00
$this->assertEquals(200, $deployments['headers']['status-code']);
$this->assertEquals(1, $deployments['body']['total']);
2024-09-19 11:35:52 +00:00
$lastDeployment = $deployments['body']['deployments'][0];
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$this->assertNotEmpty($lastDeployment['$id']);
$this->assertEquals(0, $lastDeployment['size']);
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$deploymentId = $lastDeployment['$id'];
2024-08-22 10:51:08 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId, $deploymentId) {
$deployment = $this->getDeployment($functionId, $deploymentId);
2024-09-19 20:54:25 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $deployment['headers']['status-code']);
2024-09-19 20:29:18 +00:00
$this->assertEquals('ready', $deployment['body']['status']);
2025-01-17 05:08:39 +00:00
}, 50000, 1000);
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$function = $this->getFunction($functionId);
2024-08-14 12:14:07 +00:00
$this->assertEquals(200, $function['headers']['status-code']);
$this->assertEquals($deploymentId, $function['body']['deployment']);
2024-09-19 11:35:52 +00:00
// Test starter code is used and that dynamic keys work
$execution = $this->createExecution($functionId, [
'path' => '/ping',
2024-08-14 12:14:07 +00:00
]);
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals("completed", $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertEquals("Pong", $execution['body']['responseBody']);
$this->assertEmpty($execution['body']['errors']);
2024-09-19 11:35:52 +00:00
// Test execution logged correct total users
2024-08-14 12:14:07 +00:00
$users = $this->client->call(Client::METHOD_GET, '/users', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], $this->getHeaders()), []);
2024-08-14 12:50:25 +00:00
$this->assertEquals(200, $users['headers']['status-code']);
$this->assertIsInt($users['body']['total']);
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$totalUsers = $users['body']['total'];
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$this->assertStringContainsString("Total users: " . $totalUsers, $execution['body']['logs']);
2024-08-14 12:14:07 +00:00
2024-09-04 18:12:11 +00:00
// Execute function again but async
2024-09-19 11:35:52 +00:00
$execution = $this->createExecution($functionId, [
2024-09-04 18:12:11 +00:00
'path' => '/ping',
'async' => true
]);
$this->assertEquals(202, $execution['headers']['status-code']);
$this->assertNotEmpty($execution['body']['$id']);
$this->assertEquals('waiting', $execution['body']['status']);
2024-09-19 20:29:18 +00:00
$executionId = $execution['body']['$id'] ?? '';
2024-09-04 18:12:11 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEventually(function () use ($functionId, $executionId, $totalUsers) {
$execution = $this->getExecution($functionId, $executionId);
2024-09-04 18:12:11 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEquals(200, $execution['headers']['status-code']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
2024-09-19 19:21:00 +00:00
$this->assertEquals('completed', $execution['body']['status']);
2024-09-19 11:35:52 +00:00
$this->assertEmpty($execution['body']['responseBody']);
$this->assertEmpty($execution['body']['errors']);
$this->assertStringContainsString("Total users: " . $totalUsers, $execution['body']['logs']);
2024-09-19 20:54:25 +00:00
}, 10000, 500);
2024-08-14 12:14:07 +00:00
2024-09-19 11:35:52 +00:00
$function = $this->deleteFunction($functionId);
2024-08-14 12:14:07 +00:00
}
2020-12-10 17:47:32 +00:00
/**
2024-09-19 19:21:00 +00:00
* @depends testUpdateFunction
2020-12-10 17:47:32 +00:00
*/
public function testCreateDeployment($data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$functionId = $data['functionId'];
2022-02-28 15:17:44 +00:00
2024-09-19 19:21:00 +00:00
$deployment = $this->createDeployment($functionId, [
2024-09-19 11:35:52 +00:00
'code' => $this->packageFunction('php'),
2023-03-01 12:00:54 +00:00
'activate' => true
2020-12-10 17:47:32 +00:00
]);
2022-07-20 12:01:18 +00:00
$this->assertEquals(202, $deployment['headers']['status-code']);
2022-01-24 23:46:13 +00:00
$this->assertNotEmpty($deployment['body']['$id']);
2023-02-05 20:39:41 +00:00
$this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt']));
2022-01-24 23:46:13 +00:00
$this->assertEquals('index.php', $deployment['body']['entrypoint']);
2024-09-20 09:29:49 +00:00
$deploymentIdActive = $deployment['body']['$id'] ?? '';
2021-09-28 07:51:09 +00:00
2024-09-20 09:29:49 +00:00
$this->assertEventually(function () use ($functionId, $deploymentIdActive) {
$deployment = $this->getDeployment($functionId, $deploymentIdActive);
$this->assertEquals('ready', $deployment['body']['status']);
}, 50000, 500);
2024-09-19 20:29:18 +00:00
2024-09-19 19:21:00 +00:00
$deployment = $this->createDeployment($functionId, [
2024-09-19 11:35:52 +00:00
'code' => $this->packageFunction('php'),
2024-08-14 10:12:57 +00:00
'activate' => 'false'
]);
$this->assertEquals(202, $deployment['headers']['status-code']);
$this->assertNotEmpty($deployment['body']['$id']);
2024-09-20 09:29:49 +00:00
$deploymentIdInactive = $deployment['body']['$id'] ?? '';
2024-08-14 10:12:57 +00:00
2024-09-20 09:29:49 +00:00
$this->assertEventually(function () use ($functionId, $deploymentIdInactive) {
2024-09-19 19:21:00 +00:00
$deployment = $this->getDeployment($functionId, $deploymentIdInactive);
2024-08-14 10:12:57 +00:00
2024-09-19 20:29:18 +00:00
$this->assertEquals('ready', $deployment['body']['status']);
2024-09-20 09:29:49 +00:00
}, 50000, 500);
2024-08-14 10:12:57 +00:00
2024-09-19 19:21:00 +00:00
$function = $this->getFunction($functionId);
2024-08-14 10:12:57 +00:00
$this->assertEquals(200, $function['headers']['status-code']);
2024-09-20 09:29:49 +00:00
$this->assertEquals($deploymentIdActive, $function['body']['deployment']);
2024-08-14 10:12:57 +00:00
$this->assertNotEquals($deploymentIdInactive, $function['body']['deployment']);
2024-09-19 19:21:00 +00:00
$deployment = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId . '/deployments/' . $deploymentIdInactive, array_merge([
2024-08-14 12:58:28 +00:00
'content-type' => 'application/json',
2024-08-14 10:12:57 +00:00
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $deployment['headers']['status-code']);
2024-09-20 09:29:49 +00:00
return array_merge($data, ['deploymentId' => $deploymentIdActive]);
2022-02-23 06:07:15 +00:00
}
2024-06-11 14:41:13 +00:00
/**
2024-09-20 08:15:05 +00:00
* @depends testUpdateFunction
2024-06-11 14:41:13 +00:00
*/
public function testCancelDeploymentBuild($data): void
{
2024-09-19 19:21:00 +00:00
$functionId = $data['functionId'];
2024-06-11 14:41:13 +00:00
2024-09-19 19:21:00 +00:00
$deployment = $this->createDeployment($functionId, [
2024-09-19 11:35:52 +00:00
'code' => $this->packageFunction('php'),
2024-10-02 13:16:25 +00:00
'activate' => 'false'
2024-06-11 14:41:13 +00:00
]);
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(202, $deployment['headers']['status-code']);
$this->assertNotEmpty($deployment['body']['$id']);
$this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt']));
$this->assertEquals('index.php', $deployment['body']['entrypoint']);
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId, $deploymentId) {
$deployment = $this->getDeployment($functionId, $deploymentId);
2024-06-11 14:41:13 +00:00
2024-09-18 13:29:44 +00:00
$this->assertEquals(200, $deployment['headers']['status-code']);
$this->assertEquals('building', $deployment['body']['status']);
2024-09-19 19:21:00 +00:00
}, 100000, 250);
2024-06-11 14:41:13 +00:00
2024-09-19 19:21:00 +00:00
// Cancel the deployment
$cancel = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId . '/build', array_merge([
2024-06-11 14:41:13 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2024-09-19 19:21:00 +00:00
], $this->getHeaders()));
2024-06-11 14:41:13 +00:00
$this->assertEquals(200, $cancel['headers']['status-code']);
2024-06-12 10:21:48 +00:00
$this->assertEquals('canceled', $cancel['body']['status']);
2024-06-11 14:41:13 +00:00
2024-08-20 11:38:42 +00:00
/**
* Build worker still runs the build.
2024-08-22 10:51:08 +00:00
* 30s sleep gives worker enough time to finish build.
2024-08-20 11:38:42 +00:00
* After build finished, it should still be canceled, not ready.
*/
2024-08-22 10:51:08 +00:00
\sleep(30);
2024-06-11 14:41:13 +00:00
2024-09-19 19:21:00 +00:00
$deployment = $this->getDeployment($functionId, $deploymentId);
2024-06-11 14:41:13 +00:00
$this->assertEquals(200, $deployment['headers']['status-code']);
2024-06-12 10:21:48 +00:00
$this->assertEquals('canceled', $deployment['body']['status']);
2024-06-11 14:41:13 +00:00
}
2022-02-23 06:07:15 +00:00
/**
2024-09-20 08:15:05 +00:00
* @depends testUpdateFunction
2022-02-23 06:07:15 +00:00
*/
public function testCreateDeploymentLarge($data): array
{
2021-09-28 07:51:09 +00:00
/**
* Test for Large Code File SUCCESS
*/
2024-09-19 19:21:00 +00:00
$functionId = $data['functionId'];
2022-02-23 06:07:15 +00:00
$folder = 'php-large';
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
2024-10-08 07:54:40 +00:00
Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr);
2022-02-23 06:07:15 +00:00
$chunkSize = 5 * 1024 * 1024;
2022-02-23 06:07:15 +00:00
$handle = @fopen($code, "rb");
2021-09-28 07:51:09 +00:00
$mimeType = 'application/x-gzip';
$counter = 0;
2022-02-23 06:07:15 +00:00
$size = filesize($code);
2021-09-28 07:51:09 +00:00
$headers = [
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id']
];
$id = '';
while (!feof($handle)) {
$curlFile = new \CURLFile('data://' . $mimeType . ';base64,' . base64_encode(@fread($handle, $chunkSize)), $mimeType, 'php-large-fx.tar.gz');
2023-04-19 05:38:54 +00:00
$headers['content-range'] = 'bytes ' . ($counter * $chunkSize) . '-' . min(((($counter * $chunkSize) + $chunkSize) - 1), $size - 1) . '/' . $size;
if (!empty($id)) {
2021-09-28 07:51:09 +00:00
$headers['x-appwrite-id'] = $id;
}
2024-09-19 19:21:00 +00:00
$largeTag = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge($headers, $this->getHeaders()), [
'entrypoint' => 'index.php',
2021-09-28 07:51:09 +00:00
'code' => $curlFile,
2024-08-19 14:18:57 +00:00
'activate' => true,
'commands' => 'cp blue.mp4 copy.mp4 && ls -al' // +7MB buildSize
2021-09-28 07:51:09 +00:00
]);
$counter++;
$id = $largeTag['body']['$id'];
}
@fclose($handle);
2022-07-20 12:01:18 +00:00
$this->assertEquals(202, $largeTag['headers']['status-code']);
2021-09-28 07:51:09 +00:00
$this->assertNotEmpty($largeTag['body']['$id']);
2023-02-05 20:39:41 +00:00
$this->assertEquals(true, (new DatetimeValidator())->isValid($largeTag['body']['$createdAt']));
$this->assertEquals('index.php', $largeTag['body']['entrypoint']);
2024-08-19 14:18:57 +00:00
$this->assertGreaterThan(1024 * 1024 * 5, $largeTag['body']['size']); // ~7MB video file
$this->assertLessThan(1024 * 1024 * 10, $largeTag['body']['size']); // ~7MB video file
$deploymentSize = $largeTag['body']['size'];
$deploymentId = $largeTag['body']['$id'];
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId, $deploymentId, $deploymentSize) {
$deployment = $this->getDeployment($functionId, $deploymentId);
2024-08-19 14:18:57 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $deployment['headers']['status-code']);
2024-09-19 20:29:18 +00:00
$this->assertEquals('ready', $deployment['body']['status']);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deploymentSize, $deployment['body']['size']);
$this->assertGreaterThan(1024 * 1024 * 10, $deployment['body']['buildSize']); // ~7MB video file + 10MB sample file
}, 500000, 1000);
2022-02-23 06:07:15 +00:00
return $data;
2020-12-10 17:47:32 +00:00
}
/**
2022-01-24 23:46:13 +00:00
* @depends testCreateDeployment
2020-12-10 17:47:32 +00:00
*/
public function testUpdateDeployment($data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$dateValidator = new DatetimeValidator();
$response = $this->client->call(Client::METHOD_PATCH, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([
2020-12-10 17:47:32 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
2020-12-10 17:47:32 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
2022-12-19 11:21:09 +00:00
$this->assertEquals(true, $dateValidator->isValid($response['body']['$createdAt']));
$this->assertEquals(true, $dateValidator->isValid($response['body']['$updatedAt']));
2022-01-24 23:46:13 +00:00
$this->assertEquals($data['deploymentId'], $response['body']['deployment']);
2020-12-10 17:47:32 +00:00
return $data;
}
/**
2022-01-24 23:46:13 +00:00
* @depends testCreateDeployment
2020-12-10 17:47:32 +00:00
*/
public function testListDeployments(array $data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$functionId = $data['functionId'];
$deployments = $this->listDeployments($functionId);
2020-12-10 17:47:32 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals($deployments['body']['total'], 3);
$this->assertIsArray($deployments['body']['deployments']);
$this->assertCount(3, $deployments['body']['deployments']);
$this->assertArrayHasKey('size', $deployments['body']['deployments'][0]);
$this->assertArrayHasKey('buildSize', $deployments['body']['deployments'][0]);
2020-12-10 17:47:32 +00:00
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments($functionId, [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::limit(1)->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertCount(1, $deployments['body']['deployments']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments($functionId, [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::offset(1)->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertCount(2, $deployments['body']['deployments']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments($functionId, [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('entrypoint', ['index.php'])->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertCount(3, $deployments['body']['deployments']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments($functionId, [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('entrypoint', ['index.js'])->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertCount(0, $deployments['body']['deployments']);
2021-09-21 08:22:13 +00:00
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments($functionId, [
'search' => 'php-8.0'
]);
2021-09-21 08:22:13 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals(3, $deployments['body']['total']);
$this->assertIsArray($deployments['body']['deployments']);
$this->assertCount(3, $deployments['body']['deployments']);
$this->assertEquals($deployments['body']['deployments'][0]['$id'], $data['deploymentId']);
2021-09-21 08:22:13 +00:00
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
[
'queries' => [
Query::equal('type', ['manual'])->toString(),
],
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals(3, $deployments['body']['total']);
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
[
'queries' => [
Query::equal('type', ['vcs'])->toString(),
],
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals(0, $deployments['body']['total']);
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
[
'queries' => [
Query::equal('type', ['invalid-string'])->toString(),
],
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals(0, $deployments['body']['total']);
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
[
'queries' => [
Query::greaterThan('size', 10000)->toString(),
],
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals(1, $deployments['body']['total']);
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
[
'queries' => [
Query::greaterThan('size', 0)->toString(),
],
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals(3, $deployments['body']['total']);
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
[
'queries' => [
Query::greaterThan('size', -100)->toString(),
],
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployments['headers']['status-code'], 200);
$this->assertEquals(3, $deployments['body']['total']);
2024-08-19 14:18:57 +00:00
/**
* Ensure size output and size filters work exactly.
* Prevents buildSize being counted towards deployemtn size
*/
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
2024-08-19 14:18:57 +00:00
[
Query::limit(1)->toString(),
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $deployments['headers']['status-code']);
$this->assertGreaterThanOrEqual(1, $deployments['body']['total']);
$this->assertNotEmpty($deployments['body']['deployments'][0]['$id']);
$this->assertNotEmpty($deployments['body']['deployments'][0]['size']);
2024-08-19 14:18:57 +00:00
2024-09-19 19:21:00 +00:00
$deploymentId = $deployments['body']['deployments'][0]['$id'];
$deploymentSize = $deployments['body']['deployments'][0]['size'];
2024-08-19 14:18:57 +00:00
2024-09-19 19:21:00 +00:00
$deployments = $this->listDeployments(
$functionId,
2024-08-19 14:18:57 +00:00
[
'queries' => [
Query::equal('size', [$deploymentSize])->toString(),
],
]
);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $deployments['headers']['status-code']);
$this->assertGreaterThan(0, $deployments['body']['total']);
$matchingDeployment = array_filter(
$deployments['body']['deployments'],
2024-09-20 12:44:34 +00:00
fn ($deployment) => $deployment['$id'] === $deploymentId
2024-09-19 19:21:00 +00:00
);
2024-08-19 14:18:57 +00:00
2024-09-19 19:21:00 +00:00
$this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found");
2024-08-19 14:18:57 +00:00
2024-09-19 19:21:00 +00:00
if (!empty($matchingDeployment)) {
$deployment = reset($matchingDeployment);
$this->assertEquals($deploymentSize, $deployment['size']);
}
2024-08-19 14:18:57 +00:00
2020-12-10 17:47:32 +00:00
return $data;
}
/**
2022-01-24 23:46:13 +00:00
* @depends testCreateDeployment
2020-12-10 17:47:32 +00:00
*/
public function testGetDeployment(array $data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$deployment = $this->getDeployment($data['functionId'], $data['deploymentId']);
2020-12-10 17:47:32 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $deployment['headers']['status-code']);
$this->assertGreaterThan(0, $deployment['body']['buildTime']);
$this->assertNotEmpty($deployment['body']['status']);
$this->assertNotEmpty($deployment['body']['buildLogs']);
$this->assertArrayHasKey('size', $deployment['body']);
$this->assertArrayHasKey('buildSize', $deployment['body']);
2020-12-10 17:47:32 +00:00
/**
* Test for FAILURE
*/
2024-09-19 19:21:00 +00:00
$deployment = $this->getDeployment($data['functionId'], 'x');
2020-12-10 17:47:32 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals($deployment['headers']['status-code'], 404);
2020-12-10 17:47:32 +00:00
return $data;
}
/**
2022-01-24 23:46:13 +00:00
* @depends testUpdateDeployment
2020-12-10 17:47:32 +00:00
*/
public function testCreateExecution($data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($data['functionId'], [
2024-10-02 13:16:25 +00:00
'async' => 'false',
2020-12-10 17:47:32 +00:00
]);
2023-08-16 06:19:42 +00:00
$this->assertEquals(201, $execution['headers']['status-code']);
2021-04-23 15:05:17 +00:00
$this->assertNotEmpty($execution['body']['$id']);
$this->assertNotEmpty($execution['body']['functionId']);
2023-02-05 20:39:41 +00:00
$this->assertEquals(true, (new DatetimeValidator())->isValid($execution['body']['$createdAt']));
2021-04-23 15:05:17 +00:00
$this->assertEquals($data['functionId'], $execution['body']['functionId']);
$this->assertEquals('completed', $execution['body']['status']);
2023-08-16 06:19:42 +00:00
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertStringContainsString($execution['body']['functionId'], $execution['body']['responseBody']);
$this->assertStringContainsString($data['deploymentId'], $execution['body']['responseBody']);
$this->assertStringContainsString('Test1', $execution['body']['responseBody']);
$this->assertStringContainsString('http', $execution['body']['responseBody']);
$this->assertStringContainsString('PHP', $execution['body']['responseBody']);
$this->assertStringContainsString('8.0', $execution['body']['responseBody']);
2023-09-05 11:55:02 +00:00
$this->assertStringContainsString('Global Variable Value', $execution['body']['responseBody']);
2023-08-16 06:19:42 +00:00
// $this->assertStringContainsString('êä', $execution['body']['responseBody']); // tests unknown utf-8 chars
2024-09-14 10:28:14 +00:00
$this->assertNotEmpty($execution['body']['errors']);
$this->assertNotEmpty($execution['body']['logs']);
2023-08-16 06:19:42 +00:00
$this->assertLessThan(10, $execution['body']['duration']);
2020-12-10 17:47:32 +00:00
2024-09-19 20:29:18 +00:00
$executionId = $execution['body']['$id'] ?? '';
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($data['functionId'], [
2024-10-02 13:16:25 +00:00
'async' => 'false',
2024-08-12 07:26:20 +00:00
'path' => '/?code=400'
]);
2024-09-19 20:29:18 +00:00
2024-08-12 07:26:20 +00:00
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(400, $execution['body']['responseStatusCode']);
$execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $execution['body']['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
2024-09-19 19:21:00 +00:00
2024-08-12 07:26:20 +00:00
$this->assertEquals(204, $execution['headers']['status-code']);
2020-12-10 17:47:32 +00:00
return array_merge($data, ['executionId' => $executionId]);
}
/**
* @depends testCreateExecution
*/
public function testListExecutions(array $data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($data['functionId']);
2020-12-10 17:47:32 +00:00
2024-09-20 12:42:08 +00:00
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertEquals(1, $executions['body']['total']);
2024-09-19 19:21:00 +00:00
$this->assertIsArray($executions['body']['executions']);
$this->assertCount(1, $executions['body']['executions']);
2020-12-10 17:47:32 +00:00
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($data['functionId'], [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::limit(1)->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertCount(1, $executions['body']['executions']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($data['functionId'], [
2023-12-20 10:55:09 +00:00
'queries' => [
2024-09-20 12:42:08 +00:00
Query::offset(0)->toString(),
2023-12-20 10:55:09 +00:00
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $executions['headers']['status-code']);
2024-09-20 12:42:08 +00:00
$this->assertCount(1, $executions['body']['executions']);
2022-08-24 11:55:43 +00:00
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($data['functionId'], [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('trigger', ['http'])->toString(),
],
2022-08-24 11:55:43 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertCount(1, $executions['body']['executions']);
2022-08-24 11:55:43 +00:00
/**
* Test search queries
*/
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($data['functionId'], [
'search' => $data['executionId'],
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertEquals(1, $executions['body']['total']);
$this->assertIsInt($executions['body']['total']);
$this->assertCount(1, $executions['body']['executions']);
$this->assertEquals($data['functionId'], $executions['body']['executions'][0]['functionId']);
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($data['functionId'], [
'search' => $data['functionId'],
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertEquals(1, $executions['body']['total']);
$this->assertIsInt($executions['body']['total']);
$this->assertCount(1, $executions['body']['executions']);
$this->assertEquals($data['executionId'], $executions['body']['executions'][0]['$id']);
2020-12-10 17:47:32 +00:00
return $data;
}
/**
2022-01-24 23:46:13 +00:00
* @depends testUpdateDeployment
*/
public function testSyncCreateExecution($data): array
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($data['functionId'], [
2024-10-02 13:16:25 +00:00
// Testing default value, should be 'async' => 'false'
]);
2023-08-17 21:38:05 +00:00
2022-02-27 21:09:13 +00:00
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
2023-08-16 06:19:42 +00:00
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertStringContainsString('Test1', $execution['body']['responseBody']);
$this->assertStringContainsString('http', $execution['body']['responseBody']);
$this->assertStringContainsString('PHP', $execution['body']['responseBody']);
$this->assertStringContainsString('8.0', $execution['body']['responseBody']);
// $this->assertStringContainsString('êä', $execution['body']['response']); // tests unknown utf-8 chars
2022-11-10 12:04:49 +00:00
$this->assertLessThan(1.500, $execution['body']['duration']);
return $data;
}
2020-12-10 17:47:32 +00:00
/**
* @depends testListExecutions
*/
public function testGetExecution(array $data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$execution = $this->getExecution($data['functionId'], $data['executionId']);
2020-12-10 17:47:32 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals($execution['headers']['status-code'], 200);
$this->assertEquals($execution['body']['$id'], $data['executionId']);
2020-12-10 17:47:32 +00:00
/**
* Test for FAILURE
*/
2024-09-19 19:21:00 +00:00
$function = $this->getExecution($data['functionId'], 'x');
2020-12-10 17:47:32 +00:00
$this->assertEquals($function['headers']['status-code'], 404);
return $data;
}
2024-06-27 16:36:24 +00:00
2020-12-10 17:47:32 +00:00
/**
* @depends testGetExecution
*/
2024-06-27 16:36:24 +00:00
public function testDeleteExecution($data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-06-27 16:36:24 +00:00
$execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $data['executionId'], array_merge([
2020-12-10 17:47:32 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
2024-06-27 16:36:24 +00:00
$this->assertEquals(204, $execution['headers']['status-code']);
$this->assertEmpty($execution['body']);
2020-12-10 17:47:32 +00:00
2024-06-27 16:36:24 +00:00
$execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $data['executionId'], array_merge([
2020-12-10 17:47:32 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
2024-06-27 16:36:24 +00:00
$this->assertEquals(404, $execution['headers']['status-code']);
$this->assertStringContainsString('Execution with the requested ID could not be found', $execution['body']['message']);
2020-12-10 17:47:32 +00:00
/**
* Test for FAILURE
*/
2024-06-27 16:36:24 +00:00
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/executions', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'async' => true,
]);
$executionId = $execution['body']['$id'] ?? '';
2024-09-19 20:29:18 +00:00
2024-06-27 16:36:24 +00:00
$this->assertEquals(202, $execution['headers']['status-code']);
$execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $executionId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(400, $execution['headers']['status-code']);
$this->assertStringContainsString('execution_in_progress', $execution['body']['type']);
$this->assertStringContainsString('Can\'t delete ongoing execution.', $execution['body']['message']);
2020-12-10 17:47:32 +00:00
return $data;
}
2024-06-27 22:13:17 +00:00
/**
* @depends testGetExecution
*/
public function testUpdateSpecs($data): array
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
// Change the function specs
$function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Test1',
'events' => [
'users.*.update.name',
'users.*.update.email',
],
'timeout' => 15,
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'specification' => Specification::S_1VCPU_1GB,
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $function['headers']['status-code']);
$this->assertNotEmpty($function['body']['$id']);
$this->assertEquals(Specification::S_1VCPU_1GB, $function['body']['specification']);
2024-09-19 19:21:00 +00:00
// Verify the updated specs
$execution = $this->createExecution($data['functionId']);
2024-07-22 09:17:38 +00:00
$output = json_decode($execution['body']['responseBody'], true);
2024-07-22 09:17:38 +00:00
2024-10-27 17:04:40 +00:00
$this->assertEquals(1, $output['APPWRITE_COMPUTE_CPUS']);
$this->assertEquals(1024, $output['APPWRITE_COMPUTE_MEMORY']);
2024-09-19 19:21:00 +00:00
// Change the specs to 1vcpu 512mb
$function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Test1',
'events' => [
'users.*.update.name',
'users.*.update.email',
],
'timeout' => 15,
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'specification' => Specification::S_1VCPU_512MB,
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $function['headers']['status-code']);
$this->assertNotEmpty($function['body']['$id']);
$this->assertEquals(Specification::S_1VCPU_512MB, $function['body']['specification']);
2024-09-19 19:21:00 +00:00
// Verify the updated specs
$execution = $this->createExecution($data['functionId']);
2024-07-22 09:17:38 +00:00
$output = json_decode($execution['body']['responseBody'], true);
2024-07-22 09:17:38 +00:00
2024-10-27 17:04:40 +00:00
$this->assertEquals(1, $output['APPWRITE_COMPUTE_CPUS']);
$this->assertEquals(512, $output['APPWRITE_COMPUTE_MEMORY']);
/**
* Test for FAILURE
*/
2024-09-19 19:21:00 +00:00
$function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Test1',
'events' => [
'users.*.update.name',
'users.*.update.email',
],
'timeout' => 15,
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'specification' => 's-2vcpu-512mb', // Invalid specification
]);
2024-09-19 19:21:00 +00:00
$this->assertEquals(400, $function['headers']['status-code']);
$this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $function['body']['message']);
return $data;
}
2020-12-10 17:47:32 +00:00
/**
* @depends testGetExecution
*/
public function testDeleteDeployment($data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$deployment = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([
2020-12-10 17:47:32 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
2024-09-19 19:21:00 +00:00
$this->assertEquals(204, $deployment['headers']['status-code']);
$this->assertEmpty($deployment['body']);
2024-09-19 19:21:00 +00:00
$deployment = $this->getDeployment($data['functionId'], $data['deploymentId']);
2020-12-10 17:47:32 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(404, $deployment['headers']['status-code']);
2020-12-10 17:47:32 +00:00
return $data;
}
/**
2022-01-24 23:46:13 +00:00
* @depends testCreateDeployment
2020-12-10 17:47:32 +00:00
*/
2024-09-19 19:21:00 +00:00
public function testDeleteFunction($data): array
2020-12-10 17:47:32 +00:00
{
/**
* Test for SUCCESS
*/
2024-09-19 19:21:00 +00:00
$function = $this->deleteFunction($data['functionId']);
2020-12-10 17:47:32 +00:00
$this->assertEquals(204, $function['headers']['status-code']);
$this->assertEmpty($function['body']);
2024-09-19 19:21:00 +00:00
$function = $this->getFunction($data['functionId']);
2022-01-29 00:54:47 +00:00
$this->assertEquals(404, $function['headers']['status-code']);
2020-12-10 17:47:32 +00:00
return $data;
}
2024-09-19 19:21:00 +00:00
public function testExecutionTimeout()
2020-12-12 05:42:29 +00:00
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2022-08-14 10:33:36 +00:00
'functionId' => ID::unique(),
2024-09-20 12:42:08 +00:00
'name' => 'Test php-8.0',
2024-09-19 11:35:52 +00:00
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2020-12-12 05:42:29 +00:00
'events' => [],
2024-09-19 19:21:00 +00:00
'schedule' => '',
'timeout' => 5, // Should timeout after 5 seconds
2020-12-12 05:42:29 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2024-09-20 09:29:49 +00:00
'code' => $this->packageFunction('timeout'),
2022-02-19 16:14:31 +00:00
'activate' => true,
2020-12-12 05:42:29 +00:00
]);
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId, [
'async' => true
2020-12-12 05:42:29 +00:00
]);
2022-07-20 12:01:18 +00:00
$this->assertEquals(202, $execution['headers']['status-code']);
2020-12-12 05:42:29 +00:00
2024-09-19 20:29:18 +00:00
$executionId = $execution['body']['$id'] ?? '';
2024-08-14 14:38:15 +00:00
2024-09-19 19:21:00 +00:00
\sleep(5); // Wait for the function to timeout
2024-08-14 14:38:15 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEventually(function () use ($functionId, $executionId) {
$execution = $this->getExecution($functionId, $executionId);
2024-05-20 12:14:48 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEquals(200, $execution['headers']['status-code']);
$this->assertEquals('failed', $execution['body']['status']);
$this->assertEquals(500, $execution['body']['responseStatusCode']);
$this->assertGreaterThan(2, $execution['body']['duration']);
$this->assertLessThan(20, $execution['body']['duration']);
$this->assertEquals('', $execution['body']['responseBody']);
$this->assertEquals('', $execution['body']['logs']);
$this->assertStringContainsString('timed out', $execution['body']['errors']);
2024-09-19 20:54:25 +00:00
}, 10000, 500);
2024-05-20 12:14:48 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2020-12-12 05:42:29 +00:00
}
2021-03-10 19:43:15 +00:00
/**
2023-08-19 08:05:49 +00:00
*
* @return array<mixed>
2021-03-10 19:43:15 +00:00
*/
2023-08-19 08:05:49 +00:00
public function provideCustomExecutions(): array
2021-03-10 19:43:15 +00:00
{
2023-08-19 08:05:49 +00:00
return [
2024-06-27 16:36:24 +00:00
['folder' => 'php-fn', 'name' => 'php-8.0', 'entrypoint' => 'index.php', 'runtimeName' => 'PHP', 'runtimeVersion' => '8.0'],
['folder' => 'node', 'name' => 'node-18.0', 'entrypoint' => 'index.js', 'runtimeName' => 'Node.js', 'runtimeVersion' => '18.0'],
2025-02-03 10:49:20 +00:00
// TODO: Re-enable; temporarly disabled due to OPR v4rc issues
// ['folder' => 'python', 'name' => 'python-3.9', 'entrypoint' => 'main.py', 'runtimeName' => 'Python', 'runtimeVersion' => '3.9'],
2024-06-27 16:36:24 +00:00
['folder' => 'ruby', 'name' => 'ruby-3.1', 'entrypoint' => 'main.rb', 'runtimeName' => 'Ruby', 'runtimeVersion' => '3.1'],
2025-02-03 10:49:20 +00:00
// Swift and Dart disabled on purpose, as it's very slow.
2023-08-19 11:37:45 +00:00
// [ 'folder' => 'dart', 'name' => 'dart-2.15', 'entrypoint' => 'main.dart', 'runtimeName' => 'Dart', 'runtimeVersion' => '2.15' ],
// [ 'folder' => 'swift', 'name' => 'swift-5.5', 'entrypoint' => 'index.swift', 'runtimeName' => 'Swift', 'runtimeVersion' => '5.5' ],
2023-08-19 08:05:49 +00:00
];
2021-03-10 19:43:15 +00:00
}
2021-12-09 13:02:12 +00:00
2023-08-19 08:05:49 +00:00
/**
* @param string $folder
* @param string $name
* @param string $entrypoint
2023-08-19 11:37:45 +00:00
*
2023-08-19 08:05:49 +00:00
* @dataProvider provideCustomExecutions
2024-09-20 08:15:05 +00:00
* @depends testExecutionTimeout
2023-08-19 08:05:49 +00:00
*/
public function testCreateCustomExecution(string $folder, string $name, string $entrypoint, string $runtimeName, string $runtimeVersion)
2021-12-09 13:02:12 +00:00
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2022-08-14 10:33:36 +00:00
'functionId' => ID::unique(),
'name' => 'Test ' . $name,
2022-02-23 14:39:09 +00:00
'runtime' => $name,
2023-08-11 13:34:57 +00:00
'entrypoint' => $entrypoint,
2022-02-23 14:39:09 +00:00
'events' => [],
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2022-02-23 14:39:09 +00:00
]);
2024-09-19 19:21:00 +00:00
$variable = $this->createVariable($functionId, [
2022-08-03 13:32:50 +00:00
'key' => 'CUSTOM_VARIABLE',
2024-09-19 19:21:00 +00:00
'value' => 'variable'
2022-08-03 13:32:50 +00:00
]);
$this->assertEquals(201, $variable['headers']['status-code']);
2024-09-19 19:21:00 +00:00
$deploymentId = $this->setupDeployment($functionId, [
2022-02-23 14:39:09 +00:00
'entrypoint' => $entrypoint,
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction($folder),
2023-08-19 08:05:49 +00:00
'activate' => true
2022-02-23 14:39:09 +00:00
]);
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId, [
2023-08-19 08:05:49 +00:00
'body' => 'foobar',
2024-10-02 13:16:25 +00:00
'async' => 'false'
2022-02-23 16:22:58 +00:00
]);
2023-08-19 08:05:49 +00:00
$output = json_decode($execution['body']['responseBody'], true);
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
2022-02-23 16:22:58 +00:00
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
$this->assertEquals('Test ' . $name, $output['APPWRITE_FUNCTION_NAME']);
2022-02-23 16:22:58 +00:00
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
2023-08-19 08:05:49 +00:00
$this->assertEquals($runtimeName, $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
$this->assertEquals($runtimeVersion, $output['APPWRITE_FUNCTION_RUNTIME_VERSION']);
2022-02-23 16:22:58 +00:00
$this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT']);
$this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']);
2023-08-19 08:05:49 +00:00
$this->assertEquals('variable', $output['CUSTOM_VARIABLE']);
$this->assertEmpty($output['APPWRITE_FUNCTION_USER_ID']);
2022-02-23 16:22:58 +00:00
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
$this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']);
2023-08-19 08:05:49 +00:00
$this->assertStringContainsString('Amazing Function Log', $execution['body']['logs']);
$this->assertEmpty($execution['body']['errors']);
2022-02-23 16:22:58 +00:00
2024-09-19 20:29:18 +00:00
$executionId = $execution['body']['$id'] ?? '';
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($functionId);
2022-02-24 05:57:25 +00:00
$this->assertEquals($executions['headers']['status-code'], 200);
2022-02-27 09:57:09 +00:00
$this->assertEquals($executions['body']['total'], 1);
2022-02-24 05:57:25 +00:00
$this->assertIsArray($executions['body']['executions']);
$this->assertCount(1, $executions['body']['executions']);
$this->assertEquals($executions['body']['executions'][0]['$id'], $executionId);
$this->assertEquals($executions['body']['executions'][0]['trigger'], 'http');
2023-08-19 08:05:49 +00:00
$this->assertStringContainsString('Amazing Function Log', $executions['body']['executions'][0]['logs']);
2022-02-24 05:57:25 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2023-09-05 13:47:59 +00:00
}
2024-08-05 13:08:41 +00:00
public function testCreateCustomExecutionBinaryResponse()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2024-08-05 13:08:41 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Binary executions',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2024-08-05 13:08:41 +00:00
'execute' => ['any']
]);
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2024-08-05 13:08:41 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-binary-response'),
2024-08-05 13:08:41 +00:00
'activate' => true
]);
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
'x-appwrite-project' => $this->getProject()['$id'],
2024-09-19 19:21:00 +00:00
'accept' => 'multipart/form-data', // Accept binary response
2024-08-05 13:08:41 +00:00
], $this->getHeaders()), [
'body' => null,
]);
2024-08-06 17:31:09 +00:00
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertStringContainsString('multipart/form-data', $execution['headers']['content-type']);
2024-08-14 09:53:07 +00:00
$contentType = explode(';', $execution['headers']['content-type']);
$this->assertStringContainsString('boundary=----', $contentType[1]);
2024-08-05 13:08:41 +00:00
$bytes = unpack('C*byte', $execution['body']['responseBody']);
$this->assertCount(3, $bytes);
$this->assertEquals(0, $bytes['byte1']);
$this->assertEquals(10, $bytes['byte2']);
$this->assertEquals(255, $bytes['byte3']);
2024-08-06 17:31:09 +00:00
/**
* Test for FAILURE
*/
2024-08-05 13:08:41 +00:00
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
'x-appwrite-project' => $this->getProject()['$id'],
2024-09-19 19:21:00 +00:00
'accept' => 'application/json', // Accept JSON response
2024-08-05 13:08:41 +00:00
], $this->getHeaders()), [
'body' => null,
]);
2024-08-07 13:15:53 +00:00
$this->assertEquals(400, $execution['headers']['status-code']);
2024-08-09 15:08:50 +00:00
$this->assertStringContainsString('Failed to parse response', $execution['body']['message']);
2024-08-05 13:08:41 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2024-08-05 13:08:41 +00:00
}
public function testCreateCustomExecutionBinaryRequest()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2024-08-05 13:08:41 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Binary executions',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2024-08-05 13:08:41 +00:00
'execute' => ['any']
]);
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2024-08-05 13:08:41 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-binary-request'),
2024-08-05 13:08:41 +00:00
'activate' => true
]);
$bytes = pack('C*', ...[0, 20, 255]);
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
2024-09-19 19:21:00 +00:00
'content-type' => 'multipart/form-data', // Send binary request
2024-08-05 13:08:41 +00:00
'x-appwrite-project' => $this->getProject()['$id'],
'accept' => 'application/json',
], $this->getHeaders()), [
'body' => $bytes,
], false);
$executionBody = json_decode($execution['body'], true);
2024-08-07 13:15:53 +00:00
$this->assertEquals(201, $execution['headers']['status-code']);
2024-08-05 13:08:41 +00:00
$this->assertEquals(\md5($bytes), $executionBody['responseBody']);
2024-08-07 13:15:53 +00:00
$this->assertStringStartsWith('application/json', $execution['headers']['content-type']);
2024-08-06 17:31:09 +00:00
/**
* Test for FAILURE
*/
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
2024-09-19 19:21:00 +00:00
'content-type' => 'application/json', // Send JSON headers
2024-08-06 17:31:09 +00:00
'x-appwrite-project' => $this->getProject()['$id'],
'accept' => 'application/json',
], $this->getHeaders()), [
'body' => $bytes,
], false);
$executionBody = json_decode($execution['body'], true);
2024-08-05 13:08:41 +00:00
2024-08-06 17:31:09 +00:00
$this->assertNotEquals(\md5($bytes), $executionBody['responseBody']);
2024-08-05 13:08:41 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2024-08-05 13:08:41 +00:00
}
2023-09-05 13:47:59 +00:00
public function testv2Function()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2023-09-05 13:47:59 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP V2',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'events' => [],
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2023-09-05 13:47:59 +00:00
]);
2024-09-19 19:21:00 +00:00
$variable = $this->client->call(Client::METHOD_PATCH, '/mock/functions-v2', [
2023-09-05 13:47:59 +00:00
'content-type' => 'application/json',
'origin' => 'http://localhost',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-mode' => 'admin',
2024-09-19 19:21:00 +00:00
], [
2023-09-05 13:47:59 +00:00
'functionId' => $functionId
]);
$this->assertEquals(204, $variable['headers']['status-code']);
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2023-09-05 13:47:59 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-v2'),
2023-09-05 13:47:59 +00:00
'activate' => true
]);
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId, [
2023-09-05 13:47:59 +00:00
'body' => 'foobar',
2024-10-02 13:16:25 +00:00
'async' => 'false'
2023-09-05 13:47:59 +00:00
]);
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
2024-10-02 14:19:15 +00:00
$output = json_decode($execution['body']['responseBody'], true);
2023-09-05 13:47:59 +00:00
$this->assertEquals(true, $output['v2Woks']);
2022-02-24 05:57:25 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2022-02-24 05:57:25 +00:00
}
2021-12-09 13:02:12 +00:00
public function testGetRuntimes()
{
$runtimes = $this->client->call(Client::METHOD_GET, '/functions/runtimes', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $runtimes['headers']['status-code']);
2022-02-27 09:57:09 +00:00
$this->assertGreaterThan(0, $runtimes['body']['total']);
2021-12-09 13:02:12 +00:00
$runtime = $runtimes['body']['runtimes'][0];
$this->assertArrayHasKey('$id', $runtime);
$this->assertArrayHasKey('name', $runtime);
2024-08-09 11:56:55 +00:00
$this->assertArrayHasKey('key', $runtime);
2021-12-09 13:02:12 +00:00
$this->assertArrayHasKey('version', $runtime);
$this->assertArrayHasKey('logo', $runtime);
$this->assertArrayHasKey('image', $runtime);
$this->assertArrayHasKey('base', $runtime);
$this->assertArrayHasKey('supports', $runtime);
}
2023-09-24 11:19:31 +00:00
public function testEventTrigger()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2023-09-24 11:19:31 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Event executions',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'events' => [
'users.*.create',
],
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2023-09-24 11:19:31 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2023-09-24 11:19:31 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-event'),
2023-09-24 11:19:31 +00:00
'activate' => true
]);
2024-09-19 19:21:00 +00:00
// Create user as an event trigger
2023-09-24 11:19:31 +00:00
$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'
]);
$this->assertEquals(201, $user['headers']['status-code']);
2024-09-19 20:29:18 +00:00
$userId = $user['body']['$id'] ?? '';
2023-09-24 11:19:31 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId, $userId) {
$executions = $this->listExecutions($functionId);
2023-09-24 11:19:31 +00:00
2024-09-19 19:21:00 +00:00
$lastExecution = $executions['body']['executions'][0];
2023-09-24 11:19:31 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals('completed', $lastExecution['status']);
$this->assertEquals(204, $lastExecution['responseStatusCode']);
$this->assertStringContainsString($userId, $lastExecution['logs']);
$this->assertStringContainsString('Event User', $lastExecution['logs']);
}, 10000, 500);
2023-09-24 11:19:31 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2023-09-24 11:19:31 +00:00
2024-09-19 19:21:00 +00:00
// Cleanup user
$user = $this->client->call(Client::METHOD_DELETE, '/users/' . $userId, [
2023-09-24 11:19:31 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], []);
2024-09-19 19:21:00 +00:00
$this->assertEquals(204, $user['headers']['status-code']);
2023-09-24 11:19:31 +00:00
}
2023-10-27 08:26:46 +00:00
2024-05-06 11:27:28 +00:00
public function testScopes()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2024-05-06 11:27:28 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Scopes executions',
2024-09-20 09:29:49 +00:00
'commands' => 'sh setup.sh && composer install',
2024-05-06 11:27:28 +00:00
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'scopes' => ['users.read'],
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2024-05-06 11:27:28 +00:00
]);
2024-09-19 19:21:00 +00:00
$deploymentId = $this->setupDeployment($functionId, [
2024-05-06 11:27:28 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-scopes'),
'activate' => true,
2024-05-06 11:27:28 +00:00
]);
2024-09-19 19:21:00 +00:00
$deployment = $this->getDeployment($functionId, $deploymentId);
2024-08-08 07:38:37 +00:00
$this->assertEquals(200, $deployment['headers']['status-code']);
$this->assertStringContainsStringIgnoringCase("200 OK", $deployment['body']['buildLogs']);
$this->assertStringContainsStringIgnoringCase('"total":', $deployment['body']['buildLogs']);
$this->assertStringContainsStringIgnoringCase('"users":', $deployment['body']['buildLogs']);
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId, [
2024-10-02 13:16:25 +00:00
'async' => 'false',
2024-05-06 11:27:28 +00:00
]);
$this->assertEquals(201, $execution['headers']['status-code']);
2024-08-19 08:50:30 +00:00
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertGreaterThan(0, $execution['body']['duration']);
2024-08-19 09:00:56 +00:00
$this->assertNotEmpty($execution['body']['responseBody']);
$this->assertStringContainsString("total", $execution['body']['responseBody']);
2024-08-19 08:50:30 +00:00
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId, [
'async' => true,
2024-08-19 08:50:30 +00:00
]);
2024-08-19 09:00:56 +00:00
$this->assertEquals(202, $execution['headers']['status-code']);
$this->assertNotEmpty($execution['body']['$id']);
2024-08-19 08:50:30 +00:00
2024-09-19 20:29:18 +00:00
$executionId = $execution['body']['$id'] ?? '';
2024-08-19 08:50:30 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId, $executionId) {
$execution = $this->getExecution($functionId, $executionId);
2024-05-06 11:27:28 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertGreaterThan(0, $execution['body']['duration']);
2024-09-20 12:42:08 +00:00
$this->assertNotEmpty($execution['body']['logs']);
$this->assertStringContainsString("total", $execution['body']['logs']);
2024-09-19 20:54:25 +00:00
}, 10000, 500);
2024-05-06 11:27:28 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2024-05-06 11:27:28 +00:00
}
2023-10-27 08:26:46 +00:00
public function testCookieExecution()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2023-10-27 08:26:46 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Cookie executions',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2023-10-27 08:26:46 +00:00
]);
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2023-10-27 08:26:46 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-cookie'),
2023-10-27 08:26:46 +00:00
'activate' => true
]);
2023-10-27 10:01:37 +00:00
$cookie = 'cookieName=cookieValue; cookie2=value2; cookie3=value=3; cookie4=val:ue4; cookie5=value5';
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId, [
2024-10-02 13:16:25 +00:00
'async' => 'false',
2023-10-27 08:26:46 +00:00
'headers' => [
'cookie' => $cookie
]
]);
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertEquals($cookie, $execution['body']['responseBody']);
2024-07-03 12:35:08 +00:00
$this->assertGreaterThan(0, $execution['body']['duration']);
2023-10-27 08:26:46 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2023-10-27 08:26:46 +00:00
}
2023-10-27 13:33:26 +00:00
public function testFunctionsDomain()
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2023-10-27 13:33:26 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Cookie executions',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2023-10-27 13:33:26 +00:00
'execute' => ['any']
]);
$rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2023-12-20 10:55:09 +00:00
'queries' => [
Query::equal('resourceId', [$functionId])->toString(),
Query::equal('resourceType', ['function'])->toString(),
],
2023-10-27 13:33:26 +00:00
]);
$this->assertEquals(200, $rules['headers']['status-code']);
$this->assertEquals(1, $rules['body']['total']);
$this->assertCount(1, $rules['body']['rules']);
$this->assertNotEmpty($rules['body']['rules'][0]['domain']);
$domain = $rules['body']['rules'][0]['domain'];
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2023-10-27 13:33:26 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-cookie'),
2023-10-27 13:33:26 +00:00
'activate' => true
]);
$cookie = 'cookieName=cookieValue; cookie2=value2; cookie3=value=3; cookie4=val:ue4; cookie5=value5';
$proxyClient = new Client();
$proxyClient->setEndpoint('http://' . $domain);
$response = $proxyClient->call(Client::METHOD_GET, '/', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => $cookie
]));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals($cookie, $response['body']);
2024-10-14 13:06:08 +00:00
// Async execution document creation
$this->assertEventually(function () use ($functionId) {
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertEquals(1, count($executions['body']['executions']));
});
2024-08-05 03:21:10 +00:00
// Await Aggregation
2024-09-04 18:52:01 +00:00
sleep(System::getEnv('_APP_USAGE_AGGREGATION_INTERVAL', 30));
2024-08-05 03:21:10 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId) {
$response = $this->getFunctionUsage($functionId, [
'range' => '24h'
]);
2024-08-02 07:24:54 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(19, count($response['body']));
$this->assertEquals('24h', $response['body']['range']);
$this->assertEquals(1, $response['body']['executionsTotal']);
}, 25000, 1000);
2023-10-27 13:33:26 +00:00
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2023-10-27 13:33:26 +00:00
}
2024-07-01 08:35:06 +00:00
2024-08-05 13:08:41 +00:00
public function testFunctionsDomainBinaryResponse()
2024-07-01 08:35:06 +00:00
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2024-07-01 08:35:06 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Binary executions',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2024-07-01 08:35:06 +00:00
'execute' => ['any']
]);
$rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('resourceId', [$functionId])->toString(),
Query::equal('resourceType', ['function'])->toString(),
],
]);
$this->assertEquals(200, $rules['headers']['status-code']);
$this->assertEquals(1, $rules['body']['total']);
$this->assertCount(1, $rules['body']['rules']);
$this->assertNotEmpty($rules['body']['rules'][0]['domain']);
$domain = $rules['body']['rules'][0]['domain'];
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2024-07-01 08:35:06 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-binary-response'),
2024-07-01 08:35:06 +00:00
'activate' => true
]);
$proxyClient = new Client();
$proxyClient->setEndpoint('http://' . $domain);
$response = $proxyClient->call(Client::METHOD_GET, '/', [], [], false);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']);
$bytes = unpack('C*byte', $response['body']);
$this->assertCount(3, $bytes);
$this->assertEquals(0, $bytes['byte1']);
$this->assertEquals(10, $bytes['byte2']);
$this->assertEquals(255, $bytes['byte3']);
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2024-07-01 08:35:06 +00:00
}
2024-08-05 13:08:41 +00:00
public function testFunctionsDomainBinaryRequest()
2024-07-01 08:35:06 +00:00
{
2024-09-19 19:21:00 +00:00
$functionId = $this->setupFunction([
2024-07-01 08:35:06 +00:00
'functionId' => ID::unique(),
'name' => 'Test PHP Binary executions',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'timeout' => 15,
2024-07-01 08:35:06 +00:00
'execute' => ['any']
]);
$rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('resourceId', [$functionId])->toString(),
Query::equal('resourceType', ['function'])->toString(),
],
]);
$this->assertEquals(200, $rules['headers']['status-code']);
$this->assertEquals(1, $rules['body']['total']);
$this->assertCount(1, $rules['body']['rules']);
$this->assertNotEmpty($rules['body']['rules'][0]['domain']);
$domain = $rules['body']['rules'][0]['domain'];
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
2024-07-01 08:35:06 +00:00
'entrypoint' => 'index.php',
2024-09-19 19:21:00 +00:00
'code' => $this->packageFunction('php-binary-request'),
2024-07-01 08:35:06 +00:00
'activate' => true
]);
$proxyClient = new Client();
$proxyClient->setEndpoint('http://' . $domain);
2024-08-05 13:08:41 +00:00
$bytes = pack('C*', ...[0, 20, 255]);
2024-07-01 08:35:06 +00:00
2024-08-05 13:08:41 +00:00
$response = $proxyClient->call(Client::METHOD_POST, '/', ['content-type' => 'text/plain'], $bytes, false);
2024-07-01 08:35:06 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(\md5($bytes), $response['body']);
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2024-07-01 08:35:06 +00:00
}
2024-08-16 12:31:15 +00:00
2024-10-03 09:33:05 +00:00
public function testResponseFilters()
2024-08-16 12:31:15 +00:00
{
2024-10-03 09:56:31 +00:00
// create function with 1.5.0 response format
2024-10-03 09:33:05 +00:00
$response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
2024-07-01 08:35:06 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
2024-08-16 12:31:15 +00:00
'x-appwrite-response-format' => '1.5.0', // add response format header
], $this->getHeaders()), [
'functionId' => ID::unique(),
'name' => 'Test',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'timeout' => 15,
]);
$this->assertEquals(201, $response['headers']['status-code']);
2024-09-25 12:08:30 +00:00
$this->assertArrayNotHasKey('scopes', $response['body']);
$this->assertArrayNotHasKey('specification', $response['body']);
2024-08-16 12:31:15 +00:00
2024-09-25 12:08:30 +00:00
// get function with 1.5.0 response format header
2024-09-20 07:20:30 +00:00
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $response['body']['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.5.0', // add response format header
], $this->getHeaders()));
$this->assertEquals(200, $function['headers']['status-code']);
$this->assertArrayNotHasKey('scopes', $function['body']);
$this->assertArrayNotHasKey('specification', $function['body']);
2024-10-03 10:37:01 +00:00
$function = $this->getFunction($function['body']['$id']);
2024-09-20 07:20:30 +00:00
$this->assertEquals(200, $function['headers']['status-code']);
$this->assertArrayHasKey('scopes', $function['body']);
$this->assertArrayHasKey('specification', $function['body']);
2024-10-03 09:56:31 +00:00
$functionId = $function['body']['$id'] ?? '';
$this->cleanupFunction($functionId);
}
public function testRequestFilters()
{
2024-10-03 10:37:01 +00:00
$function1Id = $this->setupFunction([
2024-10-03 09:56:31 +00:00
'functionId' => ID::unique(),
'name' => 'Test',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'timeout' => 15,
2024-10-03 10:37:01 +00:00
'execute' => ['any']
2024-10-03 09:56:31 +00:00
]);
2024-10-03 10:37:01 +00:00
$function2Id = $this->setupFunction([
2024-09-25 18:06:00 +00:00
'functionId' => ID::unique(),
'name' => 'Test2',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'timeout' => 15,
2024-10-03 10:37:01 +00:00
'execute' => ['any']
2024-09-25 18:06:00 +00:00
]);
// list functions using request filters
$response = $this->client->call(
Client::METHOD_GET,
'/functions',
array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-response-format' => '1.4.0', // Set response format for 1.4 syntax
], $this->getHeaders()),
[
2024-10-08 07:54:40 +00:00
'queries' => [ 'equal("name", ["Test2"])' ]
2024-09-25 18:06:00 +00:00
]
);
2024-10-08 07:54:40 +00:00
2024-09-25 18:06:00 +00:00
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(1, $response['body']['functions']);
$this->assertEquals('Test2', $response['body']['functions'][0]['name']);
2024-10-03 09:56:31 +00:00
$this->cleanupFunction($function1Id);
$this->cleanupFunction($function2Id);
2024-09-25 18:06:00 +00:00
}
2024-09-05 13:23:24 +00:00
public function testFunctionLogging()
{
2024-09-19 19:21:00 +00:00
$function = $this->createFunction([
2024-09-05 13:23:24 +00:00
'functionId' => ID::unique(),
'runtime' => 'node-18.0',
'name' => 'Logging Test',
'entrypoint' => 'index.js',
'logging' => false,
'execute' => ['any']
]);
$this->assertEquals(201, $function['headers']['status-code']);
$this->assertFalse($function['body']['logging']);
$this->assertNotEmpty($function['body']['$id']);
2025-02-11 12:50:54 +00:00
$functionId = $function['body']['$id'] ?? '';
2024-09-05 13:23:24 +00:00
2024-09-19 19:21:00 +00:00
$this->setupDeployment($functionId, [
'code' => $this->packageFunction('node'),
2024-09-05 13:23:24 +00:00
'activate' => true
]);
// Sync Executions test
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId);
2024-09-05 13:23:24 +00:00
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEmpty($execution['body']['logs']);
$this->assertEmpty($execution['body']['errors']);
// Async Executions test
2024-09-19 19:21:00 +00:00
$execution = $this->createExecution($functionId, [
2024-09-05 13:23:24 +00:00
'async' => true
]);
$this->assertEquals(202, $execution['headers']['status-code']);
$this->assertEmpty($execution['body']['logs']);
$this->assertEmpty($execution['body']['errors']);
$this->assertNotEmpty($execution['body']['$id']);
2024-09-19 19:21:00 +00:00
$executionId = $execution['body']['$id'] ?? '';
2024-09-05 13:23:24 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEventually(function () use ($functionId, $executionId) {
$execution = $this->getExecution($functionId, $executionId);
2024-09-05 13:23:24 +00:00
2024-09-19 19:21:00 +00:00
$this->assertEquals(200, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEmpty($execution['body']['logs']);
$this->assertEmpty($execution['body']['errors']);
2024-09-19 20:54:25 +00:00
}, 10000, 500);
2024-09-05 13:23:24 +00:00
// Domain Executions test
$rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('resourceId', [$functionId])->toString(),
Query::equal('resourceType', ['function'])->toString(),
],
]);
$this->assertEquals(200, $rules['headers']['status-code']);
$this->assertNotEmpty($rules['body']['rules'][0]['domain']);
$domain = $rules['body']['rules'][0]['domain'];
$proxyClient = new Client();
$proxyClient->setEndpoint('http://' . $domain);
$response = $proxyClient->call(Client::METHOD_GET, '/', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id']
]));
$this->assertEquals(200, $response['headers']['status-code']);
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($functionId, [
2024-09-05 13:23:24 +00:00
'queries' => [
Query::limit(1)->toString(),
Query::orderDesc('$id')->toString(),
]
]);
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertCount(1, $executions['body']['executions']);
$this->assertEmpty($executions['body']['executions'][0]['logs']);
$this->assertEmpty($executions['body']['executions'][0]['errors']);
// Ensure executions count
2024-09-19 19:21:00 +00:00
$executions = $this->listExecutions($functionId);
2024-09-05 13:23:24 +00:00
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertCount(3, $executions['body']['executions']);
// Double check logs and errors are empty
foreach ($executions['body']['executions'] as $execution) {
$this->assertEmpty($execution['logs']);
$this->assertEmpty($execution['errors']);
}
2024-09-19 19:21:00 +00:00
$this->cleanupFunction($functionId);
2024-09-05 13:23:24 +00:00
}
}