sigs.k8s.io/cluster-api@v1.6.3/controllers/remote/cluster_cache_reconciler_test.go (about) 1 /* 2 Copyright 2020 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 remote 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 24 . "github.com/onsi/gomega" 25 corev1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/client-go/kubernetes/scheme" 28 "sigs.k8s.io/controller-runtime/pkg/client" 29 "sigs.k8s.io/controller-runtime/pkg/controller" 30 "sigs.k8s.io/controller-runtime/pkg/manager" 31 metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" 32 33 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 34 "sigs.k8s.io/cluster-api/util" 35 ) 36 37 func TestClusterCacheReconciler(t *testing.T) { 38 t.Run("When running the ClusterCacheReconciler", func(t *testing.T) { 39 var ( 40 mgr manager.Manager 41 mgrContext context.Context 42 mgrCancel context.CancelFunc 43 cct *ClusterCacheTracker 44 k8sClient client.Client 45 ) 46 47 // createAndWatchCluster creates a new cluster and ensures the clusterCacheTracker has a clusterAccessor for it 48 createAndWatchCluster := func(clusterName string, testNamespace *corev1.Namespace, g *WithT) { 49 t.Logf("Creating a cluster %q", clusterName) 50 testCluster := &clusterv1.Cluster{ 51 ObjectMeta: metav1.ObjectMeta{ 52 Name: clusterName, 53 Namespace: testNamespace.GetName(), 54 }, 55 } 56 g.Expect(k8sClient.Create(ctx, testCluster)).To(Succeed()) 57 58 // Check the cluster can be fetched from the API server 59 testClusterKey := util.ObjectKey(testCluster) 60 g.Eventually(func() error { 61 return k8sClient.Get(ctx, testClusterKey, &clusterv1.Cluster{}) 62 }, timeout).Should(Succeed()) 63 64 t.Log("Creating a test cluster kubeconfig") 65 g.Expect(env.CreateKubeconfigSecret(ctx, testCluster)).To(Succeed()) 66 67 // Check the secret can be fetched from the API server 68 secretKey := client.ObjectKey{Namespace: testNamespace.GetName(), Name: fmt.Sprintf("%s-kubeconfig", testCluster.GetName())} 69 g.Eventually(func() error { 70 return k8sClient.Get(ctx, secretKey, &corev1.Secret{}) 71 }, timeout).Should(Succeed()) 72 73 t.Log("Creating a clusterAccessor for the cluster") 74 _, err := cct.GetClient(ctx, testClusterKey) 75 g.Expect(err).ToNot(HaveOccurred()) 76 } 77 78 setup := func(t *testing.T, g *WithT) *corev1.Namespace { 79 t.Helper() 80 81 t.Log("Setting up a new manager") 82 var err error 83 mgr, err = manager.New(env.Config, manager.Options{ 84 Scheme: scheme.Scheme, 85 Metrics: metricsserver.Options{ 86 BindAddress: "0", 87 }, 88 }) 89 g.Expect(err).ToNot(HaveOccurred()) 90 91 t.Log("Setting up a ClusterCacheTracker") 92 cct, err = NewClusterCacheTracker(mgr, ClusterCacheTrackerOptions{}) 93 g.Expect(err).ToNot(HaveOccurred()) 94 95 t.Log("Creating the ClusterCacheReconciler") 96 r := &ClusterCacheReconciler{ 97 Client: mgr.GetClient(), 98 Tracker: cct, 99 } 100 g.Expect(r.SetupWithManager(ctx, mgr, controller.Options{})).To(Succeed()) 101 102 t.Log("Starting the manager") 103 mgrContext, mgrCancel = context.WithCancel(ctx) 104 go func() { 105 g.Expect(mgr.Start(mgrContext)).To(Succeed()) 106 }() 107 <-env.Manager.Elected() 108 109 k8sClient = mgr.GetClient() 110 111 t.Log("Creating a namespace for the test") 112 ns, err := env.CreateNamespace(ctx, "cluster-cache-test") 113 g.Expect(err).ToNot(HaveOccurred()) 114 115 t.Log("Creating clusters to test with") 116 createAndWatchCluster("cluster-1", ns, g) 117 createAndWatchCluster("cluster-2", ns, g) 118 createAndWatchCluster("cluster-3", ns, g) 119 120 return ns 121 } 122 123 teardown := func(t *testing.T, g *WithT, ns *corev1.Namespace) { 124 t.Helper() 125 126 t.Log("Deleting any Secrets") 127 g.Expect(cleanupTestSecrets(ctx, k8sClient)).To(Succeed()) 128 t.Log("Deleting any Clusters") 129 g.Expect(cleanupTestClusters(ctx, k8sClient)).To(Succeed()) 130 t.Log("Deleting Namespace") 131 g.Expect(env.Delete(ctx, ns)).To(Succeed()) 132 t.Log("Stopping the manager") 133 mgrCancel() 134 } 135 136 t.Run("should remove clusterAccessors when clusters are deleted", func(t *testing.T) { 137 g := NewWithT(t) 138 testNamespace := setup(t, g) 139 defer teardown(t, g, testNamespace) 140 141 for _, clusterName := range []string{"cluster-1", "cluster-2", "cluster-3"} { 142 t.Logf("Deleting cluster %q", clusterName) 143 obj := &clusterv1.Cluster{ 144 ObjectMeta: metav1.ObjectMeta{ 145 Namespace: testNamespace.Name, 146 Name: clusterName, 147 }, 148 } 149 g.Expect(k8sClient.Delete(ctx, obj)).To(Succeed()) 150 151 t.Logf("Checking cluster %q's clusterAccessor is removed", clusterName) 152 g.Eventually(func() bool { return cct.clusterAccessorExists(util.ObjectKey(obj)) }, timeout).Should(BeFalse()) 153 } 154 }) 155 }) 156 }