sigs.k8s.io/controller-runtime@v0.18.2/pkg/cluster/cluster_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 cluster 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "net/http" 24 25 "github.com/go-logr/logr" 26 . "github.com/onsi/ginkgo/v2" 27 . "github.com/onsi/gomega" 28 "go.uber.org/goleak" 29 "k8s.io/apimachinery/pkg/api/meta" 30 "k8s.io/apimachinery/pkg/runtime" 31 "k8s.io/client-go/rest" 32 "sigs.k8s.io/controller-runtime/pkg/cache" 33 "sigs.k8s.io/controller-runtime/pkg/client" 34 intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" 35 ) 36 37 var _ = Describe("cluster.Cluster", func() { 38 Describe("New", func() { 39 It("should return an error if there is no Config", func() { 40 c, err := New(nil) 41 Expect(c).To(BeNil()) 42 Expect(err.Error()).To(ContainSubstring("must specify Config")) 43 44 }) 45 46 It("should return an error if it can't create a RestMapper", func() { 47 expected := fmt.Errorf("expected error: RestMapper") 48 c, err := New(cfg, func(o *Options) { 49 o.MapperProvider = func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) { return nil, expected } 50 }) 51 Expect(c).To(BeNil()) 52 Expect(err).To(Equal(expected)) 53 54 }) 55 56 It("should return an error it can't create a client.Client", func() { 57 c, err := New(cfg, func(o *Options) { 58 o.NewClient = func(config *rest.Config, options client.Options) (client.Client, error) { 59 return nil, errors.New("expected error") 60 } 61 }) 62 Expect(c).To(BeNil()) 63 Expect(err).To(HaveOccurred()) 64 Expect(err.Error()).To(ContainSubstring("expected error")) 65 }) 66 67 It("should return an error it can't create a cache.Cache", func() { 68 c, err := New(cfg, func(o *Options) { 69 o.NewCache = func(config *rest.Config, opts cache.Options) (cache.Cache, error) { 70 return nil, fmt.Errorf("expected error") 71 } 72 }) 73 Expect(c).To(BeNil()) 74 Expect(err).To(HaveOccurred()) 75 Expect(err.Error()).To(ContainSubstring("expected error")) 76 }) 77 78 It("should create a client defined in by the new client function", func() { 79 c, err := New(cfg, func(o *Options) { 80 o.NewClient = func(config *rest.Config, options client.Options) (client.Client, error) { 81 return nil, nil 82 } 83 }) 84 Expect(c).ToNot(BeNil()) 85 Expect(err).ToNot(HaveOccurred()) 86 Expect(c.GetClient()).To(BeNil()) 87 }) 88 89 It("should return an error it can't create a recorder.Provider", func() { 90 c, err := New(cfg, func(o *Options) { 91 o.newRecorderProvider = func(_ *rest.Config, _ *http.Client, _ *runtime.Scheme, _ logr.Logger, _ intrec.EventBroadcasterProducer) (*intrec.Provider, error) { 92 return nil, fmt.Errorf("expected error") 93 } 94 }) 95 Expect(c).To(BeNil()) 96 Expect(err).To(HaveOccurred()) 97 Expect(err.Error()).To(ContainSubstring("expected error")) 98 }) 99 100 }) 101 102 Describe("Start", func() { 103 It("should stop when context is cancelled", func() { 104 c, err := New(cfg) 105 Expect(err).NotTo(HaveOccurred()) 106 ctx, cancel := context.WithCancel(context.Background()) 107 cancel() 108 Expect(c.Start(ctx)).NotTo(HaveOccurred()) 109 }) 110 }) 111 112 It("should not leak goroutines when stopped", func() { 113 currentGRs := goleak.IgnoreCurrent() 114 115 c, err := New(cfg) 116 Expect(err).NotTo(HaveOccurred()) 117 118 ctx, cancel := context.WithCancel(context.Background()) 119 cancel() 120 Expect(c.Start(ctx)).NotTo(HaveOccurred()) 121 122 // force-close keep-alive connections. These'll time anyway (after 123 // like 30s or so) but force it to speed up the tests. 124 clientTransport.CloseIdleConnections() 125 Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed()) 126 }) 127 128 It("should provide a function to get the Config", func() { 129 c, err := New(cfg) 130 Expect(err).NotTo(HaveOccurred()) 131 cluster, ok := c.(*cluster) 132 Expect(ok).To(BeTrue()) 133 Expect(c.GetConfig()).To(Equal(cluster.config)) 134 }) 135 136 It("should provide a function to get the Client", func() { 137 c, err := New(cfg) 138 Expect(err).NotTo(HaveOccurred()) 139 cluster, ok := c.(*cluster) 140 Expect(ok).To(BeTrue()) 141 Expect(c.GetClient()).To(Equal(cluster.client)) 142 }) 143 144 It("should provide a function to get the Scheme", func() { 145 c, err := New(cfg) 146 Expect(err).NotTo(HaveOccurred()) 147 cluster, ok := c.(*cluster) 148 Expect(ok).To(BeTrue()) 149 Expect(c.GetScheme()).To(Equal(cluster.scheme)) 150 }) 151 152 It("should provide a function to get the FieldIndexer", func() { 153 c, err := New(cfg) 154 Expect(err).NotTo(HaveOccurred()) 155 cluster, ok := c.(*cluster) 156 Expect(ok).To(BeTrue()) 157 Expect(c.GetFieldIndexer()).To(Equal(cluster.cache)) 158 }) 159 160 It("should provide a function to get the EventRecorder", func() { 161 c, err := New(cfg) 162 Expect(err).NotTo(HaveOccurred()) 163 Expect(c.GetEventRecorderFor("test")).NotTo(BeNil()) 164 }) 165 It("should provide a function to get the APIReader", func() { 166 c, err := New(cfg) 167 Expect(err).NotTo(HaveOccurred()) 168 Expect(c.GetAPIReader()).NotTo(BeNil()) 169 }) 170 })