Skip to content

Add advanced filtering and test utilities for trap servers#1

Merged
lambdalisue merged 11 commits into
mainfrom
imp
Feb 1, 2026
Merged

Add advanced filtering and test utilities for trap servers#1
lambdalisue merged 11 commits into
mainfrom
imp

Conversation

@lambdalisue
Copy link
Copy Markdown
Member

Summary

  • Add /api/await endpoint for polling-free test synchronization
  • Add /api/count endpoint for efficient entry counting
  • Add monotonic sequence numbers to all entries
  • Add SHA-256 hashes for email attachments (trap-smtp)
  • Add regex filter support for flexible pattern matching

Why

These enhancements address common pain points in test automation:

Polling-free synchronization: Traditional tests use sleep() or polling loops to wait for async events, leading to flaky tests (too short) or slow CI/CD (too long). The /api/await endpoint blocks until conditions are met or timeout occurs, eliminating timing races.

Efficient assertions: Tests often only need to verify "N emails arrived" without fetching full payloads. The /api/count endpoint reduces overhead by returning only the count.

Gap detection: Sequence numbers enable clients to detect missed entries (e.g., after SSE reconnection) by checking for gaps in the monotonic counter, which persists across entry eviction.

Content integrity: SHA-256 hashes allow test assertions on binary attachments without storing full binary data in test expectations, and enable duplicate detection.

Advanced filtering: Regex filters complement existing substring filters for scenarios requiring domain validation (^[a-z]+@example\.com$), URL patterns, or complex content matching.

All features maintain backward compatibility and parallel test safety through stateless, filter-based isolation.

Test Plan

  • All existing tests pass (regression)
  • New unit tests for each feature (TDD approach)
  • Handler-level integration tests
  • Documentation updated with examples
  • Invalid inputs return 400 Bad Request with clear errors

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds advanced filtering and test utility features to both trap-webhook and trap-smtp servers to improve test automation and debugging capabilities.

Changes:

  • Added /api/await endpoint for polling-free synchronization in tests (blocks until conditions are met or timeout)
  • Added /api/count endpoint for efficient entry counting without fetching full payloads
  • Added monotonic sequence numbers to all entries for gap detection after reconnection
  • Added SHA-256 hashes for email attachments in trap-smtp for content integrity verification
  • Added regex filter support (path_regex, body_regex, etc.) for complex pattern matching

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
trap-webhook/store/store.go Added Seq field and nextSeq counter to track entry sequence numbers
trap-webhook/store/store_test.go Added comprehensive tests for sequence number behavior (monotonic, starts at 1, survives eviction)
trap-webhook/store/filter.go Added regex filter fields and matching logic for path, query, body, content type, and host
trap-webhook/store/filter_test.go Added test coverage for regex filters including combined filters
trap-webhook/handlers/api.go Modified parseWebhookFilter to parse regex parameters and return errors for invalid regex
trap-webhook/handlers/handlers_test.go Added tests for regex filter endpoint and invalid regex handling
trap-webhook/handlers/count.go New handler returning entry count matching filter criteria
trap-webhook/handlers/count_test.go Comprehensive tests for count endpoint with various filter scenarios
trap-webhook/handlers/await.go New handler that blocks until entries match filter or timeout occurs
trap-webhook/handlers/await_test.go Tests for await endpoint covering existing entries, waiting, timeout, and filtering
trap-webhook/handlers/doc/api.md Updated documentation with new endpoints, regex filters, and sequence number field
trap-webhook/main.go Registered new /await and /count routes
trap-smtp/store/store.go Added Seq field to EmailEntry and Sha256 field to Attachment
trap-smtp/store/store_test.go Added sequence number tests mirroring webhook implementation
trap-smtp/store/filter.go Added regex filter fields and matching logic for from, to, subject, and body
trap-smtp/store/filter_test.go Added test coverage for regex filters
trap-smtp/smtp/backend.go Added SHA-256 hash computation for attachment data
trap-smtp/smtp/backend_test.go Added tests verifying SHA-256 hash correctness for attachments and inline images
trap-smtp/handlers/api.go Modified parseEmailFilter to parse regex parameters and return errors
trap-smtp/handlers/handlers_test.go Added tests for regex filter endpoint and invalid regex handling
trap-smtp/handlers/count.go New handler returning entry count matching filter criteria
trap-smtp/handlers/count_test.go Comprehensive tests for count endpoint
trap-smtp/handlers/await.go New handler that blocks until entries match filter or timeout
trap-smtp/handlers/await_test.go Tests for await endpoint with various scenarios
trap-smtp/handlers/doc/api.md Updated documentation with new endpoints, regex filters, sequence numbers, and attachment SHA-256 field
trap-smtp/main.go Registered new /await and /count routes
README.md Updated endpoint table to include new /api/count and /api/await endpoints

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread trap-smtp/handlers/await.go Outdated
Comment thread trap-webhook/handlers/count.go Outdated
Comment thread trap-smtp/handlers/count.go Outdated
Comment thread trap-webhook/handlers/await.go Outdated
Comment thread trap-smtp/handlers/await.go Outdated
Comment thread trap-webhook/handlers/await.go Outdated
lambdalisue added a commit that referenced this pull request Jan 31, 2026
- Refactor parseAwaitFilter to call parseEmailFilter/parseWebhookFilter and clear pagination fields, eliminating code duplication
- Replace json.Marshal + w.Write with json.NewEncoder for consistency across all handlers
- Add explicit error handling for JSON encoding in count and await timeout responses

