Merge pull request #41301 from fgimenez/e2e-replicaset-pod-adoption-and-release

Automatic merge from submit-queue (batch tested with PRs 38741, 41301, 43645, 43779, 42337)

replicaset adopt and release e2e tests

**What this PR does / why we need it**: adds e2e tests for replicaset pod adoption and release

**Which issue this PR fixes** fixes #39962

**Special notes for your reviewer**: for adoption pod is created, a replicaset with a selector matching the pod's label is created and then we check for the pod being in the list of pods of the replicaset. For release, a replicaset with two replicas is created, the label of one of them is patched and then we check that that pod is no longer in the list of pods of the replicaset.

For checking the list of pods the `framework.PodsCreated` is used, maybe the name is not very adecuate given that it is used to return the pods belonging to one replicaset, no matter how they were created. Also, the patching is done through `framework.KubectlOrDie`, not sure if this is better that calling the API directly.

cc @liggitt
This commit is contained in:
Kubernetes Submit Queue 2017-03-29 14:53:31 -07:00 committed by GitHub
commit 36644a7329
2 changed files with 184 additions and 0 deletions

View File

@ -20,9 +20,11 @@ import (
"fmt"
"time"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/api/v1"
@ -50,6 +52,14 @@ var _ = framework.KubeDescribe("ReplicationController", func() {
It("should surface a failure condition on a common issue like exceeded quota", func() {
rcConditionCheck(f)
})
It("should adopt matching pods on creation", func() {
testRCAdoptMatchingOrphans(f)
})
It("should release no longer matching pods", func() {
testRCReleaseControlledNotMatching(f)
})
})
func newRC(rsName string, replicas int32, rcPodLabels map[string]string, imageName string, image string) *v1.ReplicationController {
@ -235,3 +245,85 @@ func rcConditionCheck(f *framework.Framework) {
}
Expect(err).NotTo(HaveOccurred())
}
func testRCAdoptMatchingOrphans(f *framework.Framework) {
name := "pod-adoption"
By(fmt.Sprintf("Given a Pod with a 'name' label %s is created", name))
p := f.PodClient().CreateSync(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
"name": name,
},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: name,
Image: nginxImageName,
},
},
},
})
By("When a replication controller with a matching selector is created")
replicas := int32(1)
rcSt := newRC(name, replicas, map[string]string{"name": name}, name, nginxImageName)
rcSt.Spec.Selector = map[string]string{"name": name}
rc, err := f.ClientSet.Core().ReplicationControllers(f.Namespace.Name).Create(rcSt)
Expect(err).NotTo(HaveOccurred())
By("Then the orphan pod is adopted")
err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
p2, err := f.ClientSet.Core().Pods(f.Namespace.Name).Get(p.Name, metav1.GetOptions{})
// The Pod p should either be adopted or deleted by the RC
if errors.IsNotFound(err) {
return true, nil
}
Expect(err).NotTo(HaveOccurred())
for _, owner := range p2.OwnerReferences {
if *owner.Controller && owner.UID == rc.UID {
// pod adopted
return true, nil
}
}
// pod still not adopted
return false, nil
})
Expect(err).NotTo(HaveOccurred())
}
func testRCReleaseControlledNotMatching(f *framework.Framework) {
name := "pod-release"
By("Given a ReplicationController is created")
replicas := int32(1)
rcSt := newRC(name, replicas, map[string]string{"name": name}, name, nginxImageName)
rcSt.Spec.Selector = map[string]string{"name": name}
rc, err := f.ClientSet.Core().ReplicationControllers(f.Namespace.Name).Create(rcSt)
Expect(err).NotTo(HaveOccurred())
By("When the matched label of one of its pods change")
pods, err := framework.PodsCreated(f.ClientSet, f.Namespace.Name, rc.Name, replicas)
Expect(err).NotTo(HaveOccurred())
p := pods.Items[0]
podClient := f.ClientSet.Core().Pods(f.Namespace.Name)
patch := []byte("{\"metadata\":{\"labels\":{\"name\":\"not-matching-name\"}}}")
_, err = podClient.Patch(p.Name, types.StrategicMergePatchType, patch)
Expect(err).NotTo(HaveOccurred())
By("Then the pod is released")
err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
p2, err := podClient.Get(p.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())
for _, owner := range p2.OwnerReferences {
if *owner.Controller && owner.UID == rc.UID {
// pod still belonging to the replication controller
return false, nil
}
}
// pod already released
return true, nil
})
Expect(err).NotTo(HaveOccurred())
}

