Change:
The merge queue is green with RBAC enabled, and the replicaset controller was missing permission to patch pods until fixed in Pod adoption and release depend on patching pods, which means that there are no merge-queue-blocking tests that test these features. Given that they are complex and rarely tested manually, we need tests that run as part of the merge queue to ensure they function correctly.
I'd like to work on this, where should the tests be ? I see that there are some patch-related tests for the replicaset controller in , and, according to http://submit-, the integration tests are run as part of the merge queue, is that correct? Thanks!
I think we'd want an e2e test that drives behavior externally on a normal cluster (by creating a replicaset, waiting to observe expected pods, modifies replicaset, waits to observe expected results, etc) . many of the integration tests tend to start up fake servers that don't share much in common with real deployments.
Ok thanks, on it.
cc:

Discussion:
It("should surface a failure condition on a common issue like exceeded quota", func() { rcConditionCheck(f) }) <ins> It("should adopt matching pods on creation", func() { testRCAdoptMatchingOrphans(f) }) It("should release no longer matching pods", func() { testRCReleaseControlledNotMatching(f) }) </ins> }) func newRC(rsName string, replicas int32, rcPodLabels map[string]string, imageName string, image string) *v1.ReplicationController {

} Expect(err).NotTo(HaveOccurred()) } <ins> 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()) } </ins>

"fmt" "time" <ins> "k8s.io/apimachinery/pkg/api/errors" </ins> "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" <ins> "k8s.io/apimachinery/pkg/types" </ins> "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/kubernetes/pkg/api/v1"

It("should surface a failure condition on a common issue like exceeded quota", func() { rsConditionCheck(f) }) <ins> It("should adopt matching pods on creation", func() { testRSAdoptMatchingOrphans(f) }) It("should release no longer matching pods", func() { testRSReleaseControlledNotMatching(f) }) </ins> }) // A basic test to check the deployment of an image using a ReplicaSet. The

} Expect(err).NotTo(HaveOccurred()) } <ins> 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()) } </ins>