Coverage for testnet/test_integration.py: 32%
76 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-10 16:08 +0200
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-10 16:08 +0200
1import json
2import subprocess
3import time
4from pathlib import Path
6import pytest
9def run_docker_compose(command, project_dir, env=None, check=False, text=True):
10 return subprocess.run(
11 ["docker", "compose"] + command,
12 cwd=project_dir,
13 env=env,
14 capture_output=True,
15 text=text,
16 check=check,
17 )
20@pytest.fixture(scope="session")
21def mesh_admin():
22 return "https://dmeshadmin.hydo.ch"
25@pytest.fixture(scope="session", autouse=True)
26def build_test_image():
27 run_docker_compose(
28 ["build", "-t", "meshadmin-testnet", "-f", "testnet/Dockerfile", "."],
29 project_dir=Path(__file__).parent,
30 check=True,
31 )
34@pytest.fixture(scope="session")
35def project_dir():
36 return Path(__file__).parent
39@pytest.fixture(scope="session")
40def base_env(mesh_admin):
41 auth_file = Path("auth.json")
42 if not auth_file.exists():
43 pytest.skip("No auth file found. Please run 'meshadmin login' first.")
45 return {
46 "MESH_SERVER_URL": mesh_admin,
47 "KEYCLOAK_BASE_URL": "http://auth.dmeshadmin.hydo.ch",
48 "KEYCLOAK_REALM": "meshadmin",
49 "KEYCLOAK_ADMIN_CLIENT": "admin-cli",
50 }
53@pytest.fixture(scope="session")
54def test_templates(base_env, test_network, project_dir):
55 try:
56 # Create lighthouse template
57 result = run_docker_compose(
58 [
59 "run",
60 "--rm",
61 "admin",
62 "meshadmin",
63 "create-template",
64 "lighthouse",
65 test_network,
66 "true",
67 "true",
68 "true",
69 ],
70 project_dir,
71 env=base_env,
72 )
73 assert result.returncode == 0, (
74 f"Failed to create lighthouse template: {result.stderr}"
75 )
76 lighthouse_key = json.loads(result.stdout)["enrollment_key"]
78 # Create host template
79 result = run_docker_compose(
80 [
81 "run",
82 "--rm",
83 "admin",
84 "meshadmin",
85 "create-template",
86 "host",
87 test_network,
88 "false",
89 "false",
90 "true",
91 ],
92 project_dir,
93 env=base_env,
94 )
95 assert result.returncode == 0, (
96 f"Failed to create host template: {result.stderr}"
97 )
98 host_key = json.loads(result.stdout)["enrollment_key"]
100 yield {
101 "network_name": test_network,
102 "lighthouse_key": lighthouse_key,
103 "host_key": host_key,
104 }
105 finally:
106 # Cleanup
107 for template in ["lighthouse", "host"]:
108 run_docker_compose(
109 [
110 "run",
111 "--rm",
112 "admin",
113 "meshadmin",
114 "delete-template",
115 template,
116 ],
117 project_dir,
118 env=base_env,
119 )
120 for host in ["lighthouse_hetzner", "host1", "host2"]:
121 run_docker_compose(
122 [
123 "run",
124 "--rm",
125 "admin",
126 "meshadmin",
127 "delete-host",
128 host,
129 ],
130 project_dir,
131 env=base_env,
132 )
135@pytest.fixture(scope="session")
136def test_env(base_env, test_templates):
137 full_env = base_env.copy()
138 full_env.update(
139 {
140 "LIGHTHOUSE_ENROLLMENT_KEY": test_templates["lighthouse_key"],
141 "HOST_ENROLLMENT_KEY": test_templates["host_key"],
142 "MESH_ADMIN_ENDPOINT": mesh_admin,
143 "MESH_CONFIG_PATH": "/tmp/",
144 "LIGHTHOUSE_PUBLIC_IP": "128.140.42.121",
145 "LIGHTHOUSE_HOSTNAME": "lighthouse_hetzner",
146 "HOST_PUBLIC_IP": "127.0.0.1",
147 }
148 )
149 return full_env
152@pytest.fixture(scope="session")
153def test_network(test_env, project_dir):
154 result = run_docker_compose(
155 [
156 "run",
157 "--rm",
158 "admin",
159 "meshadmin",
160 "create-network",
161 "test_network",
162 "100.100.64.0/24",
163 ],
164 project_dir,
165 env=test_env,
166 )
167 assert result.returncode == 0, f"Failed to create network: {result.stderr}"
168 return "test_network"
171def print_container_logs(project_dir):
172 for service in ["lighthouse_hetzner", "host1", "host2"]:
173 logs = run_docker_compose(["logs", service], project_dir)
174 print(f"\n=== {service} logs ===\n{logs.stdout}")
177def wait_for_enrollment(project_dir, service_name, max_attempts=3, delay=5):
178 for _ in range(max_attempts):
179 logs = run_docker_compose(["logs", service_name], project_dir)
180 if "enrollment finished" in logs.stdout:
181 return True
182 time.sleep(delay)
183 return False
186@pytest.mark.runtime
187def test_network_setup(project_dir, test_env, mesh_admin, test_templates):
188 try:
189 # Check lighthouse enrollment and startup
190 subprocess.run(
191 ["docker", "compose", "up", "-d", "lighthouse_hetzner"],
192 cwd=project_dir,
193 env=test_env,
194 capture_output=True,
195 text=True,
196 check=True,
197 )
198 time.sleep(10)
199 assert wait_for_enrollment(project_dir, "lighthouse_hetzner"), (
200 "Lighthouse enrollment failed"
201 )
202 assert (
203 "starting nebula"
204 in subprocess.run(
205 ["docker", "compose", "logs", "lighthouse_hetzner"],
206 cwd=project_dir,
207 capture_output=True,
208 text=True,
209 ).stdout
210 ), "Lighthouse nebula startup failed"
212 # Check host1 enrollment and startup
213 subprocess.run(
214 ["docker", "compose", "up", "-d", "host1"],
215 cwd=project_dir,
216 env=test_env,
217 capture_output=True,
218 text=True,
219 check=True,
220 )
221 time.sleep(10)
222 assert wait_for_enrollment(project_dir, "host1"), "Host1 enrollment failed"
223 assert (
224 "starting nebula"
225 in subprocess.run(
226 ["docker", "compose", "logs", "host1"],
227 cwd=project_dir,
228 capture_output=True,
229 text=True,
230 ).stdout
231 ), "Host1 nebula startup failed"
233 # Check host2 enrollment and startup
234 subprocess.run(
235 ["docker", "compose", "up", "-d", "host2"],
236 cwd=project_dir,
237 env=test_env,
238 capture_output=True,
239 text=True,
240 check=True,
241 )
242 time.sleep(10)
243 assert wait_for_enrollment(project_dir, "host2"), "Host2 enrollment failed"
244 assert (
245 "starting nebula"
246 in subprocess.run(
247 ["docker", "compose", "logs", "host2"],
248 cwd=project_dir,
249 capture_output=True,
250 text=True,
251 ).stdout
252 ), "Host2 nebula startup failed"
253 except AssertionError:
254 print_container_logs(project_dir)
255 raise
256 finally:
257 subprocess.run(
258 ["docker", "compose", "down", "-v"],
259 cwd=project_dir,
260 capture_output=True,
261 )