Memory: Testing & Debugging

Active Test Plans

Attachment Testing Checklist — 5 tests for attachment parsing, continuation round-trip, filter_text, scan smoke, and E2E. All passed 2026-03-16.

Attachment Email Testing Checklist — 4 tests (A-D) establishing pre-refactor baseline; re-run after attachment/LLM refactor to confirm

Test Scripts

All in ~/py/envoy/. Run with python3 <script>. No live IMAP needed except test_e2e_continuation.py.

test_parse_email_message.py — unit tests for parse_email_message() (5 cases)• test_attachment_roundtrip.pysend_continuation_email()parse_email_message() round-trip (14 fields)• test_filter_text.py — unit tests for filter_text() in list_email_attachments.py (6 cases)• test_scan_attachments.py — smoke tests for count_attachments() in scan_attachments.py (4 cases)• test_e2e_continuation.py — E2E continuation cycle: inject → run → hit limit → resume → complete• run_tests.py — older integration suite, sends 6 test emails via inject and checks replies

Logging

Orchestrator uses logging.basicConfig (no file handler). Where logs appear depends on how it's run:

Via rc script (/etc/rcs/envoy start): stdout+stderr redirected to envoy.log in the project directory.• Manual / subprocess (python3 orchestrator.py): logs go to stderr. Capture with subprocess.run(capture_output=True) and read result.stderr.

Full End-to-End Test

To test the complete local-SMTP loop (as of 2026-03-03):1. python3 send_test_email.py [subject] [body] — sends FROM envoy_test@ TO envoy@ via local Postfix2. Check mail log: journalctl -u postfix -n 5 --no-pager — confirm relay to mx-caprica.zoneedit.com3. Wait ~15-60s for Live.com delivery, then: cd ~/py/popit3 && python3 popit3.py — fetches from POP3, stores in IMAP/requests4. python3 orchestrator.py — processes email, sends reply via local SMTP5. cd ~/py/popit3 && python3 popit3.py again — fetches reply (envoy_test@), stores in responses/new/6. Check ~/py/envoy/responses/new/ for the .eml response file

IMPORTANT: the PopIt3 main script is popit3.py, NOT process_emails.py.Running process_emails.py directly only imports modules and does nothing — no POP3 fetch occurs.

Debugging Workflow

When a run produces wrong output or no output:1. Run python3 diag_list_emails.py INBOX — confirm email actually arrived2. Check cron.log or orchestrator output for dispatched actions3. Read the reply email from Sent folder — compare claims vs log4. Only then investigate code

Test Email Injection

Two methods:• send_test_email.py — full loop via local SMTP (preferred for testing SMTP routing). Sends FROM envoy_test@ TO envoy@ via sendmail/Postfix.• inject_email.py — IMAP append direct to INBOX. Faster, skips SMTP/PopIt3. Use when testing orchestrator logic only.send_test_email.py only works reliably on Virgin Media (home). On other networks port 25 may be blocked by ISP.

inject_email.py fix (2026-03-05): now passes '()' as IMAP APPEND flags so injected messages arrive as UNSEEN and the daemon picks them up immediately.Previously passed None which caused Dovecot to mark messages \Seen, requiring a manual mark-unseen step.

IMAP Tools in the Project

diag_list_emails.py [folder] — list all folders/messages with read status• inject_email.py — inject test email directly into INBOX (injects as UNSEEN)Both use the project's imap_client.IMAPClient with credentials from ~/.netrc.To read a specific message body: use a short inline script with from imap_client import IMAPClient — do NOT try to install system imapclient.

Python Environment

The project uses /usr/bin/python3 with packages installed to the user site.imapclient is available to the orchestrator but NOT directly to bare python3 -c without sourcing the right environment.Always use the project's imap_client.py wrapper rather than importing imapclient directly in ad-hoc scripts.

Cron

Orchestrator is NOT in cron — daemon handles processing via IMAP IDLE (see memory/envoy/infrastructure).

version6
created2026-02-28
updated2026-03-16