|
1 | 1 | package metrics |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bufio" |
| 5 | + "errors" |
4 | 6 | "math/rand" |
| 7 | + "net" |
5 | 8 | "net/http" |
6 | 9 | "testing" |
7 | 10 | "time" |
@@ -814,6 +817,32 @@ func NewMockResponseWriter() *MockResponseWriter { |
814 | 817 | } |
815 | 818 | } |
816 | 819 |
|
| 820 | +// MockHijackResponseWriter is a mock ResponseWriter that supports hijacking. |
| 821 | +type MockHijackResponseWriter struct { |
| 822 | + *MockResponseWriter |
| 823 | + hijackCalled bool |
| 824 | + conn net.Conn |
| 825 | + peer net.Conn |
| 826 | + buf *bufio.ReadWriter |
| 827 | +} |
| 828 | + |
| 829 | +// NewMockHijackResponseWriter creates a new MockHijackResponseWriter. |
| 830 | +func NewMockHijackResponseWriter() *MockHijackResponseWriter { |
| 831 | + conn, peer := net.Pipe() |
| 832 | + return &MockHijackResponseWriter{ |
| 833 | + MockResponseWriter: NewMockResponseWriter(), |
| 834 | + conn: conn, |
| 835 | + peer: peer, |
| 836 | + buf: bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)), |
| 837 | + } |
| 838 | +} |
| 839 | + |
| 840 | +// Hijack records the call and returns the mocked connection and buffer. |
| 841 | +func (w *MockHijackResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { |
| 842 | + w.hijackCalled = true |
| 843 | + return w.conn, w.buf, nil |
| 844 | +} |
| 845 | + |
817 | 846 | // TestMetricsMiddlewareImpl_Handler tests the Handler method of MetricsMiddlewareImpl |
818 | 847 | func TestMetricsMiddlewareImpl_Handler(t *testing.T) { |
819 | 848 | // Create a mock registry |
@@ -1181,3 +1210,47 @@ func TestResponseWriter(t *testing.T) { |
1181 | 1210 | t.Errorf("Expected underlying data %q, got %q", "Test data", string(mockRw.writtenData)) |
1182 | 1211 | } |
1183 | 1212 | } |
| 1213 | + |
| 1214 | +// TestResponseWriterHijack ensures hijack calls are forwarded. |
| 1215 | +func TestResponseWriterHijack(t *testing.T) { |
| 1216 | + mockRw := NewMockHijackResponseWriter() |
| 1217 | + t.Cleanup(func() { |
| 1218 | + _ = mockRw.conn.Close() |
| 1219 | + _ = mockRw.peer.Close() |
| 1220 | + }) |
| 1221 | + |
| 1222 | + rw := &responseWriter{ |
| 1223 | + ResponseWriter: mockRw, |
| 1224 | + statusCode: http.StatusOK, |
| 1225 | + } |
| 1226 | + |
| 1227 | + conn, buf, err := rw.Hijack() |
| 1228 | + if err != nil { |
| 1229 | + t.Fatalf("Expected hijack to succeed, got error: %v", err) |
| 1230 | + } |
| 1231 | + if !mockRw.hijackCalled { |
| 1232 | + t.Error("Expected Hijack to be called on the underlying ResponseWriter") |
| 1233 | + } |
| 1234 | + if conn != mockRw.conn { |
| 1235 | + t.Errorf("Expected hijack connection to match, got %v", conn) |
| 1236 | + } |
| 1237 | + if buf != mockRw.buf { |
| 1238 | + t.Error("Expected hijack read-writer to match") |
| 1239 | + } |
| 1240 | +} |
| 1241 | + |
| 1242 | +// TestResponseWriterHijackUnsupported ensures unsupported hijacks return ErrNotSupported. |
| 1243 | +func TestResponseWriterHijackUnsupported(t *testing.T) { |
| 1244 | + rw := &responseWriter{ |
| 1245 | + ResponseWriter: NewMockResponseWriter(), |
| 1246 | + statusCode: http.StatusOK, |
| 1247 | + } |
| 1248 | + |
| 1249 | + conn, buf, err := rw.Hijack() |
| 1250 | + if !errors.Is(err, http.ErrNotSupported) { |
| 1251 | + t.Fatalf("Expected ErrNotSupported, got %v", err) |
| 1252 | + } |
| 1253 | + if conn != nil || buf != nil { |
| 1254 | + t.Error("Expected nil connection and buffer on unsupported hijack") |
| 1255 | + } |
| 1256 | +} |
0 commit comments