github.com/interconnectedcloud/qdr-operator@v0.0.0-20210826174505-576d2b33dac7/test/e2e/framework/util.go (about)

     1  /*
     2  Copyright 2019 The Interconnectedcloud Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package framework
    18  
    19  import (
    20  	"fmt"
    21  	"sort"
    22  
    23  	"k8s.io/apimachinery/pkg/util/uuid"
    24  	clientset "k8s.io/client-go/kubernetes"
    25  	restclient "k8s.io/client-go/rest"
    26  	"k8s.io/client-go/tools/clientcmd"
    27  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    28  
    29  	e2elog "github.com/interconnectedcloud/qdr-operator/test/e2e/framework/log"
    30  
    31  	"github.com/onsi/gomega"
    32  )
    33  
    34  var (
    35  	RunID = uuid.NewUUID()
    36  )
    37  
    38  // RestclientConfig returns a config holds the information needed to build connection to kubernetes clusters.
    39  func RestclientConfig(kubeContext string) (*clientcmdapi.Config, error) {
    40  	//e2elog.Logf(">>> kubeConfig: %s", TestContext.KubeConfig)
    41  	if TestContext.KubeConfig == "" {
    42  		return nil, fmt.Errorf("KubeConfig must be specified to load client config")
    43  	}
    44  	c, err := clientcmd.LoadFromFile(TestContext.KubeConfig)
    45  	if err != nil {
    46  		return nil, fmt.Errorf("error loading KubeConfig: %v", err.Error())
    47  	}
    48  	if kubeContext != "" {
    49  		//e2elog.Logf(">>> kubeContext: %s", kubeContext)
    50  		c.CurrentContext = kubeContext
    51  	}
    52  	return c, nil
    53  }
    54  
    55  // LoadConfig returns a config for a rest client.
    56  func LoadConfig() (*restclient.Config, error) {
    57  	 c, err := RestclientConfig(TestContext.KubeContext)
    58  	if err != nil {
    59  		if TestContext.KubeConfig == "" {
    60  			return restclient.InClusterConfig()
    61  		}
    62  		return nil, err
    63  	}
    64  
    65  	return clientcmd.NewDefaultClientConfig(*c, &clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: TestContext.Host}}).ClientConfig()
    66  }
    67  
    68  // LoadClientset returns clientset for connecting to kubernetes clusters.
    69  func LoadClientset() (*clientset.Clientset, error) {
    70  	config, err := LoadConfig()
    71  	if err != nil {
    72  		return nil, fmt.Errorf("error creating client: %v", err.Error())
    73  	}
    74  	return clientset.NewForConfig(config)
    75  }
    76  
    77  // ExpectError expects an error happens, otherwise an exception raises
    78  func ExpectError(err error, explain ...interface{}) {
    79  	gomega.Expect(err).To(gomega.HaveOccurred(), explain...)
    80  }
    81  
    82  // ExpectNoError checks if "err" is set, and if so, fails assertion while logging the error.
    83  func ExpectNoError(err error, explain ...interface{}) {
    84  	ExpectNoErrorWithOffset(1, err, explain...)
    85  }
    86  
    87  // ExpectNoErrorWithOffset checks if "err" is set, and if so, fails assertion while logging the error at "offset" levels above its caller
    88  // (for example, for call chain f -> g -> ExpectNoErrorWithOffset(1, ...) error would be logged for "f").
    89  func ExpectNoErrorWithOffset(offset int, err error, explain ...interface{}) {
    90  	if err != nil {
    91  		e2elog.Logf("Unexpected error occurred: %v", err)
    92  	}
    93  	gomega.ExpectWithOffset(1+offset, err).NotTo(gomega.HaveOccurred(), explain...)
    94  }
    95  
    96  // ExpectNoErrorWithRetries checks if an error occurs with the given retry count.
    97  func ExpectNoErrorWithRetries(fn func() error, maxRetries int, explain ...interface{}) {
    98  	var err error
    99  	for i := 0; i < maxRetries; i++ {
   100  		err = fn()
   101  		if err == nil {
   102  			return
   103  		}
   104  		e2elog.Logf("(Attempt %d of %d) Unexpected error occurred: %v", i+1, maxRetries, err)
   105  	}
   106  	gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred(), explain...)
   107  }
   108  
   109  // ContainsAll can be used to compare two sorted slices and validate
   110  // both are not nil and all elements from given model are present on
   111  // the target instance.
   112  func ContainsAll(model, target []interface{}) bool {
   113  	if model == nil || target == nil {
   114  		return false
   115  	}
   116  
   117  	if len(model) > len(target) {
   118  		return false
   119  	}
   120  
   121  	ti := 0
   122  	for _, vm := range model {
   123  		found := false
   124  		for i := ti; i < len(target); i++ {
   125  			if vm == target[i] {
   126  				found = true
   127  				if ti == i {
   128  					ti++
   129  				} else {
   130  					ti = i
   131  				}
   132  				break
   133  			}
   134  		}
   135  
   136  		if !found {
   137  			return false
   138  		}
   139  	}
   140  
   141  	return true
   142  }
   143  
   144  // FromInts returns an interface array with sorted elements from int array
   145  func FromInts(m []int) []interface{} {
   146  	res := make([]interface{}, len(m))
   147  	for i, v := range m {
   148  		res[i] = v
   149  	}
   150  	sort.Slice(res, func(i1, i2 int) bool {
   151  		return res[i1].(int) < res[i2].(int)
   152  	})
   153  	return res
   154  }
   155  
   156  // FromStrings returns an interface array with sorted elements from string array
   157  func FromStrings(m []string) []interface{} {
   158  	res := make([]interface{}, len(m))
   159  	for i, v := range m {
   160  		res[i] = v
   161  	}
   162  	sort.Slice(res, func(i1, i2 int) bool {
   163  		return res[i1].(string) < res[i2].(string)
   164  	})
   165  	return res
   166  }