Connect should be passed a Responder interface

For connect handlers that need to respond with a structured error or
structured object, pass an interface that hides the details of writing
an object to the response (error or runtime.Object).

Example use case:

Connect handler that accepts a body input stream, which it streams to a
pod, and then returns a structured object with info about the pod it
just created.
This commit is contained in:
Clayton Coleman
2015-10-10 23:14:18 -04:00
parent 307fbeec3f
commit d4cdabf2fc
6 changed files with 203 additions and 61 deletions

View File

@@ -26,6 +26,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"golang.org/x/net/websocket"
@@ -33,6 +34,19 @@ import (
"k8s.io/kubernetes/pkg/util/proxy"
)
type fakeResponder struct {
called bool
err error
}
func (r *fakeResponder) Error(err error) {
if r.called {
panic("called twice")
}
r.called = true
r.err = err
}
type SimpleBackendHandler struct {
requestURL url.URL
requestHeader http.Header
@@ -110,6 +124,8 @@ func TestServeHTTP(t *testing.T) {
responseHeader map[string]string
expectedRespHeader map[string]string
notExpectedRespHeader []string
upgradeRequired bool
expectError func(err error) bool
}{
{
name: "root path, simple get",
@@ -117,6 +133,15 @@ func TestServeHTTP(t *testing.T) {
requestPath: "/",
expectedPath: "/",
},
{
name: "no upgrade header sent",
method: "GET",
requestPath: "/",
upgradeRequired: true,
expectError: func(err error) bool {
return err != nil && strings.Contains(err.Error(), "Upgrade request required")
},
},
{
name: "simple path, get",
method: "GET",
@@ -163,7 +188,7 @@ func TestServeHTTP(t *testing.T) {
},
}
for _, test := range tests {
for i, test := range tests {
func() {
backendResponse := "<html><head></head><body><a href=\"/test/path\">Hello</a></body></html>"
backendResponseHeader := test.responseHeader
@@ -179,10 +204,13 @@ func TestServeHTTP(t *testing.T) {
backendServer := httptest.NewServer(backendHandler)
defer backendServer.Close()
responder := &fakeResponder{}
backendURL, _ := url.Parse(backendServer.URL)
backendURL.Path = test.requestPath
proxyHandler := &UpgradeAwareProxyHandler{
Location: backendURL,
Location: backendURL,
Responder: responder,
UpgradeRequired: test.upgradeRequired,
}
proxyServer := httptest.NewServer(proxyHandler)
defer proxyServer.Close()
@@ -214,6 +242,17 @@ func TestServeHTTP(t *testing.T) {
t.Errorf("Error from proxy request: %v", err)
}
if test.expectError != nil {
if !responder.called {
t.Errorf("%d: responder was not invoked", i)
return
}
if !test.expectError(responder.err) {
t.Errorf("%d: unexpected error: %v", i, responder.err)
}
return
}
// Validate backend request
// Method
if backendHandler.requestMethod != test.method {
@@ -253,9 +292,8 @@ func TestServeHTTP(t *testing.T) {
}
// Error
err = proxyHandler.RequestError()
if err != nil {
t.Errorf("Unexpected proxy handler error: %v", err)
if responder.called {
t.Errorf("Unexpected proxy handler error: %v", responder.err)
}
}()
}