mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
132 lines
5.0 KiB
PHP
132 lines
5.0 KiB
PHP
<?php
|
|
|
|
use App\Livewire\Fleet\Metrics;
|
|
use App\Models\InstanceSettings;
|
|
use App\Models\PrivateKey;
|
|
use App\Models\Server;
|
|
use App\Models\Team;
|
|
use App\Models\User;
|
|
use App\Services\SentinelMetricsClient;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Livewire\Livewire;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
class ChartStubClient extends SentinelMetricsClient
|
|
{
|
|
public function summary(): ?array
|
|
{
|
|
return ['online' => true, 'cpu' => 10.0, 'memUsed' => 1, 'memTotal' => 2,
|
|
'diskUsed' => 1, 'diskTotal' => 2, 'diskPercent' => 50.0, 'load1' => 0.1, 'netRx' => 0.0, 'netTx' => 0.0];
|
|
}
|
|
|
|
public function containersCurrent(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function history(string $metric, string $range): array
|
|
{
|
|
return [[1000, 10.0], [2000, 20.0]];
|
|
}
|
|
|
|
public function networkHistory(string $range): array
|
|
{
|
|
return ['rx' => [[1000, 5.0]], 'tx' => [[1000, 1.0]]];
|
|
}
|
|
}
|
|
|
|
class ChartTestableMetrics extends Metrics
|
|
{
|
|
protected function metricsClient(Server $server): SentinelMetricsClient
|
|
{
|
|
return new ChartStubClient($server);
|
|
}
|
|
}
|
|
|
|
class DenseChartStubClient extends ChartStubClient
|
|
{
|
|
public function history(string $metric, string $range): array
|
|
{
|
|
// 300 points, like a downsampled 24h host series.
|
|
return array_map(fn ($i) => [$i * 1000, (float) $i], range(1, 300));
|
|
}
|
|
}
|
|
|
|
class DenseTestableMetrics extends Metrics
|
|
{
|
|
protected function metricsClient(Server $server): SentinelMetricsClient
|
|
{
|
|
return new DenseChartStubClient($server);
|
|
}
|
|
}
|
|
|
|
beforeEach(function () {
|
|
// The settings hook starts Sentinel when metrics turn on. A sync queue would run it and make a real SSH call.
|
|
Queue::fake();
|
|
InstanceSettings::unguarded(fn () => InstanceSettings::query()->create(['id' => 0]));
|
|
$user = User::factory()->create();
|
|
$team = Team::factory()->create();
|
|
$user->teams()->attach($team, ['role' => 'owner']);
|
|
$this->actingAs($user);
|
|
session(['currentTeam' => $team]);
|
|
$this->privateKey = PrivateKey::factory()->create(['team_id' => $team->id]);
|
|
$this->team = $team;
|
|
});
|
|
|
|
it('dispatches a chart payload with every trend series', function () {
|
|
$s = Server::factory()->create(['team_id' => $this->team->id, 'private_key_id' => $this->privateKey->id]);
|
|
$s->settings->forceFill(['is_metrics_enabled' => true, 'is_reachable' => true, 'is_usable' => true])->saveQuietly();
|
|
|
|
Livewire::test(ChartTestableMetrics::class)
|
|
->call('loadData')
|
|
->assertDispatched('refreshChartData-fleet-metrics', function ($event, $params) {
|
|
$payload = $params[0];
|
|
|
|
// Livewire JSON-serializes event params, so whole floats arrive as ints;
|
|
// compare loosely (10 == 10.0).
|
|
return $payload['cpu'] == [[1000, 10], [2000, 20]]
|
|
&& $payload['networkRx'] == [[1000, 5]]
|
|
&& array_key_exists('load', $payload);
|
|
});
|
|
});
|
|
|
|
it('includes KPI-tile spark series aligned to one shared time axis', function () {
|
|
$s = Server::factory()->create(['team_id' => $this->team->id, 'private_key_id' => $this->privateKey->id]);
|
|
$s->settings->forceFill(['is_metrics_enabled' => true, 'is_reachable' => true, 'is_usable' => true])->saveQuietly();
|
|
|
|
Livewire::test(ChartTestableMetrics::class)
|
|
->call('loadData')
|
|
->assertDispatched('refreshChartData-fleet-metrics', function ($event, $params) {
|
|
$payload = $params[0];
|
|
|
|
// Union of every series' buckets, sorted; each spark projects onto it,
|
|
// leaving gaps as null (network only has the 1000 bucket → tail is null).
|
|
return $payload['sparkCategories'] == [1000, 2000]
|
|
&& $payload['cpuSpark'] == [10, 20]
|
|
&& $payload['memSpark'] == [10, 20]
|
|
&& $payload['diskSpark'] == [10, 20]
|
|
&& $payload['netSpark'] === [6, null];
|
|
});
|
|
});
|
|
|
|
it('caps KPI-tile sparks to a readable point count on a shared axis', function () {
|
|
$s = Server::factory()->create(['team_id' => $this->team->id, 'private_key_id' => $this->privateKey->id]);
|
|
$s->settings->forceFill(['is_metrics_enabled' => true, 'is_reachable' => true, 'is_usable' => true])->saveQuietly();
|
|
|
|
Livewire::test(DenseTestableMetrics::class)
|
|
->call('loadData')
|
|
->assertDispatched('refreshChartData-fleet-metrics', function ($event, $params) {
|
|
$payload = $params[0];
|
|
|
|
// Dense trend charts keep their detail; sparks are thinned to <= 40 points,
|
|
// and every spark shares the same length as the axis (grouped-comparable).
|
|
return count($payload['cpu']) === 300
|
|
&& count($payload['sparkCategories']) <= 40
|
|
&& count($payload['cpuSpark']) === count($payload['sparkCategories'])
|
|
&& count($payload['memSpark']) === count($payload['sparkCategories'])
|
|
&& count($payload['netSpark']) === count($payload['sparkCategories']);
|
|
});
|
|
});
|