appwrite/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php

541 lines
20 KiB
PHP
Raw Normal View History

<?php
namespace Tests\E2E\Services\Functions;
use Tests\E2E\Client;
2024-03-06 17:34:21 +00:00
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideConsole;
2023-02-05 20:07:46 +00:00
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Role;
class FunctionsConsoleClientTest extends Scope
{
use ProjectCustom;
use SideConsole;
2024-09-19 11:35:52 +00:00
use FunctionsBase;
2021-10-26 13:19:28 +00:00
public function testCreateFunction(): array
{
2024-09-19 11:35:52 +00:00
$function = $this->createFunction([
2022-08-14 10:33:36 +00:00
'functionId' => ID::unique(),
'name' => 'Test',
2022-08-27 03:16:37 +00:00
'execute' => [Role::user($this->getUser()['$id'])->toString()],
'runtime' => 'php-8.0',
2023-08-11 13:34:57 +00:00
'entrypoint' => 'index.php',
'events' => [
'users.*.create',
'users.*.delete',
],
'schedule' => '0 0 1 1 *',
'timeout' => 10,
]);
2024-09-19 21:10:04 +00:00
$this->assertEquals(201, $function['headers']['status-code']);
2024-09-19 21:10:04 +00:00
$functionId = $function['body']['$id'];
2024-09-19 11:35:52 +00:00
$function2 = $this->createFunction([
2022-08-14 10:33:36 +00:00
'functionId' => ID::unique(),
'name' => 'Test Failure',
'execute' => ['some-random-string'],
2023-08-11 13:34:57 +00:00
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
]);
2024-09-19 21:10:04 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEquals(400, $function2['headers']['status-code']);
2023-08-11 13:34:57 +00:00
return [
2024-09-19 11:35:52 +00:00
'functionId' => $functionId,
];
}
2021-10-26 13:19:28 +00:00
/**
* @depends testCreateFunction
*/
2024-09-19 11:35:52 +00:00
public function testFunctionUsage(array $data)
{
/**
2024-09-19 11:35:52 +00:00
* Test for SUCCESS
*/
2025-03-08 23:19:54 +00:00
$usage = $this->getUsage($data['functionId'], [
'range' => '24h'
]);
2024-09-19 11:35:52 +00:00
$this->assertEquals(200, $usage['headers']['status-code']);
2025-04-08 09:08:04 +00:00
$this->assertEquals(24, count($usage['body']));
2024-09-19 11:35:52 +00:00
$this->assertEquals('24h', $usage['body']['range']);
$this->assertIsNumeric($usage['body']['deploymentsTotal']);
$this->assertIsNumeric($usage['body']['deploymentsStorageTotal']);
$this->assertIsNumeric($usage['body']['buildsTotal']);
$this->assertIsNumeric($usage['body']['buildsStorageTotal']);
$this->assertIsNumeric($usage['body']['buildsTimeTotal']);
$this->assertIsNumeric($usage['body']['buildsMbSecondsTotal']);
$this->assertIsNumeric($usage['body']['executionsTotal']);
$this->assertIsNumeric($usage['body']['executionsTimeTotal']);
$this->assertIsNumeric($usage['body']['executionsMbSecondsTotal']);
$this->assertIsArray($usage['body']['deployments']);
$this->assertIsArray($usage['body']['deploymentsStorage']);
$this->assertIsArray($usage['body']['builds']);
$this->assertIsArray($usage['body']['buildsTime']);
$this->assertIsArray($usage['body']['buildsStorage']);
$this->assertIsArray($usage['body']['buildsTime']);
$this->assertIsArray($usage['body']['buildsMbSeconds']);
$this->assertIsArray($usage['body']['executions']);
$this->assertIsArray($usage['body']['executionsTime']);
$this->assertIsArray($usage['body']['executionsMbSeconds']);
/**
2024-09-19 11:35:52 +00:00
* Test for FAILURE
*/
2025-03-08 23:19:54 +00:00
$usage = $this->getUsage($data['functionId'], [
2024-09-19 11:35:52 +00:00
'range' => '232h'
]);
$this->assertEquals(400, $usage['headers']['status-code']);
2025-03-08 23:19:54 +00:00
$usage = $this->getUsage('randomFunctionId', [
'range' => '24h'
]);
2024-09-19 11:35:52 +00:00
$this->assertEquals(404, $usage['headers']['status-code']);
}
2022-08-02 16:11:15 +00:00
/**
* @depends testCreateFunction
*/
2022-08-03 09:13:34 +00:00
public function testCreateFunctionVariable(array $data)
{
2022-08-30 07:53:16 +00:00
/**
* Test for SUCCESS
*/
2024-09-19 11:35:52 +00:00
$variable = $this->createVariable(
$data['functionId'],
2024-09-19 13:17:38 +00:00
[
'key' => 'APP_TEST',
2025-02-10 14:29:28 +00:00
'value' => 'TESTINGVALUE',
'secret' => false
2024-09-19 13:17:38 +00:00
]
2024-09-19 11:35:52 +00:00
);
2024-09-19 21:10:04 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEquals(201, $variable['headers']['status-code']);
2022-08-30 07:53:16 +00:00
2024-09-19 21:10:04 +00:00
$variableId = $variable['body']['$id'];
2024-10-21 14:33:57 +00:00
// test for secret variable
$variable = $this->createVariable(
$data['functionId'],
[
'key' => 'APP_TEST_1',
'value' => 'TESTINGVALUE_1',
'secret' => true
]
);
$this->assertEquals(201, $variable['headers']['status-code']);
$this->assertEquals('APP_TEST_1', $variable['body']['key']);
$this->assertEmpty($variable['body']['value']);
2025-02-10 14:29:28 +00:00
$this->assertTrue($variable['body']['secret']);
2024-10-21 14:33:57 +00:00
$secretVariableId = $variable['body']['$id'];
2022-08-30 07:53:16 +00:00
/**
* Test for FAILURE
*/
2024-09-19 11:35:52 +00:00
// Test for duplicate key
$variable = $this->createVariable(
$data['functionId'],
2024-09-19 13:17:38 +00:00
[
'key' => 'APP_TEST',
2025-02-10 14:29:28 +00:00
'value' => 'ANOTHERTESTINGVALUE',
'secret' => false
2024-09-19 13:17:38 +00:00
]
2024-09-19 11:35:52 +00:00
);
2024-09-19 21:10:04 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEquals(409, $variable['headers']['status-code']);
2022-08-30 07:53:16 +00:00
2024-09-19 11:35:52 +00:00
// Test for invalid key
$variable = $this->createVariable(
$data['functionId'],
2024-09-19 13:17:38 +00:00
[
'key' => str_repeat("A", 256),
'value' => 'TESTINGVALUE'
]
2024-09-19 11:35:52 +00:00
);
2024-09-19 21:10:04 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEquals(400, $variable['headers']['status-code']);
2022-08-30 07:53:16 +00:00
2024-09-19 11:35:52 +00:00
// Test for invalid value
$variable = $this->createVariable(
$data['functionId'],
2024-09-19 13:17:38 +00:00
[
'key' => 'LONGKEY',
'value' => str_repeat("#", 8193),
]
2024-09-19 11:35:52 +00:00
);
2024-09-19 21:10:04 +00:00
2024-09-19 11:35:52 +00:00
$this->assertEquals(400, $variable['headers']['status-code']);
2022-08-02 16:11:15 +00:00
return array_merge(
$data,
[
2024-10-21 14:33:57 +00:00
'variableId' => $variableId,
'secretVariableId' => $secretVariableId
2022-08-02 16:11:15 +00:00
]
);
}
/**
2022-08-30 07:53:16 +00:00
* @depends testCreateFunctionVariable
2022-08-02 16:11:15 +00:00
*/
2022-08-03 09:13:34 +00:00
public function testListVariables(array $data)
{
2022-08-30 07:53:16 +00:00
/**
* Test for SUCCESS
*/
2022-08-09 15:29:24 +00:00
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables', array_merge([
2022-08-02 16:11:15 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
2024-10-21 14:33:57 +00:00
$this->assertEquals(2, sizeof($response['body']['variables']));
$this->assertEquals(2, $response['body']['total']);
2022-08-02 16:11:15 +00:00
$this->assertEquals("APP_TEST", $response['body']['variables'][0]['key']);
$this->assertEquals("TESTINGVALUE", $response['body']['variables'][0]['value']);
2024-10-21 14:33:57 +00:00
$this->assertEquals("APP_TEST_1", $response['body']['variables'][1]['key']);
$this->assertEmpty($response['body']['variables'][1]['value']);
2022-08-03 09:13:34 +00:00
2022-08-30 07:53:16 +00:00
/**
* Test for FAILURE
*/
2022-08-02 16:11:15 +00:00
return $data;
}
/**
* @depends testListVariables
*/
2022-08-03 09:13:34 +00:00
public function testGetVariable(array $data)
{
2022-08-30 07:53:16 +00:00
/**
* Test for SUCCESS
*/
2022-08-09 15:29:24 +00:00
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
2022-08-02 16:11:15 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST", $response['body']['key']);
$this->assertEquals("TESTINGVALUE", $response['body']['value']);
2024-10-21 14:33:57 +00:00
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_1", $response['body']['key']);
$this->assertEmpty($response['body']['value']);
2022-08-30 07:53:16 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables/NON_EXISTING_VARIABLE', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(404, $response['headers']['status-code']);
2022-08-02 16:11:15 +00:00
return $data;
}
/**
* @depends testGetVariable
*/
2022-08-03 09:13:34 +00:00
public function testUpdateVariable(array $data)
{
2022-08-30 07:53:16 +00:00
/**
* Test for SUCCESS
*/
2022-08-09 15:29:24 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
2022-08-02 16:11:15 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE',
'value' => 'TESTINGVALUEUPDATED'
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE", $response['body']['key']);
$this->assertEquals("TESTINGVALUEUPDATED", $response['body']['value']);
2022-08-02 16:11:15 +00:00
2022-08-09 15:29:24 +00:00
$variable = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
2022-08-02 16:11:15 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $variable['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE", $variable['body']['key']);
$this->assertEquals("TESTINGVALUEUPDATED", $variable['body']['value']);
2024-10-21 14:33:57 +00:00
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE_1',
'value' => 'TESTINGVALUEUPDATED_1'
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_1", $response['body']['key']);
$this->assertEmpty($response['body']['value']);
$variable = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $variable['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_1", $variable['body']['key']);
$this->assertEmpty($variable['body']['value']);
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE_2',
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_2", $response['body']['key']);
$this->assertEquals("TESTINGVALUEUPDATED", $response['body']['value']);
$variable = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $variable['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_2", $variable['body']['key']);
$this->assertEquals("TESTINGVALUEUPDATED", $variable['body']['value']);
2025-02-10 14:29:28 +00:00
// convert non-secret variable to secret
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE_2',
'secret' => true
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_2", $response['body']['key']);
$this->assertEmpty($response['body']['value']);
$this->assertTrue($response['body']['secret']);
$variable = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $variable['headers']['status-code']);
$this->assertEquals("APP_TEST_UPDATE_2", $variable['body']['key']);
$this->assertEmpty($variable['body']['value']);
$this->assertTrue($variable['body']['secret']);
// convert secret variable to non-secret
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
2025-02-11 13:12:18 +00:00
'key' => 'APP_TEST_UPDATE',
2025-02-10 14:29:28 +00:00
'secret' => false
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-08-30 07:53:16 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(400, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'value' => 'TESTINGVALUEUPDATED_2'
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-08-30 07:53:16 +00:00
$longKey = str_repeat("A", 256);
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'key' => $longKey,
'value' => 'TESTINGVALUEUPDATED'
]);
$this->assertEquals(400, $response['headers']['status-code']);
$longValue = str_repeat("#", 8193);
$response = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'key' => 'APP_TEST_UPDATE',
'value' => $longValue
]);
$this->assertEquals(400, $response['headers']['status-code']);
2022-08-02 16:11:15 +00:00
return $data;
}
/**
* @depends testUpdateVariable
*/
2022-08-03 09:13:34 +00:00
public function testDeleteVariable(array $data)
{
2022-08-30 07:53:16 +00:00
/**
* Test for SUCCESS
*/
2022-08-09 15:29:24 +00:00
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/variables/' . $data['variableId'], array_merge([
2022-08-02 16:11:15 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
2024-10-21 14:33:57 +00:00
$this->assertEquals(204, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/variables/' . $data['secretVariableId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
2022-08-02 16:11:15 +00:00
$this->assertEquals(204, $response['headers']['status-code']);
2022-08-09 15:29:24 +00:00
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/variables', array_merge([
2022-08-02 16:11:15 +00:00
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(0, sizeof($response['body']['variables']));
$this->assertEquals(0, $response['body']['total']);
2022-08-02 16:11:15 +00:00
2022-08-30 07:53:16 +00:00
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/variables/NON_EXISTING_VARIABLE', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(404, $response['headers']['status-code']);
2022-08-02 16:11:15 +00:00
return $data;
}
2025-02-10 14:29:28 +00:00
public function testVariableE2E(): void
{
$function = $this->createFunction([
'functionId' => ID::unique(),
'runtime' => 'node-18.0',
'name' => 'Variable E2E Test',
'entrypoint' => 'index.js',
'logging' => false,
'execute' => ['any']
]);
$this->assertEquals(201, $function['headers']['status-code']);
$this->assertFalse($function['body']['logging']);
$this->assertNotEmpty($function['body']['$id']);
2025-02-11 12:50:54 +00:00
$functionId = $function['body']['$id'] ?? '';
2025-02-10 14:29:28 +00:00
// create variable
$variable = $this->createVariable($functionId, [
'key' => 'CUSTOM_VARIABLE',
2025-02-11 12:50:54 +00:00
'value' => 'a_secret_value',
2025-02-10 14:29:28 +00:00
'secret' => true,
]);
$this->assertEquals(201, $variable['headers']['status-code']);
$this->assertNotEmpty($variable['body']['$id']);
$this->assertEquals('CUSTOM_VARIABLE', $variable['body']['key']);
$this->assertEquals('', $variable['body']['value']);
$this->assertEquals(true, $variable['body']['secret']);
$deploymentId = $this->setupDeployment($functionId, [
'entrypoint' => 'index.js',
'code' => $this->packageFunction('node'),
'activate' => true
]);
$this->assertNotEmpty($deploymentId);
$execution = $this->createExecution($functionId);
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEmpty($execution['body']['logs']);
$this->assertEmpty($execution['body']['errors']);
2025-02-11 12:50:54 +00:00
$body = json_decode($execution['body']['responseBody']);
2025-02-11 13:12:18 +00:00
$this->assertEquals('a_secret_value', $body->CUSTOM_VARIABLE);
2025-02-10 14:29:28 +00:00
$this->cleanupFunction($functionId);
}
public function testFunctionDownload(): void
{
$functionId = $this->setupFunction([
'functionId' => ID::unique(),
'runtime' => 'node-18.0',
'name' => 'Download Test',
'entrypoint' => 'index.js',
'logging' => false,
'execute' => ['any']
]);
$deploymentId = $this->setupDeployment($functionId, [
'entrypoint' => 'index.js',
'code' => $this->packageFunction('node'),
'activate' => true
]);
$this->assertNotEmpty($deploymentId);
2025-03-04 12:45:44 +00:00
$response = $this->getDeploymentDownload($functionId, $deploymentId, 'source');
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals('application/gzip', $response['headers']['content-type']);
$this->assertGreaterThan(0, $response['headers']['content-length']);
$this->assertGreaterThan(0, \strlen($response['body']));
$deploymentMd5 = \md5($response['body']);
2025-03-04 12:45:44 +00:00
$response = $this->getDeploymentDownload($functionId, $deploymentId, 'output');
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals('application/gzip', $response['headers']['content-type']);
$this->assertGreaterThan(0, $response['headers']['content-length']);
$this->assertGreaterThan(0, \strlen($response['body']));
$buildMd5 = \md5($response['body']);
$this->assertNotEquals($deploymentMd5, $buildMd5);
$this->cleanupFunction($functionId);
}
2021-10-26 13:19:28 +00:00
}