Addresses 6 review comments from @copilot-pull-request-reviewer on PR #1.
@lambdalisue lambdalisue requested a review from Copilot January 31, 2026 10:46
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread trap-webhook/handlers/await.go
Comment thread trap-smtp/handlers/await.go
Comment thread trap-webhook/handlers/await.go Outdated
Comment thread trap-smtp/handlers/await.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 16 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread trap-smtp/handlers/count.go
Comment thread trap-webhook/handlers/doc/api.md Outdated
Comment thread trap-webhook/handlers/await.go Outdated
Comment thread trap-webhook/handlers/count.go Outdated
Comment thread trap-smtp/handlers/await.go Outdated
Comment thread trap-webhook/handlers/await.go Outdated
Comment thread trap-smtp/store/filter.go
Comment thread trap-webhook/handlers/await.go Outdated
Comment thread trap-smtp/handlers/await.go Outdated
Comment thread trap-webhook/store/filter.go
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread trap-smtp/handlers/count.go
Comment thread trap-webhook/handlers/await.go
Comment thread trap-webhook/handlers/doc/api.md
Comment thread trap-smtp/handlers/doc/api.md
Each entry now receives a monotonically increasing sequence number on
Add(), starting at 1 and surviving eviction. This provides a stable
ordering identifier independent of timestamps or UUIDs, useful for
cursor-based pagination in the await endpoint.
Compute and store a hex-encoded SHA-256 digest for each attachment's
binary data. This allows test assertions to verify attachment integrity
without downloading the full binary content.
Extend the filter system with regex variants for text fields (e.g.
from_regex, path_regex). Regex filters compile to Go regexp and return
400 Bad Request on invalid patterns. Combined with existing contains
filters via AND logic.
Return the number of entries matching the filter criteria without
transferring full entry data. Useful for quick test assertions like
"exactly 3 emails arrived for this sender".
Block until the specified number of entries match the filter criteria or
the timeout is reached. Returns 408 on timeout with matched/expected
counts. This eliminates sleep-based polling in CI test pipelines.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread trap-webhook/handlers/count_test.go Outdated
Comment thread trap-webhook/handlers/await_test.go
Comment thread trap-smtp/handlers/count.go Outdated
Comment thread trap-smtp/handlers/count_test.go Outdated
Comment thread trap-smtp/handlers/await_test.go
The state-smtp binary (12MB) was committed by mistake and should be
excluded from version control as a build artifact. Only source code
should be tracked, not compiled binaries.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 31 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

trap-webhook/store/store_test.go:286

  • The TestStore_ConcurrentAccess test verifies that the correct count of entries is added, but it doesn't verify that sequence numbers remain unique and monotonically increasing under concurrent access. Consider adding assertions to check that all sequence numbers are unique and in the expected range (1 to numGoroutines*entriesPerGoroutine), which would better validate thread safety of the Seq field.
    trap-smtp/store/store_test.go:286
  • The TestStore_ConcurrentAccess test verifies that the correct count of entries is added, but it doesn't verify that sequence numbers remain unique and monotonically increasing under concurrent access. Consider adding assertions to check that all sequence numbers are unique and in the expected range (1 to numGoroutines*entriesPerGoroutine), which would better validate thread safety of the Seq field.
func TestStore_ConcurrentAccess(t *testing.T) {
	t.Parallel()

	s := store.New(1000, 0)

	var wg sync.WaitGroup
	numGoroutines := 100
	entriesPerGoroutine := 10

	// Concurrent adds
	for i := 0; i < numGoroutines; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for j := 0; j < entriesPerGoroutine; j++ {
				s.Add(&store.EmailEntry{Subject: "Concurrent"})
			}
		}()
	}

	wg.Wait()

	expected := numGoroutines * entriesPerGoroutine
	if s.Count() != expected {
		t.Errorf("Count() = %d, want %d", s.Count(), expected)
	}
}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread trap-webhook/handlers/count.go Outdated
Comment thread trap-webhook/handlers/await.go
Comment thread trap-smtp/handlers/await.go
Replace streaming json.NewEncoder(w).Encode() with json.Marshal() +
w.Write() so that Content-Type and status headers are not implicitly
sent before a marshal failure. Also properly handle w.Write() errors.
The count handler already used json.Marshal() but silently discarded
the w.Write() return value. Check the error and return early on
failure for consistency with the await handlers.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 31 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread trap-smtp/handlers/api.go
Comment thread trap-webhook/handlers/await.go
Comment thread trap-smtp/handlers/await.go
Comment thread trap-webhook/handlers/api.go
@lambdalisue lambdalisue merged commit 614477b into main Feb 1, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants