"""최종 검증: 로그인 → 폴더 → 메일 목록""" import paramiko, sys, time sys.stdout.reconfigure(encoding='utf-8', errors='replace') c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15) sftp = c.open_sftp() def run(label, cmd, timeout=30): print(f'\n[{label}]') _, o, _ = c.exec_command(cmd, timeout=timeout) print(o.read().decode('utf-8','replace').strip()[:600]) # 수정 파일 재전송 sftp.put('C:/GUARDiA/workspace/zioinfo-mail/backend/imap_client.py', '/opt/mail/backend/imap_client.py') print('✅ imap_client.py 재전송') run('서비스 재기동', 'systemctl restart zioinfo-mail && sleep 3 && systemctl is-active zioinfo-mail') time.sleep(2) # E2E 테스트 run('E2E: 로그인 → 폴더 → 메일목록', """ TOKEN=$(curl -sf -X POST http://localhost:8026/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"ythong@zioinfo.co.kr","password":"1q2w3e!Q"}' 2>/dev/null | \ python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])" 2>/dev/null) echo "=폴더목록=" curl -sf http://localhost:8026/api/mail/folders \ -H "Authorization: Bearer $TOKEN" 2>/dev/null | \ python3 -c " import sys,json d=json.load(sys.stdin) for f in d: print(f' {f[\"display\"]} ({f[\"name\"]}) - 읽음:{f[\"unread\"]} / 전체:{f[\"total\"]}') " 2>/dev/null echo "=메일목록(INBOX)=" curl -sf "http://localhost:8026/api/mail/messages?folder=INBOX&page=1" \ -H "Authorization: Bearer $TOKEN" 2>/dev/null | \ python3 -c " import sys,json d=json.load(sys.stdin) print(f' 총 {d.get(\"total\",0)}개 메일') for m in d.get('messages',[])[:3]: print(f' [{m[\"uid\"]}] {m[\"subject\"][:40]} - {m[\"sender\"]}') " 2>/dev/null """, timeout=20) run('nginx URL 응답', 'curl -sf -o /dev/null -w "HTTP %{http_code}" https://localhost:8025/ -k 2>/dev/null') run('최종 서비스 상태', 'systemctl is-active zioinfo-mail && systemctl is-active nginx') sftp.close(); c.close()