Implement Keystone environment deployments
This commit is contained in:
80
tests/Feature/StatefulServiceUpdateTest.php
Normal file
80
tests/Feature/StatefulServiceUpdateTest.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
use App\Actions\Services\CreateStatefulServiceUpdateOperation;
|
||||
use App\Enums\ServiceCategory;
|
||||
use App\Enums\ServiceType;
|
||||
use App\Models\Service;
|
||||
|
||||
it('creates explicit downtime-aware update operations for postgres', function () {
|
||||
$service = Service::factory()->create([
|
||||
'name' => 'postgres',
|
||||
'category' => ServiceCategory::DATABASE,
|
||||
'type' => ServiceType::POSTGRES,
|
||||
'version' => '18',
|
||||
'version_track' => '18',
|
||||
'driver_name' => 'postgres.18',
|
||||
'current_image_digest' => 'sha256:old',
|
||||
'config' => [
|
||||
'backup_enabled' => true,
|
||||
'backup_command' => 'pg_dump --format=custom keystone > /home/keystone/backups/pre-update.dump',
|
||||
],
|
||||
]);
|
||||
|
||||
$operation = app(CreateStatefulServiceUpdateOperation::class)->execute(
|
||||
service: $service,
|
||||
imageDigest: 'sha256:new',
|
||||
backupRequested: true,
|
||||
);
|
||||
|
||||
expect($service->refresh()->available_image_digest)->toBe('sha256:new')
|
||||
->and($service->update_status)->toBe('update_pending')
|
||||
->and($operation->steps()->pluck('name')->all())
|
||||
->toBe([
|
||||
'Acknowledge downtime and data risk',
|
||||
'Run pre-update backup',
|
||||
'Render compose with updated image digest',
|
||||
'Stop existing container',
|
||||
'Preserve named volume',
|
||||
'Start service with updated image digest',
|
||||
'Health check updated service',
|
||||
])
|
||||
->and($operation->steps()->where('name', 'Run pre-update backup')->first()->script)
|
||||
->toBe('pg_dump --format=custom keystone > /home/keystone/backups/pre-update.dump')
|
||||
->and($operation->steps()->where('name', 'Render compose with updated image digest')->first()->script)
|
||||
->toContain('base64 -d')
|
||||
->and($operation->steps()->where('name', 'Stop existing container')->first()->script)
|
||||
->toBe("docker compose -f /home/keystone/services/{$service->id}/compose.yml stop {$service->name}")
|
||||
->and($operation->steps()->where('name', 'Preserve named volume')->first()->script)
|
||||
->toBe("docker volume inspect keystone_service_{$service->id}_postgres_data >/dev/null")
|
||||
->and($operation->steps()->where('name', 'Health check updated service')->first()->script)
|
||||
->toContain('docker inspect --format');
|
||||
});
|
||||
|
||||
it('rejects backup requests when no backup capability is configured', function () {
|
||||
$service = Service::factory()->create([
|
||||
'category' => ServiceCategory::DATABASE,
|
||||
'type' => ServiceType::POSTGRES,
|
||||
'version' => '18',
|
||||
'version_track' => '18',
|
||||
'driver_name' => 'postgres.18',
|
||||
'config' => [
|
||||
'backup_enabled' => false,
|
||||
],
|
||||
]);
|
||||
|
||||
expect(fn () => app(CreateStatefulServiceUpdateOperation::class)->execute($service, 'sha256:new', backupRequested: true))
|
||||
->toThrow(InvalidArgumentException::class, 'Backups are not configured for this service.');
|
||||
});
|
||||
|
||||
it('rejects stateful update operations for stateless laravel services', function () {
|
||||
$service = Service::factory()->create([
|
||||
'category' => ServiceCategory::APPLICATION,
|
||||
'type' => ServiceType::LARAVEL,
|
||||
'version' => 'php-8.4',
|
||||
'version_track' => 'php-8.4',
|
||||
'driver_name' => 'laravel.php-8.4',
|
||||
]);
|
||||
|
||||
expect(fn () => app(CreateStatefulServiceUpdateOperation::class)->execute($service, 'sha256:new'))
|
||||
->toThrow(InvalidArgumentException::class, 'Only Postgres and Valkey have v1 stateful update operations.');
|
||||
});
|
||||
Reference in New Issue
Block a user