Commit a4e16319 authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #24329 from liangchenye/refact

Automatic merge from submit-queue refactor conformance test @Random-Liu Rebase the testing code. Signed-off-by: 's avatarliang chenye <liangchenye@huawei.com>
parents 00308f7a aa3bf1fa
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
apierrs "k8s.io/kubernetes/pkg/api/errors"
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
"github.com/onsi/gomega/format" "github.com/onsi/gomega/format"
...@@ -100,5 +101,15 @@ func (cc *ConformanceContainer) Get() (ConformanceContainer, error) { ...@@ -100,5 +101,15 @@ func (cc *ConformanceContainer) Get() (ConformanceContainer, error) {
if containers == nil || len(containers) != 1 { if containers == nil || len(containers) != 1 {
return ConformanceContainer{}, errors.New("Failed to get container") return ConformanceContainer{}, errors.New("Failed to get container")
} }
return ConformanceContainer{containers[0], cc.Client, pod.Status.Phase, cc.NodeName}, nil return ConformanceContainer{containers[0], cc.Client, pod.Status.Phase, pod.Spec.NodeName}, nil
}
func (cc *ConformanceContainer) Present() (bool, error) {
_, err := cc.Client.Pods(api.NamespaceDefault).Get(cc.Container.Name)
if err == nil {
return true, nil
} else if err != nil && apierrs.IsNotFound(err) {
return false, nil
}
return false, err
} }
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"time" "time"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
apierrs "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
...@@ -38,7 +39,8 @@ var _ = Describe("Kubelet Container Manager", func() { ...@@ -38,7 +39,8 @@ var _ = Describe("Kubelet Container Manager", func() {
namespace := "oom-adj" namespace := "oom-adj"
Context("when scheduling a busybox command that always fails in a pod", func() { Context("when scheduling a busybox command that always fails in a pod", func() {
podName := "bin-false" podName := "bin-false"
It("it should return succes", func() {
BeforeEach(func() {
pod := &api.Pod{ pod := &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: podName, Name: podName,
...@@ -58,6 +60,7 @@ var _ = Describe("Kubelet Container Manager", func() { ...@@ -58,6 +60,7 @@ var _ = Describe("Kubelet Container Manager", func() {
}, },
}, },
} }
_, err := cl.Pods(namespace).Create(pod) _, err := cl.Pods(namespace).Create(pod)
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err)) Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
}) })
...@@ -86,6 +89,18 @@ var _ = Describe("Kubelet Container Manager", func() { ...@@ -86,6 +89,18 @@ var _ = Describe("Kubelet Container Manager", func() {
err := cl.Pods(namespace).Delete(podName, &api.DeleteOptions{}) err := cl.Pods(namespace).Delete(podName, &api.DeleteOptions{})
Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err)) Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err))
}) })
AfterEach(func() {
cl.Pods(namespace).Delete(podName, &api.DeleteOptions{})
Eventually(func() bool {
_, err := cl.Pods(namespace).Get(podName)
if err != nil && apierrs.IsNotFound(err) {
return true
}
return false
}, time.Minute, time.Second*4).Should(BeTrue())
})
}) })
}) })
......
...@@ -76,3 +76,7 @@ func (ci *ConformanceImage) List() ([]string, error) { ...@@ -76,3 +76,7 @@ func (ci *ConformanceImage) List() ([]string, error) {
func (ci *ConformanceImage) Remove() error { func (ci *ConformanceImage) Remove() error {
return ci.Runtime.RemoveImage(ci.Image) return ci.Runtime.RemoveImage(ci.Image)
} }
func (ci *ConformanceImage) GetTag() string {
return ci.Image.Image
}
...@@ -19,7 +19,6 @@ package e2e_node ...@@ -19,7 +19,6 @@ package e2e_node
import ( import (
"time" "time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
...@@ -28,8 +27,6 @@ import ( ...@@ -28,8 +27,6 @@ import (
) )
const ( const (
retryTimeout = time.Minute * 4
pollInterval = time.Second * 5
imageRetryTimeout = time.Minute * 2 imageRetryTimeout = time.Minute * 2
imagePullInterval = time.Second * 15 imagePullInterval = time.Second * 15
) )
...@@ -42,143 +39,100 @@ var _ = Describe("Container Conformance Test", func() { ...@@ -42,143 +39,100 @@ var _ = Describe("Container Conformance Test", func() {
cl = client.NewOrDie(&restclient.Config{Host: *apiServerAddress}) cl = client.NewOrDie(&restclient.Config{Host: *apiServerAddress})
}) })
Describe("container conformance blackbox test", func() { Describe("image conformance blackbox test", func() {
Context("when testing images that exist", func() { Context("when testing images that exist", func() {
var conformImages []ConformanceImage var conformImages []ConformanceImage
conformImageTags := []string{ BeforeEach(func() {
"gcr.io/google_containers/node-conformance:v1", existImageTags := []string{
"gcr.io/google_containers/node-conformance:v2", "gcr.io/google_containers/busybox:1.24",
"gcr.io/google_containers/node-conformance:v3", "gcr.io/google_containers/mounttest:0.2",
"gcr.io/google_containers/node-conformance:v4",
}
// TODO(random-liu): Each It should be independent, we should not let them depend on
// each other.
It("should pull successfully [Conformance]", func() {
for _, imageTag := range conformImageTags {
image, _ := NewConformanceImage("docker", imageTag)
conformImages = append(conformImages, image)
} }
for _, image := range conformImages { for _, existImageTag := range existImageTags {
conformImage, _ := NewConformanceImage("docker", existImageTag)
// Pulling images from gcr.io is flaky, so retry failures // Pulling images from gcr.io is flaky, so retry failures
Eventually(func() error { Eventually(func() error {
return image.Pull() return conformImage.Pull()
}, imageRetryTimeout, imagePullInterval).ShouldNot(HaveOccurred()) }, imageRetryTimeout, imagePullInterval).ShouldNot(HaveOccurred())
present, err := image.Present() conformImages = append(conformImages, conformImage)
}
})
It("It should present successfully [Conformance]", func() {
for _, conformImage := range conformImages {
present, err := conformImage.Present()
Expect(err).ShouldNot(HaveOccurred()) Expect(err).ShouldNot(HaveOccurred())
Expect(present).Should(BeTrue()) Expect(present).To(BeTrue())
} }
}) })
It("should list pulled images [Conformance]", func() { It("should list pulled images [Conformance]", func() {
image, _ := NewConformanceImage("docker", "") image, _ := NewConformanceImage("docker", "")
tags, _ := image.List() tags, err := image.List()
for _, tag := range conformImageTags { Expect(err).ShouldNot(HaveOccurred())
Expect(tags).To(ContainElement(tag)) for _, conformImage := range conformImages {
Expect(tags).To(ContainElement(conformImage.GetTag()))
} }
}) })
It("should remove successfully [Conformance]", func() {
for _, image := range conformImages { AfterEach(func() {
err := image.Remove() for _, conformImage := range conformImages {
Expect(err).NotTo(HaveOccurred()) conformImage.Remove()
present, err := image.Present()
Expect(err).NotTo(HaveOccurred())
Expect(present).To(BeFalse())
} }
conformImages = []ConformanceImage{}
}) })
}) })
Context("when testing image that does not exist", func() { Context("when testing image that does not exist", func() {
It("should not pull successfully [Conformance]", func() { var conformImages []ConformanceImage
BeforeEach(func() {
invalidImageTags := []string{ invalidImageTags := []string{
// nonexistent image registry // nonexistent image registry
"foo.com/foo/foo", "foo.com/foo/fooimage",
// nonexistent image // nonexistent image
"gcr.io/google_containers/not_exist", "gcr.io/google_containers/not_exist",
// TODO(random-liu): Add test for image pulling credential // TODO(random-liu): Add test for image pulling credential
} }
for _, invalidImageTag := range invalidImageTags { for _, invalidImageTag := range invalidImageTags {
invalidImage, _ := NewConformanceImage("docker", invalidImageTag) conformImage, _ := NewConformanceImage("docker", invalidImageTag)
By("start pulling image") // Pulling images from gcr.io is flaky, so retry to make sure failure is not caused by flaky.
err := invalidImage.Pull() Consistently(func() error {
Expect(err).Should(HaveOccurred()) return conformImage.Pull()
}, imageRetryTimeout, imagePullInterval).Should(HaveOccurred())
conformImages = append(conformImages, conformImage)
}
})
By("check image present") It("it should not present images [Conformance]", func() {
present, err := invalidImage.Present() for _, conformImage := range conformImages {
present, err := conformImage.Present()
Expect(err).ShouldNot(HaveOccurred()) Expect(err).ShouldNot(HaveOccurred())
Expect(present).To(BeFalse()) Expect(present).To(BeFalse())
By("listing image")
tags, err := invalidImage.List()
Expect(err).ShouldNot(HaveOccurred())
Expect(tags).NotTo(ContainElement(invalidImage))
By("removing image")
err = invalidImage.Remove()
Expect(err).Should(HaveOccurred())
} }
}) })
})
Context("when running a container that terminates", func() { It("it should not list pulled images [Conformance]", func() {
var terminateCase ConformanceContainer image, _ := NewConformanceImage("docker", "")
It("should run successfully to completion [Conformance]", func() { tags, err := image.List()
terminateCase = ConformanceContainer{ Expect(err).ShouldNot(HaveOccurred())
Container: api.Container{ for _, conformImage := range conformImages {
Image: "gcr.io/google_containers/busybox", Expect(tags).NotTo(ContainElement(conformImage.GetTag()))
Name: "busybox",
Command: []string{"sh", "-c", "env"},
ImagePullPolicy: api.PullIfNotPresent,
},
Client: cl,
Phase: api.PodSucceeded,
NodeName: *nodeName,
} }
err := terminateCase.Create()
Expect(err).NotTo(HaveOccurred())
// TODO: Check that the container enters running state by sleeping in the container #23309
Eventually(func() (api.PodPhase, error) {
pod, err := terminateCase.Get()
return pod.Phase, err
}, retryTimeout, pollInterval).Should(Equal(terminateCase.Phase))
}) })
It("should report its phase as 'succeeded' [Conformance]", func() {
ccontainer, err := terminateCase.Get() It("it should not remove non-exist images [Conformance]", func() {
Expect(err).NotTo(HaveOccurred()) for _, conformImage := range conformImages {
Expect(ccontainer).Should(CContainerEqual(terminateCase)) err := conformImage.Remove()
}) Expect(err).Should(HaveOccurred())
It("should be possible to delete [Conformance]", func() {
err := terminateCase.Delete()
Expect(err).NotTo(HaveOccurred())
})
})
Context("when running a container with invalid image", func() {
var invalidImageCase ConformanceContainer
It("should not start successfully [Conformance]", func() {
invalidImageCase = ConformanceContainer{
Container: api.Container{
Image: "foo.com/foo/foo",
Name: "foo",
Command: []string{"foo", "'Should not work'"},
ImagePullPolicy: api.PullIfNotPresent,
},
Client: cl,
Phase: api.PodPending,
NodeName: *nodeName,
} }
err := invalidImageCase.Create()
Expect(err).NotTo(HaveOccurred())
Eventually(func() (api.PodPhase, error) {
pod, err := invalidImageCase.Get()
return pod.Phase, err
}, retryTimeout, pollInterval).Should(Equal(invalidImageCase.Phase))
})
It("should report its phase as 'pending' [Conformance]", func() {
ccontainer, err := invalidImageCase.Get()
Expect(err).NotTo(HaveOccurred())
Expect(ccontainer).Should(CContainerEqual(invalidImageCase))
}) })
It("should be possible to delete [Conformance]", func() {
err := invalidImageCase.Delete() AfterEach(func() {
Expect(err).NotTo(HaveOccurred()) for _, conformImage := range conformImages {
conformImage.Remove()
}
conformImages = []ConformanceImage{}
}) })
}) })
}) })
}) })
/*
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 (
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/restclient"
client "k8s.io/kubernetes/pkg/client/unversioned"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
const (
retryTimeout = time.Minute * 4
pollInterval = time.Second * 5
)
var _ = Describe("Container Runtime Conformance Test", func() {
var cl *client.Client
BeforeEach(func() {
// Setup the apiserver client
cl = client.NewOrDie(&restclient.Config{Host: *apiServerAddress})
})
Describe("container conformance blackbox test", func() {
Context("when running a container that terminates", func() {
var containerCase ConformanceContainer
BeforeEach(func() {
containerCase = ConformanceContainer{
Container: api.Container{
Image: "gcr.io/google_containers/busybox",
Name: "busybox",
Command: []string{"sh", "-c", "env"},
ImagePullPolicy: api.PullIfNotPresent,
},
Client: cl,
Phase: api.PodSucceeded,
NodeName: *nodeName,
}
err := containerCase.Create()
Expect(err).NotTo(HaveOccurred())
})
It("it should report its phase as 'succeeded' and get a same container [Conformance]", func() {
var container ConformanceContainer
var err error
Eventually(func() api.PodPhase {
container, err = containerCase.Get()
return container.Phase
}, retryTimeout, pollInterval).Should(Equal(api.PodSucceeded))
Expect(err).NotTo(HaveOccurred())
Expect(container).Should(CContainerEqual(containerCase))
})
It("it should be possible to delete [Conformance]", func() {
err := containerCase.Delete()
Expect(err).NotTo(HaveOccurred())
Eventually(func() bool {
isPresent, err := containerCase.Present()
return err == nil && !isPresent
}, retryTimeout, pollInterval).Should(BeTrue())
})
AfterEach(func() {
containerCase.Delete()
Eventually(func() bool {
isPresent, err := containerCase.Present()
return err == nil && !isPresent
}, retryTimeout, pollInterval).Should(BeTrue())
})
})
Context("when running a container with invalid image", func() {
var containerCase ConformanceContainer
BeforeEach(func() {
containerCase = ConformanceContainer{
Container: api.Container{
Image: "foo.com/foo/foo",
Name: "foo",
Command: []string{"foo", "'Should not work'"},
ImagePullPolicy: api.PullIfNotPresent,
},
Client: cl,
Phase: api.PodPending,
NodeName: *nodeName,
}
err := containerCase.Create()
Expect(err).NotTo(HaveOccurred())
})
It("it should report its phase as 'pending' and get a same container [Conformance]", func() {
var container ConformanceContainer
var err error
Consistently(func() api.PodPhase {
container, err = containerCase.Get()
return container.Phase
}, retryTimeout, pollInterval).Should(Equal(api.PodPending))
Expect(err).NotTo(HaveOccurred())
Expect(container).Should(CContainerEqual(containerCase))
})
It("it should be possible to delete [Conformance]", func() {
err := containerCase.Delete()
Expect(err).NotTo(HaveOccurred())
Eventually(func() bool {
isPresent, err := containerCase.Present()
return err == nil && !isPresent
}, retryTimeout, pollInterval).Should(BeTrue())
})
AfterEach(func() {
containerCase.Delete()
Eventually(func() bool {
isPresent, err := containerCase.Present()
return err == nil && !isPresent
}, retryTimeout, pollInterval).Should(BeTrue())
})
})
})
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment