Files
api/services/nginx/app/tests/Support/EdgeGatewayE2eFixture.php
T

257 lines
8.6 KiB
PHP

<?php
declare(strict_types=1);
use classes\db;
use Predis\Client as PredisClient;
use Tests\Support\Api\ApiCleanup;
use Tests\Support\Api\ApiFixtures;
use Tests\Support\Api\ApiSchemaBootstrap;
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/Api/ApiCleanup.php';
require_once __DIR__ . '/Api/ApiFixtures.php';
require_once __DIR__ . '/Api/ApiSchemaBootstrap.php';
app_require('classes/db.php');
app_require('classes/edge_gateway_manager.php');
$action = strtolower(trim((string)($argv[1] ?? '')));
if ($action === '') {
edge_gateway_e2e_fixture_fail('Missing action. Expected create or cleanup.');
}
try {
if ($action === 'create') {
$context = edge_gateway_e2e_fixture_context();
$fixtures = $context['fixtures'];
$department = $fixtures->createDepartment([
'name' => 'Edge Gateway E2E Department',
]);
$session = $fixtures->createEdgeOperatorSession((int)$department['id'], [], [
'display_name' => 'Edge Gateway E2E Operator',
]);
edge_gateway_e2e_fixture_output([
'department_id' => (int)$department['id'],
'user_id' => (int)$session['user']['id'],
'group_id' => (int)$session['user']['group_id'],
'customer_number' => (int)$session['user']['customer_number'],
'auth_token' => (string)$session['token'],
'broker_secret' => edge_test_broker_secret(),
]);
}
if ($action === 'cleanup') {
$encoded = trim((string)($argv[2] ?? ''));
if ($encoded === '') {
edge_gateway_e2e_fixture_fail('Cleanup requires a base64url payload argument.');
}
$payload = json_decode(base64_decode(strtr($encoded, '-_', '+/')) ?: '', true);
if (!is_array($payload)) {
edge_gateway_e2e_fixture_fail('Invalid cleanup payload.');
}
$context = edge_gateway_e2e_fixture_context();
$db = $context['mysqli'];
$departmentId = (int)($payload['department_id'] ?? 0);
$userId = (int)($payload['user_id'] ?? 0);
$groupId = (int)($payload['group_id'] ?? 0);
if ($departmentId > 0) {
$gatewayIds = edge_gateway_e2e_gateway_ids($db, $departmentId);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_operation_events', $gatewayIds);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_operations', $gatewayIds);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_command_jobs', $gatewayIds);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_log_entries', $gatewayIds);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_shell_sessions', $gatewayIds);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_device_inventory', $gatewayIds);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_relay_bindings', $gatewayIds);
edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_audit_logs', $gatewayIds);
$db->query('DELETE FROM edge_gateway_claim_tokens WHERE department_id = ' . $departmentId);
$db->query('DELETE FROM edge_gateways WHERE department_id = ' . $departmentId);
$db->query('DELETE FROM department_variables WHERE department_id = ' . $departmentId);
}
if ($userId > 0) {
$db->query('DELETE FROM tokens WHERE user_id = ' . $userId);
$db->query('DELETE FROM users WHERE id = ' . $userId);
}
if ($groupId > 0) {
$db->query('DELETE FROM groups_permissions WHERE group_id = ' . $groupId);
$db->query('DELETE FROM groups WHERE id = ' . $groupId);
}
if ($departmentId > 0) {
$db->query('DELETE FROM departments WHERE id = ' . $departmentId);
}
edge_gateway_e2e_fixture_output(['ok' => true]);
}
edge_gateway_e2e_fixture_fail('Unsupported action: ' . $action);
} catch (Throwable $throwable) {
edge_gateway_e2e_fixture_fail($throwable->getMessage());
}
/**
* @return array{mysqli:mysqli,fixtures:ApiFixtures}
*/
function edge_gateway_e2e_fixture_context(): array
{
static $context = null;
if ($context !== null) {
return $context;
}
$dbConfig = edge_gateway_e2e_db_config();
$GLOBALS['CONFIG_DB'] = $dbConfig;
$GLOBALS['response'] = new class {
public function internal_server_error(string $message): void
{
throw new RuntimeException($message);
}
};
$db = new db($dbConfig);
$db->connect();
$GLOBALS['db'] = $db;
$mysqli = $db->conn();
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli->set_charset('utf8mb4');
(new ApiSchemaBootstrap($mysqli))->ensureSchema();
$context = [
'mysqli' => $mysqli,
'fixtures' => new ApiFixtures($mysqli, edge_gateway_e2e_redis_client(), new ApiCleanup()),
];
return $context;
}
/**
* @return array{host:string,user:string,password:string,database:string,port:int}
*/
function edge_gateway_e2e_db_config(): array
{
$target = strtolower(trim((string)(getenv('CONFIG_DB_TARGET') ?: 'live')));
if ($target !== 'debug') {
$target = 'live';
}
$host = edge_gateway_e2e_config_value('CONFIG_DB_HOST', 'CONFIG_DB_DEBUG_HOST', $target);
$user = edge_gateway_e2e_config_value('CONFIG_DB_USER', 'CONFIG_DB_DEBUG_USER', $target);
$password = edge_gateway_e2e_config_value('CONFIG_DB_PASSWORD', 'CONFIG_DB_DEBUG_PASSWORD', $target);
$database = edge_gateway_e2e_config_value('CONFIG_DB_DATABASE', 'CONFIG_DB_DEBUG_DATABASE', $target);
$port = (int)(edge_gateway_e2e_config_value('CONFIG_DB_PORT', 'CONFIG_DB_DEBUG_PORT', $target) ?: '3306');
if ($host === '' || $user === '' || $database === '') {
throw new RuntimeException('Missing database configuration for edge gateway E2E fixtures.');
}
return [
'host' => $host,
'user' => $user,
'password' => $password,
'database' => $database,
'port' => $port > 0 ? $port : 3306,
];
}
function edge_gateway_e2e_config_value(string $liveKey, string $debugKey, string $target): string
{
$liveValue = trim((string)(getenv($liveKey) ?: ''));
$debugValue = trim((string)(getenv($debugKey) ?: ''));
if ($target === 'debug' && $debugValue !== '') {
return $debugValue;
}
return $liveValue;
}
function edge_gateway_e2e_redis_client(): ?PredisClient
{
$target = strtolower(trim((string)(getenv('CONFIG_DB_TARGET') ?: 'live')));
if ($target !== 'debug') {
$target = 'live';
}
$host = edge_gateway_e2e_config_value('REDIS_CONFIG_HOST', 'REDIS_CONFIG_DEBUG_HOST', $target);
if ($host === '') {
return null;
}
$parameters = [
'scheme' => 'tcp',
'host' => $host,
'port' => (int)(edge_gateway_e2e_config_value('REDIS_CONFIG_PORT', 'REDIS_CONFIG_DEBUG_PORT', $target) ?: '6379'),
'database' => (int)(edge_gateway_e2e_config_value('REDIS_CONFIG_DATABASE', 'REDIS_CONFIG_DEBUG_DATABASE', $target) ?: '0'),
'password' => edge_gateway_e2e_config_value('REDIS_CONFIG_PASSWORD', 'REDIS_CONFIG_DEBUG_PASSWORD', $target),
];
$user = edge_gateway_e2e_config_value('REDIS_CONFIG_USER', 'REDIS_CONFIG_DEBUG_USER', $target);
if ($user !== '') {
$parameters['username'] = $user;
}
return new PredisClient($parameters);
}
/**
* @return array<int, int>
*/
function edge_gateway_e2e_gateway_ids(mysqli $db, int $departmentId): array
{
$ids = [];
$result = $db->query('SELECT id FROM edge_gateways WHERE department_id = ' . $departmentId);
if ($result === false) {
return [];
}
while ($row = $result->fetch_assoc()) {
if (isset($row['id']) && is_numeric($row['id'])) {
$ids[] = (int)$row['id'];
}
}
$result->free();
return $ids;
}
/**
* @param array<int, int> $gatewayIds
*/
function edge_gateway_e2e_delete_by_gateway_ids(mysqli $db, string $table, array $gatewayIds): void
{
$gatewayIds = array_values(array_unique(array_filter(array_map('intval', $gatewayIds), static fn(int $id): bool => $id > 0)));
if ($gatewayIds === []) {
return;
}
$db->query('DELETE FROM `' . $table . '` WHERE gateway_id IN (' . implode(', ', $gatewayIds) . ')');
}
/**
* @param array<string, mixed> $payload
*/
function edge_gateway_e2e_fixture_output(array $payload): void
{
echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
exit(0);
}
function edge_gateway_e2e_fixture_fail(string $message): never
{
fwrite(STDERR, $message . PHP_EOL);
exit(1);
}