// This test simulates the case where an object is created with an owner that // doesn't exist. It verifies the GC will delete such an object. func TestCreateWithNonExistentOwner(t *testing.T) { s, gc, clientSet := setup(t) defer s.Close() ns := framework.CreateTestingNamespace("gc-non-existing-owner", s, t) defer framework.DeleteTestingNamespace(ns, s, t) podClient := clientSet.Core().Pods(ns.Name) pod := newPod(garbageCollectedPodName, ns.Name, []metav1.OwnerReference{{UID: "doesn't matter", Name: toBeDeletedRCName}}) _, err := podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) } // set up watch pods, err := podClient.List(v1.ListOptions{}) if err != nil { t.Fatalf("Failed to list pods: %v", err) } if len(pods.Items) != 1 { t.Fatalf("Expect only 1 pod") } stopCh := make(chan struct{}) go gc.Run(5, stopCh) defer close(stopCh) // wait for the garbage collector to delete the pod if err := integration.WaitForPodToDisappear(podClient, garbageCollectedPodName, 5*time.Second, 30*time.Second); err != nil { t.Fatalf("expect pod %s to be garbage collected, got err= %v", garbageCollectedPodName, err) } }
// This test simulates the cascading deletion. func TestCascadingDeletion(t *testing.T) { glog.V(6).Infof("TestCascadingDeletion starts") defer glog.V(6).Infof("TestCascadingDeletion ends") s, gc, clientSet := setup(t) defer s.Close() ns := framework.CreateTestingNamespace("gc-cascading-deletion", s, t) defer framework.DeleteTestingNamespace(ns, s, t) rcClient := clientSet.Core().ReplicationControllers(ns.Name) podClient := clientSet.Core().Pods(ns.Name) toBeDeletedRC, err := rcClient.Create(newOwnerRC(toBeDeletedRCName, ns.Name)) if err != nil { t.Fatalf("Failed to create replication controller: %v", err) } remainingRC, err := rcClient.Create(newOwnerRC(remainingRCName, ns.Name)) if err != nil { t.Fatalf("Failed to create replication controller: %v", err) } rcs, err := rcClient.List(v1.ListOptions{}) if err != nil { t.Fatalf("Failed to list replication controllers: %v", err) } if len(rcs.Items) != 2 { t.Fatalf("Expect only 2 replication controller") } // this pod should be cascadingly deleted. pod := newPod(garbageCollectedPodName, ns.Name, []metav1.OwnerReference{{UID: toBeDeletedRC.ObjectMeta.UID, Name: toBeDeletedRCName}}) _, err = podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) } // this pod shouldn't be cascadingly deleted, because it has a valid reference. pod = newPod(oneValidOwnerPodName, ns.Name, []metav1.OwnerReference{ {UID: toBeDeletedRC.ObjectMeta.UID, Name: toBeDeletedRCName}, {UID: remainingRC.ObjectMeta.UID, Name: remainingRCName}, }) _, err = podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) } // this pod shouldn't be cascadingly deleted, because it doesn't have an owner. pod = newPod(independentPodName, ns.Name, []metav1.OwnerReference{}) _, err = podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) } // set up watch pods, err := podClient.List(v1.ListOptions{}) if err != nil { t.Fatalf("Failed to list pods: %v", err) } if len(pods.Items) != 3 { t.Fatalf("Expect only 3 pods") } stopCh := make(chan struct{}) go gc.Run(5, stopCh) defer close(stopCh) // delete one of the replication controller if err := rcClient.Delete(toBeDeletedRCName, getNonOrphanOptions()); err != nil { t.Fatalf("failed to delete replication controller: %v", err) } // sometimes the deletion of the RC takes long time to be observed by // the gc, so wait for the garbage collector to observe the deletion of // the toBeDeletedRC if err := wait.Poll(10*time.Second, 60*time.Second, func() (bool, error) { return !gc.GraphHasUID([]types.UID{toBeDeletedRC.ObjectMeta.UID}), nil }); err != nil { t.Fatal(err) } if err := integration.WaitForPodToDisappear(podClient, garbageCollectedPodName, 5*time.Second, 30*time.Second); err != nil { t.Fatalf("expect pod %s to be garbage collected, got err= %v", garbageCollectedPodName, err) } // checks the garbage collect doesn't delete pods it shouldn't delete. if _, err := podClient.Get(independentPodName, metav1.GetOptions{}); err != nil { t.Fatal(err) } if _, err := podClient.Get(oneValidOwnerPodName, metav1.GetOptions{}); err != nil { t.Fatal(err) } }