script('dpkg -l proxmox-ve', CommandResult::success('ii proxmox-ve 8.2')); $shell->connectWithPassword('1.2.3.4', 'root', 'pw'); expect($shell->run('dpkg -l proxmox-ve')->stdout)->toContain('proxmox-ve') ->and($shell->run('whoami')->ok())->toBeTrue() // default success ->and($shell->ran('dpkg -l proxmox-ve'))->toBeTrue(); $shell->putFile('/etc/wireguard/wg0.conf', '[Interface]'); expect($shell->files()['/etc/wireguard/wg0.conf'])->toBe('[Interface]') ->and($shell->connectionsWith('password'))->toHaveCount(1); }); it('removes a peer via the RemoveWireguardPeer job', function () { $hub = new FakeWireguardHub; $hub->addPeer('PK', '10.66.0.9'); (new App\Provisioning\Jobs\RemoveWireguardPeer('PK'))->handle($hub); expect($hub->peers())->toBe([]); }); it('allocates ips and tracks peers (FakeWireguardHub)', function () { $hub = new FakeWireguardHub; $a = $hub->allocateIp(); $b = $hub->allocateIp(); expect($a)->not->toBe($b); $hub->addPeer('PUBKEY', '10.66.0.9'); expect($hub->peers())->toBe(['PUBKEY' => '10.66.0.9']); $hub->removePeer('PUBKEY'); expect($hub->peers())->toBe([]); }); it('allocates addresses within a /24 subnet, skipping hub and used (LocalWireguardHub)', function () { config()->set('provisioning.wireguard.subnet', '10.66.0.0/24'); config()->set('provisioning.wireguard.hub_ip', '10.66.0.1'); Host::factory()->create(['wg_ip' => '10.66.0.2']); // .0 network, .1 hub, .2 used → first free is .3 expect((new LocalWireguardHub)->allocateIp())->toBe('10.66.0.3'); }); it('respects a non-/24 subnet (LocalWireguardHub)', function () { config()->set('provisioning.wireguard.subnet', '10.66.5.128/25'); config()->set('provisioning.wireguard.hub_ip', '10.66.5.129'); // network .128, hub .129 → first free is .130 expect((new LocalWireguardHub)->allocateIp())->toBe('10.66.5.130'); }); it('reports node capacity for a host (FakeProxmoxClient)', function () { $host = Host::factory()->create(['wg_ip' => '10.66.0.5']); $client = (new FakeProxmoxClient)->forHost($host); expect($client->listNodes())->not->toBeEmpty() ->and($client->nodeStatus('pve')['memory']['total'])->toBeGreaterThan(0) ->and($client->nodeStorage('pve')[0]['total'])->toBeGreaterThan(0); });