From ec5ecb18fab9cfaed3bba76a9e5319ca05a738e6 Mon Sep 17 00:00:00 2001 From: Phillip Wittrock Date: Fri, 20 Nov 2015 15:59:31 -0800 Subject: [PATCH] Initial Pod e2e test --- hack/verify-flags/known-flags.txt | 5 +- test/e2e_node/e2e_node_suite_test.go | 8 ++-- test/e2e_node/gcloud/gcloud.go | 7 +-- test/e2e_node/kubelet_test.go | 69 ++++++++++++++++++++-------- test/e2e_node/runner/run_e2e.go | 7 +-- test/e2e_node/util.go | 37 +++++++++++++++ 6 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 test/e2e_node/util.go diff --git a/hack/verify-flags/known-flags.txt b/hack/verify-flags/known-flags.txt index 2bcb625923..39061d1908 100644 --- a/hack/verify-flags/known-flags.txt +++ b/hack/verify-flags/known-flags.txt @@ -10,10 +10,10 @@ algorithm-provider all-namespaces allocate-node-cidrs allow-privileged +api-server-address api-burst api-prefix api-rate -api-server-host api-server-port api-servers api-token @@ -140,12 +140,12 @@ km-path kube-api-burst kube-api-qps kubectl-path +kubelet-address kubelet-cadvisor-port kubelet-certificate-authority kubelet-client-certificate kubelet-client-key kubelet-docker-endpoint -kubelet-host kubelet-host-network-sources kubelet-https kubelet-network-plugin @@ -209,6 +209,7 @@ node-monitor-grace-period node-monitor-period node-label node-labels-file +node-name node-startup-grace-period node-status-update-frequency node-sync-period diff --git a/test/e2e_node/e2e_node_suite_test.go b/test/e2e_node/e2e_node_suite_test.go index b4a230c5fc..177074a6a3 100644 --- a/test/e2e_node/e2e_node_suite_test.go +++ b/test/e2e_node/e2e_node_suite_test.go @@ -24,11 +24,9 @@ import ( "testing" ) -var kubeletHost = flag.String("kubelet-host", "localhost", "Host address of the kubelet") -var kubeletPort = flag.Int("kubelet-port", 10250, "Kubelet port") - -var apiServerHost = flag.String("api-server-host", "localhost", "Host address of the api server") -var apiServerPort = flag.Int("api-server-port", 8080, "Api server port") +var kubeletAddress = flag.String("kubelet-address", "localhost:10250", "Host and port of the kubelet") +var apiServerAddress = flag.String("api-server-address", "localhost:8080", "Host and port of the api server") +var nodeName = flag.String("node-name", "", "Name of the node") func TestE2eNode(t *testing.T) { flag.Parse() diff --git a/test/e2e_node/gcloud/gcloud.go b/test/e2e_node/gcloud/gcloud.go index d073bc981a..1a62f735ae 100644 --- a/test/e2e_node/gcloud/gcloud.go +++ b/test/e2e_node/gcloud/gcloud.go @@ -72,13 +72,14 @@ func (gc *gCloudClientImpl) Command(cmd string, moreargs ...string) ([]byte, err return exec.Command("gcloud", args...).CombinedOutput() } -func (gc *gCloudClientImpl) TunnelCommand(sudo bool, lPort string, rPort string, cmd string, moreargs ...string) ([]byte, error) { +func (gc *gCloudClientImpl) TunnelCommand(sudo bool, lPort string, rPort string, dir string, cmd string, moreargs ...string) ([]byte, error) { tunnelStr := fmt.Sprintf("-L %s:localhost:%s", lPort, rPort) args := []string{"compute", "ssh"} if gc.zone != "" { args = append(args, "--zone", gc.zone) } args = append(args, "--ssh-flag", tunnelStr, gc.host, "--") + args = append(args, "cd", dir, ";") if sudo { args = append(args, "sudo") } @@ -143,10 +144,10 @@ func (gc *gCloudClientImpl) CopyAndRun(sudo bool, remotePort string, bin string, // Do the setup go func() { // Start the process - out, err = gc.TunnelCommand(sudo, h.LPort, remotePort, cmd, args...) + out, err = gc.TunnelCommand(sudo, h.LPort, remotePort, tDir, fmt.Sprintf("./%s", f), args...) if err != nil { glog.Errorf("command failed %v", err) - h.Output <- RunResult{out, err, fmt.Sprintf("%s %s", cmd, strings.Join(args, " "))} + h.Output <- RunResult{out, err, fmt.Sprintf("%s %s", f, strings.Join(args, " "))} return } }() diff --git a/test/e2e_node/kubelet_test.go b/test/e2e_node/kubelet_test.go index c07fe35940..0e449ac689 100644 --- a/test/e2e_node/kubelet_test.go +++ b/test/e2e_node/kubelet_test.go @@ -17,36 +17,65 @@ limitations under the License. package e2e_node import ( + "bytes" "fmt" - "io/ioutil" - "net/http" + "time" - "github.com/golang/glog" . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/kubernetes/pkg/api" + client "k8s.io/kubernetes/pkg/client/unversioned" ) var _ = Describe("Kubelet", func() { + var cl *client.Client BeforeEach(func() { - // Setup the client to talk to the kubelet + // Setup the apiserver client + cl = client.NewOrDie(&client.Config{Host: *apiServerAddress}) }) - Describe("checking kubelet status", func() { - Context("when retrieving the node status", func() { - It("should have the container version", func() { + Describe("pod scheduling", func() { + Context("when scheduling a busybox command in a pod", func() { + It("it should return succes", func() { + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "busybox", + Namespace: api.NamespaceDefault, + }, + Spec: api.PodSpec{ + NodeName: *nodeName, + Containers: []api.Container{ + { + Image: "busybox", + Name: "busybox", + Command: []string{"echo", "'Hello World'"}, + ImagePullPolicy: "IfNotPresent", + }, + }, + }, + } + _, err := cl.Pods(api.NamespaceDefault).Create(pod) + Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err)) + }) - // TODO: This is just a place holder, write a real test here - resp, err := http.Get(fmt.Sprintf("http://%s:%d/api/v2.0/attributes", *kubeletHost, *kubeletPort)) - if err != nil { - glog.Errorf("Error: %v", err) - return - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - glog.Errorf("Error: %v", err) - return - } - glog.Infof("Resp: %s", body) + It("it should print the output to logs", func() { + errs := Retry(time.Minute*3, time.Second*2, cl, func(cl *client.Client) error { + rc, err := cl.Pods(api.NamespaceDefault).GetLogs("busybox", &api.PodLogOptions{}).Stream() + if err != nil { + return err + } + defer rc.Close() + buf := new(bytes.Buffer) + buf.ReadFrom(rc) + Expect(buf.String()).To(Equal("'Hello World'\n")) + return nil + }) + Expect(errs).To(BeEmpty(), fmt.Sprintf("Failed to get Logs")) + }) + + It("it should be possible to delete", func() { + err := cl.Pods(api.NamespaceDefault).Delete("busybox", &api.DeleteOptions{}) + Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err)) }) }) }) diff --git a/test/e2e_node/runner/run_e2e.go b/test/e2e_node/runner/run_e2e.go index b4f4fc2519..939fae8079 100644 --- a/test/e2e_node/runner/run_e2e.go +++ b/test/e2e_node/runner/run_e2e.go @@ -96,7 +96,7 @@ func main() { // Wait for the tests to finish w.Wait() - glog.Infof("All hosts finished") + glog.Infof("Done") } func WaitForUser() { @@ -148,7 +148,8 @@ func runTests(host string) ([]byte, error) { ginkoTests := filepath.Join(kubeRoot, ginkoTestRelPath) return exec.Command( "ginkgo", ginkoTests, "--", - "--kubelet-host", "localhost", "--kubelet-port", kh.LPort, - "--api-server-host", "localhost", "--api-server-port", kh.LPort, + "--kubelet-address", fmt.Sprintf("http://localhost:%s", kh.LPort), + "--api-server-address", fmt.Sprintf("http://localhost:%s", ah.LPort), + "--node-name", host, "-logtostderr").CombinedOutput() } diff --git a/test/e2e_node/util.go b/test/e2e_node/util.go new file mode 100644 index 0000000000..0082acda22 --- /dev/null +++ b/test/e2e_node/util.go @@ -0,0 +1,37 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 e2e_node + +import ( + "time" + + client "k8s.io/kubernetes/pkg/client/unversioned" +) + +type RetryFn func(cl *client.Client) error + +func Retry(maxWait time.Duration, wait time.Duration, cl *client.Client, retry RetryFn) []error { + errs := []error{} + for start := time.Now(); time.Now().Before(start.Add(maxWait)); { + if err := retry(cl); err != nil { + errs = append(errs, err) + } else { + return []error{} + } + } + return errs +}