Merge pull request #545 from kelseyhightower/heath_tests

Improve test coverage for the health package and remove mocks
This commit is contained in:
Daniel Smith 2014-07-21 15:49:10 -07:00
commit 5f13c4b048
4 changed files with 65 additions and 55 deletions

View File

@ -204,4 +204,3 @@ sudo docker build -t kubernetes/raml2html .
sudo docker run --name="docgen" kubernetes/raml2html sudo docker run --name="docgen" kubernetes/raml2html
sudo docker cp docgen:/data/kubernetes.html . sudo docker cp docgen:/data/kubernetes.html .
``` ```

View File

@ -42,12 +42,10 @@ type HTTPGetInterface interface {
// It returns Unknown and err if the HTTP communication itself fails. // It returns Unknown and err if the HTTP communication itself fails.
func Check(url string, client HTTPGetInterface) (Status, error) { func Check(url string, client HTTPGetInterface) (Status, error) {
res, err := client.Get(url) res, err := client.Get(url)
if res.Body != nil {
defer res.Body.Close()
}
if err != nil { if err != nil {
return Unknown, err return Unknown, err
} }
defer res.Body.Close()
if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest { if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest {
return Healthy, nil return Healthy, nil
} }

View File

@ -17,54 +17,62 @@ limitations under the License.
package health package health
import ( import (
"net"
"net/http" "net/http"
"net/http/httptest"
"net/url"
"testing" "testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
) )
// fakeHTTPClient is a fake implementation of HTTPGetInterface. const statusServerEarlyShutdown = -1
type fakeHTTPClient struct {
req string
res http.Response
err error
}
func (f *fakeHTTPClient) Get(url string) (*http.Response, error) { func TestHealthChecker(t *testing.T) {
f.req = url var healthCheckerTests = []struct {
return &f.res, f.err status int
} health Status
}{
func TestHttpHealth(t *testing.T) { {http.StatusOK, Healthy},
fakeClient := fakeHTTPClient{ {statusServerEarlyShutdown, Unknown},
res: http.Response{ {http.StatusBadRequest, Unhealthy},
StatusCode: http.StatusOK, {http.StatusBadGateway, Unhealthy},
}, {http.StatusInternalServerError, Unhealthy},
} }
for _, healthCheckerTest := range healthCheckerTests {
check := HTTPHealthChecker{ tt := healthCheckerTest
client: &fakeClient, ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(tt.status)
}))
u, err := url.Parse(ts.URL)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
host, port, err := net.SplitHostPort(u.Host)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if tt.status == statusServerEarlyShutdown {
ts.Close()
} }
container := api.Container{ container := api.Container{
LivenessProbe: &api.LivenessProbe{ LivenessProbe: &api.LivenessProbe{
HTTPGet: &api.HTTPGetProbe{ HTTPGet: &api.HTTPGetProbe{
Port: "8080", Port: port,
Path: "/foo/bar", Path: "/foo/bar",
Host: host,
}, },
Type: "http", Type: "http",
}, },
} }
hc := NewHealthChecker()
ok, err := check.HealthCheck(container) health, err := hc.HealthCheck(container)
if ok != Healthy { if err != nil && tt.health != Unknown {
t.Error("Unexpected unhealthy") t.Errorf("Unexpected error: %v", err)
} }
if err != nil { if health != tt.health {
t.Errorf("Unexpected error: %#v", err) t.Errorf("Expected %v, got %v", tt.health, health)
} }
if fakeClient.req != "http://localhost:8080/foo/bar" {
t.Errorf("Unexpected url: %s", fakeClient.req)
} }
} }
@ -81,12 +89,10 @@ func TestFindPort(t *testing.T) {
}, },
}, },
} }
check := HTTPHealthChecker{} checker := HTTPHealthChecker{}
validatePort(t, check.findPort(container, "foo"), 8080) want := int64(8080)
} got := checker.findPort(container, "foo")
if got != want {
func validatePort(t *testing.T, port int64, expectedPort int64) { t.Errorf("Expected %v, got %v", want, got)
if port != expectedPort {
t.Errorf("Unexpected port: %d, expected: %d", port, expectedPort)
} }
} }

View File

@ -17,6 +17,8 @@ limitations under the License.
package registry package registry
import ( import (
"bytes"
"io/ioutil"
"net/http" "net/http"
"reflect" "reflect"
"testing" "testing"
@ -24,10 +26,15 @@ import (
type alwaysYes struct{} type alwaysYes struct{}
func (alwaysYes) Get(url string) (*http.Response, error) { func fakeHTTPResponse(status int) *http.Response {
return &http.Response{ return &http.Response{
StatusCode: http.StatusOK, StatusCode: status,
}, nil Body: ioutil.NopCloser(&bytes.Buffer{}),
}
}
func (alwaysYes) Get(url string) (*http.Response, error) {
return fakeHTTPResponse(http.StatusOK), nil
} }
func TestBasicDelegation(t *testing.T) { func TestBasicDelegation(t *testing.T) {
@ -66,9 +73,9 @@ type notMinion struct {
func (n *notMinion) Get(url string) (*http.Response, error) { func (n *notMinion) Get(url string) (*http.Response, error) {
if url != "http://"+n.minion+":10250/healthz" { if url != "http://"+n.minion+":10250/healthz" {
return &http.Response{StatusCode: http.StatusOK}, nil return fakeHTTPResponse(http.StatusOK), nil
} else { } else {
return &http.Response{StatusCode: http.StatusInternalServerError}, nil return fakeHTTPResponse(http.StatusInternalServerError), nil
} }
} }