k8s.io/apiserver@v0.31.1/pkg/admission/initializer/initializer_test.go (about) 1 /* 2 Copyright 2017 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 initializer_test 18 19 import ( 20 "context" 21 "testing" 22 "time" 23 24 "k8s.io/apimachinery/pkg/api/meta" 25 "k8s.io/apimachinery/pkg/runtime/schema" 26 "k8s.io/apiserver/pkg/admission" 27 "k8s.io/apiserver/pkg/admission/initializer" 28 "k8s.io/apiserver/pkg/authorization/authorizer" 29 "k8s.io/client-go/informers" 30 "k8s.io/client-go/kubernetes" 31 "k8s.io/client-go/kubernetes/fake" 32 ) 33 34 // TestWantsAuthorizer ensures that the authorizer is injected 35 // when the WantsAuthorizer interface is implemented by a plugin. 36 func TestWantsAuthorizer(t *testing.T) { 37 target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, nil, nil) 38 wantAuthorizerAdmission := &WantAuthorizerAdmission{} 39 target.Initialize(wantAuthorizerAdmission) 40 if wantAuthorizerAdmission.auth == nil { 41 t.Errorf("expected authorizer to be initialized but found nil") 42 } 43 } 44 45 // TestWantsExternalKubeClientSet ensures that the clientset is injected 46 // when the WantsExternalKubeClientSet interface is implemented by a plugin. 47 func TestWantsExternalKubeClientSet(t *testing.T) { 48 cs := &fake.Clientset{} 49 target := initializer.New(cs, nil, nil, &TestAuthorizer{}, nil, nil, nil) 50 wantExternalKubeClientSet := &WantExternalKubeClientSet{} 51 target.Initialize(wantExternalKubeClientSet) 52 if wantExternalKubeClientSet.cs != cs { 53 t.Errorf("expected clientset to be initialized") 54 } 55 } 56 57 // TestWantsExternalKubeInformerFactory ensures that the informer factory is injected 58 // when the WantsExternalKubeInformerFactory interface is implemented by a plugin. 59 func TestWantsExternalKubeInformerFactory(t *testing.T) { 60 cs := &fake.Clientset{} 61 sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second) 62 target := initializer.New(cs, nil, sf, &TestAuthorizer{}, nil, nil, nil) 63 wantExternalKubeInformerFactory := &WantExternalKubeInformerFactory{} 64 target.Initialize(wantExternalKubeInformerFactory) 65 if wantExternalKubeInformerFactory.sf != sf { 66 t.Errorf("expected informer factory to be initialized") 67 } 68 } 69 70 // TestWantsShutdownSignal ensures that the shutdown signal is injected 71 // when the WantsShutdownSignal interface is implemented by a plugin. 72 func TestWantsShutdownNotification(t *testing.T) { 73 stopCh := make(chan struct{}) 74 target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, stopCh, nil) 75 wantDrainedNotification := &WantDrainedNotification{} 76 target.Initialize(wantDrainedNotification) 77 if wantDrainedNotification.stopCh == nil { 78 t.Errorf("expected stopCh to be initialized but found nil") 79 } 80 } 81 82 // WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface 83 type WantExternalKubeInformerFactory struct { 84 sf informers.SharedInformerFactory 85 } 86 87 func (self *WantExternalKubeInformerFactory) SetExternalKubeInformerFactory(sf informers.SharedInformerFactory) { 88 self.sf = sf 89 } 90 func (self *WantExternalKubeInformerFactory) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { 91 return nil 92 } 93 func (self *WantExternalKubeInformerFactory) Handles(o admission.Operation) bool { return false } 94 func (self *WantExternalKubeInformerFactory) ValidateInitialization() error { return nil } 95 96 var _ admission.Interface = &WantExternalKubeInformerFactory{} 97 var _ initializer.WantsExternalKubeInformerFactory = &WantExternalKubeInformerFactory{} 98 99 // WantExternalKubeClientSet is a test stub that fulfills the WantsExternalKubeClientSet interface 100 type WantExternalKubeClientSet struct { 101 cs kubernetes.Interface 102 } 103 104 func (self *WantExternalKubeClientSet) SetExternalKubeClientSet(cs kubernetes.Interface) { 105 self.cs = cs 106 } 107 func (self *WantExternalKubeClientSet) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { 108 return nil 109 } 110 func (self *WantExternalKubeClientSet) Handles(o admission.Operation) bool { return false } 111 func (self *WantExternalKubeClientSet) ValidateInitialization() error { return nil } 112 113 var _ admission.Interface = &WantExternalKubeClientSet{} 114 var _ initializer.WantsExternalKubeClientSet = &WantExternalKubeClientSet{} 115 116 // WantAuthorizerAdmission is a test stub that fulfills the WantsAuthorizer interface. 117 type WantAuthorizerAdmission struct { 118 auth authorizer.Authorizer 119 } 120 121 func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) { self.auth = a } 122 func (self *WantAuthorizerAdmission) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { 123 return nil 124 } 125 func (self *WantAuthorizerAdmission) Handles(o admission.Operation) bool { return false } 126 func (self *WantAuthorizerAdmission) ValidateInitialization() error { return nil } 127 128 var _ admission.Interface = &WantAuthorizerAdmission{} 129 var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{} 130 131 // WantDrainedNotification is a test stub that filfills the WantsDrainedNotification interface. 132 type WantDrainedNotification struct { 133 stopCh <-chan struct{} 134 } 135 136 func (self *WantDrainedNotification) SetDrainedNotification(stopCh <-chan struct{}) { 137 self.stopCh = stopCh 138 } 139 func (self *WantDrainedNotification) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { 140 return nil 141 } 142 func (self *WantDrainedNotification) Handles(o admission.Operation) bool { return false } 143 func (self *WantDrainedNotification) ValidateInitialization() error { return nil } 144 145 var _ admission.Interface = &WantDrainedNotification{} 146 var _ initializer.WantsDrainedNotification = &WantDrainedNotification{} 147 148 // TestAuthorizer is a test stub that fulfills the WantsAuthorizer interface. 149 type TestAuthorizer struct{} 150 151 func (t *TestAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { 152 return authorizer.DecisionNoOpinion, "", nil 153 } 154 155 func TestRESTMapperAdmissionPlugin(t *testing.T) { 156 initializer := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, nil, &doNothingRESTMapper{}) 157 wantsRESTMapperAdmission := &WantsRESTMapperAdmissionPlugin{} 158 initializer.Initialize(wantsRESTMapperAdmission) 159 160 if wantsRESTMapperAdmission.mapper == nil { 161 t.Errorf("Expected REST mapper to be initialized but found nil") 162 } 163 } 164 165 type WantsRESTMapperAdmissionPlugin struct { 166 doNothingAdmission 167 doNothingPluginInitialization 168 mapper meta.RESTMapper 169 } 170 171 func (p *WantsRESTMapperAdmissionPlugin) SetRESTMapper(mapper meta.RESTMapper) { 172 p.mapper = mapper 173 } 174 175 type doNothingRESTMapper struct{} 176 177 func (doNothingRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { 178 return schema.GroupVersionKind{}, nil 179 } 180 func (doNothingRESTMapper) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { 181 return nil, nil 182 } 183 func (doNothingRESTMapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) { 184 return schema.GroupVersionResource{}, nil 185 } 186 func (doNothingRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { 187 return nil, nil 188 } 189 func (doNothingRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) { 190 return nil, nil 191 } 192 func (doNothingRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*meta.RESTMapping, error) { 193 return nil, nil 194 } 195 func (doNothingRESTMapper) ResourceSingularizer(resource string) (singular string, err error) { 196 return "", nil 197 } 198 199 type doNothingAdmission struct{} 200 201 func (doNothingAdmission) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { 202 return nil 203 } 204 func (doNothingAdmission) Handles(o admission.Operation) bool { return false } 205 func (doNothingAdmission) Validate() error { return nil } 206 207 type doNothingPluginInitialization struct{} 208 209 func (doNothingPluginInitialization) ValidateInitialization() error { return nil }