open-nomad/api/internal/testutil/responsewriter.go
Jeff Mitchell 13dab7dd24
Divest api/ package of deps elsewhere in the nomad repo. (#5488)
* Divest api/ package of deps elsewhere in the nomad repo.

This will allow making api/ a module without then pulling in the
external repo, leading to a package name conflict.

This required some migration of tests to an apitests/ folder (can be
moved anywhere as it has no deps on it). It also required some
duplication of code, notably some test helpers from api/ -> apitests/
and part (but not all) of testutil/ -> api/testutil/.

Once there's more separation and an e.g. sdk/ folder those can be
removed in favor of a dep on the sdk/ folder, provided the sdk/ folder
doesn't depend on api/ or /.

* Also remove consul dep from api/ package

* Fix stupid linters

* Some restructuring
2019-03-29 14:47:40 -04:00

77 lines
2 KiB
Go

package testutil
import (
"net/http"
"net/http/httptest"
"sync"
)
// assert ResponseRecorder implements the http.ResponseWriter interface
var _ http.ResponseWriter = (*ResponseRecorder)(nil)
// ResponseRecorder implements a ResponseWriter which can be written to and
// read from concurrently. For use in testing streaming APIs where
// httptest.ResponseRecorder is unsafe for concurrent access. Uses
// httptest.ResponseRecorder internally and exposes most of the functionality.
type ResponseRecorder struct {
rr *httptest.ResponseRecorder
mu sync.Mutex
}
func NewResponseRecorder() *ResponseRecorder {
return &ResponseRecorder{
rr: httptest.NewRecorder(),
}
}
// Flush sets Flushed=true.
func (r *ResponseRecorder) Flush() {
r.mu.Lock()
defer r.mu.Unlock()
r.rr.Flush()
}
// Flushed returns true if Flush has been called.
func (r *ResponseRecorder) Flushed() bool {
r.mu.Lock()
defer r.mu.Unlock()
return r.rr.Flushed
}
// Header returns the response headers. Readers should call HeaderMap() to
// avoid races due to the server concurrently mutating headers.
func (r *ResponseRecorder) Header() http.Header {
r.mu.Lock()
defer r.mu.Unlock()
return r.rr.Header()
}
// HeaderMap returns the HTTP headers written before WriteHeader was called.
func (r *ResponseRecorder) HeaderMap() http.Header {
r.mu.Lock()
defer r.mu.Unlock()
return r.rr.HeaderMap
}
// Write to the underlying response buffer. Safe to call concurrent with Read.
func (r *ResponseRecorder) Write(p []byte) (int, error) {
r.mu.Lock()
defer r.mu.Unlock()
return r.rr.Body.Write(p)
}
// WriteHeader sets the response code and freezes the headers returned by
// HeaderMap. Safe to call concurrent with Read and HeaderMap.
func (r *ResponseRecorder) WriteHeader(statusCode int) {
r.mu.Lock()
defer r.mu.Unlock()
r.rr.WriteHeader(statusCode)
}
// Read available response bytes. Safe to call concurrently with Write().
func (r *ResponseRecorder) Read(p []byte) (int, error) {
r.mu.Lock()
defer r.mu.Unlock()
return r.rr.Body.Read(p)
}