up
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
"""Check development startup/cleanup with stubs; never touch running services."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import signal
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
with tempfile.TemporaryDirectory(prefix='detective-dev-') as directory:
|
||||
root = Path(directory)
|
||||
(root / 'scripts').mkdir()
|
||||
(root / 'scripts/dev.sh').write_text((ROOT / 'scripts/dev.sh').read_text())
|
||||
(root / 'evening_detective_server').mkdir()
|
||||
(root / 'evening_detective_frontend/node_modules').mkdir(parents=True)
|
||||
bin_dir = root / 'bin'
|
||||
bin_dir.mkdir()
|
||||
log = root / 'commands.log'
|
||||
env = {**os.environ, 'PATH': str(bin_dir) + os.pathsep + os.environ['PATH'], 'TEST_LOG': str(log)}
|
||||
for name in ['docker', 'make', 'npm']:
|
||||
stub = bin_dir / name
|
||||
stub.write_text(
|
||||
'#!/usr/bin/env bash\n'
|
||||
f'echo "{name} $*" >> "$TEST_LOG"\n' +
|
||||
('exit 0\n' if name == 'docker' else
|
||||
f'trap \'echo "{name} stopped" >> "$TEST_LOG"; exit 0\' TERM\n'
|
||||
'sleep 60 &\n'
|
||||
'wait\n')
|
||||
)
|
||||
stub.chmod(0o755)
|
||||
|
||||
script = str(root / 'scripts/dev.sh')
|
||||
result = subprocess.run(['bash', script], env=env, capture_output=True, text=True)
|
||||
assert result.returncode != 0 and '.env.example' in result.stderr
|
||||
assert not log.exists(), 'Missing config must fail before Docker'
|
||||
(root / 'evening_detective_server/.env').touch()
|
||||
|
||||
def wait_for(text):
|
||||
deadline = time.monotonic() + 5
|
||||
while time.monotonic() < deadline:
|
||||
if log.exists() and text in log.read_text():
|
||||
return
|
||||
time.sleep(.05)
|
||||
raise AssertionError('Missing log entry: ' + text)
|
||||
|
||||
for sig in [signal.SIGINT, signal.SIGTERM]:
|
||||
log.unlink(missing_ok=True)
|
||||
process = subprocess.Popen(['bash', script], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
try:
|
||||
wait_for('npm run dev')
|
||||
wait_for('make -C evening_detective_server run')
|
||||
process.send_signal(sig)
|
||||
process.communicate(timeout=5)
|
||||
assert process.returncode == 128 + sig
|
||||
commands = log.read_text()
|
||||
assert 'compose -f evening_detective_server/docker-compose-db.yml up -d --wait' in commands
|
||||
assert 'make stopped' in commands and 'npm stopped' in commands, commands
|
||||
finally:
|
||||
if process.poll() is None:
|
||||
process.send_signal(signal.SIGTERM)
|
||||
process.communicate(timeout=5)
|
||||
|
||||
(bin_dir / 'make').write_text('#!/bin/sh\nsleep .2\nexit 7\n')
|
||||
log.unlink(missing_ok=True)
|
||||
result = subprocess.run(['bash', script], env=env, capture_output=True, timeout=5)
|
||||
assert result.returncode == 7
|
||||
assert 'npm stopped' in log.read_text(), 'Backend failure must stop frontend'
|
||||
|
||||
stop = subprocess.check_output(['make', '-n', 'stop'], cwd=ROOT, text=True)
|
||||
assert 'venue/docker-compose.yml' in stop and 'venue/docker-compose.https.yml' in stop
|
||||
assert '--env-file venue/.env down' in stop and '-v' not in stop.split()
|
||||
game = subprocess.check_output(['make', '-n', 'game'], cwd=ROOT, text=True)
|
||||
assert game.strip() == 'bash venue/deploy.sh'
|
||||
dev = subprocess.check_output(['make', '-n', 'dev'], cwd=ROOT, text=True)
|
||||
assert dev.strip() == 'bash scripts/dev.sh'
|
||||
print('PASS: command aliases, config preflight, startup, Ctrl+C/SIGTERM cleanup, backend failure; stop preserves volumes')
|
||||
Reference in New Issue
Block a user