c8b067a686
Separate test/e2e Go module drives the shipped deploy/docker-compose.yml (plus a test-only override: self-signed cert, low ports, isolated compose project) against a fake DNS zone (CoreDNS) and an smtp-sink MX, exactly as an administrator and their applications would over HTTP/SMTP — covering the class of failure unit tests can't see (container wiring). Positive path: setup -> login -> domain -> DKIM record published into the fake zone -> application -> SMTP AUTH send -> DKIM verified against the DNS-published key -> send-log queued->sent. Negative: no-AUTH/unauthenticated relay, sender/login mismatch, L1 (anvil) and L2 (panel) rate limits, journal-milter fail-open, SELFPOST_HOSTNAME gate, session survives docker restart. release.yml moves off qemu to a native per-arch build (amd64/arm64), each gated by this suite before its tag is pushed and merged into the version manifest. Verified green on selfpost.mixfed.ru via `make e2e`; go vet/gofmt clean in both modules. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
30 lines
834 B
Go
30 lines
834 B
Go
package e2e
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// waitFor polls check every interval until it returns true or timeout elapses.
|
|
// Every wait in this suite goes through here — no fixed sleeps standing in for
|
|
// a readiness check (plan C.4): a passing check ends the wait immediately, and
|
|
// a timeout fails with what was being waited for, not a bare "timed out".
|
|
func waitFor(what string, timeout, interval time.Duration, check func() (bool, error)) error {
|
|
deadline := time.Now().Add(timeout)
|
|
var lastErr error
|
|
for {
|
|
ok, err := check()
|
|
if ok {
|
|
return nil
|
|
}
|
|
lastErr = err
|
|
if time.Now().After(deadline) {
|
|
if lastErr != nil {
|
|
return fmt.Errorf("timed out after %s waiting for %s: %w", timeout, what, lastErr)
|
|
}
|
|
return fmt.Errorf("timed out after %s waiting for %s", timeout, what)
|
|
}
|
|
time.Sleep(interval)
|
|
}
|
|
}
|