sigs.k8s.io/cluster-api@v1.7.1/internal/controllers/machine/suite_test.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes 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 machine
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"os"
    23  	"testing"
    24  	"time"
    25  
    26  	. "github.com/onsi/gomega"
    27  	"github.com/onsi/gomega/types"
    28  	"github.com/pkg/errors"
    29  	corev1 "k8s.io/api/core/v1"
    30  	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    31  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    32  	"k8s.io/apimachinery/pkg/runtime"
    33  	"k8s.io/apimachinery/pkg/runtime/schema"
    34  	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    35  	ctrl "sigs.k8s.io/controller-runtime"
    36  	"sigs.k8s.io/controller-runtime/pkg/client"
    37  	"sigs.k8s.io/controller-runtime/pkg/controller"
    38  
    39  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    40  	"sigs.k8s.io/cluster-api/api/v1beta1/index"
    41  	"sigs.k8s.io/cluster-api/controllers/remote"
    42  	"sigs.k8s.io/cluster-api/internal/test/envtest"
    43  )
    44  
    45  const (
    46  	timeout = time.Second * 30
    47  )
    48  
    49  var (
    50  	env        *envtest.Environment
    51  	ctx        = ctrl.SetupSignalHandler()
    52  	fakeScheme = runtime.NewScheme()
    53  )
    54  
    55  func init() {
    56  	_ = clientgoscheme.AddToScheme(fakeScheme)
    57  	_ = clusterv1.AddToScheme(fakeScheme)
    58  	_ = apiextensionsv1.AddToScheme(fakeScheme)
    59  	_ = corev1.AddToScheme(fakeScheme)
    60  }
    61  
    62  func TestMain(m *testing.M) {
    63  	setupIndexes := func(ctx context.Context, mgr ctrl.Manager) {
    64  		if err := index.AddDefaultIndexes(ctx, mgr); err != nil {
    65  			panic(fmt.Sprintf("unable to setup index: %v", err))
    66  		}
    67  	}
    68  
    69  	setupReconcilers := func(ctx context.Context, mgr ctrl.Manager) {
    70  		// Set up a ClusterCacheTracker and ClusterCacheReconciler to provide to controllers
    71  		// requiring a connection to a remote cluster
    72  		tracker, err := remote.NewClusterCacheTracker(
    73  			mgr,
    74  			remote.ClusterCacheTrackerOptions{
    75  				Log:     &ctrl.Log,
    76  				Indexes: []remote.Index{remote.NodeProviderIDIndex},
    77  			},
    78  		)
    79  		if err != nil {
    80  			panic(fmt.Sprintf("unable to create cluster cache tracker: %v", err))
    81  		}
    82  		if err := (&remote.ClusterCacheReconciler{
    83  			Client:  mgr.GetClient(),
    84  			Tracker: tracker,
    85  		}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: 1}); err != nil {
    86  			panic(fmt.Sprintf("Failed to start ClusterCacheReconciler: %v", err))
    87  		}
    88  
    89  		unstructuredCachingClient, err := client.New(mgr.GetConfig(), client.Options{
    90  			HTTPClient: mgr.GetHTTPClient(),
    91  			Cache: &client.CacheOptions{
    92  				Reader:       mgr.GetCache(),
    93  				Unstructured: true,
    94  			},
    95  		})
    96  		if err != nil {
    97  			panic(fmt.Sprintf("unable to create unstructuredCachineClient: %v", err))
    98  		}
    99  
   100  		if err := (&Reconciler{
   101  			Client:                    mgr.GetClient(),
   102  			UnstructuredCachingClient: unstructuredCachingClient,
   103  			APIReader:                 mgr.GetAPIReader(),
   104  			Tracker:                   tracker,
   105  		}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: 1}); err != nil {
   106  			panic(fmt.Sprintf("Failed to start MachineReconciler: %v", err))
   107  		}
   108  	}
   109  
   110  	SetDefaultEventuallyPollingInterval(100 * time.Millisecond)
   111  	SetDefaultEventuallyTimeout(timeout)
   112  
   113  	os.Exit(envtest.Run(ctx, envtest.RunInput{
   114  		M:                m,
   115  		SetupEnv:         func(e *envtest.Environment) { env = e },
   116  		SetupIndexes:     setupIndexes,
   117  		SetupReconcilers: setupReconcilers,
   118  	}))
   119  }
   120  
   121  func ContainRefOfGroupKind(group, kind string) types.GomegaMatcher {
   122  	return &refGroupKindMatcher{
   123  		kind:  kind,
   124  		group: group,
   125  	}
   126  }
   127  
   128  type refGroupKindMatcher struct {
   129  	kind  string
   130  	group string
   131  }
   132  
   133  func (matcher *refGroupKindMatcher) Match(actual interface{}) (success bool, err error) {
   134  	ownerRefs, ok := actual.([]metav1.OwnerReference)
   135  	if !ok {
   136  		return false, errors.Errorf("expected []metav1.OwnerReference; got %T", actual)
   137  	}
   138  
   139  	for _, ref := range ownerRefs {
   140  		gv, err := schema.ParseGroupVersion(ref.APIVersion)
   141  		if err != nil {
   142  			return false, nil //nolint:nilerr // If we can't get the group version we can't match, but it's not a failure
   143  		}
   144  		if ref.Kind == matcher.kind && gv.Group == clusterv1.GroupVersion.Group {
   145  			return true, nil
   146  		}
   147  	}
   148  
   149  	return false, nil
   150  }
   151  
   152  func (matcher *refGroupKindMatcher) FailureMessage(actual interface{}) (message string) {
   153  	return fmt.Sprintf("Expected %+v to contain refs of Group %s and Kind %s", actual, matcher.group, matcher.kind)
   154  }
   155  
   156  func (matcher *refGroupKindMatcher) NegatedFailureMessage(actual interface{}) (message string) {
   157  	return fmt.Sprintf("Expected %+v not to contain refs of Group %s and Kind %s", actual, matcher.group, matcher.kind)
   158  }