CluPilotCloud/tests/Feature/InstanceMetricsTest.php

88 lines
3.2 KiB
PHP

<?php
use App\Livewire\Dashboard;
use App\Models\Customer;
use App\Models\Instance;
use App\Models\InstanceMetric;
use App\Models\User;
use Illuminate\Support\Carbon;
use Livewire\Livewire;
/**
* The measurements behind the panel's ring and trend.
*
* The rule they all serve: a reading that could not be taken is not a reading
* of zero. Charting a failed sample as 0 GB tells a customer their data is
* gone, and charting a missing day as no traffic draws an outage that never
* happened.
*/
function metricFor(Instance $instance, string $day, ?int $used, ?int $total, int $rx = 0, int $tx = 0): InstanceMetric
{
return InstanceMetric::create([
'instance_id' => $instance->id,
'day' => $day,
'disk_used_bytes' => $used,
'disk_total_bytes' => $total,
'rx_bytes' => $rx,
'tx_bytes' => $tx,
]);
}
function customerWithInstance(): array
{
$user = User::factory()->create();
$customer = Customer::factory()->create(['user_id' => $user->id]);
$instance = Instance::factory()->create(['customer_id' => $customer->id, 'status' => 'active', 'quota_gb' => 500]);
return [$user, $instance];
}
it('shows the allowance, not a ring, until something has been measured', function () {
[$user, $instance] = customerWithInstance();
Livewire::actingAs($user)
->test(Dashboard::class)
->assertViewHas('disk', null)
// The contractual figure is true and says so; a ring at 0 % would read
// as "your cloud is empty".
->assertSee(__('dashboard.master.storage_note'));
});
it('draws the ring once a reading exists', function () {
[$user, $instance] = customerWithInstance();
metricFor($instance, Carbon::today()->toDateString(), used: 235_000_000_000, total: 500_000_000_000);
Livewire::actingAs($user)
->test(Dashboard::class)
->assertViewHas('disk', fn (?array $d) => $d !== null && (int) round($d['percent']) === 47);
});
it('keeps the last good reading when a sample could not be taken', function () {
[$user, $instance] = customerWithInstance();
metricFor($instance, Carbon::yesterday()->toDateString(), used: 200_000_000_000, total: 500_000_000_000);
// Today's row exists — the traffic half of the sampler wrote it — but the
// guest agent did not answer, so the disk columns stayed null.
metricFor($instance, Carbon::today()->toDateString(), used: null, total: null, rx: 5_000);
Livewire::actingAs($user)
->test(Dashboard::class)
->assertViewHas('disk', fn (?array $d) => $d !== null && $d['used'] === 200_000_000_000);
});
it('passes the measured days to the trend, and only those', function () {
[$user, $instance] = customerWithInstance();
metricFor($instance, Carbon::today()->subDays(2)->toDateString(), null, null, rx: 1_000, tx: 500);
metricFor($instance, Carbon::today()->subDay()->toDateString(), null, null, rx: 2_000, tx: 500);
metricFor($instance, Carbon::today()->toDateString(), null, null, rx: 4_000, tx: 1_000);
// Outside the window the panel draws.
metricFor($instance, Carbon::today()->subDays(40)->toDateString(), null, null, rx: 9_999_999);
Livewire::actingAs($user)
->test(Dashboard::class)
->assertViewHas('trend', [1_500, 2_500, 5_000]);
});