diff --git a/.env b/.env index c2c0cfa678..b22ab2ddcf 100644 --- a/.env +++ b/.env @@ -78,8 +78,8 @@ _APP_COMPUTE_MAINTENANCE_INTERVAL=600 _APP_COMPUTE_RUNTIMES_NETWORK=runtimes _APP_EXECUTOR_SECRET=your-secret-key _APP_EXECUTOR_HOST=http://exc1/v1 -_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1,ssr-22 -_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.24 +_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1 +_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.24,ssr-22 _APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,remix,static,flutter,other # TODO: Angular _APP_MAINTENANCE_INTERVAL=86400 _APP_MAINTENANCE_DELAY= diff --git a/app/config/frameworks/specifications.php b/app/config/frameworks/specifications.php new file mode 100644 index 0000000000..63ca3ea423 --- /dev/null +++ b/app/config/frameworks/specifications.php @@ -0,0 +1,51 @@ + [ + 'slug' => Specification::S_05VCPU_512MB, + 'memory' => 512, + 'cpus' => 0.5 + ], + Specification::S_1VCPU_512MB => [ + 'slug' => Specification::S_1VCPU_512MB, + 'memory' => 512, + 'cpus' => 1 + ], + Specification::S_1VCPU_1GB => [ + 'slug' => Specification::S_1VCPU_1GB, + 'memory' => 1024, + 'cpus' => 1 + ], + Specification::S_2VCPU_2GB => [ + 'slug' => Specification::S_2VCPU_2GB, + 'memory' => 2048, + 'cpus' => 2 + ], + Specification::S_2VCPU_4GB => [ + 'slug' => Specification::S_2VCPU_4GB, + 'memory' => 4096, + 'cpus' => 2 + ], + Specification::S_4VCPU_4GB => [ + 'slug' => Specification::S_4VCPU_4GB, + 'memory' => 4096, + 'cpus' => 4 + ], + Specification::S_4VCPU_8GB => [ + 'slug' => Specification::S_4VCPU_8GB, + 'memory' => 8192, + 'cpus' => 4 + ], + Specification::S_8VCPU_4GB => [ + 'slug' => Specification::S_8VCPU_4GB, + 'memory' => 4096, + 'cpus' => 8 + ], + Specification::S_8VCPU_8GB => [ + 'slug' => Specification::S_8VCPU_8GB, + 'memory' => 8192, + 'cpus' => 8 + ] +]; diff --git a/app/config/runtimes/specifications.php b/app/config/runtimes/specifications.php index 9ec6fc6059..d3625db8a2 100644 --- a/app/config/runtimes/specifications.php +++ b/app/config/runtimes/specifications.php @@ -5,17 +5,17 @@ use Appwrite\Functions\Specification; return [ Specification::S_05VCPU_512MB => [ 'slug' => Specification::S_05VCPU_512MB, - 'memory' => 4096, // TODO: Revert this, it was just for QA server - 'cpus' => 1 // TODO: revert this, it's a temporary change to test function performance. + 'memory' => 512, + 'cpus' => 0.5 ], Specification::S_1VCPU_512MB => [ 'slug' => Specification::S_1VCPU_512MB, - 'memory' => 4096, // TODO: Revert this, it was just for QA server + 'memory' => 512, 'cpus' => 1 ], Specification::S_1VCPU_1GB => [ 'slug' => Specification::S_1VCPU_1GB, - 'memory' => 4096, // TODO: Revert this, it was just for QA server + 'memory' => 1024, 'cpus' => 1 ], Specification::S_2VCPU_2GB => [ diff --git a/app/init.php b/app/init.php index dfa849c002..c2feb0f066 100644 --- a/app/init.php +++ b/app/init.php @@ -363,6 +363,7 @@ Config::load('storage-mimes', __DIR__ . '/config/storage/mimes.php'); Config::load('storage-inputs', __DIR__ . '/config/storage/inputs.php'); Config::load('storage-outputs', __DIR__ . '/config/storage/outputs.php'); Config::load('runtime-specifications', __DIR__ . '/config/runtimes/specifications.php'); +Config::load('framework-specifications', __DIR__ . '/config/frameworks/specifications.php'); Config::load('function-templates', __DIR__ . '/config/function-templates.php'); Config::load('site-templates', __DIR__ . '/config/site-templates.php'); diff --git a/src/Appwrite/Sites/Specification.php b/src/Appwrite/Sites/Specification.php new file mode 100644 index 0000000000..c6e725ec31 --- /dev/null +++ b/src/Appwrite/Sites/Specification.php @@ -0,0 +1,16 @@ +assertEquals(201, $execution['headers']['status-code']); $this->assertNotEmpty($execution['body']['$id']); - $this->assertNotEmpty($execution['body']['functionId']); + $this->assertNotEmpty($execution['body']['resourceId']); $this->assertEquals(true, (new DatetimeValidator())->isValid($execution['body']['$createdAt'])); - $this->assertEquals($data['functionId'], $execution['body']['functionId']); + $this->assertEquals($data['functionId'], $execution['body']['resourceId']); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['body']['responseStatusCode']); - $this->assertStringContainsString($execution['body']['functionId'], $execution['body']['responseBody']); + $this->assertStringContainsString($execution['body']['resourceId'], $execution['body']['responseBody']); $this->assertStringContainsString($data['deploymentId'], $execution['body']['responseBody']); $this->assertStringContainsString('Test1', $execution['body']['responseBody']); $this->assertStringContainsString('http', $execution['body']['responseBody']); @@ -941,7 +941,7 @@ class FunctionsCustomServerTest extends Scope $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($data['functionId'], $executions['body']['executions'][0]['resourceId']); $executions = $this->listExecutions($data['functionId'], [ 'search' => $data['functionId'], diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php index 2bb8ef44d4..d5863aea2f 100644 --- a/tests/e2e/Services/Sites/SitesCustomServerTest.php +++ b/tests/e2e/Services/Sites/SitesCustomServerTest.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\Sites; +use Appwrite\Sites\Specification; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; @@ -283,79 +284,67 @@ class SitesCustomServerTest extends Scope // // TODO: Implement testCreateDeploymentFromCLI() later // } - // public function testCreateSiteAndDeploymentFromTemplate() - // { - // $starterTemplate = $this->getTemplate('nextjs-starter'); - // $this->assertEquals(200, $starterTemplate['headers']['status-code']); + public function testCreateSiteAndDeploymentFromTemplate() + { + $starterTemplate = $this->getTemplate('nextjs-starter'); + $this->assertEquals(200, $starterTemplate['headers']['status-code']); - // $nextjsFramework = array_values(array_filter($starterTemplate['body']['frameworks'], function ($framework) { - // return $framework['key'] === 'nextjs'; - // }))[0]; + $nextjsFramework = array_values(array_filter($starterTemplate['body']['frameworks'], function ($framework) { + return $framework['key'] === 'nextjs'; + }))[0]; - // // If this fails, the template has variables, and this test needs to be updated - // $this->assertEmpty($starterTemplate['body']['variables']); + // If this fails, the template has variables, and this test needs to be updated + $this->assertEmpty($starterTemplate['body']['variables']); - // var_dump("creating site"); + $site = $this->createSite( + [ + 'siteId' => ID::unique(), + 'name' => $starterTemplate['body']['name'], + 'framework' => $nextjsFramework['key'], + 'adapter' => $nextjsFramework['adapter'], + 'buildCommand' => $nextjsFramework['buildCommand'], + 'buildRuntime' => $nextjsFramework['buildRuntime'], + 'fallbackFile' => $nextjsFramework['fallbackFile'], + 'installCommand' => $nextjsFramework['installCommand'], + 'outputDirectory' => $nextjsFramework['outputDirectory'], + 'providerRootDirectory' => $nextjsFramework['providerRootDirectory'], + 'templateOwner' => $starterTemplate['body']['providerOwner'], + 'templateRepository' => $starterTemplate['body']['providerRepositoryId'], + 'templateRootDirectory' => $nextjsFramework['providerRootDirectory'], + 'templateVersion' => $starterTemplate['body']['providerVersion'], + 'providerBranch' => 'main', + ] + ); - // $site = $this->createSite( - // [ - // 'siteId' => ID::unique(), - // 'name' => $starterTemplate['body']['name'], - // 'framework' => $nextjsFramework['key'], - // 'adapter' => $nextjsFramework['adapter'], - // 'buildCommand' => $nextjsFramework['buildCommand'], - // 'buildRuntime' => $nextjsFramework['buildRuntime'], - // 'fallbackFile' => $nextjsFramework['fallbackFile'], - // 'installCommand' => $nextjsFramework['installCommand'], - // 'outputDirectory' => $nextjsFramework['outputDirectory'], - // 'providerRootDirectory' => $nextjsFramework['providerRootDirectory'], - // 'templateOwner' => $starterTemplate['body']['providerOwner'], - // 'templateRepository' => $starterTemplate['body']['providerRepositoryId'], - // 'templateRootDirectory' => $nextjsFramework['providerRootDirectory'], - // 'templateVersion' => $starterTemplate['body']['providerVersion'], - // 'providerBranch' => 'main', - // ] - // ); + $this->assertEquals(201, $site['headers']['status-code']); + $this->assertNotEmpty($site['body']['$id']); - // $this->assertEquals(201, $site['headers']['status-code']); - // $this->assertNotEmpty($site['body']['$id']); + $siteId = $site['body']['$id'] ?? ''; - // $siteId = $site['body']['$id'] ?? ''; - // var_dump("Site id"); + $deployments = $this->listDeployments($siteId); - // $deployments = $this->listDeployments($siteId); + $this->assertEquals(200, $deployments['headers']['status-code']); + $this->assertEquals(1, $deployments['body']['total']); - // var_dump($deployments); + $lastDeployment = $deployments['body']['deployments'][0]; - // $this->assertEquals(200, $deployments['headers']['status-code']); - // $this->assertEquals(1, $deployments['body']['total']); + $this->assertNotEmpty($lastDeployment['$id']); + $this->assertEquals(0, $lastDeployment['size']); - // $lastDeployment = $deployments['body']['deployments'][0]; + $deploymentId = $lastDeployment['$id']; - // $this->assertNotEmpty($lastDeployment['$id']); - // $this->assertEquals(0, $lastDeployment['size']); + $this->assertEventually(function () use ($siteId, $deploymentId) { + $deployment = $this->getDeployment($siteId, $deploymentId); - // $deploymentId = $lastDeployment['$id']; - // var_dump("flow reached here"); + $this->assertEquals(200, $deployment['headers']['status-code']); + $this->assertEquals('ready', $deployment['body']['status']); + }, 300000, 1000); - // $this->assertEventually(function () use ($siteId, $deploymentId) { - // $deployment = $this->getDeployment($siteId, $deploymentId); + $site = $this->getSite($siteId); + $this->assertEquals(200, $site['headers']['status-code']); - // $this->assertEquals(200, $deployment['headers']['status-code']); - // // assert that deployment is ready or failed - // $this->assertContains($deployment['body']['status'], ['ready', 'failed']); - // }, 300000, 1000); - - // var_dump("flow reached here 2"); - - // $site = $this->getSite($siteId); - // $deployment = $this->getDeployment($siteId, $deploymentId); - - // $this->assertEquals(200, $site['headers']['status-code']); - // var_dump($deployment); - - // $this->cleanupSite($siteId); - // } + $this->cleanupSite($siteId); + } public function testCreateDeployment() { @@ -769,8 +758,6 @@ class SitesCustomServerTest extends Scope // $siteId = $site['body']['$id'] ?? ''; // $this->assertNotEmpty($siteId); - // var_dump($site); - // $deployment = $this->createDeployment($siteId, [ // 'code' => $this->packageSite('static'), // 'activate' => 'false' @@ -782,89 +769,87 @@ class SitesCustomServerTest extends Scope // $deployment = $this->getDeployment($siteId, $deploymentId); // $this->assertEquals('ready', $deployment['body']['status']); - // }, 50000, 500); + // }, 30000, 300); - // $domain = $site['body']['domain']; + // // get rule for this site from rules collection // $response = $this->client->call(Client::METHOD_GET, $domain); // var_dump($response); // } - // public function testUpdateSpecs(): void - // { - // $siteId = $this->setupSite([ - // 'buildRuntime' => 'ssr-22', - // 'fallbackFile' => null, - // 'framework' => 'other', - // 'name' => 'Test Site', - // 'outputDirectory' => './', - // 'providerBranch' => 'main', - // 'providerRootDirectory' => './', - // 'siteId' => ID::unique() - // ]); + public function testUpdateSpecs(): void + { + $siteId = $this->setupSite([ + 'buildRuntime' => 'ssr-22', + 'fallbackFile' => null, + 'framework' => 'other', + 'name' => 'Test Site', + 'outputDirectory' => './', + 'providerBranch' => 'main', + 'providerRootDirectory' => './', + 'siteId' => ID::unique() + ]); - // $this->assertNotNull($siteId); + $this->assertNotNull($siteId); - // /** - // * Test for SUCCESS - // */ - // // Change the function specs - // $site = $this->updateSite([ - // 'buildRuntime' => 'ssr-22', - // 'fallbackFile' => null, - // 'framework' => 'other', - // 'name' => 'Test Site', - // 'outputDirectory' => './', - // 'providerBranch' => 'main', - // 'providerRootDirectory' => './', - // '$id' => $siteId, - // 'specification' => Specification::S_1VCPU_1GB, - // ]); + /** + * Test for SUCCESS + */ + // Change the function specs + $site = $this->updateSite([ + 'buildRuntime' => 'ssr-22', + 'fallbackFile' => null, + 'framework' => 'other', + 'name' => 'Test Site', + 'outputDirectory' => './', + 'providerBranch' => 'main', + 'providerRootDirectory' => './', + '$id' => $siteId, + 'specification' => Specification::S_1VCPU_1GB, + ]); - // $this->assertEquals(200, $site['headers']['status-code']); - // $this->assertNotEmpty($site['body']['$id']); - // $this->assertEquals(Speci::S_1VCPU_1GB, $site['body']['specification']); + $this->assertEquals(200, $site['headers']['status-code']); + $this->assertNotEmpty($site['body']['$id']); + $this->assertEquals(Specification::S_1VCPU_1GB, $site['body']['specification']); - // // Change the specs to 1vcpu 512mb - // $site = $this->updateSite([ - // 'buildRuntime' => 'ssr-22', - // 'fallbackFile' => null, - // 'framework' => 'other', - // 'name' => 'Test Site', - // 'outputDirectory' => './', - // 'providerBranch' => 'main', - // 'providerRootDirectory' => './', - // '$id' => $siteId, - // 'specification' => Specification::S_1VCPU_512MB, - // ]); + // Change the specs to 1vcpu 512mb + $site = $this->updateSite([ + 'buildRuntime' => 'ssr-22', + 'fallbackFile' => null, + 'framework' => 'other', + 'name' => 'Test Site', + 'outputDirectory' => './', + 'providerBranch' => 'main', + 'providerRootDirectory' => './', + '$id' => $siteId, + 'specification' => Specification::S_1VCPU_512MB, + ]); - // $this->assertEquals(200, $site['headers']['status-code']); - // $this->assertNotEmpty($site['body']['$id']); - // $this->assertEquals(Specification::S_1VCPU_512MB, $site['body']['specification']); + $this->assertEquals(200, $site['headers']['status-code']); + $this->assertNotEmpty($site['body']['$id']); + $this->assertEquals(Specification::S_1VCPU_512MB, $site['body']['specification']); - // /** - // * Test for FAILURE - // */ + /** + * Test for FAILURE + */ - // $site = $this->updateSite([ - // 'buildRuntime' => 'ssr-22', - // 'fallbackFile' => null, - // 'framework' => 'other', - // 'name' => 'Test Site', - // 'outputDirectory' => './', - // 'providerBranch' => 'main', - // 'providerRootDirectory' => './', - // '$id' => $siteId, - // 'specification' => 's-2vcpu-512mb', // Invalid specification - // ]); + $site = $this->updateSite([ + 'buildRuntime' => 'ssr-22', + 'fallbackFile' => null, + 'framework' => 'other', + 'name' => 'Test Site', + 'outputDirectory' => './', + 'providerBranch' => 'main', + 'providerRootDirectory' => './', + '$id' => $siteId, + 'specification' => 's-2vcpu-512mb', // Invalid specification + ]); - // var_dump($site); + $this->assertEquals(400, $site['headers']['status-code']); + $this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $site['body']['message']); - // $this->assertEquals(400, $site['headers']['status-code']); - // $this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $site['body']['message']); - - // $this->cleanupSite($siteId); - // } + $this->cleanupSite($siteId); + } public function testDeleteDeployment(): void { @@ -953,4 +938,6 @@ class SitesCustomServerTest extends Scope $this->assertArrayHasKey('runtimes', $framework); $this->assertArrayHasKey('adapters', $framework); } + + // TODO: Add tests for deletion of resources when site is deleted }