rust/capture/docs/llma-integration-test-suite.md
This document describes the Rust integration test suite for the LLM Analytics capture service. These tests validate HTTP endpoint behavior, multipart parsing, and validation logic without requiring external dependencies.
Implementation Requirement: Each phase in the implementation plan must pass its corresponding integration tests before proceeding to the next phase. This ensures incremental validation and prevents regression as new features are added.
See Also: llma-acceptance-test-suite.md for end-to-end tests that require full PostHog infrastructure.
axum-test-helper::TestClientreqwest::multipart::Form to build proper multipart bodiesCapturingSink: Mock event sink that stores events in memory for Kafka output verificationFixedTime: Deterministic time source for reproducible testsTestSink: Simple no-op sink for HTTP endpoint tests$ai_generation for validation testingapplication/json, text/plain, application/octet-streamPhase Completion Requirement: All integration tests for a phase must pass before implementation can proceed to the next phase. This gate ensures quality and prevents compound issues from multiple incomplete features.
/i/v0/ai endpoint is accessible and returns correct response codestest_ai_endpoint_get_returns_405: GET requests return 405test_ai_endpoint_put_returns_405: PUT requests return 405test_ai_endpoint_delete_returns_405: DELETE requests return 405test_ai_endpoint_no_auth_returns_401: No auth header returns 401test_multipart_parsing_with_multiple_blobs: Parse 4 parts (event + 3 blobs)test_multipart_parsing_with_mixed_content_types: JSON, text, binarytest_multipart_parsing_with_large_blob: Large blob (~100KB)test_multipart_parsing_with_empty_blob: Empty blob handlingtest_multipart_missing_boundary_returns_400: Missing boundary parametertest_multipart_corrupted_boundary_returns_400: Mismatched boundary$ai_generation, $ai_trace, $ai_span, $ai_embedding, $ai_metric, $ai_feedback) are processed; invalid events rejected with proper error messagestest_all_allowed_ai_event_types_accepted: All six accepted event types pass validationtest_invalid_ai_event_type_returns_400: Invalid AI event types rejected (e.g., $ai_unknown, $ai_custom)test_invalid_event_name_not_ai_prefix_returns_400: Non-AI event names rejectedtest_invalid_event_name_regular_event_returns_400: Regular events rejected (e.g., $pageview)test_invalid_event_name_custom_event_returns_400: Custom events rejectedtest_missing_required_ai_properties_returns_400: Missing $ai_modeltest_empty_event_name_returns_400: Empty event namestest_missing_distinct_id_returns_400: Missing distinct_idtest_multipart_event_not_first_returns_400: Event part orderingmultipart/form-data acceptedtest_ai_endpoint_wrong_content_type_returns_400: Non-multipart typetest_ai_endpoint_empty_body_returns_400: Empty bodytest_ai_event_published_to_kafka: Basic event publishing verificationtest_ai_event_with_blobs_published_with_s3_placeholders: S3 placeholder URL format and sequential rangestest_ai_event_with_multiple_blobs_sequential_ranges: Multiple blobs with correct sequential byte rangestest_ai_event_metadata_preserved_in_kafka: Event metadata preservation in KafkaContent-Encoding: gzipLocation: rust/capture/tests/integration_ai_endpoint.rs
Framework: Tokio async tests with axum-test-helper
Dependencies:
reqwest with multipart feature for constructing test requestsaxum-test-helper for in-memory HTTP testingserde_json for JSON manipulation# Run all AI endpoint integration tests
cargo test --test integration_ai_endpoint
# Run specific test
cargo test --test integration_ai_endpoint test_multipart_parsing_with_multiple_blobs
# Run with detailed output
cargo test --test integration_ai_endpoint -- --nocapture