From f8653ebc26237a475cac7de0414921d63fe9729c Mon Sep 17 00:00:00 2001 From: Anibal Angulo Date: Thu, 5 Mar 2026 18:28:25 +0000 Subject: [PATCH] Update dependencies --- COVERAGE_SUMMARY.md | 286 -- OBSERVABILITY.md | 327 -- SECURITY_IMPROVEMENTS.md | 169 - TEST_COVERAGE_REPORT.md | 186 -- coverage.html | 6271 -------------------------------------- go.mod | 68 +- go.sum | 228 +- test_output.txt | 916 ------ test_output_fixed.txt | 13 - test_security_fixes.sh | 98 - 10 files changed, 113 insertions(+), 8449 deletions(-) delete mode 100644 COVERAGE_SUMMARY.md delete mode 100644 OBSERVABILITY.md delete mode 100644 SECURITY_IMPROVEMENTS.md delete mode 100644 TEST_COVERAGE_REPORT.md delete mode 100644 coverage.html delete mode 100644 test_output.txt delete mode 100644 test_output_fixed.txt delete mode 100755 test_security_fixes.sh diff --git a/COVERAGE_SUMMARY.md b/COVERAGE_SUMMARY.md deleted file mode 100644 index 356f17f..0000000 --- a/COVERAGE_SUMMARY.md +++ /dev/null @@ -1,286 +0,0 @@ -# Test Coverage Summary Report - -## Overall Results - -**Total Coverage: 46.9%** (when including cmd/gateway with 0% coverage) -**Internal Packages Coverage: ~51%** (excluding cmd/gateway) - -### Test Results by Package - -| Package | Status | Coverage | Tests | Notes | -|---------|--------|----------|-------|-------| -| internal/api | ✅ PASS | 100.0% | All passing | Already complete | -| internal/auth | ✅ PASS | 91.7% | All passing | Good coverage | -| internal/config | ✅ PASS | 100.0% | All passing | Already complete | -| **internal/conversation** | ⚠️ FAIL | **66.0%*** | 45/46 passing | 1 timing test failed | -| internal/logger | ⚠️ NO TESTS | 0.0% | None | Future work | -| **internal/observability** | ⚠️ FAIL | **34.5%*** | 36/44 passing | 8 timing/config tests failed | -| internal/providers | ✅ PASS | 63.1% | All passing | Good baseline | -| internal/providers/anthropic | ✅ PASS | 16.2% | All passing | Can be enhanced | -| internal/providers/google | ✅ PASS | 27.7% | All passing | Can be enhanced | -| internal/providers/openai | ✅ PASS | 16.1% | All passing | Can be enhanced | -| internal/ratelimit | ✅ PASS | 87.2% | All passing | Good coverage | -| internal/server | ✅ PASS | 90.8% | All passing | Excellent coverage | -| cmd/gateway | ⚠️ NO TESTS | 0.0% | None | Low priority | - -*Despite test failures, coverage was measured for code that was executed - -## Detailed Coverage Analysis - -### 🎯 Conversation Package (66.0% coverage) - -#### Memory Store (100%) -- ✅ NewMemoryStore: 100% -- ✅ Get: 100% -- ✅ Create: 100% -- ✅ Append: 100% -- ✅ Delete: 100% -- ✅ Size: 100% -- ⚠️ cleanup: 36.4% (background goroutine) -- ⚠️ Close: 0% (not tested) - -#### SQL Store (81.8% average) -- ✅ NewSQLStore: 85.7% -- ✅ Get: 81.8% -- ✅ Create: 85.7% -- ✅ Append: 69.2% -- ✅ Delete: 100% -- ✅ Size: 100% -- ✅ cleanup: 71.4% -- ✅ Close: 100% -- ⚠️ newDialect: 66.7% (postgres/mysql branches not tested) - -#### Redis Store (87.2% average) -- ✅ NewRedisStore: 100% -- ✅ key: 100% -- ✅ Get: 77.8% -- ✅ Create: 87.5% -- ✅ Append: 69.2% -- ✅ Delete: 100% -- ✅ Size: 91.7% -- ✅ Close: 100% - -**Test Failures:** -- ❌ TestSQLStore_Cleanup (1 failure) - Timing issue with TTL cleanup goroutine -- ❌ TestSQLStore_ConcurrentAccess (partial) - SQLite in-memory concurrency limitations - -**Tests Passing: 45/46** - -### 🎯 Observability Package (34.5% coverage) - -#### Metrics (100%) -- ✅ InitMetrics: 100% -- ✅ RecordCircuitBreakerStateChange: 100% -- ⚠️ MetricsMiddleware: 0% (HTTP middleware not tested yet) - -#### Tracing (Mixed) -- ✅ NewTestTracer: 100% -- ✅ NewTestRegistry: 100% -- ⚠️ InitTracer: Partially tested (schema URL conflicts in test env) -- ⚠️ createSampler: Tested but with naming issues -- ⚠️ Shutdown: Tested - -#### Provider Wrapper (93.9% average) -- ✅ NewInstrumentedProvider: 100% -- ✅ Name: 100% -- ✅ Generate: 100% -- ⚠️ GenerateStream: 81.5% (some streaming edge cases) - -#### Store Wrapper (0%) -- ⚠️ Not tested yet (all functions 0%) - -**Test Failures:** -- ❌ TestInitTracer_StdoutExporter (3 variations) - OpenTelemetry schema URL conflicts -- ❌ TestInitTracer_InvalidExporter - Same schema issue -- ❌ TestInstrumentedProvider_GenerateStream (3 variations) - Timing and channel coordination issues -- ❌ TestInstrumentedProvider_StreamTTFB - Timing issue with TTFB measurement - -**Tests Passing: 36/44** - -## Function-Level Coverage Highlights - -### High Coverage Functions (>90%) -``` -✅ conversation.NewMemoryStore: 100% -✅ conversation.Get (memory): 100% -✅ conversation.Create (memory): 100% -✅ conversation.NewRedisStore: 100% -✅ observability.InitMetrics: 100% -✅ observability.NewInstrumentedProvider: 100% -✅ observability.Generate: 100% -✅ sql_store.Delete: 100% -✅ redis_store.Delete: 100% -``` - -### Medium Coverage Functions (60-89%) -``` -⚠️ conversation.sql_store.Get: 81.8% -⚠️ conversation.sql_store.Create: 85.7% -⚠️ conversation.redis_store.Get: 77.8% -⚠️ conversation.redis_store.Create: 87.5% -⚠️ observability.GenerateStream: 81.5% -⚠️ sql_store.cleanup: 71.4% -⚠️ redis_store.Append: 69.2% -⚠️ sql_store.Append: 69.2% -``` - -### Low/No Coverage Functions -``` -❌ observability.WrapProviderRegistry: 0% -❌ observability.WrapConversationStore: 0% -❌ observability.store_wrapper.*: 0% (all functions) -❌ observability.MetricsMiddleware: 0% -❌ logger.*: 0% (all functions) -❌ conversation.testing helpers: 0% (not used by tests yet) -``` - -## Test Failure Analysis - -### Non-Critical Failures (8 tests) - -#### 1. Timing-Related (5 failures) -- **TestSQLStore_Cleanup**: TTL cleanup goroutine timing -- **TestInstrumentedProvider_GenerateStream**: Channel coordination timing -- **TestInstrumentedProvider_StreamTTFB**: TTFB measurement timing -- **Impact**: Low - functionality works, tests need timing adjustments - -#### 2. Configuration Issues (3 failures) -- **TestInitTracer_***: OpenTelemetry schema URL conflicts in test environment -- **Root Cause**: Testing library uses different OTel schema version -- **Impact**: Low - actual tracing works in production - -#### 3. Concurrency Limitations (1 failure) -- **TestSQLStore_ConcurrentAccess**: SQLite in-memory shared cache issues -- **Impact**: Low - real databases (PostgreSQL/MySQL) handle concurrency correctly - -### All Failures Are Test Environment Issues -✅ **Production functionality is not affected** - all failures are test harness issues, not code bugs - -## Coverage Improvements Achieved - -### Before Implementation -- **Overall**: 37.9% -- **Conversation Stores**: 0% (SQL/Redis) -- **Observability**: 0% (metrics/tracing/wrappers) - -### After Implementation -- **Overall**: 46.9% (51% excluding cmd/gateway) -- **Conversation Stores**: 66.0% (+66%) -- **Observability**: 34.5% (+34.5%) - -### Improvement: +9-13 percentage points overall - -## Test Statistics - -- **Total Test Functions Created**: 72 -- **Total Lines of Test Code**: ~2,000 -- **Tests Passing**: 81/90 (90%) -- **Tests Failing**: 8/90 (9%) - all non-critical -- **Tests Not Run**: 1/90 (1%) - cancelled context test - -### Test Coverage by Category -- **Unit Tests**: 68 functions -- **Integration Tests**: 4 functions (store concurrent access) -- **Helper Functions**: 10+ utilities - -## Recommendations - -### Priority 1: Quick Fixes (1-2 hours) -1. **Fix timing tests**: Add better synchronization for cleanup/streaming tests -2. **Skip problematic tests**: Mark schema conflict tests as skip in CI -3. **Document known issues**: Add comments explaining test environment limitations - -### Priority 2: Coverage Improvements (4-6 hours) -1. **Logger tests**: Add comprehensive logger tests (0% → 80%+) -2. **Store wrapper tests**: Test observability.InstrumentedStore (0% → 70%+) -3. **Metrics middleware**: Test HTTP metrics collection (0% → 80%+) - -### Priority 3: Enhanced Coverage (8-12 hours) -1. **Provider tests**: Enhance anthropic/google/openai (16-28% → 60%+) -2. **Init wrapper tests**: Test WrapProviderRegistry/WrapConversationStore -3. **Integration tests**: Add end-to-end request flow tests - -## Quality Metrics - -### Test Quality Indicators -- ✅ **Table-driven tests**: 100% compliance -- ✅ **Proper assertions**: testify/assert usage throughout -- ✅ **Test isolation**: No shared state between tests -- ✅ **Error path testing**: All error branches tested -- ✅ **Concurrent testing**: Included for stores -- ✅ **Context handling**: Cancellation tests included -- ✅ **Mock usage**: Proper mock patterns followed - -### Code Quality Indicators -- ✅ **No test compilation errors**: All tests build successfully -- ✅ **No race conditions detected**: Tests pass under race detector -- ✅ **Proper cleanup**: defer statements for resource cleanup -- ✅ **Good test names**: Descriptive test function names -- ✅ **Helper functions**: Reusable test utilities created - -## Running Tests - -### Full Test Suite -```bash -go test ./... -v -``` - -### With Coverage -```bash -go test ./... -coverprofile=coverage.out -go tool cover -html=coverage.out -``` - -### Specific Packages -```bash -go test -v ./internal/conversation/... -go test -v ./internal/observability/... -``` - -### With Race Detector -```bash -go test -race ./... -``` - -### Coverage Report -```bash -go tool cover -func=coverage.out | grep "total" -``` - -## Files Created - -### Test Files (5 new files) -1. `internal/observability/metrics_test.go` - 18 test functions -2. `internal/observability/tracing_test.go` - 11 test functions -3. `internal/observability/provider_wrapper_test.go` - 12 test functions -4. `internal/conversation/sql_store_test.go` - 16 test functions -5. `internal/conversation/redis_store_test.go` - 15 test functions - -### Helper Files (2 new files) -1. `internal/observability/testing.go` - Test utilities -2. `internal/conversation/testing.go` - Store test helpers - -### Documentation (2 new files) -1. `TEST_COVERAGE_REPORT.md` - Implementation summary -2. `COVERAGE_SUMMARY.md` - This detailed coverage report - -## Conclusion - -The test coverage improvement project successfully: - -✅ **Increased overall coverage by 9-13 percentage points** -✅ **Added 72 new test functions covering critical untested areas** -✅ **Achieved 66% coverage for conversation stores (from 0%)** -✅ **Achieved 34.5% coverage for observability (from 0%)** -✅ **Maintained 90% test pass rate** (failures are all test environment issues) -✅ **Followed established testing patterns and best practices** -✅ **Created reusable test infrastructure and helpers** - -The 8 failing tests are all related to test environment limitations (timing, schema conflicts, SQLite concurrency) and do not indicate production issues. All critical functionality is working correctly. - ---- - -**Generated**: 2026-03-05 -**Test Coverage**: 46.9% overall (51% internal packages) -**Tests Passing**: 81/90 (90%) -**Lines of Test Code**: ~2,000 diff --git a/OBSERVABILITY.md b/OBSERVABILITY.md deleted file mode 100644 index 2fee971..0000000 --- a/OBSERVABILITY.md +++ /dev/null @@ -1,327 +0,0 @@ -# Observability Implementation - -This document describes the observability features implemented in the LLM Gateway. - -## Overview - -The gateway now includes comprehensive observability with: -- **Prometheus Metrics**: Track HTTP requests, provider calls, token usage, and conversation operations -- **OpenTelemetry Tracing**: Distributed tracing with OTLP exporter support -- **Enhanced Logging**: Trace context correlation for log aggregation - -## Configuration - -Add the following to your `config.yaml`: - -```yaml -observability: - enabled: true # Master switch for all observability features - - metrics: - enabled: true - path: "/metrics" # Prometheus metrics endpoint - - tracing: - enabled: true - service_name: "llm-gateway" - sampler: - type: "probability" # "always", "never", or "probability" - rate: 0.1 # 10% sampling rate - exporter: - type: "otlp" # "otlp" for production, "stdout" for development - endpoint: "localhost:4317" # OTLP collector endpoint - insecure: true # Use insecure connection (for development) - # headers: # Optional authentication headers - # authorization: "Bearer your-token" -``` - -## Metrics - -### HTTP Metrics -- `http_requests_total` - Total HTTP requests (labels: method, path, status) -- `http_request_duration_seconds` - Request latency histogram -- `http_request_size_bytes` - Request body size histogram -- `http_response_size_bytes` - Response body size histogram - -### Provider Metrics -- `provider_requests_total` - Provider API calls (labels: provider, model, operation, status) -- `provider_request_duration_seconds` - Provider latency histogram -- `provider_tokens_total` - Token usage (labels: provider, model, type=input/output) -- `provider_stream_ttfb_seconds` - Time to first byte for streaming -- `provider_stream_chunks_total` - Stream chunk count -- `provider_stream_duration_seconds` - Total stream duration - -### Conversation Store Metrics -- `conversation_operations_total` - Store operations (labels: operation, backend, status) -- `conversation_operation_duration_seconds` - Store operation latency -- `conversation_active_count` - Current number of conversations (gauge) - -### Example Queries - -```promql -# Request rate -rate(http_requests_total[5m]) - -# P95 latency -histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) - -# Error rate -rate(http_requests_total{status=~"5.."}[5m]) - -# Tokens per minute by model -rate(provider_tokens_total[1m]) * 60 - -# Provider latency by model -histogram_quantile(0.95, rate(provider_request_duration_seconds_bucket[5m])) by (provider, model) -``` - -## Tracing - -### Trace Structure - -Each request creates a trace with the following span hierarchy: -``` -HTTP GET /v1/responses -├── provider.generate or provider.generate_stream -├── conversation.get (if using previous_response_id) -└── conversation.create (to store result) -``` - -### Span Attributes - -HTTP spans include: -- `http.method`, `http.route`, `http.status_code` -- `http.request_id` - Request ID for correlation -- `trace_id`, `span_id` - For log correlation - -Provider spans include: -- `provider.name`, `provider.model` -- `provider.input_tokens`, `provider.output_tokens` -- `provider.chunk_count`, `provider.ttfb_seconds` (for streaming) - -Conversation spans include: -- `conversation.id`, `conversation.backend` -- `conversation.message_count`, `conversation.model` - -### Log Correlation - -Logs now include `trace_id` and `span_id` fields when tracing is enabled, allowing you to: -1. Find all logs for a specific trace -2. Jump from a log entry to the corresponding trace in Jaeger/Tempo - -Example log entry: -```json -{ - "time": "2026-03-03T06:36:44Z", - "level": "INFO", - "msg": "response generated", - "request_id": "74722802-6be1-4e14-8e73-d86823fed3e3", - "trace_id": "5d8a7c3f2e1b9a8c7d6e5f4a3b2c1d0e", - "span_id": "1a2b3c4d5e6f7a8b", - "provider": "openai", - "model": "gpt-4o-mini", - "input_tokens": 23, - "output_tokens": 156 -} -``` - -## Testing Observability - -### 1. Test Metrics Endpoint - -```bash -# Start the gateway with observability enabled -./bin/gateway -config config.yaml - -# Query metrics endpoint -curl http://localhost:8080/metrics -``` - -Expected output includes: -``` -# HELP http_requests_total Total number of HTTP requests -# TYPE http_requests_total counter -http_requests_total{method="GET",path="/metrics",status="200"} 1 - -# HELP conversation_active_count Number of active conversations -# TYPE conversation_active_count gauge -conversation_active_count{backend="memory"} 0 -``` - -### 2. Test Tracing with Stdout Exporter - -Set up config with stdout exporter for quick testing: - -```yaml -observability: - enabled: true - tracing: - enabled: true - sampler: - type: "always" - exporter: - type: "stdout" -``` - -Make a request and check the logs for JSON-formatted spans. - -### 3. Test Tracing with Jaeger - -Run Jaeger with OTLP support: - -```bash -docker run -d --name jaeger \ - -e COLLECTOR_OTLP_ENABLED=true \ - -p 4317:4317 \ - -p 16686:16686 \ - jaegertracing/all-in-one:latest -``` - -Update config: -```yaml -observability: - enabled: true - tracing: - enabled: true - sampler: - type: "probability" - rate: 1.0 # 100% for testing - exporter: - type: "otlp" - endpoint: "localhost:4317" - insecure: true -``` - -Make requests and view traces at http://localhost:16686 - -### 4. End-to-End Test - -```bash -# Make a test request -curl -X POST http://localhost:8080/v1/responses \ - -H "Content-Type: application/json" \ - -d '{ - "model": "gpt-4o-mini", - "input": "Hello, world!" - }' - -# Check metrics -curl http://localhost:8080/metrics | grep -E "(http_requests|provider_)" - -# Expected metrics updates: -# - http_requests_total incremented -# - provider_requests_total incremented -# - provider_tokens_total incremented for input and output -# - provider_request_duration_seconds updated -``` - -### 5. Load Test - -```bash -# Install hey if needed -go install github.com/rakyll/hey@latest - -# Run load test -hey -n 1000 -c 10 -m POST \ - -H "Content-Type: application/json" \ - -d '{"model":"gpt-4o-mini","input":"test"}' \ - http://localhost:8080/v1/responses - -# Check metrics for aggregated data -curl http://localhost:8080/metrics | grep http_request_duration_seconds -``` - -## Integration with Monitoring Stack - -### Prometheus - -Add to `prometheus.yml`: - -```yaml -scrape_configs: - - job_name: 'llm-gateway' - static_configs: - - targets: ['localhost:8080'] - metrics_path: '/metrics' - scrape_interval: 15s -``` - -### Grafana - -Import dashboards for: -- HTTP request rates and latencies -- Provider performance by model -- Token usage and costs -- Error rates and types - -### Tempo/Jaeger - -The gateway exports traces via OTLP protocol. Configure your trace backend to accept OTLP on port 4317 (gRPC). - -## Architecture - -### Middleware Chain - -``` -Client Request - ↓ -loggingMiddleware (request ID, logging) - ↓ -tracingMiddleware (W3C Trace Context, spans) - ↓ -metricsMiddleware (Prometheus metrics) - ↓ -rateLimitMiddleware (rate limiting) - ↓ -authMiddleware (authentication) - ↓ -Application Routes -``` - -### Instrumentation Pattern - -- **Providers**: Wrapped with `InstrumentedProvider` that tracks calls, latency, and token usage -- **Conversation Store**: Wrapped with `InstrumentedStore` that tracks operations and size -- **HTTP Layer**: Middleware captures request/response metrics and creates trace spans - -### W3C Trace Context - -The gateway supports W3C Trace Context propagation: -- Extracts `traceparent` header from incoming requests -- Creates child spans for downstream operations -- Propagates context through the entire request lifecycle - -## Performance Impact - -Observability features have minimal overhead: -- Metrics: < 1% latency increase -- Tracing (10% sampling): < 2% latency increase -- Tracing (100% sampling): < 5% latency increase - -Recommended configuration for production: -- Metrics: Enabled -- Tracing: Enabled with 10-20% sampling rate -- Exporter: OTLP to dedicated collector - -## Troubleshooting - -### Metrics endpoint returns 404 -- Check `observability.metrics.enabled` is `true` -- Verify `observability.enabled` is `true` -- Check `observability.metrics.path` configuration - -### No traces appearing in Jaeger -- Verify OTLP collector is running on configured endpoint -- Check sampling rate (try `type: "always"` for testing) -- Look for tracer initialization errors in logs -- Verify `observability.tracing.enabled` is `true` - -### High memory usage -- Reduce trace sampling rate -- Check for metric cardinality explosion (too many label combinations) -- Consider using recording rules in Prometheus - -### Missing trace IDs in logs -- Ensure tracing is enabled -- Check that requests are being sampled (sampling rate > 0) -- Verify OpenTelemetry dependencies are correctly installed diff --git a/SECURITY_IMPROVEMENTS.md b/SECURITY_IMPROVEMENTS.md deleted file mode 100644 index 01c0887..0000000 --- a/SECURITY_IMPROVEMENTS.md +++ /dev/null @@ -1,169 +0,0 @@ -# Security Improvements - March 2026 - -This document summarizes the security and reliability improvements made to the go-llm-gateway project. - -## Issues Fixed - -### 1. Request Size Limits (Issue #2) ✅ - -**Problem**: The server had no limits on request body size, making it vulnerable to DoS attacks via oversized payloads. - -**Solution**: Implemented `RequestSizeLimitMiddleware` that enforces a maximum request body size. - -**Implementation Details**: -- Created `internal/server/middleware.go` with `RequestSizeLimitMiddleware` -- Uses `http.MaxBytesReader` to enforce limits at the HTTP layer -- Default limit: 10MB (10,485,760 bytes) -- Configurable via `server.max_request_body_size` in config.yaml -- Returns HTTP 413 (Request Entity Too Large) for oversized requests -- Only applies to POST, PUT, and PATCH requests (not GET/DELETE) - -**Files Modified**: -- `internal/server/middleware.go` (new file) -- `internal/server/server.go` (added 413 error handling) -- `cmd/gateway/main.go` (integrated middleware) -- `internal/config/config.go` (added config field) -- `config.example.yaml` (documented configuration) - -**Testing**: -- Comprehensive test suite in `internal/server/middleware_test.go` -- Tests cover: small payloads, exact size, oversized payloads, different HTTP methods -- Integration test verifies middleware chain behavior - -### 2. Panic Recovery Middleware (Issue #4) ✅ - -**Problem**: Any panic in HTTP handlers would crash the entire server, causing downtime. - -**Solution**: Implemented `PanicRecoveryMiddleware` that catches panics and returns proper error responses. - -**Implementation Details**: -- Created `PanicRecoveryMiddleware` in `internal/server/middleware.go` -- Uses `defer recover()` pattern to catch all panics -- Logs full stack trace with request context for debugging -- Returns HTTP 500 (Internal Server Error) to clients -- Positioned as the outermost middleware to catch panics from all layers - -**Files Modified**: -- `internal/server/middleware.go` (new file) -- `cmd/gateway/main.go` (integrated as outermost middleware) - -**Testing**: -- Tests verify recovery from string panics, error panics, and struct panics -- Integration test confirms panic recovery works through middleware chain -- Logs are captured and verified to include stack traces - -### 3. Error Handling Improvements (Bonus) ✅ - -**Problem**: Multiple instances of ignored JSON encoding errors could lead to incomplete responses. - -**Solution**: Fixed all ignored `json.Encoder.Encode()` errors throughout the codebase. - -**Files Modified**: -- `internal/server/health.go` (lines 32, 86) -- `internal/server/server.go` (lines 72, 217) - -All JSON encoding errors are now logged with proper context including request IDs. - -## Architecture - -### Middleware Chain Order - -The middleware chain is now (from outermost to innermost): -1. **PanicRecoveryMiddleware** - Catches all panics -2. **RequestSizeLimitMiddleware** - Enforces body size limits -3. **loggingMiddleware** - Request/response logging -4. **TracingMiddleware** - OpenTelemetry tracing -5. **MetricsMiddleware** - Prometheus metrics -6. **rateLimitMiddleware** - Rate limiting -7. **authMiddleware** - OIDC authentication -8. **routes** - Application handlers - -This order ensures: -- Panics are caught from all middleware layers -- Size limits are enforced before expensive operations -- All requests are logged, traced, and metered -- Security checks happen closest to the application - -## Configuration - -Add to your `config.yaml`: - -```yaml -server: - address: ":8080" - max_request_body_size: 10485760 # 10MB in bytes (default) -``` - -To customize the size limit: -- **1MB**: `1048576` -- **5MB**: `5242880` -- **10MB**: `10485760` (default) -- **50MB**: `52428800` - -If not specified, defaults to 10MB. - -## Testing - -All new functionality includes comprehensive tests: - -```bash -# Run all tests -go test ./... - -# Run only middleware tests -go test ./internal/server -v -run "TestPanicRecoveryMiddleware|TestRequestSizeLimitMiddleware" - -# Run with coverage -go test ./internal/server -cover -``` - -**Test Coverage**: -- `internal/server/middleware.go`: 100% coverage -- All edge cases covered (panics, size limits, different HTTP methods) -- Integration tests verify middleware chain interactions - -## Production Readiness - -These changes significantly improve production readiness: - -1. **DoS Protection**: Request size limits prevent memory exhaustion attacks -2. **Fault Tolerance**: Panic recovery prevents cascading failures -3. **Observability**: All errors are logged with proper context -4. **Configurability**: Limits can be tuned per deployment environment - -## Remaining Production Concerns - -While these issues are fixed, the following should still be addressed: - -- **HIGH**: Exposed credentials in `.env` file (must rotate and remove from git) -- **MEDIUM**: Observability code has 0% test coverage -- **MEDIUM**: Conversation store has only 27% test coverage -- **LOW**: Missing circuit breaker pattern for provider failures -- **LOW**: No retry logic for failed provider requests - -See the original assessment for complete details. - -## Verification - -Build and verify the changes: - -```bash -# Build the application -go build ./cmd/gateway - -# Run the gateway -./gateway -config config.yaml - -# Test with oversized payload (should return 413) -curl -X POST http://localhost:8080/v1/responses \ - -H "Content-Type: application/json" \ - -d "$(python3 -c 'print("{\"data\":\"" + "x"*11000000 + "\"}")')" -``` - -Expected response: `HTTP 413 Request Entity Too Large` - -## References - -- [OWASP: Unvalidated Redirects and Forwards](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/11-Client-side_Testing/04-Testing_for_Client-side_Resource_Manipulation) -- [CWE-400: Uncontrolled Resource Consumption](https://cwe.mitre.org/data/definitions/400.html) -- [Go HTTP Server Best Practices](https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/) diff --git a/TEST_COVERAGE_REPORT.md b/TEST_COVERAGE_REPORT.md deleted file mode 100644 index 6f3e980..0000000 --- a/TEST_COVERAGE_REPORT.md +++ /dev/null @@ -1,186 +0,0 @@ -# Test Coverage Improvement Report - -## Executive Summary - -Successfully improved test coverage for go-llm-gateway from **37.9% to 51.0%** (+13.1 percentage points). - -## Implementation Summary - -### Completed Work - -#### 1. Test Infrastructure -- ✅ Added test dependencies: `miniredis/v2`, `prometheus/testutil` -- ✅ Created test helper utilities: - - `internal/observability/testing.go` - Helpers for metrics and tracing tests - - `internal/conversation/testing.go` - Helpers for store tests - -#### 2. Observability Package Tests (34.5% coverage) -Created comprehensive tests for metrics, tracing, and instrumentation: - -**Files Created:** -- `internal/observability/metrics_test.go` (~400 lines, 18 test functions) - - TestInitMetrics - - TestRecordCircuitBreakerStateChange - - TestMetricLabels - - TestHTTPMetrics - - TestProviderMetrics - - TestConversationStoreMetrics - - TestMetricHelp, TestMetricTypes, TestMetricNaming - -- `internal/observability/tracing_test.go` (~470 lines, 11 test functions) - - TestInitTracer_StdoutExporter - - TestInitTracer_InvalidExporter - - TestCreateSampler (all sampler types) - - TestShutdown and context handling - - TestProbabilitySampler_Boundaries - -- `internal/observability/provider_wrapper_test.go` (~700 lines, 12 test functions) - - TestNewInstrumentedProvider - - TestInstrumentedProvider_Generate (success/error paths) - - TestInstrumentedProvider_GenerateStream (streaming with TTFB) - - TestInstrumentedProvider_MetricsRecording - - TestInstrumentedProvider_TracingSpans - - TestInstrumentedProvider_ConcurrentCalls - -#### 3. Conversation Store Tests (66.0% coverage) -Created comprehensive tests for SQL and Redis stores: - -**Files Created:** -- `internal/conversation/sql_store_test.go` (~350 lines, 16 test functions) - - TestNewSQLStore - - TestSQLStore_Create, Get, Append, Delete - - TestSQLStore_Size - - TestSQLStore_Cleanup (TTL expiration) - - TestSQLStore_ConcurrentAccess - - TestSQLStore_ContextCancellation - - TestSQLStore_JSONEncoding - - TestSQLStore_EmptyMessages - - TestSQLStore_UpdateExisting - -- `internal/conversation/redis_store_test.go` (~350 lines, 15 test functions) - - TestNewRedisStore - - TestRedisStore_Create, Get, Append, Delete - - TestRedisStore_Size - - TestRedisStore_TTL (expiration testing with miniredis) - - TestRedisStore_KeyStorage - - TestRedisStore_Concurrent - - TestRedisStore_JSONEncoding - - TestRedisStore_EmptyMessages - - TestRedisStore_UpdateExisting - - TestRedisStore_ContextCancellation - - TestRedisStore_ScanPagination - -## Coverage Breakdown by Package - -| Package | Before | After | Change | -|---------|--------|-------|--------| -| **Overall** | **37.9%** | **51.0%** | **+13.1%** | -| internal/api | 100.0% | 100.0% | - | -| internal/auth | 91.7% | 91.7% | - | -| internal/config | 100.0% | 100.0% | - | -| **internal/conversation** | **0%*** | **66.0%** | **+66.0%** | -| internal/logger | 0.0% | 0.0% | - | -| **internal/observability** | **0%*** | **34.5%** | **+34.5%** | -| internal/providers | 63.1% | 63.1% | - | -| internal/providers/anthropic | 16.2% | 16.2% | - | -| internal/providers/google | 27.7% | 27.7% | - | -| internal/providers/openai | 16.1% | 16.1% | - | -| internal/ratelimit | 87.2% | 87.2% | - | -| internal/server | 90.8% | 90.8% | - | - -*Stores (SQL/Redis) and observability wrappers previously had 0% coverage - -## Detailed Coverage Improvements - -### Conversation Stores (0% → 66.0%) -- **SQL Store**: 85.7% (NewSQLStore), 81.8% (Get), 85.7% (Create), 69.2% (Append), 100% (Delete/Size/Close) -- **Redis Store**: 100% (NewRedisStore), 77.8% (Get), 87.5% (Create), 69.2% (Append), 100% (Delete), 91.7% (Size) -- **Memory Store**: Already had good coverage from existing tests - -### Observability (0% → 34.5%) -- **Metrics**: 100% (InitMetrics, RecordCircuitBreakerStateChange) -- **Tracing**: Comprehensive sampler and tracer initialization tests -- **Provider Wrapper**: Full instrumentation testing with metrics and spans -- **Store Wrapper**: Not yet tested (future work) - -## Test Quality & Patterns - -All new tests follow established patterns from the codebase: -- ✅ Table-driven tests with `t.Run()` -- ✅ testify/assert and testify/require for assertions -- ✅ Custom mocks with function injection -- ✅ Proper test isolation (no shared state) -- ✅ Concurrent access testing -- ✅ Context cancellation testing -- ✅ Error path coverage - -## Known Issues & Future Work - -### Minor Test Failures (Non-Critical) -1. **Observability streaming tests**: Some streaming tests have timing issues (3 failing) -2. **Tracing schema conflicts**: OpenTelemetry schema URL conflicts in test environment (4 failing) -3. **SQL concurrent test**: SQLite in-memory concurrency issue (1 failing) - -These failures don't affect functionality and can be addressed in follow-up work. - -### Remaining Low Coverage Areas (For Future Work) -1. **Logger (0%)** - Not yet tested -2. **Provider implementations (16-28%)** - Could be enhanced -3. **Observability wrappers** - Store wrapper not yet tested -4. **Main entry point** - Low priority integration tests - -## Files Created - -### New Test Files (5) -1. `internal/observability/metrics_test.go` -2. `internal/observability/tracing_test.go` -3. `internal/observability/provider_wrapper_test.go` -4. `internal/conversation/sql_store_test.go` -5. `internal/conversation/redis_store_test.go` - -### Helper Files (2) -1. `internal/observability/testing.go` -2. `internal/conversation/testing.go` - -**Total**: ~2,000 lines of test code, 72 new test functions - -## Running the Tests - -```bash -# Run all tests -make test - -# Run tests with coverage -go test -cover ./... - -# Generate coverage report -go test -coverprofile=coverage.out ./... -go tool cover -html=coverage.out - -# Run specific package tests -go test -v ./internal/conversation/... -go test -v ./internal/observability/... -``` - -## Impact & Benefits - -1. **Quality Assurance**: Critical storage backends now have comprehensive test coverage -2. **Regression Prevention**: Tests catch issues in Redis/SQL store operations -3. **Documentation**: Tests serve as usage examples for stores and observability -4. **Confidence**: Developers can refactor with confidence -5. **CI/CD**: Better test coverage improves deployment confidence - -## Recommendations - -1. **Address timing issues**: Fix streaming and concurrent test flakiness -2. **Add logger tests**: Quick win to boost coverage (small package) -3. **Enhance provider tests**: Improve anthropic/google/openai coverage to 60%+ -4. **Integration tests**: Add end-to-end tests for complete request flows -5. **Benchmark tests**: Add performance benchmarks for stores - ---- - -**Report Generated**: 2026-03-05 -**Coverage Improvement**: 37.9% → 51.0% (+13.1 percentage points) -**Test Lines Added**: ~2,000 lines -**Test Functions Added**: 72 functions diff --git a/coverage.html b/coverage.html deleted file mode 100644 index fe2dae4..0000000 --- a/coverage.html +++ /dev/null @@ -1,6271 +0,0 @@ - - - - - - gateway: Go Coverage Report - - - -
- -
- not tracked - - not covered - covered - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - diff --git a/go.mod b/go.mod index 9579a93..294f965 100644 --- a/go.mod +++ b/go.mod @@ -10,42 +10,43 @@ require ( github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.8.0 github.com/mattn/go-sqlite3 v1.14.34 - github.com/openai/openai-go/v3 v3.2.0 + github.com/openai/openai-go/v3 v3.24.0 github.com/prometheus/client_golang v1.23.2 github.com/redis/go-redis/v9 v9.18.0 github.com/sony/gobreaker v1.0.0 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/otel v1.29.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0 - go.opentelemetry.io/otel/sdk v1.29.0 - go.opentelemetry.io/otel/trace v1.29.0 + go.opentelemetry.io/otel v1.41.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0 + go.opentelemetry.io/otel/sdk v1.41.0 + go.opentelemetry.io/otel/trace v1.41.0 golang.org/x/time v0.14.0 - google.golang.org/genai v1.48.0 - google.golang.org/grpc v1.66.2 + google.golang.org/genai v1.49.0 + google.golang.org/grpc v1.79.1 gopkg.in/yaml.v3 v3.0.1 ) require ( - cloud.google.com/go v0.116.0 // indirect - cloud.google.com/go/auth v0.9.3 // indirect - cloud.google.com/go/compute/metadata v0.5.0 // indirect - filippo.io/edwards25519 v1.1.0 // indirect + cloud.google.com/go v0.123.0 // indirect + cloud.google.com/go/auth v0.18.2 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect + filippo.io/edwards25519 v1.2.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/s2a-go v0.1.8 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.13 // indirect + github.com/googleapis/gax-go/v2 v2.17.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -53,25 +54,26 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.20.1 // indirect github.com/tidwall/gjson v1.18.0 // indirect - github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/gopher-lua v1.1.1 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect - go.opentelemetry.io/otel/metric v1.29.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.66.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect + go.opentelemetry.io/otel/metric v1.41.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.47.0 // indirect - golang.org/x/net v0.49.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.33.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + google.golang.org/protobuf v1.36.11 // indirect ) diff --git a/go.sum b/go.sum index 5cc9a19..fc62926 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,11 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= -cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= -cloud.google.com/go/auth v0.9.3 h1:VOEUIAADkkLtyfr3BLa3R8Ed/j6w1jTBmARx+wb5w5U= -cloud.google.com/go/auth v0.9.3/go.mod h1:7z6VY+7h3KUdRov5F1i8NDP5ZzWKYmEPO842BgCsmTk= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= +cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= +cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= +filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4= @@ -15,7 +14,6 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDo github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/alicebob/miniredis/v2 v2.37.0 h1:RheObYW32G1aiJIj81XVt78ZHJpHonHLHW7OLIshq68= github.com/alicebob/miniredis/v2 v2.37.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/anthropics/anthropic-sdk-go v1.26.0 h1:oUTzFaUpAevfuELAP1sjL6CQJ9HHAfT7CoSYSac11PY= @@ -26,13 +24,10 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -40,52 +35,33 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= -github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= -github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= +github.com/googleapis/enterprise-certificate-proxy v0.3.13 h1:hSPAhW3NX+7HNlTsmrvU0jL75cIzxFktheceg95Nq14= +github.com/googleapis/enterprise-certificate-proxy v0.3.13/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= +github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= @@ -108,42 +84,37 @@ github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/openai/openai-go/v3 v3.2.0 h1:2AbqFUCsoW2pm/2pUtPRuwK89dnoGHaQokzWsfoQO/U= -github.com/openai/openai-go/v3 v3.2.0/go.mod h1:UOpNxkqC9OdNXNUfpNByKOtB4jAL0EssQXq5p8gO0Xs= +github.com/openai/openai-go/v3 v3.24.0 h1:08x6GnYiB+AAejTo6yzPY8RkZMJQ8NpreiOyM5QfyYU= +github.com/openai/openai-go/v3 v3.24.0/go.mod h1:cdufnVK14cWcT9qA1rRtrXx4FTRsgbDPW7Ia7SS5cZo= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/redis/go-redis/v9 v9.18.0 h1:pMkxYPkEbMPwRdenAzUNyFNrDgHx9U+DrBabWNfSRQs= github.com/redis/go-redis/v9 v9.18.0/go.mod h1:k3ufPphLU5YXwNTUcCRXGxUoF1fqxnhFQmscfkCoDA0= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sony/gobreaker v1.0.0 h1:feX5fGGXSl3dYd4aHZItw+FpHLvvoaqkawKjVNiFMNQ= github.com/sony/gobreaker v1.0.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= +github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -153,99 +124,58 @@ github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0 h1:X3ZjNp36/WlkSYx0ul2jw4PtbNEDDeLskw3VPsrpYM0= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0/go.mod h1:2uL/xnOXh0CHOBFCWXz5u1A4GXLiW+0IQIzVbeOEQ0U= -go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= -go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= -go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.66.0 h1:PnV4kVnw0zOmwwFkAzCN5O07fw1YOIQor120zrh0AVo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.66.0/go.mod h1:ofAwF4uinaf8SXdVzzbL4OsxJ3VfeEg3f/F6CeF49/Y= +go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= +go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0 h1:61oRQmYGMW7pXmFjPg1Muy84ndqMxQ6SH2L8fBG8fSY= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0/go.mod h1:c0z2ubK4RQL+kSDuuFu9WnuXimObon3IiKjJf4NACvU= +go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= +go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= +go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= +go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90= +go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8= +go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y= +go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= +go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genai v1.48.0 h1:1vb15G291wAjJJueisMDpUhssljhEdJU2t5qTidrVPs= -google.golang.org/genai v1.48.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= -google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genai v1.49.0 h1:Se+QJaH2GYK1aaR1o5S38mlU2GD5FnVvP76nfkV7LH0= +google.golang.org/genai v1.49.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -254,5 +184,3 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/test_output.txt b/test_output.txt deleted file mode 100644 index 9ad252e..0000000 --- a/test_output.txt +++ /dev/null @@ -1,916 +0,0 @@ - github.com/ajac-zero/latticelm/cmd/gateway coverage: 0.0% of statements -=== RUN TestInputUnion_UnmarshalJSON -=== RUN TestInputUnion_UnmarshalJSON/string_input -=== RUN TestInputUnion_UnmarshalJSON/empty_string_input -=== RUN TestInputUnion_UnmarshalJSON/null_input -=== RUN TestInputUnion_UnmarshalJSON/array_input_with_single_message -=== RUN TestInputUnion_UnmarshalJSON/array_input_with_multiple_messages -=== RUN TestInputUnion_UnmarshalJSON/empty_array -=== RUN TestInputUnion_UnmarshalJSON/array_with_function_call_output -=== RUN TestInputUnion_UnmarshalJSON/invalid_JSON -=== RUN TestInputUnion_UnmarshalJSON/invalid_type_-_number -=== RUN TestInputUnion_UnmarshalJSON/invalid_type_-_object ---- PASS: TestInputUnion_UnmarshalJSON (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/string_input (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/empty_string_input (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/null_input (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/array_input_with_single_message (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/array_input_with_multiple_messages (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/empty_array (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/array_with_function_call_output (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/invalid_JSON (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/invalid_type_-_number (0.00s) - --- PASS: TestInputUnion_UnmarshalJSON/invalid_type_-_object (0.00s) -=== RUN TestInputUnion_MarshalJSON -=== RUN TestInputUnion_MarshalJSON/string_value -=== RUN TestInputUnion_MarshalJSON/empty_string -=== RUN TestInputUnion_MarshalJSON/array_value -=== RUN TestInputUnion_MarshalJSON/empty_array -=== RUN TestInputUnion_MarshalJSON/nil_values ---- PASS: TestInputUnion_MarshalJSON (0.00s) - --- PASS: TestInputUnion_MarshalJSON/string_value (0.00s) - --- PASS: TestInputUnion_MarshalJSON/empty_string (0.00s) - --- PASS: TestInputUnion_MarshalJSON/array_value (0.00s) - --- PASS: TestInputUnion_MarshalJSON/empty_array (0.00s) - --- PASS: TestInputUnion_MarshalJSON/nil_values (0.00s) -=== RUN TestInputUnion_RoundTrip -=== RUN TestInputUnion_RoundTrip/string -=== RUN TestInputUnion_RoundTrip/array_with_messages ---- PASS: TestInputUnion_RoundTrip (0.00s) - --- PASS: TestInputUnion_RoundTrip/string (0.00s) - --- PASS: TestInputUnion_RoundTrip/array_with_messages (0.00s) -=== RUN TestResponseRequest_NormalizeInput -=== RUN TestResponseRequest_NormalizeInput/string_input_creates_user_message -=== RUN TestResponseRequest_NormalizeInput/message_with_string_content -=== RUN TestResponseRequest_NormalizeInput/assistant_message_with_string_content_uses_output_text -=== RUN TestResponseRequest_NormalizeInput/message_with_content_blocks_array -=== RUN TestResponseRequest_NormalizeInput/message_with_tool_use_blocks -=== RUN TestResponseRequest_NormalizeInput/message_with_mixed_text_and_tool_use -=== RUN TestResponseRequest_NormalizeInput/multiple_tool_use_blocks -=== RUN TestResponseRequest_NormalizeInput/function_call_output_item -=== RUN TestResponseRequest_NormalizeInput/multiple_messages_in_conversation -=== RUN TestResponseRequest_NormalizeInput/complete_tool_calling_flow -=== RUN TestResponseRequest_NormalizeInput/message_without_type_defaults_to_message -=== RUN TestResponseRequest_NormalizeInput/message_with_nil_content -=== RUN TestResponseRequest_NormalizeInput/tool_use_with_empty_input -=== RUN TestResponseRequest_NormalizeInput/content_blocks_with_unknown_types_ignored ---- PASS: TestResponseRequest_NormalizeInput (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/string_input_creates_user_message (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/message_with_string_content (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/assistant_message_with_string_content_uses_output_text (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/message_with_content_blocks_array (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/message_with_tool_use_blocks (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/message_with_mixed_text_and_tool_use (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/multiple_tool_use_blocks (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/function_call_output_item (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/multiple_messages_in_conversation (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/complete_tool_calling_flow (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/message_without_type_defaults_to_message (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/message_with_nil_content (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/tool_use_with_empty_input (0.00s) - --- PASS: TestResponseRequest_NormalizeInput/content_blocks_with_unknown_types_ignored (0.00s) -=== RUN TestResponseRequest_Validate -=== RUN TestResponseRequest_Validate/valid_request_with_string_input -=== RUN TestResponseRequest_Validate/valid_request_with_array_input -=== RUN TestResponseRequest_Validate/nil_request -=== RUN TestResponseRequest_Validate/missing_model -=== RUN TestResponseRequest_Validate/missing_input -=== RUN TestResponseRequest_Validate/empty_string_input_is_invalid -=== RUN TestResponseRequest_Validate/empty_array_input_is_invalid ---- PASS: TestResponseRequest_Validate (0.00s) - --- PASS: TestResponseRequest_Validate/valid_request_with_string_input (0.00s) - --- PASS: TestResponseRequest_Validate/valid_request_with_array_input (0.00s) - --- PASS: TestResponseRequest_Validate/nil_request (0.00s) - --- PASS: TestResponseRequest_Validate/missing_model (0.00s) - --- PASS: TestResponseRequest_Validate/missing_input (0.00s) - --- PASS: TestResponseRequest_Validate/empty_string_input_is_invalid (0.00s) - --- PASS: TestResponseRequest_Validate/empty_array_input_is_invalid (0.00s) -=== RUN TestGetStringField -=== RUN TestGetStringField/existing_string_field -=== RUN TestGetStringField/missing_field -=== RUN TestGetStringField/wrong_type_-_int -=== RUN TestGetStringField/wrong_type_-_bool -=== RUN TestGetStringField/wrong_type_-_object -=== RUN TestGetStringField/empty_string_value -=== RUN TestGetStringField/nil_map ---- PASS: TestGetStringField (0.00s) - --- PASS: TestGetStringField/existing_string_field (0.00s) - --- PASS: TestGetStringField/missing_field (0.00s) - --- PASS: TestGetStringField/wrong_type_-_int (0.00s) - --- PASS: TestGetStringField/wrong_type_-_bool (0.00s) - --- PASS: TestGetStringField/wrong_type_-_object (0.00s) - --- PASS: TestGetStringField/empty_string_value (0.00s) - --- PASS: TestGetStringField/nil_map (0.00s) -=== RUN TestInputItem_ComplexContent -=== RUN TestInputItem_ComplexContent/content_with_nested_objects -=== RUN TestInputItem_ComplexContent/content_with_array_in_input ---- PASS: TestInputItem_ComplexContent (0.00s) - --- PASS: TestInputItem_ComplexContent/content_with_nested_objects (0.00s) - --- PASS: TestInputItem_ComplexContent/content_with_array_in_input (0.00s) -=== RUN TestResponseRequest_CompleteWorkflow ---- PASS: TestResponseRequest_CompleteWorkflow (0.00s) -PASS -coverage: 100.0% of statements -ok github.com/ajac-zero/latticelm/internal/api 0.011s coverage: 100.0% of statements -=== RUN TestNew -=== RUN TestNew/disabled_auth_returns_empty_middleware -=== RUN TestNew/enabled_without_issuer_returns_error -=== RUN TestNew/enabled_with_valid_config_fetches_JWKS -=== RUN TestNew/JWKS_fetch_failure_returns_error ---- PASS: TestNew (0.00s) - --- PASS: TestNew/disabled_auth_returns_empty_middleware (0.00s) - --- PASS: TestNew/enabled_without_issuer_returns_error (0.00s) - --- PASS: TestNew/enabled_with_valid_config_fetches_JWKS (0.00s) - --- PASS: TestNew/JWKS_fetch_failure_returns_error (0.00s) -=== RUN TestMiddleware_Handler -=== RUN TestMiddleware_Handler/missing_authorization_header -=== RUN TestMiddleware_Handler/malformed_authorization_header_-_no_bearer -=== RUN TestMiddleware_Handler/malformed_authorization_header_-_wrong_scheme -=== RUN TestMiddleware_Handler/valid_token_with_correct_claims -=== RUN TestMiddleware_Handler/expired_token -=== RUN TestMiddleware_Handler/token_with_wrong_issuer -=== RUN TestMiddleware_Handler/token_with_wrong_audience -=== RUN TestMiddleware_Handler/token_with_missing_kid ---- PASS: TestMiddleware_Handler (0.01s) - --- PASS: TestMiddleware_Handler/missing_authorization_header (0.00s) - --- PASS: TestMiddleware_Handler/malformed_authorization_header_-_no_bearer (0.00s) - --- PASS: TestMiddleware_Handler/malformed_authorization_header_-_wrong_scheme (0.00s) - --- PASS: TestMiddleware_Handler/valid_token_with_correct_claims (0.00s) - --- PASS: TestMiddleware_Handler/expired_token (0.00s) - --- PASS: TestMiddleware_Handler/token_with_wrong_issuer (0.00s) - --- PASS: TestMiddleware_Handler/token_with_wrong_audience (0.00s) - --- PASS: TestMiddleware_Handler/token_with_missing_kid (0.00s) -=== RUN TestMiddleware_Handler_DisabledAuth ---- PASS: TestMiddleware_Handler_DisabledAuth (0.00s) -=== RUN TestValidateToken -=== RUN TestValidateToken/valid_token_with_all_required_claims -=== RUN TestValidateToken/token_with_audience_as_array -=== RUN TestValidateToken/token_with_audience_array_not_matching -=== RUN TestValidateToken/token_with_invalid_audience_format -=== RUN TestValidateToken/token_signed_with_wrong_key -=== RUN TestValidateToken/token_with_unknown_kid_triggers_JWKS_refresh -=== RUN TestValidateToken/token_with_completely_unknown_kid_after_refresh -=== RUN TestValidateToken/malformed_token -=== RUN TestValidateToken/token_with_non-RSA_signing_method ---- PASS: TestValidateToken (0.80s) - --- PASS: TestValidateToken/valid_token_with_all_required_claims (0.00s) - --- PASS: TestValidateToken/token_with_audience_as_array (0.00s) - --- PASS: TestValidateToken/token_with_audience_array_not_matching (0.00s) - --- PASS: TestValidateToken/token_with_invalid_audience_format (0.00s) - --- PASS: TestValidateToken/token_signed_with_wrong_key (0.15s) - --- PASS: TestValidateToken/token_with_unknown_kid_triggers_JWKS_refresh (0.42s) - --- PASS: TestValidateToken/token_with_completely_unknown_kid_after_refresh (0.22s) - --- PASS: TestValidateToken/malformed_token (0.00s) - --- PASS: TestValidateToken/token_with_non-RSA_signing_method (0.00s) -=== RUN TestValidateToken_NoAudienceConfigured ---- PASS: TestValidateToken_NoAudienceConfigured (0.00s) -=== RUN TestRefreshJWKS -=== RUN TestRefreshJWKS/successful_JWKS_fetch_and_parse -=== RUN TestRefreshJWKS/OIDC_discovery_failure -=== RUN TestRefreshJWKS/JWKS_with_multiple_keys -=== RUN TestRefreshJWKS/JWKS_with_non-RSA_keys_skipped -=== RUN TestRefreshJWKS/JWKS_with_wrong_use_field_skipped -=== RUN TestRefreshJWKS/JWKS_with_invalid_base64_encoding_skipped ---- PASS: TestRefreshJWKS (0.14s) - --- PASS: TestRefreshJWKS/successful_JWKS_fetch_and_parse (0.00s) - --- PASS: TestRefreshJWKS/OIDC_discovery_failure (0.00s) - --- PASS: TestRefreshJWKS/JWKS_with_multiple_keys (0.14s) - --- PASS: TestRefreshJWKS/JWKS_with_non-RSA_keys_skipped (0.00s) - --- PASS: TestRefreshJWKS/JWKS_with_wrong_use_field_skipped (0.00s) - --- PASS: TestRefreshJWKS/JWKS_with_invalid_base64_encoding_skipped (0.00s) -=== RUN TestRefreshJWKS_Concurrency ---- PASS: TestRefreshJWKS_Concurrency (0.01s) -=== RUN TestGetClaims -=== RUN TestGetClaims/context_with_claims -=== RUN TestGetClaims/context_without_claims -=== RUN TestGetClaims/context_with_wrong_type ---- PASS: TestGetClaims (0.00s) - --- PASS: TestGetClaims/context_with_claims (0.00s) - --- PASS: TestGetClaims/context_without_claims (0.00s) - --- PASS: TestGetClaims/context_with_wrong_type (0.00s) -=== RUN TestMiddleware_IssuerWithTrailingSlash ---- PASS: TestMiddleware_IssuerWithTrailingSlash (0.00s) -PASS -coverage: 91.7% of statements -ok github.com/ajac-zero/latticelm/internal/auth 1.251s coverage: 91.7% of statements -=== RUN TestLoad -=== RUN TestLoad/basic_config_with_all_fields -=== RUN TestLoad/config_with_environment_variables -=== RUN TestLoad/minimal_config -=== RUN TestLoad/azure_openai_provider -=== RUN TestLoad/vertex_ai_provider -=== RUN TestLoad/sql_conversation_store -=== RUN TestLoad/redis_conversation_store -=== RUN TestLoad/invalid_model_references_unknown_provider -=== RUN TestLoad/invalid_YAML -=== RUN TestLoad/multiple_models_same_provider ---- PASS: TestLoad (0.01s) - --- PASS: TestLoad/basic_config_with_all_fields (0.00s) - --- PASS: TestLoad/config_with_environment_variables (0.00s) - --- PASS: TestLoad/minimal_config (0.00s) - --- PASS: TestLoad/azure_openai_provider (0.00s) - --- PASS: TestLoad/vertex_ai_provider (0.00s) - --- PASS: TestLoad/sql_conversation_store (0.00s) - --- PASS: TestLoad/redis_conversation_store (0.00s) - --- PASS: TestLoad/invalid_model_references_unknown_provider (0.00s) - --- PASS: TestLoad/invalid_YAML (0.00s) - --- PASS: TestLoad/multiple_models_same_provider (0.00s) -=== RUN TestLoadNonExistentFile ---- PASS: TestLoadNonExistentFile (0.00s) -=== RUN TestConfigValidate -=== RUN TestConfigValidate/valid_config -=== RUN TestConfigValidate/model_references_unknown_provider -=== RUN TestConfigValidate/no_models -=== RUN TestConfigValidate/multiple_models_multiple_providers ---- PASS: TestConfigValidate (0.00s) - --- PASS: TestConfigValidate/valid_config (0.00s) - --- PASS: TestConfigValidate/model_references_unknown_provider (0.00s) - --- PASS: TestConfigValidate/no_models (0.00s) - --- PASS: TestConfigValidate/multiple_models_multiple_providers (0.00s) -=== RUN TestEnvironmentVariableExpansion ---- PASS: TestEnvironmentVariableExpansion (0.00s) -PASS -coverage: 100.0% of statements -ok github.com/ajac-zero/latticelm/internal/config 0.040s coverage: 100.0% of statements -=== RUN TestMemoryStore_CreateAndGet ---- PASS: TestMemoryStore_CreateAndGet (0.00s) -=== RUN TestMemoryStore_GetNonExistent ---- PASS: TestMemoryStore_GetNonExistent (0.00s) -=== RUN TestMemoryStore_Append ---- PASS: TestMemoryStore_Append (0.00s) -=== RUN TestMemoryStore_AppendNonExistent ---- PASS: TestMemoryStore_AppendNonExistent (0.00s) -=== RUN TestMemoryStore_Delete ---- PASS: TestMemoryStore_Delete (0.00s) -=== RUN TestMemoryStore_Size ---- PASS: TestMemoryStore_Size (0.00s) -=== RUN TestMemoryStore_ConcurrentAccess ---- PASS: TestMemoryStore_ConcurrentAccess (0.00s) -=== RUN TestMemoryStore_DeepCopy ---- PASS: TestMemoryStore_DeepCopy (0.00s) -=== RUN TestMemoryStore_TTLCleanup ---- PASS: TestMemoryStore_TTLCleanup (0.15s) -=== RUN TestMemoryStore_NoTTL ---- PASS: TestMemoryStore_NoTTL (0.00s) -=== RUN TestMemoryStore_UpdatedAtTracking ---- PASS: TestMemoryStore_UpdatedAtTracking (0.01s) -=== RUN TestMemoryStore_MultipleConversations ---- PASS: TestMemoryStore_MultipleConversations (0.00s) -=== RUN TestNewRedisStore ---- PASS: TestNewRedisStore (0.00s) -=== RUN TestRedisStore_Create ---- PASS: TestRedisStore_Create (0.00s) -=== RUN TestRedisStore_Get ---- PASS: TestRedisStore_Get (0.00s) -=== RUN TestRedisStore_Append ---- PASS: TestRedisStore_Append (0.00s) -=== RUN TestRedisStore_Delete ---- PASS: TestRedisStore_Delete (0.00s) -=== RUN TestRedisStore_Size ---- PASS: TestRedisStore_Size (0.00s) -=== RUN TestRedisStore_TTL ---- PASS: TestRedisStore_TTL (0.00s) -=== RUN TestRedisStore_KeyStorage ---- PASS: TestRedisStore_KeyStorage (0.00s) -=== RUN TestRedisStore_Concurrent ---- PASS: TestRedisStore_Concurrent (0.01s) -=== RUN TestRedisStore_JSONEncoding ---- PASS: TestRedisStore_JSONEncoding (0.00s) -=== RUN TestRedisStore_EmptyMessages ---- PASS: TestRedisStore_EmptyMessages (0.00s) -=== RUN TestRedisStore_UpdateExisting ---- PASS: TestRedisStore_UpdateExisting (0.01s) -=== RUN TestRedisStore_ContextCancellation ---- PASS: TestRedisStore_ContextCancellation (0.01s) -=== RUN TestRedisStore_ScanPagination ---- PASS: TestRedisStore_ScanPagination (0.00s) -=== RUN TestNewSQLStore ---- PASS: TestNewSQLStore (0.00s) -=== RUN TestSQLStore_Create ---- PASS: TestSQLStore_Create (0.00s) -=== RUN TestSQLStore_Get ---- PASS: TestSQLStore_Get (0.00s) -=== RUN TestSQLStore_Append ---- PASS: TestSQLStore_Append (0.00s) -=== RUN TestSQLStore_Delete ---- PASS: TestSQLStore_Delete (0.00s) -=== RUN TestSQLStore_Size ---- PASS: TestSQLStore_Size (0.00s) -=== RUN TestSQLStore_Cleanup - sql_store_test.go:198: - Error Trace: /home/coder/go-llm-gateway/internal/conversation/sql_store_test.go:198 - Error: Not equal: - expected: 0 - actual : 1 - Test: TestSQLStore_Cleanup ---- FAIL: TestSQLStore_Cleanup (0.50s) -=== RUN TestSQLStore_ConcurrentAccess ---- PASS: TestSQLStore_ConcurrentAccess (0.00s) -=== RUN TestSQLStore_ContextCancellation ---- PASS: TestSQLStore_ContextCancellation (0.00s) -=== RUN TestSQLStore_JSONEncoding ---- PASS: TestSQLStore_JSONEncoding (0.00s) -=== RUN TestSQLStore_EmptyMessages ---- PASS: TestSQLStore_EmptyMessages (0.00s) -=== RUN TestSQLStore_UpdateExisting ---- PASS: TestSQLStore_UpdateExisting (0.01s) -FAIL -coverage: 66.0% of statements -FAIL github.com/ajac-zero/latticelm/internal/conversation 0.768s - github.com/ajac-zero/latticelm/internal/logger coverage: 0.0% of statements -=== RUN TestInitMetrics ---- PASS: TestInitMetrics (0.00s) -=== RUN TestRecordCircuitBreakerStateChange -=== RUN TestRecordCircuitBreakerStateChange/transition_to_closed -=== RUN TestRecordCircuitBreakerStateChange/transition_to_open -=== RUN TestRecordCircuitBreakerStateChange/transition_to_half-open -=== RUN TestRecordCircuitBreakerStateChange/closed_to_half-open -=== RUN TestRecordCircuitBreakerStateChange/half-open_to_closed -=== RUN TestRecordCircuitBreakerStateChange/half-open_to_open ---- PASS: TestRecordCircuitBreakerStateChange (0.00s) - --- PASS: TestRecordCircuitBreakerStateChange/transition_to_closed (0.00s) - --- PASS: TestRecordCircuitBreakerStateChange/transition_to_open (0.00s) - --- PASS: TestRecordCircuitBreakerStateChange/transition_to_half-open (0.00s) - --- PASS: TestRecordCircuitBreakerStateChange/closed_to_half-open (0.00s) - --- PASS: TestRecordCircuitBreakerStateChange/half-open_to_closed (0.00s) - --- PASS: TestRecordCircuitBreakerStateChange/half-open_to_open (0.00s) -=== RUN TestMetricLabels -=== RUN TestMetricLabels/basic_labels -=== RUN TestMetricLabels/different_labels -=== RUN TestMetricLabels/empty_labels ---- PASS: TestMetricLabels (0.00s) - --- PASS: TestMetricLabels/basic_labels (0.00s) - --- PASS: TestMetricLabels/different_labels (0.00s) - --- PASS: TestMetricLabels/empty_labels (0.00s) -=== RUN TestHTTPMetrics -=== RUN TestHTTPMetrics/GET_request -=== RUN TestHTTPMetrics/POST_request -=== RUN TestHTTPMetrics/error_response ---- PASS: TestHTTPMetrics (0.00s) - --- PASS: TestHTTPMetrics/GET_request (0.00s) - --- PASS: TestHTTPMetrics/POST_request (0.00s) - --- PASS: TestHTTPMetrics/error_response (0.00s) -=== RUN TestProviderMetrics -=== RUN TestProviderMetrics/OpenAI_generate_success -=== RUN TestProviderMetrics/Anthropic_stream_success -=== RUN TestProviderMetrics/Google_generate_error ---- PASS: TestProviderMetrics (0.00s) - --- PASS: TestProviderMetrics/OpenAI_generate_success (0.00s) - --- PASS: TestProviderMetrics/Anthropic_stream_success (0.00s) - --- PASS: TestProviderMetrics/Google_generate_error (0.00s) -=== RUN TestConversationStoreMetrics -=== RUN TestConversationStoreMetrics/create_success -=== RUN TestConversationStoreMetrics/get_success -=== RUN TestConversationStoreMetrics/delete_error ---- PASS: TestConversationStoreMetrics (0.00s) - --- PASS: TestConversationStoreMetrics/create_success (0.00s) - --- PASS: TestConversationStoreMetrics/get_success (0.00s) - --- PASS: TestConversationStoreMetrics/delete_error (0.00s) -=== RUN TestMetricHelp ---- PASS: TestMetricHelp (0.00s) -=== RUN TestMetricTypes ---- PASS: TestMetricTypes (0.00s) -=== RUN TestCircuitBreakerInvalidState ---- PASS: TestCircuitBreakerInvalidState (0.00s) -=== RUN TestMetricNaming ---- PASS: TestMetricNaming (0.00s) -=== RUN TestNewInstrumentedProvider -=== RUN TestNewInstrumentedProvider/with_registry_and_tracer -=== RUN TestNewInstrumentedProvider/with_registry_only -=== RUN TestNewInstrumentedProvider/with_tracer_only -=== RUN TestNewInstrumentedProvider/without_observability ---- PASS: TestNewInstrumentedProvider (0.00s) - --- PASS: TestNewInstrumentedProvider/with_registry_and_tracer (0.00s) - --- PASS: TestNewInstrumentedProvider/with_registry_only (0.00s) - --- PASS: TestNewInstrumentedProvider/with_tracer_only (0.00s) - --- PASS: TestNewInstrumentedProvider/without_observability (0.00s) -=== RUN TestInstrumentedProvider_Generate -=== RUN TestInstrumentedProvider_Generate/successful_generation -=== RUN TestInstrumentedProvider_Generate/generation_error -=== RUN TestInstrumentedProvider_Generate/nil_result -=== RUN TestInstrumentedProvider_Generate/empty_tokens ---- PASS: TestInstrumentedProvider_Generate (0.00s) - --- PASS: TestInstrumentedProvider_Generate/successful_generation (0.00s) - --- PASS: TestInstrumentedProvider_Generate/generation_error (0.00s) - --- PASS: TestInstrumentedProvider_Generate/nil_result (0.00s) - --- PASS: TestInstrumentedProvider_Generate/empty_tokens (0.00s) -=== RUN TestInstrumentedProvider_GenerateStream -=== RUN TestInstrumentedProvider_GenerateStream/successful_streaming - provider_wrapper_test.go:438: - Error Trace: /home/coder/go-llm-gateway/internal/observability/provider_wrapper_test.go:438 - Error: Not equal: - expected: 4 - actual : 2 - Test: TestInstrumentedProvider_GenerateStream/successful_streaming - provider_wrapper_test.go:455: - Error Trace: /home/coder/go-llm-gateway/internal/observability/provider_wrapper_test.go:455 - Error: Not equal: - expected: 1 - actual : 0 - Test: TestInstrumentedProvider_GenerateStream/successful_streaming - Messages: stream request counter should be incremented -=== RUN TestInstrumentedProvider_GenerateStream/streaming_error - provider_wrapper_test.go:455: - Error Trace: /home/coder/go-llm-gateway/internal/observability/provider_wrapper_test.go:455 - Error: Not equal: - expected: 1 - actual : 0 - Test: TestInstrumentedProvider_GenerateStream/streaming_error - Messages: stream request counter should be incremented -=== RUN TestInstrumentedProvider_GenerateStream/empty_stream - provider_wrapper_test.go:455: - Error Trace: /home/coder/go-llm-gateway/internal/observability/provider_wrapper_test.go:455 - Error: Not equal: - expected: 1 - actual : 0 - Test: TestInstrumentedProvider_GenerateStream/empty_stream - Messages: stream request counter should be incremented ---- FAIL: TestInstrumentedProvider_GenerateStream (0.61s) - --- FAIL: TestInstrumentedProvider_GenerateStream/successful_streaming (0.20s) - --- FAIL: TestInstrumentedProvider_GenerateStream/streaming_error (0.20s) - --- FAIL: TestInstrumentedProvider_GenerateStream/empty_stream (0.20s) -=== RUN TestInstrumentedProvider_MetricsRecording ---- PASS: TestInstrumentedProvider_MetricsRecording (0.00s) -=== RUN TestInstrumentedProvider_TracingSpans ---- PASS: TestInstrumentedProvider_TracingSpans (0.00s) -=== RUN TestInstrumentedProvider_WithoutObservability ---- PASS: TestInstrumentedProvider_WithoutObservability (0.00s) -=== RUN TestInstrumentedProvider_Name -=== RUN TestInstrumentedProvider_Name/openai_provider -=== RUN TestInstrumentedProvider_Name/anthropic_provider -=== RUN TestInstrumentedProvider_Name/google_provider ---- PASS: TestInstrumentedProvider_Name (0.00s) - --- PASS: TestInstrumentedProvider_Name/openai_provider (0.00s) - --- PASS: TestInstrumentedProvider_Name/anthropic_provider (0.00s) - --- PASS: TestInstrumentedProvider_Name/google_provider (0.00s) -=== RUN TestInstrumentedProvider_ConcurrentCalls ---- PASS: TestInstrumentedProvider_ConcurrentCalls (0.00s) -=== RUN TestInstrumentedProvider_StreamTTFB ---- PASS: TestInstrumentedProvider_StreamTTFB (0.15s) -=== RUN TestInitTracer_StdoutExporter -=== RUN TestInitTracer_StdoutExporter/stdout_exporter_with_always_sampler - tracing_test.go:74: - Error Trace: /home/coder/go-llm-gateway/internal/observability/tracing_test.go:74 - Error: Received unexpected error: - failed to create resource: conflicting Schema URL: https://opentelemetry.io/schemas/1.26.0 and https://opentelemetry.io/schemas/1.24.0 - Test: TestInitTracer_StdoutExporter/stdout_exporter_with_always_sampler -=== RUN TestInitTracer_StdoutExporter/stdout_exporter_with_never_sampler - tracing_test.go:74: - Error Trace: /home/coder/go-llm-gateway/internal/observability/tracing_test.go:74 - Error: Received unexpected error: - failed to create resource: conflicting Schema URL: https://opentelemetry.io/schemas/1.26.0 and https://opentelemetry.io/schemas/1.24.0 - Test: TestInitTracer_StdoutExporter/stdout_exporter_with_never_sampler -=== RUN TestInitTracer_StdoutExporter/stdout_exporter_with_probability_sampler - tracing_test.go:74: - Error Trace: /home/coder/go-llm-gateway/internal/observability/tracing_test.go:74 - Error: Received unexpected error: - failed to create resource: conflicting Schema URL: https://opentelemetry.io/schemas/1.26.0 and https://opentelemetry.io/schemas/1.24.0 - Test: TestInitTracer_StdoutExporter/stdout_exporter_with_probability_sampler ---- FAIL: TestInitTracer_StdoutExporter (0.00s) - --- FAIL: TestInitTracer_StdoutExporter/stdout_exporter_with_always_sampler (0.00s) - --- FAIL: TestInitTracer_StdoutExporter/stdout_exporter_with_never_sampler (0.00s) - --- FAIL: TestInitTracer_StdoutExporter/stdout_exporter_with_probability_sampler (0.00s) -=== RUN TestInitTracer_InvalidExporter - tracing_test.go:102: - Error Trace: /home/coder/go-llm-gateway/internal/observability/tracing_test.go:102 - Error: "failed to create resource: conflicting Schema URL: https://opentelemetry.io/schemas/1.26.0 and https://opentelemetry.io/schemas/1.24.0" does not contain "unsupported exporter type" - Test: TestInitTracer_InvalidExporter ---- FAIL: TestInitTracer_InvalidExporter (0.00s) -=== RUN TestCreateSampler -=== RUN TestCreateSampler/always_sampler -=== RUN TestCreateSampler/never_sampler -=== RUN TestCreateSampler/probability_sampler_-_100% -=== RUN TestCreateSampler/probability_sampler_-_0% -=== RUN TestCreateSampler/probability_sampler_-_50% -=== RUN TestCreateSampler/default_sampler_(invalid_type) ---- PASS: TestCreateSampler (0.00s) - --- PASS: TestCreateSampler/always_sampler (0.00s) - --- PASS: TestCreateSampler/never_sampler (0.00s) - --- PASS: TestCreateSampler/probability_sampler_-_100% (0.00s) - --- PASS: TestCreateSampler/probability_sampler_-_0% (0.00s) - --- PASS: TestCreateSampler/probability_sampler_-_50% (0.00s) - --- PASS: TestCreateSampler/default_sampler_(invalid_type) (0.00s) -=== RUN TestShutdown -=== RUN TestShutdown/shutdown_valid_tracer_provider -=== RUN TestShutdown/shutdown_nil_tracer_provider ---- PASS: TestShutdown (0.00s) - --- PASS: TestShutdown/shutdown_valid_tracer_provider (0.00s) - --- PASS: TestShutdown/shutdown_nil_tracer_provider (0.00s) -=== RUN TestShutdown_ContextTimeout ---- PASS: TestShutdown_ContextTimeout (0.00s) -=== RUN TestTracerConfig_ServiceName -=== RUN TestTracerConfig_ServiceName/default_service_name -=== RUN TestTracerConfig_ServiceName/custom_service_name -=== RUN TestTracerConfig_ServiceName/empty_service_name ---- PASS: TestTracerConfig_ServiceName (0.00s) - --- PASS: TestTracerConfig_ServiceName/default_service_name (0.00s) - --- PASS: TestTracerConfig_ServiceName/custom_service_name (0.00s) - --- PASS: TestTracerConfig_ServiceName/empty_service_name (0.00s) -=== RUN TestCreateSampler_EdgeCases -=== RUN TestCreateSampler_EdgeCases/negative_rate -=== RUN TestCreateSampler_EdgeCases/rate_greater_than_1 -=== RUN TestCreateSampler_EdgeCases/empty_type ---- PASS: TestCreateSampler_EdgeCases (0.00s) - --- PASS: TestCreateSampler_EdgeCases/negative_rate (0.00s) - --- PASS: TestCreateSampler_EdgeCases/rate_greater_than_1 (0.00s) - --- PASS: TestCreateSampler_EdgeCases/empty_type (0.00s) -=== RUN TestTracerProvider_MultipleShutdowns ---- PASS: TestTracerProvider_MultipleShutdowns (0.00s) -=== RUN TestSamplerDescription -=== RUN TestSamplerDescription/always_sampler_description -=== RUN TestSamplerDescription/never_sampler_description -=== RUN TestSamplerDescription/probability_sampler_description ---- PASS: TestSamplerDescription (0.00s) - --- PASS: TestSamplerDescription/always_sampler_description (0.00s) - --- PASS: TestSamplerDescription/never_sampler_description (0.00s) - --- PASS: TestSamplerDescription/probability_sampler_description (0.00s) -=== RUN TestInitTracer_ResourceAttributes ---- PASS: TestInitTracer_ResourceAttributes (0.00s) -=== RUN TestProbabilitySampler_Boundaries -=== RUN TestProbabilitySampler_Boundaries/rate_0.0_-_never_sample -=== RUN TestProbabilitySampler_Boundaries/rate_1.0_-_always_sample -=== RUN TestProbabilitySampler_Boundaries/rate_0.5_-_probabilistic ---- PASS: TestProbabilitySampler_Boundaries (0.00s) - --- PASS: TestProbabilitySampler_Boundaries/rate_0.0_-_never_sample (0.00s) - --- PASS: TestProbabilitySampler_Boundaries/rate_1.0_-_always_sample (0.00s) - --- PASS: TestProbabilitySampler_Boundaries/rate_0.5_-_probabilistic (0.00s) -FAIL -coverage: 35.1% of statements -FAIL github.com/ajac-zero/latticelm/internal/observability 0.783s -=== RUN TestNewRegistry -=== RUN TestNewRegistry/valid_config_with_OpenAI -=== RUN TestNewRegistry/valid_config_with_multiple_providers -=== RUN TestNewRegistry/no_providers_returns_error -=== RUN TestNewRegistry/Azure_OpenAI_without_endpoint_returns_error -=== RUN TestNewRegistry/Azure_OpenAI_with_endpoint_succeeds -=== RUN TestNewRegistry/Azure_Anthropic_without_endpoint_returns_error -=== RUN TestNewRegistry/Azure_Anthropic_with_endpoint_succeeds -=== RUN TestNewRegistry/Google_provider -=== RUN TestNewRegistry/Vertex_AI_without_project/location_returns_error -=== RUN TestNewRegistry/Vertex_AI_with_project_and_location_succeeds -=== RUN TestNewRegistry/unknown_provider_type_returns_error -=== RUN TestNewRegistry/provider_with_no_API_key_is_skipped -=== RUN TestNewRegistry/model_with_provider_model_id ---- PASS: TestNewRegistry (0.00s) - --- PASS: TestNewRegistry/valid_config_with_OpenAI (0.00s) - --- PASS: TestNewRegistry/valid_config_with_multiple_providers (0.00s) - --- PASS: TestNewRegistry/no_providers_returns_error (0.00s) - --- PASS: TestNewRegistry/Azure_OpenAI_without_endpoint_returns_error (0.00s) - --- PASS: TestNewRegistry/Azure_OpenAI_with_endpoint_succeeds (0.00s) - --- PASS: TestNewRegistry/Azure_Anthropic_without_endpoint_returns_error (0.00s) - --- PASS: TestNewRegistry/Azure_Anthropic_with_endpoint_succeeds (0.00s) - --- PASS: TestNewRegistry/Google_provider (0.00s) - --- PASS: TestNewRegistry/Vertex_AI_without_project/location_returns_error (0.00s) - --- PASS: TestNewRegistry/Vertex_AI_with_project_and_location_succeeds (0.00s) - --- PASS: TestNewRegistry/unknown_provider_type_returns_error (0.00s) - --- PASS: TestNewRegistry/provider_with_no_API_key_is_skipped (0.00s) - --- PASS: TestNewRegistry/model_with_provider_model_id (0.00s) -=== RUN TestRegistry_Get -=== RUN TestRegistry_Get/existing_provider -=== RUN TestRegistry_Get/another_existing_provider -=== RUN TestRegistry_Get/nonexistent_provider ---- PASS: TestRegistry_Get (0.00s) - --- PASS: TestRegistry_Get/existing_provider (0.00s) - --- PASS: TestRegistry_Get/another_existing_provider (0.00s) - --- PASS: TestRegistry_Get/nonexistent_provider (0.00s) -=== RUN TestRegistry_Models -=== RUN TestRegistry_Models/single_model -=== RUN TestRegistry_Models/multiple_models -=== RUN TestRegistry_Models/no_models ---- PASS: TestRegistry_Models (0.00s) - --- PASS: TestRegistry_Models/single_model (0.00s) - --- PASS: TestRegistry_Models/multiple_models (0.00s) - --- PASS: TestRegistry_Models/no_models (0.00s) -=== RUN TestRegistry_ResolveModelID -=== RUN TestRegistry_ResolveModelID/model_without_provider_model_id_returns_model_name -=== RUN TestRegistry_ResolveModelID/model_with_provider_model_id_returns_provider_model_id -=== RUN TestRegistry_ResolveModelID/unknown_model_returns_model_name ---- PASS: TestRegistry_ResolveModelID (0.00s) - --- PASS: TestRegistry_ResolveModelID/model_without_provider_model_id_returns_model_name (0.00s) - --- PASS: TestRegistry_ResolveModelID/model_with_provider_model_id_returns_provider_model_id (0.00s) - --- PASS: TestRegistry_ResolveModelID/unknown_model_returns_model_name (0.00s) -=== RUN TestRegistry_Default -=== RUN TestRegistry_Default/returns_provider_for_known_model -=== RUN TestRegistry_Default/returns_first_provider_for_unknown_model -=== RUN TestRegistry_Default/returns_first_provider_for_empty_model_name ---- PASS: TestRegistry_Default (0.00s) - --- PASS: TestRegistry_Default/returns_provider_for_known_model (0.00s) - --- PASS: TestRegistry_Default/returns_first_provider_for_unknown_model (0.00s) - --- PASS: TestRegistry_Default/returns_first_provider_for_empty_model_name (0.00s) -=== RUN TestBuildProvider -=== RUN TestBuildProvider/OpenAI_provider -=== RUN TestBuildProvider/OpenAI_provider_with_custom_endpoint -=== RUN TestBuildProvider/Anthropic_provider -=== RUN TestBuildProvider/Google_provider -=== RUN TestBuildProvider/provider_without_API_key_returns_nil -=== RUN TestBuildProvider/unknown_provider_type ---- PASS: TestBuildProvider (0.00s) - --- PASS: TestBuildProvider/OpenAI_provider (0.00s) - --- PASS: TestBuildProvider/OpenAI_provider_with_custom_endpoint (0.00s) - --- PASS: TestBuildProvider/Anthropic_provider (0.00s) - --- PASS: TestBuildProvider/Google_provider (0.00s) - --- PASS: TestBuildProvider/provider_without_API_key_returns_nil (0.00s) - --- PASS: TestBuildProvider/unknown_provider_type (0.00s) -PASS -coverage: 63.1% of statements -ok github.com/ajac-zero/latticelm/internal/providers 0.035s coverage: 63.1% of statements -=== RUN TestParseTools ---- PASS: TestParseTools (0.00s) -=== RUN TestParseToolChoice -=== RUN TestParseToolChoice/auto -=== RUN TestParseToolChoice/any -=== RUN TestParseToolChoice/required -=== RUN TestParseToolChoice/specific_tool ---- PASS: TestParseToolChoice (0.00s) - --- PASS: TestParseToolChoice/auto (0.00s) - --- PASS: TestParseToolChoice/any (0.00s) - --- PASS: TestParseToolChoice/required (0.00s) - --- PASS: TestParseToolChoice/specific_tool (0.00s) -PASS -coverage: 16.2% of statements -ok github.com/ajac-zero/latticelm/internal/providers/anthropic 0.016s coverage: 16.2% of statements -=== RUN TestParseTools -=== RUN TestParseTools/flat_format_tool -=== RUN TestParseTools/nested_format_tool -=== RUN TestParseTools/multiple_tools -=== RUN TestParseTools/tool_without_description -=== RUN TestParseTools/tool_without_parameters -=== RUN TestParseTools/tool_without_name_(should_skip) -=== RUN TestParseTools/nil_tools -=== RUN TestParseTools/invalid_JSON -=== RUN TestParseTools/empty_array ---- PASS: TestParseTools (0.00s) - --- PASS: TestParseTools/flat_format_tool (0.00s) - --- PASS: TestParseTools/nested_format_tool (0.00s) - --- PASS: TestParseTools/multiple_tools (0.00s) - --- PASS: TestParseTools/tool_without_description (0.00s) - --- PASS: TestParseTools/tool_without_parameters (0.00s) - --- PASS: TestParseTools/tool_without_name_(should_skip) (0.00s) - --- PASS: TestParseTools/nil_tools (0.00s) - --- PASS: TestParseTools/invalid_JSON (0.00s) - --- PASS: TestParseTools/empty_array (0.00s) -=== RUN TestParseToolChoice -=== RUN TestParseToolChoice/auto_mode -=== RUN TestParseToolChoice/none_mode -=== RUN TestParseToolChoice/required_mode -=== RUN TestParseToolChoice/any_mode -=== RUN TestParseToolChoice/specific_function -=== RUN TestParseToolChoice/nil_tool_choice -=== RUN TestParseToolChoice/unknown_string_mode -=== RUN TestParseToolChoice/invalid_JSON -=== RUN TestParseToolChoice/unsupported_object_format ---- PASS: TestParseToolChoice (0.00s) - --- PASS: TestParseToolChoice/auto_mode (0.00s) - --- PASS: TestParseToolChoice/none_mode (0.00s) - --- PASS: TestParseToolChoice/required_mode (0.00s) - --- PASS: TestParseToolChoice/any_mode (0.00s) - --- PASS: TestParseToolChoice/specific_function (0.00s) - --- PASS: TestParseToolChoice/nil_tool_choice (0.00s) - --- PASS: TestParseToolChoice/unknown_string_mode (0.00s) - --- PASS: TestParseToolChoice/invalid_JSON (0.00s) - --- PASS: TestParseToolChoice/unsupported_object_format (0.00s) -=== RUN TestExtractToolCalls -=== RUN TestExtractToolCalls/single_tool_call -=== RUN TestExtractToolCalls/tool_call_without_ID_generates_one -=== RUN TestExtractToolCalls/response_with_nil_candidates -=== RUN TestExtractToolCalls/empty_candidates ---- PASS: TestExtractToolCalls (0.00s) - --- PASS: TestExtractToolCalls/single_tool_call (0.00s) - --- PASS: TestExtractToolCalls/tool_call_without_ID_generates_one (0.00s) - --- PASS: TestExtractToolCalls/response_with_nil_candidates (0.00s) - --- PASS: TestExtractToolCalls/empty_candidates (0.00s) -=== RUN TestGenerateRandomID -=== RUN TestGenerateRandomID/generates_non-empty_ID -=== RUN TestGenerateRandomID/generates_unique_IDs -=== RUN TestGenerateRandomID/only_contains_valid_characters ---- PASS: TestGenerateRandomID (0.00s) - --- PASS: TestGenerateRandomID/generates_non-empty_ID (0.00s) - --- PASS: TestGenerateRandomID/generates_unique_IDs (0.00s) - --- PASS: TestGenerateRandomID/only_contains_valid_characters (0.00s) -PASS -coverage: 27.7% of statements -ok github.com/ajac-zero/latticelm/internal/providers/google 0.017s coverage: 27.7% of statements -=== RUN TestParseTools -=== RUN TestParseTools/single_tool_with_all_fields -=== RUN TestParseTools/multiple_tools -=== RUN TestParseTools/tool_without_description -=== RUN TestParseTools/tool_without_parameters -=== RUN TestParseTools/nil_tools -=== RUN TestParseTools/invalid_JSON -=== RUN TestParseTools/empty_array ---- PASS: TestParseTools (0.00s) - --- PASS: TestParseTools/single_tool_with_all_fields (0.00s) - --- PASS: TestParseTools/multiple_tools (0.00s) - --- PASS: TestParseTools/tool_without_description (0.00s) - --- PASS: TestParseTools/tool_without_parameters (0.00s) - --- PASS: TestParseTools/nil_tools (0.00s) - --- PASS: TestParseTools/invalid_JSON (0.00s) - --- PASS: TestParseTools/empty_array (0.00s) -=== RUN TestParseToolChoice -=== RUN TestParseToolChoice/auto_string -=== RUN TestParseToolChoice/none_string -=== RUN TestParseToolChoice/required_string -=== RUN TestParseToolChoice/specific_function -=== RUN TestParseToolChoice/nil_tool_choice -=== RUN TestParseToolChoice/invalid_JSON -=== RUN TestParseToolChoice/unsupported_format_(object_without_proper_structure) ---- PASS: TestParseToolChoice (0.00s) - --- PASS: TestParseToolChoice/auto_string (0.00s) - --- PASS: TestParseToolChoice/none_string (0.00s) - --- PASS: TestParseToolChoice/required_string (0.00s) - --- PASS: TestParseToolChoice/specific_function (0.00s) - --- PASS: TestParseToolChoice/nil_tool_choice (0.00s) - --- PASS: TestParseToolChoice/invalid_JSON (0.00s) - --- PASS: TestParseToolChoice/unsupported_format_(object_without_proper_structure) (0.00s) -=== RUN TestExtractToolCalls -=== RUN TestExtractToolCalls/nil_message_returns_nil ---- PASS: TestExtractToolCalls (0.00s) - --- PASS: TestExtractToolCalls/nil_message_returns_nil (0.00s) -=== RUN TestExtractToolCallDelta -=== RUN TestExtractToolCallDelta/empty_delta_returns_nil ---- PASS: TestExtractToolCallDelta (0.00s) - --- PASS: TestExtractToolCallDelta/empty_delta_returns_nil (0.00s) -PASS -coverage: 16.1% of statements -ok github.com/ajac-zero/latticelm/internal/providers/openai 0.024s coverage: 16.1% of statements -=== RUN TestRateLimitMiddleware -=== RUN TestRateLimitMiddleware/disabled_rate_limiting_allows_all_requests -=== RUN TestRateLimitMiddleware/enabled_rate_limiting_enforces_limits -time=2026-03-05T17:59:57.097Z level=WARN msg="rate limit exceeded" ip=192.168.1.1:1234 path=/test -time=2026-03-05T17:59:57.097Z level=WARN msg="rate limit exceeded" ip=192.168.1.1:1234 path=/test -time=2026-03-05T17:59:57.097Z level=WARN msg="rate limit exceeded" ip=192.168.1.1:1234 path=/test ---- PASS: TestRateLimitMiddleware (0.00s) - --- PASS: TestRateLimitMiddleware/disabled_rate_limiting_allows_all_requests (0.00s) - --- PASS: TestRateLimitMiddleware/enabled_rate_limiting_enforces_limits (0.00s) -=== RUN TestGetClientIP -=== RUN TestGetClientIP/uses_X-Forwarded-For_if_present -=== RUN TestGetClientIP/uses_X-Real-IP_if_X-Forwarded-For_not_present -=== RUN TestGetClientIP/uses_RemoteAddr_as_fallback ---- PASS: TestGetClientIP (0.00s) - --- PASS: TestGetClientIP/uses_X-Forwarded-For_if_present (0.00s) - --- PASS: TestGetClientIP/uses_X-Real-IP_if_X-Forwarded-For_not_present (0.00s) - --- PASS: TestGetClientIP/uses_RemoteAddr_as_fallback (0.00s) -=== RUN TestRateLimitRefill -time=2026-03-05T17:59:57.097Z level=WARN msg="rate limit exceeded" ip=192.168.1.1:1234 path=/test ---- PASS: TestRateLimitRefill (0.15s) -PASS -coverage: 87.2% of statements -ok github.com/ajac-zero/latticelm/internal/ratelimit 0.160s coverage: 87.2% of statements -=== RUN TestHealthEndpoint -=== RUN TestHealthEndpoint/GET_returns_healthy_status -=== RUN TestHealthEndpoint/POST_returns_method_not_allowed ---- PASS: TestHealthEndpoint (0.00s) - --- PASS: TestHealthEndpoint/GET_returns_healthy_status (0.00s) - --- PASS: TestHealthEndpoint/POST_returns_method_not_allowed (0.00s) -=== RUN TestReadyEndpoint -=== RUN TestReadyEndpoint/returns_ready_when_all_checks_pass -=== RUN TestReadyEndpoint/returns_not_ready_when_no_providers_configured ---- PASS: TestReadyEndpoint (0.00s) - --- PASS: TestReadyEndpoint/returns_ready_when_all_checks_pass (0.00s) - --- PASS: TestReadyEndpoint/returns_not_ready_when_no_providers_configured (0.00s) -=== RUN TestReadyEndpointMethodNotAllowed ---- PASS: TestReadyEndpointMethodNotAllowed (0.00s) -=== RUN TestPanicRecoveryMiddleware -=== RUN TestPanicRecoveryMiddleware/no_panic_-_request_succeeds -=== RUN TestPanicRecoveryMiddleware/panic_with_string_-_recovers_gracefully -=== RUN TestPanicRecoveryMiddleware/panic_with_error_-_recovers_gracefully -=== RUN TestPanicRecoveryMiddleware/panic_with_struct_-_recovers_gracefully ---- PASS: TestPanicRecoveryMiddleware (0.00s) - --- PASS: TestPanicRecoveryMiddleware/no_panic_-_request_succeeds (0.00s) - --- PASS: TestPanicRecoveryMiddleware/panic_with_string_-_recovers_gracefully (0.00s) - --- PASS: TestPanicRecoveryMiddleware/panic_with_error_-_recovers_gracefully (0.00s) - --- PASS: TestPanicRecoveryMiddleware/panic_with_struct_-_recovers_gracefully (0.00s) -=== RUN TestRequestSizeLimitMiddleware -=== RUN TestRequestSizeLimitMiddleware/small_POST_request_-_succeeds -=== RUN TestRequestSizeLimitMiddleware/exact_size_POST_request_-_succeeds -=== RUN TestRequestSizeLimitMiddleware/oversized_POST_request_-_fails -=== RUN TestRequestSizeLimitMiddleware/large_POST_request_-_fails -=== RUN TestRequestSizeLimitMiddleware/oversized_PUT_request_-_fails -=== RUN TestRequestSizeLimitMiddleware/oversized_PATCH_request_-_fails -=== RUN TestRequestSizeLimitMiddleware/GET_request_-_no_size_limit_applied -=== RUN TestRequestSizeLimitMiddleware/DELETE_request_-_no_size_limit_applied ---- PASS: TestRequestSizeLimitMiddleware (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/small_POST_request_-_succeeds (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/exact_size_POST_request_-_succeeds (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/oversized_POST_request_-_fails (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/large_POST_request_-_fails (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/oversized_PUT_request_-_fails (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/oversized_PATCH_request_-_fails (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/GET_request_-_no_size_limit_applied (0.00s) - --- PASS: TestRequestSizeLimitMiddleware/DELETE_request_-_no_size_limit_applied (0.00s) -=== RUN TestRequestSizeLimitMiddleware_WithJSONDecoding -=== RUN TestRequestSizeLimitMiddleware_WithJSONDecoding/small_JSON_payload_-_succeeds -=== RUN TestRequestSizeLimitMiddleware_WithJSONDecoding/large_JSON_payload_-_fails ---- PASS: TestRequestSizeLimitMiddleware_WithJSONDecoding (0.00s) - --- PASS: TestRequestSizeLimitMiddleware_WithJSONDecoding/small_JSON_payload_-_succeeds (0.00s) - --- PASS: TestRequestSizeLimitMiddleware_WithJSONDecoding/large_JSON_payload_-_fails (0.00s) -=== RUN TestWriteJSONError -=== RUN TestWriteJSONError/simple_error_message -=== RUN TestWriteJSONError/internal_server_error -=== RUN TestWriteJSONError/unauthorized_error ---- PASS: TestWriteJSONError (0.00s) - --- PASS: TestWriteJSONError/simple_error_message (0.00s) - --- PASS: TestWriteJSONError/internal_server_error (0.00s) - --- PASS: TestWriteJSONError/unauthorized_error (0.00s) -=== RUN TestPanicRecoveryMiddleware_Integration ---- PASS: TestPanicRecoveryMiddleware_Integration (0.00s) -=== RUN TestHandleModels -=== RUN TestHandleModels/GET_returns_model_list -=== RUN TestHandleModels/POST_returns_405 -=== RUN TestHandleModels/empty_registry_returns_empty_list ---- PASS: TestHandleModels (0.00s) - --- PASS: TestHandleModels/GET_returns_model_list (0.00s) - --- PASS: TestHandleModels/POST_returns_405 (0.00s) - --- PASS: TestHandleModels/empty_registry_returns_empty_list (0.00s) -=== RUN TestHandleResponses_Validation -=== RUN TestHandleResponses_Validation/GET_returns_405 -=== RUN TestHandleResponses_Validation/invalid_JSON_returns_400 -=== RUN TestHandleResponses_Validation/missing_model_returns_400 -=== RUN TestHandleResponses_Validation/missing_input_returns_400 ---- PASS: TestHandleResponses_Validation (0.00s) - --- PASS: TestHandleResponses_Validation/GET_returns_405 (0.00s) - --- PASS: TestHandleResponses_Validation/invalid_JSON_returns_400 (0.00s) - --- PASS: TestHandleResponses_Validation/missing_model_returns_400 (0.00s) - --- PASS: TestHandleResponses_Validation/missing_input_returns_400 (0.00s) -=== RUN TestHandleResponses_Sync_Success -=== RUN TestHandleResponses_Sync_Success/simple_text_response -=== RUN TestHandleResponses_Sync_Success/response_with_tool_calls -=== RUN TestHandleResponses_Sync_Success/response_with_multiple_tool_calls -=== RUN TestHandleResponses_Sync_Success/response_with_only_tool_calls_(no_text) -=== RUN TestHandleResponses_Sync_Success/response_echoes_request_parameters ---- PASS: TestHandleResponses_Sync_Success (0.00s) - --- PASS: TestHandleResponses_Sync_Success/simple_text_response (0.00s) - --- PASS: TestHandleResponses_Sync_Success/response_with_tool_calls (0.00s) - --- PASS: TestHandleResponses_Sync_Success/response_with_multiple_tool_calls (0.00s) - --- PASS: TestHandleResponses_Sync_Success/response_with_only_tool_calls_(no_text) (0.00s) - --- PASS: TestHandleResponses_Sync_Success/response_echoes_request_parameters (0.00s) -=== RUN TestHandleResponses_Sync_ConversationHistory -=== RUN TestHandleResponses_Sync_ConversationHistory/without_previous_response_id -=== RUN TestHandleResponses_Sync_ConversationHistory/with_valid_previous_response_id -=== RUN TestHandleResponses_Sync_ConversationHistory/with_instructions_prepends_developer_message -=== RUN TestHandleResponses_Sync_ConversationHistory/nonexistent_conversation_returns_404 -=== RUN TestHandleResponses_Sync_ConversationHistory/conversation_store_error_returns_500 ---- PASS: TestHandleResponses_Sync_ConversationHistory (0.00s) - --- PASS: TestHandleResponses_Sync_ConversationHistory/without_previous_response_id (0.00s) - --- PASS: TestHandleResponses_Sync_ConversationHistory/with_valid_previous_response_id (0.00s) - --- PASS: TestHandleResponses_Sync_ConversationHistory/with_instructions_prepends_developer_message (0.00s) - --- PASS: TestHandleResponses_Sync_ConversationHistory/nonexistent_conversation_returns_404 (0.00s) - --- PASS: TestHandleResponses_Sync_ConversationHistory/conversation_store_error_returns_500 (0.00s) -=== RUN TestHandleResponses_Sync_ProviderErrors -=== RUN TestHandleResponses_Sync_ProviderErrors/provider_returns_error -=== RUN TestHandleResponses_Sync_ProviderErrors/provider_not_configured ---- PASS: TestHandleResponses_Sync_ProviderErrors (0.00s) - --- PASS: TestHandleResponses_Sync_ProviderErrors/provider_returns_error (0.00s) - --- PASS: TestHandleResponses_Sync_ProviderErrors/provider_not_configured (0.00s) -=== RUN TestHandleResponses_Stream_Success -=== RUN TestHandleResponses_Stream_Success/simple_text_streaming -=== RUN TestHandleResponses_Stream_Success/streaming_with_tool_calls -=== RUN TestHandleResponses_Stream_Success/streaming_with_multiple_tool_calls ---- PASS: TestHandleResponses_Stream_Success (0.00s) - --- PASS: TestHandleResponses_Stream_Success/simple_text_streaming (0.00s) - --- PASS: TestHandleResponses_Stream_Success/streaming_with_tool_calls (0.00s) - --- PASS: TestHandleResponses_Stream_Success/streaming_with_multiple_tool_calls (0.00s) -=== RUN TestHandleResponses_Stream_Errors -=== RUN TestHandleResponses_Stream_Errors/stream_error_returns_failed_event ---- PASS: TestHandleResponses_Stream_Errors (0.00s) - --- PASS: TestHandleResponses_Stream_Errors/stream_error_returns_failed_event (0.00s) -=== RUN TestResolveProvider -=== RUN TestResolveProvider/explicit_provider_selection -=== RUN TestResolveProvider/default_by_model_name -=== RUN TestResolveProvider/provider_not_found_returns_error ---- PASS: TestResolveProvider (0.00s) - --- PASS: TestResolveProvider/explicit_provider_selection (0.00s) - --- PASS: TestResolveProvider/default_by_model_name (0.00s) - --- PASS: TestResolveProvider/provider_not_found_returns_error (0.00s) -=== RUN TestGenerateID -=== RUN TestGenerateID/resp__prefix -=== RUN TestGenerateID/msg__prefix -=== RUN TestGenerateID/item__prefix ---- PASS: TestGenerateID (0.00s) - --- PASS: TestGenerateID/resp__prefix (0.00s) - --- PASS: TestGenerateID/msg__prefix (0.00s) - --- PASS: TestGenerateID/item__prefix (0.00s) -=== RUN TestBuildResponse -=== RUN TestBuildResponse/minimal_response_structure -=== RUN TestBuildResponse/response_with_tool_calls -=== RUN TestBuildResponse/parameter_echoing_with_defaults -=== RUN TestBuildResponse/parameter_echoing_with_custom_values -=== RUN TestBuildResponse/usage_included_when_text_present -=== RUN TestBuildResponse/no_usage_when_no_text -=== RUN TestBuildResponse/instructions_prepended -=== RUN TestBuildResponse/previous_response_id_included ---- PASS: TestBuildResponse (0.00s) - --- PASS: TestBuildResponse/minimal_response_structure (0.00s) - --- PASS: TestBuildResponse/response_with_tool_calls (0.00s) - --- PASS: TestBuildResponse/parameter_echoing_with_defaults (0.00s) - --- PASS: TestBuildResponse/parameter_echoing_with_custom_values (0.00s) - --- PASS: TestBuildResponse/usage_included_when_text_present (0.00s) - --- PASS: TestBuildResponse/no_usage_when_no_text (0.00s) - --- PASS: TestBuildResponse/instructions_prepended (0.00s) - --- PASS: TestBuildResponse/previous_response_id_included (0.00s) -=== RUN TestSendSSE ---- PASS: TestSendSSE (0.00s) -PASS -coverage: 90.8% of statements -ok github.com/ajac-zero/latticelm/internal/server 0.018s coverage: 90.8% of statements -FAIL diff --git a/test_output_fixed.txt b/test_output_fixed.txt deleted file mode 100644 index ba67928..0000000 --- a/test_output_fixed.txt +++ /dev/null @@ -1,13 +0,0 @@ -? github.com/ajac-zero/latticelm/cmd/gateway [no test files] -ok github.com/ajac-zero/latticelm/internal/api (cached) -ok github.com/ajac-zero/latticelm/internal/auth (cached) -ok github.com/ajac-zero/latticelm/internal/config (cached) -ok github.com/ajac-zero/latticelm/internal/conversation 0.721s -? github.com/ajac-zero/latticelm/internal/logger [no test files] -ok github.com/ajac-zero/latticelm/internal/observability 0.796s -ok github.com/ajac-zero/latticelm/internal/providers 0.019s -ok github.com/ajac-zero/latticelm/internal/providers/anthropic (cached) -ok github.com/ajac-zero/latticelm/internal/providers/google 0.013s -ok github.com/ajac-zero/latticelm/internal/providers/openai (cached) -ok github.com/ajac-zero/latticelm/internal/ratelimit (cached) -ok github.com/ajac-zero/latticelm/internal/server 0.027s diff --git a/test_security_fixes.sh b/test_security_fixes.sh deleted file mode 100755 index 1c7322b..0000000 --- a/test_security_fixes.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# Test script to verify security fixes are working -# Usage: ./test_security_fixes.sh [server_url] - -SERVER_URL="${1:-http://localhost:8080}" -GREEN='\033[0;32m' -RED='\033[0;31m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -echo "Testing security improvements on $SERVER_URL" -echo "================================================" -echo "" - -# Test 1: Request size limit -echo -e "${YELLOW}Test 1: Request Size Limit${NC}" -echo "Sending a request with 11MB payload (exceeds 10MB limit)..." - -# Generate large payload -LARGE_PAYLOAD=$(python3 -c "import json; print(json.dumps({'model': 'test', 'input': 'x' * 11000000}))" 2>/dev/null || \ - perl -e 'print "{\"model\":\"test\",\"input\":\"" . ("x" x 11000000) . "\"}"') - -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$SERVER_URL/v1/responses" \ - -H "Content-Type: application/json" \ - -d "$LARGE_PAYLOAD" \ - --max-time 5 2>/dev/null) - -if [ "$HTTP_CODE" = "413" ]; then - echo -e "${GREEN}✓ PASS: Received HTTP 413 (Request Entity Too Large)${NC}" -else - echo -e "${RED}✗ FAIL: Expected 413, got $HTTP_CODE${NC}" -fi -echo "" - -# Test 2: Normal request size -echo -e "${YELLOW}Test 2: Normal Request Size${NC}" -echo "Sending a small valid request..." - -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$SERVER_URL/v1/responses" \ - -H "Content-Type: application/json" \ - -d '{"model":"test","input":"hello"}' \ - --max-time 5 2>/dev/null) - -# Expected: either 400 (invalid model) or 502 (provider error), but NOT 413 -if [ "$HTTP_CODE" != "413" ]; then - echo -e "${GREEN}✓ PASS: Request not rejected by size limit (HTTP $HTTP_CODE)${NC}" -else - echo -e "${RED}✗ FAIL: Small request incorrectly rejected with 413${NC}" -fi -echo "" - -# Test 3: Health endpoint -echo -e "${YELLOW}Test 3: Health Endpoint${NC}" -echo "Checking /health endpoint..." - -RESPONSE=$(curl -s -X GET "$SERVER_URL/health" --max-time 5 2>/dev/null) -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET "$SERVER_URL/health" --max-time 5 2>/dev/null) - -if [ "$HTTP_CODE" = "200" ] && echo "$RESPONSE" | grep -q "healthy"; then - echo -e "${GREEN}✓ PASS: Health endpoint responding correctly${NC}" -else - echo -e "${RED}✗ FAIL: Health endpoint not responding correctly (HTTP $HTTP_CODE)${NC}" -fi -echo "" - -# Test 4: Ready endpoint -echo -e "${YELLOW}Test 4: Ready Endpoint${NC}" -echo "Checking /ready endpoint..." - -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET "$SERVER_URL/ready" --max-time 5 2>/dev/null) - -if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "503" ]; then - echo -e "${GREEN}✓ PASS: Ready endpoint responding (HTTP $HTTP_CODE)${NC}" -else - echo -e "${RED}✗ FAIL: Ready endpoint not responding correctly (HTTP $HTTP_CODE)${NC}" -fi -echo "" - -# Test 5: Models endpoint -echo -e "${YELLOW}Test 5: Models Endpoint${NC}" -echo "Checking /v1/models endpoint..." - -RESPONSE=$(curl -s -X GET "$SERVER_URL/v1/models" --max-time 5 2>/dev/null) -HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET "$SERVER_URL/v1/models" --max-time 5 2>/dev/null) - -if [ "$HTTP_CODE" = "200" ] && echo "$RESPONSE" | grep -q "object"; then - echo -e "${GREEN}✓ PASS: Models endpoint responding correctly${NC}" -else - echo -e "${RED}✗ FAIL: Models endpoint not responding correctly (HTTP $HTTP_CODE)${NC}" -fi -echo "" - -echo "================================================" -echo -e "${GREEN}Testing complete!${NC}" -echo "" -echo "Note: Panic recovery cannot be tested externally without" -echo "causing intentional server errors. It has been verified" -echo "through unit tests in middleware_test.go"