github.com/jmrodri/operator-sdk@v0.5.0/pkg/test/e2eutil/wait_util.go (about)

     1  // Copyright 2018 The Operator-SDK Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package e2eutil
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/operator-framework/operator-sdk/pkg/test"
    22  
    23  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/util/wait"
    26  	"k8s.io/client-go/kubernetes"
    27  )
    28  
    29  // WaitForDeployment checks to see if a given deployment has a certain number of available replicas after a specified amount of time
    30  // If the deployment does not have the required number of replicas after 5 * retries seconds, the function returns an error
    31  // This can be used in multiple ways, like verifying that a required resource is ready before trying to use it, or to test
    32  // failure handling, like simulated in SimulatePodFail.
    33  func WaitForDeployment(t *testing.T, kubeclient kubernetes.Interface, namespace, name string, replicas int, retryInterval, timeout time.Duration) error {
    34  	return waitForDeployment(t, kubeclient, namespace, name, replicas, retryInterval, timeout, false)
    35  }
    36  
    37  // WaitForOperatorDeployment has the same functionality as WaitForDeployment but will no wait for the deployment if the
    38  // test was run with a locally run operator (--up-local flag)
    39  func WaitForOperatorDeployment(t *testing.T, kubeclient kubernetes.Interface, namespace, name string, replicas int, retryInterval, timeout time.Duration) error {
    40  	return waitForDeployment(t, kubeclient, namespace, name, replicas, retryInterval, timeout, true)
    41  }
    42  
    43  func waitForDeployment(t *testing.T, kubeclient kubernetes.Interface, namespace, name string, replicas int, retryInterval, timeout time.Duration, isOperator bool) error {
    44  	if isOperator && test.Global.LocalOperator {
    45  		t.Log("Operator is running locally; skip waitForDeployment")
    46  		return nil
    47  	}
    48  	err := wait.Poll(retryInterval, timeout, func() (done bool, err error) {
    49  		deployment, err := kubeclient.AppsV1().Deployments(namespace).Get(name, metav1.GetOptions{IncludeUninitialized: true})
    50  		if err != nil {
    51  			if apierrors.IsNotFound(err) {
    52  				t.Logf("Waiting for availability of %s deployment\n", name)
    53  				return false, nil
    54  			}
    55  			return false, err
    56  		}
    57  
    58  		if int(deployment.Status.AvailableReplicas) == replicas {
    59  			return true, nil
    60  		}
    61  		t.Logf("Waiting for full availability of %s deployment (%d/%d)\n", name, deployment.Status.AvailableReplicas, replicas)
    62  		return false, nil
    63  	})
    64  	if err != nil {
    65  		return err
    66  	}
    67  	t.Logf("Deployment available (%d/%d)\n", replicas, replicas)
    68  	return nil
    69  }