CluPilotCloud/tests/Feature/Console/ConfigureInstanceMailComman...

137 lines
5.2 KiB
PHP

<?php
use App\Models\Host;
use App\Models\Instance;
use App\Models\ProvisioningRun;
use App\Provisioning\Jobs\AdvanceRunJob;
use Illuminate\Support\Facades\Queue;
// QUEUE_CONNECTION ist in dieser Suite `sync`: ohne das hier faehrt jedes
// `AdvanceRunJob::dispatch()` den Lauf sofort im Test, gegen eine echte,
// unerreichbare Adresse. Die Laeufe, die dieser Test wirklich fahren will,
// stoesst er unten selbst an.
beforeEach(fn () => Queue::fake());
/**
* Eine aktive Instanz auf einem Host mit vmid.
*
* Der Befehl ueberspringt Instanzen ohne Host oder ohne vmid. Ein Test, der
* die Mailversand-Nachruestung fahren will, braucht beide.
*/
function aktiveInstanzMitHost(array $attributes = []): Instance
{
$host = Host::factory()->active()->create(['datacenter' => 'fsn', 'node' => 'pve']);
return Instance::factory()->create(array_merge([
'host_id' => $host->id,
'vmid' => 101,
'status' => 'active',
], $attributes));
}
it('startet je aktiver Instanz einen Lauf', function () {
$i1 = aktiveInstanzMitHost();
$i2 = aktiveInstanzMitHost(['vmid' => 102]);
Instance::factory()->create(['status' => 'closed']);
$this->artisan('clupilot:configure-instance-mail')->assertSuccessful();
$runs = ProvisioningRun::where('pipeline', 'instance-mail')->get();
expect($runs->count())->toBe(2)
->and($runs[0]->status)->toBe(ProvisioningRun::STATUS_PENDING)
->and($runs[1]->status)->toBe(ProvisioningRun::STATUS_PENDING);
// Der Auftrag muss mit der uuid des Laufs dispatched werden, nicht mit id.
// Ohne uuid findet AdvanceRunJob keine Zeile und der Lauf steht für immer auf running.
Queue::assertPushed(AdvanceRunJob::class, fn ($job) => $job->runUuid === $runs[0]->uuid);
Queue::assertPushed(AdvanceRunJob::class, fn ($job) => $job->runUuid === $runs[1]->uuid);
});
it('faengt unter --dry-run gar nichts an', function () {
aktiveInstanzMitHost();
aktiveInstanzMitHost(['vmid' => 102]);
aktiveInstanzMitHost(['vmid' => 103]);
$this->artisan('clupilot:configure-instance-mail', ['--dry-run' => true])->assertSuccessful();
expect(ProvisioningRun::where('pipeline', 'instance-mail')->count())->toBe(0);
});
it('nimmt mit --instance genau eine', function () {
$eine = aktiveInstanzMitHost();
aktiveInstanzMitHost(['vmid' => 102]);
$this->artisan('clupilot:configure-instance-mail', ['--instance' => $eine->uuid])->assertSuccessful();
expect(ProvisioningRun::where('pipeline', 'instance-mail')->count())->toBe(1);
});
it('ueberspringt eine Instanz ohne Host und sagt es', function () {
Instance::factory()->create(['status' => 'active', 'host_id' => null, 'vmid' => 101]);
$this->artisan('clupilot:configure-instance-mail')
->expectsOutputToContain('kein Host')
->assertSuccessful();
expect(ProvisioningRun::where('pipeline', 'instance-mail')->count())->toBe(0);
});
it('ueberspringt eine Instanz ohne vmid und sagt es', function () {
$host = Host::factory()->active()->create(['datacenter' => 'fsn', 'node' => 'pve']);
Instance::factory()->create(['status' => 'active', 'host_id' => $host->id, 'vmid' => null]);
$this->artisan('clupilot:configure-instance-mail')
->expectsOutputToContain('keine VMID')
->assertSuccessful();
expect(ProvisioningRun::where('pipeline', 'instance-mail')->count())->toBe(0);
});
it('ueberspringt eine Instanz mit laufendem Lauf und sagt es', function () {
$instance = aktiveInstanzMitHost();
// Ein bereits laufender Lauf gegen diese Instanz
ProvisioningRun::factory()->create([
'subject_type' => Instance::class,
'subject_id' => $instance->id,
'status' => ProvisioningRun::STATUS_RUNNING,
]);
$this->artisan('clupilot:configure-instance-mail')
->expectsOutputToContain('anderer Lauf aktiv')
->assertSuccessful();
// Kein neuer Lauf angelegt
expect(ProvisioningRun::where('pipeline', 'instance-mail')->count())->toBe(0);
});
it('zaehlt die Laeufe korrekt in der Abschlusszusammenfassung', function () {
aktiveInstanzMitHost();
aktiveInstanzMitHost(['vmid' => 102]);
aktiveInstanzMitHost(['vmid' => 103]);
// Eine Instanz ohne Host (wird uebergangen)
Instance::factory()->create(['status' => 'active', 'host_id' => null, 'vmid' => 104]);
$this->artisan('clupilot:configure-instance-mail')
// Genau 3 Laeufe, nicht 6 wegen Doppelzaehlung
->expectsOutputToContain('3 Lauf/Läufe gestartet')
->expectsOutputToContain('übersprungen (kein Host): 1')
->assertSuccessful();
});
it('zaehlt unter --dry-run richtig', function () {
aktiveInstanzMitHost();
aktiveInstanzMitHost(['vmid' => 102]);
// Eine Instanz ohne VMID (wird uebergangen)
$host = Host::factory()->active()->create(['datacenter' => 'fsn', 'node' => 'pve']);
Instance::factory()->create(['status' => 'active', 'host_id' => $host->id, 'vmid' => null]);
$this->artisan('clupilot:configure-instance-mail', ['--dry-run' => true])
// Genau 2 Instanzen im Probelauf
->expectsOutputToContain('Probelauf: 2 Instanz(en) bekämen')
->expectsOutputToContain('übersprungen (keine VMID): 1')
->assertSuccessful();
});