From 3092e765cc9c82b66deec4c844f432a5e72d4d76 Mon Sep 17 00:00:00 2001 From: fogelito Date: Sun, 9 Feb 2025 18:34:41 +0200 Subject: [PATCH 01/33] indexException --- app/controllers/api/databases.php | 18 ++++++++++++ composer.lock | 46 +++++++++++++++---------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index df46c1890b..8b2369ee15 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -377,6 +377,19 @@ function updateAttribute( $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId()); } } else { + + $validator = new IndexValidator( + $collection->getAttribute('attributes', []), + $dbForProject->getAdapter()->getMaxIndexLength(), + $dbForProject->getAdapter()->getInternalIndexesKeys(), + ); + + foreach ($collection->getAttribute('indexes', []) as $index){ + if (!$validator->isValid($index)) { + throw new Exception(Exception::INDEX_INVALID, $validator->getDescription()); + } + } + try { $dbForProject->updateAttribute( collection: $collectionId, @@ -393,6 +406,11 @@ function updateAttribute( throw new Exception(Exception::ATTRIBUTE_NOT_FOUND); } catch (LimitException) { throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED); + } catch (indexException $e) { + /** + * We do not have index indexException thrown from Utopia... + */ + throw new Exception(Exception::INDEX_INVALID, $e->getDescription()); } } diff --git a/composer.lock b/composer.lock index f3075c1801..a65fabb429 100644 --- a/composer.lock +++ b/composer.lock @@ -1237,16 +1237,16 @@ }, { "name": "open-telemetry/api", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/api.git", - "reference": "74b1a03263be8c5acb578f41da054b4bac3af4a0" + "reference": "8b925df3047628968bc5be722468db1b98b82d51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/74b1a03263be8c5acb578f41da054b4bac3af4a0", - "reference": "74b1a03263be8c5acb578f41da054b4bac3af4a0", + "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/8b925df3047628968bc5be722468db1b98b82d51", + "reference": "8b925df3047628968bc5be722468db1b98b82d51", "shasum": "" }, "require": { @@ -1303,7 +1303,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2025-01-20T23:35:16+00:00" + "time": "2025-02-03T21:49:11+00:00" }, { "name": "open-telemetry/context", @@ -1493,16 +1493,16 @@ }, { "name": "open-telemetry/sdk", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/sdk.git", - "reference": "96aeaee5b7cb8c0bc4af7ff4717b429f2d9f67e1" + "reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/96aeaee5b7cb8c0bc4af7ff4717b429f2d9f67e1", - "reference": "96aeaee5b7cb8c0bc4af7ff4717b429f2d9f67e1", + "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/37eec0fe47ddd627911f318f29b6cd48196be0c0", + "reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0", "shasum": "" }, "require": { @@ -1579,24 +1579,24 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2025-01-09T23:17:14+00:00" + "time": "2025-01-29T21:40:28+00:00" }, { "name": "open-telemetry/sem-conv", - "version": "1.27.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/sem-conv.git", - "reference": "1dba705fea74bc0718d04be26090e3697e56f4e6" + "reference": "4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/1dba705fea74bc0718d04be26090e3697e56f4e6", - "reference": "1dba705fea74bc0718d04be26090e3697e56f4e6", + "url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a", + "reference": "4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.0" }, "type": "library", "extra": { @@ -1636,7 +1636,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-08-28T09:20:31+00:00" + "time": "2025-02-06T00:21:48+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -2453,16 +2453,16 @@ }, { "name": "symfony/http-client", - "version": "v7.2.2", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "339ba21476eb184290361542f732ad12c97591ec" + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/339ba21476eb184290361542f732ad12c97591ec", - "reference": "339ba21476eb184290361542f732ad12c97591ec", + "url": "https://api.github.com/repos/symfony/http-client/zipball/7ce6078c79a4a7afff931c413d2959d3bffbfb8d", + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d", "shasum": "" }, "require": { @@ -2528,7 +2528,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.2.2" + "source": "https://github.com/symfony/http-client/tree/v7.2.3" }, "funding": [ { @@ -2544,7 +2544,7 @@ "type": "tidelift" } ], - "time": "2024-12-30T18:35:15+00:00" + "time": "2025-01-28T15:51:35+00:00" }, { "name": "symfony/http-client-contracts", @@ -8503,7 +8503,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 5b786e2a688da15bbd840fb80a06621dba42c4a8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 09:19:56 +0200 Subject: [PATCH 02/33] Catch index exception --- app/controllers/general.php | 3 +++ composer.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 7e691d033f..d9d41a16fd 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -837,6 +837,9 @@ App::error() case 'Utopia\Database\Exception\Dependency': $error = new AppwriteException(AppwriteException::INDEX_DEPENDENCY, null, previous: $error); break; + case 'Utopia\Database\Exception\Index': + $error = new AppwriteException(AppwriteException::INDEX_INVALID, $error->getMessage(), previous: $error); + break; } $code = $error->getCode(); diff --git a/composer.json b/composer.json index 8f5bb54f79..d0b457b6bd 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.56.4", + "utopia-php/database": "dev-index-exception as 0.56.4", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From 27709e7683d3505ba442fca537352db24be734da Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:04:51 +0200 Subject: [PATCH 03/33] IndexException --- app/controllers/api/databases.php | 8 +++----- composer.json | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 8b2369ee15..c0357ceac1 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -27,6 +27,7 @@ use Utopia\Database\Document; use Utopia\Database\Exception\Authorization as AuthorizationException; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Duplicate as DuplicateException; +use Utopia\Database\Exception\Index as IndexException; use Utopia\Database\Exception\Limit as LimitException; use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Query as QueryException; @@ -384,7 +385,7 @@ function updateAttribute( $dbForProject->getAdapter()->getInternalIndexesKeys(), ); - foreach ($collection->getAttribute('indexes', []) as $index){ + foreach ($collection->getAttribute('indexes', []) as $index) { if (!$validator->isValid($index)) { throw new Exception(Exception::INDEX_INVALID, $validator->getDescription()); } @@ -407,10 +408,7 @@ function updateAttribute( } catch (LimitException) { throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED); } catch (indexException $e) { - /** - * We do not have index indexException thrown from Utopia... - */ - throw new Exception(Exception::INDEX_INVALID, $e->getDescription()); + throw new Exception(Exception::INDEX_INVALID, $e->getMessage()); } } diff --git a/composer.json b/composer.json index d0b457b6bd..8f5bb54f79 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-index-exception as 0.56.4", + "utopia-php/database": "0.56.4", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", From a032540b3c5676e83322ff64d9b93ce6b51b3d36 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:11:52 +0200 Subject: [PATCH 04/33] IndexException --- app/controllers/api/databases.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index c0357ceac1..4d62c9c384 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -378,19 +378,6 @@ function updateAttribute( $dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId()); } } else { - - $validator = new IndexValidator( - $collection->getAttribute('attributes', []), - $dbForProject->getAdapter()->getMaxIndexLength(), - $dbForProject->getAdapter()->getInternalIndexesKeys(), - ); - - foreach ($collection->getAttribute('indexes', []) as $index) { - if (!$validator->isValid($index)) { - throw new Exception(Exception::INDEX_INVALID, $validator->getDescription()); - } - } - try { $dbForProject->updateAttribute( collection: $collectionId, From edbe0fb72ff58f721c32f66f53dbcf931cf01490 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:40:12 +0200 Subject: [PATCH 05/33] Bump Database version 0.58.5 --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index fe3400cfe5..b7c3711410 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.58.4", + "utopia-php/database": "0.58.5", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index 87ee9979ae..e653783ef5 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": "232691925e05350c7a3831a4e43d79d1", + "content-hash": "4a54d0bd5973ed68082970f317664df3", "packages": [ { "name": "adhocore/jwt", @@ -3717,16 +3717,16 @@ }, { "name": "utopia-php/database", - "version": "0.58.4", + "version": "0.58.5", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "ff3fd22e4fe757cc2a78f17169f6dcc45c96d0fe" + "reference": "55308014c697639c6cb270cb5a33cc88fc1ef839" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/ff3fd22e4fe757cc2a78f17169f6dcc45c96d0fe", - "reference": "ff3fd22e4fe757cc2a78f17169f6dcc45c96d0fe", + "url": "https://api.github.com/repos/utopia-php/database/zipball/55308014c697639c6cb270cb5a33cc88fc1ef839", + "reference": "55308014c697639c6cb270cb5a33cc88fc1ef839", "shasum": "" }, "require": { @@ -3767,9 +3767,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.58.4" + "source": "https://github.com/utopia-php/database/tree/0.58.5" }, - "time": "2025-02-05T02:51:02+00:00" + "time": "2025-02-10T08:26:52+00:00" }, { "name": "utopia-php/domains", From 33f55c73a7148dae168af76c8e1184e9491e5e52 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:42:29 +0200 Subject: [PATCH 06/33] Revert cast Index --- app/controllers/general.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index d9d41a16fd..7e691d033f 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -837,9 +837,6 @@ App::error() case 'Utopia\Database\Exception\Dependency': $error = new AppwriteException(AppwriteException::INDEX_DEPENDENCY, null, previous: $error); break; - case 'Utopia\Database\Exception\Index': - $error = new AppwriteException(AppwriteException::INDEX_INVALID, $error->getMessage(), previous: $error); - break; } $code = $error->getCode(); From 7caab2f9ff5ae9b56b4c583ea235d13c12b4d7aa Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 10:55:37 +0200 Subject: [PATCH 07/33] IndexException --- 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 4d62c9c384..1e0fa03d2c 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -394,7 +394,7 @@ function updateAttribute( throw new Exception(Exception::ATTRIBUTE_NOT_FOUND); } catch (LimitException) { throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED); - } catch (indexException $e) { + } catch (IndexException $e) { throw new Exception(Exception::INDEX_INVALID, $e->getMessage()); } } From 7a8688932c86097de2dc092fea254dae8d976bb1 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 15:40:21 +0200 Subject: [PATCH 08/33] Add test --- .../e2e/Services/Databases/DatabasesBase.php | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index d079cb313c..adc31a391d 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -399,6 +399,73 @@ trait DatabasesBase $this->assertEquals(400, $response['headers']['status-code']); } + /** + * @depends testCreateDatabase + */ + public function testPatchAttribute(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' => ID::unique(), + 'name' => 'patch', + 'documentSecurity' => true, + 'permissions' => [ + Permission::create(Role::user($this->getUser()['$id'])), + ], + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + $this->assertEquals($collection['body']['name'], 'patch'); + + $attribute = $this->client->call(Client::METHOD_POST, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'required' => true, + 'size' => 100, + ]); + $this->assertEquals(202, $attribute['headers']['status-code']); + $this->assertEquals($attribute['body']['size'], 100); + + sleep(1); + + $index = $this->client->call(Client::METHOD_POST, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/indexes', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'titleIndex', + 'type' => 'key', + 'attributes' => ['title'], + ]); + $this->assertEquals(202, $index['headers']['status-code']); + + sleep(1); + + /** + * Update attribute size to exceed Index maximux length + */ + $attribute = $this->client->call(Client::METHOD_PATCH, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/attributes/string/'.$attribute['body']['key'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), [ + 'size' => 1000, + 'required' => true, + 'default' => null, + ]); + + $this->assertEquals(400, $attribute['headers']['status-code']); + $this->assertEquals('Index length is longer than the maximum: 768', $attribute['body']['message']); + } + public function testUpdateAttributeEnum(): void { $database = $this->client->call(Client::METHOD_POST, '/databases', [ From 8c3a243a5d3365d95653b2ba61cde92fe35e769a Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 10 Feb 2025 15:40:45 +0200 Subject: [PATCH 09/33] Typo --- 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 adc31a391d..3321a786a7 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -450,7 +450,7 @@ trait DatabasesBase sleep(1); /** - * Update attribute size to exceed Index maximux length + * Update attribute size to exceed Index maximum length */ $attribute = $this->client->call(Client::METHOD_PATCH, '/databases/'.$databaseId.'/collections/'.$collection['body']['$id'].'/attributes/string/'.$attribute['body']['key'], array_merge([ 'content-type' => 'application/json', From abaa5c7f489910d3d8d4df7bb5b0f47e5c02df51 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 11 Feb 2025 22:26:39 +1300 Subject: [PATCH 10/33] Only run shared tables tests if database library version changed compared to base --- .github/workflows/tests.yml | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5b7438de42..e0213ea46e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,6 +11,30 @@ env: on: [pull_request] jobs: + check_database_changes: + name: Check if utopia-php/database changed + runs-on: ubuntu-latest + outputs: + database_changed: ${{ steps.check.outputs.database_changed }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Fetch base branch + run: git fetch origin ${{ github.event.pull_request.base.ref }} + + - name: Check for utopia-php/database changes + id: check + run: | + if git diff origin/${{ github.event.pull_request.base.ref }} HEAD -- composer.lock | grep -q '"name": "utopia-php/database"'; then + echo "Database version changed, going to run all mode tests." + echo "database_changed=true" >> "$GITHUB_ENV" + echo "database_changed=true" >> "$GITHUB_OUTPUT" + else + echo "database_changed=false" >> "$GITHUB_ENV" + echo "database_changed=false" >> "$GITHUB_OUTPUT" + fi + setup: name: Setup & Build Appwrite Image runs-on: ubuntu-latest @@ -102,7 +126,7 @@ jobs: e2e_service_test: name: E2E Service Test runs-on: ubuntu-latest - needs: setup + needs: [setup, check_database_changes] strategy: fail-fast: false matrix: @@ -151,6 +175,8 @@ jobs: sleep 30 - name: Run ${{ matrix.service }} tests with ${{ matrix.tables-mode }} table mode + if: | + matrix.tables-mode == 'Project' || needs.check_database_changes.outputs.database_changed == 'true' run: | if [ "${{ matrix.tables-mode }}" == "Shared V1" ]; then echo "Using shared tables V1" @@ -165,7 +191,7 @@ jobs: export _APP_DATABASE_SHARED_TABLES= export _APP_DATABASE_SHARED_TABLES_V1= fi - + docker compose exec -T \ -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ @@ -251,4 +277,4 @@ jobs: comment-id: ${{ steps.fc.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} body-path: benchmark.txt - edit-mode: replace \ No newline at end of file + edit-mode: replace From 61e65e1edaa7aba380fad5091f98f2be23eb7f5b Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 11 Feb 2025 22:37:57 +1300 Subject: [PATCH 11/33] Skip shared jobs entirely --- .github/workflows/tests.yml | 67 ++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e0213ea46e..1d35fec3c7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,7 +8,7 @@ env: IMAGE: appwrite-dev CACHE_KEY: appwrite-dev-${{ github.event.pull_request.head.sha }} -on: [pull_request] +on: [ pull_request ] jobs: check_database_changes: @@ -126,7 +126,63 @@ jobs: e2e_service_test: name: E2E Service Test runs-on: ubuntu-latest - needs: [setup, check_database_changes] + needs: setup + strategy: + fail-fast: false + matrix: + service: [ + Account, + Avatars, + Console, + Databases, + Functions, + FunctionsSchedule, + GraphQL, + Health, + Locale, + Projects, + Realtime, + Storage, + Teams, + Users, + Webhooks, + VCS, + Messaging, + Migrations + ] + steps: + - name: Checkout repository + 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 + docker compose up -d + sleep 30 + + - name: Run ${{ matrix.service }} tests with Project table mode + run: | + 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/${{ matrix.service }} --debug + + e2e_shared_mode_test: + name: E2E Shared Mode Service Test + runs-on: ubuntu-latest + needs: [ setup, check_database_changes ] + if: needs.check_database_changes.outputs.database_changed == 'true' strategy: fail-fast: false matrix: @@ -152,7 +208,6 @@ jobs: Migrations ] tables-mode: [ - 'Project', 'Shared V1', 'Shared V2', ] @@ -175,8 +230,6 @@ jobs: sleep 30 - name: Run ${{ matrix.service }} tests with ${{ matrix.tables-mode }} table mode - if: | - matrix.tables-mode == 'Project' || needs.check_database_changes.outputs.database_changed == 'true' run: | if [ "${{ matrix.tables-mode }}" == "Shared V1" ]; then echo "Using shared tables V1" @@ -186,10 +239,6 @@ jobs: echo "Using shared tables V2" export _APP_DATABASE_SHARED_TABLES=database_db_main export _APP_DATABASE_SHARED_TABLES_V1= - else - echo "Using project tables" - export _APP_DATABASE_SHARED_TABLES= - export _APP_DATABASE_SHARED_TABLES_V1= fi docker compose exec -T \ From f2ae6e07cb795db71bed614ffd3294befa55d7c9 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Mon, 10 Feb 2025 13:12:13 +0100 Subject: [PATCH 12/33] feat(builds): check if function is blocked before building --- src/Appwrite/Platform/Workers/Builds.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index e7cbbd5088..0f81c36b72 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -54,8 +54,10 @@ class Builds extends Action ->inject('cache') ->inject('dbForProject') ->inject('deviceForFunctions') + ->inject('isResourceBlocked') ->inject('log') - ->callback(fn ($message, Document $project, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, StatsUsage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log) => $this->action($message, $project, $dbForPlatform, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $log)); + ->callback(fn ($message, Document $project, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, StatsUsage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log) => + $this->action($message, $project, $dbForPlatform, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $isResourceBlocked, $log)); } /** @@ -72,7 +74,7 @@ class Builds extends Action * @return void * @throws \Utopia\Database\Exception */ - public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, StatsUsage $queueForStatsUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log): void + public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, StatsUsage $queueForStatsUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log): void { $payload = $message->getPayload() ?? []; @@ -93,7 +95,7 @@ class Builds extends Action case BUILD_TYPE_RETRY: Console::info('Creating build for deployment: ' . $deployment->getId()); $github = new GitHub($cache); - $this->buildDeployment($deviceForFunctions, $queueForFunctions, $queueForEvents, $queueForStatsUsage, $dbForPlatform, $dbForProject, $github, $project, $resource, $deployment, $template, $log); + $this->buildDeployment($deviceForFunctions, $queueForFunctions, $queueForEvents, $queueForStatsUsage, $dbForPlatform, $dbForProject, $github, $project, $resource, $deployment, $template, $isResourceBlocked, $log); break; default: @@ -118,7 +120,7 @@ class Builds extends Action * @throws \Utopia\Database\Exception * @throws Exception */ - protected function buildDeployment(Device $deviceForFunctions, Func $queueForFunctions, Event $queueForEvents, StatsUsage $queueForStatsUsage, Database $dbForPlatform, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, Log $log): void + protected function buildDeployment(Device $deviceForFunctions, Func $queueForFunctions, Event $queueForEvents, StatsUsage $queueForStatsUsage, Database $dbForPlatform, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, callable $isResourceBlocked, Log $log): void { $executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST')); @@ -130,6 +132,10 @@ class Builds extends Action throw new \Exception('Function not found', 404); } + if ($isResourceBlocked($project, RESOURCE_TYPE_FUNCTIONS, $functionId)) { + throw new \Exception('Function blocked', 403); + } + $deploymentId = $deployment->getId(); $log->addTag('deploymentId', $deploymentId); From 8324b789c5e533a709c5f6fbe7f0912620dd60f5 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Tue, 11 Feb 2025 11:00:28 +0100 Subject: [PATCH 13/33] chore(review): remove http status codes from exceptions --- src/Appwrite/Platform/Workers/Builds.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index 0f81c36b72..c21c28b517 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -129,11 +129,11 @@ class Builds extends Action $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new \Exception('Function not found', 404); + throw new \Exception('Function not found'); } if ($isResourceBlocked($project, RESOURCE_TYPE_FUNCTIONS, $functionId)) { - throw new \Exception('Function blocked', 403); + throw new \Exception('Function blocked'); } $deploymentId = $deployment->getId(); @@ -141,11 +141,11 @@ class Builds extends Action $deployment = $dbForProject->getDocument('deployments', $deploymentId); if ($deployment->isEmpty()) { - throw new \Exception('Deployment not found', 404); + throw new \Exception('Deployment not found'); } if (empty($deployment->getAttribute('entrypoint', ''))) { - throw new \Exception('Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".', 500); + throw new \Exception('Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".'); } $version = $function->getAttribute('version', 'v2'); @@ -577,7 +577,7 @@ class Builds extends Action $build = $dbForProject->getDocument('builds', $build->getId()); if ($build->isEmpty()) { - throw new \Exception('Build not found', 404); + throw new \Exception('Build not found'); } if ($build->getAttribute('status') === 'canceled') { From f6aff786f122010ffd5542090bb28d501719fb5d Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 11 Feb 2025 17:59:48 +0545 Subject: [PATCH 14/33] Fix: missing call for image transformations counting --- src/Appwrite/Platform/Workers/StatsResources.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index e3c76ecb9a..11e33417cc 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -159,6 +159,12 @@ class StatsResources extends Action } catch (Throwable $th) { call_user_func_array($this->logError, [$th, "StatsResources", "count_for_buckets_{$project->getId()}"]); } + + try { + $this->countImageTransformations($dbForProject, $dbForLogs, $region); + } catch (Throwable $th) { + call_user_func_array($this->logError, [$th, "StatsResources", "count_for_buckets_{$project->getId()}"]); + } try { $this->countForDatabase($dbForProject, $dbForLogs, $region); From 2189ca14697b62cfccc9c6b24c768b75e2a54548 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 11 Feb 2025 16:40:17 +0000 Subject: [PATCH 15/33] chore: linter --- composer.lock | 14 +++++++------- src/Appwrite/Platform/Workers/StatsResources.php | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index e653783ef5..2fcea6b3e5 100644 --- a/composer.lock +++ b/composer.lock @@ -4607,16 +4607,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.8", + "version": "0.18.9", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "84737afa634e6a833fc4f8b0c967553234d3f215" + "reference": "1cf455404e8700b3093fd73d74a38d41cdced90c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/84737afa634e6a833fc4f8b0c967553234d3f215", - "reference": "84737afa634e6a833fc4f8b0c967553234d3f215", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/1cf455404e8700b3093fd73d74a38d41cdced90c", + "reference": "1cf455404e8700b3093fd73d74a38d41cdced90c", "shasum": "" }, "require": { @@ -4656,9 +4656,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.8" + "source": "https://github.com/utopia-php/storage/tree/0.18.9" }, - "time": "2024-12-04T08:30:35+00:00" + "time": "2025-02-11T13:10:40+00:00" }, { "name": "utopia-php/swoole", @@ -8747,7 +8747,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index 11e33417cc..0ab6485953 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -159,7 +159,7 @@ class StatsResources extends Action } catch (Throwable $th) { call_user_func_array($this->logError, [$th, "StatsResources", "count_for_buckets_{$project->getId()}"]); } - + try { $this->countImageTransformations($dbForProject, $dbForLogs, $region); } catch (Throwable $th) { From e394532bcda0de2e6bb3dafacfc03a26f2cda83d Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 12 Feb 2025 17:03:37 +1300 Subject: [PATCH 16/33] Fix drop abuse on shared table project delete --- src/Appwrite/Platform/Workers/Deletes.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 46ae480684..08c6fc1b72 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -7,6 +7,7 @@ use Appwrite\Certificates\Adapter as CertificatesAdapter; use Appwrite\Extend\Exception; use Executor\Executor; use Throwable; +use Utopia\Abuse\Adapters\TimeLimit\Database as AbuseDatabase; use Utopia\Audit\Audit; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; @@ -505,7 +506,8 @@ class Deletes extends Action $projectCollectionIds = [ ...\array_keys(Config::getParam('collections', [])['projects']), - Audit::COLLECTION + Audit::COLLECTION, + AbuseDatabase::COLLECTION, ]; $limit = \count($projectCollectionIds) + 25; From 00473d47440f6779f7579ec80ccca15941c7d584 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 10:57:43 +0530 Subject: [PATCH 17/33] feat: batch create abuse logs --- .cursorignore | 7 +++ composer.json | 2 +- composer.lock | 18 +++---- src/Appwrite/Platform/Workers/Audits.php | 60 +++++++++++++++++++----- 4 files changed, 65 insertions(+), 22 deletions(-) create mode 100644 .cursorignore diff --git a/.cursorignore b/.cursorignore new file mode 100644 index 0000000000..95ce4247a6 --- /dev/null +++ b/.cursorignore @@ -0,0 +1,7 @@ +docs/* +public/* +vendor/* +dev/* +.vscode/* +app/assets/* +app/sdks/* \ No newline at end of file diff --git a/composer.json b/composer.json index b7c3711410..6e25f5f912 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "0.49.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.49.*", + "utopia-php/audit": "dev-add-batch-logging-method", "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", diff --git a/composer.lock b/composer.lock index 2fcea6b3e5..e77db78d2f 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": "4a54d0bd5973ed68082970f317664df3", + "content-hash": "9b7ba7990ac224daffbe50b377bacb0a", "packages": [ { "name": "adhocore/jwt", @@ -3474,16 +3474,16 @@ }, { "name": "utopia-php/audit", - "version": "0.49.0", + "version": "dev-add-batch-logging-method", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "9d5c5e0cf0f6d9157b911fc3971da4331d71c96d" + "reference": "41d87370f1559656c8695d8376d6ac8406c5bd8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/9d5c5e0cf0f6d9157b911fc3971da4331d71c96d", - "reference": "9d5c5e0cf0f6d9157b911fc3971da4331d71c96d", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/41d87370f1559656c8695d8376d6ac8406c5bd8e", + "reference": "41d87370f1559656c8695d8376d6ac8406c5bd8e", "shasum": "" }, "require": { @@ -3515,9 +3515,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.49.0" + "source": "https://github.com/utopia-php/audit/tree/add-batch-logging-method" }, - "time": "2025-02-04T07:27:18+00:00" + "time": "2025-02-12T05:16:50+00:00" }, { "name": "utopia-php/cache", @@ -8747,7 +8747,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "utopia-php/audit": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index c0bcab1c3a..795900f9da 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -15,6 +15,11 @@ use Utopia\Queue\Message; class Audits extends Action { + private const BATCH_SIZE = 5_000; + private const BATCH_TIME_WINDOW = 60; + + private static array $pendingEvents = []; + public static function getName(): string { return 'audits'; @@ -44,7 +49,6 @@ class Audits extends Action */ public function action(Message $message, Database $dbForProject): void { - $payload = $message->getPayload() ?? []; if (empty($payload)) { @@ -63,23 +67,53 @@ class Audits extends Action $userEmail = $user->getAttribute('email', ''); $userType = $user->getAttribute('type', Auth::ACTIVITY_TYPE_USER); - $audit = new Audit($dbForProject); - $audit->log( - userId: $user->getInternalId(), - // Pass first, most verbose event pattern - event: $event, - resource: $resource, - userAgent: $userAgent, - ip: $ip, - location: '', - data: [ + // Create event data + $eventData = [ + 'userId' => $user->getInternalId(), + 'event' => $event, + 'resource' => $resource, + 'userAgent' => $userAgent, + 'ip' => $ip, + 'location' => '', + 'data' => [ 'userId' => $user->getId(), 'userName' => $userName, 'userEmail' => $userEmail, 'userType' => $userType, 'mode' => $mode, 'data' => $auditPayload, - ] - ); + ], + 'timestamp' => time() + ]; + + self::$pendingEvents[] = $eventData; + + // Check if we should process the batch by checking both for the batch size and the elapsed time + $shouldProcessBatch = count(self::$pendingEvents) >= self::BATCH_SIZE; + if (!$shouldProcessBatch && count(self::$pendingEvents) > 0) { + $oldestEventTime = self::$pendingEvents[0]['timestamp']; + $shouldProcessBatch = (time() - $oldestEventTime) >= self::BATCH_TIME_WINDOW; + } + + if ($shouldProcessBatch) { + $audit = new Audit($dbForProject); + $batchEvents = array_map(function($event) { + return [ + 'userId' => $event['userId'], + 'event' => $event['event'], + 'resource' => $event['resource'], + 'userAgent' => $event['userAgent'], + 'ip' => $event['ip'], + 'location' => $event['location'], + 'data' => $event['data'], + 'timestamp' => $event['timestamp'] + ]; + }, self::$pendingEvents); + + $audit->logByBatch($batchEvents); + + // Clear the pending events after successful batch processing + self::$pendingEvents = []; + } } } From df27e8950bfb43fe379ddfc8a15e649582d4afa1 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 11:02:29 +0530 Subject: [PATCH 18/33] feat: update composer --- .cursorignore | 7 ------- composer.json | 2 +- composer.lock | 18 ++++++++---------- src/Appwrite/Platform/Workers/Audits.php | 2 +- 4 files changed, 10 insertions(+), 19 deletions(-) delete mode 100644 .cursorignore diff --git a/.cursorignore b/.cursorignore deleted file mode 100644 index 95ce4247a6..0000000000 --- a/.cursorignore +++ /dev/null @@ -1,7 +0,0 @@ -docs/* -public/* -vendor/* -dev/* -.vscode/* -app/assets/* -app/sdks/* \ No newline at end of file diff --git a/composer.json b/composer.json index 6e25f5f912..58b74c3fe3 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "0.49.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "dev-add-batch-logging-method", + "utopia-php/audit": "0.50.*", "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", diff --git a/composer.lock b/composer.lock index e77db78d2f..fd89ba3ae8 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": "9b7ba7990ac224daffbe50b377bacb0a", + "content-hash": "884381b7cc6c225f83c397eb472ddf11", "packages": [ { "name": "adhocore/jwt", @@ -3474,16 +3474,16 @@ }, { "name": "utopia-php/audit", - "version": "dev-add-batch-logging-method", + "version": "0.50.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "41d87370f1559656c8695d8376d6ac8406c5bd8e" + "reference": "c0da7dcdd35fc7d3f9640ba21cc82607cf7da729" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/41d87370f1559656c8695d8376d6ac8406c5bd8e", - "reference": "41d87370f1559656c8695d8376d6ac8406c5bd8e", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/c0da7dcdd35fc7d3f9640ba21cc82607cf7da729", + "reference": "c0da7dcdd35fc7d3f9640ba21cc82607cf7da729", "shasum": "" }, "require": { @@ -3515,9 +3515,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/add-batch-logging-method" + "source": "https://github.com/utopia-php/audit/tree/0.50.0" }, - "time": "2025-02-12T05:16:50+00:00" + "time": "2025-02-12T05:30:25+00:00" }, { "name": "utopia-php/cache", @@ -8747,9 +8747,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/audit": 20 - }, + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 795900f9da..d7b446ab5d 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -110,7 +110,7 @@ class Audits extends Action ]; }, self::$pendingEvents); - $audit->logByBatch($batchEvents); + $audit->logBatch($batchEvents); // Clear the pending events after successful batch processing self::$pendingEvents = []; From 7f706fce5dd6f962163ec8252487065c2b30dcc6 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 11:09:24 +0530 Subject: [PATCH 19/33] feat: linter & console logs --- src/Appwrite/Platform/Workers/Audits.php | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index d7b446ab5d..8848d03645 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -6,6 +6,7 @@ use Appwrite\Auth\Auth; use Exception; use Throwable; use Utopia\Audit\Audit; +use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; @@ -18,7 +19,7 @@ class Audits extends Action private const BATCH_SIZE = 5_000; private const BATCH_TIME_WINDOW = 60; - private static array $pendingEvents = []; + private static array $logs = []; public static function getName(): string { @@ -55,6 +56,8 @@ class Audits extends Action throw new Exception('Missing payload'); } + Console::info('Aggregating audit logs'); + $event = $payload['event'] ?? ''; $auditPayload = $payload['payload'] ?? ''; $mode = $payload['mode'] ?? ''; @@ -86,18 +89,20 @@ class Audits extends Action 'timestamp' => time() ]; - self::$pendingEvents[] = $eventData; + self::$logs[] = $eventData; // Check if we should process the batch by checking both for the batch size and the elapsed time - $shouldProcessBatch = count(self::$pendingEvents) >= self::BATCH_SIZE; - if (!$shouldProcessBatch && count(self::$pendingEvents) > 0) { - $oldestEventTime = self::$pendingEvents[0]['timestamp']; + $shouldProcessBatch = count(self::$logs) >= self::BATCH_SIZE; + if (!$shouldProcessBatch && count(self::$logs) > 0) { + $oldestEventTime = self::$logs[0]['timestamp']; $shouldProcessBatch = (time() - $oldestEventTime) >= self::BATCH_TIME_WINDOW; } if ($shouldProcessBatch) { + Console::log('Processing batch with ' . count(self::$logs) . ' events'); + $audit = new Audit($dbForProject); - $batchEvents = array_map(function($event) { + $batchEvents = array_map(function ($event) { return [ 'userId' => $event['userId'], 'event' => $event['event'], @@ -108,12 +113,14 @@ class Audits extends Action 'data' => $event['data'], 'timestamp' => $event['timestamp'] ]; - }, self::$pendingEvents); + }, self::$logs); $audit->logBatch($batchEvents); - + // Clear the pending events after successful batch processing - self::$pendingEvents = []; + self::$logs = []; + + Console::success('Audit logs processed successfully'); } } } From 978284b36fe6934c62993c9736ba7639fbb49e35 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 11:33:17 +0530 Subject: [PATCH 20/33] feat: use smaller batch size on development environments --- src/Appwrite/Platform/Workers/Audits.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 8848d03645..bdd3f942e1 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -8,19 +8,29 @@ use Throwable; use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Database\Database; +use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Structure; use Utopia\Platform\Action; use Utopia\Queue\Message; +use Utopia\System\System; class Audits extends Action { - private const BATCH_SIZE = 5_000; - private const BATCH_TIME_WINDOW = 60; + private const BATCH_SIZE_DEVELOPMENT = 1; // smaller batch size for development + private const BATCH_SIZE_PRODUCTION = 5_000; + private const BATCH_AGGREGATION_INTERVAL = 60; private static array $logs = []; + private function getBatchSize(): int + { + return System::getEnv('_APP_ENV', 'development') === 'development' + ? self::BATCH_SIZE_DEVELOPMENT + : self::BATCH_SIZE_PRODUCTION; + } + public static function getName(): string { return 'audits'; @@ -86,16 +96,17 @@ class Audits extends Action 'mode' => $mode, 'data' => $auditPayload, ], - 'timestamp' => time() + 'timestamp' => DateTime::formatTz(DateTime::now()) ]; self::$logs[] = $eventData; // Check if we should process the batch by checking both for the batch size and the elapsed time - $shouldProcessBatch = count(self::$logs) >= self::BATCH_SIZE; + $batchSize = $this->getBatchSize(); + $shouldProcessBatch = count(self::$logs) >= $batchSize; if (!$shouldProcessBatch && count(self::$logs) > 0) { $oldestEventTime = self::$logs[0]['timestamp']; - $shouldProcessBatch = (time() - $oldestEventTime) >= self::BATCH_TIME_WINDOW; + $shouldProcessBatch = (time() - $oldestEventTime) >= self::BATCH_AGGREGATION_INTERVAL; } if ($shouldProcessBatch) { From 48525ce755996a3814e59fc335cf252e3f4131b0 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 11:34:39 +0530 Subject: [PATCH 21/33] chore: linter --- src/Appwrite/Platform/Workers/Audits.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index bdd3f942e1..6c37e3e35f 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -19,15 +19,15 @@ use Utopia\System\System; class Audits extends Action { private const BATCH_SIZE_DEVELOPMENT = 1; // smaller batch size for development - private const BATCH_SIZE_PRODUCTION = 5_000; + private const BATCH_SIZE_PRODUCTION = 5_000; private const BATCH_AGGREGATION_INTERVAL = 60; private static array $logs = []; private function getBatchSize(): int { - return System::getEnv('_APP_ENV', 'development') === 'development' - ? self::BATCH_SIZE_DEVELOPMENT + return System::getEnv('_APP_ENV', 'development') === 'development' + ? self::BATCH_SIZE_DEVELOPMENT : self::BATCH_SIZE_PRODUCTION; } From 294f6818faeb627c0504c258eea9899787e44fbb Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 12:23:20 +0530 Subject: [PATCH 22/33] chore: review comments --- src/Appwrite/Platform/Workers/Audits.php | 27 ++++++++---------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 6c37e3e35f..47be7a868b 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -113,25 +113,16 @@ class Audits extends Action Console::log('Processing batch with ' . count(self::$logs) . ' events'); $audit = new Audit($dbForProject); - $batchEvents = array_map(function ($event) { - return [ - 'userId' => $event['userId'], - 'event' => $event['event'], - 'resource' => $event['resource'], - 'userAgent' => $event['userAgent'], - 'ip' => $event['ip'], - 'location' => $event['location'], - 'data' => $event['data'], - 'timestamp' => $event['timestamp'] - ]; - }, self::$logs); - $audit->logBatch($batchEvents); - - // Clear the pending events after successful batch processing - self::$logs = []; - - Console::success('Audit logs processed successfully'); + try { + $audit->logBatch(self::$logs); + Console::success('Audit logs processed successfully'); + } catch (Throwable $e) { + Console::error('Error processing audit logs: ' . $e->getMessage()); + } finally { + // Clear the pending events after successful batch processing + self::$logs = []; + } } } } From 2dffcb29b09dc628716e22c229c525af992564ef Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 13:09:31 +0530 Subject: [PATCH 23/33] chore: add comment about the unit --- src/Appwrite/Platform/Workers/Audits.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 47be7a868b..01eac10502 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -20,7 +20,7 @@ class Audits extends Action { private const BATCH_SIZE_DEVELOPMENT = 1; // smaller batch size for development private const BATCH_SIZE_PRODUCTION = 5_000; - private const BATCH_AGGREGATION_INTERVAL = 60; + private const BATCH_AGGREGATION_INTERVAL = 60; // in seconds private static array $logs = []; From d2cc5ea932a78a55c86e07c8f3886f94e0b46569 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 12 Feb 2025 10:58:51 +0000 Subject: [PATCH 24/33] Fix: missing periodic metric --- src/Appwrite/Platform/Workers/StatsResources.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index 0ab6485953..639e90a867 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -252,6 +252,8 @@ class StatsResources extends Action }); $this->createStatsDocuments($region, METRIC_FILES_IMAGES_TRANSFORMED, $totalImageTransformations, 'inf'); + $this->createStatsDocuments($region, METRIC_FILES_IMAGES_TRANSFORMED, $totalDailyImageTransformations, '1d'); + $this->createStatsDocuments($region, METRIC_FILES_IMAGES_TRANSFORMED, $totalHourlyImageTransformations, '1h'); } From 9989137ed463fe32f9fe49aae2261bf386a055f3 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 22:01:28 +0530 Subject: [PATCH 25/33] chore: use private variables for aggregation --- package.json | 8 -------- src/Appwrite/Platform/Workers/Audits.php | 23 +++++++++++++---------- 2 files changed, 13 insertions(+), 18 deletions(-) delete mode 100644 package.json diff --git a/package.json b/package.json deleted file mode 100644 index 6e32c7d515..0000000000 --- a/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "private": true, - "name": "@appwrite.io/repo", - "repository": { - "type": "git", - "url": "git+https://github.com/appwrite/appwrite.git" - } -} \ No newline at end of file diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 01eac10502..f1ae46eea7 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -22,7 +22,9 @@ class Audits extends Action private const BATCH_SIZE_PRODUCTION = 5_000; private const BATCH_AGGREGATION_INTERVAL = 60; // in seconds - private static array $logs = []; + private int $lastTriggeredTime = 0; + + private array $logs = []; private function getBatchSize(): int { @@ -46,6 +48,8 @@ class Audits extends Action ->inject('message') ->inject('dbForProject') ->callback(fn ($message, $dbForProject) => $this->action($message, $dbForProject)); + + $this->lastTriggeredTime = time(); } @@ -99,29 +103,28 @@ class Audits extends Action 'timestamp' => DateTime::formatTz(DateTime::now()) ]; - self::$logs[] = $eventData; + $this->logs[] = $eventData; // Check if we should process the batch by checking both for the batch size and the elapsed time $batchSize = $this->getBatchSize(); - $shouldProcessBatch = count(self::$logs) >= $batchSize; - if (!$shouldProcessBatch && count(self::$logs) > 0) { - $oldestEventTime = self::$logs[0]['timestamp']; - $shouldProcessBatch = (time() - $oldestEventTime) >= self::BATCH_AGGREGATION_INTERVAL; + $shouldProcessBatch = count($this->logs) >= $batchSize; + if (!$shouldProcessBatch && count($this->logs) > 0) { + $shouldProcessBatch = (time() - $this->lastTriggeredTime) >= self::BATCH_AGGREGATION_INTERVAL; } if ($shouldProcessBatch) { - Console::log('Processing batch with ' . count(self::$logs) . ' events'); - + Console::log('Processing batch with ' . count($this->logs) . ' events'); $audit = new Audit($dbForProject); try { - $audit->logBatch(self::$logs); + $audit->logBatch($this->logs); Console::success('Audit logs processed successfully'); } catch (Throwable $e) { Console::error('Error processing audit logs: ' . $e->getMessage()); } finally { // Clear the pending events after successful batch processing - self::$logs = []; + $this->logs = []; + $this->lastTriggeredTime = time(); } } } From a0482aca7a44d5c0adad03e6d47dbb49e551873e Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 12 Feb 2025 22:04:46 +0530 Subject: [PATCH 26/33] chore: revert package.json --- package.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000000..6e32c7d515 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "private": true, + "name": "@appwrite.io/repo", + "repository": { + "type": "git", + "url": "git+https://github.com/appwrite/appwrite.git" + } +} \ No newline at end of file From d4599e68849b08345da2c670ce56ccbfd8081af0 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 13 Feb 2025 06:43:49 +0000 Subject: [PATCH 27/33] Fix, time was not being written to DB --- src/Appwrite/Platform/Workers/StatsResources.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index 639e90a867..f5e3d26b2a 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -354,10 +354,11 @@ class StatsResources extends Action 'period' => $period, 'region' => $region, 'value' => $value, + 'time' => $time, ]); } } else { - $time = 'inf' === $period ? null : \date($this->periods[$period], \time()); + $time = $period === 'inf' ? null : \date($this->periods[$period], \time()); $id = \md5("{$time}_{$period}_{$metric}"); $this->documents[] = new Document([ '$id' => $id, @@ -365,6 +366,7 @@ class StatsResources extends Action 'period' => $period, 'region' => $region, 'value' => $value, + 'time' => $time, ]); } } From 43d8374c5c39ce2ca58b5d6158d4430733b28d3f Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 13 Feb 2025 16:57:32 +0900 Subject: [PATCH 28/33] Update migrations --- composer.json | 6 ++--- composer.lock | 68 +++++++++++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/composer.json b/composer.json index 58b74c3fe3..b28eec6964 100644 --- a/composer.json +++ b/composer.json @@ -45,13 +45,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.16.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.49.*", + "utopia-php/abuse": "0.50.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.50.*", + "utopia-php/audit": "0.51.*", "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.58.5", + "utopia-php/database": "0.59.0", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index fd89ba3ae8..152a7bd0d1 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": "884381b7cc6c225f83c397eb472ddf11", + "content-hash": "ed36bf1392e79d1b1bb07fb2a81f03bf", "packages": [ { "name": "adhocore/jwt", @@ -3377,16 +3377,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.49.0", + "version": "0.50.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "76612c274b895aa3d4d1fa27557a6402463eea99" + "reference": "3ff67819e9de61506c5ca070a70552f7ebe99f80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/76612c274b895aa3d4d1fa27557a6402463eea99", - "reference": "76612c274b895aa3d4d1fa27557a6402463eea99", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/3ff67819e9de61506c5ca070a70552f7ebe99f80", + "reference": "3ff67819e9de61506c5ca070a70552f7ebe99f80", "shasum": "" }, "require": { @@ -3394,7 +3394,7 @@ "ext-pdo": "*", "ext-redis": "*", "php": ">=8.0", - "utopia-php/database": "0.58.*" + "utopia-php/database": "0.59.*" }, "require-dev": { "laravel/pint": "1.*", @@ -3422,9 +3422,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.49.0" + "source": "https://github.com/utopia-php/abuse/tree/0.50.0" }, - "time": "2025-02-04T07:33:59+00:00" + "time": "2025-02-12T09:13:59+00:00" }, { "name": "utopia-php/analytics", @@ -3474,21 +3474,21 @@ }, { "name": "utopia-php/audit", - "version": "0.50.0", + "version": "0.51.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "c0da7dcdd35fc7d3f9640ba21cc82607cf7da729" + "reference": "a5a4b73a57e27a0fac8025b1d6038e145a1ca04e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/c0da7dcdd35fc7d3f9640ba21cc82607cf7da729", - "reference": "c0da7dcdd35fc7d3f9640ba21cc82607cf7da729", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/a5a4b73a57e27a0fac8025b1d6038e145a1ca04e", + "reference": "a5a4b73a57e27a0fac8025b1d6038e145a1ca04e", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "0.58.*" + "utopia-php/database": "0.59.*" }, "require-dev": { "laravel/pint": "1.*", @@ -3515,9 +3515,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.50.0" + "source": "https://github.com/utopia-php/audit/tree/0.51.0" }, - "time": "2025-02-12T05:30:25+00:00" + "time": "2025-02-12T09:12:44+00:00" }, { "name": "utopia-php/cache", @@ -3717,16 +3717,16 @@ }, { "name": "utopia-php/database", - "version": "0.58.5", + "version": "0.59.0", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "55308014c697639c6cb270cb5a33cc88fc1ef839" + "reference": "0eed7f1ad3eb66ff4a7d73b68dd9d3e05089eb18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/55308014c697639c6cb270cb5a33cc88fc1ef839", - "reference": "55308014c697639c6cb270cb5a33cc88fc1ef839", + "url": "https://api.github.com/repos/utopia-php/database/zipball/0eed7f1ad3eb66ff4a7d73b68dd9d3e05089eb18", + "reference": "0eed7f1ad3eb66ff4a7d73b68dd9d3e05089eb18", "shasum": "" }, "require": { @@ -3767,9 +3767,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.58.5" + "source": "https://github.com/utopia-php/database/tree/0.59.0" }, - "time": "2025-02-10T08:26:52+00:00" + "time": "2025-02-12T08:08:29+00:00" }, { "name": "utopia-php/domains", @@ -4170,16 +4170,16 @@ }, { "name": "utopia-php/migration", - "version": "0.6.17", + "version": "0.6.19", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "677a5c4688d7f54d1631a91f76a35d51346cf96b" + "reference": "3c9497f7a54ef88b1077c48d8326893133ad78eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/677a5c4688d7f54d1631a91f76a35d51346cf96b", - "reference": "677a5c4688d7f54d1631a91f76a35d51346cf96b", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/3c9497f7a54ef88b1077c48d8326893133ad78eb", + "reference": "3c9497f7a54ef88b1077c48d8326893133ad78eb", "shasum": "" }, "require": { @@ -4187,7 +4187,7 @@ "ext-curl": "*", "ext-openssl": "*", "php": ">=8.1", - "utopia-php/database": "0.58.*", + "utopia-php/database": "0.59.*", "utopia-php/dsn": "0.2.*", "utopia-php/framework": "0.33.*", "utopia-php/storage": "0.18.*" @@ -4220,9 +4220,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.6.17" + "source": "https://github.com/utopia-php/migration/tree/0.6.19" }, - "time": "2025-02-05T05:27:29+00:00" + "time": "2025-02-13T07:50:21+00:00" }, { "name": "utopia-php/mongo", @@ -5560,16 +5560,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.12.1", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + "reference": "024473a478be9df5fdaca2c793f2232fe788e414" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", + "reference": "024473a478be9df5fdaca2c793f2232fe788e414", "shasum": "" }, "require": { @@ -5608,7 +5608,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" }, "funding": [ { @@ -5616,7 +5616,7 @@ "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2025-02-12T12:17:51+00:00" }, { "name": "nikic/php-parser", From 6abf8ce7274a3f40a818deb71b157a5b26f97104 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Feb 2025 10:44:27 +0200 Subject: [PATCH 29/33] Fix index length test --- tests/e2e/Services/Databases/DatabasesBase.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 3321a786a7..c9e0a59b80 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -463,7 +463,16 @@ trait DatabasesBase ]); $this->assertEquals(400, $attribute['headers']['status-code']); - $this->assertEquals('Index length is longer than the maximum: 768', $attribute['body']['message']); + + $this->assertTrue( + in_array( + [ + 'Index length is longer than the maximum: 767', + 'Index length is longer than the maximum: 768' + ], + $attribute['body']['message'] + ) + ); } public function testUpdateAttributeEnum(): void From e8a306253b53cf2db27b65ba8c50da6e9777f6f2 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Feb 2025 11:22:40 +0200 Subject: [PATCH 30/33] Fix test --- tests/e2e/Services/Databases/DatabasesBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index c9e0a59b80..9c8d3db9de 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -466,11 +466,11 @@ trait DatabasesBase $this->assertTrue( in_array( + $attribute['body']['message'], [ 'Index length is longer than the maximum: 767', 'Index length is longer than the maximum: 768' - ], - $attribute['body']['message'] + ] ) ); } From 8f212ccd30344078d2daaceb7f5d06011034e501 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Feb 2025 11:24:13 +0200 Subject: [PATCH 31/33] in_array --- tests/e2e/Services/Databases/DatabasesBase.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 9c8d3db9de..82888dc959 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -466,13 +466,11 @@ trait DatabasesBase $this->assertTrue( in_array( - $attribute['body']['message'], - [ + $attribute['body']['message'], [ 'Index length is longer than the maximum: 767', 'Index length is longer than the maximum: 768' ] - ) - ); + )); } public function testUpdateAttributeEnum(): void From 8778e2e6667ecc90edc22b6d3864b2e776299b33 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Feb 2025 11:35:16 +0200 Subject: [PATCH 32/33] lint --- tests/e2e/Services/Databases/DatabasesBase.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 82888dc959..9c8d3db9de 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -466,11 +466,13 @@ trait DatabasesBase $this->assertTrue( in_array( - $attribute['body']['message'], [ + $attribute['body']['message'], + [ 'Index length is longer than the maximum: 767', 'Index length is longer than the maximum: 768' ] - )); + ) + ); } public function testUpdateAttributeEnum(): void From e4ae0d463d3b11ba96a7feb02449bc0488f776b2 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 13 Feb 2025 11:37:12 +0200 Subject: [PATCH 33/33] assertStringContainsString --- tests/e2e/Services/Databases/DatabasesBase.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 9c8d3db9de..0723f4d5bf 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -463,16 +463,7 @@ trait DatabasesBase ]); $this->assertEquals(400, $attribute['headers']['status-code']); - - $this->assertTrue( - in_array( - $attribute['body']['message'], - [ - 'Index length is longer than the maximum: 767', - 'Index length is longer than the maximum: 768' - ] - ) - ); + $this->assertStringContainsString('Index length is longer than the maximum: 76', $attribute['body']['message']); } public function testUpdateAttributeEnum(): void