175 lines
6.2 KiB
PHP
175 lines
6.2 KiB
PHP
<?php
|
|
|
|
use App\Enums\DeployPolicy;
|
|
use App\Enums\EnvironmentVariableSource;
|
|
use App\Enums\SchedulerMode;
|
|
use App\Enums\ServiceCategory;
|
|
use App\Enums\ServiceType;
|
|
use App\Models\Environment;
|
|
use App\Models\Service;
|
|
use App\Services\Compose\ComposeRenderer;
|
|
|
|
it('renders docker compose for managed postgres services', function () {
|
|
$service = Service::factory()->create([
|
|
'name' => 'primary-postgres',
|
|
'category' => ServiceCategory::DATABASE,
|
|
'type' => ServiceType::POSTGRES,
|
|
'version' => '18',
|
|
'version_track' => '18',
|
|
'driver_name' => 'postgres.18',
|
|
'deploy_policy' => DeployPolicy::DEPENDENCY_ONLY,
|
|
'credentials' => [
|
|
'user' => 'keystone',
|
|
'password' => 'secret',
|
|
'db' => 'keystone',
|
|
],
|
|
'default_cpu_limit' => 1.5,
|
|
'default_memory_limit_mb' => 1024,
|
|
]);
|
|
|
|
$compose = app(ComposeRenderer::class)->render($service);
|
|
|
|
expect($compose)
|
|
->toContain('services:')
|
|
->toContain('primary_postgres:')
|
|
->toContain('image: "postgres:18"')
|
|
->toContain('cpus: 1.500')
|
|
->toContain('mem_limit: "1024m"')
|
|
->toContain("keystone_service_{$service->id}_postgres_data:");
|
|
});
|
|
|
|
it('renders compose for caddy gateway with public ports and named volumes', function () {
|
|
$service = Service::factory()->create([
|
|
'name' => 'gateway',
|
|
'category' => ServiceCategory::GATEWAY,
|
|
'type' => ServiceType::CADDY,
|
|
'version' => '2',
|
|
'version_track' => '2',
|
|
'driver_name' => 'caddy.2',
|
|
]);
|
|
|
|
$compose = app(ComposeRenderer::class)->render($service);
|
|
|
|
expect($compose)
|
|
->toContain('image: "caddy:2"')
|
|
->toContain('- "80:80"')
|
|
->toContain('- "443:443"')
|
|
->toContain("keystone_service_{$service->id}_caddy_data:");
|
|
});
|
|
|
|
it('renders laravel scheduler and worker runtime roles into compose', function () {
|
|
$environment = Environment::factory()->create([
|
|
'scheduler_enabled' => true,
|
|
'scheduler_mode' => SchedulerMode::SINGLE,
|
|
]);
|
|
$web = Service::factory()->for($environment)->create([
|
|
'name' => 'web',
|
|
'category' => ServiceCategory::APPLICATION,
|
|
'type' => ServiceType::LARAVEL,
|
|
'version' => 'php-8.4',
|
|
'version_track' => 'php-8.4',
|
|
'driver_name' => 'laravel.php-8.4',
|
|
'process_roles' => ['web', 'scheduler'],
|
|
'desired_replicas' => 1,
|
|
]);
|
|
$environment->forceFill(['scheduler_target_service_id' => $web->id])->save();
|
|
|
|
$worker = Service::factory()->for($environment)->create([
|
|
'name' => 'worker',
|
|
'category' => ServiceCategory::APPLICATION,
|
|
'type' => ServiceType::LARAVEL,
|
|
'version' => 'php-8.4',
|
|
'version_track' => 'php-8.4',
|
|
'driver_name' => 'laravel.php-8.4',
|
|
'process_roles' => ['worker'],
|
|
'config' => [
|
|
'command' => 'php artisan queue:work --sleep=3 --tries=3',
|
|
],
|
|
]);
|
|
|
|
expect(app(ComposeRenderer::class)->render($web))
|
|
->toContain('AUTORUN_LARAVEL_SCHEDULER: "true"')
|
|
->toContain('healthcheck:')
|
|
->and(app(ComposeRenderer::class)->render($worker))
|
|
->toContain('command: "php artisan queue:work --sleep=3 --tries=3"')
|
|
->not->toContain('healthcheck:');
|
|
});
|
|
|
|
it('enforces scheduler mode when rendering laravel runtime env', function () {
|
|
$environment = Environment::factory()->create([
|
|
'scheduler_enabled' => true,
|
|
'scheduler_mode' => SchedulerMode::SINGLE,
|
|
]);
|
|
$target = Service::factory()->for($environment)->create([
|
|
'name' => 'web',
|
|
'category' => ServiceCategory::APPLICATION,
|
|
'type' => ServiceType::LARAVEL,
|
|
'version' => 'php-8.4',
|
|
'version_track' => 'php-8.4',
|
|
'driver_name' => 'laravel.php-8.4',
|
|
'process_roles' => ['web', 'scheduler'],
|
|
'desired_replicas' => 1,
|
|
]);
|
|
$nonTarget = Service::factory()->for($environment)->create([
|
|
'name' => 'worker',
|
|
'category' => ServiceCategory::APPLICATION,
|
|
'type' => ServiceType::LARAVEL,
|
|
'version' => 'php-8.4',
|
|
'version_track' => 'php-8.4',
|
|
'driver_name' => 'laravel.php-8.4',
|
|
'process_roles' => ['worker', 'scheduler'],
|
|
'desired_replicas' => 1,
|
|
]);
|
|
$environment->forceFill(['scheduler_target_service_id' => $target->id])->save();
|
|
|
|
expect(app(ComposeRenderer::class)->render($target->refresh()))
|
|
->toContain('AUTORUN_LARAVEL_SCHEDULER: "true"')
|
|
->and(app(ComposeRenderer::class)->render($nonTarget->refresh()))
|
|
->not->toContain('AUTORUN_LARAVEL_SCHEDULER');
|
|
|
|
$environment->forceFill([
|
|
'scheduler_mode' => SchedulerMode::EVERY_REPLICA,
|
|
'scheduler_target_service_id' => null,
|
|
])->save();
|
|
|
|
expect(app(ComposeRenderer::class)->render($target->refresh()))
|
|
->toContain('AUTORUN_LARAVEL_SCHEDULER: "true"')
|
|
->and(app(ComposeRenderer::class)->render($nonTarget->refresh()))
|
|
->toContain('AUTORUN_LARAVEL_SCHEDULER: "true"');
|
|
});
|
|
|
|
it('renders environment variables into laravel runtime compose', function () {
|
|
$environment = Environment::factory()->create(['name' => 'production']);
|
|
$environment->variables()->create([
|
|
'key' => 'DB_CONNECTION',
|
|
'value' => 'pgsql',
|
|
'source' => EnvironmentVariableSource::MANAGED_ATTACHMENT,
|
|
'overridable' => false,
|
|
]);
|
|
$environment->variables()->create([
|
|
'key' => 'FEATURE_FLAG',
|
|
'value' => 'enabled',
|
|
'source' => EnvironmentVariableSource::USER,
|
|
'overridable' => true,
|
|
]);
|
|
$service = Service::factory()->for($environment)->create([
|
|
'name' => 'web',
|
|
'category' => ServiceCategory::APPLICATION,
|
|
'type' => ServiceType::LARAVEL,
|
|
'version' => 'php-8.4',
|
|
'version_track' => 'php-8.4',
|
|
'driver_name' => 'laravel.php-8.4',
|
|
'process_roles' => ['web'],
|
|
]);
|
|
|
|
expect(app(ComposeRenderer::class)->render($service))
|
|
->toContain('DB_CONNECTION: "pgsql"')
|
|
->toContain('FEATURE_FLAG: "enabled"')
|
|
->toContain('APP_ENV: "production"');
|
|
|
|
expect(app(ComposeRenderer::class)->renderEnvironmentFile($service))
|
|
->toContain('DB_CONNECTION=pgsql')
|
|
->toContain('FEATURE_FLAG=enabled')
|
|
->toContain('APP_ENV=production');
|
|
});
|