mirror of
https://github.com/coollabsio/coolify.git
synced 2025-12-28 05:34:50 +00:00
Track container restart counts from Docker and detect crash loops to provide better visibility into application health issues. - Add restart_count, last_restart_at, and last_restart_type columns to applications table - Detect restart count increases from Docker inspect data and send notifications - Show restart count badge in UI with warning icon on Logs navigation - Distinguish between crash restarts and manual restarts - Implement 30-second grace period to prevent false "exited" status during crash loops - Reset restart count on manual stop, restart, and redeploy actions - Add unit tests for restart count tracking logic This helps users quickly identify when containers are in crash loops and need attention, even when the container status flickers between states during Docker's restart backoff period.
83 lines
2.4 KiB
PHP
83 lines
2.4 KiB
PHP
<?php
|
|
|
|
use App\Models\Application;
|
|
use App\Models\Server;
|
|
|
|
beforeEach(function () {
|
|
// Mock server
|
|
$this->server = Mockery::mock(Server::class);
|
|
$this->server->shouldReceive('isFunctional')->andReturn(true);
|
|
$this->server->shouldReceive('isSwarm')->andReturn(false);
|
|
$this->server->shouldReceive('applications')->andReturn(collect());
|
|
|
|
// Mock application
|
|
$this->application = Mockery::mock(Application::class);
|
|
$this->application->shouldReceive('getAttribute')->with('id')->andReturn(1);
|
|
$this->application->shouldReceive('getAttribute')->with('name')->andReturn('test-app');
|
|
$this->application->shouldReceive('getAttribute')->with('restart_count')->andReturn(0);
|
|
$this->application->shouldReceive('getAttribute')->with('uuid')->andReturn('test-uuid');
|
|
$this->application->shouldReceive('getAttribute')->with('environment')->andReturn(null);
|
|
});
|
|
|
|
it('extracts restart count from container data', function () {
|
|
$containerData = [
|
|
'RestartCount' => 5,
|
|
'State' => [
|
|
'Status' => 'running',
|
|
'Health' => ['Status' => 'healthy'],
|
|
],
|
|
'Config' => [
|
|
'Labels' => [
|
|
'coolify.applicationId' => '1',
|
|
'com.docker.compose.service' => 'web',
|
|
],
|
|
],
|
|
];
|
|
|
|
$restartCount = data_get($containerData, 'RestartCount', 0);
|
|
|
|
expect($restartCount)->toBe(5);
|
|
});
|
|
|
|
it('defaults to zero when restart count is missing', function () {
|
|
$containerData = [
|
|
'State' => [
|
|
'Status' => 'running',
|
|
],
|
|
'Config' => [
|
|
'Labels' => [],
|
|
],
|
|
];
|
|
|
|
$restartCount = data_get($containerData, 'RestartCount', 0);
|
|
|
|
expect($restartCount)->toBe(0);
|
|
});
|
|
|
|
it('detects restart count increase', function () {
|
|
$previousRestartCount = 2;
|
|
$currentRestartCount = 5;
|
|
|
|
expect($currentRestartCount)->toBeGreaterThan($previousRestartCount);
|
|
});
|
|
|
|
it('identifies maximum restart count from multiple containers', function () {
|
|
$containerRestartCounts = collect([
|
|
'web' => 3,
|
|
'worker' => 5,
|
|
'scheduler' => 1,
|
|
]);
|
|
|
|
$maxRestartCount = $containerRestartCounts->max();
|
|
|
|
expect($maxRestartCount)->toBe(5);
|
|
});
|
|
|
|
it('handles empty restart counts collection', function () {
|
|
$containerRestartCounts = collect([]);
|
|
|
|
$maxRestartCount = $containerRestartCounts->max() ?? 0;
|
|
|
|
expect($maxRestartCount)->toBe(0);
|
|
});
|