View File

@ -20,9 +20,11 @@ import (
"fmt"
"time"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/api/v1"
@ -90,6 +92,14 @@ var _ = framework.KubeDescribe("ReplicaSet", func() {
It("should surface a failure condition on a common issue like exceeded quota", func() {
rsConditionCheck(f)
})
It("should adopt matching pods on creation", func() {
testRSAdoptMatchingOrphans(f)
})
It("should release no longer matching pods", func() {
testRSReleaseControlledNotMatching(f)
})
})
// A basic test to check the deployment of an image using a ReplicaSet. The
@ -249,3 +259,85 @@ func rsConditionCheck(f *framework.Framework) {
}
Expect(err).NotTo(HaveOccurred())
}
func testRSAdoptMatchingOrphans(f *framework.Framework) {
name := "pod-adoption"
By(fmt.Sprintf("Given a Pod with a 'name' label %s is created", name))
p := f.PodClient().CreateSync(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
"name": name,
},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: name,
Image: nginxImageName,
},
},
},
})
By("When a replicaset with a matching selector is created")
replicas := int32(1)
rsSt := newRS(name, replicas, map[string]string{"name": name}, name, nginxImageName)
rsSt.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{"name": name}}
rs, err := f.ClientSet.Extensions().ReplicaSets(f.Namespace.Name).Create(rsSt)
Expect(err).NotTo(HaveOccurred())
By("Then the orphan pod is adopted")
err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
p2, err := f.ClientSet.Core().Pods(f.Namespace.Name).Get(p.Name, metav1.GetOptions{})
// The Pod p should either be adopted or deleted by the ReplicaSet
if errors.IsNotFound(err) {
return true, nil
}
Expect(err).NotTo(HaveOccurred())
for _, owner := range p2.OwnerReferences {
if *owner.Controller && owner.UID == rs.UID {
// pod adopted
return true, nil
}
}
// pod still not adopted
return false, nil
})
Expect(err).NotTo(HaveOccurred())
}
func testRSReleaseControlledNotMatching(f *framework.Framework) {
name := "pod-release"
By("Given a ReplicaSet is created")
replicas := int32(1)
rsSt := newRS(name, replicas, map[string]string{"name": name}, name, nginxImageName)
rsSt.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{"name": name}}
rs, err := f.ClientSet.Extensions().ReplicaSets(f.Namespace.Name).Create(rsSt)
Expect(err).NotTo(HaveOccurred())
By("When the matched label of one of its pods change")
pods, err := framework.PodsCreated(f.ClientSet, f.Namespace.Name, rs.Name, replicas)
Expect(err).NotTo(HaveOccurred())
p := pods.Items[0]
podClient := f.ClientSet.Core().Pods(f.Namespace.Name)
patch := []byte("{\"metadata\":{\"labels\":{\"name\":\"not-matching-name\"}}}")
_, err = podClient.Patch(p.Name, types.StrategicMergePatchType, patch)
Expect(err).NotTo(HaveOccurred())
By("Then the pod is released")
err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
p2, err := podClient.Get(p.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())
for _, owner := range p2.OwnerReferences {
if *owner.Controller && owner.UID == rs.UID {
// pod still belonging to the replicaset
return false, nil
}
}
// pod already released
return true, nil
})
Expect(err).NotTo(HaveOccurred())
}