Files
coolify/tests/Feature/NodeArchitectureTest.php
Andras Bacsai a09cdc2b29 fix(nodes): harden cluster networking and workload recovery
Reject cluster CIDRs containing host addresses and prevent removing nodes
with assigned workloads. Serialize DNS allocation and skip stale container
snapshots to preserve current inventory.

Run host scripts correctly for non-root SSH users, isolate workload
reconciliation failures, and release move targets after interrupted workers.

Add regression coverage for cluster safety, authorization, token revocation,
and workload lifecycle recovery.
2026-10-12 06:58:08 +02:00

40 lines
1.3 KiB
PHP

<?php
use App\Enums\NodeRole;
use App\Models\Node;
use App\Models\PrivateKey;
use App\Models\Server;
use App\Models\Team;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Schema;
uses(RefreshDatabase::class);
it('stores nodes separately from legacy servers', function () {
$team = Team::factory()->create();
$privateKey = PrivateKey::factory()->create(['team_id' => $team->id]);
$node = Node::factory()->create([
'team_id' => $team->id,
'private_key_id' => $privateKey->id,
'role' => NodeRole::WORKER,
]);
expect(Schema::hasTable('nodes'))->toBeTrue()
->and(Schema::hasColumn('servers', 'mode'))->toBeFalse()
->and($node->role)->toBe(NodeRole::WORKER)
->and($node->team->is($team))->toBeTrue()
->and($node->privateKey->is($privateKey))->toBeTrue()
->and(Server::query()->where('uuid', $node->uuid)->exists())->toBeFalse();
});
it('creates a node-bound Sentinel token', function () {
$node = Node::factory()->create();
$token = $node->ensureValidSentinelToken();
$payload = json_decode(decrypt($token), true);
expect($payload['node_uuid'])->toBe($node->uuid)
->and($payload['nonce'])->toHaveLength(32)
->and($node->fresh()->sentinel_token)->toBe($token);
});