diff --git a/test/e2e/pod_has_service_env_vars.go b/test/e2e/pod_has_service_env_vars.go deleted file mode 100644 index e4584e4a546..00000000000 --- a/test/e2e/pod_has_service_env_vars.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright 2014 Google Inc. 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 - -import ( - "strings" - "time" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/client" - "github.com/golang/glog" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -// TestPodHasServiceEnvVars checks that kubelets and scheduler send events about pods scheduling and running. -func TestPodHasServiceEnvVars(c *client.Client) bool { - // Make a pod that will be a service. - // This pod serves its hostname via HTTP. - serverPod := parsePodOrDie(`{ - "kind": "Pod", - "apiVersion": "v1beta1", - "id": "srv", - "desiredState": { - "manifest": { - "version": "v1beta1", - "id": "srv", - "containers": [{ - "name": "srv", - "image": "kubernetes/serve_hostname", - "ports": [{ - "containerPort": 9376, - "hostPort": 8080 - }] - }] - } - }, - "labels": { - "name": "srv" - } - }`) - _, err := c.Pods(api.NamespaceDefault).Create(serverPod) - if err != nil { - glog.Errorf("Failed to create serverPod: %v", err) - return false - } - defer c.Pods(api.NamespaceDefault).Delete(serverPod.Name) - waitForPodRunning(c, serverPod.Name) - - // This service exposes pod p's port 8080 as a service on port 8765 - svc := parseServiceOrDie(`{ - "id": "fooservice", - "kind": "Service", - "apiVersion": "v1beta1", - "port": 8765, - "containerPort": 8080, - "selector": { - "name": "p" - } - }`) - if err != nil { - glog.Errorf("Failed to delete service: %v", err) - return false - } - time.Sleep(2) - _, err = c.Services(api.NamespaceDefault).Create(svc) - if err != nil { - glog.Errorf("Failed to create service: %v", err) - return false - } - defer c.Services(api.NamespaceDefault).Delete(svc.Name) - - // TODO: we don't have a way to wait for a service to be "running". - // If this proves flaky, then we will need to retry the clientPod or insert a sleep. - - // Make a client pod that verifies that it has the service environment variables. - clientPod := parsePodOrDie(`{ - "apiVersion": "v1beta1", - "kind": "Pod", - "id": "env3", - "desiredState": { - "manifest": { - "version": "v1beta1", - "id": "env3", - "restartPolicy": { "never": {} }, - "containers": [{ - "name": "env3cont", - "image": "busybox", - "command": ["sh", "-c", "env"] - }] - } - }, - "labels": { "name": "env3" } - }`) - _, err = c.Pods(api.NamespaceDefault).Create(clientPod) - if err != nil { - glog.Errorf("Failed to create pod: %v", err) - return false - } - defer c.Pods(api.NamespaceDefault).Delete(clientPod.Name) - - // Wait for client pod to complete. - success := waitForPodSuccess(c, clientPod.Name, clientPod.Spec.Containers[0].Name) - if !success { - glog.Errorf("Failed to run client pod to detect service env vars.") - } - - // Grab its logs. Get host first. - clientPodStatus, err := c.Pods(api.NamespaceDefault).Get(clientPod.Name) - if err != nil { - glog.Errorf("Failed to get clientPod to know host: %v", err) - return false - } - glog.Infof("Trying to get logs from host %s pod %s container %s: %v", - clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err) - logs, err := c.Get(). - Prefix("proxy"). - Resource("minions"). - Name(clientPodStatus.Status.Host). - Suffix("containerLogs", api.NamespaceDefault, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name). - Do(). - Raw() - if err != nil { - glog.Errorf("Failed to get logs from host %s pod %s container %s: %v", - clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err) - return false - } - glog.Info("clientPod logs:", string(logs)) - - toFind := []string{ - "FOOSERVICE_SERVICE_HOST=", - "FOOSERVICE_SERVICE_PORT=", - "FOOSERVICE_PORT=", - "FOOSERVICE_PORT_8765_TCP_PORT=", - "FOOSERVICE_PORT_8765_TCP_PROTO=", - "FOOSERVICE_PORT_8765_TCP=", - "FOOSERVICE_PORT_8765_TCP_ADDR=", - } - - for _, m := range toFind { - if !strings.Contains(string(logs), m) { - glog.Errorf("Unable to find env var %q in client env vars.", m) - success = false - } - } - - // We could try a wget the service from the client pod. But services.sh e2e test covers that pretty well. - return success -} - -var _ = Describe("TestPodHasServiceEnvVars", func() { - It("should pass", func() { - // TODO: Instead of OrDie, client should Fail the test if there's a problem. - // In general tests should Fail() instead of glog.Fatalf(). - Expect(TestPodHasServiceEnvVars(loadClientOrDie())).To(BeTrue()) - }) -}) diff --git a/test/e2e/pod_update.go b/test/e2e/pod_update.go deleted file mode 100644 index 4b5666d4dd7..00000000000 --- a/test/e2e/pod_update.go +++ /dev/null @@ -1,108 +0,0 @@ -/* -Copyright 2014 Google Inc. 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 - -import ( - "strconv" - "time" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/client" - "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/golang/glog" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestPodUpdate(c *client.Client) bool { - podClient := c.Pods(api.NamespaceDefault) - - name := "pod-update-" + string(util.NewUUID()) - value := strconv.Itoa(time.Now().Nanosecond()) - pod := &api.Pod{ - ObjectMeta: api.ObjectMeta{ - Name: name, - Labels: map[string]string{ - "name": "foo", - "time": value, - }, - }, - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "nginx", - Image: "dockerfile/nginx", - Ports: []api.Port{{ContainerPort: 80, HostPort: 8080}}, - LivenessProbe: &api.Probe{ - Handler: api.Handler{ - HTTPGet: &api.HTTPGetAction{ - Path: "/index.html", - Port: util.NewIntOrStringFromInt(8080), - }, - }, - InitialDelaySeconds: 30, - }, - }, - }, - }, - } - _, err := podClient.Create(pod) - if err != nil { - glog.Errorf("Failed to create pod: %v", err) - return false - } - defer podClient.Delete(pod.Name) - waitForPodRunning(c, pod.Name) - pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) - if len(pods.Items) != 1 { - glog.Errorf("Failed to find the correct pod") - return false - } - - podOut, err := podClient.Get(pod.Name) - if err != nil { - glog.Errorf("Failed to get pod: %v", err) - return false - } - value = "time" + value - pod.Labels["time"] = value - pod.ResourceVersion = podOut.ResourceVersion - pod.UID = podOut.UID - pod, err = podClient.Update(pod) - if err != nil { - glog.Errorf("Failed to update pod: %v", err) - return false - } - waitForPodRunning(c, pod.Name) - pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) - if len(pods.Items) != 1 { - glog.Errorf("Failed to find the correct pod after update.") - return false - } - glog.Infof("pod update OK") - return true -} - -var _ = Describe("TestPodUpdate", func() { - It("should pass", func() { - // TODO: Instead of OrDie, client should Fail the test if there's a problem. - // In general tests should Fail() instead of glog.Fatalf(). - Expect(TestPodUpdate(loadClientOrDie())).To(BeTrue()) - }) -}) diff --git a/test/e2e/pods.go b/test/e2e/pods.go new file mode 100644 index 00000000000..64f760acc55 --- /dev/null +++ b/test/e2e/pods.go @@ -0,0 +1,286 @@ +/* +Copyright 2014 Google Inc. 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 + +import ( + "fmt" + "strconv" + "time" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Pods", func() { + var ( + c *client.Client + ) + + BeforeEach(func() { + c = loadClientOrDie() + }) + + It("should be submitted and removed", func() { + podClient := c.Pods(api.NamespaceDefault) + + By("loading the pod json") + pod := loadPodOrDie(assetPath("api", "examples", "pod.json")) + value := strconv.Itoa(time.Now().Nanosecond()) + pod.Name = pod.Name + "-" + randomSuffix() + pod.Labels["time"] = value + pod.Spec.Containers[0].Ports[0].HostPort = 0 + + By("submitting the pod to kubernetes") + _, err := podClient.Create(pod) + if err != nil { + Fail(fmt.Sprintf("Failed to create pod: %v", err)) + } + defer func() { + // We call defer here in case there is a problem with + // the test so we can ensure that we clean up after + // ourselves + defer GinkgoRecover() + podClient.Delete(pod.Name) + }() + + By("verifying the pod is in kubernetes") + pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) + if err != nil { + Fail(fmt.Sprintf("Failed to query for pods: %v", err)) + } + Expect(len(pods.Items)).To(Equal(1)) + + By("deleting the pod") + podClient.Delete(pod.Name) + pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) + Expect(len(pods.Items)).To(Equal(0)) + }) + + It("should be updated", func() { + podClient := c.Pods(api.NamespaceDefault) + + By("creating the pod") + name := "pod-update-" + string(util.NewUUID()) + value := strconv.Itoa(time.Now().Nanosecond()) + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: name, + Labels: map[string]string{ + "name": "foo", + "time": value, + }, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "nginx", + Image: "dockerfile/nginx", + Ports: []api.Port{{ContainerPort: 80, HostPort: 8080}}, + LivenessProbe: &api.Probe{ + Handler: api.Handler{ + HTTPGet: &api.HTTPGetAction{ + Path: "/index.html", + Port: util.NewIntOrStringFromInt(8080), + }, + }, + InitialDelaySeconds: 30, + }, + }, + }, + }, + } + + By("submitting the pod to kubernetes") + _, err := podClient.Create(pod) + if err != nil { + Fail(fmt.Sprintf("Failed to create pod: %v", err)) + } + defer func() { + By("deleting the pod") + defer GinkgoRecover() + podClient.Delete(pod.Name) + }() + + By("waiting for the pod to start running") + waitForPodRunning(c, pod.Name) + + By("verifying the pod is in kubernetes") + pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) + Expect(len(pods.Items)).To(Equal(1)) + + By("retrieving the pod") + podOut, err := podClient.Get(pod.Name) + if err != nil { + Fail(fmt.Sprintf("Failed to get pod: %v", err)) + } + + By("updating the pod") + value = "time" + value + pod.Labels["time"] = value + pod.ResourceVersion = podOut.ResourceVersion + pod.UID = podOut.UID + pod, err = podClient.Update(pod) + if err != nil { + Fail(fmt.Sprintf("Failed to update pod: %v", err)) + } + + By("waiting for the updated pod to start running") + waitForPodRunning(c, pod.Name) + + By("verifying the updated pod is in kubernetes") + pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) + Expect(len(pods.Items)).To(Equal(1)) + fmt.Println("pod update OK") + }) + + It("should contain environment variables for services", func() { + // Make a pod that will be a service. + // This pod serves its hostname via HTTP. + serverPod := parsePodOrDie(`{ + "kind": "Pod", + "apiVersion": "v1beta1", + "id": "srv", + "desiredState": { + "manifest": { + "version": "v1beta1", + "id": "srv", + "containers": [{ + "name": "srv", + "image": "kubernetes/serve_hostname", + "ports": [{ + "containerPort": 9376, + "hostPort": 8080 + }] + }] + } + }, + "labels": { + "name": "srv" + } + }`) + _, err := c.Pods(api.NamespaceDefault).Create(serverPod) + if err != nil { + Fail(fmt.Sprintf("Failed to create serverPod: %v", err)) + } + defer func() { + defer GinkgoRecover() + c.Pods(api.NamespaceDefault).Delete(serverPod.Name) + }() + waitForPodRunning(c, serverPod.Name) + + // This service exposes pod p's port 8080 as a service on port 8765 + svc := parseServiceOrDie(`{ + "id": "fooservice", + "kind": "Service", + "apiVersion": "v1beta1", + "port": 8765, + "containerPort": 8080, + "selector": { + "name": "p" + } + }`) + if err != nil { + Fail(fmt.Sprintf("Failed to delete service: %v", err)) + } + time.Sleep(2) + _, err = c.Services(api.NamespaceDefault).Create(svc) + if err != nil { + Fail(fmt.Sprintf("Failed to create service: %v", err)) + } + defer func() { + defer GinkgoRecover() + c.Services(api.NamespaceDefault).Delete(svc.Name) + }() + + // TODO: we don't have a way to wait for a service to be "running". // If this proves flaky, then we will need to retry the clientPod or insert a sleep. + + // Make a client pod that verifies that it has the service environment variables. + clientPod := parsePodOrDie(`{ + "apiVersion": "v1beta1", + "kind": "Pod", + "id": "env3", + "desiredState": { + "manifest": { + "version": "v1beta1", + "id": "env3", + "restartPolicy": { "never": {} }, + "containers": [{ + "name": "env3cont", + "image": "busybox", + "command": ["sh", "-c", "env"] + }] + } + }, + "labels": { "name": "env3" } + }`) + _, err = c.Pods(api.NamespaceDefault).Create(clientPod) + if err != nil { + Fail(fmt.Sprintf("Failed to create pod: %v", err)) + } + defer func() { + defer GinkgoRecover() + c.Pods(api.NamespaceDefault).Delete(clientPod.Name) + }() + + // Wait for client pod to complete. + success := waitForPodSuccess(c, clientPod.Name, clientPod.Spec.Containers[0].Name) + if !success { + Fail(fmt.Sprintf("Failed to run client pod to detect service env vars.")) + } + + // Grab its logs. Get host first. + clientPodStatus, err := c.Pods(api.NamespaceDefault).Get(clientPod.Name) + if err != nil { + Fail(fmt.Sprintf("Failed to get clientPod to know host: %v", err)) + } + By(fmt.Sprintf("Trying to get logs from host %s pod %s container %s: %v", + clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err)) + logs, err := c.Get(). + Prefix("proxy"). + Resource("minions"). + Name(clientPodStatus.Status.Host). + Suffix("containerLogs", api.NamespaceDefault, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name). + Do(). + Raw() + if err != nil { + Fail(fmt.Sprintf("Failed to get logs from host %s pod %s container %s: %v", + clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err)) + } + fmt.Sprintf("clientPod logs:%v\n", string(logs)) + + toFind := []string{ + "FOOSERVICE_SERVICE_HOST=", + "FOOSERVICE_SERVICE_PORT=", + "FOOSERVICE_PORT=", + "FOOSERVICE_PORT_8765_TCP_PORT=", + "FOOSERVICE_PORT_8765_TCP_PROTO=", + "FOOSERVICE_PORT_8765_TCP=", + "FOOSERVICE_PORT_8765_TCP_ADDR=", + } + + for _, m := range toFind { + Expect(string(logs)).To(ContainSubstring(m), "%q in client env vars", m) + } + + // We could try a wget the service from the client pod. But services.sh e2e test covers that pretty well. + }) +})