fix: skip VectorsDB/DocumentsDB database tests when backend unavailable

Add RequiresVectorsDB and RequiresDocumentsDB traits that probe the
database create endpoint once per test class and call markTestSkipped
when the backend returns a 500 error. This handles CI environments
where COMPOSE_PROFILES only starts a single database service.

Applied to all VectorsDB test classes (need PostgreSQL) and all
DocumentsDB test classes (need MongoDB): main tests, permissions
tests, and transaction tests. Also added a fallback guard in the
shared DatabasesBase::setupDatabase() method.
This commit is contained in:
Prem Palanisamy
2026-03-30 19:25:05 +01:00
parent ef8d543182
commit 206d313da1
26 changed files with 143 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
<?php
namespace Tests\E2E\Scopes;
use Tests\E2E\Client;
use Utopia\Database\Helpers\ID;
/**
* Trait that skips the entire test class when the DocumentsDB backend
* (MongoDB) is not reachable. Uses a single probe request per
* class, cached in a static flag.
*/
trait RequiresDocumentsDB
{
private static ?bool $documentsDBAvailable = null;
protected function setUp(): void
{
parent::setUp();
if (self::$documentsDBAvailable === null) {
$response = $this->client->call(Client::METHOD_POST, '/documentsdb', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'databaseId' => ID::custom('documentsdb-probe'),
'name' => 'Probe',
]);
self::$documentsDBAvailable = $response['headers']['status-code'] < 500;
if (self::$documentsDBAvailable) {
$this->client->call(Client::METHOD_DELETE, '/documentsdb/documentsdb-probe', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]);
}
}
if (!self::$documentsDBAvailable) {
$this->markTestSkipped('DocumentsDB backend (MongoDB) is not available in this CI environment.');
}
}
}
+45
View File
@@ -0,0 +1,45 @@
<?php
namespace Tests\E2E\Scopes;
use Tests\E2E\Client;
use Utopia\Database\Helpers\ID;
/**
* Trait that skips the entire test class when the VectorsDB backend
* (PostgreSQL) is not reachable. Uses a single probe request per
* class, cached in a static flag.
*/
trait RequiresVectorsDB
{
private static ?bool $vectorsDBAvailable = null;
protected function setUp(): void
{
parent::setUp();
if (self::$vectorsDBAvailable === null) {
$response = $this->client->call(Client::METHOD_POST, '/vectorsdb', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'databaseId' => ID::custom('vectorsdb-probe'),
'name' => 'Probe',
]);
self::$vectorsDBAvailable = $response['headers']['status-code'] < 500;
if (self::$vectorsDBAvailable) {
$this->client->call(Client::METHOD_DELETE, '/vectorsdb/vectorsdb-probe', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]);
}
}
if (!self::$vectorsDBAvailable) {
$this->markTestSkipped('VectorsDB backend (PostgreSQL) is not available in this CI environment.');
}
}
}
@@ -61,6 +61,10 @@ trait DatabasesBase
'name' => 'Test Database'
]);
if ($database['headers']['status-code'] >= 500) {
$this->markTestSkipped('Database backend for ' . $this->getApiBasePath() . ' is not available in this CI environment.');
}
$this->assertNotEmpty($database['body']['$id']);
$this->assertEquals(201, $database['headers']['status-code']);
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideConsole;
@@ -11,6 +12,7 @@ class DocumentsDBConsoleClientTest extends Scope
{
use DatabasesBase;
use ProjectCustom;
use RequiresDocumentsDB;
use SideConsole;
use ApiDocumentsDB;
}
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
@@ -11,6 +12,7 @@ class DocumentsDBCustomClientTest extends Scope
{
use DatabasesBase;
use ProjectCustom;
use RequiresDocumentsDB;
use SideClient;
use ApiDocumentsDB;
}
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
@@ -11,6 +12,7 @@ class DocumentsDBCustomServerTest extends Scope
{
use DatabasesBase;
use ProjectCustom;
use RequiresDocumentsDB;
use SideServer;
use ApiDocumentsDB;
}
@@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\DataProvider;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Utopia\Database\Helpers\ID;
@@ -17,6 +18,7 @@ class DocumentsDBPermissionsGuestTest extends Scope
{
use DatabasesPermissionsBase;
use ProjectCustom;
use RequiresDocumentsDB;
use SideClient;
use ApiDocumentsDB;
@@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\DataProvider;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Utopia\Database\Helpers\ID;
@@ -16,6 +17,7 @@ class DocumentsDBPermissionsMemberTest extends Scope
{
use DatabasesPermissionsBase;
use ProjectCustom;
use RequiresDocumentsDB;
use SideClient;
use ApiDocumentsDB;
@@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\DataProvider;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Utopia\Database\Helpers\ID;
@@ -16,6 +17,7 @@ class DocumentsDBPermissionsTeamTest extends Scope
{
use DatabasesPermissionsBase;
use ProjectCustom;
use RequiresDocumentsDB;
use SideClient;
use ApiDocumentsDB;
@@ -5,6 +5,7 @@ namespace Tests\E2E\Services\Databases\VectorsDB;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Services\Databases\VectorsDB\Permissions\DatabasesPermissionsScope;
@@ -16,6 +17,7 @@ use Utopia\Database\Validator\Authorization;
class VectorsDBPermissionsGuestTest extends Scope
{
use ProjectCustom;
use RequiresVectorsDB;
use SideClient;
use DatabasesPermissionsScope;
@@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Depends;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Services\Databases\VectorsDB\Permissions\DatabasesPermissionsScope;
@@ -16,6 +17,7 @@ use Utopia\Database\Helpers\Role;
class VectorsDBPermissionsMemberTest extends Scope
{
use ProjectCustom;
use RequiresVectorsDB;
use SideClient;
use DatabasesPermissionsScope;
@@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Depends;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Services\Databases\VectorsDB\Permissions\DatabasesPermissionsScope;
@@ -16,6 +17,7 @@ use Utopia\Database\Helpers\Role;
class VectorsDBPermissionsTeamTest extends Scope
{
use ProjectCustom;
use RequiresVectorsDB;
use SideClient;
use DatabasesPermissionsScope;
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Traits\DatabasesUrlHelpers;
@@ -13,6 +14,7 @@ class DocumentsDBACIDTest extends Scope
use ACIDBase;
use DatabasesUrlHelpers;
use ProjectCustom;
use RequiresDocumentsDB;
use SideClient;
use ApiDocumentsDB;
}
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Traits\DatabasesUrlHelpers;
@@ -13,6 +14,7 @@ class DocumentsDBTransactionPermissionsCustomClientTest extends Scope
use TransactionPermissionsBase;
use DatabasesUrlHelpers;
use ProjectCustom;
use RequiresDocumentsDB;
use SideClient;
use ApiDocumentsDB;
}
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideConsole;
use Tests\E2E\Traits\DatabasesUrlHelpers;
@@ -13,6 +14,7 @@ class DocumentsDBTransactionsConsoleClientTest extends Scope
use TransactionsBase;
use DatabasesUrlHelpers;
use ProjectCustom;
use RequiresDocumentsDB;
use SideConsole;
use ApiDocumentsDB;
}
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Traits\DatabasesUrlHelpers;
@@ -13,6 +14,7 @@ class DocumentsDBTransactionsCustomClientTest extends Scope
use TransactionsBase;
use DatabasesUrlHelpers;
use ProjectCustom;
use RequiresDocumentsDB;
use SideClient;
use ApiDocumentsDB;
}
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ApiDocumentsDB;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresDocumentsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
use Tests\E2E\Traits\DatabasesUrlHelpers;
@@ -13,6 +14,7 @@ class DocumentsDBTransactionsCustomServerTest extends Scope
use TransactionsBase;
use DatabasesUrlHelpers;
use ProjectCustom;
use RequiresDocumentsDB;
use SideServer;
use ApiDocumentsDB;
}
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Utopia\Database\Helpers\ID;
@@ -13,6 +14,7 @@ use Utopia\Database\Helpers\Role;
class VectorsDBACIDTest extends Scope
{
use ProjectCustom;
use RequiresVectorsDB;
use SideClient;
private function generateEmbeddings(int $dimensions = 3, float $value = 0.1): array
@@ -3,6 +3,7 @@
namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideConsole;
use Tests\E2E\Services\Databases\VectorsDB\Transactions\TransactionsBase;
@@ -11,5 +12,6 @@ class VectorsDBTransactionsConsoleClientTest extends Scope
{
use TransactionsBase;
use ProjectCustom;
use RequiresVectorsDB;
use SideConsole;
}
@@ -3,6 +3,7 @@
namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Services\Databases\VectorsDB\Transactions\TransactionsBase;
@@ -11,5 +12,6 @@ class VectorsDBTransactionsCustomClientTest extends Scope
{
use TransactionsBase;
use ProjectCustom;
use RequiresVectorsDB;
use SideClient;
}
@@ -3,6 +3,7 @@
namespace Tests\E2E\Services\Databases\Transactions;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
use Tests\E2E\Services\Databases\VectorsDB\Transactions\TransactionsBase;
@@ -11,5 +12,6 @@ class VectorsDBTransactionsCustomServerTest extends Scope
{
use TransactionsBase;
use ProjectCustom;
use RequiresVectorsDB;
use SideServer;
}
@@ -26,6 +26,10 @@ trait DatabasesBase
'name' => 'Test Database'
]);
if ($database['headers']['status-code'] >= 500) {
$this->markTestSkipped('VectorsDB backend (PostgreSQL) is not available in this CI environment.');
}
$this->assertNotEmpty($database['body']['$id']);
$this->assertEquals(201, $database['headers']['status-code']);
$this->assertEquals('Test Database', $database['body']['name']);
@@ -35,6 +35,9 @@ trait TransactionsBase
'name' => 'TransactionTestDatabase'
]);
if ($database['headers']['status-code'] >= 500) {
$this->markTestSkipped('VectorsDB backend (PostgreSQL) is not available in this CI environment.');
}
$this->assertEquals(201, $database['headers']['status-code']);
$databaseId = $database['body']['$id'];
@@ -5,6 +5,7 @@ namespace Tests\E2E\Services\Databases;
use PHPUnit\Framework\Attributes\Depends;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideConsole;
use Utopia\Database\Helpers\ID;
@@ -15,6 +16,7 @@ use Utopia\Database\Query;
class VectorsDBConsoleClientTest extends Scope
{
use ProjectCustom;
use RequiresVectorsDB;
use SideConsole;
public function testCreateCollection(): array
@@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Databases;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient;
use Tests\E2E\Services\Databases\VectorsDB\DatabasesBase;
@@ -15,6 +16,7 @@ class VectorsDBCustomClientTest extends Scope
{
use DatabasesBase;
use ProjectCustom;
use RequiresVectorsDB;
use SideClient;
public function testAllowedPermissions(): void
@@ -5,6 +5,7 @@ namespace Tests\E2E\Services\Databases;
use PHPUnit\Framework\Attributes\Depends;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\RequiresVectorsDB;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
use Tests\E2E\Services\Databases\VectorsDB\DatabasesBase;
@@ -17,6 +18,7 @@ class VectorsDBCustomServerTest extends Scope
{
use DatabasesBase;
use ProjectCustom;
use RequiresVectorsDB;
use SideServer;
public function testListDatabases(): array