import app import pytest from fastapi.testclient import TestClient def valid_bundle(): files={path:'placeholder' for path in app.GUCK_ADMIN_REPO_FILES} files['guck-admin/compose.yaml']='''services:\n guck-admin:\n build: .\n network_mode: host\n cap_add: [NET_ADMIN]\n environment:\n GUCK_LIMIT: /host/guck-limit.sh\n volumes:\n - /app-config/guck-admin/data:/data\n control-monitor:\n build: .\n network_mode: host\n cap_add: [NET_ADMIN]\n''' files['guck-admin/src/control.py']='''CREATE TABLE IF NOT EXISTS custom_networks\n2a00:8c40:f000::/36\n45.58.235.0/24\ndef sync_custom_networks(): pass\n''' return files def test_guck_admin_bundle_requires_persistent_custom_network_policy(): files=valid_bundle() files['guck-admin/src/control.py']='def old_control(): pass\n' with pytest.raises(ValueError,match='custom VPN'): app._validate_guck_admin_bundle(files) def test_guck_admin_deploy_dry_run_has_no_remote_side_effect(monkeypatch): calls=[] monkeypatch.setattr(app,'_find_inventory_host',lambda host:{'user':'debian','ip':'141.94.237.199'}) monkeypatch.setattr(app,'_ssh',lambda *args,**kwargs:calls.append(args)) result=app._deploy_guck_admin_compose(valid_bundle(),dry_run=True) assert result['status']=='validated' assert result['host']=='guck-vps' assert calls==[] def test_guck_admin_deploy_uses_inventory_target_and_verifies_policy(monkeypatch): calls=[] monkeypatch.setattr(app,'_find_inventory_host',lambda host:{'user':'debian','ip':'141.94.237.199'}) def fake_ssh(host,command,timeout=600): calls.append((host,command,timeout)) if 'ipset test vpn-v6' in command: return 0,'policy ok','' return 0,'ok','' monkeypatch.setattr(app,'_ssh',fake_ssh) result=app._deploy_guck_admin_compose(valid_bundle(),dry_run=False) assert result['status']=='deployed' assert result['policy']=='verified' assert all(host=='debian@141.94.237.199' for host,_,_ in calls) commands='\n'.join(command for _,command,_ in calls) assert 'docker compose build' in commands assert '127.0.0.1:9090/health' in commands assert '/actions/limiter/refresh' in commands assert 'ipset test vpn-v6 2a00:8c40:f02d:a34c::1' in commands assert 'ipset test vpn-v4 45.58.235.7' in commands def test_guck_admin_deploy_endpoint_requires_auth(monkeypatch): monkeypatch.setattr(app,'BUTLER_TOKEN','test-token') response=TestClient(app.app).post('/vps/guck-admin/deploy',json={'dry_run':True}) assert response.status_code in (401,403)