Change:
According to this APIsnoop query, there are still some remaining ReplicationController endpoints which are untested. Create a ReplicationController with a static label Patch the ReplicationController with a new Label and updated data Patch the ReplicationController's status Patch/Scale the ReplicationController's Replica count to 2 Replicas Get the ReplicationController Replace the ReplicationController's Status List all ReplicationControllers in all Namespaces find the ReplicationControllers(1) ensure that the ReplicationController is found and is patched Delete Namespaced ReplicationControllers(1) via a Collection with a LabelSelector Discover useragents: See all endpoints hit from this test Display test coverage change If a test with these calls gets merged, test coverage will go up by 7 points This test is also created with the goal of conformance promotion. /sig testing /sig architecture /area conformance
Deployment replaced ReplicationController a while back. It should be part of conformance. We need to check more than the data-aspect (beyond crud), we need to verify the data-plane. In this case we need to check the pods as well and not just the ReplicationController status. Moved to backlog by conformance subgroup.
PR:
/open /reopen We need this open to track the test promotion and flakyness. We can't write a promotion PR until the test has no flakes for 2 weeks.
Reopened this issue. <detailsIn response to : /open /reopen We can't write a promotion PR until the test has no flakes for 2 weeks. Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/retitle Promote CoreV1ReplicationController lifecycle mock test - +7 coverage Need to verify two weeks on non-flakeyness.
/retitle Write CoreV1ReplicationController lifecycle test+promote - +7 coverage
Closing in favour of /close
Closing this issue. <detailsIn response to : Closing in favour of /close Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details

Discussion:
"//pkg/master/ports:go_default_library", "//pkg/scheduler/nodeinfo:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", <ins> "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", </ins> "//staging/src/k8s.io/api/batch/v1:go_default_library", "//staging/src/k8s.io/api/batch/v1beta1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",

