From d892fd2b5103aca3c5cd4d51e567c02264fd9376 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Fri, 2 Feb 2018 15:50:46 +0100 Subject: [PATCH 1/2] Add test to expose interface upgrade bug In principle, we needed to iterate through all permutations, mirroring the same that is happening in the code. For lack of time, I only picked one of the cases currently buggy. As said, this really needs code generation, should we ever find ourselves touching this again. --- prometheus/promhttp/instrument_server_test.go | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/prometheus/promhttp/instrument_server_test.go b/prometheus/promhttp/instrument_server_test.go index e9af63e..716c6f4 100644 --- a/prometheus/promhttp/instrument_server_test.go +++ b/prometheus/promhttp/instrument_server_test.go @@ -281,6 +281,16 @@ func (t *testResponseWriter) ReadFrom(io.Reader) (int64, error) { return 0, nil } +// testFlusher is an http.ResponseWriter that also implements http.Flusher. +type testFlusher struct { + flushCalled bool +} + +func (t *testFlusher) Header() http.Header { return nil } +func (t *testFlusher) Write([]byte) (int, error) { return 0, nil } +func (t *testFlusher) WriteHeader(int) {} +func (t *testFlusher) Flush() { t.flushCalled = true } + func TestInterfaceUpgrade(t *testing.T) { w := &testResponseWriter{} d := newDelegator(w, nil) @@ -299,6 +309,22 @@ func TestInterfaceUpgrade(t *testing.T) { if _, ok := d.(http.Hijacker); ok { t.Error("delegator unexpectedly implements http.Hijacker") } + + f := &testFlusher{} + d = newDelegator(f, nil) + if _, ok := d.(http.CloseNotifier); ok { + t.Error("delegator unexpectedly implements http.CloseNotifier") + } + d.(http.Flusher).Flush() + if !w.flushCalled { + t.Error("Flush not called") + } + if _, ok := d.(io.ReaderFrom); ok { + t.Error("delegator unexpectedly implements io.ReaderFrom") + } + if _, ok := d.(http.Hijacker); ok { + t.Error("delegator unexpectedly implements http.Hijacker") + } } func ExampleInstrumentHandlerDuration() { From e87046a87e6fa0385d2ff32b11e7ed938664d814 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Fri, 2 Feb 2018 15:53:28 +0100 Subject: [PATCH 2/2] Fix more interface upgrade bugs --- prometheus/promhttp/delegator.go | 4 ++-- prometheus/promhttp/delegator_1_8.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/prometheus/promhttp/delegator.go b/prometheus/promhttp/delegator.go index 659c717..9c1c66d 100644 --- a/prometheus/promhttp/delegator.go +++ b/prometheus/promhttp/delegator.go @@ -102,10 +102,10 @@ func init() { return d } pickDelegator[closeNotifier] = func(d *responseWriterDelegator) delegator { // 1 - return closeNotifierDelegator{d} + return &closeNotifierDelegator{d} } pickDelegator[flusher] = func(d *responseWriterDelegator) delegator { // 2 - return flusherDelegator{d} + return &flusherDelegator{d} } pickDelegator[flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 3 return struct { diff --git a/prometheus/promhttp/delegator_1_8.go b/prometheus/promhttp/delegator_1_8.go index f4d386f..75a905e 100644 --- a/prometheus/promhttp/delegator_1_8.go +++ b/prometheus/promhttp/delegator_1_8.go @@ -28,7 +28,7 @@ func (d *pusherDelegator) Push(target string, opts *http.PushOptions) error { func init() { pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16 - return pusherDelegator{d} + return &pusherDelegator{d} } pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17 return struct {