When Sentinel is enabled and in sync, ServerStorageCheckJob was being dispatched from two locations causing unnecessary duplication: 1. PushServerUpdateJob (every ~30s with real-time filesystem data) 2. ServerManagerJob (scheduled cron check via SSH) This commit modifies ServerManagerJob to only dispatch ServerStorageCheckJob when Sentinel is out of sync or disabled. When Sentinel is active and in sync, PushServerUpdateJob provides real-time storage data, making the scheduled SSH check redundant. Benefits: - Eliminates duplicate storage checks when Sentinel is working - Reduces unnecessary SSH overhead - Storage checks still run as fallback when Sentinel fails - Maintains scheduled checks for servers without Sentinel Updated tests to reflect new behavior: - Storage check NOT dispatched when Sentinel is in sync - Storage check dispatched when Sentinel is out of sync or disabled - All timezone and frequency tests updated accordingly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
186 lines
6.3 KiB
PHP
186 lines
6.3 KiB
PHP
<?php
|
|
|
|
use App\Jobs\ServerCheckJob;
|
|
use App\Jobs\ServerManagerJob;
|
|
use App\Jobs\ServerStorageCheckJob;
|
|
use App\Models\Server;
|
|
use App\Models\Team;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Queue;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
Queue::fake();
|
|
});
|
|
|
|
afterEach(function () {
|
|
Carbon::setTestNow();
|
|
});
|
|
|
|
it('does not dispatch storage check when sentinel is in sync', function () {
|
|
// Given: A server with Sentinel recently updated (in sync)
|
|
$team = Team::factory()->create();
|
|
$server = Server::factory()->create([
|
|
'team_id' => $team->id,
|
|
'sentinel_updated_at' => now(),
|
|
]);
|
|
|
|
$server->settings->update([
|
|
'server_disk_usage_check_frequency' => '0 23 * * *',
|
|
'server_timezone' => 'UTC',
|
|
]);
|
|
|
|
// When: ServerManagerJob runs at 11 PM
|
|
Carbon::setTestNow(Carbon::parse('2025-01-15 23:00:00', 'UTC'));
|
|
$job = new ServerManagerJob;
|
|
$job->handle();
|
|
|
|
// Then: ServerStorageCheckJob should NOT be dispatched (Sentinel handles it via PushServerUpdateJob)
|
|
Queue::assertNotPushed(ServerStorageCheckJob::class);
|
|
});
|
|
|
|
it('dispatches storage check when sentinel is out of sync', function () {
|
|
// Given: A server with Sentinel out of sync (last update 10 minutes ago)
|
|
$team = Team::factory()->create();
|
|
$server = Server::factory()->create([
|
|
'team_id' => $team->id,
|
|
'sentinel_updated_at' => now()->subMinutes(10),
|
|
]);
|
|
|
|
$server->settings->update([
|
|
'server_disk_usage_check_frequency' => '0 23 * * *',
|
|
'server_timezone' => 'UTC',
|
|
]);
|
|
|
|
// When: ServerManagerJob runs at 11 PM
|
|
Carbon::setTestNow(Carbon::parse('2025-01-15 23:00:00', 'UTC'));
|
|
$job = new ServerManagerJob;
|
|
$job->handle();
|
|
|
|
// Then: Both ServerCheckJob and ServerStorageCheckJob should be dispatched
|
|
Queue::assertPushed(ServerCheckJob::class);
|
|
Queue::assertPushed(ServerStorageCheckJob::class, function ($job) use ($server) {
|
|
return $job->server->id === $server->id;
|
|
});
|
|
});
|
|
|
|
it('dispatches storage check when sentinel is disabled', function () {
|
|
// Given: A server with Sentinel disabled
|
|
$team = Team::factory()->create();
|
|
$server = Server::factory()->create([
|
|
'team_id' => $team->id,
|
|
'sentinel_updated_at' => now()->subHours(24),
|
|
]);
|
|
|
|
$server->settings->update([
|
|
'server_disk_usage_check_frequency' => '0 23 * * *',
|
|
'server_timezone' => 'UTC',
|
|
'is_metrics_enabled' => false,
|
|
]);
|
|
|
|
// When: ServerManagerJob runs at 11 PM
|
|
Carbon::setTestNow(Carbon::parse('2025-01-15 23:00:00', 'UTC'));
|
|
$job = new ServerManagerJob;
|
|
$job->handle();
|
|
|
|
// Then: ServerStorageCheckJob should be dispatched
|
|
Queue::assertPushed(ServerStorageCheckJob::class, function ($job) use ($server) {
|
|
return $job->server->id === $server->id;
|
|
});
|
|
});
|
|
|
|
it('respects custom hourly storage check frequency when sentinel is out of sync', function () {
|
|
// Given: A server with hourly storage check frequency and Sentinel out of sync
|
|
$team = Team::factory()->create();
|
|
$server = Server::factory()->create([
|
|
'team_id' => $team->id,
|
|
'sentinel_updated_at' => now()->subMinutes(10),
|
|
]);
|
|
|
|
$server->settings->update([
|
|
'server_disk_usage_check_frequency' => '0 * * * *',
|
|
'server_timezone' => 'UTC',
|
|
]);
|
|
|
|
// When: ServerManagerJob runs at the top of the hour (23:00)
|
|
Carbon::setTestNow(Carbon::parse('2025-01-15 23:00:00', 'UTC'));
|
|
$job = new ServerManagerJob;
|
|
$job->handle();
|
|
|
|
// Then: ServerStorageCheckJob should be dispatched
|
|
Queue::assertPushed(ServerStorageCheckJob::class, function ($job) use ($server) {
|
|
return $job->server->id === $server->id;
|
|
});
|
|
});
|
|
|
|
it('handles VALID_CRON_STRINGS mapping correctly when sentinel is out of sync', function () {
|
|
// Given: A server with 'hourly' string (should be converted to '0 * * * *') and Sentinel out of sync
|
|
$team = Team::factory()->create();
|
|
$server = Server::factory()->create([
|
|
'team_id' => $team->id,
|
|
'sentinel_updated_at' => now()->subMinutes(10),
|
|
]);
|
|
|
|
$server->settings->update([
|
|
'server_disk_usage_check_frequency' => 'hourly',
|
|
'server_timezone' => 'UTC',
|
|
]);
|
|
|
|
// When: ServerManagerJob runs at the top of the hour
|
|
Carbon::setTestNow(Carbon::parse('2025-01-15 23:00:00', 'UTC'));
|
|
$job = new ServerManagerJob;
|
|
$job->handle();
|
|
|
|
// Then: ServerStorageCheckJob should be dispatched (hourly was converted to cron)
|
|
Queue::assertPushed(ServerStorageCheckJob::class, function ($job) use ($server) {
|
|
return $job->server->id === $server->id;
|
|
});
|
|
});
|
|
|
|
it('respects server timezone for storage checks when sentinel is out of sync', function () {
|
|
// Given: A server in America/New_York timezone (UTC-5) configured for 11 PM local time and Sentinel out of sync
|
|
$team = Team::factory()->create();
|
|
$server = Server::factory()->create([
|
|
'team_id' => $team->id,
|
|
'sentinel_updated_at' => now()->subMinutes(10),
|
|
]);
|
|
|
|
$server->settings->update([
|
|
'server_disk_usage_check_frequency' => '0 23 * * *',
|
|
'server_timezone' => 'America/New_York',
|
|
]);
|
|
|
|
// When: ServerManagerJob runs at 11 PM New York time (4 AM UTC next day)
|
|
Carbon::setTestNow(Carbon::parse('2025-01-16 04:00:00', 'UTC'));
|
|
$job = new ServerManagerJob;
|
|
$job->handle();
|
|
|
|
// Then: ServerStorageCheckJob should be dispatched
|
|
Queue::assertPushed(ServerStorageCheckJob::class, function ($job) use ($server) {
|
|
return $job->server->id === $server->id;
|
|
});
|
|
});
|
|
|
|
it('does not dispatch storage check outside schedule', function () {
|
|
// Given: A server with daily storage check at 11 PM
|
|
$team = Team::factory()->create();
|
|
$server = Server::factory()->create([
|
|
'team_id' => $team->id,
|
|
'sentinel_updated_at' => now(),
|
|
]);
|
|
|
|
$server->settings->update([
|
|
'server_disk_usage_check_frequency' => '0 23 * * *',
|
|
'server_timezone' => 'UTC',
|
|
]);
|
|
|
|
// When: ServerManagerJob runs at 10 PM (not 11 PM)
|
|
Carbon::setTestNow(Carbon::parse('2025-01-15 22:00:00', 'UTC'));
|
|
$job = new ServerManagerJob;
|
|
$job->handle();
|
|
|
|
// Then: ServerStorageCheckJob should NOT be dispatched
|
|
Queue::assertNotPushed(ServerStorageCheckJob::class);
|
|
});
|