coulomb-social/docs/release/backup-alert-isolated-smtp-2026-10-31.rehearsal.txt
tegwick 267d502d93
Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m16s
Implement durable recurring backup alert delivery candidate
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-31 10:19:16 +01:00

51 lines
3.9 KiB
Text

import datetime, importlib.util, json, pathlib, socket, socketserver, subprocess, tempfile, threading, time, urllib.request
ROOT=pathlib.Path('/home/worsch/coulomb-social')
spec=importlib.util.spec_from_file_location('alerts',ROOT/'scripts/backup_alerts.py');alerts=importlib.util.module_from_spec(spec);spec.loader.exec_module(alerts)
received=[]
class SMTP(socketserver.StreamRequestHandler):
def handle(self):
self.wfile.write(b'220 local synthetic SMTP\r\n');self.wfile.flush()
data=False;body=[]
while line:=self.rfile.readline():
if data:
if line==b'.\r\n':received.append(b''.join(body).decode());data=False;self.wfile.write(b'250 received\r\n')
else:body.append(line)
elif line.upper().startswith((b'EHLO',b'HELO')):self.wfile.write(b'250 localhost\r\n')
elif line.upper().startswith((b'MAIL',b'RCPT',b'RSET',b'NOOP')):self.wfile.write(b'250 OK\r\n')
elif line.upper().startswith(b'DATA'):data=True;body=[];self.wfile.write(b'354 send data\r\n')
elif line.upper().startswith(b'QUIT'):self.wfile.write(b'221 bye\r\n');self.wfile.flush();return
else:self.wfile.write(b'500 unsupported\r\n')
self.wfile.flush()
with tempfile.TemporaryDirectory(prefix='csoc-native-alert-') as temp, socketserver.ThreadingTCPServer(('127.0.0.1',0),SMTP) as smtp:
threading.Thread(target=smtp.serve_forever,daemon=True).start()
root=pathlib.Path(temp)
cid=subprocess.check_output(['docker','create','--network','none','sha256:690c7b525f4367aa91f73e2f91c632206d32e97c6384bdbf2fb7a861b420340d'],text=True).strip()
try:subprocess.run(['docker','cp',cid+':/bin/alertmanager',str(root/'alertmanager')],check=True,capture_output=True)
finally:subprocess.run(['docker','rm',cid],check=True,capture_output=True)
config=json.loads((ROOT/'deploy/backup/alertmanager-config.pending.json').read_text())
email=config['receivers'][1]['email_configs'][0]
email.pop('auth_username');email.pop('auth_password_file');email['to']='receiver@example.invalid';email['from']='sender@example.invalid';email['smarthost']='127.0.0.1:'+str(smtp.server_address[1]);email['require_tls']=False
config['route']['group_wait']='0s';config['route']['group_interval']='1s'
(root/'config.json').write_text(json.dumps(config))
with socket.socket() as sock:sock.bind(('127.0.0.1',0));port=sock.getsockname()[1]
endpoint='http://127.0.0.1:'+str(port)
process=subprocess.Popen([str(root/'alertmanager'),'--config.file='+str(root/'config.json'),'--storage.path='+str(root/'data'),'--web.listen-address=127.0.0.1:'+str(port),'--cluster.listen-address='],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
try:
for i in range(100):
if process.poll() is not None:raise RuntimeError('isolated_alertmanager_stopped')
try:urllib.request.urlopen(endpoint+'/-/ready',timeout=1).close();break
except Exception:time.sleep(.1)
else:raise RuntimeError('isolated_alertmanager_not_ready')
now=datetime.datetime.now(datetime.timezone.utc)
event={'event_id':'8f002752-1b8d-4aba-a67e-a76bf5768d41','condition':'backup_stale','test':True,'observed_at':now.isoformat()}
try:result=alerts.deliver_alertmanager(endpoint,event,now)
except Exception:
print(json.dumps(alerts.request_json(endpoint+"/api/v2/alerts")));raise
for i in range(100):
if received:break
time.sleep(.1)
assert len(received)==1 and event['event_id'] in received[0] and 'receiver@example.invalid' in received[0]
proof={'schema':'coulomb.backup-alert-isolated-smtp.v1','observed_at':now.isoformat(),'real_alertmanager_api_and_route_readback':True,'synthetic_smtp_received':1,'event_id_in_email':True,'loopback_only_smtp':True,'external_email_sent':False,'production_route_activated':False,'transport_handoff':result,'fixture_overrides':['loopback SMTP without TLS/auth','example.invalid addresses','zero group wait','one second group interval']}
(ROOT/'docs/release/backup-alert-isolated-smtp-2026-10-31.json').write_text(json.dumps(proof,indent=2)+'\n');print(json.dumps(proof))
finally:
process.terminate();process.wait(timeout=10);smtp.shutdown()