import ( "context" <ins> "encoding/json" </ins> "fmt" "time" <ins> autoscalingv1 "k8s.io/api/autoscaling/v1" </ins> v1 "k8s.io/api/core/v1" apierrors "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" <ins> "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" </ins> "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" <ins> "k8s.io/client-go/dynamic" </ins> clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/pkg/controller/replication" "k8s.io/kubernetes/test/e2e/framework"

var _ = SIGDescribe("ReplicationController", func() { f := framework.NewDefaultFramework("replication-controller") <ins> var ns string var dc dynamic.Interface ginkgo.BeforeEach(func() { ns = f.Namespace.Name dc = f.DynamicClient }) </ins> /* Release : v1.9 Testname: Replication Controller, run basic image

framework.ConformanceIt("should release no longer matching pods", func() { testRCReleaseControlledNotMatching(f) }) <ins> ginkgo.It("should test the lifecycle of a ReplicationController", func() { testRcName := "rc-test" testRcNamespace := ns testRcInitialReplicaCount := int32(1) testRcMaxReplicaCount := int32(2) rcResource := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "replicationcontrollers"} rcTest := v1.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ Name:   testRcName, Labels: map[string]string{"test-rc-static": "true"}, }, Spec: v1.ReplicationControllerSpec{ Replicas: &testRcInitialReplicaCount, Selector: map[string]string{"test-rc-static": "true"}, Template: &v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Name:   testRcName, Labels: map[string]string{"test-rc-static": "true"}, }, Spec: v1.PodSpec{ Containers: []v1.Container{{ Name:  testRcName, Image: "nginx", }}, }, }, }, } ginkgo.By("creating a ReplicationController") // Create a ReplicationController _, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Create(context.TODO(), &rcTest, metav1.CreateOptions{}) framework.ExpectNoError(err, "Failed to create ReplicationController") // setup a watch for the RC rcWatchTimeoutSeconds := int64(180) rcWatch, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Watch(context.TODO(), metav1.ListOptions{LabelSelector: "test-rc-static=true", TimeoutSeconds: &rcWatchTimeoutSeconds}) framework.ExpectNoError(err, "Failed to setup watch on newly created ReplicationController") rcWatchChan := rcWatch.ResultChan() ginkgo.By("waiting for available Replicas") for event := range rcWatchChan { rc, ok := event.Object.(*v1.ReplicationController) framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch event") if rc.Status.Replicas == testRcInitialReplicaCount && rc.Status.ReadyReplicas == testRcInitialReplicaCount { break } } rcLabelPatchPayload, err := json.Marshal(v1.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{"test-rc": "patched"}, }, }) framework.ExpectNoError(err, "failed to marshal json of replicationcontroller label patch") // Patch the ReplicationController ginkgo.By("patching ReplicationController") _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcLabelPatchPayload), metav1.PatchOptions{}) framework.ExpectNoError(err, "Failed to patch ReplicationController") rcStatusPatchPayload, err := json.Marshal(map[string]interface{}{ "status": map[string]interface{}{ "readyReplicas":     0, "availableReplicas": 0, }, }) framework.ExpectNoError(err, "Failed to marshal JSON of ReplicationController label patch") // Patch the ReplicationController's status ginkgo.By("patching ReplicationController status") rcStatus, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcStatusPatchPayload), metav1.PatchOptions{}, "status") framework.ExpectNoError(err, "Failed to patch ReplicationControllerStatus") framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(0), "ReplicationControllerStatus's readyReplicas does not equal 0") ginkgo.By("fetching ReplicationController status") rcStatusUnstructured, err := dc.Resource(rcResource).Namespace(testRcNamespace).Get(testRcName, metav1.GetOptions{}, "status") framework.ExpectNoError(err, "Failed to fetch ReplicationControllerStatus") rcStatusUjson, err := json.Marshal(rcStatusUnstructured) framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") json.Unmarshal(rcStatusUjson, &rcStatus) framework.ExpectEqual(rcStatus.Status.Replicas, testRcInitialReplicaCount, "ReplicationController ReplicaSet cound does not match initial Replica count") rcScalePatchPayload, err := json.Marshal(autoscalingv1.Scale{ Spec: autoscalingv1.ScaleSpec{ Replicas: testRcMaxReplicaCount, }, }) framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") // Patch the ReplicationController's scale ginkgo.By("patching ReplicationController scale") _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcScalePatchPayload), metav1.PatchOptions{}, "scale") framework.ExpectNoError(err, "Failed to patch ReplicationControllerScale") var rcFromWatch *v1.ReplicationController ginkgo.By("waiting for ReplicationController's scale to be the max amount") foundRcWithMaxScale := false for event := range rcWatchChan { rc, ok := event.Object.(*v1.ReplicationController) framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch event") if rc.ObjectMeta.Name == testRcName && rc.ObjectMeta.Namespace == testRcNamespace && rc.Status.Replicas == testRcMaxReplicaCount && rc.Status.ReadyReplicas == testRcMaxReplicaCount { foundRcWithMaxScale = true rcFromWatch = rc break } } framework.ExpectEqual(foundRcWithMaxScale, true, "failed to locate a ReplicationController with max scale") framework.ExpectEqual(rcFromWatch.Status.Replicas, testRcMaxReplicaCount, "ReplicationController ReplicasSet Scale does not match the expected scale") // Get the ReplicationController ginkgo.By("fetching ReplicationController; ensuring that it's patched") rc, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}) framework.ExpectNoError(err, "failed to fetch ReplicationController") framework.ExpectEqual(rc.ObjectMeta.Labels["test-rc"], "patched", "ReplicationController is missing a label from earlier patch") rcStatusUpdatePayload := rc rcStatusUpdatePayload.Status.AvailableReplicas = 1 rcStatusUpdatePayload.Status.ReadyReplicas = 1 // Replace the ReplicationController's status ginkgo.By("updating ReplicationController status") rcStatus, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).UpdateStatus(context.TODO(), rcStatusUpdatePayload, metav1.UpdateOptions{}) framework.ExpectNoError(err, "failed to update ReplicationControllerStatus") framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(1), "ReplicationControllerStatus readyReplicas does not equal 1") ginkgo.By(fmt.Sprintf("waiting for ReplicationController readyReplicas to be equal to %v", testRcMaxReplicaCount)) for event := range rcWatchChan { rc, ok := event.Object.(*v1.ReplicationController) framework.ExpectEqual(ok, true, "unable to convert type of ReplicationController watch event") if rc.Status.Replicas == testRcMaxReplicaCount && rc.Status.ReadyReplicas == testRcMaxReplicaCount { break } } ginkgo.By("listing all ReplicationControllers") rcs, err := f.ClientSet.CoreV1().ReplicationControllers("").List(context.TODO(), metav1.ListOptions{LabelSelector: "test-rc-static=true"}) framework.ExpectNoError(err, "failed to list ReplicationController") framework.ExpectEqual(len(rcs.Items) > 0, true) ginkgo.By("checking that ReplicationController has expected values") foundRc := false for _, rcItem := range rcs.Items { if rcItem.ObjectMeta.Name == testRcName && rcItem.ObjectMeta.Namespace == testRcNamespace && rcItem.ObjectMeta.Labels["test-rc-static"] == "true" && rcItem.ObjectMeta.Labels["test-rc"] == "patched" && rcItem.Status.Replicas == testRcMaxReplicaCount && rcItem.Status.ReadyReplicas == testRcMaxReplicaCount { foundRc = true } } framework.ExpectEqual(foundRc, true) // Delete ReplicationController ginkgo.By("deleting ReplicationControllers by collection") err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).DeleteCollection(context.TODO(), &metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test-rc-static=true"}) framework.ExpectNoError(err, "Failed to delete ReplicationControllers") ginkgo.By("waiting for ReplicationController to have a DELETED event") for event := range rcWatchChan { if event.Type == "DELETED" { break } } }) </ins> }) func newRC(rsName string, replicas int32, rcPodLabels map[string]string, imageName string, image string, args []string) *v1.ReplicationController {