63 lines
3.0 KiB
Python
63 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Exercise the actual Rust/static HTTP service; keep all service work foreground."""
|
|
import http.cookiejar
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import socket
|
|
import subprocess
|
|
import tempfile
|
|
import time
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
root = Path(__file__).resolve().parents[1]
|
|
with socket.socket() as sock:
|
|
sock.bind(('127.0.0.1', 0))
|
|
port = sock.getsockname()[1]
|
|
origin = f'http://127.0.0.1:{port}'
|
|
with tempfile.TemporaryDirectory(prefix='webka-smoke-') as data:
|
|
env = dict(os.environ, WEBKA_DATA=data, WEBKA_BIND=f'127.0.0.1:{port}', WEBKA_ORIGIN=origin, WEBKA_MDNS='0')
|
|
proc = subprocess.Popen([str(root / 'backend/target/debug/webka')], cwd=root, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
try:
|
|
for _ in range(100):
|
|
try:
|
|
with urllib.request.urlopen(origin + '/api/bootstrap', timeout=1) as response:
|
|
assert json.load(response)['needs_setup'] is True
|
|
break
|
|
except (urllib.error.URLError, ConnectionError):
|
|
if proc.poll() is not None:
|
|
raise RuntimeError(proc.stderr.read().decode())
|
|
time.sleep(0.1)
|
|
else:
|
|
raise RuntimeError('Service did not become ready')
|
|
for route in ['/', '/login', '/host', '/watch', '/settings/accounts', '/settings/general']:
|
|
with urllib.request.urlopen(origin + route) as response:
|
|
assert response.status == 200, route
|
|
assert 'text/html' in response.headers['Content-Type'], route
|
|
assert response.headers['X-Content-Type-Options'] == 'nosniff'
|
|
cookies = http.cookiejar.CookieJar()
|
|
client = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookies))
|
|
def request(path, body=None):
|
|
return client.open(urllib.request.Request(origin + path, data=json.dumps(body).encode() if body is not None else None, headers={'Origin': origin, 'Content-Type': 'application/json'}))
|
|
password = 'smoke-test-password-123'
|
|
with request('/api/bootstrap', {'username': 'owner', 'password': password, 'setup_token': Path(data, 'setup-token').read_text()}) as response:
|
|
assert response.status == 201
|
|
with request('/api/login', {'username': 'owner', 'password': password}) as response:
|
|
assert response.status == 200
|
|
with request('/api/session') as response:
|
|
assert json.load(response)['role'] == 'admin'
|
|
with request('/api/status') as response:
|
|
status = json.load(response)
|
|
assert status['local_url'] == origin + '/watch' and status['live'] is False
|
|
with request('/api/logout', {}) as response:
|
|
assert response.status == 204
|
|
print('PASS: all six static routes, first-run setup, login, cookie/session, local share URL, logout, security headers.')
|
|
finally:
|
|
proc.terminate()
|
|
try:
|
|
proc.communicate(timeout=5)
|
|
except subprocess.TimeoutExpired:
|
|
proc.kill()
|
|
proc.communicate()
|