From 41d40824cf22d68d2fea6e7ce9d3fca07c4b59fc Mon Sep 17 00:00:00 2001 From: liangchenye Date: Tue, 1 Mar 2016 20:03:48 +0800 Subject: [PATCH] image operation conformance test Signed-off-by: liang chenye --- test/e2e_node/conformance_test.go | 65 +++++++++++++++++-- test/e2e_node/image.go | 104 ++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 7 deletions(-) create mode 100644 test/e2e_node/image.go diff --git a/test/e2e_node/conformance_test.go b/test/e2e_node/conformance_test.go index 33ab9c42a1..a3c4b46d53 100644 --- a/test/e2e_node/conformance_test.go +++ b/test/e2e_node/conformance_test.go @@ -40,12 +40,67 @@ var _ = Describe("Container Conformance Test", func() { }) Describe("container conformance blackbox test", func() { + Context("when testing images that exist", func() { + var conformImages []ConformanceImage + conformImageTags := []string{ + "gcr.io/google_containers/busybox:1.24", + "gcr.io/google_containers/mounttest:0.2", + "gcr.io/google_containers/nettest:1.7", + "gcr.io/google_containers/nginx:1.7.9", + } + It("it should pull successfully [Conformance]", func() { + for _, imageTag := range conformImageTags { + image, _ := NewConformanceImage("docker", imageTag) + conformImages = append(conformImages, image) + } + for _, image := range conformImages { + if err := image.Pull(); err != nil { + Expect(err).NotTo(HaveOccurred()) + break + } + } + }) + It("it should list pulled images [Conformance]", func() { + image, _ := NewConformanceImage("docker", "") + tags, _ := image.List() + for _, tag := range conformImageTags { + Expect(tags).To(ContainElement(tag)) + } + }) + It("it should remove successfully [Conformance]", func() { + for _, image := range conformImages { + if err := image.Remove(); err != nil { + Expect(err).NotTo(HaveOccurred()) + break + } + } + }) + }) + Context("when testing image that does not exist", func() { + var invalidImage ConformanceImage + var invalidImageTag string + It("it should not pull successfully [Conformance]", func() { + invalidImageTag = "foo.com/foo/foo" + invalidImage, _ = NewConformanceImage("docker", invalidImageTag) + err := invalidImage.Pull() + Expect(err).To(HaveOccurred()) + }) + It("it should not list pulled images [Conformance]", func() { + image, _ := NewConformanceImage("docker", "") + tags, _ := image.List() + Expect(tags).NotTo(ContainElement(invalidImageTag)) + }) + It("it should not remove successfully [Conformance]", func() { + err := invalidImage.Remove() + Expect(err).To(HaveOccurred()) + }) + }) Context("when running a container that terminates", func() { var terminateCase ConformanceContainer - BeforeEach(func() { + It("it should start successfully [Conformance]", func() { terminateCase = ConformanceContainer{ Container: api.Container{ - Image: "gcr.io/google_containers/busybox:1.24", + Image: "gcr.io/google_containers/busybox", Name: "busybox", Command: []string{"sh", "-c", "env"}, ImagePullPolicy: api.PullIfNotPresent, @@ -54,8 +109,6 @@ var _ = Describe("Container Conformance Test", func() { Phase: api.PodSucceeded, NodeName: *nodeName, } - }) - It("it should start successfully [Conformance]", func() { err := terminateCase.Create() Expect(err).NotTo(HaveOccurred()) @@ -81,7 +134,7 @@ var _ = Describe("Container Conformance Test", func() { }) Context("when running a container with invalid image", func() { var invalidImageCase ConformanceContainer - BeforeEach(func() { + It("it should not start successfully [Conformance]", func() { invalidImageCase = ConformanceContainer{ Container: api.Container{ Image: "foo.com/foo/foo", @@ -93,8 +146,6 @@ var _ = Describe("Container Conformance Test", func() { Phase: api.PodPending, NodeName: *nodeName, } - }) - It("it should not start successfully [Conformance]", func() { err := invalidImageCase.Create() Expect(err).NotTo(HaveOccurred()) diff --git a/test/e2e_node/image.go b/test/e2e_node/image.go new file mode 100644 index 0000000000..449f154d3d --- /dev/null +++ b/test/e2e_node/image.go @@ -0,0 +1,104 @@ +/* +Copyright 2016 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 ( + "fmt" + "time" + + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/dockertools" + kubepod "k8s.io/kubernetes/pkg/kubelet/pod" +) + +type ConformanceImage struct { + Image kubecontainer.ImageSpec + Runtime kubecontainer.Runtime +} + +func NewConformanceImage(containerRuntime string, image string) (ci ConformanceImage, err error) { + ci.Image = kubecontainer.ImageSpec{Image: image} + if containerRuntime == "docker" { + ci.Runtime = dockerRuntime() + return ci, nil + } + return ci, fmt.Errorf("Unsupported runtime : %s.", containerRuntime) +} + +//TODO: do not expose kubelet implementation details after we refactor the runtime API. +func dockerRuntime() kubecontainer.Runtime { + dockerClient := dockertools.ConnectToDockerOrDie("") + pm := kubepod.NewBasicPodManager(nil) + dm := dockertools.NewDockerManager( + dockerClient, + nil, nil, nil, pm, nil, + "", 0, 0, "", + nil, nil, nil, nil, nil, nil, nil, + false, nil, true, false, false, + ) + + return dm +} + +func (ci *ConformanceImage) Pull() error { + err := ci.Runtime.PullImage(ci.Image, nil) + if err != nil { + return err + } + + if present, err := ci.Runtime.IsImagePresent(ci.Image); err != nil { + return err + } else if !present { + return fmt.Errorf("Failed to detect the pulled image :%s.", ci.Image.Image) + } + + return nil +} + +func (ci *ConformanceImage) List() ([]string, error) { + if images, err := ci.Runtime.ListImages(); err != nil { + return nil, err + } else { + var tags []string + for _, image := range images { + tags = append(tags, image.RepoTags...) + } + return tags, nil + } +} + +func (ci *ConformanceImage) Remove() error { + ci.Runtime.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Second * 30, 1, 0}) + + var err error + for start := time.Now(); time.Since(start) < time.Minute*2; time.Sleep(time.Second * 30) { + if err = ci.Runtime.RemoveImage(ci.Image); err == nil { + break + } + } + if err != nil { + return err + } + + if present, err := ci.Runtime.IsImagePresent(ci.Image); err != nil { + return err + } else if present { + return fmt.Errorf("Failed to remove the pulled image %s.", ci.Image.Image) + } + + return nil +}