From 19343c6014b404fe4f69090705a850cb0e9e8399 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Sun, 8 Jun 2014 16:10:29 -0700 Subject: [PATCH 1/2] Add test to kubelet, coverage up to 37% --- pkg/kubelet/kubelet_server.go | 10 ++- pkg/kubelet/kubelet_server_test.go | 131 +++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 pkg/kubelet/kubelet_server_test.go diff --git a/pkg/kubelet/kubelet_server.go b/pkg/kubelet/kubelet_server.go index 26fbedb7d58..54fadd965f9 100644 --- a/pkg/kubelet/kubelet_server.go +++ b/pkg/kubelet/kubelet_server.go @@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + package kubelet import ( @@ -26,10 +27,17 @@ import ( ) type KubeletServer struct { - Kubelet *Kubelet + Kubelet kubeletInterface UpdateChannel chan api.ContainerManifest } +// kubeletInterface contains all the kubelet methods required by the server. +// For testablitiy. +type kubeletInterface interface { + GetContainerID(name string) (string, error) + GetContainerInfo(name string) (string, error) +} + func (s *KubeletServer) error(w http.ResponseWriter, err error) { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Internal Error: %#v", err) diff --git a/pkg/kubelet/kubelet_server_test.go b/pkg/kubelet/kubelet_server_test.go new file mode 100644 index 00000000000..cd65cdded2f --- /dev/null +++ b/pkg/kubelet/kubelet_server_test.go @@ -0,0 +1,131 @@ +package kubelet + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "reflect" + "sync" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" +) + +type fakeKubelet struct { + infoFunc func(name string) (string, error) + idFunc func(name string) (string, error) +} + +func (fk *fakeKubelet) GetContainerInfo(name string) (string, error) { + return fk.infoFunc(name) +} + +func (fk *fakeKubelet) GetContainerID(name string) (string, error) { + return fk.idFunc(name) +} + +// If we made everything distribute a list of ContainerManifests, we could just use +// channelReader. +type channelReaderSingle struct { + list []api.ContainerManifest + wg sync.WaitGroup +} + +func startReadingSingle(channel <-chan api.ContainerManifest) *channelReaderSingle { + cr := &channelReaderSingle{} + cr.wg.Add(1) + go func() { + for { + manifest, ok := <-channel + if !ok { + break + } + cr.list = append(cr.list, manifest) + } + cr.wg.Done() + }() + return cr +} + +func (cr *channelReaderSingle) GetList() []api.ContainerManifest { + cr.wg.Wait() + return cr.list +} + +type serverTestFramework struct { + updateChan chan api.ContainerManifest + updateReader *channelReaderSingle + serverUnderTest *KubeletServer + fakeKubelet *fakeKubelet + testHttpServer *httptest.Server +} + +func makeServerTest() *serverTestFramework { + fw := &serverTestFramework{ + updateChan: make(chan api.ContainerManifest), + } + fw.updateReader = startReadingSingle(fw.updateChan) + fw.fakeKubelet = &fakeKubelet{} + fw.serverUnderTest = &KubeletServer{ + Kubelet: fw.fakeKubelet, + UpdateChannel: fw.updateChan, + } + fw.testHttpServer = httptest.NewServer(fw.serverUnderTest) + return fw +} + +func readResp(resp *http.Response) (string, error) { + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + return string(body), err +} + +func TestContainer(t *testing.T) { + fw := makeServerTest() + expected := api.ContainerManifest{Id: "test_manifest"} + body := bytes.NewBuffer([]byte(util.MakeJSONString(expected))) + resp, err := http.Post(fw.testHttpServer.URL+"/container", "application/json", body) + if err != nil { + t.Errorf("Post returned: %v", err) + } + resp.Body.Close() + close(fw.updateChan) + recieved := fw.updateReader.GetList() + if len(recieved) != 1 { + t.Errorf("Expected 1 manifest, but got %v", len(recieved)) + } + if !reflect.DeepEqual(expected, recieved[0]) { + t.Errorf("Expected %#v, but got %#v", expected, recieved[0]) + } +} + +func TestContainerInfo(t *testing.T) { + fw := makeServerTest() + expected := "good container info string" + fw.fakeKubelet.idFunc = func(name string) (string, error) { + if name == "goodcontainer" { + return name, nil + } + return "", fmt.Errorf("bad container") + } + fw.fakeKubelet.infoFunc = func(name string) (string, error) { + if name == "goodcontainer" { + return expected, nil + } + return "", fmt.Errorf("bad container") + } + resp, err := http.Get(fw.testHttpServer.URL + "/containerInfo?container=goodcontainer") + if err != nil { + t.Errorf("Got error GETing: %v", err) + } + got, err := readResp(resp) + if err != nil { + t.Errorf("Error reading body: %v", err) + } + if got != expected { + t.Errorf("Expected: '%v', got: '%v'", expected, got) + } +} From c3c739d6b4b5f66fd71ff85f2156972b6dcab70e Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Sun, 8 Jun 2014 19:48:04 -0700 Subject: [PATCH 2/2] Fix spelling --- pkg/kubelet/kubelet_server_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/kubelet/kubelet_server_test.go b/pkg/kubelet/kubelet_server_test.go index cd65cdded2f..32f39782050 100644 --- a/pkg/kubelet/kubelet_server_test.go +++ b/pkg/kubelet/kubelet_server_test.go @@ -93,12 +93,12 @@ func TestContainer(t *testing.T) { } resp.Body.Close() close(fw.updateChan) - recieved := fw.updateReader.GetList() - if len(recieved) != 1 { - t.Errorf("Expected 1 manifest, but got %v", len(recieved)) + received := fw.updateReader.GetList() + if len(received) != 1 { + t.Errorf("Expected 1 manifest, but got %v", len(received)) } - if !reflect.DeepEqual(expected, recieved[0]) { - t.Errorf("Expected %#v, but got %#v", expected, recieved[0]) + if !reflect.DeepEqual(expected, received[0]) { + t.Errorf("Expected %#v, but got %#v", expected, received[0]) } }