mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 03:03:59 +00:00
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:
commit
36644a7329
@ -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())
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user