138 lines
4.7 KiB
PHP
138 lines
4.7 KiB
PHP
<?php
|
|
|
|
use App\Actions\StartHostOnboarding;
|
|
use App\Livewire\Admin\HostCreate;
|
|
use App\Models\Datacenter;
|
|
use App\Models\Host;
|
|
use App\Provisioning\Jobs\PurgeHost;
|
|
use App\Support\HostName;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Livewire\Livewire;
|
|
|
|
beforeEach(function () {
|
|
Queue::fake();
|
|
fakeServices();
|
|
// Die Zone wird hier festgenagelt statt aus der .env dieser Maschine
|
|
// gelesen: `provisioning.dns.platform_zone` leitet sich sonst aus APP_URL
|
|
// ab, und dieselbe Prüfung fiele auf einer richtig konfigurierten
|
|
// Installation um. Geprüft wird die FORM des Namens, nicht die Domain
|
|
// dieser einen Kiste.
|
|
config()->set('provisioning.dns.platform_zone', 'clupilot.com');
|
|
// Die Migration von `create_datacenters_table` legt fsn und hel schon an;
|
|
// firstOrCreate steht hier, damit der Test nicht daran hängt.
|
|
Datacenter::query()->firstOrCreate(['code' => 'fsn'], ['name' => 'Falkenstein']);
|
|
});
|
|
|
|
/** Ein Host, der so angelegt wird, wie die Konsole es tut. */
|
|
function onboard(string $dc = 'fsn'): Host
|
|
{
|
|
static $n = 0;
|
|
$n++;
|
|
|
|
return app(StartHostOnboarding::class)->run([
|
|
'datacenter' => $dc,
|
|
'public_ip' => '203.0.113.'.$n,
|
|
'root_password' => 'supersecret',
|
|
]);
|
|
}
|
|
|
|
// --- Abnahme 1 + 2 ---
|
|
|
|
it('vergibt den Namen selbst, fortlaufend je Rechenzentrum', function () {
|
|
expect(onboard()->name)->toBe('fsn-01')
|
|
->and(onboard()->name)->toBe('fsn-02');
|
|
});
|
|
|
|
it('führt je Rechenzentrum einen eigenen Zähler', function () {
|
|
Datacenter::query()->firstOrCreate(['code' => 'hel'], ['name' => 'Helsinki']);
|
|
|
|
expect(onboard('fsn')->name)->toBe('fsn-01')
|
|
->and(onboard('hel')->name)->toBe('hel-01');
|
|
});
|
|
|
|
// --- Abnahme 3: der Punkt, der die Sorgfalt trägt ---
|
|
|
|
it('gibt die Nummer eines entfernten Hosts nie wieder aus', function () {
|
|
onboard(); // fsn-01
|
|
$zweiter = onboard(); // fsn-02
|
|
onboard(); // fsn-03
|
|
|
|
// Die HÖCHSTE zu entfernen ist der gefährliche Fall: MAX(nummer) + 1
|
|
// reichte fsn-03 sofort wieder heraus, und ein zwischengespeicherter Name
|
|
// zeigte danach auf eine andere Maschine.
|
|
$zweiter->delete();
|
|
|
|
expect(onboard()->name)->toBe('fsn-04');
|
|
});
|
|
|
|
it('überlebt auch das Entfernen des höchsten Hosts', function () {
|
|
onboard(); // fsn-01
|
|
$hoechster = onboard(); // fsn-02
|
|
$hoechster->delete();
|
|
|
|
expect(onboard()->name)->toBe('fsn-03');
|
|
});
|
|
|
|
// --- Abnahme 5 ---
|
|
|
|
it('zeigt den Namen vorher an, ohne ihn zu verbrauchen', function () {
|
|
onboard(); // fsn-01 ist weg
|
|
|
|
$seite = Livewire::actingAs(admin(), 'operator')->test(HostCreate::class)
|
|
->set('datacenter', 'fsn');
|
|
|
|
$seite->assertSee('fsn-02')->assertSee('fsn-02.node.clupilot.com');
|
|
|
|
// Zweimal ansehen verbraucht nichts.
|
|
Livewire::actingAs(admin(), 'operator')->test(HostCreate::class)
|
|
->set('datacenter', 'fsn')
|
|
->assertSee('fsn-02');
|
|
|
|
expect(HostName::preview('fsn'))->toBe('fsn-02');
|
|
});
|
|
|
|
it('gibt zwei gleichzeitig geöffneten Formularen zwei verschiedene Namen', function () {
|
|
// Beide sehen fsn-01, gespeichert wird fsn-01 und fsn-02.
|
|
expect(HostName::preview('fsn'))->toBe('fsn-01')
|
|
->and(HostName::preview('fsn'))->toBe('fsn-01');
|
|
|
|
expect(onboard()->name)->toBe('fsn-01')
|
|
->and(onboard()->name)->toBe('fsn-02');
|
|
});
|
|
|
|
// --- Der Riegel ---
|
|
|
|
it('lässt zwei Hosts nicht denselben Namen tragen', function () {
|
|
onboard();
|
|
|
|
expect(fn () => Host::factory()->create(['name' => 'fsn-01']))
|
|
->toThrow(Illuminate\Database\QueryException::class);
|
|
});
|
|
|
|
it('gibt zwei ähnlich geschriebenen Rechenzentrums-Codes nicht denselben Namen', function () {
|
|
// Codes von vor der Verschärfung der Prüfregel: eu_west und eu-west werden
|
|
// zur selben DNS-Bezeichnung, führen aber getrennte Zähler. Ohne das
|
|
// Weiterzählen bekäme der zweite eu-west-01 und liefe in den Index.
|
|
Datacenter::factory()->create(['code' => 'eu_west', 'name' => 'EU West (alt)']);
|
|
Datacenter::factory()->create(['code' => 'eu-west', 'name' => 'EU West']);
|
|
|
|
expect(onboard('eu_west')->name)->toBe('eu-west-01')
|
|
->and(onboard('eu-west')->name)->toBe('eu-west-02');
|
|
});
|
|
|
|
it('zählt ab hundert ohne Sonderfall weiter', function () {
|
|
Datacenter::query()->where('code', 'fsn')->update(['next_host_number' => 100]);
|
|
|
|
expect(onboard()->name)->toBe('fsn-100');
|
|
});
|
|
|
|
// --- Ein Name, überall derselbe ---
|
|
|
|
it('nennt den Host im DNS so, wie die Konsole ihn nennt', function () {
|
|
$host = onboard();
|
|
|
|
expect(HostName::fqdn($host->name))->toBe('fsn-01.node.clupilot.com')
|
|
->and(App\Support\HostTakeoverCommand::fqdnFor($host))
|
|
->toBe(HostName::fqdn($host->name));
|
|
});
|