diff --git a/.env b/.env index 42c23ac87f..76af83a946 100644 --- a/.env +++ b/.env @@ -85,8 +85,9 @@ _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 -_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.32 +_APP_BROWSER_HOST=http://appwrite-browser:3000/v1 +_APP_FUNCTIONS_RUNTIMES=node-22 +_APP_SITES_RUNTIMES=static-1,node-22 _APP_MAINTENANCE_INTERVAL=86400 _APP_MAINTENANCE_START_TIME=12:00 _APP_MAINTENANCE_RETENTION_CACHE=2592000 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a69e11b892..57a1a1aefa 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -178,6 +178,7 @@ jobs: - name: Load and Start Appwrite run: | docker load --input /tmp/${{ env.IMAGE }}.tar + sed -i 's/_APP_BROWSER_HOST=http:\/\/appwrite-browser:3000\/v1/_APP_BROWSER_HOST=http:\/\/invalid-browser\/v1/' .env docker compose up -d sleep 30 @@ -198,7 +199,7 @@ jobs: docker compose exec -T \ -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ - appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys + appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys screenshots e2e_shared_mode_test: name: E2E Shared Mode Service Test @@ -277,7 +278,7 @@ jobs: docker compose exec -T \ -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ - appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys + appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys screenshots e2e_dev_keys: name: E2E Service Test (Dev Keys) @@ -358,3 +359,85 @@ jobs: -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys + + e2e_screenshots_keys: + name: E2E Service Test (Site Screenshots) + runs-on: ubuntu-latest + needs: setup + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: Load Cache + uses: actions/cache@v4 + with: + key: ${{ env.CACHE_KEY }} + path: /tmp/${{ env.IMAGE }}.tar + fail-on-cache-miss: true + + - name: Load and Start Appwrite + run: | + docker load --input /tmp/${{ env.IMAGE }}.tar + sed -i 's/_APP_OPTIONS_ABUSE=disabled/_APP_OPTIONS_ABUSE=enabled/' .env + docker compose up -d + sleep 30 + + - name: Run Site tests with browser connected in dedicated table mode + run: | + echo "Keeping original value of _APP_BROWSER_HOST" + echo "Using project tables" + export _APP_DATABASE_SHARED_TABLES= + export _APP_DATABASE_SHARED_TABLES_V1= + + docker compose exec -T \ + -e _APP_DATABASE_SHARED_TABLES \ + -e _APP_DATABASE_SHARED_TABLES_V1 \ + appwrite test /usr/src/code/tests/e2e/Services/Sites --debug --group=screenshots + + e2e_screenshots_shared_mode: + name: E2E Shared Mode Service Test (Site Screenshots) + runs-on: ubuntu-latest + needs: [ setup, check_database_changes ] + if: needs.check_database_changes.outputs.database_changed == 'true' + strategy: + fail-fast: false + matrix: + tables-mode: [ + 'Shared V1', + 'Shared V2', + ] + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: Load Cache + uses: actions/cache@v4 + with: + key: ${{ env.CACHE_KEY }} + path: /tmp/${{ env.IMAGE }}.tar + fail-on-cache-miss: true + + - name: Load and Start Appwrite + run: | + docker load --input /tmp/${{ env.IMAGE }}.tar + sed -i 's/_APP_OPTIONS_ABUSE=disabled/_APP_OPTIONS_ABUSE=enabled/' .env + docker compose up -d + sleep 30 + + - name: Run Site tests with browser connected in ${{ matrix.tables-mode }} table mode + run: | + echo "Keeping original value of _APP_BROWSER_HOST" + if [ "${{ matrix.tables-mode }}" == "Shared V1" ]; then + echo "Using shared tables V1" + export _APP_DATABASE_SHARED_TABLES=database_db_main + export _APP_DATABASE_SHARED_TABLES_V1=database_db_main + elif [ "${{ matrix.tables-mode }}" == "Shared V2" ]; then + echo "Using shared tables V2" + export _APP_DATABASE_SHARED_TABLES=database_db_main + export _APP_DATABASE_SHARED_TABLES_V1= + fi + + docker compose exec -T \ + -e _APP_DATABASE_SHARED_TABLES \ + -e _APP_DATABASE_SHARED_TABLES_V1 \ + appwrite test /usr/src/code/tests/e2e/Services/Sites --debug --group=screenshots diff --git a/app/controllers/mock.php b/app/controllers/mock.php index fd7b9ab495..0684e5294a 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -129,32 +129,6 @@ App::get('/v1/mock/tests/general/oauth2/failure') ]); }); -App::patch('/v1/mock/functions-v2') - ->desc('Update Function Version to V2 (outdated code syntax)') - ->groups(['mock', 'api', 'functions']) - ->label('scope', 'functions.write') - ->label('docs', false) - ->param('functionId', '', new UID(), 'Function ID.') - ->inject('response') - ->inject('dbForProject') - ->action(function (string $functionId, Response $response, Database $dbForProject) { - $isDevelopment = System::getEnv('_APP_ENV', 'development') === 'development'; - - if (!$isDevelopment) { - throw new Exception(Exception::GENERAL_NOT_IMPLEMENTED); - } - - $function = $dbForProject->getDocument('functions', $functionId); - - if ($function->isEmpty()) { - throw new Exception(Exception::FUNCTION_NOT_FOUND); - } - - $dbForProject->updateDocument('functions', $function->getId(), $function->setAttribute('version', 'v2')); - - $response->noContent(); - }); - App::post('/v1/mock/api-key-unprefixed') ->desc('Create API Key (without standard prefix)') ->groups(['mock', 'api', 'projects']) diff --git a/docker-compose.yml b/docker-compose.yml index a01165d949..ba23c4780c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -456,6 +456,7 @@ services: - redis - mariadb environment: + - _APP_BROWSER_HOST - _APP_ENV - _APP_WORKER_PER_CORE - _APP_OPENSSL_KEY_V1 @@ -977,7 +978,7 @@ services: - OPR_EXECUTOR_ENV=$_APP_ENV - OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES,$_APP_SITES_RUNTIMES - OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET - - OPR_EXECUTOR_RUNTIME_VERSIONS=v2,v5 + - OPR_EXECUTOR_RUNTIME_VERSIONS=v5 - OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG - OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE - OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index 25b3473829..adfc14abc8 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -959,8 +959,9 @@ class Builds extends Action $config['sleep'] = $framework['screenshotSleep']; } + $browserEndpoint = Config::getParam('_APP_BROWSER_HOST', 'http://appwrite-browser:3000/v1'); $fetchResponse = $client->fetch( - url: 'http://appwrite-browser:3000/v1/screenshots', + url: $browserEndpoint . '/screenshots', method: 'POST', body: $config ); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 6a8db0a88c..846ca37262 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -1461,49 +1461,6 @@ class FunctionsCustomServerTest extends Scope $this->cleanupFunction($functionId); } - public function testv2Function() - { - $functionId = $this->setupFunction([ - 'functionId' => ID::unique(), - 'name' => 'Test PHP V2', - 'runtime' => 'php-8.0', - 'entrypoint' => 'index.php', - 'events' => [], - 'timeout' => 15, - ]); - - $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', - ], [ - 'functionId' => $functionId - ]); - $this->assertEquals(204, $variable['headers']['status-code']); - - $this->setupDeployment($functionId, [ - 'entrypoint' => 'index.php', - 'code' => $this->packageFunction('php-v2'), - 'activate' => true - ]); - - $execution = $this->createExecution($functionId, [ - 'body' => 'foobar', - 'async' => 'false' - ]); - - $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); - } - public function testGetRuntimes() { $runtimes = $this->client->call(Client::METHOD_GET, '/functions/runtimes', array_merge([ diff --git a/tests/e2e/Services/Sites/SitesConsoleClientTest.php b/tests/e2e/Services/Sites/SitesConsoleClientTest.php index 1a84f46ed7..28ce2a35ec 100644 --- a/tests/e2e/Services/Sites/SitesConsoleClientTest.php +++ b/tests/e2e/Services/Sites/SitesConsoleClientTest.php @@ -14,6 +14,9 @@ class SitesConsoleClientTest extends Scope use SideConsole; use SitesBase; + /** + * @group screenshots + */ public function testSiteScreenshot(): void { $siteId = $this->setupSite([ diff --git a/tests/resources/functions/dart/main.dart b/tests/resources/functions/dart/main.dart deleted file mode 100644 index 1ed09c3485..0000000000 --- a/tests/resources/functions/dart/main.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:io' show Platform; - -Future main(final context) async { - context.log('Amazing Function Log'); - - response.json({ - 'APPWRITE_FUNCTION_ID' : Platform.environment['APPWRITE_FUNCTION_ID'] ?? '', - 'APPWRITE_FUNCTION_NAME' : Platform.environment['APPWRITE_FUNCTION_NAME'] ?? '', - 'APPWRITE_FUNCTION_DEPLOYMENT' : Platform.environment['APPWRITE_FUNCTION_DEPLOYMENT'] ?? '', - 'APPWRITE_FUNCTION_TRIGGER' : context.req.headers['x-appwrite-trigger'] ?? '', - 'APPWRITE_FUNCTION_RUNTIME_NAME' : Platform.environment['APPWRITE_FUNCTION_RUNTIME_NAME'] ?? '', - 'APPWRITE_FUNCTION_RUNTIME_VERSION' : Platform.environment['APPWRITE_FUNCTION_RUNTIME_VERSION'] ?? '', - 'APPWRITE_FUNCTION_EVENT' : context.req.headers['x-appwrite-event'] ?? '', - 'APPWRITE_FUNCTION_EVENT_DATA' : context.req.bodyRaw ?? '', - 'APPWRITE_FUNCTION_DATA' : context.req.bodyRaw ?? '', - 'APPWRITE_FUNCTION_USER_ID' : context.req.headers['x-appwrite-user-id'] ?? '', - 'APPWRITE_FUNCTION_JWT' : context.req.headers['x-appwrite-user-jwt'] ?? '', - 'APPWRITE_FUNCTION_PROJECT_ID' : Platform.environment['APPWRITE_FUNCTION_PROJECT_ID'] ?? '', - 'CUSTOM_VARIABLE' : request.variables['CUSTOM_VARIABLE'] - }); -} \ No newline at end of file diff --git a/tests/resources/functions/php-v2/index.php b/tests/resources/functions/php-v2/index.php deleted file mode 100644 index 2bf5d83304..0000000000 --- a/tests/resources/functions/php-v2/index.php +++ /dev/null @@ -1,7 +0,0 @@ -json([ - 'v2Woks' => true - ]); -}; diff --git a/tests/resources/functions/python/main.py b/tests/resources/functions/python/main.py deleted file mode 100644 index fda0b36f0e..0000000000 --- a/tests/resources/functions/python/main.py +++ /dev/null @@ -1,21 +0,0 @@ -import json -import os - -def main(context): - context.log('Amazing Function Log') - - return context.res.json({ - 'APPWRITE_FUNCTION_ID' : os.environ.get('APPWRITE_FUNCTION_ID',''), - 'APPWRITE_FUNCTION_NAME' : os.environ.get('APPWRITE_FUNCTION_NAME',''), - 'APPWRITE_FUNCTION_DEPLOYMENT' : os.environ.get('APPWRITE_FUNCTION_DEPLOYMENT',''), - 'APPWRITE_FUNCTION_TRIGGER' : context.req.headers.get('x-appwrite-trigger', ''), - 'APPWRITE_FUNCTION_RUNTIME_NAME' : os.environ.get('APPWRITE_FUNCTION_RUNTIME_NAME',''), - 'APPWRITE_FUNCTION_RUNTIME_VERSION' : os.environ.get('APPWRITE_FUNCTION_RUNTIME_VERSION',''), - 'APPWRITE_FUNCTION_EVENT' : context.req.headers.get('x-appwrite-event', ''), - 'APPWRITE_FUNCTION_EVENT_DATA' : context.req.body_raw, - 'APPWRITE_FUNCTION_DATA' : context.req.body_raw, - 'APPWRITE_FUNCTION_USER_ID' : context.req.headers.get('x-appwrite-user-id', ''), - 'APPWRITE_FUNCTION_JWT' : context.req.headers.get('x-appwrite-user-jwt', ''), - 'APPWRITE_FUNCTION_PROJECT_ID' : os.environ.get('APPWRITE_FUNCTION_PROJECT_ID',''), - 'CUSTOM_VARIABLE' : os.environ.get('CUSTOM_VARIABLE',''), - }) \ No newline at end of file diff --git a/tests/resources/functions/ruby/main.rb b/tests/resources/functions/ruby/main.rb deleted file mode 100644 index c14f591fa1..0000000000 --- a/tests/resources/functions/ruby/main.rb +++ /dev/null @@ -1,19 +0,0 @@ -def main(context) - context.log('Amazing Function Log') - - return context.res.json({ - 'APPWRITE_FUNCTION_ID' => ENV['APPWRITE_FUNCTION_ID'] || '', - 'APPWRITE_FUNCTION_NAME' => ENV['APPWRITE_FUNCTION_NAME'] || '', - 'APPWRITE_FUNCTION_DEPLOYMENT' => ENV['APPWRITE_FUNCTION_DEPLOYMENT'] || '', - 'APPWRITE_FUNCTION_TRIGGER' => context.req.headers['x-appwrite-trigger'] || '', - 'APPWRITE_FUNCTION_RUNTIME_NAME' => ENV['APPWRITE_FUNCTION_RUNTIME_NAME'] || '', - 'APPWRITE_FUNCTION_RUNTIME_VERSION' => ENV['APPWRITE_FUNCTION_RUNTIME_VERSION'] || '', - 'APPWRITE_FUNCTION_EVENT' => context.req.headers['x-appwrite-event'] || '', - 'APPWRITE_FUNCTION_EVENT_DATA' => context.req.body_raw || '', - 'APPWRITE_FUNCTION_DATA' => context.req.body_raw || '', - 'APPWRITE_FUNCTION_USER_ID' => context.req.headers['x-appwrite-user-id'] || '', - 'APPWRITE_FUNCTION_JWT' => context.req.headers['x-appwrite-user-jwt'] || '', - 'APPWRITE_FUNCTION_PROJECT_ID' => ENV['APPWRITE_FUNCTION_PROJECT_ID'] || '', - 'CUSTOM_VARIABLE' => ENV['CUSTOM_VARIABLE'] || '' - }) -end \ No newline at end of file diff --git a/tests/resources/functions/swift/index.swift b/tests/resources/functions/swift/index.swift deleted file mode 100644 index b3dcdbc91a..0000000000 --- a/tests/resources/functions/swift/index.swift +++ /dev/null @@ -1,17 +0,0 @@ -func main(req: RequestValue, res: RequestResponse) throws -> RequestResponse { - return res.json(data: [ - "APPWRITE_FUNCTION_ID": req.variables["APPWRITE_FUNCTION_ID"], - "APPWRITE_FUNCTION_NAME": req.variables["APPWRITE_FUNCTION_NAME"], - "APPWRITE_FUNCTION_DEPLOYMENT": req.variables["APPWRITE_FUNCTION_DEPLOYMENT"], - "APPWRITE_FUNCTION_TRIGGER": req.variables["APPWRITE_FUNCTION_TRIGGER"], - "APPWRITE_FUNCTION_RUNTIME_NAME": req.variables["APPWRITE_FUNCTION_RUNTIME_NAME"], - "APPWRITE_FUNCTION_RUNTIME_VERSION": req.variables["APPWRITE_FUNCTION_RUNTIME_VERSION"], - "APPWRITE_FUNCTION_EVENT": req.variables["APPWRITE_FUNCTION_EVENT"], - "APPWRITE_FUNCTION_EVENT_DATA": req.variables["APPWRITE_FUNCTION_EVENT_DATA"], - "APPWRITE_FUNCTION_DATA": req.variables["APPWRITE_FUNCTION_DATA"], - "APPWRITE_FUNCTION_USER_ID": req.variables["APPWRITE_FUNCTION_USER_ID"], - "APPWRITE_FUNCTION_JWT": req.variables["APPWRITE_FUNCTION_JWT"], - "APPWRITE_FUNCTION_PROJECT_ID": req.variables["APPWRITE_FUNCTION_PROJECT_ID"], - "CUSTOM_VARIABLE": req.variables["CUSTOM_VARIABLE"] - ]) -} \ No newline at end of file