From 06a5e76c5047a8fe941cd9cc48d29bad5d482fe5 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 23 May 2024 17:42:03 +0300 Subject: [PATCH 001/213] ScheduleBase refactor --- app/init.php | 4 ++-- src/Appwrite/Platform/Tasks/ScheduleBase.php | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/init.php b/app/init.php index 57ad5fab87..45c28319f4 100644 --- a/app/init.php +++ b/app/init.php @@ -1454,9 +1454,9 @@ App::setResource('deviceForBuilds', function ($project) { return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId()); }, ['project']); -function getDevice($root): Device +function getDevice(string $root, string $connection = null): Device { - $connection = System::getEnv('_APP_CONNECTIONS_STORAGE', ''); + $connection = empty($connection) ? System::getEnv('_APP_CONNECTIONS_STORAGE', '') : System::getEnv($connection, ''); if (!empty($connection)) { $acl = 'private'; diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index a50fbb2403..c8c183603e 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -27,7 +27,8 @@ abstract class ScheduleBase extends Action abstract protected function enqueueResources( Group $pools, - Database $dbForConsole + Database $dbForConsole, + callable $getProjectDB ); public function __construct() @@ -130,7 +131,7 @@ abstract class ScheduleBase extends Action Console::success("Starting timers at " . DateTime::now()); - run(function () use ($dbForConsole, &$lastSyncUpdate, $getSchedule, $pools) { + run(function () use ($dbForConsole, &$lastSyncUpdate, $getSchedule, $pools, $getProjectDB) { /** * The timer synchronize $schedules copy with database collection. */ @@ -190,10 +191,10 @@ abstract class ScheduleBase extends Action Timer::tick( static::ENQUEUE_TIMER * 1000, - fn () => $this->enqueueResources($pools, $dbForConsole) + fn () => $this->enqueueResources($pools, $dbForConsole, $getProjectDB) ); - $this->enqueueResources($pools, $dbForConsole); + $this->enqueueResources($pools, $dbForConsole, $getProjectDB); }); } } From ecfc5d68c20ed442d9af702242455f79b13f713c Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 23 May 2024 17:49:41 +0300 Subject: [PATCH 002/213] accept null --- app/init.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/init.php b/app/init.php index 45c28319f4..0f9b3b3bfa 100644 --- a/app/init.php +++ b/app/init.php @@ -1454,7 +1454,7 @@ App::setResource('deviceForBuilds', function ($project) { return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId()); }, ['project']); -function getDevice(string $root, string $connection = null): Device +function getDevice(string $root, ?string $connection = null): Device { $connection = empty($connection) ? System::getEnv('_APP_CONNECTIONS_STORAGE', '') : System::getEnv($connection, ''); From 0994b0f2dee1dcf940191b0e81a95c265d89eba4 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 23 May 2024 18:14:00 +0300 Subject: [PATCH 003/213] trigger migration --- src/Appwrite/Event/Migration.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Event/Migration.php b/src/Appwrite/Event/Migration.php index 478291829b..1bba6e6180 100644 --- a/src/Appwrite/Event/Migration.php +++ b/src/Appwrite/Event/Migration.php @@ -10,6 +10,7 @@ class Migration extends Event { protected string $type = ''; protected ?Document $migration = null; + protected ?Document $backup; public function __construct(protected Connection $connection) { @@ -33,6 +34,19 @@ class Migration extends Event return $this; } + /** + * Sets backup. + * + * @param Document $backup + * @return self + */ + public function setBackup(Document $backup): self + { + $this->backup = $backup; + + return $this; + } + /** * Returns set migration document for the function event. * @@ -81,7 +95,8 @@ class Migration extends Event return $client->enqueue([ 'project' => $this->project, 'user' => $this->user, - 'migration' => $this->migration + 'migration' => $this->migration, + 'backup' => $this->backup ]); } } From 552c729c5a50d7ab94302b0ccd5ee09cea54c326 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 23 May 2024 18:22:25 +0300 Subject: [PATCH 004/213] fix enqueueResources --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 7 +------ src/Appwrite/Platform/Tasks/ScheduleFunctions.php | 2 +- src/Appwrite/Platform/Tasks/ScheduleMessages.php | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index c8c183603e..605082b2d3 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -24,12 +24,7 @@ abstract class ScheduleBase extends Action abstract public static function getName(): string; abstract public static function getSupportedResource(): string; - - abstract protected function enqueueResources( - Group $pools, - Database $dbForConsole, - callable $getProjectDB - ); + abstract protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB):void; public function __construct() { diff --git a/src/Appwrite/Platform/Tasks/ScheduleFunctions.php b/src/Appwrite/Platform/Tasks/ScheduleFunctions.php index e2c278714f..98a935876a 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleFunctions.php +++ b/src/Appwrite/Platform/Tasks/ScheduleFunctions.php @@ -26,7 +26,7 @@ class ScheduleFunctions extends ScheduleBase return 'function'; } - protected function enqueueResources(Group $pools, Database $dbForConsole): void + protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void { $timerStart = \microtime(true); $time = DateTime::now(); diff --git a/src/Appwrite/Platform/Tasks/ScheduleMessages.php b/src/Appwrite/Platform/Tasks/ScheduleMessages.php index 8e52973a0c..ac2eaa3302 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleMessages.php +++ b/src/Appwrite/Platform/Tasks/ScheduleMessages.php @@ -21,7 +21,7 @@ class ScheduleMessages extends ScheduleBase return 'message'; } - protected function enqueueResources(Group $pools, Database $dbForConsole): void + protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void { foreach ($this->schedules as $schedule) { if (!$schedule['active']) { From d4b0ca7804ced1c72c98857bc0ee99660e686f41 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 26 May 2024 11:05:18 +0300 Subject: [PATCH 005/213] add scopes --- tests/e2e/Scopes/ProjectCustom.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e/Scopes/ProjectCustom.php b/tests/e2e/Scopes/ProjectCustom.php index ad2c93790c..3edc35a34c 100644 --- a/tests/e2e/Scopes/ProjectCustom.php +++ b/tests/e2e/Scopes/ProjectCustom.php @@ -94,6 +94,8 @@ trait ProjectCustom 'topics.read', 'subscribers.write', 'subscribers.read', + 'backups.write', + 'backups.read' ], ]); From a7b7059916ed377bf69c773d3c4a8ff363f0897f Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 26 May 2024 11:37:16 +0300 Subject: [PATCH 006/213] revert scope --- tests/e2e/Scopes/ProjectCustom.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/e2e/Scopes/ProjectCustom.php b/tests/e2e/Scopes/ProjectCustom.php index 3edc35a34c..ad2c93790c 100644 --- a/tests/e2e/Scopes/ProjectCustom.php +++ b/tests/e2e/Scopes/ProjectCustom.php @@ -94,8 +94,6 @@ trait ProjectCustom 'topics.read', 'subscribers.write', 'subscribers.read', - 'backups.write', - 'backups.read' ], ]); From bbcab38590e91f9de8877bcf2aa5c73795ec416a Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 26 May 2024 12:14:40 +0300 Subject: [PATCH 007/213] add config backups scopes --- app/config/scopes.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/config/scopes.php b/app/config/scopes.php index 3765ab54fa..7243e35f96 100644 --- a/app/config/scopes.php +++ b/app/config/scopes.php @@ -130,4 +130,10 @@ return [ // List of publicly visible scopes 'assistant.read' => [ 'description' => 'Access to read the Assistant service', ], + 'backups.write' => [ + 'description' => 'Access to create, update, and delete your backups', + ], + 'backups.read' => [ + 'description' => 'Access to read the backups service', + ], ]; From 9c591bd42d5b9008cb3678b145cfd2e8964f0643 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 27 May 2024 17:06:08 +0300 Subject: [PATCH 008/213] add resourceType backup --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 605082b2d3..4b6a27e53f 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -60,7 +60,8 @@ abstract class ScheduleBase extends Action $collectionId = match ($schedule->getAttribute('resourceType')) { 'function' => 'functions', - 'message' => 'messages' + 'message' => 'messages', + 'backup' => 'backupsPolicy' }; $resource = $getProjectDB($project)->getDocument( From b5061da8c3cd7dc09251229819acdc483cae521e Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 27 May 2024 17:17:58 +0300 Subject: [PATCH 009/213] add resourceType backup --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 4b6a27e53f..313730e9c2 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -110,7 +110,8 @@ abstract class ScheduleBase extends Action } catch (\Throwable $th) { $collectionId = match ($document->getAttribute('resourceType')) { 'function' => 'functions', - 'message' => 'messages' + 'message' => 'messages', + 'backup' => 'backupsPolicy' }; Console::error("Failed to load schedule for project {$document['projectId']} {$collectionId} {$document['resourceId']}"); From bc62405810fe74abe52f880ef6e218767e214e46 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 27 May 2024 17:42:51 +0300 Subject: [PATCH 010/213] Add debug --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 313730e9c2..ec0022dc79 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -106,6 +106,9 @@ abstract class ScheduleBase extends Action foreach ($results as $document) { try { + var_dump('=== ScheduleBase start'); + var_dump($getSchedule($document)); + var_dump('=== ScheduleBase end'); $this->schedules[$document['resourceId']] = $getSchedule($document); } catch (\Throwable $th) { $collectionId = match ($document->getAttribute('resourceType')) { From f68f21a26419d9568167f0e86d9eb3f0cf277bde Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 27 May 2024 17:53:50 +0300 Subject: [PATCH 011/213] Add debug --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index ec0022dc79..c155f6069c 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -107,7 +107,7 @@ abstract class ScheduleBase extends Action foreach ($results as $document) { try { var_dump('=== ScheduleBase start'); - var_dump($getSchedule($document)); + var_dump($getSchedule($document)['resource']); var_dump('=== ScheduleBase end'); $this->schedules[$document['resourceId']] = $getSchedule($document); } catch (\Throwable $th) { From ddb0ce317533dea708fb32174cccbccadc3d2f15 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 27 May 2024 18:52:33 +0300 Subject: [PATCH 012/213] add destinations --- app/config/collections.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/config/collections.php b/app/config/collections.php index 72d126e343..73dbc9eaa5 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4040,6 +4040,17 @@ $projectCollections = array_merge([ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('destination'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 500, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('credentials'), 'type' => Database::VAR_STRING, From c08d34ead9fd0387d873f2ac594792bd519403fb Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 27 May 2024 18:56:28 +0300 Subject: [PATCH 013/213] add destinations to api's --- app/controllers/api/migrations.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/api/migrations.php b/app/controllers/api/migrations.php index 3899b26ad4..dd65d7600b 100644 --- a/app/controllers/api/migrations.php +++ b/app/controllers/api/migrations.php @@ -60,6 +60,7 @@ App::post('/v1/migrations/appwrite') 'status' => 'pending', 'stage' => 'init', 'source' => Appwrite::getName(), + 'destination' => Appwrite::getName(), 'credentials' => [ 'endpoint' => $endpoint, 'projectId' => $projectId, @@ -164,6 +165,7 @@ App::post('/v1/migrations/firebase/oauth') 'status' => 'pending', 'stage' => 'init', 'source' => Firebase::getName(), + 'destination' => Appwrite::getName(), 'credentials' => [ 'serviceAccount' => json_encode($serviceAccount), ], @@ -224,6 +226,7 @@ App::post('/v1/migrations/firebase') 'status' => 'pending', 'stage' => 'init', 'source' => Firebase::getName(), + 'destination' => Appwrite::getName(), 'credentials' => [ 'serviceAccount' => $serviceAccount, ], @@ -279,6 +282,7 @@ App::post('/v1/migrations/supabase') 'status' => 'pending', 'stage' => 'init', 'source' => Supabase::getName(), + 'destination' => Appwrite::getName(), 'credentials' => [ 'endpoint' => $endpoint, 'apiKey' => $apiKey, @@ -340,6 +344,7 @@ App::post('/v1/migrations/nhost') 'status' => 'pending', 'stage' => 'init', 'source' => NHost::getName(), + 'destination' => Appwrite::getName(), 'credentials' => [ 'subdomain' => $subdomain, 'region' => $region, From bdb73509947e4ab635e191b399c01c45bfc64d3f Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 28 May 2024 19:50:37 +0300 Subject: [PATCH 014/213] change private to protected --- src/Appwrite/Platform/Workers/Migrations.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 8e4aa5216d..0b20607637 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -30,8 +30,8 @@ use Utopia\Queue\Message; class Migrations extends Action { - private ?Database $dbForProject = null; - private ?Database $dbForConsole = null; + protected ?Database $dbForProject = null; + protected ?Database $dbForConsole = null; public static function getName(): string { @@ -93,13 +93,15 @@ class Migrations extends Action } /** - * @param string $source - * @param array $credentials + * @param Document $document * @return Source * @throws Exception */ - protected function processSource(string $source, array $credentials): Source + protected function processSource(Document $document): Source { + $source = $document->getAttribute('source'); + $credentials = $document->getAttribute('credentials'); + return match ($source) { Firebase::getName() => new Firebase( json_decode($credentials['serviceAccount'], true), @@ -263,7 +265,8 @@ class Migrations extends Action $log->addTag('type', $migrationDocument->getAttribute('source')); - $source = $this->processSource($migrationDocument->getAttribute('source'), $migrationDocument->getAttribute('credentials')); + //$source = $this->processSource($migrationDocument->getAttribute('source'), $migrationDocument->getAttribute('credentials')); + $source = $this->processSource($migrationDocument); $source->report(); From 6149f4662114c7b168a9ef3bf8aea06a6a9df3fe Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 28 May 2024 19:59:54 +0300 Subject: [PATCH 015/213] processDestination --- src/Appwrite/Platform/Workers/Migrations.php | 22 +++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 0b20607637..870cf78331 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -6,6 +6,7 @@ use Appwrite\Event\Event; use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Permission; use Appwrite\Role; +use Appwrite\Utopia\Migration\Destinations\Backup; use Exception; use Utopia\CLI\Console; use Utopia\Database\Database; @@ -17,7 +18,8 @@ use Utopia\Database\Exception\Structure; use Utopia\Database\Helpers\ID; use Utopia\Logger\Log; use Utopia\Logger\Log\Breadcrumb; -use Utopia\Migration\Destinations\Appwrite as DestinationsAppwrite; +use Utopia\Migration\Destination; +use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite; use Utopia\Migration\Exception as MigrationException; use Utopia\Migration\Source; use Utopia\Migration\Sources\Appwrite; @@ -129,6 +131,24 @@ class Migrations extends Action }; } + /** + * @param string $destination + * @param array $credentials + * @return Destination + * @throws Exception + */ + protected function processDestination(string $destination, array $credentials): Destination + { + return match ($destination) { + DestinationAppwrite::getName() => new DestinationAppwrite( + $credentials['projectId'], + str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], + $credentials['apiKey'] + ), + default => throw new \Exception('Invalid destination type'), + }; + } + /** * @throws Authorization * @throws Structure From 73280fd173e312e38beac68fd44cc9733d2cbcf7 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 28 May 2024 20:05:36 +0300 Subject: [PATCH 016/213] processSource --- src/Appwrite/Platform/Workers/Migrations.php | 29 ++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 870cf78331..da33970bc5 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -95,15 +95,13 @@ class Migrations extends Action } /** - * @param Document $document + * @param string $source + * @param array $credentials * @return Source * @throws Exception */ - protected function processSource(Document $document): Source + protected function processSource(string $source, array $credentials): Source { - $source = $document->getAttribute('source'); - $credentials = $document->getAttribute('credentials'); - return match ($source) { Firebase::getName() => new Firebase( json_decode($credentials['serviceAccount'], true), @@ -126,7 +124,11 @@ class Migrations extends Action $credentials['password'], $credentials['port'], ), - Appwrite::getName() => new Appwrite($credentials['projectId'], str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], $credentials['apiKey']), + Appwrite::getName() => new Appwrite( + $credentials['projectId'], + str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], + $credentials['apiKey'] + ), default => throw new \Exception('Invalid source type'), }; } @@ -285,8 +287,19 @@ class Migrations extends Action $log->addTag('type', $migrationDocument->getAttribute('source')); - //$source = $this->processSource($migrationDocument->getAttribute('source'), $migrationDocument->getAttribute('credentials')); - $source = $this->processSource($migrationDocument); + $source = $this->processSource( + $migrationDocument->getAttribute('source'), + $migrationDocument->getAttribute('credentials') + ); + + $destination = $this->processDestination( + $migrationDocument->getAttribute('destination'), + [ + 'projectId' => $projectDocument->getId(), + 'endpoint' => 'http://appwrite/v1', + 'apiKey' => $tempAPIKey['secret'] + ] + ); $source->report(); From 75ec86eed487de5224acdfa6b6e273a9cac05fda Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 28 May 2024 20:12:58 +0300 Subject: [PATCH 017/213] SourceAppwrite --- src/Appwrite/Platform/Workers/Migrations.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index da33970bc5..13f53277ee 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -20,6 +20,7 @@ use Utopia\Logger\Log; use Utopia\Logger\Log\Breadcrumb; use Utopia\Migration\Destination; use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite; +use Utopia\Migration\Sources\Appwrite as SourceAppwrite; use Utopia\Migration\Exception as MigrationException; use Utopia\Migration\Source; use Utopia\Migration\Sources\Appwrite; @@ -124,7 +125,7 @@ class Migrations extends Action $credentials['password'], $credentials['port'], ), - Appwrite::getName() => new Appwrite( + SourceAppwrite::getName() => new SourceAppwrite( $credentials['projectId'], str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], $credentials['apiKey'] @@ -303,12 +304,6 @@ class Migrations extends Action $source->report(); - $destination = new DestinationsAppwrite( - $projectDocument->getId(), - 'http://appwrite/v1', - $tempAPIKey['secret'], - ); - $transfer = new Transfer( $source, $destination From d503a436d02a99ea123c7c4adcdf42664b6c90b7 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 28 May 2024 20:37:37 +0300 Subject: [PATCH 018/213] add project --- src/Appwrite/Platform/Workers/Migrations.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 13f53277ee..dc8db4d626 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -33,8 +33,9 @@ use Utopia\Queue\Message; class Migrations extends Action { - protected ?Database $dbForProject = null; - protected ?Database $dbForConsole = null; + protected Database $dbForProject; + protected Database $dbForConsole; + protected Document $project; public static function getName(): string { @@ -81,6 +82,7 @@ class Migrations extends Action $this->dbForProject = $dbForProject; $this->dbForConsole = $dbForConsole; + $this->project = $project; /** * Handle Event execution. @@ -92,7 +94,7 @@ class Migrations extends Action $log->addTag('migrationId', $migration->getId()); $log->addTag('projectId', $project->getId()); - $this->processMigration($project, $migration, $log); + $this->processMigration($migration, $log); } /** @@ -268,14 +270,9 @@ class Migrations extends Action * @throws Structure * @throws \Utopia\Database\Exception */ - protected function processMigration(Document $project, Document $migration, Log $log): void + protected function processMigration(Document $migration, Log $log): void { - /** - * @var Document $migrationDocument - * @var Transfer $transfer - */ - $migrationDocument = null; - $transfer = null; + $project = $this->project; $projectDocument = $this->dbForConsole->getDocument('projects', $project->getId()); $tempAPIKey = $this->generateAPIKey($projectDocument); From 68f5947b40a08219dbb97dfffbbfbb24b6351eb6 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 28 May 2024 20:40:57 +0300 Subject: [PATCH 019/213] Remove backup --- src/Appwrite/Platform/Workers/Migrations.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index dc8db4d626..db2b778834 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -6,7 +6,6 @@ use Appwrite\Event\Event; use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Permission; use Appwrite\Role; -use Appwrite\Utopia\Migration\Destinations\Backup; use Exception; use Utopia\CLI\Console; use Utopia\Database\Database; @@ -23,7 +22,6 @@ use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite; use Utopia\Migration\Sources\Appwrite as SourceAppwrite; use Utopia\Migration\Exception as MigrationException; use Utopia\Migration\Source; -use Utopia\Migration\Sources\Appwrite; use Utopia\Migration\Sources\Firebase; use Utopia\Migration\Sources\NHost; use Utopia\Migration\Sources\Supabase; From 15ffce36de414d5fc70bfceb1b3dc455333ed3d3 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 28 May 2024 20:52:32 +0300 Subject: [PATCH 020/213] add hooks --- src/Appwrite/Platform/Workers/Migrations.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index db2b778834..4782de001e 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -308,6 +308,9 @@ class Migrations extends Action $migrationDocument->setAttribute('stage', 'migrating'); $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'migrating'", \microtime(true))); $this->updateMigrationDocument($migrationDocument, $projectDocument); + + $destination->init(); + $transfer->run($migrationDocument->getAttribute('resources'), function () use ($migrationDocument, $transfer, $projectDocument) { $migrationDocument->setAttribute('resourceData', json_encode($transfer->getCache())); $migrationDocument->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); @@ -315,6 +318,8 @@ class Migrations extends Action $this->updateMigrationDocument($migrationDocument, $projectDocument); }); + $destination->shutDown(); + $sourceErrors = $source->getErrors(); $destinationErrors = $destination->getErrors(); From 3ebbc5976fe85836ea32cc6778ba6da3578d909c Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 May 2024 11:31:00 +0300 Subject: [PATCH 021/213] hint update --- src/Appwrite/Platform/Workers/Migrations.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 4782de001e..3d955cc757 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -258,7 +258,6 @@ class Migrations extends Action } /** - * @param Document $project * @param Document $migration * @param Log $log * @return void From 97703b03320680f4b0206071884332dfdcef0a42 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 May 2024 18:16:29 +0300 Subject: [PATCH 022/213] Question --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index c155f6069c..5dbc52f886 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -153,6 +153,7 @@ abstract class ScheduleBase extends Action $paginationQueries[] = Query::cursorAfter($latestDocument); } + // do we need add query active = 1? $results = $dbForConsole->find('schedules', \array_merge($paginationQueries, [ Query::equal('region', [System::getEnv('_APP_REGION', 'default')]), Query::equal('resourceType', [static::getSupportedResource()]), From 07bfe3823c6f6033f3d4f7cc44064a20dd2c6df3 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 May 2024 18:59:10 +0300 Subject: [PATCH 023/213] getCollectionId --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 1 + src/Appwrite/Platform/Tasks/ScheduleFunctions.php | 5 +++++ src/Appwrite/Platform/Tasks/ScheduleMessages.php | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 5dbc52f886..af7fe9d221 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -24,6 +24,7 @@ abstract class ScheduleBase extends Action abstract public static function getName(): string; abstract public static function getSupportedResource(): string; + abstract public static function getCollectionId(): string; abstract protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB):void; public function __construct() diff --git a/src/Appwrite/Platform/Tasks/ScheduleFunctions.php b/src/Appwrite/Platform/Tasks/ScheduleFunctions.php index 98a935876a..4d57902330 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleFunctions.php +++ b/src/Appwrite/Platform/Tasks/ScheduleFunctions.php @@ -26,6 +26,11 @@ class ScheduleFunctions extends ScheduleBase return 'function'; } + public static function getCollectionId(): string + { + return 'functions'; + } + protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void { $timerStart = \microtime(true); diff --git a/src/Appwrite/Platform/Tasks/ScheduleMessages.php b/src/Appwrite/Platform/Tasks/ScheduleMessages.php index ac2eaa3302..5629979dce 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleMessages.php +++ b/src/Appwrite/Platform/Tasks/ScheduleMessages.php @@ -21,6 +21,11 @@ class ScheduleMessages extends ScheduleBase return 'message'; } + public static function getCollectionId(): string + { + return 'messages'; + } + protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void { foreach ($this->schedules as $schedule) { From 5764ea9ade2691302ce2cee4340f74fff3cd3f98 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 May 2024 19:09:14 +0300 Subject: [PATCH 024/213] static getCollectionId --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index af7fe9d221..e06873e825 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -59,14 +59,8 @@ abstract class ScheduleBase extends Action $getSchedule = function (Document $schedule) use ($dbForConsole, $getProjectDB): array { $project = $dbForConsole->getDocument('projects', $schedule->getAttribute('projectId')); - $collectionId = match ($schedule->getAttribute('resourceType')) { - 'function' => 'functions', - 'message' => 'messages', - 'backup' => 'backupsPolicy' - }; - $resource = $getProjectDB($project)->getDocument( - $collectionId, + static::getCollectionId(), $schedule->getAttribute('resourceId') ); @@ -112,12 +106,7 @@ abstract class ScheduleBase extends Action var_dump('=== ScheduleBase end'); $this->schedules[$document['resourceId']] = $getSchedule($document); } catch (\Throwable $th) { - $collectionId = match ($document->getAttribute('resourceType')) { - 'function' => 'functions', - 'message' => 'messages', - 'backup' => 'backupsPolicy' - }; - + $collectionId = static::getCollectionId(); Console::error("Failed to load schedule for project {$document['projectId']} {$collectionId} {$document['resourceId']}"); Console::error($th->getMessage()); } From ed0995fa49d57e04c5d4c2f31ba0316c8bd0c0fb Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 May 2024 19:26:44 +0300 Subject: [PATCH 025/213] Fix bug? --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index e06873e825..2e1e673bf4 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -143,7 +143,6 @@ abstract class ScheduleBase extends Action $paginationQueries[] = Query::cursorAfter($latestDocument); } - // do we need add query active = 1? $results = $dbForConsole->find('schedules', \array_merge($paginationQueries, [ Query::equal('region', [System::getEnv('_APP_REGION', 'default')]), Query::equal('resourceType', [static::getSupportedResource()]), @@ -154,7 +153,8 @@ abstract class ScheduleBase extends Action $total = $total + $sum; foreach ($results as $document) { - $localDocument = $schedules[$document['resourceId']] ?? null; + // todo: change this to Internal id or add projectId as + $localDocument = $this->schedules[$document['resourceId']] ?? null; // Check if resource has been updated since last sync $org = $localDocument !== null ? \strtotime($localDocument['resourceUpdatedAt']) : null; From d000c160b65730d9de3837fd2811e00376b35c23 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 May 2024 19:29:03 +0300 Subject: [PATCH 026/213] Fix bug? --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 2e1e673bf4..1c8eb8f7db 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -153,7 +153,7 @@ abstract class ScheduleBase extends Action $total = $total + $sum; foreach ($results as $document) { - // todo: change this to Internal id or add projectId as + // todo: change resourceId to Internal id or add projectId as second nested key $localDocument = $this->schedules[$document['resourceId']] ?? null; // Check if resource has been updated since last sync From 26c714da481258759e1431ec803880918e1e71fb Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 29 May 2024 19:30:52 +0300 Subject: [PATCH 027/213] dbg --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 1c8eb8f7db..ab37849faf 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -59,6 +59,10 @@ abstract class ScheduleBase extends Action $getSchedule = function (Document $schedule) use ($dbForConsole, $getProjectDB): array { $project = $dbForConsole->getDocument('projects', $schedule->getAttribute('projectId')); + var_dump('===== $getSchedule getCollectionId = '); + var_dump(static::getCollectionId()); + var_dump('===== $getSchedule getCollectionId = '); + $resource = $getProjectDB($project)->getDocument( static::getCollectionId(), $schedule->getAttribute('resourceId') From abde5393df9d88f437dc7decf57813f5a2dc016b Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Jun 2024 16:18:40 +0300 Subject: [PATCH 028/213] Set Archive --- src/Appwrite/Event/Migration.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Appwrite/Event/Migration.php b/src/Appwrite/Event/Migration.php index 1bba6e6180..29ce2c2716 100644 --- a/src/Appwrite/Event/Migration.php +++ b/src/Appwrite/Event/Migration.php @@ -10,7 +10,8 @@ class Migration extends Event { protected string $type = ''; protected ?Document $migration = null; - protected ?Document $backup; + protected ?Document $archive = null; + protected ?Document $backup = null; public function __construct(protected Connection $connection) { @@ -35,14 +36,14 @@ class Migration extends Event } /** - * Sets backup. + * Sets archive * - * @param Document $backup + * @param Document $archive * @return self */ - public function setBackup(Document $backup): self + public function setArchive(Document $archive): self { - $this->backup = $backup; + $this->archive = $archive; return $this; } @@ -96,7 +97,7 @@ class Migration extends Event 'project' => $this->project, 'user' => $this->user, 'migration' => $this->migration, - 'backup' => $this->backup + 'archive' => $this->archive ]); } } From 0e33fb2b64bb845f26d6dfe53d6a9c7699a8df98 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Jun 2024 16:19:02 +0300 Subject: [PATCH 029/213] remove $backup --- src/Appwrite/Event/Migration.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Appwrite/Event/Migration.php b/src/Appwrite/Event/Migration.php index 29ce2c2716..c5af751a6b 100644 --- a/src/Appwrite/Event/Migration.php +++ b/src/Appwrite/Event/Migration.php @@ -11,7 +11,6 @@ class Migration extends Event protected string $type = ''; protected ?Document $migration = null; protected ?Document $archive = null; - protected ?Document $backup = null; public function __construct(protected Connection $connection) { From d5025e7db37f350efdd95b08efacf328d9bde871 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Jun 2024 16:59:23 +0300 Subject: [PATCH 030/213] add todo --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index ab37849faf..392d232f8b 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -108,6 +108,7 @@ abstract class ScheduleBase extends Action var_dump('=== ScheduleBase start'); var_dump($getSchedule($document)['resource']); var_dump('=== ScheduleBase end'); + //todo: use a unique key as InternalId or add projectId $this->schedules[$document['resourceId']] = $getSchedule($document); } catch (\Throwable $th) { $collectionId = static::getCollectionId(); From 25b661b908ed3e05b320e4cf2f0346b0bee712e1 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Jun 2024 17:15:17 +0300 Subject: [PATCH 031/213] Move Archive event to cloud --- src/Appwrite/Event/Migration.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/Appwrite/Event/Migration.php b/src/Appwrite/Event/Migration.php index c5af751a6b..e57ac3c87c 100644 --- a/src/Appwrite/Event/Migration.php +++ b/src/Appwrite/Event/Migration.php @@ -10,7 +10,6 @@ class Migration extends Event { protected string $type = ''; protected ?Document $migration = null; - protected ?Document $archive = null; public function __construct(protected Connection $connection) { @@ -34,19 +33,6 @@ class Migration extends Event return $this; } - /** - * Sets archive - * - * @param Document $archive - * @return self - */ - public function setArchive(Document $archive): self - { - $this->archive = $archive; - - return $this; - } - /** * Returns set migration document for the function event. * @@ -96,7 +82,6 @@ class Migration extends Event 'project' => $this->project, 'user' => $this->user, 'migration' => $this->migration, - 'archive' => $this->archive ]); } } From b23f7b0725824d9fcce1f7ccce77deef6c3da868 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Jun 2024 19:25:49 +0300 Subject: [PATCH 032/213] Revert archive --- src/Appwrite/Event/Migration.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Appwrite/Event/Migration.php b/src/Appwrite/Event/Migration.php index e57ac3c87c..c33e8ec767 100644 --- a/src/Appwrite/Event/Migration.php +++ b/src/Appwrite/Event/Migration.php @@ -10,6 +10,7 @@ class Migration extends Event { protected string $type = ''; protected ?Document $migration = null; + protected ?Document $archive = null; public function __construct(protected Connection $connection) { @@ -82,6 +83,20 @@ class Migration extends Event 'project' => $this->project, 'user' => $this->user, 'migration' => $this->migration, + 'archive' => $this->archive ]); } + + /** + * Sets archive + * + * @param Document $archive + * @return self + */ + public function setArchive(Document $archive): self + { + $this->archive = $archive; + + return $this; + } } From 91cc3a3ff5478bf0c239fae925b171fea2024884 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Jun 2024 19:36:41 +0300 Subject: [PATCH 033/213] Remove archive --- src/Appwrite/Event/Migration.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/Appwrite/Event/Migration.php b/src/Appwrite/Event/Migration.php index c33e8ec767..e57ac3c87c 100644 --- a/src/Appwrite/Event/Migration.php +++ b/src/Appwrite/Event/Migration.php @@ -10,7 +10,6 @@ class Migration extends Event { protected string $type = ''; protected ?Document $migration = null; - protected ?Document $archive = null; public function __construct(protected Connection $connection) { @@ -83,20 +82,6 @@ class Migration extends Event 'project' => $this->project, 'user' => $this->user, 'migration' => $this->migration, - 'archive' => $this->archive ]); } - - /** - * Sets archive - * - * @param Document $archive - * @return self - */ - public function setArchive(Document $archive): self - { - $this->archive = $archive; - - return $this; - } } From 82be39af3d08778cd3787df418abd25e834b3365 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Jun 2024 15:14:56 +0300 Subject: [PATCH 034/213] Update cache --- composer.json | 2 +- composer.lock | 105 +++++++++++++++++++++++++------------------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/composer.json b/composer.json index 205fe308f0..c847612f65 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "utopia-php/abuse": "0.37.*", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.39.*", - "utopia-php/cache": "0.9.*", + "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", "utopia-php/database": "0.49.*", diff --git a/composer.lock b/composer.lock index bfe8fc0730..64b9f59d21 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "53996479cd4ba0c73dbc72d46b240be0", + "content-hash": "44dc3f42d5df8bab8d3e45ff631f384d", "packages": [ { "name": "adhocore/jwt", @@ -1427,16 +1427,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.0", + "version": "0.37.1", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062" + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/2de5c12886cbd516e511e559afdd9e615d871062", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981", + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981", "shasum": "" }, "require": { @@ -1470,9 +1470,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.0" + "source": "https://github.com/utopia-php/abuse/tree/0.37.1" }, - "time": "2024-03-06T21:20:27+00:00" + "time": "2024-06-05T18:03:59+00:00" }, { "name": "utopia-php/analytics", @@ -1522,16 +1522,16 @@ }, { "name": "utopia-php/audit", - "version": "0.39.0", + "version": "0.39.1", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c" + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/f0bc15012e05cc0b9dde012ab27d25f193768a2c", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2", + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2", "shasum": "" }, "require": { @@ -1563,22 +1563,22 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.0" + "source": "https://github.com/utopia-php/audit/tree/0.39.1" }, - "time": "2024-03-06T21:20:37+00:00" + "time": "2024-06-05T19:28:22+00:00" }, { "name": "utopia-php/cache", - "version": "0.9.1", + "version": "0.10.0", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6" + "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/552b4c554bb14d0c529631ce304cdf4a2b9d06a6", - "reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/313bcdfbb166f75c2c205a59d1467cead63a9626", + "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626", "shasum": "" }, "require": { @@ -1613,9 +1613,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.9.1" + "source": "https://github.com/utopia-php/cache/tree/0.10.0" }, - "time": "2024-03-19T17:07:20+00:00" + "time": "2024-06-05T16:40:43+00:00" }, { "name": "utopia-php/cli", @@ -1719,23 +1719,23 @@ }, { "name": "utopia-php/database", - "version": "0.49.10", + "version": "0.49.12", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec" + "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/216209121bc97a2010f67a39c561fafe1e936bec", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec", + "url": "https://api.github.com/repos/utopia-php/database/zipball/45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", + "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", "shasum": "" }, "require": { "ext-mbstring": "*", "ext-pdo": "*", "php": ">=8.0", - "utopia-php/cache": "0.9.*", + "utopia-php/cache": "0.10.*", "utopia-php/framework": "0.33.*", "utopia-php/mongo": "0.3.*" }, @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.10" + "source": "https://github.com/utopia-php/database/tree/0.49.12" }, - "time": "2024-05-20T02:14:20+00:00" + "time": "2024-06-05T16:52:59+00:00" }, { "name": "utopia-php/domains", @@ -2755,22 +2755,22 @@ }, { "name": "utopia-php/vcs", - "version": "0.6.6", + "version": "0.6.7", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4" + "reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/e538264cfee5e3efdfe1771efba04750cf20b2c4", - "reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974", + "reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", - "utopia-php/cache": "^0.9.0", + "utopia-php/cache": "^0.10.0", "utopia-php/framework": "0.*.*" }, "require-dev": { @@ -2798,9 +2798,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.6.6" + "source": "https://github.com/utopia-php/vcs/tree/0.6.7" }, - "time": "2024-05-17T09:36:30+00:00" + "time": "2024-06-05T17:38:29+00:00" }, { "name": "utopia-php/websocket", @@ -2987,16 +2987,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.38.6", + "version": "0.38.7", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699" + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", "shasum": "" }, "require": { @@ -3032,9 +3032,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.6" + "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" }, - "time": "2024-05-20T18:00:16+00:00" + "time": "2024-06-10T00:23:02+00:00" }, { "name": "doctrine/deprecations", @@ -3345,16 +3345,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -3362,11 +3362,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -3392,7 +3393,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -3400,7 +3401,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "nikic/php-parser", @@ -3824,16 +3825,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.0", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { @@ -3865,9 +3866,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2024-05-06T12:04:23+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "phpunit/php-code-coverage", From 2c80823d96304dfe86e1a6c6703905404fde27e2 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Jun 2024 18:26:13 +0300 Subject: [PATCH 035/213] composer.lock --- composer.lock | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index aee6c86d53..b9c45b149f 100644 --- a/composer.lock +++ b/composer.lock @@ -2988,16 +2988,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.38.6", + "version": "0.38.7", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699" + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", "shasum": "" }, "require": { @@ -3033,9 +3033,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.6" + "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" }, - "time": "2024-05-20T18:00:16+00:00" + "time": "2024-06-10T00:23:02+00:00" }, { "name": "doctrine/deprecations", @@ -3346,16 +3346,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -3363,11 +3363,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -3393,7 +3394,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -3401,7 +3402,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "nikic/php-parser", From e58033aff0932266be363ad473541398d8a04e69 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Jun 2024 19:03:51 +0300 Subject: [PATCH 036/213] Downgrade utopia-php/platform to 0.5 --- composer.json | 2 +- composer.lock | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 192b311822..9ba8db0e09 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "utopia-php/messaging": "0.12.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", - "utopia-php/platform": "0.7.*", + "utopia-php/platform": "0.5.*", "utopia-php/pools": "0.5.*", "utopia-php/preloader": "0.2.*", "utopia-php/queue": "0.7.*", diff --git a/composer.lock b/composer.lock index b9c45b149f..c86e058a8c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e002600539435ca8eaaace6e73b4004d", + "content-hash": "9ba1190efa21ae307532896397b3228d", "packages": [ { "name": "adhocore/jwt", @@ -2327,16 +2327,16 @@ }, { "name": "utopia-php/platform", - "version": "0.7.0", + "version": "0.5.2", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52" + "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", - "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/b9feabc79b92dc2b05683a986ad43bce5c1583e3", + "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3", "shasum": "" }, "require": { @@ -2344,8 +2344,7 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.33.*", - "utopia-php/queue": "0.7.*" + "utopia-php/framework": "0.33.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2371,9 +2370,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.7.0" + "source": "https://github.com/utopia-php/platform/tree/0.5.2" }, - "time": "2024-05-08T17:00:55+00:00" + "time": "2024-05-22T12:50:35+00:00" }, { "name": "utopia-php/pools", From 610edc95848da1fb0084e77b12e3a63cd0a8a8ed Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 16 Jun 2024 09:52:53 +0300 Subject: [PATCH 037/213] composer.lock --- composer.json | 2 +- composer.lock | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 9ba8db0e09..192b311822 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "utopia-php/messaging": "0.12.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", - "utopia-php/platform": "0.5.*", + "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", "utopia-php/preloader": "0.2.*", "utopia-php/queue": "0.7.*", diff --git a/composer.lock b/composer.lock index c86e058a8c..b9c45b149f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9ba1190efa21ae307532896397b3228d", + "content-hash": "e002600539435ca8eaaace6e73b4004d", "packages": [ { "name": "adhocore/jwt", @@ -2327,16 +2327,16 @@ }, { "name": "utopia-php/platform", - "version": "0.5.2", + "version": "0.7.0", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3" + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/b9feabc79b92dc2b05683a986ad43bce5c1583e3", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", "shasum": "" }, "require": { @@ -2344,7 +2344,8 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.33.*" + "utopia-php/framework": "0.33.*", + "utopia-php/queue": "0.7.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2370,9 +2371,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.2" + "source": "https://github.com/utopia-php/platform/tree/0.7.0" }, - "time": "2024-05-22T12:50:35+00:00" + "time": "2024-05-08T17:00:55+00:00" }, { "name": "utopia-php/pools", From d39060e0a8740b9dc871cdddeb1ef10b9b4a9fd5 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 16 Jun 2024 12:49:34 +0300 Subject: [PATCH 038/213] getDevice --- app/init.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/init.php b/app/init.php index c201c0b4a3..04836b0ea1 100644 --- a/app/init.php +++ b/app/init.php @@ -1451,9 +1451,9 @@ App::setResource('deviceForBuilds', function ($project) { return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId()); }, ['project']); -function getDevice(string $root, ?string $connection = null): Device +function getDevice(string $root, string $connection = ''): Device { - $connection = empty($connection) ? System::getEnv('_APP_CONNECTIONS_STORAGE', '') : System::getEnv($connection, ''); + $connection = !empty($connection) ? $connection : System::getEnv('_APP_CONNECTIONS_STORAGE', ''); if (!empty($connection)) { $acl = 'private'; From f1bff1b62cc3bbce200e04349099be5cdbb4f1e6 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 11:09:37 +0300 Subject: [PATCH 039/213] add migrations document --- src/Appwrite/Platform/Workers/Migrations.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 3d955cc757..cdaefe41fc 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -34,6 +34,7 @@ class Migrations extends Action protected Database $dbForProject; protected Database $dbForConsole; protected Document $project; + protected Document $migration; public static function getName(): string { @@ -81,6 +82,7 @@ class Migrations extends Action $this->dbForProject = $dbForProject; $this->dbForConsole = $dbForConsole; $this->project = $project; + $this->migration = $migration; /** * Handle Event execution. From ec71fb22de19a973eeb1e5b48d137e0abb913ed9 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 11:45:07 +0300 Subject: [PATCH 040/213] Change processSource processDestination params --- src/Appwrite/Platform/Workers/Migrations.php | 35 ++++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index cdaefe41fc..19fd92e3fe 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -98,13 +98,15 @@ class Migrations extends Action } /** - * @param string $source - * @param array $credentials + * @param Document $migration * @return Source * @throws Exception */ - protected function processSource(string $source, array $credentials): Source + protected function processSource(Document $migration): Source { + $source = $migration->getAttribute('source'); + $credentials = $migration->getAttribute('credentials'); + return match ($source) { Firebase::getName() => new Firebase( json_decode($credentials['serviceAccount'], true), @@ -137,13 +139,15 @@ class Migrations extends Action } /** - * @param string $destination + * @param Document $migration * @param array $credentials * @return Destination * @throws Exception */ - protected function processDestination(string $destination, array $credentials): Destination + protected function processDestination(Document $migration, array $credentials): Destination { + $destination = $migration->getAttribute('destination'); + return match ($destination) { DestinationAppwrite::getName() => new DestinationAppwrite( $credentials['projectId'], @@ -284,19 +288,30 @@ class Migrations extends Action $log->addTag('type', $migrationDocument->getAttribute('source')); - $source = $this->processSource( - $migrationDocument->getAttribute('source'), - $migrationDocument->getAttribute('credentials') - ); + $source = $this->processSource($migrationDocument); $destination = $this->processDestination( - $migrationDocument->getAttribute('destination'), + $migrationDocument, [ 'projectId' => $projectDocument->getId(), 'endpoint' => 'http://appwrite/v1', 'apiKey' => $tempAPIKey['secret'] ] ); +// +// $source = $this->processSource( +// $migrationDocument->getAttribute('source'), +// $migrationDocument->getAttribute('credentials') +// ); +// +// $destination = $this->processDestination( +// $migrationDocument->getAttribute('destination'), +// [ +// 'projectId' => $projectDocument->getId(), +// 'endpoint' => 'http://appwrite/v1', +// 'apiKey' => $tempAPIKey['secret'] +// ] +// ); $source->report(); From 2d1299bb468de55ccca633e8d6a1603b83d8a39b Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 11:46:32 +0300 Subject: [PATCH 041/213] Remove migration --- src/Appwrite/Platform/Workers/Migrations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 19fd92e3fe..458d19ca84 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -34,7 +34,7 @@ class Migrations extends Action protected Database $dbForProject; protected Database $dbForConsole; protected Document $project; - protected Document $migration; + //protected Document $migration; public static function getName(): string { @@ -82,7 +82,7 @@ class Migrations extends Action $this->dbForProject = $dbForProject; $this->dbForConsole = $dbForConsole; $this->project = $project; - $this->migration = $migration; + //$this->migration = $migration; /** * Handle Event execution. From 2ba6916e535c11665634d35c8de92dd815eb59f2 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 12:03:32 +0300 Subject: [PATCH 042/213] Undefineds --- src/Appwrite/Platform/Workers/Migrations.php | 74 ++++++++++---------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 458d19ca84..9f6ba39df8 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -272,26 +272,28 @@ class Migrations extends Action * @throws Restricted * @throws Structure * @throws \Utopia\Database\Exception + * @throws Exception */ protected function processMigration(Document $migration, Log $log): void { $project = $this->project; $projectDocument = $this->dbForConsole->getDocument('projects', $project->getId()); $tempAPIKey = $this->generateAPIKey($projectDocument); + $transfer = $source = $destination = null; try { - $migrationDocument = $this->dbForProject->getDocument('migrations', $migration->getId()); - $migrationDocument->setAttribute('stage', 'processing'); - $migrationDocument->setAttribute('status', 'processing'); + $migration = $this->dbForProject->getDocument('migrations', $migration->getId()); + $migration->setAttribute('stage', 'processing'); + $migration->setAttribute('status', 'processing'); $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'processing'", \microtime(true))); - $this->updateMigrationDocument($migrationDocument, $projectDocument); + $this->updateMigrationDocument($migration, $projectDocument); - $log->addTag('type', $migrationDocument->getAttribute('source')); + $log->addTag('type', $migration->getAttribute('source')); - $source = $this->processSource($migrationDocument); + $source = $this->processSource($migration); $destination = $this->processDestination( - $migrationDocument, + $migration, [ 'projectId' => $projectDocument->getId(), 'endpoint' => 'http://appwrite/v1', @@ -300,12 +302,12 @@ class Migrations extends Action ); // // $source = $this->processSource( -// $migrationDocument->getAttribute('source'), -// $migrationDocument->getAttribute('credentials') +// $migration->getAttribute('source'), +// $migration->getAttribute('credentials') // ); // // $destination = $this->processDestination( -// $migrationDocument->getAttribute('destination'), +// $migration->getAttribute('destination'), // [ // 'projectId' => $projectDocument->getId(), // 'endpoint' => 'http://appwrite/v1', @@ -321,17 +323,17 @@ class Migrations extends Action ); /** Start Transfer */ - $migrationDocument->setAttribute('stage', 'migrating'); + $migration->setAttribute('stage', 'migrating'); $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'migrating'", \microtime(true))); - $this->updateMigrationDocument($migrationDocument, $projectDocument); + $this->updateMigrationDocument($migration, $projectDocument); $destination->init(); - $transfer->run($migrationDocument->getAttribute('resources'), function () use ($migrationDocument, $transfer, $projectDocument) { - $migrationDocument->setAttribute('resourceData', json_encode($transfer->getCache())); - $migrationDocument->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); + $transfer->run($migration->getAttribute('resources'), function () use ($migration, $transfer, $projectDocument) { + $migration->setAttribute('resourceData', json_encode($transfer->getCache())); + $migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); - $this->updateMigrationDocument($migrationDocument, $projectDocument); + $this->updateMigrationDocument($migration, $projectDocument); }); $destination->shutDown(); @@ -340,8 +342,8 @@ class Migrations extends Action $destinationErrors = $destination->getErrors(); if (!empty($sourceErrors) || !empty($destinationErrors)) { - $migrationDocument->setAttribute('status', 'failed'); - $migrationDocument->setAttribute('stage', 'finished'); + $migration->setAttribute('status', 'failed'); + $migration->setAttribute('stage', 'finished'); $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'finished' and failed", \microtime(true))); $errorMessages = []; @@ -354,25 +356,26 @@ class Migrations extends Action $errorMessages[] = "Error occurred while pushing '{$error->getResourceType()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; } - $migrationDocument->setAttribute('errors', $errorMessages); + $migration->setAttribute('errors', $errorMessages); $log->addExtra('migrationErrors', json_encode($errorMessages)); - $this->updateMigrationDocument($migrationDocument, $projectDocument); + $this->updateMigrationDocument($migration, $projectDocument); return; } - $migrationDocument->setAttribute('status', 'completed'); - $migrationDocument->setAttribute('stage', 'finished'); + $migration->setAttribute('status', 'completed'); + $migration->setAttribute('stage', 'finished'); $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'finished' and succeeded", \microtime(true))); } catch (\Throwable $th) { - Console::error($th->getMessage()); - if ($migrationDocument) { - Console::error($th->getMessage()); - Console::error($th->getTraceAsString()); - $migrationDocument->setAttribute('status', 'failed'); - $migrationDocument->setAttribute('stage', 'finished'); - $migrationDocument->setAttribute('errors', [$th->getMessage()]); + Console::error($th->getMessage()); + Console::error($th->getMessage()); + Console::error($th->getTraceAsString()); + + if (!$migration->isEmpty()) { + $migration->setAttribute('status', 'failed'); + $migration->setAttribute('stage', 'finished'); + $migration->setAttribute('errors', [$th->getMessage()]); return; } @@ -391,19 +394,18 @@ class Migrations extends Action $errorMessages[] = "Error occurred while pushing '{$error->getResourceType()}:{$error->getResourceId()}' to destination with message '{$error->getMessage()}'"; } - $migrationDocument->setAttribute('errors', $errorMessages); + $migration->setAttribute('errors', $errorMessages); $log->addTag('migrationErrors', json_encode($errorMessages)); } } finally { - if ($tempAPIKey) { + if (!$tempAPIKey->isEmpty()) { $this->removeAPIKey($tempAPIKey); } - if ($migrationDocument) { - $this->updateMigrationDocument($migrationDocument, $projectDocument); - if ($migrationDocument->getAttribute('status', '') == 'failed') { - throw new Exception("Migration failed"); - } + $this->updateMigrationDocument($migration, $projectDocument); + + if ($migration->getAttribute('status', '') == 'failed') { + throw new Exception("Migration failed"); } } } From ef6bc042fdba042ff01ddf07feeac52319b1a00d Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 13:11:21 +0300 Subject: [PATCH 043/213] Migrations 0.4.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 192b311822..7de6b86d67 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "0.4.*", + "utopia-php/migration": "dev-backups as 0.4.4", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From e457ed194f2b76b91d303660edacf3c1e3864b16 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 13:13:56 +0300 Subject: [PATCH 044/213] Minimum stable --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7de6b86d67..db9d5ca953 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "dev-backups as 0.4.4", + "utopia-php/migration": "dev-backups as 1.4.4", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From 33a3674989164b1b264ab51346caed0616bba490 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 13:14:57 +0300 Subject: [PATCH 045/213] 0.4.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index db9d5ca953..7de6b86d67 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "dev-backups as 1.4.4", + "utopia-php/migration": "dev-backups as 0.4.4", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From b31a1e25847f195ad607036e3353ba56d95ecb3e Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 13:17:14 +0300 Subject: [PATCH 046/213] Remove comments --- src/Appwrite/Platform/Workers/Migrations.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 9f6ba39df8..dff23e7802 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -300,20 +300,6 @@ class Migrations extends Action 'apiKey' => $tempAPIKey['secret'] ] ); -// -// $source = $this->processSource( -// $migration->getAttribute('source'), -// $migration->getAttribute('credentials') -// ); -// -// $destination = $this->processDestination( -// $migration->getAttribute('destination'), -// [ -// 'projectId' => $projectDocument->getId(), -// 'endpoint' => 'http://appwrite/v1', -// 'apiKey' => $tempAPIKey['secret'] -// ] -// ); $source->report(); From 4c4b95a39f384877e700d8c4212be451a8923d96 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 13:19:44 +0300 Subject: [PATCH 047/213] composer.lock --- composer.lock | 87 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/composer.lock b/composer.lock index b9c45b149f..e8e687c455 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e002600539435ca8eaaace6e73b4004d", + "content-hash": "17035c3cd6a671688ab9b18a6c69e0a5", "packages": [ { "name": "adhocore/jwt", @@ -1569,16 +1569,16 @@ }, { "name": "utopia-php/cache", - "version": "0.10.0", + "version": "0.10.1", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626" + "reference": "87ee4fc91e50d4ddfef650aa999ea12be3a99583" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/313bcdfbb166f75c2c205a59d1467cead63a9626", - "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/87ee4fc91e50d4ddfef650aa999ea12be3a99583", + "reference": "87ee4fc91e50d4ddfef650aa999ea12be3a99583", "shasum": "" }, "require": { @@ -1613,9 +1613,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.10.0" + "source": "https://github.com/utopia-php/cache/tree/0.10.1" }, - "time": "2024-06-05T16:40:43+00:00" + "time": "2024-06-18T13:20:25+00:00" }, { "name": "utopia-php/cli", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.12", + "version": "0.49.13", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63" + "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", - "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", + "url": "https://api.github.com/repos/utopia-php/database/zipball/fff42e0bd1db5a03d8c5df4302d72443bde3b860", + "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860", "shasum": "" }, "require": { @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.12" + "source": "https://github.com/utopia-php/database/tree/0.49.13" }, - "time": "2024-06-05T16:52:59+00:00" + "time": "2024-06-18T14:33:55+00:00" }, { "name": "utopia-php/domains", @@ -2170,26 +2170,34 @@ }, { "name": "utopia-php/migration", - "version": "0.4.4", + "version": "dev-backups", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "a8a5d392bebf082faf289f4dfe09d9fd76844c33" + "reference": "ce55838583cc237aabd9bdfc898229f17cef130c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/a8a5d392bebf082faf289f4dfe09d9fd76844c33", - "reference": "a8a5d392bebf082faf289f4dfe09d9fd76844c33", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/ce55838583cc237aabd9bdfc898229f17cef130c", + "reference": "ce55838583cc237aabd9bdfc898229f17cef130c", "shasum": "" }, "require": { - "appwrite/appwrite": "10.1.0", - "php": "8.*" + "appwrite/appwrite": "10.1.*", + "ext-curl": "*", + "ext-openssl": "*", + "php": "8.3", + "utopia-php/cli": "0.15.*", + "utopia-php/database": "0.49.*", + "utopia-php/dsn": "0.2.*", + "utopia-php/framework": "0.33.*", + "utopia-php/storage": "0.18.*" }, "require-dev": { - "laravel/pint": "1.*", - "phpunit/phpunit": "9.*", - "vlucas/phpdotenv": "5.*" + "laravel/pint": "1.12.*", + "phpstan/phpstan": "^1.11", + "phpunit/phpunit": "10.5.*", + "vlucas/phpdotenv": "5.6.*" }, "type": "library", "autoload": { @@ -2211,9 +2219,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.4.4" + "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-05-17T05:25:31+00:00" + "time": "2024-06-17T08:26:44+00:00" }, { "name": "utopia-php/mongo", @@ -3156,16 +3164,16 @@ }, { "name": "laravel/pint", - "version": "v1.16.0", + "version": "v1.16.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98" + "reference": "9266a47f1b9231b83e0cfd849009547329d871b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", - "reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", + "url": "https://api.github.com/repos/laravel/pint/zipball/9266a47f1b9231b83e0cfd849009547329d871b1", + "reference": "9266a47f1b9231b83e0cfd849009547329d871b1", "shasum": "" }, "require": { @@ -3176,13 +3184,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.57.1", - "illuminate/view": "^10.48.10", - "larastan/larastan": "^2.9.6", + "friendsofphp/php-cs-fixer": "^3.59.3", + "illuminate/view": "^10.48.12", + "larastan/larastan": "^2.9.7", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.34.7" + "pestphp/pest": "^2.34.8" }, "bin": [ "builds/pint" @@ -3218,7 +3226,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-05-21T18:08:25+00:00" + "time": "2024-06-18T16:50:05+00:00" }, { "name": "matthiasmullie/minify", @@ -5589,9 +5597,18 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/migration", + "version": "dev-backups", + "alias": "0.4.4", + "alias_normalized": "0.4.4.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/migration": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From b84fe6891c5b2600beeef56a2bcde4d5196912f4 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 13:26:52 +0300 Subject: [PATCH 048/213] lint --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 2 +- src/Appwrite/Platform/Workers/Migrations.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 392d232f8b..3904f94fb9 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -25,7 +25,7 @@ abstract class ScheduleBase extends Action abstract public static function getName(): string; abstract public static function getSupportedResource(): string; abstract public static function getCollectionId(): string; - abstract protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB):void; + abstract protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void; public function __construct() { diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index dff23e7802..b257cc9f2f 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -19,9 +19,9 @@ use Utopia\Logger\Log; use Utopia\Logger\Log\Breadcrumb; use Utopia\Migration\Destination; use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite; -use Utopia\Migration\Sources\Appwrite as SourceAppwrite; use Utopia\Migration\Exception as MigrationException; use Utopia\Migration\Source; +use Utopia\Migration\Sources\Appwrite as SourceAppwrite; use Utopia\Migration\Sources\Firebase; use Utopia\Migration\Sources\NHost; use Utopia\Migration\Sources\Supabase; From 2412946939cbcfc0d9aa860b54b6f6fd1ec3d3fd Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 19 Jun 2024 17:26:48 +0300 Subject: [PATCH 049/213] Comment init $destination init --- src/Appwrite/Platform/Workers/Migrations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index b257cc9f2f..a008a50510 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -313,7 +313,7 @@ class Migrations extends Action $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'migrating'", \microtime(true))); $this->updateMigrationDocument($migration, $projectDocument); - $destination->init(); + //$destination->init(); $transfer->run($migration->getAttribute('resources'), function () use ($migration, $transfer, $projectDocument) { $migration->setAttribute('resourceData', json_encode($transfer->getCache())); From 72c647fba837ed289b3c6479a9c294d236dd6fb7 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 26 Jun 2024 10:54:57 +0300 Subject: [PATCH 050/213] Add source shutDown --- composer.lock | 97 ++++++++++---------- src/Appwrite/Platform/Workers/Migrations.php | 3 +- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/composer.lock b/composer.lock index e8e687c455..d38d0436af 100644 --- a/composer.lock +++ b/composer.lock @@ -65,16 +65,16 @@ }, { "name": "appwrite/appwrite", - "version": "10.1.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-for-php.git", - "reference": "da579af70723cfc117b5af84375bdef117e27312" + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/da579af70723cfc117b5af84375bdef117e27312", - "reference": "da579af70723cfc117b5af84375bdef117e27312", + "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/1d043f543acdb17b9fdb440b1b2dd208e400bad3", + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3", "shasum": "" }, "require": { @@ -83,7 +83,8 @@ "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "3.7.35" + "mockery/mockery": "^1.6.6", + "phpunit/phpunit": "^10" }, "type": "library", "autoload": { @@ -99,10 +100,10 @@ "support": { "email": "team@appwrite.io", "issues": "https://github.com/appwrite/sdk-for-php/issues", - "source": "https://github.com/appwrite/sdk-for-php/tree/10.1.0", + "source": "https://github.com/appwrite/sdk-for-php/tree/11.1.0", "url": "https://appwrite.io/support" }, - "time": "2023-11-20T09:56:12+00:00" + "time": "2024-06-26T07:03:23+00:00" }, { "name": "appwrite/php-clamav", @@ -1128,16 +1129,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", "shasum": "" }, "require": { @@ -1188,7 +1189,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" }, "funding": [ { @@ -1204,20 +1205,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", "shasum": "" }, "require": { @@ -1268,7 +1269,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" }, "funding": [ { @@ -1284,7 +1285,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "thecodingmachine/safe", @@ -1569,16 +1570,16 @@ }, { "name": "utopia-php/cache", - "version": "0.10.1", + "version": "0.10.2", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "87ee4fc91e50d4ddfef650aa999ea12be3a99583" + "reference": "b22c6eb6d308de246b023efd0fc9758aee8b8247" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/87ee4fc91e50d4ddfef650aa999ea12be3a99583", - "reference": "87ee4fc91e50d4ddfef650aa999ea12be3a99583", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/b22c6eb6d308de246b023efd0fc9758aee8b8247", + "reference": "b22c6eb6d308de246b023efd0fc9758aee8b8247", "shasum": "" }, "require": { @@ -1613,9 +1614,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.10.1" + "source": "https://github.com/utopia-php/cache/tree/0.10.2" }, - "time": "2024-06-18T13:20:25+00:00" + "time": "2024-06-25T20:36:35+00:00" }, { "name": "utopia-php/cli", @@ -1719,16 +1720,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.13", + "version": "0.49.14", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860" + "reference": "415588c0b98edee9d72cdfe269ff79b14cd8f56d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/fff42e0bd1db5a03d8c5df4302d72443bde3b860", - "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860", + "url": "https://api.github.com/repos/utopia-php/database/zipball/415588c0b98edee9d72cdfe269ff79b14cd8f56d", + "reference": "415588c0b98edee9d72cdfe269ff79b14cd8f56d", "shasum": "" }, "require": { @@ -1769,9 +1770,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.13" + "source": "https://github.com/utopia-php/database/tree/0.49.14" }, - "time": "2024-06-18T14:33:55+00:00" + "time": "2024-06-20T02:39:23+00:00" }, { "name": "utopia-php/domains", @@ -2174,16 +2175,16 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "ce55838583cc237aabd9bdfc898229f17cef130c" + "reference": "2b491d582f316ca7670c4c23f01259482c0ff2a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/ce55838583cc237aabd9bdfc898229f17cef130c", - "reference": "ce55838583cc237aabd9bdfc898229f17cef130c", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/2b491d582f316ca7670c4c23f01259482c0ff2a3", + "reference": "2b491d582f316ca7670c4c23f01259482c0ff2a3", "shasum": "" }, "require": { - "appwrite/appwrite": "10.1.*", + "appwrite/appwrite": "11.1.*", "ext-curl": "*", "ext-openssl": "*", "php": "8.3", @@ -2221,7 +2222,7 @@ "issues": "https://github.com/utopia-php/migration/issues", "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-06-17T08:26:44+00:00" + "time": "2024-06-26T07:48:24+00:00" }, { "name": "utopia-php/mongo", @@ -2996,16 +2997,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.38.7", + "version": "0.38.8", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a" + "reference": "6367c57ddbcf7b88cacb900c4fe7ef3f28bf38ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", - "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/6367c57ddbcf7b88cacb900c4fe7ef3f28bf38ef", + "reference": "6367c57ddbcf7b88cacb900c4fe7ef3f28bf38ef", "shasum": "" }, "require": { @@ -3041,9 +3042,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" + "source": "https://github.com/appwrite/sdk-generator/tree/0.38.8" }, - "time": "2024-06-10T00:23:02+00:00" + "time": "2024-06-17T00:42:27+00:00" }, { "name": "doctrine/deprecations", @@ -5348,16 +5349,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "0424dff1c58f028c451efff2045f5d92410bd540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540", "shasum": "" }, "require": { @@ -5407,7 +5408,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" }, "funding": [ { @@ -5423,7 +5424,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "textalk/websocket", diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index a008a50510..a64fdbdc56 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -313,8 +313,6 @@ class Migrations extends Action $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'migrating'", \microtime(true))); $this->updateMigrationDocument($migration, $projectDocument); - //$destination->init(); - $transfer->run($migration->getAttribute('resources'), function () use ($migration, $transfer, $projectDocument) { $migration->setAttribute('resourceData', json_encode($transfer->getCache())); $migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); @@ -323,6 +321,7 @@ class Migrations extends Action }); $destination->shutDown(); + $source->shutDown(); $sourceErrors = $source->getErrors(); $destinationErrors = $destination->getErrors(); From ed1a5b600dfac78f4f2a54587211ca2dd0bde9a8 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 10 Jul 2024 19:00:10 +1200 Subject: [PATCH 051/213] Fix oldAttribute key length --- app/controllers/api/databases.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index c8903538d0..446aecdda0 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -2434,7 +2434,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes') 'required' => true, 'array' => false, 'default' => null, - 'size' => 36 + 'size' => Database::LENGTH_KEY ]; $oldAttributes[] = [ From b4ab1c2c698662f59dfbc0bf69e58b5982f100ed Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 10 Jul 2024 16:34:05 +0300 Subject: [PATCH 052/213] Debug create document --- app/controllers/api/databases.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 446aecdda0..a0a31c1968 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -2900,6 +2900,8 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') $checkPermissions($collection, $document, Database::PERMISSION_CREATE); + var_dump($document); + try { $document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document); } catch (StructureException $exception) { From 865bfdbd34fc1e583f7f2b2569bf1d0954beb24a Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 11 Jul 2024 12:38:55 +0300 Subject: [PATCH 053/213] DuplicateException dbg --- app/controllers/api/databases.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index a0a31c1968..bff7d0a1a2 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -2907,6 +2907,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') } catch (StructureException $exception) { throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage()); } catch (DuplicateException $exception) { + var_dump($exception); throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS); } From 475e2a64cea02f59c7585ee04a1f00c5d9084352 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 11 Jul 2024 13:36:28 +0300 Subject: [PATCH 054/213] DuplicateException dbg --- app/controllers/api/databases.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index bff7d0a1a2..2c37e096c2 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -2907,7 +2907,11 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') } catch (StructureException $exception) { throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage()); } catch (DuplicateException $exception) { - var_dump($exception); + var_dump('DuplicateException found'); + var_dump($exception->getMessage()); + var_dump($exception->getFile()); + var_dump($exception->getLine()); + var_dump("-----------------"); throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS); } From 6a717f22728d7cda0fd82d0e0eba382026854bde Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 11 Jul 2024 18:47:03 +0300 Subject: [PATCH 055/213] Add resourceId to migration collections.php --- app/config/collections.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/config/collections.php b/app/config/collections.php index 73dbc9eaa5..4533ce3e01 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4073,6 +4073,17 @@ $projectCollections = array_merge([ 'array' => true, 'filters' => [], ], + [ + '$id' => ID::custom('resourceId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('statusCounters'), 'type' => Database::VAR_STRING, From d9da0dd671526723dc15bc4185c4d6d6ea799198 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 15 Jul 2024 17:22:36 +0300 Subject: [PATCH 056/213] Add resourceId to migration collections.php --- composer.lock | 32 ++++++++++---------- src/Appwrite/Platform/Workers/Migrations.php | 15 +++++---- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/composer.lock b/composer.lock index d38d0436af..b1c23caf84 100644 --- a/composer.lock +++ b/composer.lock @@ -2175,12 +2175,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "2b491d582f316ca7670c4c23f01259482c0ff2a3" + "reference": "a7dc26f65866d022451a17860d50e29123edd7e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/2b491d582f316ca7670c4c23f01259482c0ff2a3", - "reference": "2b491d582f316ca7670c4c23f01259482c0ff2a3", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/a7dc26f65866d022451a17860d50e29123edd7e4", + "reference": "a7dc26f65866d022451a17860d50e29123edd7e4", "shasum": "" }, "require": { @@ -2222,7 +2222,7 @@ "issues": "https://github.com/utopia-php/migration/issues", "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-06-26T07:48:24+00:00" + "time": "2024-07-15T11:52:33+00:00" }, { "name": "utopia-php/mongo", @@ -3165,16 +3165,16 @@ }, { "name": "laravel/pint", - "version": "v1.16.1", + "version": "v1.16.2", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "9266a47f1b9231b83e0cfd849009547329d871b1" + "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/9266a47f1b9231b83e0cfd849009547329d871b1", - "reference": "9266a47f1b9231b83e0cfd849009547329d871b1", + "url": "https://api.github.com/repos/laravel/pint/zipball/51f1ba679a6afe0315621ad143d788bd7ded0eca", + "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca", "shasum": "" }, "require": { @@ -3227,7 +3227,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-06-18T16:50:05+00:00" + "time": "2024-07-09T15:58:08+00:00" }, { "name": "matthiasmullie/minify", @@ -3415,16 +3415,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.2", + "version": "v5.1.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", "shasum": "" }, "require": { @@ -3435,7 +3435,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -3467,9 +3467,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" }, - "time": "2024-03-05T20:51:40+00:00" + "time": "2024-07-01T20:03:41+00:00" }, { "name": "phar-io/manifest", diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index a64fdbdc56..f833642055 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -313,12 +313,15 @@ class Migrations extends Action $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'migrating'", \microtime(true))); $this->updateMigrationDocument($migration, $projectDocument); - $transfer->run($migration->getAttribute('resources'), function () use ($migration, $transfer, $projectDocument) { - $migration->setAttribute('resourceData', json_encode($transfer->getCache())); - $migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); - - $this->updateMigrationDocument($migration, $projectDocument); - }); + $transfer->run( + $migration->getAttribute('resources'), + function () use ($migration, $transfer, $projectDocument) { + $migration->setAttribute('resourceData', json_encode($transfer->getCache())); + $migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); + $this->updateMigrationDocument($migration, $projectDocument); + }, + $migration->getAttribute('resourceId', '') + ); $destination->shutDown(); $source->shutDown(); From 865d84f4e75b2a03156f61785dacfc534c0af0e9 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 15 Jul 2024 17:28:40 +0300 Subject: [PATCH 057/213] ResourceId default value --- src/Appwrite/Platform/Workers/Migrations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index f833642055..309a562a8a 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -320,7 +320,7 @@ class Migrations extends Action $migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); $this->updateMigrationDocument($migration, $projectDocument); }, - $migration->getAttribute('resourceId', '') + $migration->getAttribute('resourceId') ); $destination->shutDown(); From 8de8ae03f38bbaf6350dd1279224c2950d1bb00d Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 22 Jul 2024 15:38:58 +0300 Subject: [PATCH 058/213] Add header x-appwrite-preserve-dates --- app/controllers/api/databases.php | 14 ++--- composer.lock | 29 +++++----- .../e2e/Services/Databases/DatabasesBase.php | 56 ++++++++++++++++++- 3 files changed, 76 insertions(+), 23 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 2c37e096c2..bd8a1cc444 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -2743,11 +2743,16 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') ->param('data', [], new JSON(), 'Document data as JSON object.') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->inject('response') + ->inject('request') ->inject('dbForProject') ->inject('user') ->inject('queueForEvents') ->inject('mode') - ->action(function (string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, string $mode) { + ->action(function (string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, Response $response, Request $request, Database $dbForProject, Document $user, Event $queueForEvents, string $mode) { + + if ($request->getHeader('x-appwrite-preserve-dates') === 'true') { + $dbForProject->setPreserveDates(true); + } $data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array @@ -2900,18 +2905,11 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') $checkPermissions($collection, $document, Database::PERMISSION_CREATE); - var_dump($document); - try { $document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document); } catch (StructureException $exception) { throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage()); } catch (DuplicateException $exception) { - var_dump('DuplicateException found'); - var_dump($exception->getMessage()); - var_dump($exception->getFile()); - var_dump($exception->getLine()); - var_dump("-----------------"); throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS); } diff --git a/composer.lock b/composer.lock index b1c23caf84..da60b31309 100644 --- a/composer.lock +++ b/composer.lock @@ -356,16 +356,16 @@ }, { "name": "chillerlan/php-settings-container", - "version": "2.1.5", + "version": "2.1.6", "source": { "type": "git", "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "f705310389264c3578fdd9ffb15aa2cd6d91772e" + "reference": "5553558bd381fce5108c6d0343c12e488cfec6bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/f705310389264c3578fdd9ffb15aa2cd6d91772e", - "reference": "f705310389264c3578fdd9ffb15aa2cd6d91772e", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/5553558bd381fce5108c6d0343c12e488cfec6bb", + "reference": "5553558bd381fce5108c6d0343c12e488cfec6bb", "shasum": "" }, "require": { @@ -373,15 +373,16 @@ "php": "^7.4 || ^8.0" }, "require-dev": { - "phan/phan": "^5.4", - "phpcsstandards/php_codesniffer": "^3.8", - "phpmd/phpmd": "^2.13", - "phpunit/phpunit": "^9.6" + "phpmd/phpmd": "^2.15", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-deprecation-rules": "^1.2", + "phpunit/phpunit": "^9.6", + "squizlabs/php_codesniffer": "^3.10" }, "type": "library", "autoload": { "psr-4": { - "chillerlan\\Settings\\": "src/" + "chillerlan\\Settings\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -418,7 +419,7 @@ "type": "ko_fi" } ], - "time": "2024-01-05T23:20:55+00:00" + "time": "2024-07-17T01:04:28+00:00" }, { "name": "dragonmantank/cron-expression", @@ -2175,12 +2176,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "a7dc26f65866d022451a17860d50e29123edd7e4" + "reference": "d63024ce593124a5ec47f9606386bc01ba27424c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/a7dc26f65866d022451a17860d50e29123edd7e4", - "reference": "a7dc26f65866d022451a17860d50e29123edd7e4", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/d63024ce593124a5ec47f9606386bc01ba27424c", + "reference": "d63024ce593124a5ec47f9606386bc01ba27424c", "shasum": "" }, "require": { @@ -2222,7 +2223,7 @@ "issues": "https://github.com/utopia-php/migration/issues", "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-07-15T11:52:33+00:00" + "time": "2024-07-21T12:03:39+00:00" }, { "name": "utopia-php/mongo", diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 6f65552f1c..1b0bd45a8a 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -4754,6 +4754,8 @@ trait DatabasesBase $this->assertEquals($longtext['headers']['status-code'], 202); + $longtext = file_get_contents(__DIR__ . '/../../../resources/longtext.txt'); + for ($i = 0; $i < 1; $i++) { $this->client->call(Client::METHOD_POST, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([ 'content-type' => 'application/json', @@ -4761,7 +4763,7 @@ trait DatabasesBase ], $this->getHeaders()), [ 'documentId' => ID::unique(), 'data' => [ - 'longtext' => file_get_contents(__DIR__ . '/../../../resources/longtext.txt'), + 'longtext' => $longtext . $longtext, ], 'permissions' => [ Permission::read(Role::user($this->getUser()['$id'])), @@ -4783,4 +4785,56 @@ trait DatabasesBase $this->assertEquals(408, $response['headers']['status-code']); } + + /** + * @depends testCreateDatabase + */ + public function testPreserveDates(array $data): void + { + $databaseId = $data['databaseId']; + + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), [ + 'collectionId' => 'preserve_dates', + 'name' => 'Preserve Dates', + 'documentSecurity' => true, + 'permissions' => [ + Permission::create(Role::user($this->getUser()['$id'])), + ], + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collection['body']['$id'] . '/documents', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-preserve-dates' => 'true' + ], $this->getHeaders()), [ + 'documentId' => ID::unique(), + 'data' => [ + '$createdAt' => '2000-01-01 01:01:01', + '$updatedAt' => '2020-01-01 01:01:01', + ], + 'permissions' => [ + Permission::read(Role::user($this->getUser()['$id'])), + ] + ]); + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collection['body']['$id'] . '/documents', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [ + Query::equal('$id', [$response['body']['$id']])->toString(), + ], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('2000-01-01T01:01:01.000+00:00', $response['body']['documents'][0]['$createdAt']); + $this->assertEquals('2020-01-01T01:01:01.000+00:00', $response['body']['documents'][0]['$updatedAt']); + } } From 6fb318c7882c9f32725c7418b2fe33d776c212fb Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 24 Jul 2024 12:04:11 +0300 Subject: [PATCH 059/213] policies scope --- app/config/scopes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/config/scopes.php b/app/config/scopes.php index 7243e35f96..7162dccc4f 100644 --- a/app/config/scopes.php +++ b/app/config/scopes.php @@ -130,10 +130,10 @@ return [ // List of publicly visible scopes 'assistant.read' => [ 'description' => 'Access to read the Assistant service', ], - 'backups.write' => [ + 'policies.write' => [ 'description' => 'Access to create, update, and delete your backups', ], - 'backups.read' => [ + 'policies.read' => [ 'description' => 'Access to read the backups service', ], ]; From b217221cefa0653e508594a907a43892d7d34906 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 25 Jul 2024 11:53:35 +0300 Subject: [PATCH 060/213] Database 0.50.* --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7de6b86d67..8190297215 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.49.*", + "utopia-php/database": "0.50.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From a0c57d20d8aab6ace2e7ff9aada2ed0a165ba39f Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 25 Jul 2024 11:58:15 +0300 Subject: [PATCH 061/213] Abuse Audit upgrade --- composer.json | 4 +-- composer.lock | 73 +++++++++++++++++++++++++++------------------------ 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/composer.json b/composer.json index 8190297215..d2d47c766b 100644 --- a/composer.json +++ b/composer.json @@ -44,9 +44,9 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.37.*", + "utopia-php/abuse": "0.39.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.39.*", + "utopia-php/audit": "0.40.*", "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", diff --git a/composer.lock b/composer.lock index da60b31309..600ee19ad8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "17035c3cd6a671688ab9b18a6c69e0a5", + "content-hash": "a6904abee5dfb9496340caaa2c9f1f69", "packages": [ { "name": "adhocore/jwt", @@ -1429,26 +1429,28 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.1", + "version": "0.39.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981" + "reference": "55e184db4d89d93e9b557f29f95f3dea661907b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981", - "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/55e184db4d89d93e9b557f29f95f3dea661907b0", + "reference": "55e184db4d89d93e9b557f29f95f3dea661907b0", "shasum": "" }, "require": { "ext-curl": "*", "ext-pdo": "*", + "ext-redis": "*", "php": ">=8.0", - "utopia-php/database": "0.49.*" + "utopia-php/database": "0.50.*" }, "require-dev": { "laravel/pint": "1.5.*", + "phpbench/phpbench": "^1.2", "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^9.4" }, @@ -1472,9 +1474,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.1" + "source": "https://github.com/utopia-php/abuse/tree/0.39.0" }, - "time": "2024-06-05T18:03:59+00:00" + "time": "2024-07-07T20:51:30+00:00" }, { "name": "utopia-php/analytics", @@ -1524,21 +1526,21 @@ }, { "name": "utopia-php/audit", - "version": "0.39.1", + "version": "0.40.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "7ea91e0ceea7b94293612fea94022b73315677c2" + "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2", - "reference": "7ea91e0ceea7b94293612fea94022b73315677c2", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/735ae211ce5fee5b52b736731571b4030b1d7cdc", + "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "0.49.*" + "utopia-php/database": "0.50.*" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1565,9 +1567,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.1" + "source": "https://github.com/utopia-php/audit/tree/0.40.0" }, - "time": "2024-06-05T19:28:22+00:00" + "time": "2024-06-24T00:52:17+00:00" }, { "name": "utopia-php/cache", @@ -1721,16 +1723,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.14", + "version": "0.50.0", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "415588c0b98edee9d72cdfe269ff79b14cd8f56d" + "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/415588c0b98edee9d72cdfe269ff79b14cd8f56d", - "reference": "415588c0b98edee9d72cdfe269ff79b14cd8f56d", + "url": "https://api.github.com/repos/utopia-php/database/zipball/ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", + "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", "shasum": "" }, "require": { @@ -1771,9 +1773,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.14" + "source": "https://github.com/utopia-php/database/tree/0.50.0" }, - "time": "2024-06-20T02:39:23+00:00" + "time": "2024-06-21T03:21:42+00:00" }, { "name": "utopia-php/domains", @@ -2176,12 +2178,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "d63024ce593124a5ec47f9606386bc01ba27424c" + "reference": "3668d07abf45d1356f9dacc43a19283c055f0c57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/d63024ce593124a5ec47f9606386bc01ba27424c", - "reference": "d63024ce593124a5ec47f9606386bc01ba27424c", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/3668d07abf45d1356f9dacc43a19283c055f0c57", + "reference": "3668d07abf45d1356f9dacc43a19283c055f0c57", "shasum": "" }, "require": { @@ -2189,16 +2191,17 @@ "ext-curl": "*", "ext-openssl": "*", "php": "8.3", - "utopia-php/cli": "0.15.*", - "utopia-php/database": "0.49.*", + "utopia-php/database": "0.50.*", "utopia-php/dsn": "0.2.*", "utopia-php/framework": "0.33.*", "utopia-php/storage": "0.18.*" }, "require-dev": { - "laravel/pint": "1.12.*", - "phpstan/phpstan": "^1.11", - "phpunit/phpunit": "10.5.*", + "ext-pdo": "*", + "laravel/pint": "1.17.*", + "phpstan/phpstan": "1.11.*", + "phpunit/phpunit": "11.2.*", + "utopia-php/cli": "0.16.*", "vlucas/phpdotenv": "5.6.*" }, "type": "library", @@ -2223,7 +2226,7 @@ "issues": "https://github.com/utopia-php/migration/issues", "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-07-21T12:03:39+00:00" + "time": "2024-07-25T02:50:15+00:00" }, { "name": "utopia-php/mongo", @@ -3166,16 +3169,16 @@ }, { "name": "laravel/pint", - "version": "v1.16.2", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca" + "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/51f1ba679a6afe0315621ad143d788bd7ded0eca", - "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca", + "url": "https://api.github.com/repos/laravel/pint/zipball/4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", + "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", "shasum": "" }, "require": { @@ -3228,7 +3231,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-07-09T15:58:08+00:00" + "time": "2024-07-23T16:40:20+00:00" }, { "name": "matthiasmullie/minify", From d67e9eec3424ecc5bdf21f58ddf78cc4275d2eaa Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 25 Jul 2024 12:08:30 +0300 Subject: [PATCH 062/213] composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d2d47c766b..b40b32f979 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "dev-backups as 0.4.4", + "utopia-php/migration": "dev-backups as 0.4.999", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From 203021ecb76495fb54e00b6b2411d2fd039bdf2b Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 25 Jul 2024 12:38:54 +0300 Subject: [PATCH 063/213] "utopia-php/abuse": "0.38.*", --- composer.json | 2 +- composer.lock | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index b40b32f979..4e04807374 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.39.*", + "utopia-php/abuse": "0.38.*", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.40.*", "utopia-php/cache": "0.10.*", diff --git a/composer.lock b/composer.lock index 600ee19ad8..bbdf6a6e21 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a6904abee5dfb9496340caaa2c9f1f69", + "content-hash": "afb5cff358a14fb833338c25d6337864", "packages": [ { "name": "adhocore/jwt", @@ -1429,28 +1429,26 @@ }, { "name": "utopia-php/abuse", - "version": "0.39.0", + "version": "0.38.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "55e184db4d89d93e9b557f29f95f3dea661907b0" + "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/55e184db4d89d93e9b557f29f95f3dea661907b0", - "reference": "55e184db4d89d93e9b557f29f95f3dea661907b0", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/b7be9086c9d9b4561d810cbd42fdda798742f56c", + "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c", "shasum": "" }, "require": { "ext-curl": "*", "ext-pdo": "*", - "ext-redis": "*", "php": ">=8.0", "utopia-php/database": "0.50.*" }, "require-dev": { "laravel/pint": "1.5.*", - "phpbench/phpbench": "^1.2", "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^9.4" }, @@ -1474,9 +1472,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.39.0" + "source": "https://github.com/utopia-php/abuse/tree/0.38.0" }, - "time": "2024-07-07T20:51:30+00:00" + "time": "2024-06-24T00:52:02+00:00" }, { "name": "utopia-php/analytics", @@ -5606,8 +5604,8 @@ { "package": "utopia-php/migration", "version": "dev-backups", - "alias": "0.4.4", - "alias_normalized": "0.4.4.0" + "alias": "0.4.999", + "alias_normalized": "0.4.999.0" } ], "minimum-stability": "stable", From 1ff717eceff42b4d49c833bdaa109de1d725e847 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 25 Jul 2024 14:34:19 +0300 Subject: [PATCH 064/213] Change to getResourceName --- src/Appwrite/Platform/Workers/Migrations.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 309a562a8a..ba256b0905 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -337,11 +337,11 @@ class Migrations extends Action $errorMessages = []; foreach ($sourceErrors as $error) { /** @var MigrationException $error */ - $errorMessages[] = "Error occurred while fetching '{$error->getResourceType()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; + $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; } foreach ($destinationErrors as $error) { /** @var MigrationException $error */ - $errorMessages[] = "Error occurred while pushing '{$error->getResourceType()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; + $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; } $migration->setAttribute('errors', $errorMessages); @@ -375,11 +375,11 @@ class Migrations extends Action $errorMessages = []; foreach ($sourceErrors as $error) { /** @var MigrationException $error */ - $errorMessages[] = "Error occurred while fetching '{$error->getResourceType()}:{$error->getResourceId()}' from source with message '{$error->getMessage()}'"; + $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message '{$error->getMessage()}'"; } foreach ($destinationErrors as $error) { /** @var MigrationException $error */ - $errorMessages[] = "Error occurred while pushing '{$error->getResourceType()}:{$error->getResourceId()}' to destination with message '{$error->getMessage()}'"; + $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message '{$error->getMessage()}'"; } $migration->setAttribute('errors', $errorMessages); From 965cf9aac68fa92ca7848d97247da48e8e076851 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 28 Jul 2024 09:27:18 +0300 Subject: [PATCH 065/213] processDestination params --- src/Appwrite/Platform/Workers/Migrations.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index ba256b0905..980fb850fc 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -8,6 +8,7 @@ use Appwrite\Permission; use Appwrite\Role; use Exception; use Utopia\CLI\Console; +use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; @@ -152,7 +153,9 @@ class Migrations extends Action DestinationAppwrite::getName() => new DestinationAppwrite( $credentials['projectId'], str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], - $credentials['apiKey'] + $credentials['apiKey'], + $this->dbForProject, + Config::getParam('collections', [])['databases']['collections'] ), default => throw new \Exception('Invalid destination type'), }; From a98ff7118813dc6bd5dcf285091cb937b66db070 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 28 Jul 2024 09:29:02 +0300 Subject: [PATCH 066/213] processDestination constructor --- src/Appwrite/Platform/Workers/Migrations.php | 45 +++++++------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 980fb850fc..27e62d0364 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -33,7 +33,9 @@ use Utopia\Queue\Message; class Migrations extends Action { protected Database $dbForProject; + protected Database $dbForConsole; + protected Document $project; //protected Document $migration; @@ -57,11 +59,6 @@ class Migrations extends Action } /** - * @param Message $message - * @param Database $dbForProject - * @param Database $dbForConsole - * @param Log $log - * @return void * @throws Exception */ public function action(Message $message, Database $dbForProject, Database $dbForConsole, Log $log): void @@ -72,8 +69,8 @@ class Migrations extends Action throw new Exception('Missing payload'); } - $events = $payload['events'] ?? []; - $project = new Document($payload['project'] ?? []); + $events = $payload['events'] ?? []; + $project = new Document($payload['project'] ?? []); $migration = new Document($payload['migration'] ?? []); if ($project->getId() === 'console') { @@ -99,8 +96,6 @@ class Migrations extends Action } /** - * @param Document $migration - * @return Source * @throws Exception */ protected function processSource(Document $migration): Source @@ -140,9 +135,6 @@ class Migrations extends Action } /** - * @param Document $migration - * @param array $credentials - * @return Destination * @throws Exception */ protected function processDestination(Document $migration, array $credentials): Destination @@ -155,7 +147,7 @@ class Migrations extends Action str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], $credentials['apiKey'], $this->dbForProject, - Config::getParam('collections', [])['databases']['collections'] + Config::getParam('collections', [])['databases']['collections'], ), default => throw new \Exception('Invalid destination type'), }; @@ -201,8 +193,6 @@ class Migrations extends Action } /** - * @param Document $apiKey - * @return void * @throws \Utopia\Database\Exception * @throws Authorization * @throws Conflict @@ -215,8 +205,6 @@ class Migrations extends Action } /** - * @param Document $project - * @return Document * @throws Authorization * @throws Structure * @throws \Utopia\Database\Exception @@ -267,9 +255,6 @@ class Migrations extends Action } /** - * @param Document $migration - * @param Log $log - * @return void * @throws Authorization * @throws Conflict * @throws Restricted @@ -288,7 +273,7 @@ class Migrations extends Action $migration = $this->dbForProject->getDocument('migrations', $migration->getId()); $migration->setAttribute('stage', 'processing'); $migration->setAttribute('status', 'processing'); - $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'processing'", \microtime(true))); + $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'processing'", \microtime(true))); $this->updateMigrationDocument($migration, $projectDocument); $log->addTag('type', $migration->getAttribute('source')); @@ -299,8 +284,8 @@ class Migrations extends Action $migration, [ 'projectId' => $projectDocument->getId(), - 'endpoint' => 'http://appwrite/v1', - 'apiKey' => $tempAPIKey['secret'] + 'endpoint' => 'http://appwrite/v1', + 'apiKey' => $tempAPIKey['secret'], ] ); @@ -313,7 +298,7 @@ class Migrations extends Action /** Start Transfer */ $migration->setAttribute('stage', 'migrating'); - $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'migrating'", \microtime(true))); + $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'migrating'", \microtime(true))); $this->updateMigrationDocument($migration, $projectDocument); $transfer->run( @@ -332,10 +317,10 @@ class Migrations extends Action $sourceErrors = $source->getErrors(); $destinationErrors = $destination->getErrors(); - if (!empty($sourceErrors) || !empty($destinationErrors)) { + if (! empty($sourceErrors) || ! empty($destinationErrors)) { $migration->setAttribute('status', 'failed'); $migration->setAttribute('stage', 'finished'); - $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'finished' and failed", \microtime(true))); + $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'finished' and failed", \microtime(true))); $errorMessages = []; foreach ($sourceErrors as $error) { @@ -356,14 +341,14 @@ class Migrations extends Action $migration->setAttribute('status', 'completed'); $migration->setAttribute('stage', 'finished'); - $log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'finished' and succeeded", \microtime(true))); + $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'finished' and succeeded", \microtime(true))); } catch (\Throwable $th) { Console::error($th->getMessage()); Console::error($th->getMessage()); Console::error($th->getTraceAsString()); - if (!$migration->isEmpty()) { + if (! $migration->isEmpty()) { $migration->setAttribute('status', 'failed'); $migration->setAttribute('stage', 'finished'); $migration->setAttribute('errors', [$th->getMessage()]); @@ -389,14 +374,14 @@ class Migrations extends Action $log->addTag('migrationErrors', json_encode($errorMessages)); } } finally { - if (!$tempAPIKey->isEmpty()) { + if (! $tempAPIKey->isEmpty()) { $this->removeAPIKey($tempAPIKey); } $this->updateMigrationDocument($migration, $projectDocument); if ($migration->getAttribute('status', '') == 'failed') { - throw new Exception("Migration failed"); + throw new Exception('Migration failed'); } } } From 854f243fb1e9704c5de92620829ce2f3cce6b8cf Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 28 Jul 2024 09:51:22 +0300 Subject: [PATCH 067/213] dbg error --- src/Appwrite/Platform/Workers/Migrations.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 27e62d0364..9fe1d1fd86 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -329,6 +329,13 @@ class Migrations extends Action } foreach ($destinationErrors as $error) { /** @var MigrationException $error */ + var_dump('$destinationErrors ====== '); + var_dump($error->getMessage()); + var_dump($error->getLine()); + var_dump($error->getFile()); + var_dump($error->getPrevious()->getMessage()); + var_dump($error->getPrevious()->getLine()); + var_dump($error->getPrevious()->getFile()); $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; } From 5620f360c8a023e03738b8d6944f2693211701fa Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 28 Jul 2024 09:52:47 +0300 Subject: [PATCH 068/213] dbg error --- src/Appwrite/Platform/Workers/Migrations.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 9fe1d1fd86..00037ec258 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -324,7 +324,14 @@ class Migrations extends Action $errorMessages = []; foreach ($sourceErrors as $error) { - /** @var MigrationException $error */ + /** @var $sourceErrors $error */ + var_dump('$sourceErrors ====== '); + var_dump($error->getMessage()); + var_dump($error->getLine()); + var_dump($error->getFile()); + var_dump($error->getPrevious()->getMessage()); + var_dump($error->getPrevious()->getLine()); + var_dump($error->getPrevious()->getFile()); $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; } foreach ($destinationErrors as $error) { From 1a97848d9cd835ec6d8da41f2781833c153169f8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 28 Jul 2024 11:58:04 +0300 Subject: [PATCH 069/213] getTraceAsString --- src/Appwrite/Platform/Workers/Migrations.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 00037ec258..442f639fae 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -343,6 +343,7 @@ class Migrations extends Action var_dump($error->getPrevious()->getMessage()); var_dump($error->getPrevious()->getLine()); var_dump($error->getPrevious()->getFile()); + var_dump($error->getPrevious()->getTraceAsString()); $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; } From ebb8d4a23b7ed35596db501b71999ceef5c46c2a Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 28 Jul 2024 11:58:36 +0300 Subject: [PATCH 070/213] getTraceAsString --- src/Appwrite/Platform/Workers/Migrations.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 442f639fae..5d6c62a2c8 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -340,6 +340,7 @@ class Migrations extends Action var_dump($error->getMessage()); var_dump($error->getLine()); var_dump($error->getFile()); + var_dump($error->getTraceAsString()); var_dump($error->getPrevious()->getMessage()); var_dump($error->getPrevious()->getLine()); var_dump($error->getPrevious()->getFile()); From 4f87d72bcd80bab98ac89e47b406cb51d3773022 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 28 Jul 2024 14:44:37 +0300 Subject: [PATCH 071/213] Migrations errors --- src/Appwrite/Platform/Workers/Migrations.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 5d6c62a2c8..4474f3dda9 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -325,26 +325,10 @@ class Migrations extends Action $errorMessages = []; foreach ($sourceErrors as $error) { /** @var $sourceErrors $error */ - var_dump('$sourceErrors ====== '); - var_dump($error->getMessage()); - var_dump($error->getLine()); - var_dump($error->getFile()); - var_dump($error->getPrevious()->getMessage()); - var_dump($error->getPrevious()->getLine()); - var_dump($error->getPrevious()->getFile()); $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; } foreach ($destinationErrors as $error) { /** @var MigrationException $error */ - var_dump('$destinationErrors ====== '); - var_dump($error->getMessage()); - var_dump($error->getLine()); - var_dump($error->getFile()); - var_dump($error->getTraceAsString()); - var_dump($error->getPrevious()->getMessage()); - var_dump($error->getPrevious()->getLine()); - var_dump($error->getPrevious()->getFile()); - var_dump($error->getPrevious()->getTraceAsString()); $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; } From 0ed7827fe49b78bdcbe2ce4189925174b723de40 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 30 Jul 2024 10:26:13 +0300 Subject: [PATCH 072/213] Add backups scopes --- app/config/scopes.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/config/scopes.php b/app/config/scopes.php index 7162dccc4f..181562f1eb 100644 --- a/app/config/scopes.php +++ b/app/config/scopes.php @@ -136,4 +136,13 @@ return [ // List of publicly visible scopes 'policies.read' => [ 'description' => 'Access to read the backups service', ], + 'archives.read' => [ + 'description' => 'Access to read the backups service', + ], + 'archives.write' => [ + 'description' => 'Access to create, update, and delete your archive', + ], + 'restorations.write' => [ + 'description' => 'Access to create, update, and delete your restoration', + ], ]; From 85b43d1f5c29c5670b286081ddb985e1c18e4574 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 5 Aug 2024 14:48:47 +0300 Subject: [PATCH 073/213] restorations.read --- app/config/scopes.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/config/scopes.php b/app/config/scopes.php index 181562f1eb..99faa59e54 100644 --- a/app/config/scopes.php +++ b/app/config/scopes.php @@ -142,6 +142,9 @@ return [ // List of publicly visible scopes 'archives.write' => [ 'description' => 'Access to create, update, and delete your archive', ], + 'restorations.read' => [ + 'description' => 'Access to read your restorations', + ], 'restorations.write' => [ 'description' => 'Access to create, update, and delete your restoration', ], From 0bb34e0d01a7caf24607ab144006d3b284d0c7a0 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 6 Aug 2024 12:46:13 +0300 Subject: [PATCH 074/213] Add resourceType --- composer.lock | 42 ++++++++++---------- src/Appwrite/Platform/Workers/Migrations.php | 3 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/composer.lock b/composer.lock index bbdf6a6e21..6949a53726 100644 --- a/composer.lock +++ b/composer.lock @@ -1721,16 +1721,16 @@ }, { "name": "utopia-php/database", - "version": "0.50.0", + "version": "0.50.2", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7" + "reference": "c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", - "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", + "url": "https://api.github.com/repos/utopia-php/database/zipball/c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa", + "reference": "c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa", "shasum": "" }, "require": { @@ -1771,9 +1771,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.50.0" + "source": "https://github.com/utopia-php/database/tree/0.50.2" }, - "time": "2024-06-21T03:21:42+00:00" + "time": "2024-07-31T10:12:19+00:00" }, { "name": "utopia-php/domains", @@ -1923,16 +1923,16 @@ }, { "name": "utopia-php/framework", - "version": "0.33.6", + "version": "0.33.7", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "8fe57da0cecd57e3b17cd395b4a666a24f4c07a6" + "reference": "78d293d99a262bd63ece750bbf989c7e0643b825" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/8fe57da0cecd57e3b17cd395b4a666a24f4c07a6", - "reference": "8fe57da0cecd57e3b17cd395b4a666a24f4c07a6", + "url": "https://api.github.com/repos/utopia-php/http/zipball/78d293d99a262bd63ece750bbf989c7e0643b825", + "reference": "78d293d99a262bd63ece750bbf989c7e0643b825", "shasum": "" }, "require": { @@ -1962,9 +1962,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.6" + "source": "https://github.com/utopia-php/http/tree/0.33.7" }, - "time": "2024-03-21T18:10:57+00:00" + "time": "2024-08-01T14:01:04+00:00" }, { "name": "utopia-php/image", @@ -2176,12 +2176,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "3668d07abf45d1356f9dacc43a19283c055f0c57" + "reference": "ae6151e7a65fc5bf253461cd8db909001d7549e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/3668d07abf45d1356f9dacc43a19283c055f0c57", - "reference": "3668d07abf45d1356f9dacc43a19283c055f0c57", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/ae6151e7a65fc5bf253461cd8db909001d7549e9", + "reference": "ae6151e7a65fc5bf253461cd8db909001d7549e9", "shasum": "" }, "require": { @@ -2224,7 +2224,7 @@ "issues": "https://github.com/utopia-php/migration/issues", "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-07-25T02:50:15+00:00" + "time": "2024-08-06T09:32:45+00:00" }, { "name": "utopia-php/mongo", @@ -3167,16 +3167,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5" + "reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", - "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", + "url": "https://api.github.com/repos/laravel/pint/zipball/b5b6f716db298671c1dfea5b1082ec2c0ae7064f", + "reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f", "shasum": "" }, "require": { @@ -3229,7 +3229,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-07-23T16:40:20+00:00" + "time": "2024-08-01T09:06:33+00:00" }, { "name": "matthiasmullie/minify", diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 4474f3dda9..d80df6b1a0 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -308,7 +308,8 @@ class Migrations extends Action $migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); $this->updateMigrationDocument($migration, $projectDocument); }, - $migration->getAttribute('resourceId') + $migration->getAttribute('resourceId'), + $migration->getAttribute('resourceType') ); $destination->shutDown(); From 96274e9c77cf6e15b67a616c70f6dfd34681af5f Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 6 Aug 2024 13:55:59 +0300 Subject: [PATCH 075/213] Collections resourceType --- app/config/collections.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/config/collections.php b/app/config/collections.php index 4533ce3e01..29e19d4967 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4084,6 +4084,17 @@ $projectCollections = array_merge([ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('resourceType'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('statusCounters'), 'type' => Database::VAR_STRING, From 7593537f3d55d7b3fe9909e8c5d48b475a94eaa8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 7 Aug 2024 16:02:24 +0300 Subject: [PATCH 076/213] Add error hook --- composer.lock | 26 ++++++++++---------- src/Appwrite/Platform/Workers/Migrations.php | 4 ++- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/composer.lock b/composer.lock index 6949a53726..a7b43d2011 100644 --- a/composer.lock +++ b/composer.lock @@ -2176,12 +2176,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "ae6151e7a65fc5bf253461cd8db909001d7549e9" + "reference": "274115b3246e40b9235f259288a9bbc3f403227c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/ae6151e7a65fc5bf253461cd8db909001d7549e9", - "reference": "ae6151e7a65fc5bf253461cd8db909001d7549e9", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/274115b3246e40b9235f259288a9bbc3f403227c", + "reference": "274115b3246e40b9235f259288a9bbc3f403227c", "shasum": "" }, "require": { @@ -2224,7 +2224,7 @@ "issues": "https://github.com/utopia-php/migration/issues", "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-08-06T09:32:45+00:00" + "time": "2024-08-07T12:56:55+00:00" }, { "name": "utopia-php/mongo", @@ -3167,16 +3167,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.1", + "version": "v1.17.2", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f" + "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/b5b6f716db298671c1dfea5b1082ec2c0ae7064f", - "reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f", + "url": "https://api.github.com/repos/laravel/pint/zipball/e8a88130a25e3f9d4d5785e6a1afca98268ab110", + "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110", "shasum": "" }, "require": { @@ -3187,13 +3187,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.59.3", - "illuminate/view": "^10.48.12", - "larastan/larastan": "^2.9.7", + "friendsofphp/php-cs-fixer": "^3.61.1", + "illuminate/view": "^10.48.18", + "larastan/larastan": "^2.9.8", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.34.8" + "pestphp/pest": "^2.35.0" }, "bin": [ "builds/pint" @@ -3229,7 +3229,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-08-01T09:06:33+00:00" + "time": "2024-08-06T15:11:54+00:00" }, { "name": "matthiasmullie/minify", diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index d80df6b1a0..42e2035964 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -37,7 +37,6 @@ class Migrations extends Action protected Database $dbForConsole; protected Document $project; - //protected Document $migration; public static function getName(): string { @@ -375,6 +374,9 @@ class Migrations extends Action $log->addTag('migrationErrors', json_encode($errorMessages)); } } finally { + $destination->error($migration); + $source->error($migration); + if (! $tempAPIKey->isEmpty()) { $this->removeAPIKey($tempAPIKey); } From 0ac5e2aa76cf19cda99f434162ef2aeb03ce0d79 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 7 Aug 2024 16:33:54 +0300 Subject: [PATCH 077/213] error no params --- composer.lock | 8 ++++---- src/Appwrite/Platform/Workers/Migrations.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index a7b43d2011..ee21f6f98a 100644 --- a/composer.lock +++ b/composer.lock @@ -2176,12 +2176,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "274115b3246e40b9235f259288a9bbc3f403227c" + "reference": "d579f344cea485b6519b3050f41d976c62c3c4ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/274115b3246e40b9235f259288a9bbc3f403227c", - "reference": "274115b3246e40b9235f259288a9bbc3f403227c", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/d579f344cea485b6519b3050f41d976c62c3c4ba", + "reference": "d579f344cea485b6519b3050f41d976c62c3c4ba", "shasum": "" }, "require": { @@ -2224,7 +2224,7 @@ "issues": "https://github.com/utopia-php/migration/issues", "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-08-07T12:56:55+00:00" + "time": "2024-08-07T13:33:05+00:00" }, { "name": "utopia-php/mongo", diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 42e2035964..1d252b1bd5 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -374,8 +374,8 @@ class Migrations extends Action $log->addTag('migrationErrors', json_encode($errorMessages)); } } finally { - $destination->error($migration); - $source->error($migration); + $destination->error(); + $source->error(); if (! $tempAPIKey->isEmpty()) { $this->removeAPIKey($tempAPIKey); From f12a578efe419bbfb62ce53cded10388808db9f9 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 7 Aug 2024 16:58:00 +0300 Subject: [PATCH 078/213] Update on failed --- src/Appwrite/Platform/Workers/Migrations.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 1d252b1bd5..250f82bcec 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -374,9 +374,6 @@ class Migrations extends Action $log->addTag('migrationErrors', json_encode($errorMessages)); } } finally { - $destination->error(); - $source->error(); - if (! $tempAPIKey->isEmpty()) { $this->removeAPIKey($tempAPIKey); } @@ -384,6 +381,9 @@ class Migrations extends Action $this->updateMigrationDocument($migration, $projectDocument); if ($migration->getAttribute('status', '') == 'failed') { + $destination->error(); + $source->error(); + throw new Exception('Migration failed'); } } From 41beb8af9cc7e424c0965e1a1d470c78ffd56dfa Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 8 Aug 2024 15:14:43 +0300 Subject: [PATCH 079/213] credentials --- src/Appwrite/Platform/Workers/Migrations.php | 24 ++++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 250f82bcec..74bca22206 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -126,7 +126,7 @@ class Migrations extends Action ), SourceAppwrite::getName() => new SourceAppwrite( $credentials['projectId'], - str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], + $credentials['endpoint'], $credentials['apiKey'] ), default => throw new \Exception('Invalid source type'), @@ -136,14 +136,15 @@ class Migrations extends Action /** * @throws Exception */ - protected function processDestination(Document $migration, array $credentials): Destination + protected function processDestination(Document $migration): Destination { $destination = $migration->getAttribute('destination'); + $credentials = $migration->getAttribute('credentials'); return match ($destination) { DestinationAppwrite::getName() => new DestinationAppwrite( $credentials['projectId'], - str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], + $credentials['endpoint'], $credentials['apiKey'], $this->dbForProject, Config::getParam('collections', [])['databases']['collections'], @@ -277,16 +278,19 @@ class Migrations extends Action $log->addTag('type', $migration->getAttribute('source')); - $source = $this->processSource($migration); - - $destination = $this->processDestination( - $migration, - [ + if ( + $migration->getAttribute('source') === SourceAppwrite::getName() || + $migration->getAttribute('destination') === DestinationAppwrite::getName() + ) { + $migration->setAttribute('credentials', [ 'projectId' => $projectDocument->getId(), 'endpoint' => 'http://appwrite/v1', 'apiKey' => $tempAPIKey['secret'], - ] - ); + ]); + } + + $source = $this->processSource($migration); + $destination = $this->processDestination($migration); $source->report(); From d29740f0d7d79b76636cfaa54177d1822d6e4e32 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 8 Aug 2024 15:43:11 +0300 Subject: [PATCH 080/213] credentials --- composer.lock | 12 +++---- src/Appwrite/Platform/Workers/Migrations.php | 37 +++++++++++--------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/composer.lock b/composer.lock index ee21f6f98a..fbf409232b 100644 --- a/composer.lock +++ b/composer.lock @@ -1721,16 +1721,16 @@ }, { "name": "utopia-php/database", - "version": "0.50.2", + "version": "0.50.3", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa" + "reference": "4287e6625c7273411c7322abd151c4285ee7b50f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa", - "reference": "c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa", + "url": "https://api.github.com/repos/utopia-php/database/zipball/4287e6625c7273411c7322abd151c4285ee7b50f", + "reference": "4287e6625c7273411c7322abd151c4285ee7b50f", "shasum": "" }, "require": { @@ -1771,9 +1771,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.50.2" + "source": "https://github.com/utopia-php/database/tree/0.50.3" }, - "time": "2024-07-31T10:12:19+00:00" + "time": "2024-08-08T01:40:54+00:00" }, { "name": "utopia-php/domains", diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 74bca22206..4fbc83d8e8 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -38,6 +38,8 @@ class Migrations extends Action protected Document $project; + protected array $credentials = []; + public static function getName(): string { return 'migrations'; @@ -125,9 +127,9 @@ class Migrations extends Action $credentials['port'], ), SourceAppwrite::getName() => new SourceAppwrite( - $credentials['projectId'], - $credentials['endpoint'], - $credentials['apiKey'] + $this->credentials['projectId'], + $this->credentials['endpoint'], + $this->credentials['apiKey'] ), default => throw new \Exception('Invalid source type'), }; @@ -139,13 +141,12 @@ class Migrations extends Action protected function processDestination(Document $migration): Destination { $destination = $migration->getAttribute('destination'); - $credentials = $migration->getAttribute('credentials'); return match ($destination) { DestinationAppwrite::getName() => new DestinationAppwrite( - $credentials['projectId'], - $credentials['endpoint'], - $credentials['apiKey'], + $this->credentials['projectId'], + $this->credentials['endpoint'], + $this->credentials['apiKey'], $this->dbForProject, Config::getParam('collections', [])['databases']['collections'], ), @@ -278,16 +279,18 @@ class Migrations extends Action $log->addTag('type', $migration->getAttribute('source')); - if ( - $migration->getAttribute('source') === SourceAppwrite::getName() || - $migration->getAttribute('destination') === DestinationAppwrite::getName() - ) { - $migration->setAttribute('credentials', [ - 'projectId' => $projectDocument->getId(), - 'endpoint' => 'http://appwrite/v1', - 'apiKey' => $tempAPIKey['secret'], - ]); - } +// if ( +// $migration->getAttribute('source') === SourceAppwrite::getName() || +// $migration->getAttribute('destination') === DestinationAppwrite::getName() +// ) { +// $migration->setAttribute('credentials', ); +// } + + $this->credentials = [ + 'projectId' => $projectDocument->getId(), + 'endpoint' => 'http://appwrite/v1', + 'apiKey' => $tempAPIKey['secret'], + ]; $source = $this->processSource($migration); $destination = $this->processDestination($migration); From 3800ccee1d62dbd2bb94352e39e32c583e193d7b Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 8 Aug 2024 19:46:44 +0300 Subject: [PATCH 081/213] credentials --- src/Appwrite/Platform/Workers/Migrations.php | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 4fbc83d8e8..7cad7f8b5e 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -268,6 +268,13 @@ class Migrations extends Action $project = $this->project; $projectDocument = $this->dbForConsole->getDocument('projects', $project->getId()); $tempAPIKey = $this->generateAPIKey($projectDocument); + + $this->credentials = [ + 'projectId' => $projectDocument->getId(), + 'endpoint' => 'http://appwrite/v1', + 'apiKey' => $tempAPIKey['secret'], + ]; + $transfer = $source = $destination = null; try { @@ -279,19 +286,6 @@ class Migrations extends Action $log->addTag('type', $migration->getAttribute('source')); -// if ( -// $migration->getAttribute('source') === SourceAppwrite::getName() || -// $migration->getAttribute('destination') === DestinationAppwrite::getName() -// ) { -// $migration->setAttribute('credentials', ); -// } - - $this->credentials = [ - 'projectId' => $projectDocument->getId(), - 'endpoint' => 'http://appwrite/v1', - 'apiKey' => $tempAPIKey['secret'], - ]; - $source = $this->processSource($migration); $destination = $this->processDestination($migration); From 919b5ac06ded738afa697f9258f38f7d582526bc Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 12 Aug 2024 11:15:14 +0300 Subject: [PATCH 082/213] Use document credentials --- src/Appwrite/Platform/Workers/Migrations.php | 41 +++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 7cad7f8b5e..1ae127dc03 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -38,7 +38,7 @@ class Migrations extends Action protected Document $project; - protected array $credentials = []; + //protected array $credentials = []; public static function getName(): string { @@ -127,9 +127,9 @@ class Migrations extends Action $credentials['port'], ), SourceAppwrite::getName() => new SourceAppwrite( - $this->credentials['projectId'], - $this->credentials['endpoint'], - $this->credentials['apiKey'] + $credentials['projectId'], + $credentials['endpoint'], + $credentials['apiKey'], ), default => throw new \Exception('Invalid source type'), }; @@ -141,12 +141,13 @@ class Migrations extends Action protected function processDestination(Document $migration): Destination { $destination = $migration->getAttribute('destination'); + $credentials = $migration->getAttribute('credentials'); return match ($destination) { DestinationAppwrite::getName() => new DestinationAppwrite( - $this->credentials['projectId'], - $this->credentials['endpoint'], - $this->credentials['apiKey'], + $credentials['projectId'], + $credentials['endpoint'], + $credentials['apiKey'], $this->dbForProject, Config::getParam('collections', [])['databases']['collections'], ), @@ -269,16 +270,30 @@ class Migrations extends Action $projectDocument = $this->dbForConsole->getDocument('projects', $project->getId()); $tempAPIKey = $this->generateAPIKey($projectDocument); - $this->credentials = [ - 'projectId' => $projectDocument->getId(), - 'endpoint' => 'http://appwrite/v1', - 'apiKey' => $tempAPIKey['secret'], - ]; - + // $this->credentials = [ + // 'projectId' => $projectDocument->getId(), + // 'endpoint' => 'http://appwrite/v1', + // 'apiKey' => $tempAPIKey['secret'], + // ]; + $transfer = $source = $destination = null; try { $migration = $this->dbForProject->getDocument('migrations', $migration->getId()); + + if ( + $migration->getAttribute('source') === SourceAppwrite::getName() || + $migration->getAttribute('destination') === DestinationAppwrite::getName() + ) { + $credentials = $migration->getAttribute('credentials', []); + + $credentials['projectId'] = $credentials['projectId'] ?? $projectDocument->getId(); + $credentials['endpoint'] = $credentials['endpoint'] ?? 'http://appwrite/v1'; + $credentials['apiKey'] = $credentials['apiKey'] ?? $tempAPIKey['secret']; + + $migration->setAttribute('credentials', $credentials); + } + $migration->setAttribute('stage', 'processing'); $migration->setAttribute('status', 'processing'); $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'processing'", \microtime(true))); From ab4ac2e56847209035dd3766506bddaa647207c1 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 12 Aug 2024 17:44:05 +0300 Subject: [PATCH 083/213] Change private to protected --- src/Appwrite/Platform/Workers/Deletes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index d54f3f5079..cc366c7877 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -951,7 +951,7 @@ class Deletes extends Action * @return void * @throws Exception */ - private function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void + protected function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void { $count = 0; $chunk = 0; @@ -993,7 +993,7 @@ class Deletes extends Action * @return void * @throws Exception */ - private function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void + protected function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void { $count = 0; $chunk = 0; From ccc34b049ad6cd011510b9facaca12ca0689011c Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 19 Aug 2024 14:03:49 +0300 Subject: [PATCH 084/213] notifyProjects --- src/Appwrite/Platform/Tasks/Maintenance.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index cfbc4b200a..cd1c40cbe8 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -49,11 +49,7 @@ class Maintenance extends Action $this->foreachProject($dbForConsole, function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) { $queueForDeletes->setProject($project); - $this->notifyDeleteExecutionLogs($queueForDeletes); - $this->notifyDeleteAbuseLogs($queueForDeletes); - $this->notifyDeleteAuditLogs($queueForDeletes); - $this->notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes); - $this->notifyDeleteExpiredSessions($queueForDeletes); + $this->notifyProjects($queueForDeletes, $usageStatsRetentionHourly); }); $this->notifyDeleteConnections($queueForDeletes); @@ -64,6 +60,15 @@ class Maintenance extends Action }, $interval, $delay); } + protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void + { + $this->notifyDeleteExecutionLogs($queueForDeletes); + $this->notifyDeleteAbuseLogs($queueForDeletes); + $this->notifyDeleteAuditLogs($queueForDeletes); + $this->notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes); + $this->notifyDeleteExpiredSessions($queueForDeletes); + } + protected function foreachProject(Database $dbForConsole, callable $callback): void { // TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document From 9265ba743e6ab571d247f78b7da971091da240ee Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 19 Aug 2024 15:19:06 +0300 Subject: [PATCH 085/213] Add implements Projects --- src/Appwrite/Platform/Tasks/Maintenance.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index cd1c40cbe8..7f8a907d8b 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -12,7 +12,12 @@ use Utopia\Database\Query; use Utopia\Platform\Action; use Utopia\System\System; -class Maintenance extends Action +interface Projects +{ + public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly); +} + +class Maintenance extends Action implements Projects { public static function getName(): string { @@ -60,7 +65,7 @@ class Maintenance extends Action }, $interval, $delay); } - protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void + public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void { $this->notifyDeleteExecutionLogs($queueForDeletes); $this->notifyDeleteAbuseLogs($queueForDeletes); @@ -188,4 +193,14 @@ class Maintenance extends Action ->setType(DELETE_TYPE_EXPIRED_TARGETS) ->trigger(); } + + public function setVariable($name, $var) + { + // TODO: Implement setVariable() method. + } + + public function getHtml($template) + { + // TODO: Implement getHtml() method. + } } From aa5ce6200de649b366f74a0b8c167faf56ca2863 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 19 Aug 2024 16:33:15 +0300 Subject: [PATCH 086/213] Appwrite notifyProjects --- src/Appwrite/Platform/Tasks/Maintenance.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 7f8a907d8b..bf691b1e83 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -67,6 +67,8 @@ class Maintenance extends Action implements Projects public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void { + Console::info("Appwrite notifyProjects"); + $this->notifyDeleteExecutionLogs($queueForDeletes); $this->notifyDeleteAbuseLogs($queueForDeletes); $this->notifyDeleteAuditLogs($queueForDeletes); From 49b659a9aed661bd53d297b12d4e25ffc0d3f29c Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 19 Aug 2024 18:01:29 +0300 Subject: [PATCH 087/213] Remove interface --- src/Appwrite/Platform/Tasks/Maintenance.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index bf691b1e83..629a6ab11f 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -12,12 +12,12 @@ use Utopia\Database\Query; use Utopia\Platform\Action; use Utopia\System\System; -interface Projects -{ - public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly); -} +//interface Projects +//{ +// public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly); +//} -class Maintenance extends Action implements Projects +class Maintenance extends Action { public static function getName(): string { @@ -51,12 +51,16 @@ class Maintenance extends Action implements Projects Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds"); + var_dump('shmuel 1'); $this->foreachProject($dbForConsole, function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) { $queueForDeletes->setProject($project); + var_dump('shmuel 2'); $this->notifyProjects($queueForDeletes, $usageStatsRetentionHourly); + var_dump('shmuel 3'); }); + var_dump('shmuel 4'); $this->notifyDeleteConnections($queueForDeletes); $this->renewCertificates($dbForConsole, $queueForCertificates); $this->notifyDeleteCache($cacheRetention, $queueForDeletes); From b47fd08f712350c4416e1733b796c7e50c6dc141 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 19 Aug 2024 18:26:54 +0300 Subject: [PATCH 088/213] Remove interface --- src/Appwrite/Platform/Tasks/Maintenance.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 629a6ab11f..d967ead5b4 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -82,6 +82,9 @@ class Maintenance extends Action protected function foreachProject(Database $dbForConsole, callable $callback): void { + + var_dump('shmuel 22'); + // TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document $count = 0; $chunk = 0; @@ -90,13 +93,14 @@ class Maintenance extends Action $executionStart = \microtime(true); while ($sum === $limit) { + var_dump('shmuel 33'); $projects = $dbForConsole->find('projects', [Query::limit($limit), Query::offset($chunk * $limit)]); $chunk++; /** @var string[] $projectIds */ $sum = count($projects); - + var_dump('shmuel 44'); foreach ($projects as $project) { $callback($project); $count++; From 04967763e762ddf28e46fc489feb1f01971bf90c Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 19 Aug 2024 18:46:20 +0300 Subject: [PATCH 089/213] Add Iprojects --- src/Appwrite/Platform/Tasks/Maintenance.php | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index d967ead5b4..aaf8b589da 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -12,12 +12,12 @@ use Utopia\Database\Query; use Utopia\Platform\Action; use Utopia\System\System; -//interface Projects -//{ -// public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly); -//} +interface Iprojects +{ + public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly); +} -class Maintenance extends Action +class Maintenance extends Action implements Iprojects { public static function getName(): string { @@ -51,16 +51,12 @@ class Maintenance extends Action Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds"); - var_dump('shmuel 1'); $this->foreachProject($dbForConsole, function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) { $queueForDeletes->setProject($project); - var_dump('shmuel 2'); $this->notifyProjects($queueForDeletes, $usageStatsRetentionHourly); - var_dump('shmuel 3'); }); - var_dump('shmuel 4'); $this->notifyDeleteConnections($queueForDeletes); $this->renewCertificates($dbForConsole, $queueForCertificates); $this->notifyDeleteCache($cacheRetention, $queueForDeletes); @@ -82,9 +78,6 @@ class Maintenance extends Action protected function foreachProject(Database $dbForConsole, callable $callback): void { - - var_dump('shmuel 22'); - // TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document $count = 0; $chunk = 0; @@ -93,14 +86,12 @@ class Maintenance extends Action $executionStart = \microtime(true); while ($sum === $limit) { - var_dump('shmuel 33'); $projects = $dbForConsole->find('projects', [Query::limit($limit), Query::offset($chunk * $limit)]); $chunk++; /** @var string[] $projectIds */ $sum = count($projects); - var_dump('shmuel 44'); foreach ($projects as $project) { $callback($project); $count++; From 42671400bb97a0622ea9846db768a483b5795c07 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 20 Aug 2024 10:08:07 +0300 Subject: [PATCH 090/213] Remove interface --- src/Appwrite/Platform/Tasks/Maintenance.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index aaf8b589da..748ba1f87d 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -12,12 +12,7 @@ use Utopia\Database\Query; use Utopia\Platform\Action; use Utopia\System\System; -interface Iprojects -{ - public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly); -} - -class Maintenance extends Action implements Iprojects +class Maintenance extends Action { public static function getName(): string { @@ -65,9 +60,16 @@ class Maintenance extends Action implements Iprojects }, $interval, $delay); } - public function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void + /** + * Overridable method for Cloud, Please do not delete + * + * @param Delete $queueForDeletes + * @param int $usageStatsRetentionHourly + * @return void + */ + protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void { - Console::info("Appwrite notifyProjects"); + var_dump("Appwrite notifyProjects"); $this->notifyDeleteExecutionLogs($queueForDeletes); $this->notifyDeleteAbuseLogs($queueForDeletes); From 9b20802b4ca608ee46c6e6438b161f9fea838621 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 20 Aug 2024 10:09:02 +0300 Subject: [PATCH 091/213] Only comment --- src/Appwrite/Platform/Tasks/Maintenance.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 748ba1f87d..fe488fdbda 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -62,10 +62,6 @@ class Maintenance extends Action /** * Overridable method for Cloud, Please do not delete - * - * @param Delete $queueForDeletes - * @param int $usageStatsRetentionHourly - * @return void */ protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void { From 2d84816bc91b42d580a3b3f372d5a655760fc556 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 20 Aug 2024 16:39:39 +0300 Subject: [PATCH 092/213] composer.lock --- composer.lock | 116 +++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 49 deletions(-) diff --git a/composer.lock b/composer.lock index cd1cdf2a11..4127580d05 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b5c0db330bf30bd1d240b96116d96baf", + "content-hash": "3582bf9477a65a24fe8030215075ccd4", "packages": [ { "name": "adhocore/jwt", @@ -65,16 +65,16 @@ }, { "name": "appwrite/appwrite", - "version": "10.1.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-for-php.git", - "reference": "da579af70723cfc117b5af84375bdef117e27312" + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/da579af70723cfc117b5af84375bdef117e27312", - "reference": "da579af70723cfc117b5af84375bdef117e27312", + "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/1d043f543acdb17b9fdb440b1b2dd208e400bad3", + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3", "shasum": "" }, "require": { @@ -83,7 +83,8 @@ "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "3.7.35" + "mockery/mockery": "^1.6.6", + "phpunit/phpunit": "^10" }, "type": "library", "autoload": { @@ -99,10 +100,10 @@ "support": { "email": "team@appwrite.io", "issues": "https://github.com/appwrite/sdk-for-php/issues", - "source": "https://github.com/appwrite/sdk-for-php/tree/10.1.0", + "source": "https://github.com/appwrite/sdk-for-php/tree/11.1.0", "url": "https://appwrite.io/support" }, - "time": "2023-11-20T09:56:12+00:00" + "time": "2024-06-26T07:03:23+00:00" }, { "name": "appwrite/php-clamav", @@ -1720,16 +1721,16 @@ }, { "name": "utopia-php/database", - "version": "0.50.1", + "version": "0.50.4", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "1745147bef29a9bddf5dd03fd9174ec29e2c26f0" + "reference": "fd3b856be77bd643bc8a9e3572ee11e4185b9230" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/1745147bef29a9bddf5dd03fd9174ec29e2c26f0", - "reference": "1745147bef29a9bddf5dd03fd9174ec29e2c26f0", + "url": "https://api.github.com/repos/utopia-php/database/zipball/fd3b856be77bd643bc8a9e3572ee11e4185b9230", + "reference": "fd3b856be77bd643bc8a9e3572ee11e4185b9230", "shasum": "" }, "require": { @@ -1770,9 +1771,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.50.1" + "source": "https://github.com/utopia-php/database/tree/0.50.4" }, - "time": "2024-07-26T11:56:05+00:00" + "time": "2024-08-13T03:18:26+00:00" }, { "name": "utopia-php/domains", @@ -1922,16 +1923,16 @@ }, { "name": "utopia-php/framework", - "version": "0.33.6", + "version": "0.33.8", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "8fe57da0cecd57e3b17cd395b4a666a24f4c07a6" + "reference": "a7f577540a25cb90896fef2b64767bf8d700f3c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/8fe57da0cecd57e3b17cd395b4a666a24f4c07a6", - "reference": "8fe57da0cecd57e3b17cd395b4a666a24f4c07a6", + "url": "https://api.github.com/repos/utopia-php/http/zipball/a7f577540a25cb90896fef2b64767bf8d700f3c5", + "reference": "a7f577540a25cb90896fef2b64767bf8d700f3c5", "shasum": "" }, "require": { @@ -1961,9 +1962,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.6" + "source": "https://github.com/utopia-php/http/tree/0.33.8" }, - "time": "2024-03-21T18:10:57+00:00" + "time": "2024-08-15T14:10:09+00:00" }, { "name": "utopia-php/image", @@ -2171,27 +2172,35 @@ }, { "name": "utopia-php/migration", - "version": "0.5.2", + "version": "dev-backups", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "f18d44d4459f78c292dac9edde856fd156fe497a" + "reference": "2bb9c1bf89eff0e90e47f3844cb43eda80e6a069" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/f18d44d4459f78c292dac9edde856fd156fe497a", - "reference": "f18d44d4459f78c292dac9edde856fd156fe497a", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/2bb9c1bf89eff0e90e47f3844cb43eda80e6a069", + "reference": "2bb9c1bf89eff0e90e47f3844cb43eda80e6a069", "shasum": "" }, "require": { - "appwrite/appwrite": "10.1.0", - "php": "8.*" + "appwrite/appwrite": "11.1.*", + "ext-curl": "*", + "ext-openssl": "*", + "php": "8.3", + "utopia-php/database": "0.50.*", + "utopia-php/dsn": "0.2.*", + "utopia-php/framework": "0.33.*", + "utopia-php/storage": "0.18.*" }, "require-dev": { - "laravel/pint": "1.*", - "phpunit/phpunit": "9.*", - "utopia-php/cli": "^0.18.0", - "vlucas/phpdotenv": "5.*" + "ext-pdo": "*", + "laravel/pint": "1.17.*", + "phpstan/phpstan": "1.11.*", + "phpunit/phpunit": "11.2.*", + "utopia-php/cli": "0.16.*", + "vlucas/phpdotenv": "5.6.*" }, "type": "library", "autoload": { @@ -2213,9 +2222,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.5.2" + "source": "https://github.com/utopia-php/migration/tree/backups" }, - "time": "2024-07-22T09:27:07+00:00" + "time": "2024-08-20T13:02:03+00:00" }, { "name": "utopia-php/mongo", @@ -2758,16 +2767,16 @@ }, { "name": "utopia-php/vcs", - "version": "0.8.1", + "version": "0.8.2", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "3084aa93d24ed1e70f01e75f4318fc0d07f12596" + "reference": "eb9b7eade1a46a4f660e0d5a6304f7fa26ec9d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/3084aa93d24ed1e70f01e75f4318fc0d07f12596", - "reference": "3084aa93d24ed1e70f01e75f4318fc0d07f12596", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/eb9b7eade1a46a4f660e0d5a6304f7fa26ec9d18", + "reference": "eb9b7eade1a46a4f660e0d5a6304f7fa26ec9d18", "shasum": "" }, "require": { @@ -2801,9 +2810,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.8.1" + "source": "https://github.com/utopia-php/vcs/tree/0.8.2" }, - "time": "2024-07-29T20:49:09+00:00" + "time": "2024-08-13T14:36:30+00:00" }, { "name": "utopia-php/websocket", @@ -3158,16 +3167,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.0", + "version": "v1.17.2", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5" + "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", - "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", + "url": "https://api.github.com/repos/laravel/pint/zipball/e8a88130a25e3f9d4d5785e6a1afca98268ab110", + "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110", "shasum": "" }, "require": { @@ -3178,13 +3187,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.59.3", - "illuminate/view": "^10.48.12", - "larastan/larastan": "^2.9.7", + "friendsofphp/php-cs-fixer": "^3.61.1", + "illuminate/view": "^10.48.18", + "larastan/larastan": "^2.9.8", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.34.8" + "pestphp/pest": "^2.35.0" }, "bin": [ "builds/pint" @@ -3220,7 +3229,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-07-23T16:40:20+00:00" + "time": "2024-08-06T15:11:54+00:00" }, { "name": "matthiasmullie/minify", @@ -5591,9 +5600,18 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/migration", + "version": "dev-backups", + "alias": "0.4.999", + "alias_normalized": "0.4.999.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/migration": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From f1da0b2e613c07479dfd179bff1072263e52cfc0 Mon Sep 17 00:00:00 2001 From: Shmuel Fogel Date: Thu, 22 Aug 2024 17:21:11 +0300 Subject: [PATCH 093/213] Update src/Appwrite/Platform/Tasks/Maintenance.php Co-authored-by: Jake Barnby --- src/Appwrite/Platform/Tasks/Maintenance.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 8421d9291c..3f06fe42a2 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -60,7 +60,7 @@ class Maintenance extends Action } /** - * Overridable method for Cloud, Please do not delete + * Hook to allow sub-classes to extend project-level maintenance functionality. */ protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void { From 5f27d75c11d921b86cd26f97426d8d28416c9a1d Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 17:30:50 +0300 Subject: [PATCH 094/213] Address comments --- app/controllers/api/databases.php | 8 +-- src/Appwrite/Platform/Tasks/Maintenance.php | 2 - src/Appwrite/Platform/Tasks/ScheduleBase.php | 9 +-- .../e2e/Services/Databases/DatabasesBase.php | 56 +------------------ 4 files changed, 3 insertions(+), 72 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 6740325261..2643a79f54 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -2743,17 +2743,11 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') ->param('data', [], new JSON(), 'Document data as JSON object.') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->inject('response') - ->inject('request') ->inject('dbForProject') ->inject('user') ->inject('queueForEvents') ->inject('mode') - ->action(function (string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, Response $response, Request $request, Database $dbForProject, Document $user, Event $queueForEvents, string $mode) { - - if ($request->getHeader('x-appwrite-preserve-dates') === 'true') { - $dbForProject->setPreserveDates(true); - } - + ->action(function (string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, string $mode) { $data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array if (empty($data)) { diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 8421d9291c..167e837ddb 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -64,8 +64,6 @@ class Maintenance extends Action */ protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void { - var_dump("Appwrite notifyProjects"); - $this->notifyDeleteTargets($queueForDeletes); $this->notifyDeleteExecutionLogs($queueForDeletes); $this->notifyDeleteAbuseLogs($queueForDeletes); diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 3904f94fb9..f5e4d92612 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -59,10 +59,6 @@ abstract class ScheduleBase extends Action $getSchedule = function (Document $schedule) use ($dbForConsole, $getProjectDB): array { $project = $dbForConsole->getDocument('projects', $schedule->getAttribute('projectId')); - var_dump('===== $getSchedule getCollectionId = '); - var_dump(static::getCollectionId()); - var_dump('===== $getSchedule getCollectionId = '); - $resource = $getProjectDB($project)->getDocument( static::getCollectionId(), $schedule->getAttribute('resourceId') @@ -105,10 +101,7 @@ abstract class ScheduleBase extends Action foreach ($results as $document) { try { - var_dump('=== ScheduleBase start'); - var_dump($getSchedule($document)['resource']); - var_dump('=== ScheduleBase end'); - //todo: use a unique key as InternalId or add projectId + //todo: add projectId to be unique $this->schedules[$document['resourceId']]['projectId'] $this->schedules[$document['resourceId']] = $getSchedule($document); } catch (\Throwable $th) { $collectionId = static::getCollectionId(); diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 1b0bd45a8a..6f65552f1c 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -4754,8 +4754,6 @@ trait DatabasesBase $this->assertEquals($longtext['headers']['status-code'], 202); - $longtext = file_get_contents(__DIR__ . '/../../../resources/longtext.txt'); - for ($i = 0; $i < 1; $i++) { $this->client->call(Client::METHOD_POST, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([ 'content-type' => 'application/json', @@ -4763,7 +4761,7 @@ trait DatabasesBase ], $this->getHeaders()), [ 'documentId' => ID::unique(), 'data' => [ - 'longtext' => $longtext . $longtext, + 'longtext' => file_get_contents(__DIR__ . '/../../../resources/longtext.txt'), ], 'permissions' => [ Permission::read(Role::user($this->getUser()['$id'])), @@ -4785,56 +4783,4 @@ trait DatabasesBase $this->assertEquals(408, $response['headers']['status-code']); } - - /** - * @depends testCreateDatabase - */ - public function testPreserveDates(array $data): void - { - $databaseId = $data['databaseId']; - - $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), [ - 'collectionId' => 'preserve_dates', - 'name' => 'Preserve Dates', - 'documentSecurity' => true, - 'permissions' => [ - Permission::create(Role::user($this->getUser()['$id'])), - ], - ]); - - $this->assertEquals(201, $collection['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collection['body']['$id'] . '/documents', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-preserve-dates' => 'true' - ], $this->getHeaders()), [ - 'documentId' => ID::unique(), - 'data' => [ - '$createdAt' => '2000-01-01 01:01:01', - '$updatedAt' => '2020-01-01 01:01:01', - ], - 'permissions' => [ - Permission::read(Role::user($this->getUser()['$id'])), - ] - ]); - $this->assertEquals(201, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collection['body']['$id'] . '/documents', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::equal('$id', [$response['body']['$id']])->toString(), - ], - ]); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals('2000-01-01T01:01:01.000+00:00', $response['body']['documents'][0]['$createdAt']); - $this->assertEquals('2020-01-01T01:01:01.000+00:00', $response['body']['documents'][0]['$updatedAt']); - } } From 4b0c78289141f01086df644ca1de925cb20e357d Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:18:56 +0300 Subject: [PATCH 095/213] databases 0.52.* --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 553ac8ca23..3fabbe7a9d 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.50.*", + "utopia-php/database": "0.52.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From fd52a172a79fa455e5f5066c249659d965401b2c Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:20:57 +0300 Subject: [PATCH 096/213] audit abuse --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 3fabbe7a9d..dc109a555d 100644 --- a/composer.json +++ b/composer.json @@ -44,9 +44,9 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.38.*", + "utopia-php/abuse": "0.42.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.40.*", + "utopia-php/audit": "0.42.*", "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", From 43e7c1e9a68c4be60a28bad8f7c4769d97238dc1 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:36:41 +0300 Subject: [PATCH 097/213] database 50 --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index dc109a555d..f33463e90b 100644 --- a/composer.json +++ b/composer.json @@ -44,13 +44,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.42.*", + "utopia-php/abuse": "0.37.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.42.*", - "utopia-php/cache": "0.10.*", + "utopia-php/audit": "0.39.*", + "utopia-php/cache": "0.9.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.52.*", + "utopia-php/database": "0.50.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From 1cdac28631580e444667b7f04ce079c5631f868b Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:42:22 +0300 Subject: [PATCH 098/213] 0.10.* cache --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f33463e90b..de588ef65f 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "utopia-php/abuse": "0.37.*", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.39.*", - "utopia-php/cache": "0.9.*", + "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", "utopia-php/database": "0.50.*", From 9419e36de0ccb9e1292d20369bb80f7cacecf33b Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:43:04 +0300 Subject: [PATCH 099/213] abuse --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index de588ef65f..effeb7f3cc 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.37.*", + "utopia-php/abuse": "0.39.*", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.39.*", "utopia-php/cache": "0.10.*", From cf7e1121fa66a6a8da48df71c1e36e678fb340cd Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:43:42 +0300 Subject: [PATCH 100/213] audit --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index effeb7f3cc..06d9f00579 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "0.39.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.39.*", + "utopia-php/audit": "0.40.*", "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", From 404ad5b75dfafff7216f4672398ac3d0edba0f2c Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:52:06 +0300 Subject: [PATCH 101/213] database 49 --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 06d9f00579..0ce7892427 100644 --- a/composer.json +++ b/composer.json @@ -44,13 +44,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.39.*", + "utopia-php/abuse": "0.37.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.40.*", - "utopia-php/cache": "0.10.*", + "utopia-php/audit": "0.39.*", + "utopia-php/cache": "0.9.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.50.*", + "utopia-php/database": "0.49.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From b0e218cb3b9de8e4aa1401a926b66d13833c970e Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 18:58:16 +0300 Subject: [PATCH 102/213] database 50 --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 0ce7892427..553ac8ca23 100644 --- a/composer.json +++ b/composer.json @@ -44,13 +44,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.37.*", + "utopia-php/abuse": "0.38.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.39.*", - "utopia-php/cache": "0.9.*", + "utopia-php/audit": "0.40.*", + "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.49.*", + "utopia-php/database": "0.50.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From 2fc483b9e05b3971f7b1aaefc69a2a6f7911d5e6 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 19:01:19 +0300 Subject: [PATCH 103/213] rm migration version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 553ac8ca23..0f263a2594 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "dev-backups as 0.4.999", + "utopia-php/migration": "dev-backups", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From ed0652f86a355aac1c130cde42f79dbd683552e9 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 22 Aug 2024 19:11:06 +0300 Subject: [PATCH 104/213] database 52 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 0f263a2594..4af025fefe 100644 --- a/composer.json +++ b/composer.json @@ -44,13 +44,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.38.*", + "utopia-php/abuse": "0.42.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.40.*", + "utopia-php/audit": "0.42.*", "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.50.*", + "utopia-php/database": "0.52.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From 732a8938ce42daff1abac09fb5cb231e001c3e99 Mon Sep 17 00:00:00 2001 From: Shmuel Fogel Date: Sun, 25 Aug 2024 09:48:50 +0300 Subject: [PATCH 105/213] Update composer.json Co-authored-by: Jake Barnby --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4af025fefe..73bb84159a 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "dev-backups", + "utopia-php/migration": "0.6.*", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From b35f90638445465baf794c7b44c186aac5d554db Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 25 Aug 2024 09:49:44 +0300 Subject: [PATCH 106/213] Longtext test --- tests/e2e/Services/Databases/DatabasesBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 6f65552f1c..6ebd95aa5d 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -4754,7 +4754,7 @@ trait DatabasesBase $this->assertEquals($longtext['headers']['status-code'], 202); - for ($i = 0; $i < 1; $i++) { + for ($i = 0; $i < 10; $i++) { $this->client->call(Client::METHOD_POST, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], From e11e92258727d0817aa59e47a529a94dc890a50e Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 25 Aug 2024 09:58:54 +0300 Subject: [PATCH 107/213] Move scopes --- app/config/scopes.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/app/config/scopes.php b/app/config/scopes.php index 99faa59e54..3765ab54fa 100644 --- a/app/config/scopes.php +++ b/app/config/scopes.php @@ -130,22 +130,4 @@ return [ // List of publicly visible scopes 'assistant.read' => [ 'description' => 'Access to read the Assistant service', ], - 'policies.write' => [ - 'description' => 'Access to create, update, and delete your backups', - ], - 'policies.read' => [ - 'description' => 'Access to read the backups service', - ], - 'archives.read' => [ - 'description' => 'Access to read the backups service', - ], - 'archives.write' => [ - 'description' => 'Access to create, update, and delete your archive', - ], - 'restorations.read' => [ - 'description' => 'Access to read your restorations', - ], - 'restorations.write' => [ - 'description' => 'Access to create, update, and delete your restoration', - ], ]; From 6b1196fb26d52451e97b98d5490677a1f03e60cd Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 25 Aug 2024 11:10:42 +0300 Subject: [PATCH 108/213] update composer.lock --- composer.lock | 135 ++++++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 71 deletions(-) diff --git a/composer.lock b/composer.lock index 4127580d05..a0d2f3be1f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3582bf9477a65a24fe8030215075ccd4", + "content-hash": "b737874b23ae7480c9579c5ee28ad46f", "packages": [ { "name": "adhocore/jwt", @@ -1429,26 +1429,28 @@ }, { "name": "utopia-php/abuse", - "version": "0.38.0", + "version": "0.42.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c" + "reference": "08cf17e7f4fd213966c8d8702e406f2269244f0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/b7be9086c9d9b4561d810cbd42fdda798742f56c", - "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/08cf17e7f4fd213966c8d8702e406f2269244f0f", + "reference": "08cf17e7f4fd213966c8d8702e406f2269244f0f", "shasum": "" }, "require": { "ext-curl": "*", "ext-pdo": "*", + "ext-redis": "*", "php": ">=8.0", - "utopia-php/database": "0.50.*" + "utopia-php/database": "0.52.*" }, "require-dev": { "laravel/pint": "1.5.*", + "phpbench/phpbench": "^1.2", "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^9.4" }, @@ -1472,9 +1474,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.38.0" + "source": "https://github.com/utopia-php/abuse/tree/0.42.0" }, - "time": "2024-06-24T00:52:02+00:00" + "time": "2024-08-21T08:24:01+00:00" }, { "name": "utopia-php/analytics", @@ -1524,21 +1526,21 @@ }, { "name": "utopia-php/audit", - "version": "0.40.0", + "version": "0.42.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc" + "reference": "9dc168470625bcf11ff8cd9ab5660db09129f618" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/735ae211ce5fee5b52b736731571b4030b1d7cdc", - "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/9dc168470625bcf11ff8cd9ab5660db09129f618", + "reference": "9dc168470625bcf11ff8cd9ab5660db09129f618", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "0.50.*" + "utopia-php/database": "0.52.*" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1565,9 +1567,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.40.0" + "source": "https://github.com/utopia-php/audit/tree/0.42.0" }, - "time": "2024-06-24T00:52:17+00:00" + "time": "2024-08-21T08:24:08+00:00" }, { "name": "utopia-php/cache", @@ -1721,16 +1723,16 @@ }, { "name": "utopia-php/database", - "version": "0.50.4", + "version": "0.52.1", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "fd3b856be77bd643bc8a9e3572ee11e4185b9230" + "reference": "d22a316a010699c5ebb4768c1020167c192b9c6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/fd3b856be77bd643bc8a9e3572ee11e4185b9230", - "reference": "fd3b856be77bd643bc8a9e3572ee11e4185b9230", + "url": "https://api.github.com/repos/utopia-php/database/zipball/d22a316a010699c5ebb4768c1020167c192b9c6b", + "reference": "d22a316a010699c5ebb4768c1020167c192b9c6b", "shasum": "" }, "require": { @@ -1742,14 +1744,14 @@ "utopia-php/mongo": "0.3.*" }, "require-dev": { - "fakerphp/faker": "^1.14", - "laravel/pint": "1.13.*", - "pcov/clobber": "^2.0", - "phpstan/phpstan": "1.10.*", - "phpunit/phpunit": "^9.4", - "rregeer/phpunit-coverage-check": "^0.3.1", - "swoole/ide-helper": "4.8.0", - "utopia-php/cli": "^0.14.0" + "fakerphp/faker": "1.23.*", + "laravel/pint": "1.17.*", + "pcov/clobber": "2.0.*", + "phpstan/phpstan": "1.11.*", + "phpunit/phpunit": "9.6.*", + "rregeer/phpunit-coverage-check": "0.3.*", + "swoole/ide-helper": "5.1.3", + "utopia-php/cli": "0.14.*" }, "type": "library", "autoload": { @@ -1771,9 +1773,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.50.4" + "source": "https://github.com/utopia-php/database/tree/0.52.1" }, - "time": "2024-08-13T03:18:26+00:00" + "time": "2024-08-23T02:43:43+00:00" }, { "name": "utopia-php/domains", @@ -2172,24 +2174,24 @@ }, { "name": "utopia-php/migration", - "version": "dev-backups", + "version": "0.6.0", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "2bb9c1bf89eff0e90e47f3844cb43eda80e6a069" + "reference": "33d2fedb7e8e60261f552acfcc42c7875bacc9aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/2bb9c1bf89eff0e90e47f3844cb43eda80e6a069", - "reference": "2bb9c1bf89eff0e90e47f3844cb43eda80e6a069", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/33d2fedb7e8e60261f552acfcc42c7875bacc9aa", + "reference": "33d2fedb7e8e60261f552acfcc42c7875bacc9aa", "shasum": "" }, "require": { "appwrite/appwrite": "11.1.*", "ext-curl": "*", "ext-openssl": "*", - "php": "8.3", - "utopia-php/database": "0.50.*", + "php": "8.3.*", + "utopia-php/database": "0.52.*", "utopia-php/dsn": "0.2.*", "utopia-php/framework": "0.33.*", "utopia-php/storage": "0.18.*" @@ -2222,9 +2224,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/backups" + "source": "https://github.com/utopia-php/migration/tree/0.6.0" }, - "time": "2024-08-20T13:02:03+00:00" + "time": "2024-08-23T03:43:23+00:00" }, { "name": "utopia-php/mongo", @@ -3884,35 +3886,35 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.31", + "version": "9.2.32", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.6" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -3921,7 +3923,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "9.2.x-dev" } }, "autoload": { @@ -3950,7 +3952,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" }, "funding": [ { @@ -3958,7 +3960,7 @@ "type": "github" } ], - "time": "2024-03-02T06:37:42+00:00" + "time": "2024-08-22T04:23:01+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4306,16 +4308,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "79dff0b268932c640297f5208d6298f71855c03e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", + "reference": "79dff0b268932c640297f5208d6298f71855c03e", "shasum": "" }, "require": { @@ -4350,9 +4352,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.1" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-08-21T13:31:24+00:00" }, { "name": "sebastian/cli-parser", @@ -5600,18 +5602,9 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [ - { - "package": "utopia-php/migration", - "version": "dev-backups", - "alias": "0.4.999", - "alias_normalized": "0.4.999.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/migration": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From d8148c54913d2d399bd09b1a9074dd87f96721c5 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 25 Aug 2024 11:19:25 +0300 Subject: [PATCH 109/213] Change TimeLimit namespace --- app/controllers/api/projects.php | 2 +- app/controllers/shared/api.php | 2 +- app/http.php | 2 +- app/realtime.php | 2 +- src/Appwrite/Platform/Workers/Deletes.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index bc8f372991..b9b8ad4750 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -14,7 +14,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Projects; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use PHPMailer\PHPMailer\PHPMailer; -use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\Abuse\Adapters\Database\TimeLimit; use Utopia\App; use Utopia\Audit\Audit; use Utopia\Cache\Cache; diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 2b0013db29..b2f41bbaee 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -16,7 +16,7 @@ use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\Abuse\Abuse; -use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\Abuse\Adapters\Database\TimeLimit; use Utopia\App; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; diff --git a/app/http.php b/app/http.php index 20a5288fe4..f8319a0ab2 100644 --- a/app/http.php +++ b/app/http.php @@ -9,7 +9,7 @@ use Swoole\Http\Request as SwooleRequest; use Swoole\Http\Response as SwooleResponse; use Swoole\Http\Server; use Swoole\Process; -use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\Abuse\Adapters\Database\TimeLimit; use Utopia\App; use Utopia\Audit\Audit; use Utopia\CLI\Console; diff --git a/app/realtime.php b/app/realtime.php index 9c3c2b4d6a..b8fdb2cf21 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -13,7 +13,7 @@ use Swoole\Runtime; use Swoole\Table; use Swoole\Timer; use Utopia\Abuse\Abuse; -use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\Abuse\Adapters\Database\TimeLimit; use Utopia\App; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index cc366c7877..0c799abd50 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -7,7 +7,7 @@ use Appwrite\Extend\Exception; use Executor\Executor; use Throwable; use Utopia\Abuse\Abuse; -use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\Abuse\Adapters\Database\TimeLimit; use Utopia\Audit\Audit; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; From 2d03ce598b8fbe2b281b3624ea53ac10b3ab921a Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 28 Aug 2024 18:00:44 +1200 Subject: [PATCH 110/213] Allow overriding request/response types for spec generation --- src/Appwrite/Platform/Tasks/Specs.php | 27 +++++++++++++++++++-------- src/Appwrite/Utopia/Request.php | 6 +++++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Specs.php b/src/Appwrite/Platform/Tasks/Specs.php index 114e12ac85..8b5093eeab 100644 --- a/src/Appwrite/Platform/Tasks/Specs.php +++ b/src/Appwrite/Platform/Tasks/Specs.php @@ -5,9 +5,11 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Specification\Format\OpenAPI3; use Appwrite\Specification\Format\Swagger2; use Appwrite\Specification\Specification; -use Appwrite\Utopia\Response; +use Appwrite\Utopia\Request as AppwriteRequest; +use Appwrite\Utopia\Response as AppwriteResponse; use Exception; -use Swoole\Http\Response as HttpResponse; +use Swoole\Http\Request as SwooleRequest; +use Swoole\Http\Response as SwooleResponse; use Utopia\App; use Utopia\Cache\Adapter\None; use Utopia\Cache\Cache; @@ -17,7 +19,8 @@ use Utopia\Database\Adapter\MySQL; use Utopia\Database\Database; use Utopia\Platform\Action; use Utopia\Registry\Registry; -use Utopia\Request; +use Utopia\Request as UtopiaRequest; +use Utopia\Response as UtopiaResponse; use Utopia\System\System; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; @@ -29,6 +32,16 @@ class Specs extends Action return 'specs'; } + public function getRequest(): UtopiaRequest + { + return new AppwriteRequest(new SwooleRequest()); + } + + public function getResponse(): UtopiaResponse + { + return new AppwriteResponse(new SwooleResponse()); + } + public function __construct() { $this @@ -42,11 +55,11 @@ class Specs extends Action public function action(string $version, string $mode, Registry $register): void { $appRoutes = App::getRoutes(); - $response = new Response(new HttpResponse()); + $response = $this->getResponse(); $mocks = ($mode === 'mocks'); // Mock dependencies - App::setResource('request', fn () => new Request()); + App::setResource('request', fn () => $this->getRequest()); App::setResource('response', fn () => $response); App::setResource('dbForConsole', fn () => new Database(new MySQL(''), new Cache(new None()))); App::setResource('dbForProject', fn () => new Database(new MySQL(''), new Cache(new None()))); @@ -183,10 +196,8 @@ class Specs extends Action case APP_AUTH_TYPE_SESSION: $sdkPlatforms[] = APP_PLATFORM_CLIENT; break; - case APP_AUTH_TYPE_KEY: - $sdkPlatforms[] = APP_PLATFORM_SERVER; - break; case APP_AUTH_TYPE_JWT: + case APP_AUTH_TYPE_KEY: $sdkPlatforms[] = APP_PLATFORM_SERVER; break; case APP_AUTH_TYPE_ADMIN: diff --git a/src/Appwrite/Utopia/Request.php b/src/Appwrite/Utopia/Request.php index 3f0a196d5e..26c1baf188 100644 --- a/src/Appwrite/Utopia/Request.php +++ b/src/Appwrite/Utopia/Request.php @@ -122,7 +122,11 @@ class Request extends UtopiaRequest */ public function getHeaders(): array { - $headers = $this->generateHeaders(); + try { + $headers = $this->generateHeaders(); + } catch (\Throwable) { + $headers = []; + } if (empty($this->swoole->cookie)) { return $headers; From c868c669caa29605a152d314875d8af958750e20 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 28 Aug 2024 21:35:16 +1200 Subject: [PATCH 111/213] Move const to init to avoid redefine warnings --- app/config/platforms.php | 4 ---- app/init.php | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/config/platforms.php b/app/config/platforms.php index 21db108624..13c6d73203 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -1,9 +1,5 @@ [ 'key' => APP_PLATFORM_CLIENT, diff --git a/app/init.php b/app/init.php index 1eb7cc93ce..45620a9a02 100644 --- a/app/init.php +++ b/app/init.php @@ -142,6 +142,9 @@ const APP_SOCIAL_DEV = 'https://dev.to/appwrite'; const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite'; const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1'; const APP_HOSTNAME_INTERNAL = 'appwrite'; +const APP_PLATFORM_SERVER = 'server'; +const APP_PLATFORM_CLIENT = 'client'; +const APP_PLATFORM_CONSOLE = 'console'; // Database Reconnect const DATABASE_RECONNECT_SLEEP = 2; From f3a5572b598b27bc73069aa5fbd5de919d97cec5 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 28 Aug 2024 22:27:00 +1200 Subject: [PATCH 112/213] Update SDK generator --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 73bb84159a..658ddfc53c 100644 --- a/composer.json +++ b/composer.json @@ -82,7 +82,7 @@ }, "require-dev": { "ext-fileinfo": "*", - "appwrite/sdk-generator": "0.38.*", + "appwrite/sdk-generator": "0.39.*", "phpunit/phpunit": "9.5.20", "swoole/ide-helper": "5.1.2", "textalk/websocket": "1.5.7", diff --git a/composer.lock b/composer.lock index a0d2f3be1f..6e9d369fa8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b737874b23ae7480c9579c5ee28ad46f", + "content-hash": "0e770d4489dbe657c00281b1afd3c0ee", "packages": [ { "name": "adhocore/jwt", @@ -3001,16 +3001,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.38.8", + "version": "0.39.18", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "6367c57ddbcf7b88cacb900c4fe7ef3f28bf38ef" + "reference": "3f12532d3a41f6e3e7528f41c0e79a6d473c4a4c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/6367c57ddbcf7b88cacb900c4fe7ef3f28bf38ef", - "reference": "6367c57ddbcf7b88cacb900c4fe7ef3f28bf38ef", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/3f12532d3a41f6e3e7528f41c0e79a6d473c4a4c", + "reference": "3f12532d3a41f6e3e7528f41c0e79a6d473c4a4c", "shasum": "" }, "require": { @@ -3046,9 +3046,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.8" + "source": "https://github.com/appwrite/sdk-generator/tree/0.39.18" }, - "time": "2024-06-17T00:42:27+00:00" + "time": "2024-08-27T11:22:14+00:00" }, { "name": "doctrine/deprecations", From 79fd72ead493f4d6f7bf99bbc76a306220ffe5ba Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 1 Sep 2024 13:13:06 +0300 Subject: [PATCH 113/213] Add backups scopes --- app/config/roles.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/config/roles.php b/app/config/roles.php index 65b9643b89..742212ff86 100644 --- a/app/config/roles.php +++ b/app/config/roles.php @@ -75,7 +75,13 @@ $admins = [ 'topics.write', 'topics.read', 'subscribers.write', - 'subscribers.read' + 'subscribers.read', + 'policies.write', + 'policies.read', + 'archives.read', + 'archives.write', + 'restorations.read', + 'restorations.write', ]; return [ From 209c610cbe91903e6b4512caf5a2dd48dd4ba938 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 1 Sep 2024 13:15:51 +0300 Subject: [PATCH 114/213] composer.lock --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 6e9d369fa8..5b4c1a9546 100644 --- a/composer.lock +++ b/composer.lock @@ -3839,16 +3839,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f", + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f", "shasum": "" }, "require": { @@ -3880,9 +3880,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-08-29T09:54:52+00:00" }, { "name": "phpunit/php-code-coverage", From 964be49c3a092c638fd0151744d973a03ecfffdd Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 2 Sep 2024 10:26:03 +0300 Subject: [PATCH 115/213] revert roles.php --- app/config/roles.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/config/roles.php b/app/config/roles.php index 742212ff86..333ad7e914 100644 --- a/app/config/roles.php +++ b/app/config/roles.php @@ -76,12 +76,6 @@ $admins = [ 'topics.read', 'subscribers.write', 'subscribers.read', - 'policies.write', - 'policies.read', - 'archives.read', - 'archives.write', - 'restorations.read', - 'restorations.write', ]; return [ From a93fa2cb0cbf3985f17c9f177ccc97817ff8fc6f Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Mon, 2 Sep 2024 21:43:44 +1200 Subject: [PATCH 116/213] Check base class for query validator descendants --- .../Specification/Format/Swagger2.php | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index 03dcd38814..c7278a793c 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -286,7 +286,21 @@ class Swagger2 extends Format $validator = $validator->getValidator(); } - switch ((!empty($validator)) ? \get_class($validator) : '') { + $class = !empty($validator) + ? \get_class($validator) + : ''; + + $base = !empty($class) + ? \get_parent_class($class) + : ''; + + switch ($base) { + case 'Appwrite\Utopia\Database\Validator\Queries\Base': + $class = $base; + break; + } + + switch ($class) { case 'Utopia\Validator\Text': case 'Utopia\Database\Validator\UID': $node['type'] = $validator->getType(); @@ -338,29 +352,7 @@ class Swagger2 extends Format $consumes = ['multipart/form-data']; $node['type'] = 'file'; break; - case 'Appwrite\Utopia\Database\Validator\Queries\Attributes': - case 'Appwrite\Utopia\Database\Validator\Queries\Buckets': - case 'Appwrite\Utopia\Database\Validator\Queries\Collections': - case 'Appwrite\Utopia\Database\Validator\Queries\Databases': - case 'Appwrite\Utopia\Database\Validator\Queries\Deployments': - case 'Appwrite\Utopia\Database\Validator\Queries\Executions': - case 'Appwrite\Utopia\Database\Validator\Queries\Files': - case 'Appwrite\Utopia\Database\Validator\Queries\Functions': - case 'Appwrite\Utopia\Database\Validator\Queries\Identities': - case 'Appwrite\Utopia\Database\Validator\Queries\Indexes': - case 'Appwrite\Utopia\Database\Validator\Queries\Installations': - case 'Appwrite\Utopia\Database\Validator\Queries\Memberships': - case 'Appwrite\Utopia\Database\Validator\Queries\Messages': - case 'Appwrite\Utopia\Database\Validator\Queries\Migrations': - case 'Appwrite\Utopia\Database\Validator\Queries\Projects': - case 'Appwrite\Utopia\Database\Validator\Queries\Providers': - case 'Appwrite\Utopia\Database\Validator\Queries\Rules': - case 'Appwrite\Utopia\Database\Validator\Queries\Subscribers': - case 'Appwrite\Utopia\Database\Validator\Queries\Targets': - case 'Appwrite\Utopia\Database\Validator\Queries\Teams': - case 'Appwrite\Utopia\Database\Validator\Queries\Topics': - case 'Appwrite\Utopia\Database\Validator\Queries\Users': - case 'Appwrite\Utopia\Database\Validator\Queries\Variables': + case 'Appwrite\Utopia\Database\Validator\Queries\Base': case 'Utopia\Database\Validator\Queries': case 'Utopia\Database\Validator\Queries\Document': case 'Utopia\Database\Validator\Queries\Documents': From 982ccf8873f2d3389a00b29c7a063856c02359eb Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 2 Sep 2024 14:20:02 +0300 Subject: [PATCH 117/213] logger update --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 658ddfc53c..495ec6221a 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "utopia-php/fetch": "0.2.*", "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", - "utopia-php/logger": "0.5.*", + "utopia-php/logger": "0.6.*", "utopia-php/messaging": "0.12.*", "utopia-php/migration": "0.6.*", "utopia-php/orchestration": "0.9.*", From 6854451565af4630a9cc4e660d289a36e2e1f547 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 3 Sep 2024 15:07:53 +1200 Subject: [PATCH 118/213] Fix execution scheduler merge --- src/Appwrite/Platform/Tasks/ScheduleExecutions.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleExecutions.php b/src/Appwrite/Platform/Tasks/ScheduleExecutions.php index c5f9b40d15..1ac07fc582 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleExecutions.php +++ b/src/Appwrite/Platform/Tasks/ScheduleExecutions.php @@ -22,7 +22,12 @@ class ScheduleExecutions extends ScheduleBase return 'execution'; } - protected function enqueueResources(Group $pools, Database $dbForConsole): void + public static function getCollectionId(): string + { + return 'executions'; + } + + protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void { $queue = $pools->get('queue')->pop(); $connection = $queue->getResource(); From e79e2857f9122be7c0cd0183586fa61a6ddf69b5 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 4 Sep 2024 20:27:29 +1200 Subject: [PATCH 119/213] Remove console --- app/console | 1 - 1 file changed, 1 deletion(-) delete mode 160000 app/console diff --git a/app/console b/app/console deleted file mode 160000 index 0959b594b3..0000000000 --- a/app/console +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0959b594b32f176819d4afb3a769afea212db789 From 1ce6a8502681566de72c33b25862ccf37bdf440d Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 5 Sep 2024 17:25:41 +0300 Subject: [PATCH 120/213] Use preserveDates branch --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 12020477d3..3ecf645817 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.6.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "0.6.*", + "utopia-php/migration": "dev-preserveDates as 0.6.0", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From 745968ebd407bbd98bac7f88894564f0dc133a37 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 5 Sep 2024 19:06:19 +0300 Subject: [PATCH 121/213] Debug info --- src/Appwrite/Platform/Workers/Migrations.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index d6a0bfc583..72f691f1b4 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -332,6 +332,11 @@ class Migrations extends Action $errorMessages = []; foreach ($sourceErrors as $error) { /** @var $sourceErrors $error */ + var_dump($error->getPrevious()->getMessage()); + var_dump($error->getPrevious()->getLine()); + var_dump($error->getPrevious()->getFile()); + var_dump($error->getLine()); + var_dump($error->getFile()); $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; } foreach ($destinationErrors as $error) { From 626b2390e4d3ec4274a5182c763c82d5ee6be6d9 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 5 Sep 2024 19:06:48 +0300 Subject: [PATCH 122/213] Debug info --- src/Appwrite/Platform/Workers/Migrations.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 72f691f1b4..d4ce30b010 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -340,6 +340,11 @@ class Migrations extends Action $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; } foreach ($destinationErrors as $error) { + var_dump($error->getPrevious()->getMessage()); + var_dump($error->getPrevious()->getLine()); + var_dump($error->getPrevious()->getFile()); + var_dump($error->getLine()); + var_dump($error->getFile()); /** @var MigrationException $error */ $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; } From a008c7c67b315968c74482c2cc2a01d5b576c663 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 5 Sep 2024 19:16:15 +0300 Subject: [PATCH 123/213] Debug info --- src/Appwrite/Platform/Workers/Migrations.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index d4ce30b010..47104c4faf 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -340,11 +340,12 @@ class Migrations extends Action $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; } foreach ($destinationErrors as $error) { - var_dump($error->getPrevious()->getMessage()); - var_dump($error->getPrevious()->getLine()); - var_dump($error->getPrevious()->getFile()); - var_dump($error->getLine()); - var_dump($error->getFile()); + Console::error($error->getPrevious()->getMessage()); + Console::error($error->getPrevious()->getTraceAsString()); + Console::error("Message: " . $error->getMessage()); + Console::error("File: " . $error->getFile()); + Console::error("Line: " . $error->getLine()); + /** @var MigrationException $error */ $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; } @@ -360,8 +361,6 @@ class Migrations extends Action $migration->setAttribute('stage', 'finished'); $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'finished' and succeeded", \microtime(true))); } catch (\Throwable $th) { - - Console::error($th->getMessage()); Console::error($th->getMessage()); Console::error($th->getTraceAsString()); From c5b93ce23163ab0e9fef45030b9d0f5ebc6525e8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 5 Sep 2024 19:33:05 +0300 Subject: [PATCH 124/213] Debug info --- src/Appwrite/Platform/Workers/Migrations.php | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 47104c4faf..c51f4ae8e2 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -332,22 +332,22 @@ class Migrations extends Action $errorMessages = []; foreach ($sourceErrors as $error) { /** @var $sourceErrors $error */ - var_dump($error->getPrevious()->getMessage()); - var_dump($error->getPrevious()->getLine()); - var_dump($error->getPrevious()->getFile()); - var_dump($error->getLine()); - var_dump($error->getFile()); - $errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; + $message = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; + if($error->getPrevious()){ + $message .= " Message: ".$error->getPrevious()->getLine() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); + } + + $errorMessages[] = $message; } foreach ($destinationErrors as $error) { - Console::error($error->getPrevious()->getMessage()); - Console::error($error->getPrevious()->getTraceAsString()); - Console::error("Message: " . $error->getMessage()); - Console::error("File: " . $error->getFile()); - Console::error("Line: " . $error->getLine()); + $message = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; + + if($error->getPrevious()){ + $message .= " Message: ".$error->getPrevious()->getLine() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); + } /** @var MigrationException $error */ - $errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; + $errorMessages[] = $message; } $migration->setAttribute('errors', $errorMessages); From 6f550688386f7c6a5f50aec7365b810a1d72fd75 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 5 Sep 2024 19:40:04 +0300 Subject: [PATCH 125/213] Fix getMessage --- src/Appwrite/Platform/Workers/Migrations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index c51f4ae8e2..c4c2516424 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -334,7 +334,7 @@ class Migrations extends Action /** @var $sourceErrors $error */ $message = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; if($error->getPrevious()){ - $message .= " Message: ".$error->getPrevious()->getLine() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); + $message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); } $errorMessages[] = $message; @@ -343,7 +343,7 @@ class Migrations extends Action $message = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; if($error->getPrevious()){ - $message .= " Message: ".$error->getPrevious()->getLine() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); + $message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); } /** @var MigrationException $error */ From c4b742ac0d6ca14bb86597a987826fa55c500882 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Mon, 9 Sep 2024 20:52:37 +1200 Subject: [PATCH 126/213] Allow overriding realtime instance --- app/realtime.php | 15 +++++++++++---- src/Appwrite/Messaging/Adapter/Realtime.php | 4 ++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/realtime.php b/app/realtime.php index b8fdb2cf21..11bcf923ef 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -40,7 +40,7 @@ require_once __DIR__ . '/init.php'; Runtime::enableCoroutine(SWOOLE_HOOK_ALL); // Allows overriding -if (!function_exists("getConsoleDB")) { +if (!function_exists('getConsoleDB')) { function getConsoleDB(): Database { global $register; @@ -66,7 +66,7 @@ if (!function_exists("getConsoleDB")) { } // Allows overriding -if (!function_exists("getProjectDB")) { +if (!function_exists('getProjectDB')) { function getProjectDB(Document $project): Database { global $register; @@ -113,7 +113,7 @@ if (!function_exists("getProjectDB")) { } // Allows overriding -if (!function_exists("getCache")) { +if (!function_exists('getCache')) { function getCache(): Cache { global $register; @@ -135,7 +135,14 @@ if (!function_exists("getCache")) { } } -$realtime = new Realtime(); +if (!function_exists('getRealtime')) { + function getRealtime(): Realtime + { + return new Realtime(); + } +} + +$realtime = getRealtime(); /** * Table for statistics across all workers. diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 55d8db2924..49aa305c3f 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -243,7 +243,11 @@ class Realtime extends Adapter * @param string $event * @param Document $payload * @param Document|null $project + * @param Document|null $database + * @param Document|null $collection + * @param Document|null $bucket * @return array + * @throws \Exception */ public static function fromPayload(string $event, Document $payload, Document $project = null, Document $database = null, Document $collection = null, Document $bucket = null): array { From 1848de14cc947c3bcaf6e44308e972080f28582b Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 10 Sep 2024 19:30:08 +1200 Subject: [PATCH 127/213] Revert migrations upgrade --- composer.json | 2 +- composer.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 3ecf645817..8ca1ec75e2 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.6.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "dev-preserveDates as 0.6.0", + "utopia-php/migration": "0.6.0", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", diff --git a/composer.lock b/composer.lock index 6fb2fe1749..cd695985cc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6991849c4c8e911d1d7bf602cf43497a", + "content-hash": "b6046c157219fbaaad4e2cb6309ff8be", "packages": [ { "name": "adhocore/jwt", @@ -1211,20 +1211,20 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -1271,7 +1271,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -1287,7 +1287,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "thecodingmachine/safe", @@ -2608,16 +2608,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.4", + "version": "0.18.5", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "94ab8758fabcefee5c5fa723616e45719833f922" + "reference": "7d355c5e3ccc8ecebc0266f8ddd30088a43be919" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/94ab8758fabcefee5c5fa723616e45719833f922", - "reference": "94ab8758fabcefee5c5fa723616e45719833f922", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/7d355c5e3ccc8ecebc0266f8ddd30088a43be919", + "reference": "7d355c5e3ccc8ecebc0266f8ddd30088a43be919", "shasum": "" }, "require": { @@ -2657,9 +2657,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.4" + "source": "https://github.com/utopia-php/storage/tree/0.18.5" }, - "time": "2024-04-02T08:24:09+00:00" + "time": "2024-09-04T08:57:27+00:00" }, { "name": "utopia-php/swoole", From 707d9554df7ea746819cf8fe4957e7a1f98d1a7f Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 10 Sep 2024 12:39:52 +0200 Subject: [PATCH 128/213] Add $createdAt $updatedAt --- .../Utopia/Response/Model/Attribute.php | 13 ++++++++++++- src/Appwrite/Utopia/Response/Model/Index.php | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Appwrite/Utopia/Response/Model/Attribute.php b/src/Appwrite/Utopia/Response/Model/Attribute.php index 9f9ceca317..8c43f8d21c 100644 --- a/src/Appwrite/Utopia/Response/Model/Attribute.php +++ b/src/Appwrite/Utopia/Response/Model/Attribute.php @@ -47,7 +47,18 @@ class Attribute extends Model 'required' => false, 'example' => false, ]) - ; + ->addRule('$createdAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Attribute creation date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('$updatedAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Attribute update date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]); } public array $conditions = []; diff --git a/src/Appwrite/Utopia/Response/Model/Index.php b/src/Appwrite/Utopia/Response/Model/Index.php index 3d3d1a3b52..2d795ad439 100644 --- a/src/Appwrite/Utopia/Response/Model/Index.php +++ b/src/Appwrite/Utopia/Response/Model/Index.php @@ -49,13 +49,22 @@ class Index extends Model 'array' => true, 'required' => false, ]) - ; + ->addRule('$createdAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Index creation date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('$updatedAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Index update date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]); } /** * Get Name - * - * @return string */ public function getName(): string { @@ -64,8 +73,6 @@ class Index extends Model /** * Get Collection - * - * @return string */ public function getType(): string { From 82df6bf936e2cd819e5ce4db9d6b52343fdbfbd8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 15 Sep 2024 11:50:49 +0300 Subject: [PATCH 129/213] Add preserve dates --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8ca1ec75e2..3ecf645817 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.6.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "0.6.0", + "utopia-php/migration": "dev-preserveDates as 0.6.0", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From 20fa8b30175a01382dc6b86cc745566f34314a58 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:29:44 +0100 Subject: [PATCH 130/213] fix: flaky functions shot 1 --- .../e2e/Services/Functions/FunctionsBase.php | 25 +++-- .../Functions/FunctionsCustomClientTest.php | 89 ++++++++--------- .../Functions/FunctionsCustomServerTest.php | 98 +++++++++---------- tests/extensions/Async.php | 17 ++++ tests/extensions/Async/Eventually.php | 54 ++++++++++ 5 files changed, 172 insertions(+), 111 deletions(-) create mode 100644 tests/extensions/Async.php create mode 100644 tests/extensions/Async/Eventually.php diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 2d94b9f0e3..26f2ae7aed 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -2,11 +2,14 @@ namespace Tests\E2E\Services\Functions; +use Appwrite\Tests\Async; use Tests\E2E\Client; use Utopia\CLI\Console; trait FunctionsBase { + use Async; + protected string $stdout = ''; protected string $stderr = ''; @@ -15,29 +18,23 @@ trait FunctionsBase Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); } - protected function awaitDeploymentIsBuilt($functionId, $deploymentId, $checkForSuccess = true): void + protected function assertDeployment($functionId, $deploymentId, $allowFailure = false) { - while (true) { + $this->assertEventually(function () use ($functionId, $deploymentId, $allowFailure) { $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/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; + $status = $deployment['body']['status']; + + if ($allowFailure && $status === 'failed') { + $this->fail('Deployment failed: ' . json_encode($deployment['body']['buildStderr'])); } - \sleep(1); - } - - if ($checkForSuccess) { - $this->assertEquals(200, $deployment['headers']['status-code']); - $this->assertEquals('ready', $deployment['body']['status'], \json_encode($deployment['body'])); - } + $this->assertEquals('ready', $status); + }, 180000, 3000); } // /** diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 92b7c33034..f5f15a0fc6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -2,7 +2,6 @@ namespace Tests\E2E\Services\Functions; -use Appwrite\Tests\Retry; use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; @@ -44,7 +43,6 @@ class FunctionsCustomClientTest extends Scope return []; } - #[Retry(count: 2)] public function testCreateExecution(): array { /** @@ -120,7 +118,7 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId); + $this->assertDeployment($function['body']['$id'], $deploymentId); $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $function['body']['$id'] . '/deployments/' . $deploymentId, [ 'content-type' => 'application/json', @@ -148,25 +146,26 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(202, $execution['headers']['status-code']); - // Wait for the first scheduled execution to be created - sleep(90); + $this->assertEventually(function () use ($function) { + $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertCount(2, $executions['body']['executions']); - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertCount(2, $executions['body']['executions']); - $this->assertIsArray($executions['body']['executions']); - $this->assertEquals($executions['body']['executions'][1]['trigger'], 'schedule'); - $this->assertEquals($executions['body']['executions'][1]['status'], 'completed'); - $this->assertEquals($executions['body']['executions'][1]['responseStatusCode'], 200); - $this->assertEquals($executions['body']['executions'][1]['responseBody'], ''); - $this->assertNotEmpty($executions['body']['executions'][1]['logs'], ''); - $this->assertNotEmpty($executions['body']['executions'][1]['errors'], ''); - $this->assertGreaterThan(0, $executions['body']['executions'][1]['duration']); + // Check if the scheduled execution has completed + $scheduledExecution = $executions['body']['executions'][1]; + $this->assertEquals('schedule', $scheduledExecution['trigger']); + $this->assertEquals('completed', $scheduledExecution['status']); + $this->assertEquals(200, $scheduledExecution['responseStatusCode']); + $this->assertEquals('', $scheduledExecution['responseBody']); + $this->assertNotEmpty($scheduledExecution['logs']); + $this->assertNotEmpty($scheduledExecution['errors']); + $this->assertGreaterThan(0, $scheduledExecution['duration']); + }, 120000, 2000); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $function['body']['$id'], [ @@ -216,7 +215,7 @@ class FunctionsCustomClientTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, true); + $this->assertDeployment($function['body']['$id'], $deploymentId, true); // Schedule execution for the future \date_default_timezone_set('UTC'); @@ -245,25 +244,22 @@ class FunctionsCustomClientTest extends Scope $executionId = $execution['body']['$id']; - $start = \microtime(true); - while (true) { + $this->assertEventually(function () use ($function, $executionId) { $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions/' . $executionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ]); - if ($execution['body']['status'] === 'completed') { - break; - } + $this->assertEquals('completed', $execution['body']['status']); + }, 150000, 2000); // Timeout after 150 seconds, wait 2 seconds between retries - $timeout = 60 + 60 + 15; // up to 1 minute round up, 1 minute schedule postpone, 15s cold start safety - if (\microtime(true) - $start > $timeout) { - $this->fail('Scheduled execution did not complete with status ' . $execution['body']['status'] . ': ' . \json_encode($execution)); - } - - usleep(500000); // 0.5 seconds - } + // After ensuring the execution is completed, fetch it again for assertions + $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions/' . $executionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); $this->assertEquals(200, $execution['headers']['status-code']); $this->assertEquals(200, $execution['body']['responseStatusCode']); @@ -409,7 +405,7 @@ class FunctionsCustomClientTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId); + $this->assertDeployment($function['body']['$id'], $deploymentId); $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ 'content-type' => 'application/json', @@ -458,17 +454,16 @@ class FunctionsCustomClientTest extends Scope $executionId = $execution['body']['$id'] ?? ''; - sleep(5); + $this->assertEventually(function () use ($functionId, $executionId, $projectId, $apikey) { + $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $apikey, + ]); - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ]); - - $this->assertEmpty($execution['body']['responseBody']); - $this->assertEquals(200, $execution['headers']['status-code']); - $this->assertEquals(200, $execution['body']['responseStatusCode']); + $this->assertEquals('completed', $execution['body']['status']); + $this->assertEquals(200, $execution['body']['responseStatusCode']); + }, 30000, 1000); return [ 'functionId' => $functionId @@ -521,7 +516,7 @@ class FunctionsCustomClientTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId); + $this->assertDeployment($function['body']['$id'], $deploymentId); // Why do we have to do this? $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ @@ -760,7 +755,7 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId); + $this->assertDeployment($function['body']['$id'], $deploymentId); $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ 'content-type' => 'application/json', @@ -853,7 +848,7 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId); + $this->assertDeployment($function['body']['$id'], $deploymentId); $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 2958e6cb5f..4005279560 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -3,7 +3,6 @@ namespace Tests\E2E\Services\Functions; use Appwrite\Functions\Specification; -use Appwrite\Tests\Retry; use CURLFile; use PHPUnit\Framework\ExpectationFailedException; use Tests\E2E\Client; @@ -429,7 +428,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId); + $this->assertDeployment($function['body']['$id'], $deploymentId); $functionDetails = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ 'content-type' => 'application/json', @@ -521,7 +520,7 @@ class FunctionsCustomServerTest extends Scope // Wait for deployment build to finish // Deployment is automatically activated - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId); + $this->assertDeployment($function['body']['$id'], $deploymentId); $deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ 'content-type' => 'application/json', @@ -635,7 +634,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt'])); $this->assertEquals('index.php', $deployment['body']['entrypoint']); - $this->awaitDeploymentIsBuilt($data['functionId'], $deploymentId); + $this->assertDeployment($data['functionId'], $deploymentId); $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', @@ -650,7 +649,7 @@ class FunctionsCustomServerTest extends Scope $deploymentIdInactive = $deployment['body']['$id']; - $this->awaitDeploymentIsBuilt($data['functionId'], $deploymentIdInactive); + $this->assertDeployment($data['functionId'], $deploymentIdInactive); $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'], array_merge([ 'content-type' => 'application/json', @@ -696,26 +695,16 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt'])); $this->assertEquals('index.php', $deployment['body']['entrypoint']); - // Poll until deployment is in progress - while (true) { + $this->assertEventually(function () use ($data, $deploymentId) { $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ]); - if ( - $deployment['headers']['status-code'] >= 400 - || $deployment['body']['status'] === 'building' - ) { - break; - } - - \sleep(1); - } - - $this->assertEquals(200, $deployment['headers']['status-code']); - $this->assertEquals('building', $deployment['body']['status']); + $this->assertEquals(200, $deployment['headers']['status-code']); + $this->assertEquals('building', $deployment['body']['status']); + }, 60000, 1000); // Cancel the deployment build $cancel = $this->client->call(Client::METHOD_PATCH, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId . '/build', [ @@ -729,10 +718,10 @@ class FunctionsCustomServerTest extends Scope /** * Build worker still runs the build. - * 30s sleep gives worker enough time to finish build. + * 10s sleep gives worker enough time to finish build. * After build finished, it should still be canceled, not ready. */ - \sleep(30); + \sleep(10); $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -794,7 +783,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $largeTag['body']['$id']; - $this->awaitDeploymentIsBuilt($data['functionId'], $deploymentId, true); + $this->assertDeployment($data['functionId'], $deploymentId, true); $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -1294,7 +1283,6 @@ class FunctionsCustomServerTest extends Scope /** * @depends testUpdateDeployment */ - #[Retry(count: 2)] public function testSyncCreateExecution($data): array { /** @@ -1417,14 +1405,23 @@ class FunctionsCustomServerTest extends Scope $executionId = $execution['body']['$id'] ?? ''; $this->assertEquals(202, $execution['headers']['status-code']); - sleep(5); - $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $executionId, array_merge([ + + $this->assertEventually(function () use ($data, $executionId) { + $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions/' . $executionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]); + + $this->assertEquals(200, $execution['headers']['status-code']); + $this->assertEquals('waiting', $execution['body']['status']); + }, 10000, 500); + + $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $executionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + ]); $this->assertEquals(204, $execution['headers']['status-code']); - $this->assertEmpty($execution['body']); return $data; } @@ -1432,7 +1429,6 @@ class FunctionsCustomServerTest extends Scope /** * @depends testGetExecution */ - #[Retry(count: 2)] public function testUpdateSpecs($data): array { /** @@ -1622,7 +1618,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($functionId, $deploymentId); + $this->assertDeployment($functionId, $deploymentId); $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', @@ -1773,7 +1769,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -1868,7 +1864,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -1954,7 +1950,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2054,7 +2050,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2147,7 +2143,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2169,21 +2165,23 @@ class FunctionsCustomServerTest extends Scope ]); $userId = $user['body']['$id']; - $this->assertEquals(201, $user['headers']['status-code']); - // Wait for execution to occur - sleep(15); + $execution = null; + $this->assertEventually(function () use ($functionId, &$execution) { + $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]); - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + if (empty($executions['body']['executions'])) { + throw new \Exception('No executions found yet'); + } - $execution = $executions['body']['executions'][0]; + $execution = $executions['body']['executions'][0]; + $this->assertEquals('completed', $execution['status']); + }, 30000, 1000); - $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']); @@ -2243,7 +2241,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2346,7 +2344,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2437,7 +2435,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2553,7 +2551,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2639,7 +2637,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->awaitDeploymentIsBuilt($function['body']['$id'], $deploymentId, checkForSuccess: false); + $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); $deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2735,7 +2733,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; - $this->awaitDeploymentIsBuilt($functionId, $deploymentId, checkForSuccess: false); + $this->assertDeployment($functionId, $deploymentId, allowFailure: true); // Sync Executions test $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ diff --git a/tests/extensions/Async.php b/tests/extensions/Async.php new file mode 100644 index 0000000000..48af24bc02 --- /dev/null +++ b/tests/extensions/Async.php @@ -0,0 +1,17 @@ +timeoutMs = $timeoutMs; + $this->waitMs = $waitMs; + } + + public function evaluate(mixed $probe, string $description = '', bool $returnResult = false): ?bool + { + if (!is_callable($probe)) { + throw new \Exception('Probe must be a callable'); + } + + $start = microtime(true); + $lastException = null; + + do { + try { + $probe(); + return true; + } catch (\Exception $exception) { + $lastException = $exception; + } + + usleep($this->waitMs * 1000); + } while (microtime(true) - $start < $this->timeoutMs / 1000); + + if ($returnResult) { + return false; + } + + throw $lastException; + } + + protected function failureDescription(mixed $other): string + { + return 'the given probe was satisfied within ' . $this->timeoutMs . 'ms.'; + } + + public function toString(): string + { + return 'Eventually'; + } +} From 121b9f32b816b26d3a4afb49a1e0a57e8f8d6be2 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:50:36 +0100 Subject: [PATCH 131/213] fix: allowFailure --- .../e2e/Services/Functions/FunctionsBase.php | 2 +- .../Functions/FunctionsCustomServerTest.php | 177 ++++-------------- 2 files changed, 40 insertions(+), 139 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 26f2ae7aed..7f33e0b2ee 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -34,7 +34,7 @@ trait FunctionsBase } $this->assertEquals('ready', $status); - }, 180000, 3000); + }, 180000, 1000); } // /** diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 4005279560..193e99d89e 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1631,33 +1631,32 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(202, $execution['headers']['status-code']); - sleep(20); + $executionData = null; - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::equal('trigger', ['http'])->toString(), - ], - ]); + $this->assertEventually(function () use ($functionId, $executionId, &$executionData) { + $executionData = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); - $this->assertEquals($executions['headers']['status-code'], 200); - $this->assertEquals($executions['body']['total'], 1); - $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'); - $this->assertEquals($executions['body']['executions'][0]['status'], 'failed'); - $this->assertEquals($executions['body']['executions'][0]['responseStatusCode'], 500); - $this->assertGreaterThan(2, $executions['body']['executions'][0]['duration']); - $this->assertLessThan(20, $executions['body']['executions'][0]['duration']); - $this->assertEquals($executions['body']['executions'][0]['responseBody'], ''); - $this->assertEquals($executions['body']['executions'][0]['logs'], ''); - $this->assertStringContainsString('timed out', $executions['body']['executions'][0]['errors']); + $this->assertEquals(200, $executionData['headers']['status-code']); + $this->assertEquals('failed', $executionData['body']['status']); - $start = \microtime(true); - while (true) { + if ($executionData['body']['status'] !== 'failed') { + } + }, 30000, 1000); + + $this->assertEquals('failed', $executionData['body']['status']); + $this->assertEquals(500, $executionData['body']['responseStatusCode']); + $this->assertGreaterThan(2, $executionData['body']['duration']); + $this->assertLessThan(20, $executionData['body']['duration']); + $this->assertEquals('', $executionData['body']['responseBody']); + $this->assertEquals('', $executionData['body']['logs']); + $this->assertStringContainsString('timed out', $executionData['body']['errors']); + + $scheduledExecutionData = null; + + $this->assertEventually(function () use ($functionId, &$scheduledExecutionData) { $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1668,27 +1667,12 @@ class FunctionsCustomServerTest extends Scope ]); $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertEquals(1, $executions['body']['total']); - if (\count($executions['body']['executions']) > 0) { - break; - } + $scheduledExecutionData = $executions['body']['executions'][0]; + }, 140000, 1000); // Wait up to 140 seconds, checking every 1 second - // 0s would mean instant execution - // +60 seconds, maximum possible waiting time before next minute - // +10 seconds, maximum update interval time - // +60 seconds, possible overlap between update and schedule tick - // +10 seconds, maximum execution time including cold-start - // Result: We allow maximum - if (\microtime(true) - $start > 140) { - $this->fail('Execution did not create within 140 seconds of schedule: ' . \json_encode($executions)); - } - - usleep(1000000); // 1 second - } - - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertGreaterThanOrEqual(1, \count($executions['body']['executions'])); - $this->assertEquals($executions['body']['executions'][0]['trigger'], 'schedule'); + $this->assertEquals('schedule', $scheduledExecutionData['trigger']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ @@ -1700,6 +1684,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(204, $response['headers']['status-code']); } + /** * * @return array @@ -1769,14 +1754,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); + $this->assertDeployment($function['body']['$id'], $deploymentId); $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', @@ -1864,17 +1842,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); - - // Wait a little for activation to finish - sleep(5); + $this->assertDeployment($function['body']['$id'], $deploymentId); $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'x-appwrite-project' => $this->getProject()['$id'], @@ -1950,17 +1918,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); - - // Wait a little for activation to finish - sleep(5); + $this->assertDeployment($function['body']['$id'], $deploymentId); $bytes = pack('C*', ...[0, 20, 255]); @@ -2050,14 +2008,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); + $this->assertDeployment($function['body']['$id'], $deploymentId); $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', @@ -2143,17 +2094,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); - - // Wait a little for activation to finish - sleep(5); + $this->assertDeployment($function['body']['$id'], $deploymentId); // Create user to trigger event $user = $this->client->call(Client::METHOD_POST, '/users', array_merge([ @@ -2241,7 +2182,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); + $this->assertDeployment($function['body']['$id'], $deploymentId); $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -2344,17 +2285,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); - - // Wait a little for activation to finish - sleep(5); + $this->assertDeployment($function['body']['$id'], $deploymentId); $cookie = 'cookieName=cookieValue; cookie2=value2; cookie3=value=3; cookie4=val:ue4; cookie5=value5'; @@ -2435,17 +2366,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); - - // Wait a little for activation to finish - sleep(5); + $this->assertDeployment($function['body']['$id'], $deploymentId); $cookie = 'cookieName=cookieValue; cookie2=value2; cookie3=value=3; cookie4=val:ue4; cookie5=value5'; @@ -2551,17 +2472,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); - - // Wait a little for activation to finish - sleep(5); + $this->assertDeployment($function['body']['$id'], $deploymentId); $proxyClient = new Client(); $proxyClient->setEndpoint('http://' . $domain); @@ -2637,17 +2548,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeployment($function['body']['$id'], $deploymentId, allowFailure: true); - - $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']); - - // Wait a little for activation to finish - sleep(5); + $this->assertDeployment($function['body']['$id'], $deploymentId); $proxyClient = new Client(); $proxyClient->setEndpoint('http://' . $domain); @@ -2733,7 +2634,7 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertDeployment($functionId, $deploymentId, allowFailure: true); + $this->assertDeployment($functionId, $deploymentId); // Sync Executions test $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ From 979fcacd6cab9bb48aae251f665ad5b576c803ba Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:35:52 +0100 Subject: [PATCH 132/213] fix: abstract requests --- .../e2e/Services/Functions/FunctionsBase.php | 391 +++++---- .../Functions/FunctionsConsoleClientTest.php | 173 ++-- .../Functions/FunctionsCustomClientTest.php | 739 +++--------------- .../Functions/FunctionsCustomServerTest.php | 358 +++------ 4 files changed, 469 insertions(+), 1192 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 7f33e0b2ee..92210a3027 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -3,6 +3,7 @@ namespace Tests\E2E\Services\Functions; use Appwrite\Tests\Async; +use CURLFile; use Tests\E2E\Client; use Utopia\CLI\Console; @@ -13,220 +14,212 @@ trait FunctionsBase protected string $stdout = ''; protected string $stderr = ''; - protected function packageCode($folder) + protected function setupFunction(mixed $params): string { + $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), $params); + $functionId = $function['body']['$id']; + + $this->assertEquals($function['headers']['status-code'], 201); + return $functionId; + } + + protected function setupDeployment(string $functionId, mixed $params): string + { + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), $params); + $deploymentId = $deployment['body']['$id']; + + $this->assertEquals($deployment['headers']['status-code'], 202); + + $this->assertEventually(function () use ($functionId, $deploymentId) { + $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals('completed', $deployment['body']['status']); + }, 200000, 500); + + return $deploymentId; + } + + protected function cleanupFunction(string $functionId): void + { + $function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ])); + + $this->assertEquals($function['headers']['status-code'], 204); + } + + protected function createFunction(mixed $params) + { + $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + $functionId = $function['body']['$id']; + + if (empty($variables)) { + return $function; + } + + $function = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $function; + } + + protected function createVariable($functionId, $key, $value) + { + $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'key' => $key, + 'value' => $value + ]); + + return $variable; + } + + protected function getFunction($functionId) + { + $function = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $function; + } + + protected function getDeployment($functionId, $deploymentId) + { + $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $deployment; + } + + protected function getExecution($functionId, $executionId) + { + $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $execution; + } + + protected function listDeployments($functionId, $params = []) + { + $deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), $params)); + + return $deployments; + } + + protected function listExecutions($functionId, $params = []) + { + $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), $params)); + + return $executions; + } + + protected function packageFunction(string $folder = 'php') + { + $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); + + if (!file_exists($code)) { + throw new \Exception('Failed to create code package. ' . $code . ' does not exist.'); + } + if (filesize($code) > 1024 * 1024 * 5) { + throw new \Exception('Code package is too large. Use the chunked upload method instead.'); + } + + return new CURLFile($code, 'application/x-gzip', \basename($code)); } - protected function assertDeployment($functionId, $deploymentId, $allowFailure = false) - { - $this->assertEventually(function () use ($functionId, $deploymentId, $allowFailure) { - $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + protected function createDeployment( + string $functionId, + mixed $params, + bool $cli = false, + bool $admin = false + ) { + $authHeaders = $this->getHeaders(); + + if ($admin) { + $authHeaders = [ 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); + ]; + } + if ($cli) { + $authHeaders[] = 'x-sdk-language: cli'; + } - $status = $deployment['body']['status']; + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], - if ($allowFailure && $status === 'failed') { - $this->fail('Deployment failed: ' . json_encode($deployment['body']['buildStderr'])); - } + ], $params); - $this->assertEquals('ready', $status); - }, 180000, 1000); + return $deployment; } - // /** - // * @depends testCreateTeam - // */ - // public function testGetTeam($data):array - // { - // $id = $data['teamUid'] ?? ''; + protected function getFunctionUsage($functionId, $params) + { + $usage = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders(), $params)); - // /** - // * Test for SUCCESS - // */ - // $response = $this->client->call(Client::METHOD_GET, '/teams/'.$id, array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders())); + return $usage; + } - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertNotEmpty($response['body']['$id']); - // $this->assertEquals('Arsenal', $response['body']['name']); - // $this->assertGreaterThan(-1, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertIsInt($response['body']['dateCreated']); + protected function getTemplate(string $templateId) + { + $template = $this->client->call(Client::METHOD_GET, '/functions/templates/' . $templateId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); - // /** - // * Test for FAILURE - // */ + return $template; + } - // return []; - // } + protected function createExecution(string $functionId, mixed $params) + { + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); - // /** - // * @depends testCreateTeam - // */ - // public function testListTeams($data):array - // { - // /** - // * Test for SUCCESS - // */ - // $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders())); + return $execution; + } - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertGreaterThan(0, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertCount(3, $response['body']['teams']); + protected function deleteFunction($functionId) + { + $function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); - // $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'limit' => 2, - // ]); - - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertGreaterThan(0, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertCount(2, $response['body']['teams']); - - // $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'offset' => 1, - // ]); - - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertGreaterThan(0, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertCount(2, $response['body']['teams']); - - // $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'search' => 'Manchester', - // ]); - - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertGreaterThan(0, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertCount(1, $response['body']['teams']); - // $this->assertEquals('Manchester United', $response['body']['teams'][0]['name']); - - // $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'search' => 'United', - // ]); - - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertGreaterThan(0, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertCount(1, $response['body']['teams']); - // $this->assertEquals('Manchester United', $response['body']['teams'][0]['name']); - - // /** - // * Test for FAILURE - // */ - - // return []; - // } - - // public function testUpdateTeam():array - // { - // /** - // * Test for SUCCESS - // */ - // $response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'name' => 'Demo' - // ]); - - // $this->assertEquals(201, $response['headers']['status-code']); - // $this->assertNotEmpty($response['body']['$id']); - // $this->assertEquals('Demo', $response['body']['name']); - // $this->assertGreaterThan(-1, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertIsInt($response['body']['dateCreated']); - - // $response = $this->client->call(Client::METHOD_PUT, '/teams/'.$response['body']['$id'], array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'name' => 'Demo New' - // ]); - - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertNotEmpty($response['body']['$id']); - // $this->assertEquals('Demo New', $response['body']['name']); - // $this->assertGreaterThan(-1, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertIsInt($response['body']['dateCreated']); - - // /** - // * Test for FAILURE - // */ - // $response = $this->client->call(Client::METHOD_PUT, '/teams/'.$response['body']['$id'], array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // ]); - - // $this->assertEquals(400, $response['headers']['status-code']); - - // return []; - // } - - // public function testDeleteTeam():array - // { - // /** - // * Test for SUCCESS - // */ - // $response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'name' => 'Demo' - // ]); - - // $teamUid = $response['body']['$id']; - - // $this->assertEquals(201, $response['headers']['status-code']); - // $this->assertNotEmpty($response['body']['$id']); - // $this->assertEquals('Demo', $response['body']['name']); - // $this->assertGreaterThan(-1, $response['body']['total']); - // $this->assertIsInt($response['body']['total']); - // $this->assertIsInt($response['body']['dateCreated']); - - // $response = $this->client->call(Client::METHOD_DELETE, '/teams/'.$teamUid, array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders())); - - // $this->assertEquals(204, $response['headers']['status-code']); - // $this->assertEmpty($response['body']); - - // /** - // * Test for FAILURE - // */ - // $response = $this->client->call(Client::METHOD_GET, '/teams/'.$teamUid, array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders())); - - // $this->assertEquals(404, $response['headers']['status-code']); - - // return []; - // } + return $function; + } } diff --git a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php index 8cb7f6f869..6ee5a1085d 100644 --- a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php @@ -13,13 +13,11 @@ class FunctionsConsoleClientTest extends Scope { use ProjectCustom; use SideConsole; + use FunctionsBase; public function testCreateFunction(): array { - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function = $this->createFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [Role::user($this->getUser()['$id'])->toString()], @@ -32,87 +30,69 @@ class FunctionsConsoleClientTest extends Scope 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); - + $functionId = $function['body']['$id']; $this->assertEquals(201, $function['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function2 = $this->createFunction([ 'functionId' => ID::unique(), 'name' => 'Test Failure', 'execute' => ['some-random-string'], 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', ]); - - $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals(400, $function2['headers']['status-code']); return [ - 'functionId' => $function['body']['$id'] + 'functionId' => $functionId, ]; } /** * @depends testCreateFunction */ - public function testGetCollectionUsage(array $data) + public function testFunctionUsage(array $data) { - /** - * Test for FAILURE - */ - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'] - ], $this->getHeaders()), [ - 'range' => '232h' - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_GET, '/functions/randomFunctionId/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'] - ], $this->getHeaders()), [ - 'range' => '24h' - ]); - - $this->assertEquals(404, $response['headers']['status-code']); - /** * Test for SUCCESS */ - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'] - ], $this->getHeaders()), [ + $usage = $this->getFunctionUsage($data['functionId'], [ 'range' => '24h' ]); + $this->assertEquals(200, $usage['headers']['status-code']); + $this->assertEquals(19, count($usage['body'])); + $this->assertEquals('24h', $usage['body']['range']); + $this->assertIsNumeric($usage['body']['deploymentsTotal']); + $this->assertIsNumeric($usage['body']['deploymentsStorageTotal']); + $this->assertIsNumeric($usage['body']['buildsTotal']); + $this->assertIsNumeric($usage['body']['buildsStorageTotal']); + $this->assertIsNumeric($usage['body']['buildsTimeTotal']); + $this->assertIsNumeric($usage['body']['buildsMbSecondsTotal']); + $this->assertIsNumeric($usage['body']['executionsTotal']); + $this->assertIsNumeric($usage['body']['executionsTimeTotal']); + $this->assertIsNumeric($usage['body']['executionsMbSecondsTotal']); + $this->assertIsArray($usage['body']['deployments']); + $this->assertIsArray($usage['body']['deploymentsStorage']); + $this->assertIsArray($usage['body']['builds']); + $this->assertIsArray($usage['body']['buildsTime']); + $this->assertIsArray($usage['body']['buildsStorage']); + $this->assertIsArray($usage['body']['buildsTime']); + $this->assertIsArray($usage['body']['buildsMbSeconds']); + $this->assertIsArray($usage['body']['executions']); + $this->assertIsArray($usage['body']['executionsTime']); + $this->assertIsArray($usage['body']['executionsMbSeconds']); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(19, count($response['body'])); - $this->assertEquals('24h', $response['body']['range']); - $this->assertIsNumeric($response['body']['deploymentsTotal']); - $this->assertIsNumeric($response['body']['deploymentsStorageTotal']); - $this->assertIsNumeric($response['body']['buildsTotal']); - $this->assertIsNumeric($response['body']['buildsStorageTotal']); - $this->assertIsNumeric($response['body']['buildsTimeTotal']); - $this->assertIsNumeric($response['body']['buildsMbSecondsTotal']); - $this->assertIsNumeric($response['body']['executionsTotal']); - $this->assertIsNumeric($response['body']['executionsTimeTotal']); - $this->assertIsNumeric($response['body']['executionsMbSecondsTotal']); - $this->assertIsArray($response['body']['deployments']); - $this->assertIsArray($response['body']['deploymentsStorage']); - $this->assertIsArray($response['body']['builds']); - $this->assertIsArray($response['body']['buildsTime']); - $this->assertIsArray($response['body']['buildsStorage']); - $this->assertIsArray($response['body']['buildsTime']); - $this->assertIsArray($response['body']['buildsMbSeconds']); - $this->assertIsArray($response['body']['executions']); - $this->assertIsArray($response['body']['executionsTime']); - $this->assertIsArray($response['body']['executionsMbSeconds']); + /** + * Test for FAILURE + */ + $usage = $this->getFunctionUsage($data['functionId'], [ + 'range' => '232h' + ]); + $this->assertEquals(400, $usage['headers']['status-code']); + + $usage = $this->getFunctionUsage('randomFunctionId', [ + 'range' => '24h' + ]); + $this->assertEquals(404, $usage['headers']['status-code']); } /** @@ -123,31 +103,40 @@ class FunctionsConsoleClientTest extends Scope /** * Test for SUCCESS */ - - $response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => 'APP_TEST', - 'value' => 'TESTINGVALUE' - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $variableId = $response['body']['$id']; + $variable = $this->createVariable( + $data['functionId'], + 'APP_TEST', + 'TESTINGVALUE' + ); + $variableId = $variable['body']['$id']; + $this->assertEquals(201, $variable['headers']['status-code']); /** * Test for FAILURE */ + // Test for duplicate key + $variable = $this->createVariable( + $data['functionId'], + 'APP_TEST', + 'ANOTHER_TESTINGVALUE' + ); + $this->assertEquals(409, $variable['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => 'APP_TEST', - 'value' => 'ANOTHER_TESTINGVALUE' - ]); + // Test for invalid key + $variable = $this->createVariable( + $data['functionId'], + str_repeat("A", 256), + 'TESTINGVALUE' + ); + $this->assertEquals(400, $variable['headers']['status-code']); - $this->assertEquals(409, $response['headers']['status-code']); + // Test for invalid value + $variable = $this->createVariable( + $data['functionId'], + 'LONGKEY', + str_repeat("#", 8193) + ); + $this->assertEquals(400, $variable['headers']['status-code']); return array_merge( $data, @@ -155,28 +144,6 @@ class FunctionsConsoleClientTest extends Scope 'variableId' => $variableId ] ); - - $longKey = str_repeat("A", 256); - $response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => $longKey, - 'value' => 'TESTINGVALUE' - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $longValue = str_repeat("#", 8193); - $response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => 'LONGKEY', - 'value' => $longValue - ]); - - $this->assertEquals(400, $response['headers']['status-code']); } /** diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index f5f15a0fc6..872249085e 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -2,16 +2,12 @@ namespace Tests\E2E\Services\Functions; -use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\Config\Config; -use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; -use Utopia\Database\Query; class FunctionsCustomClientTest extends Scope { @@ -19,15 +15,12 @@ class FunctionsCustomClientTest extends Scope use ProjectCustom; use SideClient; - public function testCreate(): array + public function testCreate() { /** - * Test for SUCCESS + * Test for FAILURE */ - $response1 = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function = $this->createFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'events' => [ @@ -37,22 +30,15 @@ class FunctionsCustomClientTest extends Scope 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); - - $this->assertEquals(401, $response1['headers']['status-code']); - - return []; + $this->assertEquals(401, $function['headers']['status-code']); } - public function testCreateExecution(): array + public function testCreateExecution() { /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_POST, '/functions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [Role::user($this->getUser()['$id'])->toString()], @@ -62,121 +48,41 @@ class FunctionsCustomClientTest extends Scope 'users.*.create', 'users.*.delete', ], - 'schedule' => '* * * * *', // execute every minute + 'schedule' => '* * * * *', // Execute every minute 'timeout' => 10, ]); - - $this->assertEquals(201, $function['headers']['status-code']); - - /** Create Variables */ - $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'key' => 'funcKey1', - 'value' => 'funcValue1', - ]); - - $variable2 = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'key' => 'funcKey2', - 'value' => 'funcValue2', - ]); - - $variable3 = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'key' => 'funcKey3', - 'value' => 'funcValue3', - ]); - - $this->assertEquals(201, $variable['headers']['status-code']); - $this->assertEquals(201, $variable2['headers']['status-code']); - $this->assertEquals(201, $variable3['headers']['status-code']); - - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/deployments', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), + 'code' => $this->packageFunction('php'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $function['body']['$id'] . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], []); - - $this->assertEquals(200, $function['headers']['status-code']); - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], [ - 'async' => true, + $execution = $this->createExecution($functionId, [ + 'async' => false, ]); - $this->assertEquals(401, $execution['headers']['status-code']); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => true, ]); - $this->assertEquals(202, $execution['headers']['status-code']); - $this->assertEventually(function () use ($function) { - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); - + $this->assertEventually(function () use ($functionId) { + $executions = $this->listExecutions($functionId); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertCount(2, $executions['body']['executions']); - // Check if the scheduled execution has completed - $scheduledExecution = $executions['body']['executions'][1]; - $this->assertEquals('schedule', $scheduledExecution['trigger']); - $this->assertEquals('completed', $scheduledExecution['status']); - $this->assertEquals(200, $scheduledExecution['responseStatusCode']); - $this->assertEquals('', $scheduledExecution['responseBody']); - $this->assertNotEmpty($scheduledExecution['logs']); - $this->assertNotEmpty($scheduledExecution['errors']); - $this->assertGreaterThan(0, $scheduledExecution['duration']); - }, 120000, 2000); + $asyncExecution = $executions['body']['executions'][1]; + $this->assertEquals('schedule', $asyncExecution['trigger']); + $this->assertEquals('completed', $asyncExecution['status']); + $this->assertEquals(200, $asyncExecution['responseStatusCode']); + $this->assertEquals('', $asyncExecution['responseBody']); + $this->assertNotEmpty($asyncExecution['logs']); + $this->assertNotEmpty($asyncExecution['errors']); + $this->assertGreaterThan(0, $asyncExecution['duration']); + }, 100000, 250); - // Cleanup : Delete function - $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $function['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], []); - - $this->assertEquals(204, $response['headers']['status-code']); - - return []; + $this->cleanupFunction($functionId); } public function testCreateScheduledExecution(): void @@ -184,11 +90,7 @@ class FunctionsCustomClientTest extends Scope /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_POST, '/functions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [Role::user($this->getUser()['$id'])->toString()], @@ -196,38 +98,20 @@ class FunctionsCustomClientTest extends Scope 'entrypoint' => 'index.php', 'timeout' => 10, ]); - - $this->assertEquals(201, $function['headers']['status-code']); - - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/deployments', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), + 'code' => $this->packageFunction('php'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId, true); // Schedule execution for the future \date_default_timezone_set('UTC'); - $futureTime = (new \DateTime())->add(new \DateInterval('PT2M')); + $futureTime = (new \DateTime())->add(new \DateInterval('PT30S')); // 30 seconds from now $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => true, - 'scheduledAt' => $futureTime->format(\DateTime::ATOM), + 'scheduledAt' => $futureTime->format(\DateTime::ATOM), 'path' => '/custom-path', 'method' => 'PATCH', 'body' => 'custom-body', @@ -235,101 +119,60 @@ class FunctionsCustomClientTest extends Scope 'x-custom-header' => 'custom-value' ] ]); - + $executionId = $execution['body']['$id']; $this->assertEquals(202, $execution['headers']['status-code']); $this->assertEquals('scheduled', $execution['body']['status']); $this->assertEquals('PATCH', $execution['body']['requestMethod']); $this->assertEquals('/custom-path', $execution['body']['requestPath']); $this->assertCount(0, $execution['body']['requestHeaders']); - $executionId = $execution['body']['$id']; - - $this->assertEventually(function () use ($function, $executionId) { - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions/' . $executionId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); - + $this->assertEventually(function () use ($functionId, $executionId) { + $execution = $this->getExecution($functionId, $executionId); $this->assertEquals('completed', $execution['body']['status']); - }, 150000, 2000); // Timeout after 150 seconds, wait 2 seconds between retries - - // After ensuring the execution is completed, fetch it again for assertions - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions/' . $executionId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); - - $this->assertEquals(200, $execution['headers']['status-code']); - $this->assertEquals(200, $execution['body']['responseStatusCode']); - $this->assertEquals('completed', $execution['body']['status']); - $this->assertEquals('/custom-path', $execution['body']['requestPath']); - $this->assertEquals('PATCH', $execution['body']['requestMethod']); - $this->assertStringContainsString('body-is-custom-body', $execution['body']['logs']); - $this->assertStringContainsString('custom-header-is-custom-value', $execution['body']['logs']); - $this->assertStringContainsString('method-is-patch', $execution['body']['logs']); - $this->assertStringContainsString('path-is-/custom-path', $execution['body']['logs']); - $this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']); - $this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']); - $this->assertGreaterThan(0, $execution['body']['duration']); + $this->assertEquals(200, $execution['headers']['status-code']); + $this->assertEquals(200, $execution['body']['responseStatusCode']); + $this->assertEquals('completed', $execution['body']['status']); + $this->assertEquals('/custom-path', $execution['body']['requestPath']); + $this->assertEquals('PATCH', $execution['body']['requestMethod']); + $this->assertStringContainsString('body-is-custom-body', $execution['body']['logs']); + $this->assertStringContainsString('custom-header-is-custom-value', $execution['body']['logs']); + $this->assertStringContainsString('method-is-patch', $execution['body']['logs']); + $this->assertStringContainsString('path-is-/custom-path', $execution['body']['logs']); + $this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']); + $this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']); + $this->assertGreaterThan(0, $execution['body']['duration']); + }, 40000, 2500); /* Test for FAILURE */ - // Schedule synchronous execution - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => false, - 'scheduledAt' => $futureTime->format(\DateTime::ATOM), + 'scheduledAt' => $futureTime->format(\DateTime::ATOM), ]); - $this->assertEquals(400, $execution['headers']['status-code']); // Execution with seconds precision - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => true, 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02"))->format(\DateTime::ATOM) ]); - $this->assertEquals(400, $execution['headers']['status-code']); // Execution with milliseconds precision - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => true, 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02.255"))->format(\DateTime::ATOM) ]); - $this->assertEquals(400, $execution['headers']['status-code']); // Execution too soon - $futureTime = (new \DateTime())->add(new \DateInterval('PT1M')); - $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => true, - 'scheduledAt' => $futureTime->format(\DateTime::ATOM), + 'scheduledAt' => (new \DateTime())->add(new \DateInterval('PT1S'))->format(\DateTime::ATOM) ]); - $this->assertEquals(400, $execution['headers']['status-code']); - // Cleanup : Delete function - $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $function['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], []); - - $this->assertEquals(204, $response['headers']['status-code']); + $this->cleanupFunction($functionId, $executionId); } public function testCreateCustomExecution(): array @@ -337,14 +180,7 @@ class FunctionsCustomClientTest extends Scope /** * Test for SUCCESS */ - $projectId = $this->getProject()['$id']; - $apikey = $this->getProject()['apiKey']; - - $function = $this->client->call(Client::METHOD_POST, '/functions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [Role::any()->toString()], @@ -352,77 +188,16 @@ class FunctionsCustomClientTest extends Scope 'entrypoint' => 'index.php', 'timeout' => 10, ]); - - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - - /** Create Variables */ - $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'key' => 'funcKey1', - 'value' => 'funcValue1', - ]); - - $variable2 = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'key' => 'funcKey2', - 'value' => 'funcValue2', - ]); - - $variable3 = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'key' => 'funcKey3', - 'value' => 'funcValue3', - ]); - - $this->assertEquals(201, $variable['headers']['status-code']); - $this->assertEquals(201, $variable2['headers']['status-code']); - $this->assertEquals(201, $variable3['headers']['status-code']); - - $folder = 'php-fn'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $deploymentId = $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional + 'code' => $this->packageFunction('php-fn'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], []); - - $this->assertEquals(200, $function['headers']['status-code']); - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'body' => 'foobar', 'async' => false ]); - $output = json_decode($execution['body']['responseBody'], true); $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals(200, $execution['body']['responseStatusCode']); @@ -440,30 +215,20 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']); $this->assertEquals($this->getUser()['$id'], $output['APPWRITE_FUNCTION_USER_ID']); $this->assertNotEmpty($output['APPWRITE_FUNCTION_JWT']); - $this->assertEquals($projectId, $output['APPWRITE_FUNCTION_PROJECT_ID']); + $this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'body' => 'foobar', 'async' => true ]); - + $executionId = $execution['body']['$id']; $this->assertEquals(202, $execution['headers']['status-code']); - $executionId = $execution['body']['$id'] ?? ''; - - $this->assertEventually(function () use ($functionId, $executionId, $projectId, $apikey) { - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ]); - + $this->assertEventually(function () use ($functionId, $executionId) { + $execution = $this->getExecution($functionId, $executionId); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); - }, 30000, 1000); + }, 10000, 250); return [ 'functionId' => $functionId @@ -475,14 +240,7 @@ class FunctionsCustomClientTest extends Scope /** * Test for SUCCESS */ - $projectId = $this->getProject()['$id']; - $apikey = $this->getProject()['apiKey']; - - $function = $this->client->call(Client::METHOD_POST, '/functions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [Role::any()->toString()], @@ -495,56 +253,25 @@ class FunctionsCustomClientTest extends Scope ], 'timeout' => 10, ]); - - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - - $folder = 'php-fn'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional + 'code' => $this->packageFunction('php-fn'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - // Why do we have to do this? - $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], []); - - $this->assertEquals(200, $function['headers']['status-code']); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', [ 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, + 'x-appwrite-project' => $this->getProject()['$id'], ], [ 'data' => 'foobar', 'async' => true, ]); - $this->assertEquals(202, $execution['headers']['status-code']); } - public function testCreateExecutionNoDeployment(): array + public function testCreateExecutionNoDeployment() { - $function = $this->client->call(Client::METHOD_POST, '/functions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [], @@ -553,146 +280,18 @@ class FunctionsCustomClientTest extends Scope 'timeout' => 10, ]); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], [ - 'async' => true, + $execution = $this->createExecution($functionId, [ + 'async' => true ]); - $this->assertEquals(404, $execution['headers']['status-code']); - - return []; } - /** - * @depends testCreateCustomExecution - */ - public function testListExecutions(array $data) - { - $functionId = $data['functionId']; - $projectId = $this->getProject()['$id']; - $apikey = $this->getProject()['apiKey']; - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - ], $this->getHeaders()), [ - 'data' => 'foobar' - ]); - - $this->assertEquals(201, $execution['headers']['status-code']); - - $base = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ]); - - $this->assertEquals(200, $base['headers']['status-code']); - $this->assertCount(3, $base['body']['executions']); - $this->assertEquals('completed', $base['body']['executions'][0]['status']); - $this->assertEquals('completed', $base['body']['executions'][1]['status']); - - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'queries' => [ - Query::limit(1)->toString(), - ], - ]); - - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertCount(1, $executions['body']['executions']); - - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'queries' => [ - Query::offset(1)->toString(), - ], - ]); - - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertCount(2, $executions['body']['executions']); - - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'queries' => [ - Query::equal('status', ['completed'])->toString(), - ], - ]); - - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertCount(3, $executions['body']['executions']); - - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'queries' => [ - Query::equal('status', ['failed'])->toString(), - ], - ]); - - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertCount(0, $executions['body']['executions']); - - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'queries' => [ - Query::cursorAfter(new Document(['$id' => $base['body']['executions'][0]['$id']]))->toString(), - ], - ]); - - $this->assertCount(2, $executions['body']['executions']); - $this->assertEquals($base['body']['executions'][1]['$id'], $executions['body']['executions'][0]['$id']); - - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'queries' => [ - Query::cursorBefore(new Document(['$id' => $base['body']['executions'][1]['$id']]))->toString(), - ], - ]); - - // 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']); - } - - public function testSynchronousExecution(): array + public function testSynchronousExecution() { /** * Test for SUCCESS */ - - $projectId = $this->getProject()['$id']; - $apikey = $this->getProject()['apiKey']; - - $function = $this->client->call(Client::METHOD_POST, '/functions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [Role::any()->toString()], @@ -700,79 +299,16 @@ class FunctionsCustomClientTest extends Scope 'entrypoint' => 'index.php', 'timeout' => 10, ]); - - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - - /** Create Variables */ - $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'key' => 'funcKey1', - 'value' => 'funcValue1', - ]); - - $variable2 = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'key' => 'funcKey2', - 'value' => 'funcValue2', - ]); - - $variable3 = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ - 'key' => 'funcKey3', - 'value' => 'funcValue3', - ]); - - $this->assertEquals(201, $variable['headers']['status-code']); - $this->assertEquals(201, $variable2['headers']['status-code']); - $this->assertEquals(201, $variable3['headers']['status-code']); - - $folder = 'php-fn'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $deploymentId = $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional + 'code' => $this->packageFunction('php-fn'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - $function = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ]); - - $this->assertEquals(200, $function['headers']['status-code']); - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'body' => 'foobar', // Testing default value, should be 'async' => false ]); - $output = json_decode($execution['body']['responseBody'], true); $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); @@ -789,67 +325,29 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']); $this->assertEquals($this->getUser()['$id'], $output['APPWRITE_FUNCTION_USER_ID']); $this->assertNotEmpty($output['APPWRITE_FUNCTION_JWT']); - $this->assertEquals($projectId, $output['APPWRITE_FUNCTION_PROJECT_ID']); + $this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']); // Client should never see logs and errors $this->assertEmpty($execution['body']['logs']); $this->assertEmpty($execution['body']['errors']); - // 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']); - - return []; + $this->cleanupFunction($functionId); } - public function testNonOverrideOfHeaders(): array + public function testNonOverrideOfHeaders() { - /** - * Test for SUCCESS - */ - $projectId = $this->getProject()['$id']; - $apikey = $this->getProject()['apiKey']; - - $function = $this->client->call(Client::METHOD_POST, '/functions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'execute' => [Role::any()->toString()], 'runtime' => 'node-18.0', 'entrypoint' => 'index.js' ]); - - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - - $folder = 'node'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $projectId, - 'x-appwrite-key' => $apikey, - ], [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.js', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional + 'code' => $this->packageFunction('node'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -859,23 +357,13 @@ class FunctionsCustomClientTest extends Scope 'x-appwrite-user-id' => "OVERRIDDEN", 'x-appwrite-user-jwt' => "OVERRIDDEN", ]); - $output = json_decode($execution['body']['responseBody'], true); $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_JWT']); $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_EVENT']); $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_TRIGGER']); $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_USER_ID']); - // 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']); - - return []; + $this->cleanupFunction($functionId); } public function testListTemplates() @@ -883,50 +371,43 @@ class FunctionsCustomClientTest extends Scope /** * Test for SUCCESS */ - $expectedTemplates = array_slice(Config::getParam('function-templates', []), 0, 25); + // List all templates $templates = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ 'content-type' => 'application/json', ], $this->getHeaders())); - $this->assertEquals(200, $templates['headers']['status-code']); $this->assertGreaterThan(0, $templates['body']['total']); $this->assertIsArray($templates['body']['templates']); - - $this->assertArrayHasKey('runtimes', $templates['body']['templates'][0]); - $this->assertArrayHasKey('useCases', $templates['body']['templates'][0]); - for ($i = 0; $i < 25; $i++) { - $this->assertEquals($expectedTemplates[$i]['name'], $templates['body']['templates'][$i]['name']); - $this->assertEquals($expectedTemplates[$i]['id'], $templates['body']['templates'][$i]['id']); - $this->assertEquals($expectedTemplates[$i]['icon'], $templates['body']['templates'][$i]['icon']); - $this->assertEquals($expectedTemplates[$i]['tagline'], $templates['body']['templates'][$i]['tagline']); - $this->assertEquals($expectedTemplates[$i]['useCases'], $templates['body']['templates'][$i]['useCases']); - $this->assertEquals($expectedTemplates[$i]['vcsProvider'], $templates['body']['templates'][$i]['vcsProvider']); - $this->assertEquals($expectedTemplates[$i]['runtimes'], $templates['body']['templates'][$i]['runtimes']); - $this->assertEquals($expectedTemplates[$i]['variables'], $templates['body']['templates'][$i]['variables']); - if (array_key_exists('scopes', $expectedTemplates[$i])) { - $this->assertEquals($expectedTemplates[$i]['scopes'], $templates['body']['templates'][$i]['scopes']); - } + foreach ($templates['body']['templates'] as $template) { + $this->assertArrayHasKey('name', $template); + $this->assertArrayHasKey('id', $template); + $this->assertArrayHasKey('icon', $template); + $this->assertArrayHasKey('tagline', $template); + $this->assertArrayHasKey('useCases', $template); + $this->assertArrayHasKey('vcsProvider', $template); + $this->assertArrayHasKey('runtimes', $template); + $this->assertArrayHasKey('variables', $template); + $this->assertArrayHasKey('scopes', $template); } - $templates_offset = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ + // List templates with pagination + $templatesOffset = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ 'content-type' => 'application/json', ], $this->getHeaders()), [ 'limit' => 1, 'offset' => 2 ]); + $this->assertEquals(200, $templatesOffset['headers']['status-code']); + $this->assertEquals(1, $templatesOffset['body']['total']); + $this->assertEquals($templates['body']['templates'][2]['id'], $templatesOffset['body']['templates'][0]['id']); - $this->assertEquals(200, $templates_offset['headers']['status-code']); - $this->assertEquals(1, $templates_offset['body']['total']); - // assert that offset works as expected - $this->assertEquals($templates['body']['templates'][2]['id'], $templates_offset['body']['templates'][0]['id']); - + // List templates with filters $templates = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ 'content-type' => 'application/json', ], $this->getHeaders()), [ 'useCases' => ['starter', 'ai'], 'runtimes' => ['bun-1.0', 'dart-2.16'] ]); - $this->assertEquals(200, $templates['headers']['status-code']); $this->assertGreaterThanOrEqual(3, $templates['body']['total']); $this->assertIsArray($templates['body']['templates']); @@ -936,6 +417,7 @@ class FunctionsCustomClientTest extends Scope $this->assertArrayHasKey('runtimes', $templates['body']['templates'][0]); $this->assertContains('bun-1.0', array_column($templates['body']['templates'][0]['runtimes'], 'name')); + // List templates with pagination and filters $templates = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -958,16 +440,16 @@ class FunctionsCustomClientTest extends Scope /** * Test for FAILURE */ + // List templates with invalid limit $templates = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ 'content-type' => 'application/json', ], $this->getHeaders()), [ 'limit' => 5001, 'offset' => 10, ]); - $this->assertEquals(400, $templates['headers']['status-code']); - $this->assertEquals('Invalid `limit` param: Value must be a valid range between 1 and 5,000', $templates['body']['message']); + // List templates with invalid offset $templates = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -975,9 +457,7 @@ class FunctionsCustomClientTest extends Scope 'limit' => 5, 'offset' => 5001, ]); - $this->assertEquals(400, $templates['headers']['status-code']); - $this->assertEquals('Invalid `offset` param: Value must be a valid range between 0 and 5,000', $templates['body']['message']); } public function testGetTemplate() @@ -985,10 +465,7 @@ class FunctionsCustomClientTest extends Scope /** * Test for SUCCESS */ - $template = $this->client->call(Client::METHOD_GET, '/functions/templates/query-neo4j-auradb', array_merge([ - 'content-type' => 'application/json', - ], $this->getHeaders()), []); - + $template = $this->getTemplate('query-neo4j-auradb'); $this->assertEquals(200, $template['headers']['status-code']); $this->assertIsArray($template['body']); $this->assertEquals('query-neo4j-auradb', $template['body']['id']); @@ -997,15 +474,13 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals('Graph database with focus on relations between data.', $template['body']['tagline']); $this->assertEquals(['databases'], $template['body']['useCases']); $this->assertEquals('github', $template['body']['vcsProvider']); + $this->assertIsArray($template['body']['runtimes']); + $this->assertIsArray($template['body']['scopes']); /** * Test for FAILURE */ - $template = $this->client->call(Client::METHOD_GET, '/functions/templates/invalid-template-id', array_merge([ - 'content-type' => 'application/json', - ], $this->getHeaders()), []); - + $template = $this->getTemplate('invalid-template-id'); $this->assertEquals(404, $template['headers']['status-code']); - $this->assertEquals('Function Template with the requested ID could not be found.', $template['body']['message']); } } diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 193e99d89e..8fe4aedca7 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -388,12 +388,9 @@ class FunctionsCustomServerTest extends Scope public function testCreateDeploymentFromCLI() { - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function = $this->createFunction([ 'functionId' => ID::unique(), - 'name' => 'Test', + 'name' => 'test-cli-deployment', 'execute' => [Role::user($this->getUser()['$id'])->toString()], 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', @@ -401,210 +398,127 @@ class FunctionsCustomServerTest extends Scope 'users.*.create', 'users.*.delete', ], - 'schedule' => '0 0 1 1 *', + 'schedule' => '0 0 1 1 *', // Once a year 'timeout' => 10, ]); + $functionId = $function['body']['$id']; $this->assertEquals(201, $function['headers']['status-code']); - $functionId = $function['body']['$id']; - - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/deployments', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - 'x-sdk-language' => 'cli', - ], [ + $deployment = $this->createDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), + 'code' => $this->packageFunction('php'), 'activate' => true - ]); - - $deploymentId = $deployment['body']['$id'] ?? ''; + ], cli: true); + $deploymentId = $deployment['body']['$id']; $this->assertEquals(202, $deployment['headers']['status-code']); + $this->assertDeploymentStatus($functionId, $deploymentId, 'ready'); - $this->assertDeployment($function['body']['$id'], $deploymentId); - - $functionDetails = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], []); - - $this->assertEquals(200, $functionDetails['headers']['status-code']); - $this->assertEquals('cli', $functionDetails['body']['type']); + $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); + $this->assertEquals('cli', $deployment['body']['type']); } public function testCreateDeploymentFromTemplate() { - $runtimeName = 'php-8.0'; - // Fetch starter template (used to create function later) - $template = $this->client->call(Client::METHOD_GET, '/functions/templates/starter', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $starterTemplate = $this->getTemplate('starter'); + $this->assertEquals(200, $starterTemplate['headers']['status-code']); - $this->assertEquals(200, $template['headers']['status-code']); + $phpRuntime = array_values(array_filter($starterTemplate['body']['runtimes'], function ($runtime) { + return $runtime['name'] === 'php-8.0'; + }))[0]; - $entrypoint = null; - $rootDirectory = null; - $commands = null; - foreach ($template['body']['runtimes'] as $runtime) { - if ($runtime["name"] !== $runtimeName) { - continue; - } - - $entrypoint = $runtime["entrypoint"]; - $rootDirectory = $runtime["providerRootDirectory"]; - $commands = $runtime["commands"]; - break; - } - - $this->assertNotNull($entrypoint); - - /** - * If below test ever starts failing, it means temaplate used in - * this test now has some variables. This test currently doesnt test variables. - * Remove bellow assertion and update test to crete variable, - * and ensure variable works as expected in execution. - */ - $this->assertEmpty($template['body']['variables']); - - // Create function using settings from template. - // Deployment is automatically created from template inside endpoint - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], $this->getHeaders()), [ - 'functionId' => ID::unique(), - 'name' => $template['body']['name'], - 'runtime' => $runtimeName, - 'execute' => $template['body']['permissions'], - 'entrypoint' => $entrypoint, - 'events' => $template['body']['events'], - 'schedule' => $template['body']['cron'], - 'timeout' => $template['body']['timeout'], - 'commands' => $commands, - 'scopes' => $template['body']['scopes'], - 'templateRepository' => $template['body']['providerRepositoryId'], - 'templateOwner' => $template['body']['providerOwner'], - 'templateRootDirectory' => $rootDirectory, - 'templateVersion' => $template['body']['providerVersion'], - ]); + // If this fails, the template has variables, and this test needs to be updated + $this->assertEmpty($starterTemplate['body']['variables']); + $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'], + ] + ); + $functionId = $function['body']['$id']; $this->assertEquals(201, $function['headers']['status-code']); $this->assertNotEmpty($function['body']['$id']); - $functionId = $function['body']['$id']; - - // List deployments so we can await deployment build - $deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], []); - + $deployments = $this->listDeployments($functionId); $this->assertEquals(200, $deployments['headers']['status-code']); $this->assertEquals(1, $deployments['body']['total']); - $this->assertNotEmpty($deployments['body']['deployments'][0]['$id']); - $this->assertEquals(0, $deployments['body']['deployments'][0]['size']); - $deploymentId = $deployments['body']['deployments'][0]['$id']; + $lastDeployment = $deployments['body']['deployments'][0]; + $this->assertNotEmpty($lastDeployment['$id']); + $this->assertEquals(0, $lastDeployment['size']); - // Wait for deployment build to finish - // Deployment is automatically activated - $this->assertDeployment($function['body']['$id'], $deploymentId); + $deploymentId = $lastDeployment['$id']; + $this->assertDeploymentStatus($function['body']['$id'], $deploymentId, 'ready'); - $deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], []); - $this->assertGreaterThan(0, $deployments['body']['size']); - - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], $this->getHeaders()), []); + $deployment = $this->getDeployment($function['body']['$id'], $deploymentId); + $this->assertGreaterThan(0, $deployment['body']['size']); + $function = $this->getFunction($functionId); $this->assertEquals(200, $function['headers']['status-code']); $this->assertEquals($deploymentId, $function['body']['deployment']); - // Execute function to ensure starter code is used - // Also tests if dynamic keys works as expected - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'path' => '/ping' + // Test starter code is used and that dynamic keys work + $execution = $this->createExecution($functionId, [ + 'path' => '/ping', ]); - $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']); - // Get users to ensure execution logged correct total users + // Test execution logged correct total users $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()), []); - $this->assertEquals(200, $users['headers']['status-code']); $this->assertIsInt($users['body']['total']); - $totalusers = $users['body']['total']; - - $this->assertStringContainsString("Total users: " . $totalusers, $execution['body']['logs']); + $totalUsers = $users['body']['total']; + $this->assertStringContainsString("Total users: " . $totalUsers, $execution['body']['logs']); // Execute function again but async - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'path' => '/ping', 'async' => true ]); - + $executionId = $execution['body']['$id']; $this->assertEquals(202, $execution['headers']['status-code']); $this->assertNotEmpty($execution['body']['$id']); $this->assertEquals('waiting', $execution['body']['status']); - $executionId = $execution['body']['$id']; - // Wait for async execuntion to finish - sleep(5); + $this->assertEventually(function () use ($functionId, $executionId, $totalUsers) { + $execution = $this->getExecution($functionId, $executionId); - // Ensure execution was successful - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); + $this->assertEquals('completed', $execution['body']['status']); + $this->assertEquals(200, $execution['headers']['status-code']); + $this->assertEquals("completed", $execution['body']['status']); + $this->assertEquals(200, $execution['body']['responseStatusCode']); + $this->assertEmpty($execution['body']['responseBody']); + $this->assertEmpty($execution['body']['errors']); + $this->assertStringContainsString("Total users: " . $totalUsers, $execution['body']['logs']); + }, 100000, 250); - $this->assertEquals(200, $execution['headers']['status-code']); - $this->assertEquals("completed", $execution['body']['status']); - $this->assertEquals(200, $execution['body']['responseStatusCode']); - $this->assertEmpty($execution['body']['responseBody']); - $this->assertEmpty($execution['body']['errors']); - $this->assertStringContainsString("Total users: " . $totalusers, $execution['body']['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']); + $function = $this->deleteFunction($functionId); + $this->assertEquals(204, $function['headers']['status-code']); } /** @@ -615,15 +529,11 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), + 'code' => $this->packageFunction('php'), 'activate' => true ]); @@ -640,7 +550,7 @@ class FunctionsCustomServerTest extends Scope 'content-type' => 'multipart/form-data', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), + 'code' => $this->packageFunction('php'), 'activate' => 'false' ]); @@ -675,16 +585,11 @@ class FunctionsCustomServerTest extends Scope */ public function testCancelDeploymentBuild($data): void { - // Create a new deployment to cancel - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), + 'code' => $this->packageFunction('php'), 'activate' => true ]); @@ -1406,16 +1311,6 @@ class FunctionsCustomServerTest extends Scope $executionId = $execution['body']['$id'] ?? ''; $this->assertEquals(202, $execution['headers']['status-code']); - $this->assertEventually(function () use ($data, $executionId) { - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions/' . $executionId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]); - - $this->assertEquals(200, $execution['headers']['status-code']); - $this->assertEquals('waiting', $execution['body']['status']); - }, 10000, 500); - $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $executionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1580,87 +1475,41 @@ class FunctionsCustomServerTest extends Scope public function testTimeout() { - $name = 'php-8.0'; - $entrypoint = 'index.php'; - $timeout = 15; - $folder = 'timeout'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $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 ' . $name, - 'runtime' => $name, - 'entrypoint' => $entrypoint, + $function = $this->createFunction([ + 'name' => 'timeout-php-8.0', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', 'events' => [], - 'schedule' => '* * * * *', // execute every minute - 'timeout' => $timeout, + 'schedule' => '*/10 * * * *', // Execute every 10 seconds + 'timeout' => 15, ]); - - $functionId = $function['body']['$id'] ?? ''; - + $functionId = $function['body']['id']; $this->assertEquals(201, $function['headers']['status-code']); - $this->assertEquals('* * * * *', $function['body']['schedule']); - $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' => $entrypoint, - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), - 'activate' => true, - ]); - - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($functionId, $deploymentId); - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'async' => true, - ]); + $deployment = $this->createDeployment($functionId, 'php'); + $deploymentId = $deployment['body']['$id']; + $this->assertDeploymentStatus($functionId, $deploymentId, 'ready'); + $execution = $this->createExecution($functionId, ['async' => true]); $executionId = $execution['body']['$id'] ?? ''; - $this->assertEquals(202, $execution['headers']['status-code']); - $executionData = null; + $this->assertEventually(function () use ($functionId, $executionId) { + $execution = $this->getExecution($functionId, $executionId); - $this->assertEventually(function () use ($functionId, $executionId, &$executionData) { - $executionData = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $this->assertEquals(200, $execution['headers']['status-code']); + $this->assertEquals('failed', $execution['body']['status']); + $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']); + }, 20000, 500); - $this->assertEquals(200, $executionData['headers']['status-code']); - $this->assertEquals('failed', $executionData['body']['status']); - - if ($executionData['body']['status'] !== 'failed') { - } - }, 30000, 1000); - - $this->assertEquals('failed', $executionData['body']['status']); - $this->assertEquals(500, $executionData['body']['responseStatusCode']); - $this->assertGreaterThan(2, $executionData['body']['duration']); - $this->assertLessThan(20, $executionData['body']['duration']); - $this->assertEquals('', $executionData['body']['responseBody']); - $this->assertEquals('', $executionData['body']['logs']); - $this->assertStringContainsString('timed out', $executionData['body']['errors']); - - $scheduledExecutionData = null; - - $this->assertEventually(function () use ($functionId, &$scheduledExecutionData) { - $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->assertEventually(function () use ($functionId) { + $executions = $this->listExecutions($functionId, [ 'queries' => [ Query::equal('trigger', ['schedule'])->toString(), ], @@ -1669,19 +1518,12 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals(1, $executions['body']['total']); - $scheduledExecutionData = $executions['body']['executions'][0]; - }, 140000, 1000); // Wait up to 140 seconds, checking every 1 second + $lastExecution = $executions['body']['executions'][0]; + $this->assertEquals('schedule', $lastExecution['trigger']); + }, 20000, 500); - $this->assertEquals('schedule', $scheduledExecutionData['trigger']); - - // 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']); + $function = $this->deleteFunction($functionId); + $this->assertEquals(204, $function['headers']['status-code']); } From af509f3479a25def65685e090d33bf4ee6cd41f1 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:17:38 +0100 Subject: [PATCH 133/213] fix: flakyness --- .../e2e/Services/Functions/FunctionsBase.php | 78 +++++++------------ .../Functions/FunctionsConsoleClientTest.php | 24 ++++-- .../Functions/FunctionsCustomClientTest.php | 10 ++- 3 files changed, 51 insertions(+), 61 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 92210a3027..cdb4781e5e 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -21,27 +21,26 @@ trait FunctionsBase 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ]), $params); - $functionId = $function['body']['$id']; + $this->assertEquals($function['headers']['status-code'], 201, 'Setup function failed with status code: ' . $function['headers']['status-code'] . ' and response: ' . json_encode($function['body'])); - $this->assertEquals($function['headers']['status-code'], 201); + $functionId = $function['body']['$id']; return $functionId; } protected function setupDeployment(string $functionId, mixed $params): string { $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ - 'content-type' => 'application/json', + 'content-type' => 'multipart/form-data', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ]), $params); + $this->assertEquals($deployment['headers']['status-code'], 202, 'Setup deployment failed with status code: ' . $deployment['headers']['status-code'] . ' and response: ' . json_encode($deployment['body'])); $deploymentId = $deployment['body']['$id']; - $this->assertEquals($deployment['headers']['status-code'], 202); - $this->assertEventually(function () use ($functionId, $deploymentId) { $deployment = $this->getDeployment($functionId, $deploymentId); $this->assertEquals('completed', $deployment['body']['status']); - }, 200000, 500); + }, 50000, 500); return $deploymentId; } @@ -57,40 +56,27 @@ trait FunctionsBase $this->assertEquals($function['headers']['status-code'], 204); } - protected function createFunction(mixed $params) + protected function createFunction(mixed $params): mixed { $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), $params); - $functionId = $function['body']['$id']; - - if (empty($variables)) { - return $function; - } - - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); return $function; } - protected function createVariable($functionId, $key, $value) + protected function createVariable(string $functionId, mixed $params): mixed { $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => $key, - 'value' => $value - ]); + ], $this->getHeaders()), $params); return $variable; } - protected function getFunction($functionId) + protected function getFunction(string $functionId): mixed { $function = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, array_merge([ 'content-type' => 'application/json', @@ -100,7 +86,7 @@ trait FunctionsBase return $function; } - protected function getDeployment($functionId, $deploymentId) + protected function getDeployment(string $functionId, string $deploymentId): mixed { $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', @@ -120,12 +106,22 @@ trait FunctionsBase return $execution; } + protected function listFunctions($params = []) + { + $functions = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $functions; + } + protected function listDeployments($functionId, $params = []) { $deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders(), $params)); + ], $this->getHeaders()), $params); return $deployments; } @@ -135,19 +131,17 @@ trait FunctionsBase $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders(), $params)); + ], $this->getHeaders()), $params); return $executions; } - protected function packageFunction(string $folder = 'php') + protected function packageFunction(string $folder = 'php'): CURLFile { $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); - if (!file_exists($code)) { - throw new \Exception('Failed to create code package. ' . $code . ' does not exist.'); + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); } if (filesize($code) > 1024 * 1024 * 5) { throw new \Exception('Code package is too large. Use the chunked upload method instead.'); @@ -158,36 +152,22 @@ trait FunctionsBase protected function createDeployment( string $functionId, - mixed $params, - bool $cli = false, - bool $admin = false + mixed $params ) { - $authHeaders = $this->getHeaders(); - - if ($admin) { - $authHeaders = [ - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]; - } - if ($cli) { - $authHeaders[] = 'x-sdk-language: cli'; - } - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', 'x-appwrite-project' => $this->getProject()['$id'], - - ], $params); + ], $this->getHeaders()), $params); return $deployment; } - protected function getFunctionUsage($functionId, $params) + protected function getFunctionUsage(string $functionId, mixed $params): mixed { $usage = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders(), $params)); + ], $this->getHeaders()), $params); return $usage; } diff --git a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php index 6ee5a1085d..cbfca09564 100644 --- a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php @@ -105,8 +105,10 @@ class FunctionsConsoleClientTest extends Scope */ $variable = $this->createVariable( $data['functionId'], - 'APP_TEST', - 'TESTINGVALUE' + [ + 'key' => 'APP_TEST', + 'value' => 'TESTINGVALUE' + ] ); $variableId = $variable['body']['$id']; $this->assertEquals(201, $variable['headers']['status-code']); @@ -117,24 +119,30 @@ class FunctionsConsoleClientTest extends Scope // Test for duplicate key $variable = $this->createVariable( $data['functionId'], - 'APP_TEST', - 'ANOTHER_TESTINGVALUE' + [ + 'key' => 'APP_TEST', + 'value' => 'ANOTHERTESTINGVALUE' + ] ); $this->assertEquals(409, $variable['headers']['status-code']); // Test for invalid key $variable = $this->createVariable( $data['functionId'], - str_repeat("A", 256), - 'TESTINGVALUE' + [ + 'key' => str_repeat("A", 256), + 'value' => 'TESTINGVALUE' + ] ); $this->assertEquals(400, $variable['headers']['status-code']); // Test for invalid value $variable = $this->createVariable( $data['functionId'], - 'LONGKEY', - str_repeat("#", 8193) + [ + 'key' => 'LONGKEY', + 'value' => str_repeat("#", 8193), + ] ); $this->assertEquals(400, $variable['headers']['status-code']); diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 872249085e..1dc81c8171 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -15,7 +15,7 @@ class FunctionsCustomClientTest extends Scope use ProjectCustom; use SideClient; - public function testCreate() + public function testCreateFunction() { /** * Test for FAILURE @@ -80,7 +80,7 @@ class FunctionsCustomClientTest extends Scope $this->assertNotEmpty($asyncExecution['logs']); $this->assertNotEmpty($asyncExecution['errors']); $this->assertGreaterThan(0, $asyncExecution['duration']); - }, 100000, 250); + }, 10000, 250); $this->cleanupFunction($functionId); } @@ -106,7 +106,7 @@ class FunctionsCustomClientTest extends Scope // Schedule execution for the future \date_default_timezone_set('UTC'); - $futureTime = (new \DateTime())->add(new \DateInterval('PT30S')); // 30 seconds from now + $futureTime = (new \DateTime())->add(new \DateInterval('PT15S')); // 15 seconds from now $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); $execution = $this->createExecution($functionId, [ @@ -126,6 +126,8 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals('/custom-path', $execution['body']['requestPath']); $this->assertCount(0, $execution['body']['requestHeaders']); + \sleep(15); + $this->assertEventually(function () use ($functionId, $executionId) { $execution = $this->getExecution($functionId, $executionId); $this->assertEquals('completed', $execution['body']['status']); @@ -141,7 +143,7 @@ class FunctionsCustomClientTest extends Scope $this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']); $this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']); $this->assertGreaterThan(0, $execution['body']['duration']); - }, 40000, 2500); + }, 10000, 250); /* Test for FAILURE */ // Schedule synchronous execution From d6d7cf1d9fbaec70274b2dbcb6b143cbd7061730 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 19 Sep 2024 18:27:02 +0300 Subject: [PATCH 134/213] Pull 1.6.x --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index c0f3333469..079c8d749f 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -151,7 +151,7 @@ abstract class ScheduleBase extends Action $total = $total + $sum; foreach ($results as $document) { - $localDocument = $schedules[$document['resourceId']] ?? null; + $localDocument = $this->schedules[$document['resourceId']] ?? null; // Check if resource has been updated since last sync $org = $localDocument !== null ? \strtotime($localDocument['resourceUpdatedAt']) : null; From 9a0c72294c19ab9d7f84c27befed05f690bb5408 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 19 Sep 2024 18:37:09 +0300 Subject: [PATCH 135/213] composer.lock --- composer.lock | 62 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/composer.lock b/composer.lock index 147800df32..d2a5d88fb9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b6820da26239716cf14a445697902a03", + "content-hash": "67946bb84bca00b694c8a41fbe41f359", "packages": [ { "name": "adhocore/jwt", @@ -65,16 +65,16 @@ }, { "name": "appwrite/appwrite", - "version": "10.1.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-for-php.git", - "reference": "da579af70723cfc117b5af84375bdef117e27312" + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/da579af70723cfc117b5af84375bdef117e27312", - "reference": "da579af70723cfc117b5af84375bdef117e27312", + "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/1d043f543acdb17b9fdb440b1b2dd208e400bad3", + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3", "shasum": "" }, "require": { @@ -83,7 +83,8 @@ "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "3.7.35" + "mockery/mockery": "^1.6.6", + "phpunit/phpunit": "^10" }, "type": "library", "autoload": { @@ -99,10 +100,10 @@ "support": { "email": "team@appwrite.io", "issues": "https://github.com/appwrite/sdk-for-php/issues", - "source": "https://github.com/appwrite/sdk-for-php/tree/10.1.0", + "source": "https://github.com/appwrite/sdk-for-php/tree/11.1.0", "url": "https://appwrite.io/support" }, - "time": "2023-11-20T09:56:12+00:00" + "time": "2024-06-26T07:03:23+00:00" }, { "name": "appwrite/php-clamav", @@ -2174,27 +2175,35 @@ }, { "name": "utopia-php/migration", - "version": "0.5.2", + "version": "dev-preserveDates", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "f18d44d4459f78c292dac9edde856fd156fe497a" + "reference": "c5ac9347448e34832ff0bd1f9d3d90c54cd6e2fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/f18d44d4459f78c292dac9edde856fd156fe497a", - "reference": "f18d44d4459f78c292dac9edde856fd156fe497a", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/c5ac9347448e34832ff0bd1f9d3d90c54cd6e2fe", + "reference": "c5ac9347448e34832ff0bd1f9d3d90c54cd6e2fe", "shasum": "" }, "require": { - "appwrite/appwrite": "10.1.0", - "php": "8.*" + "appwrite/appwrite": "11.1.*", + "ext-curl": "*", + "ext-openssl": "*", + "php": "8.3.*", + "utopia-php/database": "0.53.*", + "utopia-php/dsn": "0.2.*", + "utopia-php/framework": "0.33.*", + "utopia-php/storage": "0.18.*" }, "require-dev": { - "laravel/pint": "1.*", - "phpunit/phpunit": "9.*", - "utopia-php/cli": "^0.18.0", - "vlucas/phpdotenv": "5.*" + "ext-pdo": "*", + "laravel/pint": "1.17.*", + "phpstan/phpstan": "1.11.*", + "phpunit/phpunit": "11.2.*", + "utopia-php/cli": "0.16.*", + "vlucas/phpdotenv": "5.6.*" }, "type": "library", "autoload": { @@ -2216,9 +2225,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.5.2" + "source": "https://github.com/utopia-php/migration/tree/preserveDates" }, - "time": "2024-07-22T09:27:07+00:00" + "time": "2024-09-19T15:32:44+00:00" }, { "name": "utopia-php/mongo", @@ -6993,9 +7002,18 @@ "time": "2024-03-07T20:33:40+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/migration", + "version": "dev-preserveDates", + "alias": "0.6.0", + "alias_normalized": "0.6.0.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/migration": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From 964b616e05b3c6ee2c1ba3b03b276deb95c59ee8 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:21:00 +0100 Subject: [PATCH 136/213] fix: refactor custom server test --- .../e2e/Services/Functions/FunctionsBase.php | 16 +- .../Functions/FunctionsCustomClientTest.php | 37 +- .../Functions/FunctionsCustomServerTest.php | 1582 +++++------------ 3 files changed, 481 insertions(+), 1154 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index cdb4781e5e..730c7bff48 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -21,7 +21,7 @@ trait FunctionsBase 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ]), $params); - $this->assertEquals($function['headers']['status-code'], 201, 'Setup function failed with status code: ' . $function['headers']['status-code'] . ' and response: ' . json_encode($function['body'])); + $this->assertEquals($function['headers']['status-code'], 201, 'Setup function failed with status code: ' . $function['headers']['status-code'] . ' and response: ' . json_encode($function['body'], JSON_PRETTY_PRINT)); $functionId = $function['body']['$id']; return $functionId; @@ -34,12 +34,16 @@ trait FunctionsBase 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ]), $params); - $this->assertEquals($deployment['headers']['status-code'], 202, 'Setup deployment failed with status code: ' . $deployment['headers']['status-code'] . ' and response: ' . json_encode($deployment['body'])); - $deploymentId = $deployment['body']['$id']; + $this->assertEquals($deployment['headers']['status-code'], 202, 'Setup deployment failed with status code: ' . $deployment['headers']['status-code'] . ' and response: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT)); + $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEventually(function () use ($functionId, $deploymentId) { - $deployment = $this->getDeployment($functionId, $deploymentId); - $this->assertEquals('completed', $deployment['body']['status']); + $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ])); + $this->assertEquals('ready', $deployment['body']['status']); }, 50000, 500); return $deploymentId; @@ -182,7 +186,7 @@ trait FunctionsBase return $template; } - protected function createExecution(string $functionId, mixed $params) + protected function createExecution(string $functionId, mixed $params = []) { $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 1dc81c8171..dd950ca655 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -48,7 +48,7 @@ class FunctionsCustomClientTest extends Scope 'users.*.create', 'users.*.delete', ], - 'schedule' => '* * * * *', // Execute every minute + 'schedule' => '* * * * *', // Execute every 60 seconds 'timeout' => 10, ]); $this->setupDeployment($functionId, [ @@ -57,18 +57,30 @@ class FunctionsCustomClientTest extends Scope 'activate' => true ]); - $execution = $this->createExecution($functionId, [ - 'async' => false, + // Deny create async execution as guest + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], [ + 'async' => true, ]); $this->assertEquals(401, $execution['headers']['status-code']); + // Allow create async execution as user $execution = $this->createExecution($functionId, [ 'async' => true, ]); $this->assertEquals(202, $execution['headers']['status-code']); + // Wait for scheduled execution + \sleep(60); + $this->assertEventually(function () use ($functionId) { - $executions = $this->listExecutions($functionId); + $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['key'], + ]); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertCount(2, $executions['body']['executions']); @@ -80,7 +92,7 @@ class FunctionsCustomClientTest extends Scope $this->assertNotEmpty($asyncExecution['logs']); $this->assertNotEmpty($asyncExecution['errors']); $this->assertGreaterThan(0, $asyncExecution['duration']); - }, 10000, 250); + }, 10000, 500); $this->cleanupFunction($functionId); } @@ -97,6 +109,7 @@ class FunctionsCustomClientTest extends Scope 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'timeout' => 10, + 'logging' => true, ]); $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', @@ -106,7 +119,7 @@ class FunctionsCustomClientTest extends Scope // Schedule execution for the future \date_default_timezone_set('UTC'); - $futureTime = (new \DateTime())->add(new \DateInterval('PT15S')); // 15 seconds from now + $futureTime = (new \DateTime())->add(new \DateInterval('PT2M')); // 2 minute in the future $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); $execution = $this->createExecution($functionId, [ @@ -120,17 +133,18 @@ class FunctionsCustomClientTest extends Scope ] ]); $executionId = $execution['body']['$id']; + $this->assertEquals(202, $execution['headers']['status-code']); $this->assertEquals('scheduled', $execution['body']['status']); $this->assertEquals('PATCH', $execution['body']['requestMethod']); $this->assertEquals('/custom-path', $execution['body']['requestPath']); $this->assertCount(0, $execution['body']['requestHeaders']); - \sleep(15); + \sleep(120); $this->assertEventually(function () use ($functionId, $executionId) { $execution = $this->getExecution($functionId, $executionId); - $this->assertEquals('completed', $execution['body']['status']); + $this->assertEquals(200, $execution['headers']['status-code']); $this->assertEquals(200, $execution['body']['responseStatusCode']); $this->assertEquals('completed', $execution['body']['status']); @@ -143,7 +157,7 @@ class FunctionsCustomClientTest extends Scope $this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']); $this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']); $this->assertGreaterThan(0, $execution['body']['duration']); - }, 10000, 250); + }, 10000, 500); /* Test for FAILURE */ // Schedule synchronous execution @@ -377,9 +391,11 @@ class FunctionsCustomClientTest extends Scope $templates = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ 'content-type' => 'application/json', ], $this->getHeaders())); + $this->assertEquals(200, $templates['headers']['status-code']); $this->assertGreaterThan(0, $templates['body']['total']); $this->assertIsArray($templates['body']['templates']); + foreach ($templates['body']['templates'] as $template) { $this->assertArrayHasKey('name', $template); $this->assertArrayHasKey('id', $template); @@ -389,7 +405,6 @@ class FunctionsCustomClientTest extends Scope $this->assertArrayHasKey('vcsProvider', $template); $this->assertArrayHasKey('runtimes', $template); $this->assertArrayHasKey('variables', $template); - $this->assertArrayHasKey('scopes', $template); } // List templates with pagination @@ -434,9 +449,11 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(5, $templates['body']['total']); $this->assertIsArray($templates['body']['templates']); $this->assertArrayHasKey('runtimes', $templates['body']['templates'][0]); + foreach ($templates['body']['templates'] as $template) { $this->assertContains($template['useCases'][0], ['databases']); } + $this->assertContains('node-16.0', array_column($templates['body']['templates'][0]['runtimes'], 'name')); /** diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 8fe4aedca7..80f34d6d34 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -10,27 +10,27 @@ use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; use Utopia\App; +use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\Database\Validator\Datetime as DatetimeValidator; +use function PHPSTORM_META\map; + class FunctionsCustomServerTest extends Scope { use FunctionsBase; use ProjectCustom; use SideServer; - public function testCreate(): array + public function testCreateFunction(): array { /** * Test for SUCCESS */ - $response1 = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function = $this->createFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'runtime' => 'php-8.0', @@ -42,162 +42,115 @@ class FunctionsCustomServerTest extends Scope 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); - - $functionId = $response1['body']['$id'] ?? ''; - - $this->assertEquals(201, $response1['headers']['status-code']); - $this->assertNotEmpty($response1['body']['$id']); - $this->assertEquals('Test', $response1['body']['name']); - $this->assertEquals('php-8.0', $response1['body']['runtime']); + $functionId = $functionId = $function['body']['$id'] ?? ''; $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response1['body']['$createdAt'])); - $this->assertEquals(true, $dateValidator->isValid($response1['body']['$updatedAt'])); - $this->assertEquals('', $response1['body']['deployment']); + $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']); $this->assertEquals([ 'buckets.*.create', 'buckets.*.delete', - ], $response1['body']['events']); - $this->assertEquals('0 0 1 1 *', $response1['body']['schedule']); - $this->assertEquals(10, $response1['body']['timeout']); + ], $function['body']['events']); + $this->assertEquals('0 0 1 1 *', $function['body']['schedule']); + $this->assertEquals(10, $function['body']['timeout']); - /** Create Variables */ - $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $variable = $this->createVariable($functionId, [ 'key' => 'funcKey1', 'value' => 'funcValue1', ]); - - $variable2 = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $variable2 = $this->createVariable($functionId, [ 'key' => 'funcKey2', 'value' => 'funcValue2', ]); - - $variable3 = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $variable3 = $this->createVariable($functionId, [ 'key' => 'funcKey3', 'value' => 'funcValue3', ]); - $this->assertEquals(201, $variable['headers']['status-code']); $this->assertEquals(201, $variable2['headers']['status-code']); $this->assertEquals(201, $variable3['headers']['status-code']); - /** - * Test for FAILURE - */ - return [ 'functionId' => $functionId, ]; } /** - * @depends testCreate + * @depends testCreateFunction */ - public function testList(array $data): array + public function testListFunctions(array $data): array { /** * Test for SUCCESS */ - - /** - * Test search queries - */ - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test search id + $functions = $this->listFunctions([ 'search' => $data['functionId'] ]); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(1, $functions['body']['functions']); + $this->assertEquals($functions['body']['functions'][0]['name'], 'Test'); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(1, $response['body']['functions']); - $this->assertEquals($response['body']['functions'][0]['name'], 'Test'); - - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test pagination limit + $functions = $this->listFunctions([ 'queries' => [ Query::limit(1)->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(1, $functions['body']['functions']); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(1, $response['body']['functions']); - - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test pagination offset + $functions = $this->listFunctions([ 'queries' => [ Query::offset(1)->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(0, $functions['body']['functions']); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(0, $response['body']['functions']); - - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test filter enabled + $functions = $this->listFunctions([ 'queries' => [ Query::equal('enabled', [true])->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(1, $functions['body']['functions']); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(1, $response['body']['functions']); - - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test filter disabled + $functions = $this->listFunctions([ 'queries' => [ Query::equal('enabled', [false])->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(0, $functions['body']['functions']); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(0, $response['body']['functions']); - - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test search name + $functions = $this->listFunctions([ 'search' => 'Test' ]); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(1, $functions['body']['functions']); + $this->assertEquals($functions['body']['functions'][0]['$id'], $data['functionId']); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(1, $response['body']['functions']); - $this->assertEquals($response['body']['functions'][0]['$id'], $data['functionId']); - - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test search runtime + $functions = $this->listExecutions([ 'search' => 'php-8.0' ]); - - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(1, $response['body']['functions']); - $this->assertEquals($response['body']['functions'][0]['$id'], $data['functionId']); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(1, $functions['body']['functions']); + $this->assertEquals($functions['body']['functions'][0]['$id'], $data['functionId']); /** * Test pagination */ - $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test 2', 'runtime' => 'php-8.0', @@ -209,42 +162,8 @@ class FunctionsCustomServerTest extends Scope 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); - $this->assertNotEmpty($response['body']['$id']); - - /** Create Variables */ - $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $response['body']['$id'] . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => 'funcKey1', - 'value' => 'funcValue1', - ]); - - $variable2 = $this->client->call(Client::METHOD_POST, '/functions/' . $response['body']['$id'] . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => 'funcKey2', - 'value' => 'funcValue2', - ]); - - $variable3 = $this->client->call(Client::METHOD_POST, '/functions/' . $response['body']['$id'] . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'key' => 'funcKey3', - 'value' => 'funcValue3', - ]); - - $this->assertEquals(201, $variable['headers']['status-code']); - $this->assertEquals(201, $variable2['headers']['status-code']); - $this->assertEquals(201, $variable3['headers']['status-code']); - - $functions = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $functions = $this->listFunctions(); $this->assertEquals($functions['headers']['status-code'], 200); $this->assertEquals($functions['body']['total'], 2); $this->assertIsArray($functions['body']['functions']); @@ -252,87 +171,67 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($functions['body']['functions'][0]['name'], 'Test'); $this->assertEquals($functions['body']['functions'][1]['name'], 'Test 2'); - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functions = $this->listFunctions([ 'queries' => [ Query::cursorAfter(new Document(['$id' => $functions['body']['functions'][0]['$id']]))->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(1, $functions['body']['functions']); + $this->assertEquals($functions['body']['functions'][0]['name'], 'Test 2'); - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(1, $response['body']['functions']); - $this->assertEquals($response['body']['functions'][0]['name'], 'Test 2'); - - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functions = $this->listFunctions([ 'queries' => [ Query::cursorBefore(new Document(['$id' => $functions['body']['functions'][1]['$id']]))->toString(), ], ]); - - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertCount(1, $response['body']['functions']); - $this->assertEquals($response['body']['functions'][0]['name'], 'Test'); + $this->assertEquals($functions['headers']['status-code'], 200); + $this->assertCount(1, $functions['body']['functions']); + $this->assertEquals($functions['body']['functions'][0]['name'], 'Test'); /** * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functions = $this->listFunctions([ 'queries' => [ Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(), ], ]); - - $this->assertEquals($response['headers']['status-code'], 400); + $this->assertEquals($functions['headers']['status-code'], 400); return $data; } /** - * @depends testList + * @depends testListFunctions */ - public function testGet(array $data): array + public function testGetFunction(array $data): array { /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - + $function = $this->getFunction($data['functionId']); $this->assertEquals($function['headers']['status-code'], 200); $this->assertEquals($function['body']['name'], 'Test'); /** * Test for FAILURE */ - $function = $this->client->call(Client::METHOD_GET, '/functions/x', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - + $function = $this->getFunction('x'); $this->assertEquals($function['headers']['status-code'], 404); return $data; } /** - * @depends testGet + * @depends testGetFunction */ - public function testUpdate($data): array + public function testUpdateFunction($data): array { /** * Test for SUCCESS */ - $response1 = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ + $function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -347,36 +246,25 @@ class FunctionsCustomServerTest extends Scope 'entrypoint' => 'index.php', ]); - $this->assertEquals(200, $response1['headers']['status-code']); - $this->assertNotEmpty($response1['body']['$id']); - $this->assertEquals('Test1', $response1['body']['name']); + $this->assertEquals(200, $function['headers']['status-code']); + $this->assertNotEmpty($function['body']['$id']); + $this->assertEquals('Test1', $function['body']['name']); $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response1['body']['$createdAt'])); - $this->assertEquals(true, $dateValidator->isValid($response1['body']['$updatedAt'])); - $this->assertEquals('', $response1['body']['deployment']); + $this->assertEquals(true, $dateValidator->isValid($function['body']['$createdAt'])); + $this->assertEquals(true, $dateValidator->isValid($function['body']['$updatedAt'])); + $this->assertEquals('', $function['body']['deployment']); $this->assertEquals([ 'users.*.update.name', 'users.*.update.email', - ], $response1['body']['events']); - $this->assertEquals('0 0 1 1 *', $response1['body']['schedule']); - $this->assertEquals(15, $response1['body']['timeout']); + ], $function['body']['events']); + $this->assertEquals('0 0 1 1 *', $function['body']['schedule']); + $this->assertEquals(15, $function['body']['timeout']); - /** - * Create global variable to test in execution later - */ - $headers = [ - 'content-type' => 'application/json', - 'origin' => 'http://localhost', - 'cookie' => 'a_session_console=' . $this->getRoot()['session'], - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-mode' => 'admin', - ]; - - $variable = $this->client->call(Client::METHOD_POST, '/project/variables', $headers, [ + // Create a variable for later tests + $variable = $this->createVariable($data['functionId'], [ 'key' => 'GLOBAL_VARIABLE', 'value' => 'Global Variable Value', ]); - $this->assertEquals(201, $variable['headers']['status-code']); /** @@ -388,7 +276,7 @@ class FunctionsCustomServerTest extends Scope public function testCreateDeploymentFromCLI() { - $function = $this->createFunction([ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'test-cli-deployment', 'execute' => [Role::user($this->getUser()['$id'])->toString()], @@ -401,26 +289,29 @@ class FunctionsCustomServerTest extends Scope 'schedule' => '0 0 1 1 *', // Once a year 'timeout' => 10, ]); - $functionId = $function['body']['$id']; - $this->assertEquals(201, $function['headers']['status-code']); - - $deployment = $this->createDeployment($functionId, [ + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + 'x-sdk-language' => 'cli', + ], $this->getHeaders()), [ 'entrypoint' => 'index.php', 'code' => $this->packageFunction('php'), 'activate' => true - ], cli: true); - $deploymentId = $deployment['body']['$id']; - + ]); + $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertDeploymentStatus($functionId, $deploymentId, 'ready'); - $deployment = $this->getDeployment($functionId, $deploymentId); - $this->assertEquals(200, $deployment['headers']['status-code']); - $this->assertEquals('cli', $deployment['body']['type']); + $this->assertEventually(function () use ($functionId, $deploymentId) { + $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); + $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals('cli', $deployment['body']['type']); + }, 500000, 1000); } - public function testCreateDeploymentFromTemplate() + public function testCreateFunctionAndDeploymentFromTemplate() { $starterTemplate = $this->getTemplate('starter'); @@ -451,7 +342,7 @@ class FunctionsCustomServerTest extends Scope 'templateVersion' => $starterTemplate['body']['providerVersion'], ] ); - $functionId = $function['body']['$id']; + $functionId = $functionId = $function['body']['$id'] ?? ''; $this->assertEquals(201, $function['headers']['status-code']); $this->assertNotEmpty($function['body']['$id']); @@ -464,10 +355,12 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(0, $lastDeployment['size']); $deploymentId = $lastDeployment['$id']; - $this->assertDeploymentStatus($function['body']['$id'], $deploymentId, 'ready'); - - $deployment = $this->getDeployment($function['body']['$id'], $deploymentId); - $this->assertGreaterThan(0, $deployment['body']['size']); + $this->assertEventually(function () use ($functionId, $deploymentId) { + $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); + $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals('cli', $deployment['body']['type']); + }, 500000, 1000); $function = $this->getFunction($functionId); $this->assertEquals(200, $function['headers']['status-code']); @@ -500,18 +393,16 @@ class FunctionsCustomServerTest extends Scope 'path' => '/ping', 'async' => true ]); - $executionId = $execution['body']['$id']; + $executionId = $execution['body']['$id'] ?? ''; $this->assertEquals(202, $execution['headers']['status-code']); $this->assertNotEmpty($execution['body']['$id']); $this->assertEquals('waiting', $execution['body']['status']); $this->assertEventually(function () use ($functionId, $executionId, $totalUsers) { $execution = $this->getExecution($functionId, $executionId); - - $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['headers']['status-code']); - $this->assertEquals("completed", $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); + $this->assertEquals('completed', $execution['body']['status']); $this->assertEmpty($execution['body']['responseBody']); $this->assertEmpty($execution['body']['errors']); $this->assertStringContainsString("Total users: " . $totalUsers, $execution['body']['logs']); @@ -522,21 +413,18 @@ class FunctionsCustomServerTest extends Scope } /** - * @depends testUpdate + * @depends testUpdateFunction */ public function testCreateDeployment($data): array { /** * Test for SUCCESS */ - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $data['functionId']; + $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); @@ -544,37 +432,31 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt'])); $this->assertEquals('index.php', $deployment['body']['entrypoint']); - $this->assertDeployment($data['functionId'], $deploymentId); - - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => 'false' + 'activate' => false ]); - + $deploymentIdInactive = $deployment['body']['$id']; $this->assertEquals(202, $deployment['headers']['status-code']); $this->assertNotEmpty($deployment['body']['$id']); - $deploymentIdInactive = $deployment['body']['$id']; + $this->assertEventually(function () use ($functionId, $deploymentId, $deploymentIdInactive) { + $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals('completed', $deployment['body']['status']); - $this->assertDeployment($data['functionId'], $deploymentIdInactive); - - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $deployment = $this->getDeployment($functionId, $deploymentIdInactive); + $this->assertEquals('completed', $deployment['body']['status']); + }, 500000, 1000); + $function = $this->getFunction($functionId); $this->assertEquals(200, $function['headers']['status-code']); $this->assertEquals($deploymentId, $function['body']['deployment']); $this->assertNotEquals($deploymentIdInactive, $function['body']['deployment']); - $deployment = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentIdInactive, array_merge([ + $deployment = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId . '/deployments/' . $deploymentIdInactive, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), []); - $this->assertEquals(204, $deployment['headers']['status-code']); return array_merge($data, ['deploymentId' => $deploymentId]); @@ -585,14 +467,11 @@ class FunctionsCustomServerTest extends Scope */ public function testCancelDeploymentBuild($data): void { - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $data['functionId']; + $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => true + 'activate' => false ]); - $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); @@ -600,39 +479,28 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt'])); $this->assertEquals('index.php', $deployment['body']['entrypoint']); - $this->assertEventually(function () use ($data, $deploymentId) { - $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); - + $this->assertEventually(function () use ($functionId, $deploymentId) { + $deployment = $this->getDeployment($functionId, $deploymentId); $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertEquals('building', $deployment['body']['status']); - }, 60000, 1000); + }, 100000, 250); - // Cancel the deployment build - $cancel = $this->client->call(Client::METHOD_PATCH, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId . '/build', [ + // Cancel the deployment + $cancel = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId . '/build', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); - + ], $this->getHeaders())); $this->assertEquals(200, $cancel['headers']['status-code']); $this->assertEquals('canceled', $cancel['body']['status']); /** * Build worker still runs the build. - * 10s sleep gives worker enough time to finish build. + * 30s sleep gives worker enough time to finish build. * After build finished, it should still be canceled, not ready. */ - \sleep(10); - $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); + \sleep(30); + $deployment = $this->getDeployment($functionId, $deploymentId); $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertEquals('canceled', $deployment['body']['status']); } @@ -645,10 +513,11 @@ class FunctionsCustomServerTest extends Scope /** * Test for Large Code File SUCCESS */ + $functionId = $data['functionId']; $folder = 'php-large'; $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); $chunkSize = 5 * 1024 * 1024; $handle = @fopen($code, "rb"); @@ -666,7 +535,7 @@ class FunctionsCustomServerTest extends Scope if (!empty($id)) { $headers['x-appwrite-id'] = $id; } - $largeTag = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge($headers, $this->getHeaders()), [ + $largeTag = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge($headers, $this->getHeaders()), [ 'entrypoint' => 'index.php', 'code' => $curlFile, 'activate' => true, @@ -685,19 +554,15 @@ class FunctionsCustomServerTest extends Scope $this->assertLessThan(1024 * 1024 * 10, $largeTag['body']['size']); // ~7MB video file $deploymentSize = $largeTag['body']['size']; - $deploymentId = $largeTag['body']['$id']; - $this->assertDeployment($data['functionId'], $deploymentId, true); - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals($deploymentSize, $response['body']['size']); - $this->assertGreaterThan(1024 * 1024 * 10, $response['body']['buildSize']); // ~7MB video file + 10MB sample file + $this->assertEventually(function () use ($functionId, $deploymentId, $deploymentSize) { + $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); + $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals($deploymentSize, $deployment['body']['size']); + $this->assertGreaterThan(1024 * 1024 * 10, $deployment['body']['buildSize']); // ~7MB video file + 10MB sample file + }, 500000, 1000); return $data; } @@ -710,6 +575,8 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ + $dateValidator = new DatetimeValidator(); + $response = $this->client->call(Client::METHOD_PATCH, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -717,15 +584,10 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); - $dateValidator = new DatetimeValidator(); $this->assertEquals(true, $dateValidator->isValid($response['body']['$createdAt'])); $this->assertEquals(true, $dateValidator->isValid($response['body']['$updatedAt'])); $this->assertEquals($data['deploymentId'], $response['body']['deployment']); - /** - * Test for FAILURE - */ - return $data; } @@ -737,127 +599,85 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $functionId = $data['functionId']; + $deployments = $this->listDeployments($functionId); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals($function['body']['total'], 3); - $this->assertIsArray($function['body']['deployments']); - $this->assertCount(3, $function['body']['deployments']); - $this->assertArrayHasKey('size', $function['body']['deployments'][0]); - $this->assertArrayHasKey('buildSize', $function['body']['deployments'][0]); + $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]); - /** - * Test search queries - */ - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders(), [ - 'search' => $data['functionId'] - ]) - ); + // Test search id + $deployments = $this->listDeployments($functionId, [ + 'search' => $data['functionId'] + ]); + $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']); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(3, $function['body']['total']); - $this->assertIsArray($function['body']['deployments']); - $this->assertCount(3, $function['body']['deployments']); - $this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']); - - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + // Test pagination limit + $deployments = $this->listDeployments($functionId, [ 'queries' => [ Query::limit(1)->toString(), ], ]); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertCount(1, $deployments['body']['deployments']); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertCount(1, $function['body']['deployments']); - - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $deployments = $this->listDeployments($functionId, [ 'queries' => [ Query::offset(1)->toString(), ], ]); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertCount(2, $function['body']['deployments']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertCount(2, $deployments['body']['deployments']); - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $deployments = $this->listDeployments($functionId, [ 'queries' => [ Query::equal('entrypoint', ['index.php'])->toString(), ], ]); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertCount(3, $function['body']['deployments']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertCount(3, $deployments['body']['deployments']); - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $deployments = $this->listDeployments($functionId, [ 'queries' => [ Query::equal('entrypoint', ['index.js'])->toString(), ], ]); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertCount(0, $function['body']['deployments']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertCount(0, $deployments['body']['deployments']); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders(), [ - 'search' => 'Test' - ]) - ); + $deployments = $this->listDeployments($functionId, [ + 'search' => 'Test' + ]); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(3, $function['body']['total']); - $this->assertIsArray($function['body']['deployments']); - $this->assertCount(3, $function['body']['deployments']); - $this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders(), [ - 'search' => 'php-8.0' - ]) - ); + $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']); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(3, $function['body']['total']); - $this->assertIsArray($function['body']['deployments']); - $this->assertCount(3, $function['body']['deployments']); - $this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']); + $deployments = $this->listDeployments($functionId, [ + 'search' => 'php-8.0' + ]); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $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']); + + $deployments = $this->listDeployments( + $functionId, [ 'queries' => [ Query::equal('type', ['manual'])->toString(), @@ -865,16 +685,11 @@ class FunctionsCustomServerTest extends Scope ] ); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(3, $function['body']['total']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertEquals(3, $deployments['body']['total']); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $deployments = $this->listDeployments( + $functionId, [ 'queries' => [ Query::equal('type', ['vcs'])->toString(), @@ -882,16 +697,11 @@ class FunctionsCustomServerTest extends Scope ] ); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(0, $function['body']['total']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertEquals(0, $deployments['body']['total']); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $deployments = $this->listDeployments( + $functionId, [ 'queries' => [ Query::equal('type', ['invalid-string'])->toString(), @@ -899,16 +709,11 @@ class FunctionsCustomServerTest extends Scope ] ); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(0, $function['body']['total']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertEquals(0, $deployments['body']['total']); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $deployments = $this->listDeployments( + $functionId, [ 'queries' => [ Query::greaterThan('size', 10000)->toString(), @@ -916,16 +721,11 @@ class FunctionsCustomServerTest extends Scope ] ); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(1, $function['body']['total']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertEquals(1, $deployments['body']['total']); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $deployments = $this->listDeployments( + $functionId, [ 'queries' => [ Query::greaterThan('size', 0)->toString(), @@ -933,57 +733,40 @@ class FunctionsCustomServerTest extends Scope ] ); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(3, $function['body']['total']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertEquals(3, $deployments['body']['total']); - $function = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $deployments = $this->listDeployments( + $functionId, [ 'queries' => [ Query::greaterThan('size', -100)->toString(), ], ] ); - - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals(3, $function['body']['total']); + $this->assertEquals($deployments['headers']['status-code'], 200); + $this->assertEquals(3, $deployments['body']['total']); /** * Ensure size output and size filters work exactly. * Prevents buildSize being counted towards deployemtn size */ - $response = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $deployments = $this->listDeployments( + $functionId, [ Query::limit(1)->toString(), ] ); + $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']); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertGreaterThanOrEqual(1, $response['body']['total']); - $this->assertNotEmpty($response['body']['deployments'][0]['$id']); - $this->assertNotEmpty($response['body']['deployments'][0]['size']); + $deploymentId = $deployments['body']['deployments'][0]['$id']; + $deploymentSize = $deployments['body']['deployments'][0]['size']; - $deploymentId = $function['body']['deployments'][0]['$id']; - $deploymentSize = $function['body']['deployments'][0]['size']; - - $response = $this->client->call( - Client::METHOD_GET, - '/functions/' . $data['functionId'] . '/deployments', - array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), + $deployments = $this->listDeployments( + $functionId, [ 'queries' => [ Query::equal('size', [$deploymentSize])->toString(), @@ -991,20 +774,21 @@ class FunctionsCustomServerTest extends Scope ] ); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertGreaterThan(0, $response['body']['total']); + $this->assertEquals(200, $deployments['headers']['status-code']); + $this->assertGreaterThan(0, $deployments['body']['total']); - $found = false; - foreach ($response['body']['deployments'] as $deployment) { - if ($deployment['$id'] === $deploymentId) { - $found = true; - $this->assertEquals($deploymentSize, $deployment['size']); - break; - } + $matchingDeployment = array_filter( + $deployments['body']['deployments'], + fn($deployment) => $deployment['$id'] === $deploymentId + ); + + $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); + + if (!empty($matchingDeployment)) { + $deployment = reset($matchingDeployment); + $this->assertEquals($deploymentSize, $deployment['size']); } - $this->assertTrue($found); - return $data; } @@ -1016,27 +800,19 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - $this->assertEquals(200, $function['headers']['status-code']); - $this->assertGreaterThan(0, $function['body']['buildTime']); - $this->assertNotEmpty($function['body']['status']); - $this->assertNotEmpty($function['body']['buildLogs']); - $this->assertArrayHasKey('size', $function['body']); - $this->assertArrayHasKey('buildSize', $function['body']); + $deployment = $this->getDeployment($data['functionId'], $data['deploymentId']); + $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']); /** * Test for FAILURE */ - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/x', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - $this->assertEquals($function['headers']['status-code'], 404); + $deployment = $this->getDeployment($data['functionId'], 'x'); + $this->assertEquals($deployment['headers']['status-code'], 404); return $data; } @@ -1049,13 +825,9 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $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()), [ + $execution = $this->createExecution($data['functionId'], [ 'async' => false, ]); - $executionId = $execution['body']['$id'] ?? ''; $this->assertEquals(201, $execution['headers']['status-code']); @@ -1077,10 +849,7 @@ class FunctionsCustomServerTest extends Scope $this->assertNotEmpty($execution['body']['logs']); $this->assertLessThan(10, $execution['body']['duration']); - $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()), [ + $execution = $this->createExecution($data['functionId'], [ 'async' => false, 'path' => '/?code=400' ]); @@ -1092,6 +861,8 @@ class FunctionsCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), []); + + $execution = $this->createExecution($data['functionId']); $this->assertEquals(204, $execution['headers']['status-code']); return array_merge($data, ['executionId' => $executionId]); @@ -1105,82 +876,57 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $executions = $this->listExecutions($data['functionId']); + $this->assertEquals($executions['headers']['status-code'], 200); + $this->assertEquals($executions['body']['total'], 1); + $this->assertIsArray($executions['body']['executions']); + $this->assertCount(1, $executions['body']['executions']); + $this->assertEquals($executions['body']['executions'][0]['$id'], $data['executionId']); - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals($function['body']['total'], 1); - $this->assertIsArray($function['body']['executions']); - $this->assertCount(1, $function['body']['executions']); - $this->assertEquals($function['body']['executions'][0]['$id'], $data['executionId']); - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $executions = $this->listExecutions($data['functionId'], [ 'queries' => [ Query::limit(1)->toString(), ], ]); + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertCount(1, $executions['body']['executions']); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(1, $response['body']['executions']); - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $executions = $this->listExecutions($data['functionId'], [ 'queries' => [ Query::offset(1)->toString(), ], ]); + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertCount(0, $executions['body']['executions']); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(0, $response['body']['executions']); - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $executions = $this->listExecutions($data['functionId'], [ 'queries' => [ Query::equal('trigger', ['http'])->toString(), ], ]); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(1, $response['body']['executions']); + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertCount(1, $executions['body']['executions']); /** * Test search queries */ - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $executions = $this->listExecutions($data['functionId'], [ 'search' => $data['executionId'], ]); + $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']); - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(1, $response['body']['total']); - $this->assertIsInt($response['body']['total']); - $this->assertCount(1, $response['body']['executions']); - $this->assertEquals($data['functionId'], $response['body']['executions'][0]['functionId']); - - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $executions = $this->listExecutions($data['functionId'], [ 'search' => $data['functionId'], ]); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(1, $response['body']['total']); - $this->assertIsInt($response['body']['total']); - $this->assertCount(1, $response['body']['executions']); - $this->assertEquals($data['executionId'], $response['body']['executions'][0]['$id']); + $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']); return $data; } @@ -1193,13 +939,9 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $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()), [ + $execution = $this->createExecution($data['functionId'], [ // Testing default value, should be 'async' => false ]); - $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); @@ -1221,22 +963,14 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions/' . $data['executionId'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - $this->assertEquals($function['headers']['status-code'], 200); - $this->assertEquals($function['body']['$id'], $data['executionId']); + $execution = $this->getExecution($data['functionId'], $data['executionId']); + $this->assertEquals($execution['headers']['status-code'], 200); + $this->assertEquals($execution['body']['$id'], $data['executionId']); /** * Test for FAILURE */ - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions/x', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - + $function = $this->getExecution($data['functionId'], 'x'); $this->assertEquals($function['headers']['status-code'], 404); return $data; @@ -1329,7 +1063,8 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $response1 = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ + // 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()), [ @@ -1344,22 +1079,19 @@ class FunctionsCustomServerTest extends Scope 'specification' => Specification::S_1VCPU_1GB, ]); - $this->assertEquals(200, $response1['headers']['status-code']); - $this->assertNotEmpty($response1['body']['$id']); - $this->assertEquals(Specification::S_1VCPU_1GB, $response1['body']['specification']); + $this->assertEquals(200, $function['headers']['status-code']); + $this->assertNotEmpty($function['body']['$id']); + $this->assertEquals(Specification::S_1VCPU_1GB, $function['body']['specification']); - // Test Execution - $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())); + // Verify the updated specs + $execution = $this->createExecution($data['functionId']); $output = json_decode($execution['body']['responseBody'], true); - $this->assertEquals(1, $output['APPWRITE_FUNCTION_CPUS']); $this->assertEquals(1024, $output['APPWRITE_FUNCTION_MEMORY']); - $response2 = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ + // 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()), [ @@ -1374,25 +1106,21 @@ class FunctionsCustomServerTest extends Scope 'specification' => Specification::S_1VCPU_512MB, ]); - $this->assertEquals(200, $response2['headers']['status-code']); - $this->assertNotEmpty($response2['body']['$id']); - $this->assertEquals(Specification::S_1VCPU_512MB, $response2['body']['specification']); + $this->assertEquals(200, $function['headers']['status-code']); + $this->assertNotEmpty($function['body']['$id']); + $this->assertEquals(Specification::S_1VCPU_512MB, $function['body']['specification']); - // Test Execution - $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())); + // Verify the updated specs + $execution = $this->createExecution($data['functionId']); $output = json_decode($execution['body']['responseBody'], true); - $this->assertEquals(1, $output['APPWRITE_FUNCTION_CPUS']); $this->assertEquals(512, $output['APPWRITE_FUNCTION_MEMORY']); /** * Test for FAILURE */ - $response3 = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ + $function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -1406,9 +1134,8 @@ class FunctionsCustomServerTest extends Scope 'entrypoint' => 'index.php', 'specification' => 's-2vcpu-512mb', // Invalid specification ]); - - $this->assertEquals(400, $response3['headers']['status-code']); - $this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $response3['body']['message']); + $this->assertEquals(400, $function['headers']['status-code']); + $this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $function['body']['message']); return $data; } @@ -1421,24 +1148,15 @@ class FunctionsCustomServerTest extends Scope /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([ + $deployment = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); + $this->assertEquals(204, $deployment['headers']['status-code']); + $this->assertEmpty($deployment['body']); - $this->assertEquals(204, $function['headers']['status-code']); - $this->assertEmpty($function['body']); - - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - $this->assertEquals(404, $function['headers']['status-code']); - - /** - * Test for FAILURE - */ + $deployment = $this->getDeployment($data['functionId'], $data['deploymentId']); + $this->assertEquals(404, $deployment['headers']['status-code']); return $data; } @@ -1446,87 +1164,60 @@ class FunctionsCustomServerTest extends Scope /** * @depends testCreateDeployment */ - public function testDelete($data): array + public function testDeleteFunction($data): array { /** * Test for SUCCESS */ - $function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - + $function = $this->deleteFunction($data['functionId']); $this->assertEquals(204, $function['headers']['status-code']); $this->assertEmpty($function['body']); - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - + $function = $this->getFunction($data['functionId']); $this->assertEquals(404, $function['headers']['status-code']); - /** - * Test for FAILURE - */ - return $data; } - public function testTimeout() + public function testExecutionTimeout() { - $function = $this->createFunction([ + $functionId = $this->setupFunction([ 'name' => 'timeout-php-8.0', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'events' => [], - 'schedule' => '*/10 * * * *', // Execute every 10 seconds - 'timeout' => 15, + 'schedule' => '', + 'timeout' => 5, // Should timeout after 5 seconds + ]); + $this->setupDeployment($functionId, [ + 'code' => $this->packageFunction('php'), + 'activate' => true, ]); - $functionId = $function['body']['id']; - $this->assertEquals(201, $function['headers']['status-code']); - $deployment = $this->createDeployment($functionId, 'php'); - $deploymentId = $deployment['body']['$id']; - $this->assertDeploymentStatus($functionId, $deploymentId, 'ready'); - - $execution = $this->createExecution($functionId, ['async' => true]); + $execution = $this->createExecution($functionId, [ + 'async' => true + ]); $executionId = $execution['body']['$id'] ?? ''; $this->assertEquals(202, $execution['headers']['status-code']); + \sleep(5); // Wait for the function to timeout + $this->assertEventually(function () use ($functionId, $executionId) { $execution = $this->getExecution($functionId, $executionId); $this->assertEquals(200, $execution['headers']['status-code']); $this->assertEquals('failed', $execution['body']['status']); - $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']); - }, 20000, 500); + }, 5000, 250); - $this->assertEventually(function () use ($functionId) { - $executions = $this->listExecutions($functionId, [ - 'queries' => [ - Query::equal('trigger', ['schedule'])->toString(), - ], - ]); - - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertEquals(1, $executions['body']['total']); - - $lastExecution = $executions['body']['executions'][0]; - $this->assertEquals('schedule', $lastExecution['trigger']); - }, 20000, 500); - - $function = $this->deleteFunction($functionId); - $this->assertEquals(204, $function['headers']['status-code']); + $this->cleanupFunction($functionId); } - /** * * @return array @@ -1554,61 +1245,33 @@ class FunctionsCustomServerTest extends Scope */ public function testCreateCustomExecution(string $folder, string $name, string $entrypoint, string $runtimeName, string $runtimeVersion) { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test ' . $name, 'runtime' => $name, 'entrypoint' => $entrypoint, 'events' => [], - 'timeout' => $timeout, + 'timeout' => 15, ]); - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - - $variable = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $variable = $this->createVariable($functionId, [ 'key' => 'CUSTOM_VARIABLE', - 'value' => 'variable', + 'value' => 'variable' ]); - $this->assertEquals(201, $variable['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()), [ + $deploymentId = $this->setupDeployment($functionId, [ 'entrypoint' => $entrypoint, - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction($folder), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'body' => 'foobar', 'async' => false ]); - $executionId = $execution['body']['$id'] ?? ''; $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']); @@ -1627,11 +1290,7 @@ class FunctionsCustomServerTest extends Scope $this->assertStringContainsString('Amazing Function Log', $execution['body']['logs']); $this->assertEmpty($execution['body']['errors']); - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - + $executions = $this->listExecutions($functionId); $this->assertEquals($executions['headers']['status-code'], 200); $this->assertEquals($executions['body']['total'], 1); $this->assertIsArray($executions['body']['executions']); @@ -1640,55 +1299,28 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); $this->assertStringContainsString('Amazing Function Log', $executions['body']['executions'][0]['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']); + $this->cleanupFunction($functionId); } public function testCreateCustomExecutionBinaryResponse() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-binary-response/code.tar.gz"; - $this->packageCode('php-binary-response'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Binary executions', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', - 'timeout' => $timeout, + 'timeout' => 15, 'execute' => ['any'] ]); - - $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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('php-binary-response'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'x-appwrite-project' => $this->getProject()['$id'], - 'accept' => 'multipart/form-data', + 'accept' => 'multipart/form-data', // Accept binary response ], $this->getHeaders()), [ 'body' => null, ]); @@ -1708,7 +1340,7 @@ class FunctionsCustomServerTest extends Scope */ $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'x-appwrite-project' => $this->getProject()['$id'], - 'accept' => 'application/json', + 'accept' => 'application/json', // Accept JSON response ], $this->getHeaders()), [ 'body' => null, ]); @@ -1716,56 +1348,29 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(400, $execution['headers']['status-code']); $this->assertStringContainsString('Failed to parse response', $execution['body']['message']); - // 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']); + $this->cleanupFunction($functionId); } public function testCreateCustomExecutionBinaryRequest() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-binary-request/code.tar.gz"; - $this->packageCode('php-binary-request'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Binary executions', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', - 'timeout' => $timeout, + 'timeout' => 15, 'execute' => ['any'] ]); - - $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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('php-binary-request'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - $bytes = pack('C*', ...[0, 20, 255]); $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'multipart/form-data', + 'content-type' => 'multipart/form-data', // Send binary request 'x-appwrite-project' => $this->getProject()['$id'], 'accept' => 'application/json', ], $this->getHeaders()), [ @@ -1773,7 +1378,6 @@ class FunctionsCustomServerTest extends Scope ], false); $executionBody = json_decode($execution['body'], true); - $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals(\md5($bytes), $executionBody['responseBody']); $this->assertStringStartsWith('application/json', $execution['headers']['content-type']); @@ -1782,7 +1386,7 @@ class FunctionsCustomServerTest extends Scope * Test for FAILURE */ $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', + 'content-type' => 'application/json', // Send JSON headers 'x-appwrite-project' => $this->getProject()['$id'], 'accept' => 'application/json', ], $this->getHeaders()), [ @@ -1792,89 +1396,48 @@ class FunctionsCustomServerTest extends Scope $executionBody = json_decode($execution['body'], true); $this->assertNotEquals(\md5($bytes), $executionBody['responseBody']); - // 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']); + $this->cleanupFunction($functionId); } public function testv2Function() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-v2/code.tar.gz"; - $this->packageCode('php-v2'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP V2', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'events' => [], - 'timeout' => $timeout, + 'timeout' => 15, ]); - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - - $headers = [ + $variable = $this->client->call(Client::METHOD_PATCH, '/mock/functions-v2', [ 'content-type' => 'application/json', 'origin' => 'http://localhost', 'cookie' => 'a_session_console=' . $this->getRoot()['session'], 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-mode' => 'admin', - ]; - - $variable = $this->client->call(Client::METHOD_PATCH, '/mock/functions-v2', $headers, [ + ], [ 'functionId' => $functionId ]); - $this->assertEquals(204, $variable['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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('php-v2'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'body' => 'foobar', 'async' => false ]); - $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']); $this->assertEquals(true, $output['v2Woks']); - // 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']); + $this->cleanupFunction($functionId); } public function testGetRuntimes() @@ -1902,14 +1465,7 @@ class FunctionsCustomServerTest extends Scope public function testEventTrigger() { - $timeout = 15; - $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 = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Event executions', 'runtime' => 'php-8.0', @@ -1917,28 +1473,15 @@ class FunctionsCustomServerTest extends Scope 'events' => [ 'users.*.create', ], - 'timeout' => $timeout, + 'timeout' => 15, ]); - - $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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('php-event'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - // Create user to trigger event + // Create user as an event trigger $user = $this->client->call(Client::METHOD_POST, '/users', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1946,111 +1489,57 @@ class FunctionsCustomServerTest extends Scope 'userId' => 'unique()', 'name' => 'Event User' ]); - - $userId = $user['body']['$id']; + $userId = $user['body']['$id'] ?? ''; $this->assertEquals(201, $user['headers']['status-code']); - $execution = null; - $this->assertEventually(function () use ($functionId, &$execution) { - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]); + $this->assertEventually(function () use ($functionId, $userId) { + $executions = $this->listExecutions($functionId); + $lastExecution = $executions['body']['executions'][0]; + $this->assertEquals('completed', $lastExecution['status']); + $this->assertEquals(204, $lastExecution['responseStatusCode']); + $this->assertStringContainsString($userId, $lastExecution['logs']); + $this->assertStringContainsString('Event User', $lastExecution['logs']); + }, 10000, 500); - if (empty($executions['body']['executions'])) { - throw new \Exception('No executions found yet'); - } + $this->cleanupFunction($functionId); - $execution = $executions['body']['executions'][0]; - $this->assertEquals('completed', $execution['status']); - }, 30000, 1000); - - $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, [ + // Cleanup user + $user = $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']); - - // 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']); + $this->assertEquals(204, $user['headers']['status-code']); } public function testScopes() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-scopes/code.tar.gz"; - $this->packageCode('php-scopes'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Scopes executions', 'commands' => 'composer update --no-interaction --ignore-platform-reqs --optimize-autoloader --prefer-dist --no-dev', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'scopes' => ['users.read'], - 'timeout' => $timeout, + 'timeout' => 15, ]); - $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()), [ + $deploymentId = $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', 'commands' => 'sh setup.sh && composer install', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), - 'activate' => true + 'code' => $this->packageFunction('php-scopes'), + 'activate' => true, ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - - $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); + $deployment = $this->getDeployment($functionId, $deploymentId); $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']); - $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']); - - // Wait a little for activation to finish - sleep(5); - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'async' => false + $execution = $this->createExecution($functionId, [ + 'async' => false, ]); $this->assertEquals(201, $execution['headers']['status-code']); @@ -2060,81 +1549,44 @@ class FunctionsCustomServerTest extends Scope $this->assertNotEmpty($execution['body']['responseBody']); $this->assertStringContainsString("total", $execution['body']['responseBody']); - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'async' => true + $execution = $this->createExecution($functionId, [ + 'async' => true, ]); - + $executionId = $execution['body']['$id'] ?? ''; $this->assertEquals(202, $execution['headers']['status-code']); $this->assertNotEmpty($execution['body']['$id']); - \sleep(10); + $this->assertEventually(function () use ($functionId, $executionId) { + $execution = $this->getExecution($functionId, $executionId); - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $execution['body']['$id'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); + $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']); + $this->assertNotEmpty($execution['body']['responseBody']); + $this->assertStringContainsString("total", $execution['body']['responseBody']); + }, 5000, 250); - $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']); - $this->assertNotEmpty($execution['body']['logs']); - $this->assertStringContainsString("total", $execution['body']['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']); + $this->cleanupFunction($functionId); } public function testCookieExecution() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-cookie/code.tar.gz"; - $this->packageCode('php-cookie'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Cookie executions', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', - 'timeout' => $timeout, + 'timeout' => 15, ]); - - $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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('php-cookie'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - $cookie = 'cookieName=cookieValue; cookie2=value2; cookie3=value=3; cookie4=val:ue4; cookie5=value5'; - - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => false, 'headers' => [ 'cookie' => $cookie @@ -2147,38 +1599,20 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($cookie, $execution['body']['responseBody']); $this->assertGreaterThan(0, $execution['body']['duration']); - // 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']); + $this->cleanupFunction($functionId); } public function testFunctionsDomain() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-cookie/code.tar.gz"; - $this->packageCode('php-cookie'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Cookie executions', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', - 'timeout' => $timeout, + 'timeout' => 15, 'execute' => ['any'] ]); - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - $rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -2196,20 +1630,12 @@ class FunctionsCustomServerTest extends Scope $domain = $rules['body']['rules'][0]['domain']; - $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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('php-cookie'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - $cookie = 'cookieName=cookieValue; cookie2=value2; cookie3=value=3; cookie4=val:ue4; cookie5=value5'; $proxyClient = new Client(); @@ -2227,64 +1653,31 @@ class FunctionsCustomServerTest extends Scope // Await Aggregation sleep(App::getEnv('_APP_USAGE_AGGREGATION_INTERVAL', 30)); - $tries = 0; - while (true) { - try { - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'] - ], $this->getHeaders()), [ - 'range' => '24h' - ]); + $this->assertEventually(function () use ($functionId) { + $response = $this->getFunctionUsage($functionId, [ + 'range' => '24h' + ]); - $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']); + $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); - break; - } catch (ExpectationFailedException $th) { - if ($tries >= 5) { - throw $th; - } else { - $tries++; - sleep(5); - } - } - } - - // 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']); + $this->cleanupFunction($functionId); } public function testFunctionsDomainBinaryResponse() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-binary-response/code.tar.gz"; - $this->packageCode('php-binary-response'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Binary executions', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', - 'timeout' => $timeout, + 'timeout' => 15, 'execute' => ['any'] ]); - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - $rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -2302,20 +1695,11 @@ class FunctionsCustomServerTest extends Scope $domain = $rules['body']['rules'][0]['domain']; - $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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), - 'activate' => true + 'code' => $this->packageFunction('php-binary-response'), ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - $proxyClient = new Client(); $proxyClient->setEndpoint('http://' . $domain); @@ -2329,38 +1713,20 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(10, $bytes['byte2']); $this->assertEquals(255, $bytes['byte3']); - // 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']); + $this->cleanupFunction($functionId); } public function testFunctionsDomainBinaryRequest() { - $timeout = 15; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php-binary-request/code.tar.gz"; - $this->packageCode('php-binary-request'); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Binary executions', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', - 'timeout' => $timeout, + 'timeout' => 15, 'execute' => ['any'] ]); - $functionId = $function['body']['$id'] ?? ''; - - $this->assertEquals(201, $function['headers']['status-code']); - $rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -2378,20 +1744,12 @@ class FunctionsCustomServerTest extends Scope $domain = $rules['body']['rules'][0]['domain']; - $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()), [ + $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('php-binary-request'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); - - $this->assertDeployment($function['body']['$id'], $deploymentId); - $proxyClient = new Client(); $proxyClient->setEndpoint('http://' . $domain); @@ -2402,19 +1760,12 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(\md5($bytes), $response['body']); - // 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']); + $this->cleanupFunction($functionId); } public function testCreateFunctionWithResponseFormatHeader() { - $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ + $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-response-format' => '1.5.0', // add response format header @@ -2426,29 +1777,16 @@ class FunctionsCustomServerTest extends Scope 'timeout' => 15, ]); - $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(201, $function['headers']['status-code']); - // Cleanup : Delete function - $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $response['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], []); + $functionId = $function['body']['$id'] ?? ''; - $this->assertEquals(204, $response['headers']['status-code']); + $this->cleanupFunction($functionId); } public function testFunctionLogging() { - // Preparations: Create Function - $folder = 'node'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - - $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function = $this->createFunction([ 'functionId' => ID::unique(), 'runtime' => 'node-18.0', 'name' => 'Logging Test', @@ -2461,38 +1799,22 @@ class FunctionsCustomServerTest extends Scope $this->assertFalse($function['body']['logging']); $this->assertNotEmpty($function['body']['$id']); - $functionId = $function['body']['$id']; + $functionId = $functionId = $function['body']['$id'] ?? ''; - $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()), [ - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + $this->setupDeployment($functionId, [ + 'code' => $this->packageFunction('node'), 'activate' => true ]); - $this->assertEquals(202, $deployment['headers']['status-code']); - $this->assertNotEmpty($deployment['body']['$id']); - - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertDeployment($functionId, $deploymentId); - // Sync Executions test - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); + $execution = $this->createExecution($functionId); $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEmpty($execution['body']['logs']); $this->assertEmpty($execution['body']['errors']); // Async Executions test - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $execution = $this->createExecution($functionId, [ 'async' => true ]); @@ -2501,19 +1823,16 @@ class FunctionsCustomServerTest extends Scope $this->assertEmpty($execution['body']['errors']); $this->assertNotEmpty($execution['body']['$id']); - $executionId = $execution['body']['$id']; + $executionId = $execution['body']['$id'] ?? ''; - sleep(5); + $this->assertEventually(function () use ($functionId, $executionId) { + $execution = $this->getExecution($functionId, $executionId); - $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - $this->assertEquals(200, $execution['headers']['status-code']); - $this->assertEquals('completed', $execution['body']['status']); - $this->assertEmpty($execution['body']['logs']); - $this->assertEmpty($execution['body']['errors']); + $this->assertEquals(200, $execution['headers']['status-code']); + $this->assertEquals('completed', $execution['body']['status']); + $this->assertEmpty($execution['body']['logs']); + $this->assertEmpty($execution['body']['errors']); + }, 5000, 250); // Domain Executions test $rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([ @@ -2541,10 +1860,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $executions = $this->listExecutions($functionId, [ 'queries' => [ Query::limit(1)->toString(), Query::orderDesc('$id')->toString(), @@ -2557,10 +1873,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEmpty($executions['body']['executions'][0]['errors']); // Ensure executions count - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $executions = $this->listExecutions($functionId); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertCount(3, $executions['body']['executions']); @@ -2571,13 +1884,6 @@ class FunctionsCustomServerTest extends Scope $this->assertEmpty($execution['errors']); } - // 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']); + $this->cleanupFunction($functionId); } } From 32657e22cc1e8d3ade1dca3fb52962277a4fe54f Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:34:38 +0100 Subject: [PATCH 137/213] fix: conflicts --- tests/e2e/Services/Functions/FunctionsBase.php | 2 +- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 7cfa04b0ac..04039e3acc 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -146,7 +146,7 @@ trait FunctionsBase $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; if (!file_exists($code)) { - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output, $this->output); } if (filesize($code) > 1024 * 1024 * 5) { throw new \Exception('Code package is too large. Use the chunked upload method instead.'); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e383abe36f..1796871c26 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -513,7 +513,7 @@ class FunctionsCustomServerTest extends Scope $folder = 'php-large'; $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output, $this->output); $chunkSize = 5 * 1024 * 1024; $handle = @fopen($code, "rb"); From 504711845aae015cbc487e000f5b944a33094fc9 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:46:05 +0100 Subject: [PATCH 138/213] fix: stdout --- tests/e2e/Services/Functions/FunctionsBase.php | 2 +- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 04039e3acc..d2bb19dea2 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -146,7 +146,7 @@ trait FunctionsBase $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; if (!file_exists($code)) { - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output, $this->output); + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output); } if (filesize($code) > 1024 * 1024 * 5) { throw new \Exception('Code package is too large. Use the chunked upload method instead.'); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 1796871c26..7c4cd6d1ee 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -513,7 +513,7 @@ class FunctionsCustomServerTest extends Scope $folder = 'php-large'; $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output, $this->output); + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output); $chunkSize = 5 * 1024 * 1024; $handle = @fopen($code, "rb"); From 65c0db32852f3eb41a560034b5fb64876d67e859 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:58:09 +0100 Subject: [PATCH 139/213] fix: package function --- tests/e2e/Services/Functions/FunctionsBase.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index d2bb19dea2..5ed87b4895 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -141,18 +141,20 @@ trait FunctionsBase return $executions; } - protected function packageFunction(string $folder = 'php'): CURLFile + protected function packageFunction(string $function = 'php'): CURLFile { - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; + $folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function"; + $tarPath = "$folderPath/code.tar.gz"; - if (!file_exists($code)) { - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output); + if (!file_exists($tarPath)) { + Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output); } - if (filesize($code) > 1024 * 1024 * 5) { + + if (filesize($tarPath) > 1024 * 1024 * 5) { throw new \Exception('Code package is too large. Use the chunked upload method instead.'); } - return new CURLFile($code, 'application/x-gzip', \basename($code)); + return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath)); } protected function createDeployment( From cb0416be7bd294725c4c6c455c44c05d973f38c9 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 21:08:04 +0100 Subject: [PATCH 140/213] chore: fmt --- tests/e2e/General/UsageTest.php | 7 ++----- .../Functions/FunctionsCustomServerTest.php | 2 +- tests/e2e/Services/GraphQL/Base.php | 19 +++++++++++++++---- .../Services/GraphQL/FunctionsClientTest.php | 7 +------ .../Services/GraphQL/FunctionsServerTest.php | 7 +------ .../Realtime/RealtimeConsoleClientTest.php | 9 +-------- 6 files changed, 21 insertions(+), 30 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index d3623acffc..69460aa4cd 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -629,9 +629,6 @@ class UsageTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); - $code = realpath(__DIR__ . '/../../resources/functions') . "/php/code.tar.gz"; - $this->packageCode('php'); - $response = $this->client->call( Client::METHOD_POST, '/functions/' . $functionId . '/deployments', @@ -641,8 +638,8 @@ class UsageTest extends Scope ], $this->getHeaders()), [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), - 'activate' => true + 'code' => $this->packageFunction('php'), + 'activate' => true, ] ); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 7c4cd6d1ee..4ff6639864 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -775,7 +775,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn($deployment) => $deployment['$id'] === $deploymentId + fn ($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); diff --git a/tests/e2e/Services/GraphQL/Base.php b/tests/e2e/Services/GraphQL/Base.php index b77f006bf8..449275f102 100644 --- a/tests/e2e/Services/GraphQL/Base.php +++ b/tests/e2e/Services/GraphQL/Base.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\GraphQL; +use CURLFile; use Utopia\CLI\Console; trait Base @@ -2493,11 +2494,21 @@ trait Base } // Function-related methods - protected string $stdout = ''; - protected string $stderr = ''; + protected string $output = ''; - protected function packageCode($folder): void + protected function packageFunction(string $function = 'php'): CURLFile { - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout); + $folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function"; + $tarPath = "$folderPath/code.tar.gz"; + + if (!file_exists($tarPath)) { + Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output); + } + + if (filesize($tarPath) > 1024 * 1024 * 5) { + throw new \Exception('Code package is too large. Use the chunked upload method instead.'); + } + + return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath)); } } diff --git a/tests/e2e/Services/GraphQL/FunctionsClientTest.php b/tests/e2e/Services/GraphQL/FunctionsClientTest.php index 3f0ee1966a..e7e8421254 100644 --- a/tests/e2e/Services/GraphQL/FunctionsClientTest.php +++ b/tests/e2e/Services/GraphQL/FunctionsClientTest.php @@ -2,7 +2,6 @@ namespace Tests\E2E\Services\GraphQL; -use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; @@ -83,10 +82,6 @@ class FunctionsClientTest extends Scope $projectId = $this->getProject()['$id']; $query = $this->getQuery(self::$CREATE_DEPLOYMENT); - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - $gqlPayload = [ 'operations' => \json_encode([ 'query' => $query, @@ -99,7 +94,7 @@ class FunctionsClientTest extends Scope 'map' => \json_encode([ 'code' => ["variables.code"] ]), - 'code' => new CURLFile($code, 'application/gzip', 'code.tar.gz'), + 'code' => $this->packageFunction('php') ]; $deployment = $this->client->call(Client::METHOD_POST, '/graphql', [ diff --git a/tests/e2e/Services/GraphQL/FunctionsServerTest.php b/tests/e2e/Services/GraphQL/FunctionsServerTest.php index 25a671fa1c..c3606244c4 100644 --- a/tests/e2e/Services/GraphQL/FunctionsServerTest.php +++ b/tests/e2e/Services/GraphQL/FunctionsServerTest.php @@ -2,7 +2,6 @@ namespace Tests\E2E\Services\GraphQL; -use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; @@ -82,10 +81,6 @@ class FunctionsServerTest extends Scope $projectId = $this->getProject()['$id']; $query = $this->getQuery(self::$CREATE_DEPLOYMENT); - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - $gqlPayload = [ 'operations' => \json_encode([ 'query' => $query, @@ -98,7 +93,7 @@ class FunctionsServerTest extends Scope 'map' => \json_encode([ 'code' => ["variables.code"] ]), - 'code' => new CURLFile($code, 'application/gzip', 'code.tar.gz'), + 'code' => $this->packageFunction('php'), ]; $deployment = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ diff --git a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php index 6ab2874f8e..b1777cdba9 100644 --- a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php @@ -2,7 +2,6 @@ namespace Tests\E2E\Services\Realtime; -use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; @@ -506,21 +505,15 @@ class RealtimeConsoleClientTest extends Scope * Test Create Deployment */ - $folder = 'php'; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; - $this->packageCode($folder); - $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)), + 'code' => $this->packageFunction('php'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; - $this->assertEquals(202, $deployment['headers']['status-code']); $response = json_decode($client->receive(), true); From 410a35deb510535de565915921afa6c09add1075 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 21:29:18 +0100 Subject: [PATCH 141/213] fix: spacing --- .../Functions/FunctionsCustomServerTest.php | 123 ++++++++++++++---- 1 file changed, 100 insertions(+), 23 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 4ff6639864..47e80efde9 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -38,7 +38,9 @@ class FunctionsCustomServerTest extends Scope 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); + $functionId = $functionId = $function['body']['$id'] ?? ''; + $dateValidator = new DatetimeValidator(); $this->assertEquals(201, $function['headers']['status-code']); $this->assertNotEmpty($function['body']['$id']); @@ -66,6 +68,7 @@ class FunctionsCustomServerTest extends Scope 'key' => 'funcKey3', 'value' => 'funcValue3', ]); + $this->assertEquals(201, $variable['headers']['status-code']); $this->assertEquals(201, $variable2['headers']['status-code']); $this->assertEquals(201, $variable3['headers']['status-code']); @@ -87,6 +90,7 @@ class FunctionsCustomServerTest extends Scope $functions = $this->listFunctions([ 'search' => $data['functionId'] ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(1, $functions['body']['functions']); $this->assertEquals($functions['body']['functions'][0]['name'], 'Test'); @@ -97,6 +101,7 @@ class FunctionsCustomServerTest extends Scope Query::limit(1)->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(1, $functions['body']['functions']); @@ -106,6 +111,7 @@ class FunctionsCustomServerTest extends Scope Query::offset(1)->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(0, $functions['body']['functions']); @@ -115,6 +121,7 @@ class FunctionsCustomServerTest extends Scope Query::equal('enabled', [true])->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(1, $functions['body']['functions']); @@ -124,6 +131,7 @@ class FunctionsCustomServerTest extends Scope Query::equal('enabled', [false])->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(0, $functions['body']['functions']); @@ -131,6 +139,7 @@ class FunctionsCustomServerTest extends Scope $functions = $this->listFunctions([ 'search' => 'Test' ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(1, $functions['body']['functions']); $this->assertEquals($functions['body']['functions'][0]['$id'], $data['functionId']); @@ -139,6 +148,7 @@ class FunctionsCustomServerTest extends Scope $functions = $this->listExecutions([ 'search' => 'php-8.0' ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(1, $functions['body']['functions']); $this->assertEquals($functions['body']['functions'][0]['$id'], $data['functionId']); @@ -160,6 +170,7 @@ class FunctionsCustomServerTest extends Scope ]); $functions = $this->listFunctions(); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertEquals($functions['body']['total'], 2); $this->assertIsArray($functions['body']['functions']); @@ -172,6 +183,7 @@ class FunctionsCustomServerTest extends Scope Query::cursorAfter(new Document(['$id' => $functions['body']['functions'][0]['$id']]))->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(1, $functions['body']['functions']); $this->assertEquals($functions['body']['functions'][0]['name'], 'Test 2'); @@ -181,6 +193,7 @@ class FunctionsCustomServerTest extends Scope Query::cursorBefore(new Document(['$id' => $functions['body']['functions'][1]['$id']]))->toString(), ], ]); + $this->assertEquals($functions['headers']['status-code'], 200); $this->assertCount(1, $functions['body']['functions']); $this->assertEquals($functions['body']['functions'][0]['name'], 'Test'); @@ -207,6 +220,7 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $function = $this->getFunction($data['functionId']); + $this->assertEquals($function['headers']['status-code'], 200); $this->assertEquals($function['body']['name'], 'Test'); @@ -214,6 +228,7 @@ class FunctionsCustomServerTest extends Scope * Test for FAILURE */ $function = $this->getFunction('x'); + $this->assertEquals($function['headers']['status-code'], 404); return $data; @@ -242,10 +257,11 @@ class FunctionsCustomServerTest extends Scope 'entrypoint' => 'index.php', ]); + $dateValidator = new DatetimeValidator(); + $this->assertEquals(200, $function['headers']['status-code']); $this->assertNotEmpty($function['body']['$id']); $this->assertEquals('Test1', $function['body']['name']); - $dateValidator = new DatetimeValidator(); $this->assertEquals(true, $dateValidator->isValid($function['body']['$createdAt'])); $this->assertEquals(true, $dateValidator->isValid($function['body']['$updatedAt'])); $this->assertEquals('', $function['body']['deployment']); @@ -261,11 +277,8 @@ class FunctionsCustomServerTest extends Scope 'key' => 'GLOBAL_VARIABLE', 'value' => 'Global Variable Value', ]); - $this->assertEquals(201, $variable['headers']['status-code']); - /** - * Test for FAILURE - */ + $this->assertEquals(201, $variable['headers']['status-code']); return $data; } @@ -296,13 +309,15 @@ class FunctionsCustomServerTest extends Scope 'code' => $this->packageFunction('php'), 'activate' => true ]); - $deploymentId = $deployment['body']['$id'] ?? ''; + $this->assertEquals(202, $deployment['headers']['status-code']); + $deploymentId = $deployment['body']['$id'] ?? ''; + $this->assertEventually(function () use ($functionId, $deploymentId) { $deployment = $this->getDeployment($functionId, $deploymentId); $this->assertEquals(200, $deployment['headers']['status-code']); - $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals('ready', $deployment['body']['status']); $this->assertEquals('cli', $deployment['body']['type']); }, 500000, 1000); } @@ -338,23 +353,28 @@ class FunctionsCustomServerTest extends Scope 'templateVersion' => $starterTemplate['body']['providerVersion'], ] ); - $functionId = $functionId = $function['body']['$id'] ?? ''; + $this->assertEquals(201, $function['headers']['status-code']); $this->assertNotEmpty($function['body']['$id']); + $functionId = $functionId = $function['body']['$id'] ?? ''; + $deployments = $this->listDeployments($functionId); + $this->assertEquals(200, $deployments['headers']['status-code']); $this->assertEquals(1, $deployments['body']['total']); $lastDeployment = $deployments['body']['deployments'][0]; + $this->assertNotEmpty($lastDeployment['$id']); $this->assertEquals(0, $lastDeployment['size']); $deploymentId = $lastDeployment['$id']; + $this->assertEventually(function () use ($functionId, $deploymentId) { $deployment = $this->getDeployment($functionId, $deploymentId); $this->assertEquals(200, $deployment['headers']['status-code']); - $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals('ready', $deployment['body']['status']); $this->assertEquals('cli', $deployment['body']['type']); }, 500000, 1000); @@ -366,6 +386,7 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($functionId, [ 'path' => '/ping', ]); + $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals("completed", $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); @@ -378,10 +399,12 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ], $this->getHeaders()), []); + $this->assertEquals(200, $users['headers']['status-code']); $this->assertIsInt($users['body']['total']); $totalUsers = $users['body']['total']; + $this->assertStringContainsString("Total users: " . $totalUsers, $execution['body']['logs']); // Execute function again but async @@ -389,13 +412,16 @@ class FunctionsCustomServerTest extends Scope 'path' => '/ping', 'async' => true ]); - $executionId = $execution['body']['$id'] ?? ''; + $this->assertEquals(202, $execution['headers']['status-code']); $this->assertNotEmpty($execution['body']['$id']); $this->assertEquals('waiting', $execution['body']['status']); + $executionId = $execution['body']['$id'] ?? ''; + $this->assertEventually(function () use ($functionId, $executionId, $totalUsers) { $execution = $this->getExecution($functionId, $executionId); + $this->assertEquals(200, $execution['headers']['status-code']); $this->assertEquals(200, $execution['body']['responseStatusCode']); $this->assertEquals('completed', $execution['body']['status']); @@ -405,7 +431,6 @@ class FunctionsCustomServerTest extends Scope }, 100000, 250); $function = $this->deleteFunction($functionId); - $this->assertEquals(204, $function['headers']['status-code']); } /** @@ -417,34 +442,39 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $functionId = $data['functionId']; + $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), 'activate' => true ]); - $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']); + $deploymentId = $deployment['body']['$id'] ?? ''; + $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), 'activate' => false ]); + $deploymentIdInactive = $deployment['body']['$id']; + $this->assertEquals(202, $deployment['headers']['status-code']); $this->assertNotEmpty($deployment['body']['$id']); $this->assertEventually(function () use ($functionId, $deploymentId, $deploymentIdInactive) { $deployment = $this->getDeployment($functionId, $deploymentId); - $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals('ready', $deployment['body']['status']); $deployment = $this->getDeployment($functionId, $deploymentIdInactive); - $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals('ready', $deployment['body']['status']); }, 500000, 1000); $function = $this->getFunction($functionId); + $this->assertEquals(200, $function['headers']['status-code']); $this->assertEquals($deploymentId, $function['body']['deployment']); $this->assertNotEquals($deploymentIdInactive, $function['body']['deployment']); @@ -453,6 +483,7 @@ class FunctionsCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), []); + $this->assertEquals(204, $deployment['headers']['status-code']); return array_merge($data, ['deploymentId' => $deploymentId]); @@ -464,10 +495,12 @@ class FunctionsCustomServerTest extends Scope public function testCancelDeploymentBuild($data): void { $functionId = $data['functionId']; + $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), 'activate' => false ]); + $deploymentId = $deployment['body']['$id'] ?? ''; $this->assertEquals(202, $deployment['headers']['status-code']); @@ -477,6 +510,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEventually(function () use ($functionId, $deploymentId) { $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertEquals('building', $deployment['body']['status']); }, 100000, 250); @@ -486,6 +520,7 @@ class FunctionsCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); + $this->assertEquals(200, $cancel['headers']['status-code']); $this->assertEquals('canceled', $cancel['body']['status']); @@ -497,6 +532,7 @@ class FunctionsCustomServerTest extends Scope \sleep(30); $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertEquals('canceled', $deployment['body']['status']); } @@ -554,8 +590,9 @@ class FunctionsCustomServerTest extends Scope $this->assertEventually(function () use ($functionId, $deploymentId, $deploymentSize) { $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); - $this->assertEquals('completed', $deployment['body']['status']); + $this->assertEquals('ready', $deployment['body']['status']); $this->assertEquals($deploymentSize, $deployment['body']['size']); $this->assertGreaterThan(1024 * 1024 * 10, $deployment['body']['buildSize']); // ~7MB video file + 10MB sample file }, 500000, 1000); @@ -609,6 +646,7 @@ class FunctionsCustomServerTest extends Scope $deployments = $this->listDeployments($functionId, [ 'search' => $data['functionId'] ]); + $this->assertEquals($deployments['headers']['status-code'], 200); $this->assertEquals(3, $deployments['body']['total']); $this->assertIsArray($deployments['body']['deployments']); @@ -621,6 +659,7 @@ class FunctionsCustomServerTest extends Scope Query::limit(1)->toString(), ], ]); + $this->assertEquals($deployments['headers']['status-code'], 200); $this->assertCount(1, $deployments['body']['deployments']); @@ -655,7 +694,6 @@ class FunctionsCustomServerTest extends Scope 'search' => 'Test' ]); - $this->assertEquals($deployments['headers']['status-code'], 200); $this->assertEquals(3, $deployments['body']['total']); $this->assertIsArray($deployments['body']['deployments']); @@ -753,6 +791,7 @@ class FunctionsCustomServerTest extends Scope Query::limit(1)->toString(), ] ); + $this->assertEquals(200, $deployments['headers']['status-code']); $this->assertGreaterThanOrEqual(1, $deployments['body']['total']); $this->assertNotEmpty($deployments['body']['deployments'][0]['$id']); @@ -775,7 +814,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn ($deployment) => $deployment['$id'] === $deploymentId + fn($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); @@ -797,6 +836,7 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $deployment = $this->getDeployment($data['functionId'], $data['deploymentId']); + $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertGreaterThan(0, $deployment['body']['buildTime']); $this->assertNotEmpty($deployment['body']['status']); @@ -808,6 +848,7 @@ class FunctionsCustomServerTest extends Scope * Test for FAILURE */ $deployment = $this->getDeployment($data['functionId'], 'x'); + $this->assertEquals($deployment['headers']['status-code'], 404); return $data; @@ -824,7 +865,6 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($data['functionId'], [ 'async' => false, ]); - $executionId = $execution['body']['$id'] ?? ''; $this->assertEquals(201, $execution['headers']['status-code']); $this->assertNotEmpty($execution['body']['$id']); @@ -845,10 +885,13 @@ class FunctionsCustomServerTest extends Scope $this->assertNotEmpty($execution['body']['logs']); $this->assertLessThan(10, $execution['body']['duration']); + $executionId = $execution['body']['$id'] ?? ''; + $execution = $this->createExecution($data['functionId'], [ 'async' => false, 'path' => '/?code=400' ]); + $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(400, $execution['body']['responseStatusCode']); @@ -859,6 +902,7 @@ class FunctionsCustomServerTest extends Scope ], $this->getHeaders()), []); $execution = $this->createExecution($data['functionId']); + $this->assertEquals(204, $execution['headers']['status-code']); return array_merge($data, ['executionId' => $executionId]); @@ -873,6 +917,7 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $executions = $this->listExecutions($data['functionId']); + $this->assertEquals($executions['headers']['status-code'], 200); $this->assertEquals($executions['body']['total'], 1); $this->assertIsArray($executions['body']['executions']); @@ -884,6 +929,7 @@ class FunctionsCustomServerTest extends Scope Query::limit(1)->toString(), ], ]); + $this->assertEquals(200, $executions['headers']['status-code']); $this->assertCount(1, $executions['body']['executions']); @@ -892,6 +938,7 @@ class FunctionsCustomServerTest extends Scope Query::offset(1)->toString(), ], ]); + $this->assertEquals(200, $executions['headers']['status-code']); $this->assertCount(0, $executions['body']['executions']); @@ -900,6 +947,7 @@ class FunctionsCustomServerTest extends Scope Query::equal('trigger', ['http'])->toString(), ], ]); + $this->assertEquals(200, $executions['headers']['status-code']); $this->assertCount(1, $executions['body']['executions']); @@ -909,6 +957,7 @@ class FunctionsCustomServerTest extends Scope $executions = $this->listExecutions($data['functionId'], [ 'search' => $data['executionId'], ]); + $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals(1, $executions['body']['total']); $this->assertIsInt($executions['body']['total']); @@ -918,6 +967,7 @@ class FunctionsCustomServerTest extends Scope $executions = $this->listExecutions($data['functionId'], [ 'search' => $data['functionId'], ]); + $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals(1, $executions['body']['total']); $this->assertIsInt($executions['body']['total']); @@ -938,6 +988,7 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($data['functionId'], [ // Testing default value, should be 'async' => false ]); + $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); @@ -960,6 +1011,7 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $execution = $this->getExecution($data['functionId'], $data['executionId']); + $this->assertEquals($execution['headers']['status-code'], 200); $this->assertEquals($execution['body']['$id'], $data['executionId']); @@ -967,6 +1019,7 @@ class FunctionsCustomServerTest extends Scope * Test for FAILURE */ $function = $this->getExecution($data['functionId'], 'x'); + $this->assertEquals($function['headers']['status-code'], 404); return $data; @@ -1008,6 +1061,7 @@ class FunctionsCustomServerTest extends Scope ]); $executionId = $execution['body']['$id'] ?? ''; + $this->assertEquals(202, $execution['headers']['status-code']); $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $executionId, array_merge([ @@ -1039,6 +1093,7 @@ class FunctionsCustomServerTest extends Scope ]); $executionId = $execution['body']['$id'] ?? ''; + $this->assertEquals(202, $execution['headers']['status-code']); $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $executionId, [ @@ -1083,6 +1138,7 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($data['functionId']); $output = json_decode($execution['body']['responseBody'], true); + $this->assertEquals(1, $output['APPWRITE_FUNCTION_CPUS']); $this->assertEquals(1024, $output['APPWRITE_FUNCTION_MEMORY']); @@ -1110,6 +1166,7 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($data['functionId']); $output = json_decode($execution['body']['responseBody'], true); + $this->assertEquals(1, $output['APPWRITE_FUNCTION_CPUS']); $this->assertEquals(512, $output['APPWRITE_FUNCTION_MEMORY']); @@ -1130,6 +1187,7 @@ class FunctionsCustomServerTest extends Scope 'entrypoint' => 'index.php', 'specification' => 's-2vcpu-512mb', // Invalid specification ]); + $this->assertEquals(400, $function['headers']['status-code']); $this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $function['body']['message']); @@ -1148,10 +1206,12 @@ class FunctionsCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); + $this->assertEquals(204, $deployment['headers']['status-code']); $this->assertEmpty($deployment['body']); $deployment = $this->getDeployment($data['functionId'], $data['deploymentId']); + $this->assertEquals(404, $deployment['headers']['status-code']); return $data; @@ -1166,10 +1226,12 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $function = $this->deleteFunction($data['functionId']); + $this->assertEquals(204, $function['headers']['status-code']); $this->assertEmpty($function['body']); $function = $this->getFunction($data['functionId']); + $this->assertEquals(404, $function['headers']['status-code']); return $data; @@ -1193,9 +1255,11 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($functionId, [ 'async' => true ]); - $executionId = $execution['body']['$id'] ?? ''; + $this->assertEquals(202, $execution['headers']['status-code']); + $executionId = $execution['body']['$id'] ?? ''; + \sleep(5); // Wait for the function to timeout $this->assertEventually(function () use ($functionId, $executionId) { @@ -1254,6 +1318,7 @@ class FunctionsCustomServerTest extends Scope 'key' => 'CUSTOM_VARIABLE', 'value' => 'variable' ]); + $this->assertEquals(201, $variable['headers']['status-code']); $deploymentId = $this->setupDeployment($functionId, [ @@ -1266,7 +1331,7 @@ class FunctionsCustomServerTest extends Scope 'body' => 'foobar', 'async' => false ]); - $executionId = $execution['body']['$id'] ?? ''; + $output = json_decode($execution['body']['responseBody'], true); $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); @@ -1286,7 +1351,10 @@ class FunctionsCustomServerTest extends Scope $this->assertStringContainsString('Amazing Function Log', $execution['body']['logs']); $this->assertEmpty($execution['body']['errors']); + $executionId = $execution['body']['$id'] ?? ''; + $executions = $this->listExecutions($functionId); + $this->assertEquals($executions['headers']['status-code'], 200); $this->assertEquals($executions['body']['total'], 1); $this->assertIsArray($executions['body']['executions']); @@ -1374,6 +1442,7 @@ class FunctionsCustomServerTest extends Scope ], false); $executionBody = json_decode($execution['body'], true); + $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals(\md5($bytes), $executionBody['responseBody']); $this->assertStringStartsWith('application/json', $execution['headers']['content-type']); @@ -1390,6 +1459,7 @@ class FunctionsCustomServerTest extends Scope ], false); $executionBody = json_decode($execution['body'], true); + $this->assertNotEquals(\md5($bytes), $executionBody['responseBody']); $this->cleanupFunction($functionId); @@ -1427,6 +1497,7 @@ class FunctionsCustomServerTest extends Scope 'body' => 'foobar', 'async' => false ]); + $output = json_decode($execution['body']['responseBody'], true); $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); @@ -1485,12 +1556,16 @@ class FunctionsCustomServerTest extends Scope 'userId' => 'unique()', 'name' => 'Event User' ]); - $userId = $user['body']['$id'] ?? ''; + $this->assertEquals(201, $user['headers']['status-code']); + $userId = $user['body']['$id'] ?? ''; + $this->assertEventually(function () use ($functionId, $userId) { $executions = $this->listExecutions($functionId); + $lastExecution = $executions['body']['executions'][0]; + $this->assertEquals('completed', $lastExecution['status']); $this->assertEquals(204, $lastExecution['responseStatusCode']); $this->assertStringContainsString($userId, $lastExecution['logs']); @@ -1548,10 +1623,12 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($functionId, [ 'async' => true, ]); - $executionId = $execution['body']['$id'] ?? ''; + $this->assertEquals(202, $execution['headers']['status-code']); $this->assertNotEmpty($execution['body']['$id']); + $executionId = $execution['body']['$id'] ?? ''; + $this->assertEventually(function () use ($functionId, $executionId) { $execution = $this->getExecution($functionId, $executionId); @@ -1646,7 +1723,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals($cookie, $response['body']); - // Await Aggregation + // Wait for usage to be aggregated sleep(System::getEnv('_APP_USAGE_AGGREGATION_INTERVAL', 30)); $this->assertEventually(function () use ($functionId) { From 906ef59d95b221af625d508d54551e5c8d88fff7 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 21:36:19 +0100 Subject: [PATCH 142/213] chore: fmt --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 47e80efde9..82f80a8cd8 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -814,7 +814,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn($deployment) => $deployment['$id'] === $deploymentId + fn ($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); From 19ea682a52e462418223654dc4e8f1fe3f8b2f1b Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 21:54:25 +0100 Subject: [PATCH 143/213] chore: timeouts --- .../Services/Functions/FunctionsCustomClientTest.php | 2 +- .../Services/Functions/FunctionsCustomServerTest.php | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index dd950ca655..53713cfd40 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -244,7 +244,7 @@ class FunctionsCustomClientTest extends Scope $execution = $this->getExecution($functionId, $executionId); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); - }, 10000, 250); + }, 10000, 500); return [ 'functionId' => $functionId diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 82f80a8cd8..b895e4c938 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -373,12 +373,14 @@ class FunctionsCustomServerTest extends Scope $this->assertEventually(function () use ($functionId, $deploymentId) { $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertEquals('ready', $deployment['body']['status']); $this->assertEquals('cli', $deployment['body']['type']); }, 500000, 1000); $function = $this->getFunction($functionId); + $this->assertEquals(200, $function['headers']['status-code']); $this->assertEquals($deploymentId, $function['body']['deployment']); @@ -428,7 +430,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEmpty($execution['body']['responseBody']); $this->assertEmpty($execution['body']['errors']); $this->assertStringContainsString("Total users: " . $totalUsers, $execution['body']['logs']); - }, 100000, 250); + }, 10000, 500); $function = $this->deleteFunction($functionId); } @@ -1273,7 +1275,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals('', $execution['body']['responseBody']); $this->assertEquals('', $execution['body']['logs']); $this->assertStringContainsString('timed out', $execution['body']['errors']); - }, 5000, 250); + }, 10000, 500); $this->cleanupFunction($functionId); } @@ -1638,7 +1640,7 @@ class FunctionsCustomServerTest extends Scope $this->assertGreaterThan(0, $execution['body']['duration']); $this->assertNotEmpty($execution['body']['responseBody']); $this->assertStringContainsString("total", $execution['body']['responseBody']); - }, 5000, 250); + }, 10000, 500); $this->cleanupFunction($functionId); } @@ -1905,7 +1907,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals('completed', $execution['body']['status']); $this->assertEmpty($execution['body']['logs']); $this->assertEmpty($execution['body']['errors']); - }, 5000, 250); + }, 10000, 500); // Domain Executions test $rules = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([ From 92ce8d711d923a1b4398d5d1d6cc7ad847dfc8ff Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:10:04 +0100 Subject: [PATCH 144/213] feat: split scheduled tests --- .../Functions/FunctionsConsoleClientTest.php | 12 +- .../Functions/FunctionsCustomClientTest.php | 115 ---------- .../Functions/FunctionsCustomServerTest.php | 36 +--- .../Functions/FunctionsScheduleTest.php | 203 ++++++++++++++++++ 4 files changed, 216 insertions(+), 150 deletions(-) create mode 100644 tests/e2e/Services/Functions/FunctionsScheduleTest.php diff --git a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php index cbfca09564..3a02cbcba2 100644 --- a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php @@ -30,9 +30,11 @@ class FunctionsConsoleClientTest extends Scope 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); - $functionId = $function['body']['$id']; + $this->assertEquals(201, $function['headers']['status-code']); + $functionId = $function['body']['$id']; + $function2 = $this->createFunction([ 'functionId' => ID::unique(), 'name' => 'Test Failure', @@ -40,6 +42,7 @@ class FunctionsConsoleClientTest extends Scope 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', ]); + $this->assertEquals(400, $function2['headers']['status-code']); return [ @@ -110,9 +113,11 @@ class FunctionsConsoleClientTest extends Scope 'value' => 'TESTINGVALUE' ] ); - $variableId = $variable['body']['$id']; + $this->assertEquals(201, $variable['headers']['status-code']); + $variableId = $variable['body']['$id']; + /** * Test for FAILURE */ @@ -124,6 +129,7 @@ class FunctionsConsoleClientTest extends Scope 'value' => 'ANOTHERTESTINGVALUE' ] ); + $this->assertEquals(409, $variable['headers']['status-code']); // Test for invalid key @@ -134,6 +140,7 @@ class FunctionsConsoleClientTest extends Scope 'value' => 'TESTINGVALUE' ] ); + $this->assertEquals(400, $variable['headers']['status-code']); // Test for invalid value @@ -144,6 +151,7 @@ class FunctionsConsoleClientTest extends Scope 'value' => str_repeat("#", 8193), ] ); + $this->assertEquals(400, $variable['headers']['status-code']); return array_merge( diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 53713cfd40..3447ee0547 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -48,7 +48,6 @@ class FunctionsCustomClientTest extends Scope 'users.*.create', 'users.*.delete', ], - 'schedule' => '* * * * *', // Execute every 60 seconds 'timeout' => 10, ]); $this->setupDeployment($functionId, [ @@ -72,124 +71,10 @@ class FunctionsCustomClientTest extends Scope ]); $this->assertEquals(202, $execution['headers']['status-code']); - // Wait for scheduled execution - \sleep(60); - - $this->assertEventually(function () use ($functionId) { - $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['key'], - ]); - $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertCount(2, $executions['body']['executions']); - - $asyncExecution = $executions['body']['executions'][1]; - $this->assertEquals('schedule', $asyncExecution['trigger']); - $this->assertEquals('completed', $asyncExecution['status']); - $this->assertEquals(200, $asyncExecution['responseStatusCode']); - $this->assertEquals('', $asyncExecution['responseBody']); - $this->assertNotEmpty($asyncExecution['logs']); - $this->assertNotEmpty($asyncExecution['errors']); - $this->assertGreaterThan(0, $asyncExecution['duration']); - }, 10000, 500); - $this->cleanupFunction($functionId); } - public function testCreateScheduledExecution(): void - { - /** - * Test for SUCCESS - */ - $functionId = $this->setupFunction([ - 'functionId' => ID::unique(), - 'name' => 'Test', - 'execute' => [Role::user($this->getUser()['$id'])->toString()], - 'runtime' => 'php-8.0', - 'entrypoint' => 'index.php', - 'timeout' => 10, - 'logging' => true, - ]); - $this->setupDeployment($functionId, [ - 'entrypoint' => 'index.php', - 'code' => $this->packageFunction('php'), - 'activate' => true - ]); - // Schedule execution for the future - \date_default_timezone_set('UTC'); - $futureTime = (new \DateTime())->add(new \DateInterval('PT2M')); // 2 minute in the future - $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); - - $execution = $this->createExecution($functionId, [ - 'async' => true, - 'scheduledAt' => $futureTime->format(\DateTime::ATOM), - 'path' => '/custom-path', - 'method' => 'PATCH', - 'body' => 'custom-body', - 'headers' => [ - 'x-custom-header' => 'custom-value' - ] - ]); - $executionId = $execution['body']['$id']; - - $this->assertEquals(202, $execution['headers']['status-code']); - $this->assertEquals('scheduled', $execution['body']['status']); - $this->assertEquals('PATCH', $execution['body']['requestMethod']); - $this->assertEquals('/custom-path', $execution['body']['requestPath']); - $this->assertCount(0, $execution['body']['requestHeaders']); - - \sleep(120); - - $this->assertEventually(function () use ($functionId, $executionId) { - $execution = $this->getExecution($functionId, $executionId); - - $this->assertEquals(200, $execution['headers']['status-code']); - $this->assertEquals(200, $execution['body']['responseStatusCode']); - $this->assertEquals('completed', $execution['body']['status']); - $this->assertEquals('/custom-path', $execution['body']['requestPath']); - $this->assertEquals('PATCH', $execution['body']['requestMethod']); - $this->assertStringContainsString('body-is-custom-body', $execution['body']['logs']); - $this->assertStringContainsString('custom-header-is-custom-value', $execution['body']['logs']); - $this->assertStringContainsString('method-is-patch', $execution['body']['logs']); - $this->assertStringContainsString('path-is-/custom-path', $execution['body']['logs']); - $this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']); - $this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']); - $this->assertGreaterThan(0, $execution['body']['duration']); - }, 10000, 500); - - /* Test for FAILURE */ - // Schedule synchronous execution - $execution = $this->createExecution($functionId, [ - 'async' => false, - 'scheduledAt' => $futureTime->format(\DateTime::ATOM), - ]); - $this->assertEquals(400, $execution['headers']['status-code']); - - // Execution with seconds precision - $execution = $this->createExecution($functionId, [ - 'async' => true, - 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02"))->format(\DateTime::ATOM) - ]); - $this->assertEquals(400, $execution['headers']['status-code']); - - // Execution with milliseconds precision - $execution = $this->createExecution($functionId, [ - 'async' => true, - 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02.255"))->format(\DateTime::ATOM) - ]); - $this->assertEquals(400, $execution['headers']['status-code']); - - // Execution too soon - $execution = $this->createExecution($functionId, [ - 'async' => true, - 'scheduledAt' => (new \DateTime())->add(new \DateInterval('PT1S'))->format(\DateTime::ATOM) - ]); - $this->assertEquals(400, $execution['headers']['status-code']); - - $this->cleanupFunction($functionId, $executionId); - } public function testCreateCustomExecution(): array { diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index b895e4c938..71dce2258c 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -35,7 +35,6 @@ class FunctionsCustomServerTest extends Scope 'buckets.*.create', 'buckets.*.delete', ], - 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); @@ -53,7 +52,7 @@ class FunctionsCustomServerTest extends Scope 'buckets.*.create', 'buckets.*.delete', ], $function['body']['events']); - $this->assertEquals('0 0 1 1 *', $function['body']['schedule']); + $this->assertEmpty($function['body']['schedule']); $this->assertEquals(10, $function['body']['timeout']); $variable = $this->createVariable($functionId, [ @@ -156,7 +155,7 @@ class FunctionsCustomServerTest extends Scope /** * Test pagination */ - $functionId = $this->setupFunction([ + $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test 2', 'runtime' => 'php-8.0', @@ -165,7 +164,6 @@ class FunctionsCustomServerTest extends Scope 'buckets.*.create', 'buckets.*.delete', ], - 'schedule' => '0 0 1 1 *', 'timeout' => 10, ]); @@ -816,7 +814,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn ($deployment) => $deployment['$id'] === $deploymentId + fn($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); @@ -1078,35 +1076,7 @@ class FunctionsCustomServerTest extends Scope return $data; } - /** - * @depends testGetExecution - */ - public function testDeleteScheduledExecution($data): array - { - $futureTime = (new \DateTime())->add(new \DateInterval('PT10H')); - $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); - $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, - 'scheduledAt' => $futureTime->format('Y-m-d H:i:s'), - ]); - - $executionId = $execution['body']['$id'] ?? ''; - - $this->assertEquals(202, $execution['headers']['status-code']); - - $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $executionId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]); - - $this->assertEquals(204, $execution['headers']['status-code']); - - return $data; - } /** * @depends testGetExecution diff --git a/tests/e2e/Services/Functions/FunctionsScheduleTest.php b/tests/e2e/Services/Functions/FunctionsScheduleTest.php new file mode 100644 index 0000000000..bab9a2a684 --- /dev/null +++ b/tests/e2e/Services/Functions/FunctionsScheduleTest.php @@ -0,0 +1,203 @@ +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', + ], + 'schedule' => '* * * * *', // Execute every 60 seconds + 'timeout' => 10, + ]); + + $this->setupDeployment($functionId, [ + 'entrypoint' => 'index.php', + 'code' => $this->packageFunction('php'), + 'activate' => true + ]); + + // Wait for scheduled execution + \sleep(60); + + $this->assertEventually(function () use ($functionId) { + $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['key'], + ]); + + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertCount(1, $executions['body']['executions']); + + $asyncExecution = $executions['body']['executions'][0]; + + $this->assertEquals('schedule', $asyncExecution['trigger']); + $this->assertEquals('completed', $asyncExecution['status']); + $this->assertEquals(200, $asyncExecution['responseStatusCode']); + $this->assertEquals('', $asyncExecution['responseBody']); + $this->assertNotEmpty($asyncExecution['logs']); + $this->assertNotEmpty($asyncExecution['errors']); + $this->assertGreaterThan(0, $asyncExecution['duration']); + }, 10000, 500); + + $this->cleanupFunction($functionId); + } + + public function testCreateScheduledAtExecution(): void + { + /** + * Test for SUCCESS + */ + $functionId = $this->setupFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'execute' => [Role::user($this->getUser()['$id'])->toString()], + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'timeout' => 10, + 'logging' => true, + ]); + $this->setupDeployment($functionId, [ + 'entrypoint' => 'index.php', + 'code' => $this->packageFunction('php'), + 'activate' => true + ]); + + // Schedule execution for the future + \date_default_timezone_set('UTC'); + $futureTime = (new \DateTime())->add(new \DateInterval('PT2M')); // 2 minute in the future + $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); + + $execution = $this->createExecution($functionId, [ + 'async' => true, + 'scheduledAt' => $futureTime->format(\DateTime::ATOM), + 'path' => '/custom-path', + 'method' => 'PATCH', + 'body' => 'custom-body', + 'headers' => [ + 'x-custom-header' => 'custom-value' + ] + ]); + $executionId = $execution['body']['$id']; + + $this->assertEquals(202, $execution['headers']['status-code']); + $this->assertEquals('scheduled', $execution['body']['status']); + $this->assertEquals('PATCH', $execution['body']['requestMethod']); + $this->assertEquals('/custom-path', $execution['body']['requestPath']); + $this->assertCount(0, $execution['body']['requestHeaders']); + + \sleep(120); + + $this->assertEventually(function () use ($functionId, $executionId) { + $execution = $this->getExecution($functionId, $executionId); + + $this->assertEquals(200, $execution['headers']['status-code']); + $this->assertEquals(200, $execution['body']['responseStatusCode']); + $this->assertEquals('completed', $execution['body']['status']); + $this->assertEquals('/custom-path', $execution['body']['requestPath']); + $this->assertEquals('PATCH', $execution['body']['requestMethod']); + $this->assertStringContainsString('body-is-custom-body', $execution['body']['logs']); + $this->assertStringContainsString('custom-header-is-custom-value', $execution['body']['logs']); + $this->assertStringContainsString('method-is-patch', $execution['body']['logs']); + $this->assertStringContainsString('path-is-/custom-path', $execution['body']['logs']); + $this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']); + $this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']); + $this->assertGreaterThan(0, $execution['body']['duration']); + }, 10000, 500); + + /* Test for FAILURE */ + // Schedule synchronous execution + $execution = $this->createExecution($functionId, [ + 'async' => false, + 'scheduledAt' => $futureTime->format(\DateTime::ATOM), + ]); + $this->assertEquals(400, $execution['headers']['status-code']); + + // Execution with seconds precision + $execution = $this->createExecution($functionId, [ + 'async' => true, + 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02"))->format(\DateTime::ATOM) + ]); + $this->assertEquals(400, $execution['headers']['status-code']); + + // Execution with milliseconds precision + $execution = $this->createExecution($functionId, [ + 'async' => true, + 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02.255"))->format(\DateTime::ATOM) + ]); + $this->assertEquals(400, $execution['headers']['status-code']); + + // Execution too soon + $execution = $this->createExecution($functionId, [ + 'async' => true, + 'scheduledAt' => (new \DateTime())->add(new \DateInterval('PT1S'))->format(\DateTime::ATOM) + ]); + $this->assertEquals(400, $execution['headers']['status-code']); + + $this->cleanupFunction($functionId, $executionId); + } + + public function testDeleteScheduledExecution() + { + $functionId = $this->setupFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'execute' => [Role::user($this->getUser()['$id'])->toString()], + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'timeout' => 10, + 'logging' => true, + ]); + + $this->setupDeployment($functionId, [ + 'entrypoint' => 'index.php', + 'code' => $this->packageFunction('php'), + 'activate' => true + ]); + + $futureTime = (new \DateTime())->add(new \DateInterval('PT10H')); + $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); + + $execution = $this->createExecution($functionId, [ + 'async' => true, + 'scheduledAt' => $futureTime->format('Y-m-d H:i:s'), + ]); + + $this->assertEquals(202, $execution['headers']['status-code']); + + $executionId = $execution['body']['$id'] ?? ''; + + $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(204, $execution['headers']['status-code']); + + $this->cleanupFunction($functionId); + } +} From f04e47b3d455b99ed6d36d04baa6c61143e05313 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:11:44 +0100 Subject: [PATCH 145/213] chore: fmt --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 71dce2258c..5db051da2b 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -814,7 +814,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn($deployment) => $deployment['$id'] === $deploymentId + fn ($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); From b621ec2e8bdf5f7bda51da1e63e4708dd3ff1f9d Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:50:30 +0530 Subject: [PATCH 146/213] test for response and request filters --- .../Functions/FunctionsCustomServerTest.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index dccbf2e544..4dabec67f0 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -2685,6 +2685,27 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); + // get function with 1.5.0 response format + $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']); + + // get function without response format header + $function = $this->client->call(Client::METHOD_GET, '/functions/' . $response['body']['$id'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $function['headers']['status-code']); + $this->assertArrayHasKey('scopes', $function['body']); + $this->assertArrayHasKey('specification', $function['body']); + // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $response['body']['$id'], [ 'content-type' => 'application/json', From 321227db15a5fc9dbbba5ecc667b6dbcd7cbd05c Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:15:05 +0100 Subject: [PATCH 147/213] fix: seperate tests --- .github/workflows/tests.yml | 3 ++- tests/e2e/Services/Functions/FunctionsBase.php | 18 ++++++++---------- .../Functions/FunctionsCustomServerTest.php | 11 ++++++----- .../FunctionsScheduleTest.php | 6 +++--- 4 files changed, 19 insertions(+), 19 deletions(-) rename tests/e2e/Services/{Functions => FunctionsSchedule}/FunctionsScheduleTest.php (98%) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 633bd46ea4..5b82cba594 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -113,6 +113,7 @@ jobs: Console, Databases, Functions, + FunctionsSchedule, GraphQL, Health, Locale, @@ -141,7 +142,7 @@ jobs: run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose up -d - sleep 25 + sleep 10 - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 5ed87b4895..8b19c65705 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -101,7 +101,7 @@ trait FunctionsBase return $deployment; } - protected function getExecution($functionId, $executionId) + protected function getExecution(string $functionId, $executionId): mixed { $execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([ 'content-type' => 'application/json', @@ -111,7 +111,7 @@ trait FunctionsBase return $execution; } - protected function listFunctions($params = []) + protected function listFunctions(mixed $params = []): mixed { $functions = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ 'content-type' => 'application/json', @@ -121,7 +121,7 @@ trait FunctionsBase return $functions; } - protected function listDeployments($functionId, $params = []) + protected function listDeployments(string $functionId, $params = []): mixed { $deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments', array_merge([ 'content-type' => 'application/json', @@ -131,7 +131,7 @@ trait FunctionsBase return $deployments; } - protected function listExecutions($functionId, $params = []) + protected function listExecutions(string $functionId, mixed $params = []): mixed { $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', @@ -157,10 +157,8 @@ trait FunctionsBase return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath)); } - protected function createDeployment( - string $functionId, - mixed $params - ) { + protected function createDeployment(string $functionId, mixed $params = []): mixed + { $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', 'x-appwrite-project' => $this->getProject()['$id'], @@ -189,7 +187,7 @@ trait FunctionsBase return $template; } - protected function createExecution(string $functionId, mixed $params = []) + protected function createExecution(string $functionId, mixed $params = []): mixed { $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', @@ -199,7 +197,7 @@ trait FunctionsBase return $execution; } - protected function deleteFunction($functionId) + protected function deleteFunction(string $functionId): mixed { $function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ 'content-type' => 'application/json', diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 5db051da2b..b57cd3d0b8 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -144,7 +144,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($functions['body']['functions'][0]['$id'], $data['functionId']); // Test search runtime - $functions = $this->listExecutions([ + $functions = $this->listFunctions([ 'search' => 'php-8.0' ]); @@ -490,7 +490,7 @@ class FunctionsCustomServerTest extends Scope } /** - * @depends testUpdate + * @depends testUpdateFunction */ public function testCancelDeploymentBuild($data): void { @@ -538,7 +538,7 @@ class FunctionsCustomServerTest extends Scope } /** - * @depends testUpdate + * @depends testUpdateFunction */ public function testCreateDeploymentLarge($data): array { @@ -814,7 +814,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn ($deployment) => $deployment['$id'] === $deploymentId + fn($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); @@ -1273,7 +1273,7 @@ class FunctionsCustomServerTest extends Scope * @param string $entrypoint * * @dataProvider provideCustomExecutions - * @depends testTimeout + * @depends testExecutionTimeout */ public function testCreateCustomExecution(string $folder, string $name, string $entrypoint, string $runtimeName, string $runtimeVersion) { @@ -1743,6 +1743,7 @@ class FunctionsCustomServerTest extends Scope $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', 'code' => $this->packageFunction('php-binary-response'), + 'activate' => true ]); $proxyClient = new Client(); diff --git a/tests/e2e/Services/Functions/FunctionsScheduleTest.php b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php similarity index 98% rename from tests/e2e/Services/Functions/FunctionsScheduleTest.php rename to tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php index bab9a2a684..f39efb42b5 100644 --- a/tests/e2e/Services/Functions/FunctionsScheduleTest.php +++ b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php @@ -6,14 +6,14 @@ use Appwrite\ID; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\SideServer; +use Tests\E2E\Scopes\SideClient; use Utopia\Database\Helpers\Role; class FunctionsScheduleTest extends Scope { use FunctionsBase; use ProjectCustom; - use SideServer; + use SideClient; public function testCreateScheduledExecution() { @@ -47,7 +47,7 @@ class FunctionsScheduleTest extends Scope $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['key'], + 'x-appwrite-key' => $this->getProject()['apiKey'], ]); $this->assertEquals(200, $executions['headers']['status-code']); From 72ddef855ed6452c7ffd9dd5d82ec43908ef01f0 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:16:18 +0100 Subject: [PATCH 148/213] chore: fmt --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index b57cd3d0b8..e9297a109f 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -814,7 +814,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn($deployment) => $deployment['$id'] === $deploymentId + fn ($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); From e4ad2ed566e349c1bfa849074bcbebeafaf8446f Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:33:26 +0100 Subject: [PATCH 149/213] fix: realtime tests --- .../FunctionsScheduleTest.php | 33 ++++++++++++------- tests/e2e/Services/Realtime/RealtimeBase.php | 21 ++++++++++++ .../Realtime/RealtimeCustomClientTest.php | 9 +---- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php index f39efb42b5..7e36662e9e 100644 --- a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php +++ b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php @@ -6,14 +6,14 @@ use Appwrite\ID; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\SideClient; +use Tests\E2E\Scopes\SideServer; use Utopia\Database\Helpers\Role; class FunctionsScheduleTest extends Scope { use FunctionsBase; use ProjectCustom; - use SideClient; + use SideServer; public function testCreateScheduledExecution() { @@ -92,16 +92,27 @@ class FunctionsScheduleTest extends Scope $futureTime = (new \DateTime())->add(new \DateInterval('PT2M')); // 2 minute in the future $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); - $execution = $this->createExecution($functionId, [ - 'async' => true, - 'scheduledAt' => $futureTime->format(\DateTime::ATOM), - 'path' => '/custom-path', - 'method' => 'PATCH', - 'body' => 'custom-body', - 'headers' => [ - 'x-custom-header' => 'custom-value' + + $execution = $this->client->call( + Client::METHOD_POST, + '/functions/' . $functionId . '/executions', + [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $this->getUser()['session'], + ], + [ + 'async' => true, + 'scheduledAt' => $futureTime->format(\DateTime::ATOM), + 'path' => '/custom-path', + 'method' => 'PATCH', + 'body' => 'custom-body', + 'headers' => [ + 'x-custom-header' => 'custom-value' + ] ] - ]); + ); $executionId = $execution['body']['$id']; $this->assertEquals(202, $execution['headers']['status-code']); diff --git a/tests/e2e/Services/Realtime/RealtimeBase.php b/tests/e2e/Services/Realtime/RealtimeBase.php index 30c411ba93..f0cd0e7c3b 100644 --- a/tests/e2e/Services/Realtime/RealtimeBase.php +++ b/tests/e2e/Services/Realtime/RealtimeBase.php @@ -2,6 +2,8 @@ namespace Tests\E2E\Services\Realtime; +use CURLFile; +use Utopia\CLI\Console; use WebSocket\Client as WebSocketClient; use WebSocket\ConnectionException; @@ -71,4 +73,23 @@ trait RealtimeBase $this->expectException(ConnectionException::class); // Check if server disconnnected client $client->close(); } + + // Function-related methods + protected string $output = ''; + + protected function packageFunction(string $function = 'php'): CURLFile + { + $folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function"; + $tarPath = "$folderPath/code.tar.gz"; + + if (!file_exists($tarPath)) { + Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output); + } + + if (filesize($tarPath) > 1024 * 1024 * 5) { + throw new \Exception('Code package is too large. Use the chunked upload method instead.'); + } + + return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath)); + } } diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 86aaee2ab0..4c23bb2eb9 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -7,7 +7,6 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\CLI\Console; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -1271,19 +1270,13 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals($function['headers']['status-code'], 201); $this->assertNotEmpty($function['body']['$id']); - $folder = 'timeout'; - $output = ''; - $code = realpath(__DIR__ . '/../../../resources/functions') . "/{$folder}/code.tar.gz"; - - Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/{$folder} && tar --exclude code.tar.gz -czf code.tar.gz .", '', $output); - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ]), [ 'entrypoint' => 'index.php', - 'code' => new CURLFile($code, 'application/x-gzip', basename($code)), + 'code' => $this->packageFunction('timeout'), 'activate' => true ]); From f24863349e133f51712aae84ba686ae86eaf3437 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:41:34 +0100 Subject: [PATCH 150/213] fixes --- .../Functions/FunctionsCustomServerTest.php | 24 ++++++++++--------- tests/e2e/Services/Realtime/RealtimeBase.php | 21 ---------------- .../Realtime/RealtimeCustomClientTest.php | 2 ++ 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e9297a109f..d95d611f13 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -176,25 +176,25 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($functions['body']['functions'][0]['name'], 'Test'); $this->assertEquals($functions['body']['functions'][1]['name'], 'Test 2'); - $functions = $this->listFunctions([ + $functions1 = $this->listFunctions([ 'queries' => [ Query::cursorAfter(new Document(['$id' => $functions['body']['functions'][0]['$id']]))->toString(), ], ]); - $this->assertEquals($functions['headers']['status-code'], 200); - $this->assertCount(1, $functions['body']['functions']); - $this->assertEquals($functions['body']['functions'][0]['name'], 'Test 2'); + $this->assertEquals($functions1['headers']['status-code'], 200); + $this->assertCount(1, $functions1['body']['functions']); + $this->assertEquals($functions1['body']['functions'][0]['name'], 'Test 2'); - $functions = $this->listFunctions([ + $functions2 = $this->listFunctions([ 'queries' => [ Query::cursorBefore(new Document(['$id' => $functions['body']['functions'][1]['$id']]))->toString(), ], ]); - $this->assertEquals($functions['headers']['status-code'], 200); - $this->assertCount(1, $functions['body']['functions']); - $this->assertEquals($functions['body']['functions'][0]['name'], 'Test'); + $this->assertEquals($functions2['headers']['status-code'], 200); + $this->assertCount(1, $functions2['body']['functions']); + $this->assertEquals($functions2['body']['functions'][0]['name'], 'Test'); /** * Test for FAILURE @@ -285,7 +285,7 @@ class FunctionsCustomServerTest extends Scope { $functionId = $this->setupFunction([ 'functionId' => ID::unique(), - 'name' => 'test-cli-deployment', + 'name' => 'Test', 'execute' => [Role::user($this->getUser()['$id'])->toString()], 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', @@ -297,12 +297,12 @@ class FunctionsCustomServerTest extends Scope 'timeout' => 10, ]); - $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ + $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', - ], $this->getHeaders()), [ + ], [ 'entrypoint' => 'index.php', 'code' => $this->packageFunction('php'), 'activate' => true @@ -314,6 +314,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEventually(function () use ($functionId, $deploymentId) { $deployment = $this->getDeployment($functionId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertEquals('ready', $deployment['body']['status']); $this->assertEquals('cli', $deployment['body']['type']); @@ -1212,6 +1213,7 @@ class FunctionsCustomServerTest extends Scope public function testExecutionTimeout() { $functionId = $this->setupFunction([ + 'functionId' => ID::unique(), 'name' => 'timeout-php-8.0', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', diff --git a/tests/e2e/Services/Realtime/RealtimeBase.php b/tests/e2e/Services/Realtime/RealtimeBase.php index f0cd0e7c3b..30c411ba93 100644 --- a/tests/e2e/Services/Realtime/RealtimeBase.php +++ b/tests/e2e/Services/Realtime/RealtimeBase.php @@ -2,8 +2,6 @@ namespace Tests\E2E\Services\Realtime; -use CURLFile; -use Utopia\CLI\Console; use WebSocket\Client as WebSocketClient; use WebSocket\ConnectionException; @@ -73,23 +71,4 @@ trait RealtimeBase $this->expectException(ConnectionException::class); // Check if server disconnnected client $client->close(); } - - // Function-related methods - protected string $output = ''; - - protected function packageFunction(string $function = 'php'): CURLFile - { - $folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function"; - $tarPath = "$folderPath/code.tar.gz"; - - if (!file_exists($tarPath)) { - Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->output); - } - - if (filesize($tarPath) > 1024 * 1024 * 5) { - throw new \Exception('Code package is too large. Use the chunked upload method instead.'); - } - - return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath)); - } } diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 4c23bb2eb9..260d5da3bf 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -7,6 +7,7 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; +use Tests\E2E\Services\Functions\FunctionsBase; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -14,6 +15,7 @@ use WebSocket\ConnectionException; class RealtimeCustomClientTest extends Scope { + use FunctionsBase; use RealtimeBase; use ProjectCustom; use SideClient; From 1509aa544de051c61856fe4cc42d64fcc3ab2d3c Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:43:41 +0100 Subject: [PATCH 151/213] debug: output fail deployment --- tests/e2e/Services/Functions/FunctionsBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 8b19c65705..529846c623 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -44,7 +44,7 @@ trait FunctionsBase 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ])); - $this->assertEquals('ready', $deployment['body']['status']); + $this->assertEquals('ready', $deployment['body']['status'], 'Deployment status is not ready, deployment: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT)); }, 50000, 500); return $deploymentId; From 39490e981988ce24ead726a47e571ad9a6053c7f Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:06:58 +0100 Subject: [PATCH 152/213] chore: bump tests --- .github/workflows/tests.yml | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5b82cba594..4bc7b18d23 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,22 +16,22 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Build Appwrite - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v6 with: context: . push: false tags: ${{ env.IMAGE }} load: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=appwrite + cache-to: type=gha,mode=max,scope=appwrite outputs: type=docker,dest=/tmp/${{ env.IMAGE }}.tar build-args: | DEBUG=false @@ -39,9 +39,11 @@ jobs: VERSION=dev - name: Cache Docker Image - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ env.CACHE_KEY }} + restore-keys: | + appwrite-dev- path: /tmp/${{ env.IMAGE }}.tar unit_test: @@ -51,10 +53,10 @@ jobs: steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Load Cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ env.CACHE_KEY }} path: /tmp/${{ env.IMAGE }}.tar @@ -81,10 +83,10 @@ jobs: needs: setup steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Load Cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ env.CACHE_KEY }} path: /tmp/${{ env.IMAGE }}.tar @@ -129,10 +131,10 @@ jobs: steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Load Cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ env.CACHE_KEY }} path: /tmp/${{ env.IMAGE }}.tar @@ -142,7 +144,7 @@ jobs: run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose up -d - sleep 10 + sleep 25 - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug @@ -150,15 +152,15 @@ jobs: - name: Run ${{matrix.service}} Shared Tables Tests run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug - benchamrking: + benchmarking: name: Benchmark runs-on: ubuntu-latest needs: setup steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Load Cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ env.CACHE_KEY }} path: /tmp/${{ env.IMAGE }}.tar From 8e13aafbc854ff8cba1b1b62c2683af97ca42bc6 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:29:49 +0100 Subject: [PATCH 153/213] fixes --- .../Functions/FunctionsCustomServerTest.php | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index d95d611f13..66f77a1df8 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -454,30 +454,34 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt'])); $this->assertEquals('index.php', $deployment['body']['entrypoint']); - $deploymentId = $deployment['body']['$id'] ?? ''; + $deploymentIdActive = $deployment['body']['$id'] ?? ''; + + $this->assertEventually(function () use ($functionId, $deploymentIdActive) { + $deployment = $this->getDeployment($functionId, $deploymentIdActive); + + $this->assertEquals('ready', $deployment['body']['status']); + }, 50000, 500); $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), 'activate' => false ]); - $deploymentIdInactive = $deployment['body']['$id']; - $this->assertEquals(202, $deployment['headers']['status-code']); $this->assertNotEmpty($deployment['body']['$id']); - $this->assertEventually(function () use ($functionId, $deploymentId, $deploymentIdInactive) { - $deployment = $this->getDeployment($functionId, $deploymentId); - $this->assertEquals('ready', $deployment['body']['status']); + $deploymentIdInactive = $deployment['body']['$id'] ?? ''; + $this->assertEventually(function () use ($functionId, $deploymentIdInactive) { $deployment = $this->getDeployment($functionId, $deploymentIdInactive); + $this->assertEquals('ready', $deployment['body']['status']); - }, 500000, 1000); + }, 50000, 500); $function = $this->getFunction($functionId); $this->assertEquals(200, $function['headers']['status-code']); - $this->assertEquals($deploymentId, $function['body']['deployment']); + $this->assertEquals($deploymentIdActive, $function['body']['deployment']); $this->assertNotEquals($deploymentIdInactive, $function['body']['deployment']); $deployment = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId . '/deployments/' . $deploymentIdInactive, array_merge([ @@ -487,7 +491,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(204, $deployment['headers']['status-code']); - return array_merge($data, ['deploymentId' => $deploymentId]); + return array_merge($data, ['deploymentId' => $deploymentIdActive]); } /** @@ -1222,7 +1226,7 @@ class FunctionsCustomServerTest extends Scope 'timeout' => 5, // Should timeout after 5 seconds ]); $this->setupDeployment($functionId, [ - 'code' => $this->packageFunction('php'), + 'code' => $this->packageFunction('timeout'), 'activate' => true, ]); @@ -1562,7 +1566,7 @@ class FunctionsCustomServerTest extends Scope $functionId = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test PHP Scopes executions', - 'commands' => 'composer update --no-interaction --ignore-platform-reqs --optimize-autoloader --prefer-dist --no-dev', + 'commands' => 'sh setup.sh && composer install', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'scopes' => ['users.read'], @@ -1571,7 +1575,6 @@ class FunctionsCustomServerTest extends Scope $deploymentId = $this->setupDeployment($functionId, [ 'entrypoint' => 'index.php', - 'commands' => 'sh setup.sh && composer install', 'code' => $this->packageFunction('php-scopes'), 'activate' => true, ]); From 41490602f77b59677d64c9e6b67af1ee1b52d774 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:38:43 +0100 Subject: [PATCH 154/213] fix: template --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 1 - tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 66f77a1df8..7021030331 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -375,7 +375,6 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $deployment['headers']['status-code']); $this->assertEquals('ready', $deployment['body']['status']); - $this->assertEquals('cli', $deployment['body']['type']); }, 500000, 1000); $function = $this->getFunction($functionId); diff --git a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php index 7e36662e9e..bee15693f1 100644 --- a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php +++ b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php @@ -62,7 +62,7 @@ class FunctionsScheduleTest extends Scope $this->assertNotEmpty($asyncExecution['logs']); $this->assertNotEmpty($asyncExecution['errors']); $this->assertGreaterThan(0, $asyncExecution['duration']); - }, 10000, 500); + }, 15000, 500); $this->cleanupFunction($functionId); } From 2d102a122c4c1f8c60110770a6285bbe445e33ab Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:42:08 +0100 Subject: [PATCH 155/213] fix: tests --- .../Functions/FunctionsCustomServerTest.php | 47 +++++-------------- .../FunctionsScheduleTest.php | 2 +- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 7021030331..fec815c2ef 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -463,7 +463,7 @@ class FunctionsCustomServerTest extends Scope $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => false + 'activate' => 'false' ]); $this->assertEquals(202, $deployment['headers']['status-code']); @@ -502,7 +502,7 @@ class FunctionsCustomServerTest extends Scope $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => false + 'activate' => 'false' ]); $deploymentId = $deployment['body']['$id'] ?? ''; @@ -646,18 +646,6 @@ class FunctionsCustomServerTest extends Scope $this->assertArrayHasKey('size', $deployments['body']['deployments'][0]); $this->assertArrayHasKey('buildSize', $deployments['body']['deployments'][0]); - // Test search id - $deployments = $this->listDeployments($functionId, [ - 'search' => $data['functionId'] - ]); - - $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']); - - // Test pagination limit $deployments = $this->listDeployments($functionId, [ 'queries' => [ Query::limit(1)->toString(), @@ -694,16 +682,6 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($deployments['headers']['status-code'], 200); $this->assertCount(0, $deployments['body']['deployments']); - $deployments = $this->listDeployments($functionId, [ - 'search' => 'Test' - ]); - - $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']); - $deployments = $this->listDeployments($functionId, [ 'search' => 'php-8.0' ]); @@ -818,7 +796,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn ($deployment) => $deployment['$id'] === $deploymentId + fn($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); @@ -905,8 +883,6 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), []); - $execution = $this->createExecution($data['functionId']); - $this->assertEquals(204, $execution['headers']['status-code']); return array_merge($data, ['executionId' => $executionId]); @@ -922,11 +898,12 @@ class FunctionsCustomServerTest extends Scope */ $executions = $this->listExecutions($data['functionId']); - $this->assertEquals($executions['headers']['status-code'], 200); - $this->assertEquals($executions['body']['total'], 1); + fwrite(STDERR, print_r(json_encode($executions, JSON_PRETTY_PRINT), true)); + + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertEquals(1, $executions['body']['total']); $this->assertIsArray($executions['body']['executions']); $this->assertCount(1, $executions['body']['executions']); - $this->assertEquals($executions['body']['executions'][0]['$id'], $data['executionId']); $executions = $this->listExecutions($data['functionId'], [ 'queries' => [ @@ -939,12 +916,12 @@ class FunctionsCustomServerTest extends Scope $executions = $this->listExecutions($data['functionId'], [ 'queries' => [ - Query::offset(1)->toString(), + Query::offset(0)->toString(), ], ]); $this->assertEquals(200, $executions['headers']['status-code']); - $this->assertCount(0, $executions['body']['executions']); + $this->assertCount(1, $executions['body']['executions']); $executions = $this->listExecutions($data['functionId'], [ 'queries' => [ @@ -1217,7 +1194,7 @@ class FunctionsCustomServerTest extends Scope { $functionId = $this->setupFunction([ 'functionId' => ID::unique(), - 'name' => 'timeout-php-8.0', + 'name' => 'Test php-8.0', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'events' => [], @@ -1612,8 +1589,8 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); $this->assertGreaterThan(0, $execution['body']['duration']); - $this->assertNotEmpty($execution['body']['responseBody']); - $this->assertStringContainsString("total", $execution['body']['responseBody']); + $this->assertNotEmpty($execution['body']['logs']); + $this->assertStringContainsString("total", $execution['body']['logs']); }, 10000, 500); $this->cleanupFunction($functionId); diff --git a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php index bee15693f1..cbe54b6445 100644 --- a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php +++ b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php @@ -62,7 +62,7 @@ class FunctionsScheduleTest extends Scope $this->assertNotEmpty($asyncExecution['logs']); $this->assertNotEmpty($asyncExecution['errors']); $this->assertGreaterThan(0, $asyncExecution['duration']); - }, 15000, 500); + }, 60000, 500); $this->cleanupFunction($functionId); } From cefc7a1d4baf4ac670125d8ff491617092b6687d Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:44:34 +0100 Subject: [PATCH 156/213] chore: fmt --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index fec815c2ef..050c0681c5 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -796,7 +796,7 @@ class FunctionsCustomServerTest extends Scope $matchingDeployment = array_filter( $deployments['body']['deployments'], - fn($deployment) => $deployment['$id'] === $deploymentId + fn ($deployment) => $deployment['$id'] === $deploymentId ); $this->assertNotEmpty($matchingDeployment, "Deployment with ID {$deploymentId} not found"); From 42ae429153156a6b20d7fd92cfbef699e02631ef Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:49:29 +0100 Subject: [PATCH 157/213] chore: remove test --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 050c0681c5..a0395a08b0 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -898,8 +898,6 @@ class FunctionsCustomServerTest extends Scope */ $executions = $this->listExecutions($data['functionId']); - fwrite(STDERR, print_r(json_encode($executions, JSON_PRETTY_PRINT), true)); - $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals(1, $executions['body']['total']); $this->assertIsArray($executions['body']['executions']); From df9e80a9629c638a276f96717096e406b71f98c2 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:02:23 +0100 Subject: [PATCH 158/213] feat: handle bools --- tests/e2e/Client.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e/Client.php b/tests/e2e/Client.php index 0774f1c6fd..0595611570 100644 --- a/tests/e2e/Client.php +++ b/tests/e2e/Client.php @@ -303,6 +303,8 @@ class Client if (is_array($value)) { $output += $this->flatten($value, $finalKey); // @todo: handle name collision here if needed + } elseif (is_bool($value)) { + $output[$finalKey] = $value ? 'true' : 'false'; } else { $output[$finalKey] = $value; } From f0485ca87010df935785a3c4a8c29c47ca3d034e Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:30:26 +0100 Subject: [PATCH 159/213] fix: use boolean false --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index a0395a08b0..9166a7c4e8 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -463,7 +463,7 @@ class FunctionsCustomServerTest extends Scope $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => 'false' + 'activate' => false ]); $this->assertEquals(202, $deployment['headers']['status-code']); @@ -502,7 +502,7 @@ class FunctionsCustomServerTest extends Scope $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => 'false' + 'activate' => false ]); $deploymentId = $deployment['body']['$id'] ?? ''; From 0eb0054f3818ea09e6ee71f9641f12dc26410393 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 22 Sep 2024 10:50:13 +0300 Subject: [PATCH 160/213] Add info resourceType --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index dc76f668e6..15ef0f4987 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -158,10 +158,10 @@ abstract class ScheduleBase extends Action $new = \strtotime($document['resourceUpdatedAt']); if (!$document['active']) { - Console::info("Removing: {$document['resourceId']}"); + Console::info("Removing: {$document['resourceType']}-{$document['resourceId']}"); unset($this->schedules[$document->getInternalId()]); } elseif ($new !== $org) { - Console::info("Updating: {$document['resourceId']}"); + Console::info("Updating: {$document['resourceType']}-{$document['resourceId']}"); $this->schedules[$document->getInternalId()] = $getSchedule($document); } } From 8213b37cf428b6de15a9f90ca87e746984311856 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 22 Sep 2024 13:29:42 +0300 Subject: [PATCH 161/213] Add info resourceType --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 15ef0f4987..6e3459667f 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -158,10 +158,10 @@ abstract class ScheduleBase extends Action $new = \strtotime($document['resourceUpdatedAt']); if (!$document['active']) { - Console::info("Removing: {$document['resourceType']}-{$document['resourceId']}"); + Console::info("Removing: {$document['resourceType']}:{$document['resourceId']}"); unset($this->schedules[$document->getInternalId()]); } elseif ($new !== $org) { - Console::info("Updating: {$document['resourceType']}-{$document['resourceId']}"); + Console::info("Updating: {$document['resourceType']}:{$document['resourceId']}"); $this->schedules[$document->getInternalId()] = $getSchedule($document); } } From 6f5b144e70f919b61e0008771e0cefd5ff1c6749 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 22 Sep 2024 14:15:01 +0300 Subject: [PATCH 162/213] Add info resourceType --- src/Appwrite/Platform/Tasks/ScheduleBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 6e3459667f..a1b85c341f 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -158,10 +158,10 @@ abstract class ScheduleBase extends Action $new = \strtotime($document['resourceUpdatedAt']); if (!$document['active']) { - Console::info("Removing: {$document['resourceType']}:{$document['resourceId']}"); + Console::info("Removing: {$document['resourceType']}::{$document['resourceId']}"); unset($this->schedules[$document->getInternalId()]); } elseif ($new !== $org) { - Console::info("Updating: {$document['resourceType']}:{$document['resourceId']}"); + Console::info("Updating: {$document['resourceType']}::{$document['resourceId']}"); $this->schedules[$document->getInternalId()] = $getSchedule($document); } } From f6e3759f6b05cb87a446c982e94ce91518ed663a Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Sun, 22 Sep 2024 20:14:58 +0100 Subject: [PATCH 163/213] chore: add async --- tests/e2e/Services/Functions/FunctionsBase.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index badab22147..15acce8ba2 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -2,12 +2,15 @@ namespace Tests\E2E\Services\Functions; +use Appwrite\Tests\Async; use CURLFile; use Tests\E2E\Client; use Utopia\CLI\Console; trait FunctionsBase { + use Async; + protected string $stdout = ''; protected string $stderr = ''; From a95cd51be059023f239c6b575abd365f445e9f9b Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 23 Sep 2024 11:20:38 +0300 Subject: [PATCH 164/213] destination false --- app/config/collections.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/collections.php b/app/config/collections.php index f6f5d7b7ef..79a1b659c5 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4122,7 +4122,7 @@ $projectCollections = array_merge([ 'format' => '', 'size' => 500, 'signed' => true, - 'required' => true, + 'required' => false, // make true after patch script 'default' => null, 'array' => false, 'filters' => [], From 831472fc64260b03c827b7f7a5d2f1f66a5668c6 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 12:48:18 +0300 Subject: [PATCH 165/213] destination size --- app/config/collections.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 79a1b659c5..1eb286cf8f 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4109,7 +4109,7 @@ $projectCollections = array_merge([ '$id' => ID::custom('source'), 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 8192, + 'size' => 8192, // reduce size 'signed' => true, 'required' => true, 'default' => null, @@ -4120,7 +4120,7 @@ $projectCollections = array_merge([ '$id' => ID::custom('destination'), 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 500, + 'size' => Database::LENGTH_KEY, 'signed' => true, 'required' => false, // make true after patch script 'default' => null, From 77aad0bfce0026275e8759620b882586cde922aa Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 12:58:09 +0300 Subject: [PATCH 166/213] Bumb migration tag --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5bff5a62fa..7d261fbab7 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,7 @@ "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.6.*", "utopia-php/messaging": "0.12.*", - "utopia-php/migration": "dev-preserveDates as 0.6.0", + "utopia-php/migration": "0.6.*", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", From ab908aa9cb65c758d3218a2f11e18c8f2c1652c8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 18:20:00 +0300 Subject: [PATCH 167/213] Add const --- app/config/platforms.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/config/platforms.php b/app/config/platforms.php index e7eb1180cd..40cea19fd3 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -1,5 +1,9 @@ [ 'key' => APP_PLATFORM_CLIENT, From 3121cd1c07fe28b0ac35bda55f97d374cec59671 Mon Sep 17 00:00:00 2001 From: Shmuel Fogel Date: Tue, 24 Sep 2024 18:52:38 +0300 Subject: [PATCH 168/213] Update src/Appwrite/Platform/Workers/Migrations.php Co-authored-by: Christy Jacob --- src/Appwrite/Platform/Workers/Migrations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index c4c2516424..1fbbd6d16c 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -396,7 +396,7 @@ class Migrations extends Action $this->updateMigrationDocument($migration, $projectDocument); - if ($migration->getAttribute('status', '') == 'failed') { + if ($migration->getAttribute('status', '') === 'failed') { $destination->error(); $source->error(); From 75d681e6e208346e88737b3febabc10b6c2e3825 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 19:01:01 +0300 Subject: [PATCH 169/213] Remove Breadcrumb --- src/Appwrite/Platform/Workers/Migrations.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 1fbbd6d16c..08757d3e2a 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -287,7 +287,6 @@ class Migrations extends Action $migration->setAttribute('stage', 'processing'); $migration->setAttribute('status', 'processing'); - $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'processing'", \microtime(true))); $this->updateMigrationDocument($migration, $projectDocument); $log->addTag('type', $migration->getAttribute('source')); @@ -304,7 +303,6 @@ class Migrations extends Action /** Start Transfer */ $migration->setAttribute('stage', 'migrating'); - $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'migrating'", \microtime(true))); $this->updateMigrationDocument($migration, $projectDocument); $transfer->run( @@ -327,7 +325,6 @@ class Migrations extends Action if (! empty($sourceErrors) || ! empty($destinationErrors)) { $migration->setAttribute('status', 'failed'); $migration->setAttribute('stage', 'finished'); - $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'finished' and failed", \microtime(true))); $errorMessages = []; foreach ($sourceErrors as $error) { @@ -359,7 +356,6 @@ class Migrations extends Action $migration->setAttribute('status', 'completed'); $migration->setAttribute('stage', 'finished'); - $log->addBreadcrumb(new Breadcrumb('debug', 'migration', "Migration hit stage 'finished' and succeeded", \microtime(true))); } catch (\Throwable $th) { Console::error($th->getMessage()); Console::error($th->getTraceAsString()); From 3ff6ccbda1482f8a46e373a5cb9a19341c757c2c Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 19:18:05 +0300 Subject: [PATCH 170/213] Remove and add in init.php --- app/config/platforms.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/config/platforms.php b/app/config/platforms.php index 40cea19fd3..e7eb1180cd 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -1,9 +1,5 @@ [ 'key' => APP_PLATFORM_CLIENT, From bd8335109217fea7c9150c1816a49d5384ce61a3 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 19:18:40 +0300 Subject: [PATCH 171/213] lock.file --- composer.lock | 109 +++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 59 deletions(-) diff --git a/composer.lock b/composer.lock index d2a5d88fb9..4cd5853fd0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "67946bb84bca00b694c8a41fbe41f359", + "content-hash": "3a25a9050c489b1a2cb4e320af1586d5", "packages": [ { "name": "adhocore/jwt", @@ -2070,16 +2070,16 @@ }, { "name": "utopia-php/logger", - "version": "0.6.0", + "version": "0.6.1", "source": { "type": "git", "url": "https://github.com/utopia-php/logger.git", - "reference": "a2d1daeeb8f61fdec6d851950d9a021a3d05c9f9" + "reference": "7e8ff512c6f04577aba1df67c7b9628971946f9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/a2d1daeeb8f61fdec6d851950d9a021a3d05c9f9", - "reference": "a2d1daeeb8f61fdec6d851950d9a021a3d05c9f9", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/7e8ff512c6f04577aba1df67c7b9628971946f9c", + "reference": "7e8ff512c6f04577aba1df67c7b9628971946f9c", "shasum": "" }, "require": { @@ -2118,9 +2118,9 @@ ], "support": { "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.6.0" + "source": "https://github.com/utopia-php/logger/tree/0.6.1" }, - "time": "2024-05-23T13:37:54+00:00" + "time": "2024-09-20T14:02:12+00:00" }, { "name": "utopia-php/messaging", @@ -2175,16 +2175,16 @@ }, { "name": "utopia-php/migration", - "version": "dev-preserveDates", + "version": "0.6.1", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "c5ac9347448e34832ff0bd1f9d3d90c54cd6e2fe" + "reference": "6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/c5ac9347448e34832ff0bd1f9d3d90c54cd6e2fe", - "reference": "c5ac9347448e34832ff0bd1f9d3d90c54cd6e2fe", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0", + "reference": "6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0", "shasum": "" }, "require": { @@ -2225,9 +2225,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/preserveDates" + "source": "https://github.com/utopia-php/migration/tree/0.6.1" }, - "time": "2024-09-19T15:32:44+00:00" + "time": "2024-09-24T09:54:09+00:00" }, { "name": "utopia-php/mongo", @@ -3323,16 +3323,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.3", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482" + "reference": "eb2bcbd85034c1a508cf409b7ee318eb3137f090" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/9d77be916e145864f10788bb94531d03e1f7b482", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482", + "url": "https://api.github.com/repos/laravel/pint/zipball/eb2bcbd85034c1a508cf409b7ee318eb3137f090", + "reference": "eb2bcbd85034c1a508cf409b7ee318eb3137f090", "shasum": "" }, "require": { @@ -3385,7 +3385,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-09-03T15:00:28+00:00" + "time": "2024-09-24T15:48:42+00:00" }, { "name": "matthiasmullie/minify", @@ -4194,16 +4194,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.30.1", + "version": "1.31.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e" + "reference": "249f15fb843bf240cf058372dad29e100cee6c17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/51b95ec8670af41009e2b2b56873bad96682413e", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/249f15fb843bf240cf058372dad29e100cee6c17", + "reference": "249f15fb843bf240cf058372dad29e100cee6c17", "shasum": "" }, "require": { @@ -4235,9 +4235,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.31.0" }, - "time": "2024-09-07T20:13:05+00:00" + "time": "2024-09-22T11:32:18+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5874,16 +5874,16 @@ }, { "name": "symfony/console", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111" + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111", - "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", "shasum": "" }, "require": { @@ -5947,7 +5947,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.4" + "source": "https://github.com/symfony/console/tree/v7.1.5" }, "funding": [ { @@ -5963,7 +5963,7 @@ "type": "tidelift" } ], - "time": "2024-08-15T22:48:53+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6034,16 +6034,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.1.2", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "92a91985250c251de9b947a14bb2c9390b1a562c" + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/92a91985250c251de9b947a14bb2c9390b1a562c", - "reference": "92a91985250c251de9b947a14bb2c9390b1a562c", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", "shasum": "" }, "require": { @@ -6080,7 +6080,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.2" + "source": "https://github.com/symfony/filesystem/tree/v7.1.5" }, "funding": [ { @@ -6096,7 +6096,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T10:03:55+00:00" + "time": "2024-09-17T09:16:35+00:00" }, { "name": "symfony/finder", @@ -6545,16 +6545,16 @@ }, { "name": "symfony/process", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca" + "reference": "5c03ee6369281177f07f7c68252a280beccba847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", "shasum": "" }, "require": { @@ -6586,7 +6586,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.3" + "source": "https://github.com/symfony/process/tree/v7.1.5" }, "funding": [ { @@ -6602,7 +6602,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:44:47+00:00" + "time": "2024-09-19T21:48:23+00:00" }, { "name": "symfony/service-contracts", @@ -6689,16 +6689,16 @@ }, { "name": "symfony/string", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b" + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b", - "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", "shasum": "" }, "require": { @@ -6756,7 +6756,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.4" + "source": "https://github.com/symfony/string/tree/v7.1.5" }, "funding": [ { @@ -6772,7 +6772,7 @@ "type": "tidelift" } ], - "time": "2024-08-12T09:59:40+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "textalk/websocket", @@ -7002,18 +7002,9 @@ "time": "2024-03-07T20:33:40+00:00" } ], - "aliases": [ - { - "package": "utopia-php/migration", - "version": "dev-preserveDates", - "alias": "0.6.0", - "alias_normalized": "0.6.0.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/migration": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From a2c1ce4e8f2516903a0d20dcc8bb331dd4961c58 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 19:39:39 +0300 Subject: [PATCH 172/213] specs --- .../specs/open-api3-latest-console.json | 140 +++++++++++++++++- app/config/specs/open-api3-latest-server.json | 140 +++++++++++++++++- app/config/specs/swagger2-latest-console.json | 140 +++++++++++++++++- app/config/specs/swagger2-latest-server.json | 140 +++++++++++++++++- 4 files changed, 544 insertions(+), 16 deletions(-) diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 07749889d8..86a6ee7e53 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -32946,6 +32946,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -32965,6 +32975,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -33003,6 +33015,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -33030,7 +33052,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -33068,6 +33092,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -33095,7 +33129,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -33133,6 +33169,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -33145,7 +33191,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -33183,6 +33231,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33201,6 +33259,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33239,6 +33299,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -33265,6 +33335,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -33304,6 +33376,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33322,6 +33404,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33360,6 +33444,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33378,6 +33472,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33416,6 +33512,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -33434,6 +33540,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33472,6 +33580,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -33509,6 +33627,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -33557,6 +33677,16 @@ }, "x-example": [], "nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -33564,7 +33694,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index ef41688ca8..84c6fe1454 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -23677,6 +23677,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -23696,6 +23706,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -23734,6 +23746,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -23761,7 +23783,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -23799,6 +23823,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -23826,7 +23860,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -23864,6 +23900,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -23876,7 +23922,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -23914,6 +23962,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -23932,6 +23990,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -23970,6 +24030,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -23996,6 +24066,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -24035,6 +24107,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24053,6 +24135,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24091,6 +24175,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24109,6 +24203,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24147,6 +24243,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -24165,6 +24271,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24203,6 +24311,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -24240,6 +24358,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -24288,6 +24408,16 @@ }, "x-example": [], "nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -24295,7 +24425,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 51935a5e01..49d60e980b 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -33456,6 +33456,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -33475,6 +33485,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -33513,6 +33525,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -33540,7 +33562,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -33578,6 +33602,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -33605,7 +33639,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -33643,6 +33679,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -33655,7 +33701,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -33693,6 +33741,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33711,6 +33769,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33749,6 +33809,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -33775,6 +33845,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -33814,6 +33886,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33832,6 +33914,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33870,6 +33954,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33888,6 +33982,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33926,6 +34022,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -33944,6 +34050,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33982,6 +34090,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -34019,6 +34137,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -34067,6 +34187,16 @@ }, "x-example": [], "x-nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -34074,7 +34204,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index af6274226f..bc22585860 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -24166,6 +24166,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -24185,6 +24195,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -24223,6 +24235,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -24250,7 +24272,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -24288,6 +24312,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -24315,7 +24349,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -24353,6 +24389,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -24365,7 +24411,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -24403,6 +24451,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24421,6 +24479,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24459,6 +24519,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -24485,6 +24555,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -24524,6 +24596,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24542,6 +24624,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24580,6 +24664,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24598,6 +24692,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24636,6 +24732,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -24654,6 +24760,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24692,6 +24800,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -24729,6 +24847,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -24777,6 +24897,16 @@ }, "x-example": [], "x-nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -24784,7 +24914,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { From d532c874d52333402fca9f4ae99332ea61827297 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 19:43:05 +0300 Subject: [PATCH 173/213] specs 1.6.x --- app/config/specs/open-api3-1.6.x-console.json | 140 +++++++++++++++++- app/config/specs/open-api3-1.6.x-server.json | 140 +++++++++++++++++- app/config/specs/swagger2-1.6.x-console.json | 140 +++++++++++++++++- app/config/specs/swagger2-1.6.x-server.json | 140 +++++++++++++++++- 4 files changed, 544 insertions(+), 16 deletions(-) diff --git a/app/config/specs/open-api3-1.6.x-console.json b/app/config/specs/open-api3-1.6.x-console.json index 07749889d8..86a6ee7e53 100644 --- a/app/config/specs/open-api3-1.6.x-console.json +++ b/app/config/specs/open-api3-1.6.x-console.json @@ -32946,6 +32946,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -32965,6 +32975,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -33003,6 +33015,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -33030,7 +33052,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -33068,6 +33092,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -33095,7 +33129,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -33133,6 +33169,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -33145,7 +33191,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -33183,6 +33231,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33201,6 +33259,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33239,6 +33299,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -33265,6 +33335,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -33304,6 +33376,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33322,6 +33404,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33360,6 +33444,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33378,6 +33472,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33416,6 +33512,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -33434,6 +33540,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33472,6 +33580,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -33509,6 +33627,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -33557,6 +33677,16 @@ }, "x-example": [], "nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -33564,7 +33694,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { diff --git a/app/config/specs/open-api3-1.6.x-server.json b/app/config/specs/open-api3-1.6.x-server.json index ef41688ca8..84c6fe1454 100644 --- a/app/config/specs/open-api3-1.6.x-server.json +++ b/app/config/specs/open-api3-1.6.x-server.json @@ -23677,6 +23677,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -23696,6 +23706,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -23734,6 +23746,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -23761,7 +23783,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -23799,6 +23823,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -23826,7 +23860,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -23864,6 +23900,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -23876,7 +23922,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -23914,6 +23962,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -23932,6 +23990,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -23970,6 +24030,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -23996,6 +24066,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -24035,6 +24107,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24053,6 +24135,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24091,6 +24175,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24109,6 +24203,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24147,6 +24243,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -24165,6 +24271,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24203,6 +24311,16 @@ "x-example": false, "nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -24240,6 +24358,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -24288,6 +24408,16 @@ }, "x-example": [], "nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -24295,7 +24425,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { diff --git a/app/config/specs/swagger2-1.6.x-console.json b/app/config/specs/swagger2-1.6.x-console.json index 51935a5e01..49d60e980b 100644 --- a/app/config/specs/swagger2-1.6.x-console.json +++ b/app/config/specs/swagger2-1.6.x-console.json @@ -33456,6 +33456,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -33475,6 +33485,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -33513,6 +33525,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -33540,7 +33562,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -33578,6 +33602,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -33605,7 +33639,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -33643,6 +33679,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -33655,7 +33701,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -33693,6 +33741,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33711,6 +33769,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33749,6 +33809,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -33775,6 +33845,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -33814,6 +33886,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33832,6 +33914,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33870,6 +33954,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -33888,6 +33982,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33926,6 +34022,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -33944,6 +34050,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -33982,6 +34090,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -34019,6 +34137,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -34067,6 +34187,16 @@ }, "x-example": [], "x-nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -34074,7 +34204,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { diff --git a/app/config/specs/swagger2-1.6.x-server.json b/app/config/specs/swagger2-1.6.x-server.json index af6274226f..bc22585860 100644 --- a/app/config/specs/swagger2-1.6.x-server.json +++ b/app/config/specs/swagger2-1.6.x-server.json @@ -24166,6 +24166,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "size": { "type": "integer", "description": "Attribute size.", @@ -24185,6 +24195,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "size" ] }, @@ -24223,6 +24235,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "integer", "description": "Minimum value to enforce for new documents.", @@ -24250,7 +24272,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeFloat": { @@ -24288,6 +24312,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "min": { "type": "number", "description": "Minimum value to enforce for new documents.", @@ -24315,7 +24349,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeBoolean": { @@ -24353,6 +24389,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "default": { "type": "boolean", "description": "Default value for attribute when not provided. Cannot be set when attribute is required.", @@ -24365,7 +24411,9 @@ "type", "status", "error", - "required" + "required", + "$createdAt", + "$updatedAt" ] }, "attributeEmail": { @@ -24403,6 +24451,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24421,6 +24479,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24459,6 +24519,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "elements": { "type": "array", "description": "Array of elements in enumerated type.", @@ -24485,6 +24555,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "elements", "format" ] @@ -24524,6 +24596,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24542,6 +24624,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24580,6 +24664,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "String format.", @@ -24598,6 +24692,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24636,6 +24732,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "format": { "type": "string", "description": "ISO 8601 format.", @@ -24654,6 +24760,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "format" ] }, @@ -24692,6 +24800,16 @@ "x-example": false, "x-nullable": true }, + "$createdAt": { + "type": "string", + "description": "Attribute creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Attribute update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "relatedCollection": { "type": "string", "description": "The ID of the related collection.", @@ -24729,6 +24847,8 @@ "status", "error", "required", + "$createdAt", + "$updatedAt", "relatedCollection", "relationType", "twoWay", @@ -24777,6 +24897,16 @@ }, "x-example": [], "x-nullable": true + }, + "$createdAt": { + "type": "string", + "description": "Index creation date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Index update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" } }, "required": [ @@ -24784,7 +24914,9 @@ "type", "status", "error", - "attributes" + "attributes", + "$createdAt", + "$updatedAt" ] }, "document": { From 12d119069e35d299619ebf65e5a4c32556747587 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 22:02:18 +0300 Subject: [PATCH 174/213] equal --- src/Appwrite/Platform/Workers/Migrations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 08757d3e2a..9e58310733 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -392,7 +392,7 @@ class Migrations extends Action $this->updateMigrationDocument($migration, $projectDocument); - if ($migration->getAttribute('status', '') === 'failed') { + if ($migration->getAttribute('status', '') == 'failed') { $destination->error(); $source->error(); From a42a669d6e0e7e1c480edff143edf56083d79a54 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 24 Sep 2024 22:02:38 +0300 Subject: [PATCH 175/213] equal equal --- src/Appwrite/Platform/Workers/Migrations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 9e58310733..08757d3e2a 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -392,7 +392,7 @@ class Migrations extends Action $this->updateMigrationDocument($migration, $projectDocument); - if ($migration->getAttribute('status', '') == 'failed') { + if ($migration->getAttribute('status', '') === 'failed') { $destination->error(); $source->error(); From 0753163066d24591688bee6f095acf12703c4d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 25 Sep 2024 13:32:09 +0200 Subject: [PATCH 176/213] PR review changes --- tests/e2e/Client.php | 2 -- tests/e2e/Services/Functions/FunctionsBase.php | 11 ++++------- tests/e2e/Services/GraphQL/Base.php | 6 ++---- tests/extensions/Async/Eventually.php | 7 +------ 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/tests/e2e/Client.php b/tests/e2e/Client.php index 0595611570..0774f1c6fd 100644 --- a/tests/e2e/Client.php +++ b/tests/e2e/Client.php @@ -303,8 +303,6 @@ class Client if (is_array($value)) { $output += $this->flatten($value, $finalKey); // @todo: handle name collision here if needed - } elseif (is_bool($value)) { - $output[$finalKey] = $value ? 'true' : 'false'; } else { $output[$finalKey] = $value; } diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index 15acce8ba2..a1bb8f2b21 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -142,14 +142,12 @@ trait FunctionsBase return $executions; } - protected function packageFunction(string $function = 'php'): CURLFile + protected function packageFunction(string $function): CURLFile { $folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function"; $tarPath = "$folderPath/code.tar.gz"; - if (!file_exists($tarPath)) { - Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); - } + Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); if (filesize($tarPath) > 1024 * 1024 * 5) { throw new \Exception('Code package is too large. Use the chunked upload method instead.'); @@ -200,11 +198,10 @@ trait FunctionsBase protected function deleteFunction(string $functionId): mixed { - $function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ + $function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]); + ], $this->getHeaders())); return $function; } diff --git a/tests/e2e/Services/GraphQL/Base.php b/tests/e2e/Services/GraphQL/Base.php index 01f9508a81..0b3250cecf 100644 --- a/tests/e2e/Services/GraphQL/Base.php +++ b/tests/e2e/Services/GraphQL/Base.php @@ -2497,14 +2497,12 @@ trait Base protected string $stdout = ''; protected string $stderr = ''; - protected function packageFunction(string $function = 'php'): CURLFile + protected function packageFunction(string $function): CURLFile { $folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function"; $tarPath = "$folderPath/code.tar.gz"; - if (!file_exists($tarPath)) { - Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); - } + Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); if (filesize($tarPath) > 1024 * 1024 * 5) { throw new \Exception('Code package is too large. Use the chunked upload method instead.'); diff --git a/tests/extensions/Async/Eventually.php b/tests/extensions/Async/Eventually.php index e4987de410..9840b1a114 100644 --- a/tests/extensions/Async/Eventually.php +++ b/tests/extensions/Async/Eventually.php @@ -6,13 +6,8 @@ use PHPUnit\Framework\Constraint\Constraint; final class Eventually extends Constraint { - private int $timeoutMs; - private int $waitMs; - - public function __construct(int $timeoutMs, int $waitMs) + public function __construct(private int $timeoutMs, private int $waitMs) { - $this->timeoutMs = $timeoutMs; - $this->waitMs = $waitMs; } public function evaluate(mixed $probe, string $description = '', bool $returnResult = false): ?bool From 5f97aafe4604e535cf437115d82f9db000acbdf8 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:38:30 +0530 Subject: [PATCH 177/213] More asserts --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 4dabec67f0..f101524aaf 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -2669,8 +2669,9 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(204, $response['headers']['status-code']); } - public function testCreateFunctionWithResponseFormatHeader() + public function testResponseFilters() { + // create function with 1.5.0 response format $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -2684,8 +2685,10 @@ class FunctionsCustomServerTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); + $this->assertArrayNotHasKey('scopes', $response['body']); + $this->assertArrayNotHasKey('specification', $response['body']); - // get function with 1.5.0 response format + // get function with 1.5.0 response format header $function = $this->client->call(Client::METHOD_GET, '/functions/' . $response['body']['$id'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], From 71ffe2bf5234d595b18d60464e8bdbb032f33d16 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 25 Sep 2024 16:39:31 +0300 Subject: [PATCH 178/213] Deletes schedules --- src/Appwrite/Platform/Workers/Deletes.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 7b7f5e1fa6..c69b8a1bbd 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -557,6 +557,11 @@ class Deletes extends Action Query::equal('projectInternalId', [$projectInternalId]), ], $dbForConsole); + // Delete Schedules + $this->deleteByGroup('schedules', [ + Query::equal('projectInternalId', [$projectInternalId]), + ], $dbForConsole); + // Delete metadata table if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $dbForProject->deleteCollection('_metadata'); From a9469e87344f7b30f4b0f6281dadbf2d94b26586 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 25 Sep 2024 16:49:49 +0300 Subject: [PATCH 179/213] projectId schedules --- src/Appwrite/Platform/Workers/Deletes.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index c69b8a1bbd..8b835c53f3 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -480,6 +480,7 @@ class Deletes extends Action private function deleteProject(Database $dbForConsole, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, Document $document): void { $projectInternalId = $document->getInternalId(); + $projectId = $document->getId(); try { $dsn = new DSN($document->getAttribute('database', 'console')); @@ -557,9 +558,9 @@ class Deletes extends Action Query::equal('projectInternalId', [$projectInternalId]), ], $dbForConsole); - // Delete Schedules + // Delete Schedules (No projectInternalId in this collection) $this->deleteByGroup('schedules', [ - Query::equal('projectInternalId', [$projectInternalId]), + Query::equal('projectId', [$projectId]), ], $dbForConsole); // Delete metadata table From 7116405793d6a9795ae7a44f2ba90772e3c0d4c1 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 25 Sep 2024 18:16:57 +0300 Subject: [PATCH 180/213] Dbg $projectCollectionIds --- src/Appwrite/Platform/Workers/Deletes.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 8b835c53f3..022c217682 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -496,7 +496,7 @@ class Deletes extends Action Audit::COLLECTION, TimeLimit::COLLECTION, ]; - +var_dump($projectCollectionIds); $limit = \count($projectCollectionIds) + 25; while (true) { @@ -559,6 +559,7 @@ class Deletes extends Action ], $dbForConsole); // Delete Schedules (No projectInternalId in this collection) + var_dump("deleting schedules projectId = " . $projectId); $this->deleteByGroup('schedules', [ Query::equal('projectId', [$projectId]), ], $dbForConsole); From 868c4162023cfaea1faddebb4ebb4b0e88af7348 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 25 Sep 2024 18:19:41 +0300 Subject: [PATCH 181/213] Dbg $projectCollectionIds --- src/Appwrite/Platform/Workers/Deletes.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 022c217682..a2abd91814 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -496,13 +496,16 @@ class Deletes extends Action Audit::COLLECTION, TimeLimit::COLLECTION, ]; -var_dump($projectCollectionIds); + $limit = \count($projectCollectionIds) + 25; while (true) { $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { + + var_dump($collection->getId()); + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); } else { From 3228ccb4f9088b9b3ba33aa08e0f472d54a4376b Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 25 Sep 2024 18:21:47 +0300 Subject: [PATCH 182/213] Dbg $projectCollectionIds --- src/Appwrite/Platform/Workers/Deletes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index a2abd91814..af99c7e37d 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -496,7 +496,7 @@ class Deletes extends Action Audit::COLLECTION, TimeLimit::COLLECTION, ]; - + var_dump($projectCollectionIds); $limit = \count($projectCollectionIds) + 25; while (true) { From 0ace58f00bdc60ceaf36065cdbfb05ec012123d0 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 25 Sep 2024 19:04:47 +0300 Subject: [PATCH 183/213] Dbg $projectCollectionIds --- src/Appwrite/Platform/Workers/Deletes.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index af99c7e37d..de90f4a5f3 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -507,7 +507,13 @@ class Deletes extends Action var_dump($collection->getId()); if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { + var_dump('start ' . $collection->getId()); + $dbForProject->deleteCollection($collection->getId()); + + var_dump('finish ' . $collection->getId()); + var_dump(''); + } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } From 1cf26b1f4600b0aa4c0f7dad7f5d053c63a216cc Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 25 Sep 2024 19:08:24 +0300 Subject: [PATCH 184/213] Dbg $projectCollectionIds --- src/Appwrite/Platform/Workers/Deletes.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index de90f4a5f3..7400a43b93 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -503,9 +503,6 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { - - var_dump($collection->getId()); - if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { var_dump('start ' . $collection->getId()); @@ -515,6 +512,8 @@ class Deletes extends Action var_dump(''); } else { + + var_dump('deleteByGroup' . $collection->getId()); $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } } From fdf73f8a7ae7129f5a82a235bcf18f5e337d9e23 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Wed, 25 Sep 2024 23:36:00 +0530 Subject: [PATCH 185/213] Add test for request filters --- .../Functions/FunctionsCustomServerTest.php | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index f101524aaf..d4adc1119f 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -2719,6 +2719,55 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(204, $response['headers']['status-code']); } + public function testRequestFilters() + { + // create function + $response = $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', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'timeout' => 15, + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // create another function + $response = $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' => 'Test2', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'timeout' => 15, + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // 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()), + [ + 'queries' => [ 'equal("name", ["Test2"])' ] + ] + ); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertCount(1, $response['body']['functions']); + $this->assertEquals('Test2', $response['body']['functions'][0]['name']); + } + public function testFunctionLogging() { // Preparations: Create Function From 17d0053f37b917b23e5df63cedc3cd668ae4fe61 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 09:45:00 +0300 Subject: [PATCH 186/213] use Authorization skip --- src/Appwrite/Platform/Workers/Deletes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 7400a43b93..58f326cae3 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -506,7 +506,7 @@ class Deletes extends Action if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { var_dump('start ' . $collection->getId()); - $dbForProject->deleteCollection($collection->getId()); + \Utopia\Database\Validator\Authorization::skip(fn () => $dbForProject->deleteCollection($collection->getId())); var_dump('finish ' . $collection->getId()); var_dump(''); From 5c7e4393a7c4cbd9d00e0e43c3ae2d0a8e10cd42 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 09:54:26 +0300 Subject: [PATCH 187/213] revert --- src/Appwrite/Platform/Workers/Deletes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 58f326cae3..7400a43b93 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -506,7 +506,7 @@ class Deletes extends Action if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { var_dump('start ' . $collection->getId()); - \Utopia\Database\Validator\Authorization::skip(fn () => $dbForProject->deleteCollection($collection->getId())); + $dbForProject->deleteCollection($collection->getId()); var_dump('finish ' . $collection->getId()); var_dump(''); From 226c3c0372faf129799758c39c5d80371ce13cc9 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 10:38:36 +0300 Subject: [PATCH 188/213] Remove var_dumps --- src/Appwrite/Platform/Workers/Deletes.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 7400a43b93..8b835c53f3 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -496,7 +496,7 @@ class Deletes extends Action Audit::COLLECTION, TimeLimit::COLLECTION, ]; - var_dump($projectCollectionIds); + $limit = \count($projectCollectionIds) + 25; while (true) { @@ -504,16 +504,8 @@ class Deletes extends Action foreach ($collections as $collection) { if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { - var_dump('start ' . $collection->getId()); - $dbForProject->deleteCollection($collection->getId()); - - var_dump('finish ' . $collection->getId()); - var_dump(''); - } else { - - var_dump('deleteByGroup' . $collection->getId()); $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } } @@ -567,7 +559,6 @@ class Deletes extends Action ], $dbForConsole); // Delete Schedules (No projectInternalId in this collection) - var_dump("deleting schedules projectId = " . $projectId); $this->deleteByGroup('schedules', [ Query::equal('projectId', [$projectId]), ], $dbForConsole); From 672c8b2730dc00e9e6a2e04fdfd0beedcf64e013 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 10:52:53 +0300 Subject: [PATCH 189/213] lock file --- composer.lock | 71 +++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/composer.lock b/composer.lock index b3a94545b4..268995100b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7066d9ca32e7a1a60614effdc4701970", + "content-hash": "18b1ca2bf504854287ba8a490b63b597", "packages": [ { "name": "adhocore/jwt", @@ -65,16 +65,16 @@ }, { "name": "appwrite/appwrite", - "version": "10.1.0", + "version": "11.1.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-for-php.git", - "reference": "da579af70723cfc117b5af84375bdef117e27312" + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/da579af70723cfc117b5af84375bdef117e27312", - "reference": "da579af70723cfc117b5af84375bdef117e27312", + "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/1d043f543acdb17b9fdb440b1b2dd208e400bad3", + "reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3", "shasum": "" }, "require": { @@ -83,7 +83,8 @@ "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "3.7.35" + "mockery/mockery": "^1.6.6", + "phpunit/phpunit": "^10" }, "type": "library", "autoload": { @@ -99,10 +100,10 @@ "support": { "email": "team@appwrite.io", "issues": "https://github.com/appwrite/sdk-for-php/issues", - "source": "https://github.com/appwrite/sdk-for-php/tree/10.1.0", + "source": "https://github.com/appwrite/sdk-for-php/tree/11.1.0", "url": "https://appwrite.io/support" }, - "time": "2023-11-20T09:56:12+00:00" + "time": "2024-06-26T07:03:23+00:00" }, { "name": "appwrite/php-clamav", @@ -2205,27 +2206,35 @@ }, { "name": "utopia-php/migration", - "version": "0.5.2", + "version": "0.6.1", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "f18d44d4459f78c292dac9edde856fd156fe497a" + "reference": "6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/f18d44d4459f78c292dac9edde856fd156fe497a", - "reference": "f18d44d4459f78c292dac9edde856fd156fe497a", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0", + "reference": "6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0", "shasum": "" }, "require": { - "appwrite/appwrite": "10.1.0", - "php": "8.*" + "appwrite/appwrite": "11.1.*", + "ext-curl": "*", + "ext-openssl": "*", + "php": "8.3.*", + "utopia-php/database": "0.53.*", + "utopia-php/dsn": "0.2.*", + "utopia-php/framework": "0.33.*", + "utopia-php/storage": "0.18.*" }, "require-dev": { - "laravel/pint": "1.*", - "phpunit/phpunit": "9.*", - "utopia-php/cli": "^0.18.0", - "vlucas/phpdotenv": "5.*" + "ext-pdo": "*", + "laravel/pint": "1.17.*", + "phpstan/phpstan": "1.11.*", + "phpunit/phpunit": "11.2.*", + "utopia-php/cli": "0.16.*", + "vlucas/phpdotenv": "5.6.*" }, "type": "library", "autoload": { @@ -2247,9 +2256,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.5.2" + "source": "https://github.com/utopia-php/migration/tree/0.6.1" }, - "time": "2024-07-22T09:27:07+00:00" + "time": "2024-09-24T09:54:09+00:00" }, { "name": "utopia-php/mongo", @@ -3345,16 +3354,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.3", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482" + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/9d77be916e145864f10788bb94531d03e1f7b482", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482", + "url": "https://api.github.com/repos/laravel/pint/zipball/35c00c05ec43e6b46d295efc0f4386ceb30d50d9", + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9", "shasum": "" }, "require": { @@ -3407,7 +3416,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-09-03T15:00:28+00:00" + "time": "2024-09-24T17:22:50+00:00" }, { "name": "matthiasmullie/minify", @@ -4216,16 +4225,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.31.0", + "version": "1.32.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "249f15fb843bf240cf058372dad29e100cee6c17" + "reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/249f15fb843bf240cf058372dad29e100cee6c17", - "reference": "249f15fb843bf240cf058372dad29e100cee6c17", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6ca22b154efdd9e3c68c56f5d94670920a1c19a4", + "reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4", "shasum": "" }, "require": { @@ -4257,9 +4266,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.31.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.32.0" }, - "time": "2024-09-22T11:32:18+00:00" + "time": "2024-09-26T07:23:32+00:00" }, { "name": "phpunit/php-code-coverage", From 2b08fb59c341ac9d5c7f0a7ea0a181915fd4f010 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 16:50:42 +0300 Subject: [PATCH 190/213] relations --- src/Appwrite/Platform/Workers/Deletes.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 8b835c53f3..988a8f2e48 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -503,6 +503,25 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { + + /** + * Ignore junction tables; + */ + $relationships = \array_filter( + $collection->getAttribute('attributes', []), + fn ($attribute) => + $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP && + $attribute->getAttribute('options')['side'] === Database::RELATION_SIDE_PARENT && + $attribute->getAttribute('options')['relationType'] === Database::RELATION_MANY_TO_MANY + ); + + $junctions = []; + foreach ($relationships as $relationship) { + var_dump("many2many"); + var_dump($collection->getInternalId()); + var_dump($relationship); + } + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); } else { From e000234dbd92c02f3bc6da2d14cbac2a7718d720 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 18:11:41 +0300 Subject: [PATCH 191/213] relatedCollection --- src/Appwrite/Platform/Workers/Deletes.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 988a8f2e48..3ffd29f3a1 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -517,11 +517,18 @@ class Deletes extends Action $junctions = []; foreach ($relationships as $relationship) { + $relatedCollection = $relationship->getAttribute('options')['relatedCollection']; var_dump("many2many"); + var_dump("relatedCollection"); var_dump($collection->getInternalId()); + var_dump($relatedCollection->getInternalId()); var_dump($relationship); + $x = "_{$relatedCollection->getInternalId()}_{$collection->getInternalId()}"; + var_dump($x); } + $junctions = []; + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); } else { From d642111bfa48480a09adaf1a9747437a32f40a14 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 18:13:27 +0300 Subject: [PATCH 192/213] relatedCollection --- src/Appwrite/Platform/Workers/Deletes.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 3ffd29f3a1..7fda80d670 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -498,6 +498,7 @@ class Deletes extends Action ]; $limit = \count($projectCollectionIds) + 25; + $junctions = []; while (true) { $collections = $dbForProject->listCollections($limit); @@ -515,7 +516,6 @@ class Deletes extends Action $attribute->getAttribute('options')['relationType'] === Database::RELATION_MANY_TO_MANY ); - $junctions = []; foreach ($relationships as $relationship) { $relatedCollection = $relationship->getAttribute('options')['relatedCollection']; var_dump("many2many"); @@ -524,10 +524,11 @@ class Deletes extends Action var_dump($relatedCollection->getInternalId()); var_dump($relationship); $x = "_{$relatedCollection->getInternalId()}_{$collection->getInternalId()}"; + $junctions[] = "_{$relatedCollection->getInternalId()}_{$collection->getInternalId()}"; var_dump($x); } - $junctions = []; + var_dump($junctions); if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); From a8bb54a33ed8df36a0e1f421b6f8201206d4895a Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 26 Sep 2024 18:24:40 +0300 Subject: [PATCH 193/213] var_dump $junctions --- src/Appwrite/Platform/Workers/Deletes.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 7fda80d670..f90e9d34ec 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -504,7 +504,6 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { - /** * Ignore junction tables; */ From 26f0efc34defb5d9fde6e32d9b8c87e7f42e18f3 Mon Sep 17 00:00:00 2001 From: fogelito Date: Fri, 27 Sep 2024 10:45:23 +0300 Subject: [PATCH 194/213] Ignore junction tables --- src/Appwrite/Platform/Workers/Deletes.php | 38 +++++++---------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index f90e9d34ec..c22d23087f 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -504,33 +504,19 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { - /** - * Ignore junction tables; - */ - $relationships = \array_filter( - $collection->getAttribute('attributes', []), - fn ($attribute) => - $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP && - $attribute->getAttribute('options')['side'] === Database::RELATION_SIDE_PARENT && - $attribute->getAttribute('options')['relationType'] === Database::RELATION_MANY_TO_MANY - ); - - foreach ($relationships as $relationship) { - $relatedCollection = $relationship->getAttribute('options')['relatedCollection']; - var_dump("many2many"); - var_dump("relatedCollection"); - var_dump($collection->getInternalId()); - var_dump($relatedCollection->getInternalId()); - var_dump($relationship); - $x = "_{$relatedCollection->getInternalId()}_{$collection->getInternalId()}"; - $junctions[] = "_{$relatedCollection->getInternalId()}_{$collection->getInternalId()}"; - var_dump($x); - } - - var_dump($junctions); - if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { - $dbForProject->deleteCollection($collection->getId()); + try { + $dbForProject->deleteCollection($collection->getId()); + } catch (DatabaseException $e) { + Console::error('Error deleting '.$collection->getId().' '.$e->getMessage()); + + /** + * Ignore junction tables; + */ + if (!preg_match('/^_\d+_\d+$/', $collection->getId())) { + throw $e; + } + } } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } From 7389c9a5fe1f918b83e4f5aee0baf7a0c3fc55ae Mon Sep 17 00:00:00 2001 From: fogelito Date: Fri, 27 Sep 2024 10:50:09 +0300 Subject: [PATCH 195/213] Catch Throwable --- src/Appwrite/Platform/Workers/Deletes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index c22d23087f..4c589f4485 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -507,7 +507,7 @@ class Deletes extends Action if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { try { $dbForProject->deleteCollection($collection->getId()); - } catch (DatabaseException $e) { + } catch (Throwable $e) { Console::error('Error deleting '.$collection->getId().' '.$e->getMessage()); /** From e627cab92e8f0a08a42af2c1293c7ee7e532cfc8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Fri, 27 Sep 2024 11:43:22 +0300 Subject: [PATCH 196/213] Check deviceForFiles --- src/Appwrite/Platform/Workers/Deletes.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 4c589f4485..306e2abba9 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -582,6 +582,9 @@ class Deletes extends Action $this->deleteByGroup('_metadata', [], $dbForProject); } + + Console::error('deviceForFiles === ' . $deviceForFiles->getRoot()); + // Delete all storage directories $deviceForFiles->delete($deviceForFiles->getRoot(), true); $deviceForFunctions->delete($deviceForFunctions->getRoot(), true); From d5bf134c927020c3de8662756f5c2ee70236d09a Mon Sep 17 00:00:00 2001 From: fogelito Date: Fri, 27 Sep 2024 13:14:38 +0300 Subject: [PATCH 197/213] delete deleteCollection --- src/Appwrite/Platform/Workers/Deletes.php | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 306e2abba9..8b835c53f3 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -498,25 +498,13 @@ class Deletes extends Action ]; $limit = \count($projectCollectionIds) + 25; - $junctions = []; while (true) { $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { - try { - $dbForProject->deleteCollection($collection->getId()); - } catch (Throwable $e) { - Console::error('Error deleting '.$collection->getId().' '.$e->getMessage()); - - /** - * Ignore junction tables; - */ - if (!preg_match('/^_\d+_\d+$/', $collection->getId())) { - throw $e; - } - } + $dbForProject->deleteCollection($collection->getId()); } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } @@ -582,9 +570,6 @@ class Deletes extends Action $this->deleteByGroup('_metadata', [], $dbForProject); } - - Console::error('deviceForFiles === ' . $deviceForFiles->getRoot()); - // Delete all storage directories $deviceForFiles->delete($deviceForFiles->getRoot(), true); $deviceForFunctions->delete($deviceForFunctions->getRoot(), true); From 032fec3cae4591fbf1fb592a70b7798c9bf19ac3 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 30 Sep 2024 10:43:50 +0300 Subject: [PATCH 198/213] Add id --- src/Appwrite/Platform/Workers/Migrations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 08757d3e2a..2747b85580 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -396,7 +396,7 @@ class Migrations extends Action $destination->error(); $source->error(); - throw new Exception('Migration failed'); + throw new Exception('Migration('.$migration->getId().') failed, Project('.$this->project->getId().')'); } } } From 6625d4e4a83a063f081f258f58043dc2f85b7fb9 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 30 Sep 2024 11:01:01 +0300 Subject: [PATCH 199/213] Add console error --- src/Appwrite/Platform/Workers/Migrations.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 2747b85580..863548f0f3 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -393,10 +393,12 @@ class Migrations extends Action $this->updateMigrationDocument($migration, $projectDocument); if ($migration->getAttribute('status', '') === 'failed') { + Console::error('Migration('.$migration->getInternalId().':'.$migration->getId().') failed, Project('.$this->project->getInternalId().':'.$this->project->getId().')'); + $destination->error(); $source->error(); - throw new Exception('Migration('.$migration->getId().') failed, Project('.$this->project->getId().')'); + throw new Exception('Migration failed'); } } } From 05bcb92f73a34d2c175aba50151ec52502ee37c1 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:45:06 +0100 Subject: [PATCH 200/213] test: extra sleep --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4bc7b18d23..6e7012527d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -144,7 +144,7 @@ jobs: run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose up -d - sleep 25 + sleep 30 - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug From bb20b3f52c16b3b72e00397bbe45bc6c9a7eed94 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 30 Sep 2024 16:32:50 +0200 Subject: [PATCH 201/213] feat(realtime): projects channels --- src/Appwrite/Messaging/Adapter/Realtime.php | 5 +++ src/Appwrite/Platform/Workers/Migrations.php | 5 +-- .../Specification/Format/Swagger2.php | 2 +- .../Realtime/RealtimeConsoleClientTest.php | 43 +++++++++++++------ 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 49aa305c3f..d0d4a7c725 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -266,6 +266,7 @@ class Realtime extends Adapter break; case 'rules': $channels[] = 'console'; + $channels[] = 'projects.' . $project->getId(); $projectId = 'console'; $roles = [Role::team($project->getAttribute('teamId'))->toString()]; break; @@ -284,6 +285,7 @@ class Realtime extends Adapter case 'databases': if (in_array($parts[4] ?? [], ['attributes', 'indexes'])) { $channels[] = 'console'; + $channels[] = 'projects.' . $project->getId(); $projectId = 'console'; $roles = [Role::team($project->getAttribute('teamId'))->toString()]; } elseif (($parts[4] ?? '') === 'documents') { @@ -323,6 +325,7 @@ class Realtime extends Adapter if ($parts[2] === 'executions') { if (!empty($payload->getRead())) { $channels[] = 'console'; + $channels[] = 'projects.' . $project->getId(); $channels[] = 'executions'; $channels[] = 'executions.' . $payload->getId(); $channels[] = 'functions.' . $payload->getAttribute('functionId'); @@ -330,6 +333,7 @@ class Realtime extends Adapter } } elseif ($parts[2] === 'deployments') { $channels[] = 'console'; + $channels[] = 'projects.' . $project->getId(); $projectId = 'console'; $roles = [Role::team($project->getAttribute('teamId'))->toString()]; } @@ -337,6 +341,7 @@ class Realtime extends Adapter break; case 'migrations': $channels[] = 'console'; + $channels[] = 'projects.' . $project->getId(); $projectId = 'console'; $roles = [Role::team($project->getAttribute('teamId'))->toString()]; break; diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 863548f0f3..c25d1b59e4 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -17,7 +17,6 @@ use Utopia\Database\Exception\Restricted; use Utopia\Database\Exception\Structure; use Utopia\Database\Helpers\ID; use Utopia\Logger\Log; -use Utopia\Logger\Log\Breadcrumb; use Utopia\Migration\Destination; use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite; use Utopia\Migration\Exception as MigrationException; @@ -330,7 +329,7 @@ class Migrations extends Action foreach ($sourceErrors as $error) { /** @var $sourceErrors $error */ $message = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'"; - if($error->getPrevious()){ + if ($error->getPrevious()) { $message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); } @@ -339,7 +338,7 @@ class Migrations extends Action foreach ($destinationErrors as $error) { $message = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'"; - if($error->getPrevious()){ + if ($error->getPrevious()) { $message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine(); } diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index 826bee83e6..15e3fdc2f4 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -300,7 +300,7 @@ class Swagger2 extends Format break; } - if($class === 'Utopia\Validator\AnyOf') { + if ($class === 'Utopia\Validator\AnyOf') { $validator = $param['validator']->getValidators()[0]; $class = \get_class($validator); } diff --git a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php index 6ab2874f8e..d4054ab8e9 100644 --- a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php @@ -19,7 +19,7 @@ class RealtimeConsoleClientTest extends Scope use ProjectCustom; use SideConsole; - public function testManualAuthentication() + public function testManualAuthentication(): void { $user = $this->getUser(); $userId = $user['$id'] ?? ''; @@ -124,7 +124,7 @@ class RealtimeConsoleClientTest extends Scope $client->close(); } - public function testAttributes() + public function testAttributes(): array { $user = $this->getUser(); $projectId = 'console'; @@ -184,6 +184,7 @@ class RealtimeConsoleClientTest extends Scope 'required' => true, ]); + $projectId = $this->getProject()['$id']; $attributeKey = $name['body']['key']; $this->assertEquals($name['headers']['status-code'], 202); @@ -198,8 +199,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.create", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -218,8 +220,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.update", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -276,6 +279,8 @@ class RealtimeConsoleClientTest extends Scope ]); $this->assertEquals($index['headers']['status-code'], 202); + + $projectId = $this->getProject()['$id']; $indexKey = $index['body']['key']; $response = json_decode($client->receive(), true); @@ -285,8 +290,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.create", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -303,8 +309,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.update", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -343,6 +350,8 @@ class RealtimeConsoleClientTest extends Scope $this->assertContains('console', $response['data']['channels']); $this->assertNotEmpty($response['data']['user']); + $projectId = $this->getProject()['$id']; + /** * Test Delete Index */ @@ -353,6 +362,7 @@ class RealtimeConsoleClientTest extends Scope ], $this->getHeaders())); $this->assertEquals($attribute['headers']['status-code'], 204); + $response = json_decode($client->receive(), true); $this->assertArrayHasKey('type', $response); @@ -360,8 +370,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.update", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -377,8 +388,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.delete", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -416,10 +428,12 @@ class RealtimeConsoleClientTest extends Scope $this->assertContains('console', $response['data']['channels']); $this->assertNotEmpty($response['data']['user']); + $attributeKey = 'name'; + $projectId = $this->getProject()['$id']; + /** * Test Delete Attribute */ - $attributeKey = 'name'; $attribute = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $data['actorsId'] . '/attributes/' . $attributeKey, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -433,8 +447,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.update", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -450,8 +465,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.delete", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']); @@ -505,10 +521,10 @@ class RealtimeConsoleClientTest extends Scope /** * Test Create Deployment */ - $folder = 'php'; $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; $this->packageCode($folder); + $projectId = $this->getProject()['$id']; $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', @@ -530,8 +546,9 @@ class RealtimeConsoleClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(1, $response['data']['channels']); + $this->assertCount(2, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$projectId}", $response['data']['channels']); // $this->assertContains("functions.{$functionId}.deployments.{$deploymentId}.create", $response['data']['events']); TODO @christyjacob4 : enable test once we allow functions.* events $this->assertNotEmpty($response['data']['payload']); From 333682c4dc8eb9e930eeb4090991fbbb91e89654 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 30 Sep 2024 16:53:25 +0200 Subject: [PATCH 202/213] tests: add projects channel assertions --- src/Appwrite/Platform/Workers/Functions.php | 3 ++- tests/e2e/Services/Realtime/RealtimeCustomClientTest.php | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index e60f67416d..dfe7435426 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -587,7 +587,8 @@ class Functions extends Action $target = Realtime::fromPayload( // Pass first, most verbose event pattern event: $allEvents[0], - payload: $execution + payload: $execution, + project: $project ); Realtime::send( projectId: 'console', diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index c3372b98c5..d526afe13a 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -1340,8 +1340,9 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - $this->assertCount(4, $response['data']['channels']); + $this->assertCount(5, $response['data']['channels']); $this->assertContains('console', $response['data']['channels']); + $this->assertContains("projects.{$this->getProject()['$id']}", $response['data']['channels']); $this->assertContains('executions', $response['data']['channels']); $this->assertContains("executions.{$executionId}", $response['data']['channels']); $this->assertContains("functions.{$functionId}", $response['data']['channels']); @@ -1362,8 +1363,9 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals('event', $responseUpdate['type']); $this->assertNotEmpty($responseUpdate['data']); $this->assertArrayHasKey('timestamp', $responseUpdate['data']); - $this->assertCount(4, $responseUpdate['data']['channels']); + $this->assertCount(5, $responseUpdate['data']['channels']); $this->assertContains('console', $responseUpdate['data']['channels']); + $this->assertContains("projects.{$this->getProject()['$id']}", $response['data']['channels']); $this->assertContains('executions', $responseUpdate['data']['channels']); $this->assertContains("executions.{$executionId}", $responseUpdate['data']['channels']); $this->assertContains("functions.{$functionId}", $responseUpdate['data']['channels']); From e6d8221c898fa1d00c5b1e246589c5190c044c7c Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 30 Sep 2024 17:08:17 +0200 Subject: [PATCH 203/213] tests(realtime): fix argument types --- tests/e2e/Services/Realtime/RealtimeBase.php | 67 ++++++++++++-------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/tests/e2e/Services/Realtime/RealtimeBase.php b/tests/e2e/Services/Realtime/RealtimeBase.php index 30c411ba93..99f31134c0 100644 --- a/tests/e2e/Services/Realtime/RealtimeBase.php +++ b/tests/e2e/Services/Realtime/RealtimeBase.php @@ -7,25 +7,34 @@ use WebSocket\ConnectionException; trait RealtimeBase { - private function getWebsocket($channels = [], $headers = [], $projectId = null): WebSocketClient - { + private function getWebsocket( + array $channels = [], + array $headers = [], + string $projectId = null + ): WebSocketClient { if (is_null($projectId)) { $projectId = $this->getProject()['$id']; } - $headers = array_merge([ - 'Origin' => 'appwrite.test' - ], $headers); + $headers = array_merge( + [ + "Origin" => "appwrite.test", + ], + $headers + ); $query = [ - 'project' => $projectId, - 'channels' => $channels + "project" => $projectId, + "channels" => $channels, ]; - return new WebSocketClient('ws://appwrite-traefik/v1/realtime?' . http_build_query($query), [ - 'headers' => $headers, - 'timeout' => 30, - ]); + return new WebSocketClient( + "ws://appwrite-traefik/v1/realtime?" . http_build_query($query), + [ + "headers" => $headers, + "timeout" => 30, + ] + ); } public function testConnection(): void @@ -33,7 +42,7 @@ trait RealtimeBase /** * Test for SUCCESS */ - $client = $this->getWebsocket(['documents']); + $client = $this->getWebsocket(["documents"]); $this->assertNotEmpty($client->receive()); $client->close(); } @@ -43,11 +52,11 @@ trait RealtimeBase $client = $this->getWebsocket(); $payload = json_decode($client->receive(), true); - $this->assertArrayHasKey('type', $payload); - $this->assertArrayHasKey('data', $payload); - $this->assertEquals('error', $payload['type']); - $this->assertEquals(1008, $payload['data']['code']); - $this->assertEquals('Missing channels', $payload['data']['message']); + $this->assertArrayHasKey("type", $payload); + $this->assertArrayHasKey("data", $payload); + $this->assertEquals("error", $payload["type"]); + $this->assertEquals(1008, $payload["data"]["code"]); + $this->assertEquals("Missing channels", $payload["data"]["message"]); \usleep(250000); // 250ms $this->expectException(ConnectionException::class); // Check if server disconnnected client $client->close(); @@ -55,18 +64,24 @@ trait RealtimeBase public function testConnectionFailureUnknownProject(): void { - $client = new WebSocketClient('ws://appwrite-traefik/v1/realtime?project=123', [ - 'headers' => [ - 'Origin' => 'appwrite.test' + $client = new WebSocketClient( + "ws://appwrite-traefik/v1/realtime?project=123", + [ + "headers" => [ + "Origin" => "appwrite.test", + ], ] - ]); + ); $payload = json_decode($client->receive(), true); - $this->assertArrayHasKey('type', $payload); - $this->assertArrayHasKey('data', $payload); - $this->assertEquals('error', $payload['type']); - $this->assertEquals(1008, $payload['data']['code']); - $this->assertEquals('Missing or unknown project ID', $payload['data']['message']); + $this->assertArrayHasKey("type", $payload); + $this->assertArrayHasKey("data", $payload); + $this->assertEquals("error", $payload["type"]); + $this->assertEquals(1008, $payload["data"]["code"]); + $this->assertEquals( + "Missing or unknown project ID", + $payload["data"]["message"] + ); \usleep(250000); // 250ms $this->expectException(ConnectionException::class); // Check if server disconnnected client $client->close(); From 51152ae87958ebad59facf09c7295e39537bbce4 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 30 Sep 2024 23:07:37 +0300 Subject: [PATCH 204/213] Ignore junction tables --- src/Appwrite/Platform/Workers/Deletes.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 8b835c53f3..62fd8cd177 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -504,7 +504,18 @@ class Deletes extends Action foreach ($collections as $collection) { if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { - $dbForProject->deleteCollection($collection->getId()); + try { + $dbForProject->deleteCollection($collection->getId()); + } catch (Throwable $e) { + Console::error('Error deleting '.$collection->getId().' '.$e->getMessage()); + + /** + * Ignore junction tables; + */ + if (!preg_match('/^_\d+_\d+$/', $collection->getId())) { + throw $e; + } + } } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } From 54f55f65f42f1f4731b3443f871a00f341869565 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 1 Oct 2024 17:17:36 +0300 Subject: [PATCH 205/213] deletes-worker-set-project --- app/controllers/api/projects.php | 1 + app/worker.php | 11 +++-------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index aafd480398..ab46e91330 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -923,6 +923,7 @@ App::delete('/v1/projects/:projectId') } $queueForDeletes + ->setProject($project) ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($project); diff --git a/app/worker.php b/app/worker.php index 9bcdae78e6..9f17987ba5 100644 --- a/app/worker.php +++ b/app/worker.php @@ -54,16 +54,11 @@ Server::setResource('dbForConsole', function (Cache $cache, Registry $register) return $adapter; }, ['cache', 'register']); -Server::setResource('project', function (Message $message, Database $dbForConsole) { +Server::setResource('project', function (Message $message) { $payload = $message->getPayload() ?? []; - $project = new Document($payload['project'] ?? []); - if ($project->getId() === 'console') { - return $project; - } - - return $dbForConsole->getDocument('projects', $project->getId()); -}, ['message', 'dbForConsole']); + return new Document($payload['project'] ?? []); +}, ['message']); Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForConsole) { if ($project->isEmpty() || $project->getId() === 'console') { From c3b186b3f995432aa039b8c28d2674010c19ef24 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 2 Oct 2024 14:32:56 +0300 Subject: [PATCH 206/213] set setResource project --- app/worker.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/worker.php b/app/worker.php index bb56eca8c1..b356d42ff7 100644 --- a/app/worker.php +++ b/app/worker.php @@ -54,11 +54,16 @@ Server::setResource('dbForConsole', function (Cache $cache, Registry $register) return $adapter; }, ['cache', 'register']); -Server::setResource('project', function (Message $message) { +Server::setResource('project', function (Message $message, Database $dbForConsole) { $payload = $message->getPayload() ?? []; + $project = new Document($payload['project'] ?? []); - return new Document($payload['project'] ?? []); -}, ['message']); + if ($project->getId() === 'console' || $project->isEmpty() || !empty($project->getInternalId())) { + return $project; + } + + return $dbForConsole->getDocument('projects', $project->getId()); +}, ['message', 'dbForConsole']); Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForConsole) { if ($project->isEmpty() || $project->getId() === 'console') { From a408cd3b579972d8071c6bb41c37bc42494a775c Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 2 Oct 2024 14:36:09 +0300 Subject: [PATCH 207/213] set setResource project --- app/worker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/worker.php b/app/worker.php index b356d42ff7..2d59259284 100644 --- a/app/worker.php +++ b/app/worker.php @@ -58,7 +58,7 @@ Server::setResource('project', function (Message $message, Database $dbForConsol $payload = $message->getPayload() ?? []; $project = new Document($payload['project'] ?? []); - if ($project->getId() === 'console' || $project->isEmpty() || !empty($project->getInternalId())) { + if ($project->getId() === 'console' || $project->isEmpty() || ! empty($project->getInternalId())) { return $project; } From a45db60313b52115eadbbfb0ddc3b4d473c71942 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:16:25 +0100 Subject: [PATCH 208/213] fix: falsy values --- tests/e2e/General/UsageTest.php | 4 ++-- .../Functions/FunctionsCustomClientTest.php | 4 ++-- .../Functions/FunctionsCustomServerTest.php | 18 +++++++++--------- .../FunctionsScheduleTest.php | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index db75a5db45..c50a15fd3f 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -931,7 +931,7 @@ class UsageTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ - 'async' => false, + 'async' => 'false', ] ); @@ -955,7 +955,7 @@ class UsageTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ - 'async' => false, + 'async' => 'false', ] ); diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 3447ee0547..31cc05f423 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -97,7 +97,7 @@ class FunctionsCustomClientTest extends Scope $execution = $this->createExecution($functionId, [ 'body' => 'foobar', - 'async' => false + 'async' => 'false' ]); $output = json_decode($execution['body']['responseBody'], true); $this->assertEquals(201, $execution['headers']['status-code']); @@ -208,7 +208,7 @@ class FunctionsCustomClientTest extends Scope $execution = $this->createExecution($functionId, [ 'body' => 'foobar', - // Testing default value, should be 'async' => false + // Testing default value, should be 'async' => 'false' ]); $output = json_decode($execution['body']['responseBody'], true); $this->assertEquals(201, $execution['headers']['status-code']); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 14ec660c4b..2c3ddbcf58 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -463,7 +463,7 @@ class FunctionsCustomServerTest extends Scope $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => false + 'activate' => 'false' ]); $this->assertEquals(202, $deployment['headers']['status-code']); @@ -502,7 +502,7 @@ class FunctionsCustomServerTest extends Scope $deployment = $this->createDeployment($functionId, [ 'code' => $this->packageFunction('php'), - 'activate' => false + 'activate' => 'false' ]); $deploymentId = $deployment['body']['$id'] ?? ''; @@ -845,7 +845,7 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $execution = $this->createExecution($data['functionId'], [ - 'async' => false, + 'async' => 'false', ]); $this->assertEquals(201, $execution['headers']['status-code']); @@ -870,7 +870,7 @@ class FunctionsCustomServerTest extends Scope $executionId = $execution['body']['$id'] ?? ''; $execution = $this->createExecution($data['functionId'], [ - 'async' => false, + 'async' => 'false', 'path' => '/?code=400' ]); @@ -965,7 +965,7 @@ class FunctionsCustomServerTest extends Scope * Test for SUCCESS */ $execution = $this->createExecution($data['functionId'], [ - // Testing default value, should be 'async' => false + // Testing default value, should be 'async' => 'false' ]); $this->assertEquals(201, $execution['headers']['status-code']); @@ -1281,7 +1281,7 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($functionId, [ 'body' => 'foobar', - 'async' => false + 'async' => 'false' ]); $output = json_decode($execution['body']['responseBody'], true); @@ -1447,7 +1447,7 @@ class FunctionsCustomServerTest extends Scope $execution = $this->createExecution($functionId, [ 'body' => 'foobar', - 'async' => false + 'async' => 'false' ]); $output = json_decode($execution['body']['responseBody'], true); @@ -1561,7 +1561,7 @@ class FunctionsCustomServerTest extends Scope $this->assertStringContainsStringIgnoringCase('"users":', $deployment['body']['buildLogs']); $execution = $this->createExecution($functionId, [ - 'async' => false, + 'async' => 'false', ]); $this->assertEquals(201, $execution['headers']['status-code']); @@ -1611,7 +1611,7 @@ class FunctionsCustomServerTest extends Scope $cookie = 'cookieName=cookieValue; cookie2=value2; cookie3=value=3; cookie4=val:ue4; cookie5=value5'; $execution = $this->createExecution($functionId, [ - 'async' => false, + 'async' => 'false', 'headers' => [ 'cookie' => $cookie ] diff --git a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php index cbe54b6445..b1315103b1 100644 --- a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php +++ b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php @@ -143,7 +143,7 @@ class FunctionsScheduleTest extends Scope /* Test for FAILURE */ // Schedule synchronous execution $execution = $this->createExecution($functionId, [ - 'async' => false, + 'async' => 'false', 'scheduledAt' => $futureTime->format(\DateTime::ATOM), ]); $this->assertEquals(400, $execution['headers']['status-code']); From 886687ed34fc275b29bfa6c542419555c85d8320 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:19:15 +0100 Subject: [PATCH 209/213] fix: reorder assertions --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 2c3ddbcf58..3af050438f 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1450,10 +1450,11 @@ class FunctionsCustomServerTest extends Scope 'async' => 'false' ]); - $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']); + + $output = json_decode($execution['body']['responseBody'], true); $this->assertEquals(true, $output['v2Woks']); $this->cleanupFunction($functionId); From 48e57be312d1ebeccc833e64f530653530232d35 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 2 Oct 2024 17:18:10 +0200 Subject: [PATCH 210/213] chore: update composer lock --- composer.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/composer.lock b/composer.lock index 268995100b..ea8044633b 100644 --- a/composer.lock +++ b/composer.lock @@ -1804,7 +1804,7 @@ "utopia" ], "support": { - "source": "https://github.com/utopia-php/database/tree/0.53.5-rc1", + "source": "https://github.com/utopia-php/database/tree/0.53.5", "issues": "https://github.com/utopia-php/database/issues" }, "time": "2024-09-24T08:43:10+00:00" @@ -2206,16 +2206,16 @@ }, { "name": "utopia-php/migration", - "version": "0.6.1", + "version": "0.6.4", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0" + "reference": "e43ef283f1386084e11d1ffe093fb6c6d7a6ce6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0", - "reference": "6a064179dd0a7278bfbaf65d9abdef19d6d2bbe0", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/e43ef283f1386084e11d1ffe093fb6c6d7a6ce6c", + "reference": "e43ef283f1386084e11d1ffe093fb6c6d7a6ce6c", "shasum": "" }, "require": { @@ -2256,9 +2256,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.6.1" + "source": "https://github.com/utopia-php/migration/tree/0.6.4" }, - "time": "2024-09-24T09:54:09+00:00" + "time": "2024-10-02T15:16:36+00:00" }, { "name": "utopia-php/mongo", @@ -3033,16 +3033,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.39.21", + "version": "0.39.22", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "9754b190d33aaad56fdb8defc94f90248184c5ac" + "reference": "bdbb1607527550e67283ff0533522d1410c2c0df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/9754b190d33aaad56fdb8defc94f90248184c5ac", - "reference": "9754b190d33aaad56fdb8defc94f90248184c5ac", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/bdbb1607527550e67283ff0533522d1410c2c0df", + "reference": "bdbb1607527550e67283ff0533522d1410c2c0df", "shasum": "" }, "require": { @@ -3078,9 +3078,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.39.21" + "source": "https://github.com/appwrite/sdk-generator/tree/0.39.22" }, - "time": "2024-09-10T08:49:29+00:00" + "time": "2024-10-01T16:16:26+00:00" }, { "name": "doctrine/annotations", @@ -3604,16 +3604,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.2.0", + "version": "v5.3.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb" + "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3abf7425cd284141dc5d8d14a9ee444de3345d1a", + "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a", "shasum": "" }, "require": { @@ -3656,9 +3656,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.0" }, - "time": "2024-09-15T16:40:33+00:00" + "time": "2024-09-29T13:56:26+00:00" }, { "name": "phar-io/manifest", From 04bc24f42b3d179a056f09b49b135695a74e03e1 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 3 Oct 2024 11:20:47 +0200 Subject: [PATCH 211/213] tests: fix merge conflict --- tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php index bd2cd9c40a..60c96c6e19 100644 --- a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php @@ -520,9 +520,10 @@ class RealtimeConsoleClientTest extends Scope /** * Test Create Deployment */ + $projectId = $this->getProject()['$id']; $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([ 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-project' => $projectId, ], $this->getHeaders()), [ 'entrypoint' => 'index.php', 'code' => $this->packageFunction('php'), From ef6ed675b3051bd0b49e0d643860499598c100ab Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:26:31 +0530 Subject: [PATCH 212/213] Fix request response filter tests --- .../Functions/FunctionsCustomServerTest.php | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 571f528805..976553059b 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1791,6 +1791,7 @@ class FunctionsCustomServerTest extends Scope public function testResponseFilters() { + // create function with 1.5.0 response format $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1803,27 +1804,6 @@ class FunctionsCustomServerTest extends Scope 'timeout' => 15, ]); - $this->assertEquals(201, $response['headers']['status-code']); - - $functionId = $function['body']['$id'] ?? ''; - - $this->cleanupFunction($functionId); - } - - public function testRequestFilters() - { - // create function with 1.5.0 response format header - $response = $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', - 'runtime' => 'php-8.0', - 'entrypoint' => 'index.php', - 'timeout' => 15, - ]); - $this->assertEquals(201, $response['headers']['status-code']); $this->assertArrayNotHasKey('scopes', $response['body']); $this->assertArrayNotHasKey('specification', $response['body']); @@ -1849,6 +1829,27 @@ class FunctionsCustomServerTest extends Scope $this->assertArrayHasKey('scopes', $function['body']); $this->assertArrayHasKey('specification', $function['body']); + $functionId = $function['body']['$id'] ?? ''; + $this->cleanupFunction($functionId); + } + + public function testRequestFilters() + { + // create function + $response = $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', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'timeout' => 15, + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $function1Id = $response['body']['$id']; + // create another function $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', @@ -1862,6 +1863,7 @@ class FunctionsCustomServerTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); + $function2Id = $response['body']['$id']; // list functions using request filters $response = $this->client->call( @@ -1880,6 +1882,9 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertCount(1, $response['body']['functions']); $this->assertEquals('Test2', $response['body']['functions'][0]['name']); + + $this->cleanupFunction($function1Id); + $this->cleanupFunction($function2Id); } public function testFunctionLogging() From 34527efc79add92c10faf0f9f5eec9d1494e90a1 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:07:01 +0530 Subject: [PATCH 213/213] Use helper functions --- .../Functions/FunctionsCustomServerTest.php | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 976553059b..59a3041a3f 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1819,11 +1819,7 @@ class FunctionsCustomServerTest extends Scope $this->assertArrayNotHasKey('scopes', $function['body']); $this->assertArrayNotHasKey('specification', $function['body']); - // get function without response format header - $function = $this->client->call(Client::METHOD_GET, '/functions/' . $response['body']['$id'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); + $function = $this->getFunction($function['body']['$id']); $this->assertEquals(200, $function['headers']['status-code']); $this->assertArrayHasKey('scopes', $function['body']); @@ -1835,36 +1831,24 @@ class FunctionsCustomServerTest extends Scope public function testRequestFilters() { - // create function - $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function1Id = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'timeout' => 15, + 'execute' => ['any'] ]); - $this->assertEquals(201, $response['headers']['status-code']); - $function1Id = $response['body']['$id']; - - // create another function - $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + $function2Id = $this->setupFunction([ 'functionId' => ID::unique(), 'name' => 'Test2', 'runtime' => 'php-8.0', 'entrypoint' => 'index.php', 'timeout' => 15, + 'execute' => ['any'] ]); - $this->assertEquals(201, $response['headers']['status-code']); - $function2Id = $response['body']['$id']; - // list functions using request filters $response = $this->client->call( Client::METHOD_GET,