Updating federation e2e tests to verify cascading deletion

pull/6/head
nikhiljindal 2016-11-09 17:50:25 -08:00
parent d51e27fe96
commit 14246a9494
6 changed files with 450 additions and 80 deletions

View File

@ -22,6 +22,7 @@ import (
"os" "os"
"reflect" "reflect"
"strconv" "strconv"
"strings"
"time" "time"
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
@ -53,13 +54,8 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
Describe("Federated Ingresses", func() { Describe("Federated Ingresses", func() {
AfterEach(func() { AfterEach(func() {
nsName := f.FederationNamespace.Name nsName := f.FederationNamespace.Name
// Delete registered ingresses. // Delete all ingresses.
ingressList, err := f.FederationClientset_1_5.Extensions().Ingresses(nsName).List(v1.ListOptions{}) deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
Expect(err).NotTo(HaveOccurred())
for _, ingress := range ingressList.Items {
err := f.FederationClientset_1_5.Extensions().Ingresses(nsName).Delete(ingress.Name, &v1.DeleteOptions{})
Expect(err).NotTo(HaveOccurred())
}
}) })
It("should be created and deleted successfully", func() { It("should be created and deleted successfully", func() {
@ -97,26 +93,43 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
}) })
AfterEach(func() { AfterEach(func() {
// Delete all ingresses.
nsName := f.FederationNamespace.Name
deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
unregisterClusters(clusters, f) unregisterClusters(clusters, f)
}) })
It("should create and update matching ingresses in underlying clusters", func() { It("should create and update matching ingresses in underlying clusters", func() {
ingress := createIngressOrFail(f.FederationClientset_1_5, ns) ingress := createIngressOrFail(f.FederationClientset_1_5, ns)
defer func() { // Cleanup
By(fmt.Sprintf("Deleting ingress %q in namespace %q", ingress.Name, ns))
err := f.FederationClientset_1_5.Ingresses(ns).Delete(ingress.Name, &v1.DeleteOptions{})
framework.ExpectNoError(err, "Error deleting ingress %q/%q in federation", ns, ingress.Name)
for clusterName, cluster := range clusters {
err := cluster.Ingresses(ns).Delete(ingress.Name, &v1.DeleteOptions{})
framework.ExpectNoError(err, "Error deleting ingress %q/%q in cluster %q", ns, ingress.Name, clusterName)
}
}()
// wait for ingress shards being created // wait for ingress shards being created
waitForIngressShardsOrFail(ns, ingress, clusters) waitForIngressShardsOrFail(ns, ingress, clusters)
ingress = updateIngressOrFail(f.FederationClientset_1_5, ns) ingress = updateIngressOrFail(f.FederationClientset_1_5, ns)
waitForIngressShardsUpdatedOrFail(ns, ingress, clusters) waitForIngressShardsUpdatedOrFail(ns, ingress, clusters)
}) })
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := false
verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that ingresses were deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := true
verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, nil, nsName)
By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
})
var _ = Describe("Ingress connectivity and DNS", func() { var _ = Describe("Ingress connectivity and DNS", func() {
var ( var (
@ -147,7 +160,7 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
By("No service to delete. Service is nil") By("No service to delete. Service is nil")
} }
if jig.ing != nil { if jig.ing != nil {
deleteIngressOrFail(f.FederationClientset_1_5, ns, jig.ing.Name) deleteIngressOrFail(f.FederationClientset_1_5, ns, jig.ing.Name, nil)
for clusterName, cluster := range clusters { for clusterName, cluster := range clusters {
deleteClusterIngressOrFail(clusterName, cluster.Clientset, ns, jig.ing.Name) deleteClusterIngressOrFail(clusterName, cluster.Clientset, ns, jig.ing.Name)
} }
@ -182,6 +195,13 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
}) })
}) })
// Deletes all Ingresses in the given namespace name.
func deleteAllIngressesOrFail(clientset *fedclientset.Clientset, nsName string) {
orphanDependents := false
err := clientset.Extensions().Ingresses(nsName).DeleteCollection(&v1.DeleteOptions{OrphanDependents: &orphanDependents}, v1.ListOptions{})
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error in deleting ingresses in namespace: %s", nsName))
}
/* /*
equivalent returns true if the two ingress spec are equivalent. equivalent returns true if the two ingress spec are equivalent.
*/ */
@ -189,6 +209,36 @@ func equivalentIngress(federatedIngress, clusterIngress v1beta1.Ingress) bool {
return reflect.DeepEqual(clusterIngress.Spec, federatedIngress.Spec) return reflect.DeepEqual(clusterIngress.Spec, federatedIngress.Spec)
} }
// verifyCascadingDeletionForIngress verifies that ingresses are deleted from
// underlying clusters when orphan dependents is false and they are not deleted
// when orphan dependents is true.
func verifyCascadingDeletionForIngress(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
ingress := createIngressOrFail(clientset, nsName)
ingressName := ingress.Name
// Check subclusters if the ingress was created there.
By(fmt.Sprintf("Waiting for ingress %s to be created in all underlying clusters", ingressName))
waitForIngressShardsOrFail(nsName, ingress, clusters)
By(fmt.Sprintf("Deleting ingress %s", ingressName))
deleteIngressOrFail(clientset, nsName, ingressName, orphanDependents)
By(fmt.Sprintf("Verifying ingresses %s in underlying clusters", ingressName))
errMessages := []string{}
// ingress should be present in underlying clusters unless orphanDependents is false.
shouldExist := orphanDependents == nil || *orphanDependents == true
for clusterName, clusterClientset := range clusters {
_, err := clusterClientset.Extensions().Ingresses(nsName).Get(ingressName)
if shouldExist && errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for ingress %s in cluster %s, expected ingress to exist", ingressName, clusterName))
} else if !shouldExist && !errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for ingress %s in cluster %s, got error: %v", ingressName, clusterName, err))
}
}
if len(errMessages) != 0 {
framework.Failf("%s", strings.Join(errMessages, "; "))
}
}
/* /*
waitForIngressOrFail waits until a ingress is either present or absent in the cluster specified by clientset. waitForIngressOrFail waits until a ingress is either present or absent in the cluster specified by clientset.
If the condition is not met within timout, it fails the calling test. If the condition is not met within timout, it fails the calling test.
@ -268,12 +318,23 @@ func waitForIngressShardsGoneOrFail(namespace string, ingress *v1beta1.Ingress,
} }
} }
func deleteIngressOrFail(clientset *fedclientset.Clientset, namespace string, ingressName string) { func deleteIngressOrFail(clientset *fedclientset.Clientset, namespace string, ingressName string, orphanDependents *bool) {
if clientset == nil || len(namespace) == 0 || len(ingressName) == 0 { if clientset == nil || len(namespace) == 0 || len(ingressName) == 0 {
Fail(fmt.Sprintf("Internal error: invalid parameters passed to deleteIngressOrFail: clientset: %v, namespace: %v, ingress: %v", clientset, namespace, ingressName)) Fail(fmt.Sprintf("Internal error: invalid parameters passed to deleteIngressOrFail: clientset: %v, namespace: %v, ingress: %v", clientset, namespace, ingressName))
} }
err := clientset.Ingresses(namespace).Delete(ingressName, v1.NewDeleteOptions(0)) err := clientset.Ingresses(namespace).Delete(ingressName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
framework.ExpectNoError(err, "Error deleting ingress %q from namespace %q", ingressName, namespace) framework.ExpectNoError(err, "Error deleting ingress %q from namespace %q", ingressName, namespace)
// Wait for the ingress to be deleted.
err = wait.Poll(framework.Poll, wait.ForeverTestTimeout, func() (bool, error) {
_, err := clientset.Extensions().Ingresses(namespace).Get(ingressName)
if err != nil && errors.IsNotFound(err) {
return true, nil
}
return false, err
})
if err != nil {
framework.Failf("Error in deleting ingress %s: %v", ingressName, err)
}
} }
// TODO: quinton: This is largely a cut 'n paste of the above. Yuck! Refactor as soon as we have a common interface implmented by both fedclientset.Clientset and kubeclientset.Clientset // TODO: quinton: This is largely a cut 'n paste of the above. Yuck! Refactor as soon as we have a common interface implmented by both fedclientset.Clientset and kubeclientset.Clientset

View File

@ -59,11 +59,11 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
AfterEach(func() { AfterEach(func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
deleteAllTestNamespaces(false, deleteAllTestNamespaces(nil,
f.FederationClientset_1_5.Core().Namespaces().List, f.FederationClientset_1_5.Core().Namespaces().List,
f.FederationClientset_1_5.Core().Namespaces().Delete) f.FederationClientset_1_5.Core().Namespaces().Delete)
for _, cluster := range clusters { for _, cluster := range clusters {
deleteAllTestNamespaces(false, deleteAllTestNamespaces(nil,
cluster.Core().Namespaces().List, cluster.Core().Namespaces().List,
cluster.Core().Namespaces().Delete) cluster.Core().Namespaces().Delete)
} }
@ -76,22 +76,30 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
nsName := createNamespace(f.FederationClientset_1_5.Core().Namespaces()) nsName := createNamespace(f.FederationClientset_1_5.Core().Namespaces())
By(fmt.Sprintf("Deleting namespace %s", nsName)) By(fmt.Sprintf("Deleting namespace %s", nsName))
deleteAllTestNamespaces(false, deleteAllTestNamespaces(nil,
f.FederationClientset_1_5.Core().Namespaces().List, f.FederationClientset_1_5.Core().Namespaces().List,
f.FederationClientset_1_5.Core().Namespaces().Delete) f.FederationClientset_1_5.Core().Namespaces().Delete)
By(fmt.Sprintf("Verified that deletion succeeded")) By(fmt.Sprintf("Verified that deletion succeeded"))
}) })
It("should be deleted from underlying clusters when OrphanDependents is false", func() { It("should be deleted from underlying clusters when OrphanDependents is false", func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
orphanDependents := false
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, false) verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, &orphanDependents)
By(fmt.Sprintf("Verified that namespaces were deleted from underlying clusters")) By(fmt.Sprintf("Verified that namespaces were deleted from underlying clusters"))
}) })
It("should not be deleted from underlying clusters when OrphanDependents is true", func() { It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
orphanDependents := true
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, &orphanDependents)
By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
})
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, true) It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
framework.SkipUnlessFederated(f.ClientSet)
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, nil)
By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters")) By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
}) })
@ -119,7 +127,7 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
} }
By(fmt.Sprintf("Deleting namespace %s", nsName)) By(fmt.Sprintf("Deleting namespace %s", nsName))
deleteAllTestNamespaces(false, deleteAllTestNamespaces(nil,
f.FederationClientset_1_5.Core().Namespaces().List, f.FederationClientset_1_5.Core().Namespaces().List,
f.FederationClientset_1_5.Core().Namespaces().Delete) f.FederationClientset_1_5.Core().Namespaces().Delete)
@ -133,10 +141,10 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
}) })
}) })
// Verifies that namespaces are deleted from underlying clusters when orphan dependents is false // verifyNsCascadingDeletion verifies that namespaces are deleted from
// and they are not deleted when orphan dependents is true. // underlying clusters when orphan dependents is false and they are not
func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface, // deleted when orphan dependents is true.
clusters map[string]*cluster, orphanDependents bool) { func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface, clusters map[string]*cluster, orphanDependents *bool) {
nsName := createNamespace(nsClient) nsName := createNamespace(nsClient)
// Check subclusters if the namespace was created there. // Check subclusters if the namespace was created there.
By(fmt.Sprintf("Waiting for namespace %s to be created in all underlying clusters", nsName)) By(fmt.Sprintf("Waiting for namespace %s to be created in all underlying clusters", nsName))
@ -159,11 +167,13 @@ func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface,
By(fmt.Sprintf("Verifying namespaces %s in underlying clusters", nsName)) By(fmt.Sprintf("Verifying namespaces %s in underlying clusters", nsName))
errMessages := []string{} errMessages := []string{}
// namespace should be present in underlying clusters unless orphanDependents is false.
shouldExist := orphanDependents == nil || *orphanDependents == true
for clusterName, clusterClientset := range clusters { for clusterName, clusterClientset := range clusters {
_, err := clusterClientset.Core().Namespaces().Get(nsName) _, err := clusterClientset.Core().Namespaces().Get(nsName)
if orphanDependents && errors.IsNotFound(err) { if shouldExist && errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for namespace %s in cluster %s, expected namespace to exist", nsName, clusterName)) errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for namespace %s in cluster %s, expected namespace to exist", nsName, clusterName))
} else if !orphanDependents && (err == nil || !errors.IsNotFound(err)) { } else if !shouldExist && !errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for namespace %s in cluster %s, got error: %v", nsName, clusterName, err)) errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for namespace %s in cluster %s, got error: %v", nsName, clusterName, err))
} }
} }
@ -185,7 +195,7 @@ func createNamespace(nsClient clientset.NamespaceInterface) string {
return ns.Name return ns.Name
} }
func deleteAllTestNamespaces(orphanDependents bool, lister func(api_v1.ListOptions) (*api_v1.NamespaceList, error), deleter func(string, *api_v1.DeleteOptions) error) { func deleteAllTestNamespaces(orphanDependents *bool, lister func(api_v1.ListOptions) (*api_v1.NamespaceList, error), deleter func(string, *api_v1.DeleteOptions) error) {
list, err := lister(api_v1.ListOptions{}) list, err := lister(api_v1.ListOptions{})
if err != nil { if err != nil {
framework.Failf("Failed to get all namespaes: %v", err) framework.Failf("Failed to get all namespaes: %v", err)
@ -194,7 +204,7 @@ func deleteAllTestNamespaces(orphanDependents bool, lister func(api_v1.ListOptio
for _, namespace := range list.Items { for _, namespace := range list.Items {
if strings.HasPrefix(namespace.Name, namespacePrefix) { if strings.HasPrefix(namespace.Name, namespacePrefix) {
By(fmt.Sprintf("Deleting ns: %s, found by listing", namespace.Name)) By(fmt.Sprintf("Deleting ns: %s, found by listing", namespace.Name))
err := deleter(namespace.Name, &api_v1.DeleteOptions{OrphanDependents: &orphanDependents}) err := deleter(namespace.Name, &api_v1.DeleteOptions{OrphanDependents: orphanDependents})
if err != nil { if err != nil {
framework.Failf("Failed to set %s for deletion: %v", namespace.Name, err) framework.Failf("Failed to set %s for deletion: %v", namespace.Name, err)
} }

View File

@ -55,16 +55,17 @@ var _ = framework.KubeDescribe("Federation secrets [Feature:Federation]", func()
AfterEach(func() { AfterEach(func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
// Delete all secrets.
nsName := f.FederationNamespace.Name
deleteAllSecretsOrFail(f.FederationClientset_1_5, nsName)
unregisterClusters(clusters, f) unregisterClusters(clusters, f)
}) })
It("should be created and deleted successfully", func() { It("should be created and deleted successfully", func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name nsName := f.FederationNamespace.Name
secret := createSecretOrFail(f.FederationClientset_1_5, nsName) secret := createSecretOrFail(f.FederationClientset_1_5, nsName)
defer func() { // Cleanup
deleteSecretOrFail(f.FederationClientset_1_5, nsName, secret.Name, true)
}()
// wait for secret shards being created // wait for secret shards being created
waitForSecretShardsOrFail(nsName, secret, clusters) waitForSecretShardsOrFail(nsName, secret, clusters)
secret = updateSecretOrFail(f.FederationClientset_1_5, nsName, secret.Name) secret = updateSecretOrFail(f.FederationClientset_1_5, nsName, secret.Name)
@ -74,23 +75,42 @@ var _ = framework.KubeDescribe("Federation secrets [Feature:Federation]", func()
It("should be deleted from underlying clusters when OrphanDependents is false", func() { It("should be deleted from underlying clusters when OrphanDependents is false", func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name nsName := f.FederationNamespace.Name
verifyCascadingDeletion(f.FederationClientset_1_5, clusters, false, nsName) orphanDependents := false
verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that secrets were deleted from underlying clusters")) By(fmt.Sprintf("Verified that secrets were deleted from underlying clusters"))
}) })
It("should not be deleted from underlying clusters when OrphanDependents is true", func() { It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name nsName := f.FederationNamespace.Name
verifyCascadingDeletion(f.FederationClientset_1_5, clusters, true, nsName) orphanDependents := true
verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, nil, nsName)
By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters")) By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
}) })
}) })
}) })
// Verifies that secrets are deleted from underlying clusters when orphan dependents is false // deleteAllSecretsOrFail deletes all secrets in the given namespace name.
// and they are not deleted when orphan dependents is true. func deleteAllSecretsOrFail(clientset *fedclientset.Clientset, nsName string) {
func verifyCascadingDeletion(clientset *fedclientset.Clientset, SecretList, err := clientset.Core().Secrets(nsName).List(v1.ListOptions{})
clusters map[string]*cluster, orphanDependents bool, nsName string) { Expect(err).NotTo(HaveOccurred())
orphanDependents := false
for _, Secret := range SecretList.Items {
deleteSecretOrFail(clientset, nsName, Secret.Name, &orphanDependents)
}
}
// verifyCascadingDeletionForSecret verifies that secrets are deleted from
// underlying clusters when orphan dependents is false and they are not
// deleted when orphan dependents is true.
func verifyCascadingDeletionForSecret(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
secret := createSecretOrFail(clientset, nsName) secret := createSecretOrFail(clientset, nsName)
secretName := secret.Name secretName := secret.Name
// Check subclusters if the secret was created there. // Check subclusters if the secret was created there.
@ -104,7 +124,6 @@ func verifyCascadingDeletion(clientset *fedclientset.Clientset,
} }
return false, nil return false, nil
} }
} }
return true, nil return true, nil
}) })
@ -115,11 +134,13 @@ func verifyCascadingDeletion(clientset *fedclientset.Clientset,
By(fmt.Sprintf("Verifying secrets %s in underlying clusters", secretName)) By(fmt.Sprintf("Verifying secrets %s in underlying clusters", secretName))
errMessages := []string{} errMessages := []string{}
// secret should be present in underlying clusters unless orphanDependents is false.
shouldExist := orphanDependents == nil || *orphanDependents == true
for clusterName, clusterClientset := range clusters { for clusterName, clusterClientset := range clusters {
_, err := clusterClientset.Core().Secrets(nsName).Get(secretName) _, err := clusterClientset.Core().Secrets(nsName).Get(secretName)
if orphanDependents && errors.IsNotFound(err) { if shouldExist && errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for secret %s in cluster %s, expected secret to exist", secretName, clusterName)) errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for secret %s in cluster %s, expected secret to exist", secretName, clusterName))
} else if !orphanDependents && (err == nil || !errors.IsNotFound(err)) { } else if !shouldExist && !errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for secret %s in cluster %s, got error: %v", secretName, clusterName, err)) errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for secret %s in cluster %s, got error: %v", secretName, clusterName, err))
} }
} }
@ -146,9 +167,9 @@ func createSecretOrFail(clientset *fedclientset.Clientset, nsName string) *v1.Se
return secret return secret
} }
func deleteSecretOrFail(clientset *fedclientset.Clientset, nsName string, secretName string, orphanDependents bool) { func deleteSecretOrFail(clientset *fedclientset.Clientset, nsName string, secretName string, orphanDependents *bool) {
By(fmt.Sprintf("Deleting secret %q in namespace %q", secretName, nsName)) By(fmt.Sprintf("Deleting secret %q in namespace %q", secretName, nsName))
err := clientset.Core().Secrets(nsName).Delete(secretName, &v1.DeleteOptions{OrphanDependents: &orphanDependents}) err := clientset.Core().Secrets(nsName).Delete(secretName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
framework.ExpectNoError(err, "Error deleting secret %q in namespace %q", secretName, nsName) framework.ExpectNoError(err, "Error deleting secret %q in namespace %q", secretName, nsName)
// Wait for the secret to be deleted. // Wait for the secret to be deleted.

View File

@ -18,6 +18,7 @@ package e2e
import ( import (
"fmt" "fmt"
"strings"
"time" "time"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
@ -39,7 +40,7 @@ const (
) )
// Create/delete daemonset api objects // Create/delete daemonset api objects
var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", func() { var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation]", func() {
var clusters map[string]*cluster // All clusters, keyed by cluster name var clusters map[string]*cluster // All clusters, keyed by cluster name
f := framework.NewDefaultFederatedFramework("federated-daemonset") f := framework.NewDefaultFederatedFramework("federated-daemonset")
@ -54,6 +55,9 @@ var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", f
AfterEach(func() { AfterEach(func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
// Delete all daemonsets.
nsName := f.FederationNamespace.Name
deleteAllDaemonSetsOrFail(f.FederationClientset_1_5, nsName)
unregisterClusters(clusters, f) unregisterClusters(clusters, f)
}) })
@ -71,9 +75,83 @@ var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", f
daemonset = updateDaemonSetOrFail(f.FederationClientset_1_5, nsName) daemonset = updateDaemonSetOrFail(f.FederationClientset_1_5, nsName)
waitForDaemonSetShardsUpdatedOrFail(nsName, daemonset, clusters) waitForDaemonSetShardsUpdatedOrFail(nsName, daemonset, clusters)
}) })
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := false
verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that daemonsets were deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := true
verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, nil, nsName)
By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
})
}) })
}) })
// deleteAllDaemonSetsOrFail deletes all DaemonSets in the given namespace name.
func deleteAllDaemonSetsOrFail(clientset *fedclientset.Clientset, nsName string) {
DaemonSetList, err := clientset.Extensions().DaemonSets(nsName).List(v1.ListOptions{})
Expect(err).NotTo(HaveOccurred())
orphanDependents := false
for _, daemonSet := range DaemonSetList.Items {
deleteDaemonSetOrFail(clientset, nsName, daemonSet.Name, &orphanDependents)
}
}
// verifyCascadingDeletionForDS verifies that daemonsets are deleted from
// underlying clusters when orphan dependents is false and they are not
// deleted when orphan dependents is true.
func verifyCascadingDeletionForDS(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
daemonset := createDaemonSetOrFail(clientset, nsName)
daemonsetName := daemonset.Name
// Check subclusters if the daemonset was created there.
By(fmt.Sprintf("Waiting for daemonset %s to be created in all underlying clusters", daemonsetName))
err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
for _, cluster := range clusters {
_, err := cluster.Extensions().DaemonSets(nsName).Get(daemonsetName)
if err != nil && errors.IsNotFound(err) {
return false, nil
}
if err != nil {
return false, err
}
}
return true, nil
})
framework.ExpectNoError(err, "Not all daemonsets created")
By(fmt.Sprintf("Deleting daemonset %s", daemonsetName))
deleteDaemonSetOrFail(clientset, nsName, daemonsetName, orphanDependents)
By(fmt.Sprintf("Verifying daemonsets %s in underlying clusters", daemonsetName))
errMessages := []string{}
// daemon set should be present in underlying clusters unless orphanDependents is false.
shouldExist := orphanDependents == nil || *orphanDependents == true
for clusterName, clusterClientset := range clusters {
_, err := clusterClientset.Extensions().DaemonSets(nsName).Get(daemonsetName)
if shouldExist && errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for daemonset %s in cluster %s, expected daemonset to exist", daemonsetName, clusterName))
} else if !shouldExist && !errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for daemonset %s in cluster %s, got error: %v", daemonsetName, clusterName, err))
}
}
if len(errMessages) != 0 {
framework.Failf("%s", strings.Join(errMessages, "; "))
}
}
func createDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet { func createDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet {
if clientset == nil || len(namespace) == 0 { if clientset == nil || len(namespace) == 0 {
Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace)) Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
@ -108,6 +186,24 @@ func createDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string)
return daemonset return daemonset
} }
func deleteDaemonSetOrFail(clientset *fedclientset.Clientset, nsName string, daemonsetName string, orphanDependents *bool) {
By(fmt.Sprintf("Deleting daemonset %q in namespace %q", daemonsetName, nsName))
err := clientset.Extensions().DaemonSets(nsName).Delete(daemonsetName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
framework.ExpectNoError(err, "Error deleting daemonset %q in namespace %q", daemonsetName, nsName)
// Wait for the daemonset to be deleted.
err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
_, err := clientset.Extensions().DaemonSets(nsName).Get(daemonsetName)
if err != nil && errors.IsNotFound(err) {
return true, nil
}
return false, err
})
if err != nil {
framework.Failf("Error in deleting daemonset %s: %v", daemonsetName, err)
}
}
func updateDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet { func updateDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet {
if clientset == nil || len(namespace) == 0 { if clientset == nil || len(namespace) == 0 {
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace)) Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace))

View File

@ -19,9 +19,10 @@ package e2e
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"time" "time"
"k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util" fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
@ -49,14 +50,9 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
AfterEach(func() { AfterEach(func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
// Delete registered deployments. // Delete all deployments.
nsName := f.FederationNamespace.Name nsName := f.FederationNamespace.Name
deploymentList, err := f.FederationClientset_1_5.Extensions().Deployments(nsName).List(v1.ListOptions{}) deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
Expect(err).NotTo(HaveOccurred())
for _, deployment := range deploymentList.Items {
err := f.FederationClientset_1_5.Extensions().Deployments(nsName).Delete(deployment.Name, &v1.DeleteOptions{})
Expect(err).NotTo(HaveOccurred())
}
}) })
It("should be created and deleted successfully", func() { It("should be created and deleted successfully", func() {
@ -89,6 +85,8 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
}) })
AfterEach(func() { AfterEach(func() {
nsName := f.FederationNamespace.Name
deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
unregisterClusters(clusters, f) unregisterClusters(clusters, f)
}) })
@ -111,25 +109,101 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters) waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name)) By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name))
}) })
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := false
verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that deployments were deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := true
verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, nil, nsName)
By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
})
}) })
}) })
func waitForDeploymentOrFail(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) { // deleteAllDeploymentsOrFail deletes all deployments in the given namespace name.
err := waitForDeployment(c, namespace, replicaSetName, clusters) func deleteAllDeploymentsOrFail(clientset *fedclientset.Clientset, nsName string) {
framework.ExpectNoError(err, "Failed to verify deployment %q/%q, err: %v", namespace, replicaSetName, err) deploymentList, err := clientset.Extensions().Deployments(nsName).List(v1.ListOptions{})
Expect(err).NotTo(HaveOccurred())
orphanDependents := false
for _, deployment := range deploymentList.Items {
deleteDeploymentOrFail(clientset, nsName, deployment.Name, &orphanDependents)
}
} }
func waitForDeployment(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error { // verifyCascadingDeletionForDeployment verifies that deployments are deleted
// from underlying clusters when orphan dependents is false and they are not
// deleted when orphan dependents is true.
func verifyCascadingDeletionForDeployment(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
deployment := createDeploymentOrFail(clientset, nsName)
deploymentName := deployment.Name
// Check subclusters if the deployment was created there.
By(fmt.Sprintf("Waiting for deployment %s to be created in all underlying clusters", deploymentName))
err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
for _, cluster := range clusters {
_, err := cluster.Extensions().Deployments(nsName).Get(deploymentName)
if err != nil && errors.IsNotFound(err) {
return false, nil
}
if err != nil {
return false, err
}
}
return true, nil
})
framework.ExpectNoError(err, "Not all deployments created")
By(fmt.Sprintf("Deleting deployment %s", deploymentName))
deleteDeploymentOrFail(clientset, nsName, deploymentName, orphanDependents)
By(fmt.Sprintf("Verifying deployments %s in underlying clusters", deploymentName))
errMessages := []string{}
// deployment should be present in underlying clusters unless orphanDependents is false.
shouldExist := orphanDependents == nil || *orphanDependents == true
for clusterName, clusterClientset := range clusters {
_, err := clusterClientset.Extensions().Deployments(nsName).Get(deploymentName)
if shouldExist && errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for deployment %s in cluster %s, expected deployment to exist", deploymentName, clusterName))
} else if shouldExist && !errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for deployment %s in cluster %s, got error: %v", deploymentName, clusterName, err))
}
}
if len(errMessages) != 0 {
framework.Failf("%s", strings.Join(errMessages, "; "))
}
}
func waitForDeploymentOrFail(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) {
err := waitForDeployment(c, namespace, deploymentName, clusters)
framework.ExpectNoError(err, "Failed to verify deployment %q/%q, err: %v", namespace, deploymentName, err)
}
func waitForDeployment(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) error {
err := wait.Poll(10*time.Second, FederatedDeploymentTimeout, func() (bool, error) { err := wait.Poll(10*time.Second, FederatedDeploymentTimeout, func() (bool, error) {
fdep, err := c.Deployments(namespace).Get(replicaSetName) fdep, err := c.Deployments(namespace).Get(deploymentName)
if err != nil { if err != nil {
return false, err return false, err
} }
specReplicas, statusReplicas := int32(0), int32(0) specReplicas, statusReplicas := int32(0), int32(0)
for _, cluster := range clusters { for _, cluster := range clusters {
dep, err := cluster.Deployments(namespace).Get(replicaSetName) dep, err := cluster.Deployments(namespace).Get(deploymentName)
if err != nil && !errors.IsNotFound(err) { if err != nil && !errors.IsNotFound(err) {
By(fmt.Sprintf("Failed getting deployment: %q/%q/%q, err: %v", cluster.name, namespace, replicaSetName, err)) By(fmt.Sprintf("Failed getting deployment: %q/%q/%q, err: %v", cluster.name, namespace, deploymentName, err))
return false, err return false, err
} }
if err == nil { if err == nil {
@ -158,7 +232,7 @@ func equivalentDeployment(fedDeployment, localDeployment *v1beta1.Deployment) bo
reflect.DeepEqual(fedDeployment.Spec, localDeploymentSpec) reflect.DeepEqual(fedDeployment.Spec, localDeploymentSpec)
} }
func createDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.Deployment { func createDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
if clientset == nil || len(namespace) == 0 { if clientset == nil || len(namespace) == 0 {
Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace)) Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
} }
@ -172,7 +246,7 @@ func createDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespa
return deployment return deployment
} }
func updateDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.Deployment { func updateDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
if clientset == nil || len(namespace) == 0 { if clientset == nil || len(namespace) == 0 {
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace)) Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
} }
@ -187,6 +261,24 @@ func updateDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespa
return newRs return newRs
} }
func deleteDeploymentOrFail(clientset *fedclientset.Clientset, nsName string, deploymentName string, orphanDependents *bool) {
By(fmt.Sprintf("Deleting deployment %q in namespace %q", deploymentName, nsName))
err := clientset.Extensions().Deployments(nsName).Delete(deploymentName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deploymentName, nsName)
// Wait for the deployment to be deleted.
err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
_, err := clientset.Extensions().Deployments(nsName).Get(deploymentName)
if err != nil && errors.IsNotFound(err) {
return true, nil
}
return false, err
})
if err != nil {
framework.Failf("Error in deleting deployment %s: %v", deploymentName, err)
}
}
func newDeploymentForFed(namespace string, name string, replicas int32) *v1beta1.Deployment { func newDeploymentForFed(namespace string, name string, replicas int32) *v1beta1.Deployment {
return &v1beta1.Deployment{ return &v1beta1.Deployment{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: v1.ObjectMeta{

View File

@ -19,9 +19,10 @@ package e2e
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"time" "time"
"k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util" fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
@ -49,14 +50,9 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
AfterEach(func() { AfterEach(func() {
framework.SkipUnlessFederated(f.ClientSet) framework.SkipUnlessFederated(f.ClientSet)
// Delete registered replicasets. // Delete all replicasets.
nsName := f.FederationNamespace.Name nsName := f.FederationNamespace.Name
replicasetList, err := f.FederationClientset_1_5.Extensions().ReplicaSets(nsName).List(v1.ListOptions{}) deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
Expect(err).NotTo(HaveOccurred())
for _, replicaset := range replicasetList.Items {
err := f.FederationClientset_1_5.Extensions().ReplicaSets(nsName).Delete(replicaset.Name, &v1.DeleteOptions{})
Expect(err).NotTo(HaveOccurred())
}
}) })
It("should be created and deleted successfully", func() { It("should be created and deleted successfully", func() {
@ -89,6 +85,9 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
}) })
AfterEach(func() { AfterEach(func() {
// Delete all replicasets.
nsName := f.FederationNamespace.Name
deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
unregisterClusters(clusters, f) unregisterClusters(clusters, f)
}) })
@ -111,15 +110,88 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters) waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters)
By(fmt.Sprintf("Successfuly updated and synced replicaset %q/%q to clusters", nsName, rs.Name)) By(fmt.Sprintf("Successfuly updated and synced replicaset %q/%q to clusters", nsName, rs.Name))
}) })
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := false
verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that replica sets were deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
orphanDependents := true
verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
})
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
framework.SkipUnlessFederated(f.ClientSet)
nsName := f.FederationNamespace.Name
verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, nil, nsName)
By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
})
}) })
}) })
func waitForReplicaSetOrFail(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) { // deleteAllReplicaSetsOrFail deletes all replicasets in the given namespace name.
err := waitForReplicaSet(c, namespace, replicaSetName, clusters) func deleteAllReplicaSetsOrFail(clientset *fedclientset.Clientset, nsName string) {
framework.ExpectNoError(err, "Failed to verify replicaset %q/%q, err: %v", namespace, replicaSetName, err) replicasetList, err := clientset.Extensions().ReplicaSets(nsName).List(v1.ListOptions{})
Expect(err).NotTo(HaveOccurred())
orphanDependents := false
for _, replicaset := range replicasetList.Items {
deleteReplicaSetOrFail(clientset, nsName, replicaset.Name, &orphanDependents)
}
} }
func waitForReplicaSet(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error { // verifyCascadingDeletionForReplicaSet verifies that replicaSets are deleted
// from underlying clusters when orphan dependents is false and they are not
// deleted when orphan dependents is true.
func verifyCascadingDeletionForReplicaSet(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
replicaSet := createReplicaSetOrFail(clientset, nsName)
replicaSetName := replicaSet.Name
// Check subclusters if the replicaSet was created there.
By(fmt.Sprintf("Waiting for replica sets %s to be created in all underlying clusters", replicaSetName))
err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
for _, cluster := range clusters {
_, err := cluster.Extensions().ReplicaSets(nsName).Get(replicaSetName)
if err != nil && errors.IsNotFound(err) {
return false, nil
}
if err != nil {
return false, err
}
}
return true, nil
})
framework.ExpectNoError(err, "Not all replica sets created")
By(fmt.Sprintf("Deleting replica set %s", replicaSetName))
deleteReplicaSetOrFail(clientset, nsName, replicaSetName, orphanDependents)
By(fmt.Sprintf("Verifying replica sets %s in underlying clusters", replicaSetName))
errMessages := []string{}
for clusterName, clusterClientset := range clusters {
_, err := clusterClientset.Extensions().ReplicaSets(nsName).Get(replicaSetName)
if (orphanDependents == nil || *orphanDependents == true) && errors.IsNotFound(err) {
errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for replica set %s in cluster %s, expected replica set to exist", replicaSetName, clusterName))
} else if (orphanDependents != nil && *orphanDependents == false) && (err == nil || !errors.IsNotFound(err)) {
errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for replica set %s in cluster %s, got error: %v", replicaSetName, clusterName, err))
}
}
if len(errMessages) != 0 {
framework.Failf("%s", strings.Join(errMessages, "; "))
}
}
func waitForReplicaSetOrFail(c *fedclientset.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) {
err := waitForReplicaSet(c, namespace, replicaSetName, clusters)
framework.ExpectNoError(err, "Failed to verify replica set %q/%q, err: %v", namespace, replicaSetName, err)
}
func waitForReplicaSet(c *fedclientset.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error {
err := wait.Poll(10*time.Second, FederatedReplicaSetTimeout, func() (bool, error) { err := wait.Poll(10*time.Second, FederatedReplicaSetTimeout, func() (bool, error) {
frs, err := c.ReplicaSets(namespace).Get(replicaSetName) frs, err := c.ReplicaSets(namespace).Get(replicaSetName)
if err != nil { if err != nil {
@ -158,7 +230,7 @@ func equivalentReplicaSet(fedReplicaSet, localReplicaSet *v1beta1.ReplicaSet) bo
reflect.DeepEqual(fedReplicaSet.Spec, localReplicaSetSpec) reflect.DeepEqual(fedReplicaSet.Spec, localReplicaSetSpec)
} }
func createReplicaSetOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.ReplicaSet { func createReplicaSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.ReplicaSet {
if clientset == nil || len(namespace) == 0 { if clientset == nil || len(namespace) == 0 {
Fail(fmt.Sprintf("Internal error: invalid parameters passed to createReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace)) Fail(fmt.Sprintf("Internal error: invalid parameters passed to createReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
} }
@ -172,7 +244,25 @@ func createReplicaSetOrFail(clientset *federation_release_1_5.Clientset, namespa
return replicaset return replicaset
} }
func updateReplicaSetOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.ReplicaSet { func deleteReplicaSetOrFail(clientset *fedclientset.Clientset, nsName string, replicaSetName string, orphanDependents *bool) {
By(fmt.Sprintf("Deleting replica set %q in namespace %q", replicaSetName, nsName))
err := clientset.Extensions().ReplicaSets(nsName).Delete(replicaSetName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
framework.ExpectNoError(err, "Error deleting replica set %q in namespace %q", replicaSetName, nsName)
// Wait for the replicaSet to be deleted.
err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
_, err := clientset.Extensions().ReplicaSets(nsName).Get(replicaSetName)
if err != nil && errors.IsNotFound(err) {
return true, nil
}
return false, err
})
if err != nil {
framework.Failf("Error in deleting replica set %s: %v", replicaSetName, err)
}
}
func updateReplicaSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.ReplicaSet {
if clientset == nil || len(namespace) == 0 { if clientset == nil || len(namespace) == 0 {
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace)) Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
} }