fix: resolve CI failures in database, functions, and realtime tests

- Increase SchemaPolling default timeouts from 8min to 15min for
  waitForAttribute, waitForAttributes, waitForAttributeCount, and
  waitForIndex to match waitForAllAttributes/waitForAllIndexes. Under
  parallel test load the database worker gets backlogged, causing
  attributes to stay in 'processing' state longer than 8 minutes.
- Add isEmpty check in Functions Delete before updating schedules to
  prevent 500 errors when the schedule document is missing (consistent
  with other modules like Executions/Delete).
- Add retry logic to cleanupFunction in FunctionsBase for transient
  MongoDB transaction abort errors during function deletion.
- Increase Realtime attribute/index polling timeouts from 2min to 15min
  to handle worker backlog under CI load.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jake Barnby
2026-02-20 17:22:51 +13:00
co-authored by Claude Opus 4.6
parent 0b7c8865f5
commit 89f0f227d6
4 changed files with 30 additions and 17 deletions
@@ -86,10 +86,12 @@ class Delete extends Base
// Inform scheduler to no longer run function
$schedule = $dbForPlatform->getDocument('schedules', $function->getAttribute('scheduleId'));
$schedule
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('active', false);
$authorization->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
if (!$schedule->isEmpty()) {
$schedule
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('active', false);
$authorization->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
}
$queueForDeletes
->setType(DELETE_TYPE_DOCUMENT)
+4 -4
View File
@@ -19,7 +19,7 @@ trait SchemaPolling
* @param int $timeoutMs Maximum time to wait in milliseconds
* @param int $waitMs Time between polling attempts in milliseconds
*/
protected function waitForAttribute(string $databaseId, string $containerId, string $attributeKey, int $timeoutMs = 480000, int $waitMs = 500): void
protected function waitForAttribute(string $databaseId, string $containerId, string $attributeKey, int $timeoutMs = 900000, int $waitMs = 500): void
{
$this->assertEventually(function () use ($databaseId, $containerId, $attributeKey) {
$attribute = $this->client->call(
@@ -46,7 +46,7 @@ trait SchemaPolling
* @param int $timeoutMs Maximum time to wait in milliseconds
* @param int $waitMs Time between polling attempts in milliseconds
*/
protected function waitForAttributes(string $databaseId, string $containerId, array $attributeKeys, int $timeoutMs = 480000, int $waitMs = 500): void
protected function waitForAttributes(string $databaseId, string $containerId, array $attributeKeys, int $timeoutMs = 900000, int $waitMs = 500): void
{
$this->assertEventually(function () use ($databaseId, $containerId, $attributeKeys) {
$container = $this->client->call(
@@ -87,7 +87,7 @@ trait SchemaPolling
* @param int $timeoutMs Maximum time to wait in milliseconds
* @param int $waitMs Time between polling attempts in milliseconds
*/
protected function waitForAttributeCount(string $databaseId, string $containerId, int $count, int $timeoutMs = 480000, int $waitMs = 500): void
protected function waitForAttributeCount(string $databaseId, string $containerId, int $count, int $timeoutMs = 900000, int $waitMs = 500): void
{
$this->assertEventually(function () use ($databaseId, $containerId, $count) {
$container = $this->client->call(
@@ -126,7 +126,7 @@ trait SchemaPolling
* @param int $timeoutMs Maximum time to wait in milliseconds
* @param int $waitMs Time between polling attempts in milliseconds
*/
protected function waitForIndex(string $databaseId, string $containerId, string $indexKey, int $timeoutMs = 480000, int $waitMs = 500): void
protected function waitForIndex(string $databaseId, string $containerId, string $indexKey, int $timeoutMs = 900000, int $waitMs = 500): void
{
$this->assertEventually(function () use ($databaseId, $containerId, $indexKey) {
$index = $this->client->call(
+16 -5
View File
@@ -102,11 +102,22 @@ trait FunctionsBase
protected function cleanupFunction(string $functionId): void
{
$function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]));
$maxRetries = 3;
for ($i = 0; $i < $maxRetries; $i++) {
$function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]));
if ($function['headers']['status-code'] === 204) {
return;
}
if ($i < $maxRetries - 1) {
\sleep(1);
}
}
$this->assertEquals(204, $function['headers']['status-code']);
}
@@ -68,7 +68,7 @@ class RealtimeConsoleClientTest extends Scope
], $this->getHeaders()));
$this->assertEquals(200, $attribute['headers']['status-code']);
$this->assertEquals('available', $attribute['body']['status']);
}, 120000, 500);
}, 900000, 500);
return ['actorsId' => $actorsId, 'databaseId' => $databaseId];
}
@@ -120,7 +120,7 @@ class RealtimeConsoleClientTest extends Scope
], $this->getHeaders()));
$this->assertEquals(200, $column['headers']['status-code']);
$this->assertEquals('available', $column['body']['status']);
}, 120000, 500);
}, 900000, 500);
return ['actorsId' => $actorsId, 'databaseId' => $databaseId];
}
@@ -151,7 +151,7 @@ class RealtimeConsoleClientTest extends Scope
], $this->getHeaders()));
$this->assertEquals(200, $index['headers']['status-code'], 'Index polling returned ' . $index['headers']['status-code'] . ': ' . json_encode($index['body'] ?? ''));
$this->assertEquals('available', $index['body']['status']);
}, 120000, 500);
}, 900000, 500);
return $data;
}
@@ -182,7 +182,7 @@ class RealtimeConsoleClientTest extends Scope
], $this->getHeaders()));
$this->assertEquals(200, $index['headers']['status-code'], 'Index polling returned ' . $index['headers']['status-code'] . ': ' . json_encode($index['body'] ?? ''));
$this->assertEquals('available', $index['body']['status']);
}, 120000, 500);
}, 900000, 500);
return $data;
}