Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions internal/tracing/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,33 @@ func TestStatusResponseWriter_Unwrap_ReturnsUnderlying(t *testing.T) {
assert.Same(t, rec, underlying, "Unwrap should return the wrapped ResponseWriter")
}

// TestWrapHTTPHandler_PatternMethodMismatch_ClearsRoute verifies that when a request
// pattern contains a different HTTP method than the actual request method, the
// http.route attribute is not added to the span.
// This exercises the `route = ""` branch in WrapHTTPHandler.
func TestWrapHTTPHandler_PatternMethodMismatch_ClearsRoute(t *testing.T) {
// Build a request whose Pattern method differs from its actual Method.
// In normal mux routing this cannot happen, but direct manipulation lets us
// verify that WrapHTTPHandler handles it gracefully without setting http.route.
req := httptest.NewRequest("GET", "/some/path", nil)
req.Pattern = "POST /some/path" // method in pattern != request method

rr := httptest.NewRecorder()
var capturedRoute string
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Record the Pattern so the test can confirm we reached the inner handler.
capturedRoute = r.Pattern
w.WriteHeader(http.StatusOK)
})

// No panics, no mismatched route attribute.
require.NotPanics(t, func() {
WrapHTTPHandler(inner, "test.route.mismatch").ServeHTTP(rr, req)
})
assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, "POST /some/path", capturedRoute, "inner handler should receive the original request unchanged")
}

func TestStatusResponseWriter_Unwrap_ExposesOptionalInterfaces(t *testing.T) {
mf := &mockFlusher{ResponseRecorder: *httptest.NewRecorder()}
srw := &statusResponseWriter{BaseResponseWriter: httputil.BaseResponseWriter{ResponseWriter: mf}}
Expand Down
25 changes: 25 additions & 0 deletions internal/tracing/parse_headers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,28 @@ func TestResolveHeaders_NoConfigNoEnvVar(t *testing.T) {
headers := resolveHeaders(cfg)
assert.Nil(t, headers)
}

// TestParseOTLPHeadersWithDecoder_InvalidPercentEncoding verifies that when
// percent-decoding fails the raw value is used unchanged and no panic occurs.
// This exercises the url.PathUnescape error branch in parseOTLPHeadersWithDecoder.
func TestParseOTLPHeadersWithDecoder_InvalidPercentEncoding(t *testing.T) {
// %GZ is not valid percent-encoding; url.PathUnescape will return an error.
result := parseOTLPHeadersWithDecoder("X-Token=Bearer%GZvalue,X-Other=ok", true)
// The raw (un-decoded) value must be used when decoding fails.
assert.Equal(t, "Bearer%GZvalue", result["X-Token"], "raw value should be preserved on decode failure")
assert.Equal(t, "ok", result["X-Other"], "valid pairs must still be decoded correctly")
}

// TestParseOTLPHeadersWithDecoder_ValidPercentEncoding verifies that well-formed
// percent-encoded values are decoded when decodeValues is true.
func TestParseOTLPHeadersWithDecoder_ValidPercentEncoding(t *testing.T) {
result := parseOTLPHeadersWithDecoder("Authorization=Bearer%20my-token", true)
assert.Equal(t, "Bearer my-token", result["Authorization"])
}

// TestParseOTLPHeadersWithDecoder_NoDecoding verifies that percent-encoded values
// are preserved as-is when decodeValues is false.
func TestParseOTLPHeadersWithDecoder_NoDecoding(t *testing.T) {
result := parseOTLPHeadersWithDecoder("Authorization=Bearer%20my-token", false)
assert.Equal(t, "Bearer%20my-token", result["Authorization"])
}