e2e: use Ginkgo context

All code must use the context from Ginkgo when doing API calls or polling for a
change, otherwise the code would not return immediately when the test gets
aborted.
This commit is contained in:
Patrick Ohly
2022-12-12 10:11:10 +01:00
parent bf1d1dfd0f
commit 2f6c4f5eab
418 changed files with 11489 additions and 11369 deletions

View File

@@ -146,7 +146,7 @@ var (
var RunID = uuid.NewUUID()
// CreateTestingNSFn is a func that is responsible for creating namespace used for executing e2e tests.
type CreateTestingNSFn func(baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error)
type CreateTestingNSFn func(ctx context.Context, baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error)
// APIAddress returns a address of an instance.
func APIAddress() string {
@@ -198,9 +198,9 @@ func NodeOSArchIs(supportedNodeOsArchs ...string) bool {
// DeleteNamespaces deletes all namespaces that match the given delete and skip filters.
// Filter is by simple strings.Contains; first skip filter, then delete filter.
// Returns the list of deleted namespaces or an error.
func DeleteNamespaces(c clientset.Interface, deleteFilter, skipFilter []string) ([]string, error) {
func DeleteNamespaces(ctx context.Context, c clientset.Interface, deleteFilter, skipFilter []string) ([]string, error) {
ginkgo.By("Deleting namespaces")
nsList, err := c.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
nsList, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
ExpectNoError(err, "Failed to get namespace list")
var deleted []string
var wg sync.WaitGroup
@@ -228,7 +228,7 @@ OUTER:
go func(nsName string) {
defer wg.Done()
defer ginkgo.GinkgoRecover()
gomega.Expect(c.CoreV1().Namespaces().Delete(context.TODO(), nsName, metav1.DeleteOptions{})).To(gomega.Succeed())
gomega.Expect(c.CoreV1().Namespaces().Delete(ctx, nsName, metav1.DeleteOptions{})).To(gomega.Succeed())
Logf("namespace : %v api call to delete is complete ", nsName)
}(item.Name)
}
@@ -237,16 +237,16 @@ OUTER:
}
// WaitForNamespacesDeleted waits for the namespaces to be deleted.
func WaitForNamespacesDeleted(c clientset.Interface, namespaces []string, timeout time.Duration) error {
func WaitForNamespacesDeleted(ctx context.Context, c clientset.Interface, namespaces []string, timeout time.Duration) error {
ginkgo.By(fmt.Sprintf("Waiting for namespaces %+v to vanish", namespaces))
nsMap := map[string]bool{}
for _, ns := range namespaces {
nsMap[ns] = true
}
//Now POLL until all namespaces have been eradicated.
return wait.Poll(2*time.Second, timeout,
func() (bool, error) {
nsList, err := c.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
return wait.PollWithContext(ctx, 2*time.Second, timeout,
func(ctx context.Context) (bool, error) {
nsList, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
return false, err
}
@@ -259,20 +259,20 @@ func WaitForNamespacesDeleted(c clientset.Interface, namespaces []string, timeou
})
}
func waitForConfigMapInNamespace(c clientset.Interface, ns, name string, timeout time.Duration) error {
func waitForConfigMapInNamespace(ctx context.Context, c clientset.Interface, ns, name string, timeout time.Duration) error {
fieldSelector := fields.OneTermEqualSelector("metadata.name", name).String()
ctx, cancel := watchtools.ContextWithOptionalTimeout(ctx, timeout)
defer cancel()
lw := &cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (object runtime.Object, e error) {
options.FieldSelector = fieldSelector
return c.CoreV1().ConfigMaps(ns).List(context.TODO(), options)
return c.CoreV1().ConfigMaps(ns).List(ctx, options)
},
WatchFunc: func(options metav1.ListOptions) (i watch.Interface, e error) {
options.FieldSelector = fieldSelector
return c.CoreV1().ConfigMaps(ns).Watch(context.TODO(), options)
return c.CoreV1().ConfigMaps(ns).Watch(ctx, options)
},
}
ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout)
defer cancel()
_, err := watchtools.UntilWithSync(ctx, lw, &v1.ConfigMap{}, nil, func(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
@@ -285,20 +285,20 @@ func waitForConfigMapInNamespace(c clientset.Interface, ns, name string, timeout
return err
}
func waitForServiceAccountInNamespace(c clientset.Interface, ns, serviceAccountName string, timeout time.Duration) error {
func waitForServiceAccountInNamespace(ctx context.Context, c clientset.Interface, ns, serviceAccountName string, timeout time.Duration) error {
fieldSelector := fields.OneTermEqualSelector("metadata.name", serviceAccountName).String()
ctx, cancel := watchtools.ContextWithOptionalTimeout(ctx, timeout)
defer cancel()
lw := &cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (object runtime.Object, e error) {
options.FieldSelector = fieldSelector
return c.CoreV1().ServiceAccounts(ns).List(context.TODO(), options)
return c.CoreV1().ServiceAccounts(ns).List(ctx, options)
},
WatchFunc: func(options metav1.ListOptions) (i watch.Interface, e error) {
options.FieldSelector = fieldSelector
return c.CoreV1().ServiceAccounts(ns).Watch(context.TODO(), options)
return c.CoreV1().ServiceAccounts(ns).Watch(ctx, options)
},
}
ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout)
defer cancel()
_, err := watchtools.UntilWithSync(ctx, lw, &v1.ServiceAccount{}, nil, func(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
@@ -317,20 +317,20 @@ func waitForServiceAccountInNamespace(c clientset.Interface, ns, serviceAccountN
// WaitForDefaultServiceAccountInNamespace waits for the default service account to be provisioned
// the default service account is what is associated with pods when they do not specify a service account
// as a result, pods are not able to be provisioned in a namespace until the service account is provisioned
func WaitForDefaultServiceAccountInNamespace(c clientset.Interface, namespace string) error {
return waitForServiceAccountInNamespace(c, namespace, "default", ServiceAccountProvisionTimeout)
func WaitForDefaultServiceAccountInNamespace(ctx context.Context, c clientset.Interface, namespace string) error {
return waitForServiceAccountInNamespace(ctx, c, namespace, "default", ServiceAccountProvisionTimeout)
}
// WaitForKubeRootCAInNamespace waits for the configmap kube-root-ca.crt containing the service account
// CA trust bundle to be provisioned in the specified namespace so that pods do not have to retry mounting
// the config map (which creates noise that hides other issues in the Kubelet).
func WaitForKubeRootCAInNamespace(c clientset.Interface, namespace string) error {
return waitForConfigMapInNamespace(c, namespace, "kube-root-ca.crt", ServiceAccountProvisionTimeout)
func WaitForKubeRootCAInNamespace(ctx context.Context, c clientset.Interface, namespace string) error {
return waitForConfigMapInNamespace(ctx, c, namespace, "kube-root-ca.crt", ServiceAccountProvisionTimeout)
}
// CreateTestingNS should be used by every test, note that we append a common prefix to the provided test name.
// Please see NewFramework instead of using this directly.
func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error) {
func CreateTestingNS(ctx context.Context, baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error) {
if labels == nil {
labels = map[string]string{}
}
@@ -351,9 +351,9 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s
}
// Be robust about making the namespace creation call.
var got *v1.Namespace
if err := wait.PollImmediate(Poll, 30*time.Second, func() (bool, error) {
if err := wait.PollImmediateWithContext(ctx, Poll, 30*time.Second, func(ctx context.Context) (bool, error) {
var err error
got, err = c.CoreV1().Namespaces().Create(context.TODO(), namespaceObj, metav1.CreateOptions{})
got, err = c.CoreV1().Namespaces().Create(ctx, namespaceObj, metav1.CreateOptions{})
if err != nil {
if apierrors.IsAlreadyExists(err) {
// regenerate on conflict
@@ -370,7 +370,7 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s
}
if TestContext.VerifyServiceAccount {
if err := WaitForDefaultServiceAccountInNamespace(c, got.Name); err != nil {
if err := WaitForDefaultServiceAccountInNamespace(ctx, c, got.Name); err != nil {
// Even if we fail to create serviceAccount in the namespace,
// we have successfully create a namespace.
// So, return the created namespace.
@@ -382,7 +382,7 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s
// CheckTestingNSDeletedExcept checks whether all e2e based existing namespaces are in the Terminating state
// and waits until they are finally deleted. It ignores namespace skip.
func CheckTestingNSDeletedExcept(c clientset.Interface, skip string) error {
func CheckTestingNSDeletedExcept(ctx context.Context, c clientset.Interface, skip string) error {
// TODO: Since we don't have support for bulk resource deletion in the API,
// while deleting a namespace we are deleting all objects from that namespace
// one by one (one deletion == one API call). This basically exposes us to
@@ -398,7 +398,7 @@ func CheckTestingNSDeletedExcept(c clientset.Interface, skip string) error {
Logf("Waiting for terminating namespaces to be deleted...")
for start := time.Now(); time.Since(start) < timeout; time.Sleep(15 * time.Second) {
namespaces, err := c.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
namespaces, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
Logf("Listing namespaces failed: %v", err)
continue
@@ -420,10 +420,10 @@ func CheckTestingNSDeletedExcept(c clientset.Interface, skip string) error {
}
// WaitForServiceEndpointsNum waits until the amount of endpoints that implement service to expectNum.
func WaitForServiceEndpointsNum(c clientset.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error {
return wait.Poll(interval, timeout, func() (bool, error) {
func WaitForServiceEndpointsNum(ctx context.Context, c clientset.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error {
return wait.PollWithContext(ctx, interval, timeout, func(ctx context.Context) (bool, error) {
Logf("Waiting for amount of service:%s endpoints to be %d", serviceName, expectNum)
list, err := c.CoreV1().Endpoints(namespace).List(context.TODO(), metav1.ListOptions{})
list, err := c.CoreV1().Endpoints(namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return false, err
}
@@ -547,8 +547,8 @@ func TryKill(cmd *exec.Cmd) {
// EnsureLoadBalancerResourcesDeleted ensures that cloud load balancer resources that were created
// are actually cleaned up. Currently only implemented for GCE/GKE.
func EnsureLoadBalancerResourcesDeleted(ip, portRange string) error {
return TestContext.CloudConfig.Provider.EnsureLoadBalancerResourcesDeleted(ip, portRange)
func EnsureLoadBalancerResourcesDeleted(ctx context.Context, ip, portRange string) error {
return TestContext.CloudConfig.Provider.EnsureLoadBalancerResourcesDeleted(ctx, ip, portRange)
}
// CoreDump SSHs to the master and all nodes and dumps their logs into dir.
@@ -613,11 +613,11 @@ func RunCmdEnv(env []string, command string, args ...string) (string, string, er
// getControlPlaneAddresses returns the externalIP, internalIP and hostname fields of control plane nodes.
// If any of these is unavailable, empty slices are returned.
func getControlPlaneAddresses(c clientset.Interface) ([]string, []string, []string) {
func getControlPlaneAddresses(ctx context.Context, c clientset.Interface) ([]string, []string, []string) {
var externalIPs, internalIPs, hostnames []string
// Populate the internal IPs.
eps, err := c.CoreV1().Endpoints(metav1.NamespaceDefault).Get(context.TODO(), "kubernetes", metav1.GetOptions{})
eps, err := c.CoreV1().Endpoints(metav1.NamespaceDefault).Get(ctx, "kubernetes", metav1.GetOptions{})
if err != nil {
Failf("Failed to get kubernetes endpoints: %v", err)
}
@@ -647,8 +647,8 @@ func getControlPlaneAddresses(c clientset.Interface) ([]string, []string, []stri
// It may return internal and external IPs, even if we expect for
// e.g. internal IPs to be used (issue #56787), so that we can be
// sure to block the control plane fully during tests.
func GetControlPlaneAddresses(c clientset.Interface) []string {
externalIPs, internalIPs, _ := getControlPlaneAddresses(c)
func GetControlPlaneAddresses(ctx context.Context, c clientset.Interface) []string {
externalIPs, internalIPs, _ := getControlPlaneAddresses(ctx, c)
ips := sets.NewString()
switch TestContext.Provider {
@@ -685,7 +685,7 @@ func PrettyPrintJSON(metrics interface{}) string {
// WatchEventSequenceVerifier ...
// manages a watch for a given resource, ensures that events take place in a given order, retries the test on failure
//
// testContext cancellation signal across API boundaries, e.g: context.TODO()
// ctx cancellation signal across API boundaries, e.g: context from Ginkgo
// dc sets up a client to the API
// resourceType specify the type of resource
// namespace select a namespace