k8s.io/apiserver@v0.31.1/pkg/endpoints/discovery/aggregated/fake.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 aggregated 18 19 import ( 20 "context" 21 "errors" 22 "net/http" 23 "reflect" 24 "sync" 25 "time" 26 27 "github.com/emicklei/go-restful/v3" 28 "github.com/google/go-cmp/cmp" 29 apidiscoveryv2 "k8s.io/api/apidiscovery/v2" 30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 "k8s.io/apimachinery/pkg/util/wait" 32 ) 33 34 type FakeResourceManager interface { 35 ResourceManager 36 Expect() ResourceManager 37 38 HasExpectedNumberActions() bool 39 Validate() error 40 WaitForActions(ctx context.Context, timeout time.Duration) error 41 } 42 43 func NewFakeResourceManager() FakeResourceManager { 44 return &fakeResourceManager{} 45 } 46 47 // a resource manager with helper functions for checking the actions 48 // match expected. For Use in tests 49 type fakeResourceManager struct { 50 recorderResourceManager 51 expect recorderResourceManager 52 } 53 54 // a resource manager which instead of managing a discovery document, 55 // simply records the calls to its interface functoins for testing 56 type recorderResourceManager struct { 57 lock sync.RWMutex 58 Actions []recorderResourceManagerAction 59 } 60 61 var _ ResourceManager = &fakeResourceManager{} 62 var _ ResourceManager = &recorderResourceManager{} 63 64 // Storage type for a call to the resource manager 65 type recorderResourceManagerAction struct { 66 Type string 67 Group string 68 Version string 69 Value interface{} 70 } 71 72 func (f *fakeResourceManager) Expect() ResourceManager { 73 return &f.expect 74 } 75 76 func (f *fakeResourceManager) HasExpectedNumberActions() bool { 77 f.lock.RLock() 78 defer f.lock.RUnlock() 79 80 f.expect.lock.RLock() 81 defer f.expect.lock.RUnlock() 82 83 return len(f.Actions) >= len(f.expect.Actions) 84 } 85 86 func (f *fakeResourceManager) Validate() error { 87 f.lock.RLock() 88 defer f.lock.RUnlock() 89 90 f.expect.lock.RLock() 91 defer f.expect.lock.RUnlock() 92 93 if !reflect.DeepEqual(f.expect.Actions, f.Actions) { 94 return errors.New(cmp.Diff(f.expect.Actions, f.Actions)) 95 } 96 return nil 97 } 98 99 func (f *fakeResourceManager) WaitForActions(ctx context.Context, timeout time.Duration) error { 100 err := wait.PollImmediateWithContext( 101 ctx, 102 100*time.Millisecond, // try every 100ms 103 timeout, // timeout after timeout 104 func(ctx context.Context) (done bool, err error) { 105 if f.HasExpectedNumberActions() { 106 return true, f.Validate() 107 } 108 return false, nil 109 }) 110 return err 111 } 112 113 func (f *recorderResourceManager) SetGroupVersionPriority(gv metav1.GroupVersion, grouppriority, versionpriority int) { 114 f.lock.Lock() 115 defer f.lock.Unlock() 116 117 f.Actions = append(f.Actions, recorderResourceManagerAction{ 118 Type: "SetGroupVersionPriority", 119 Group: gv.Group, 120 Version: gv.Version, 121 Value: versionpriority, 122 }) 123 } 124 125 func (f *recorderResourceManager) AddGroupVersion(groupName string, value apidiscoveryv2.APIVersionDiscovery) { 126 f.lock.Lock() 127 defer f.lock.Unlock() 128 129 f.Actions = append(f.Actions, recorderResourceManagerAction{ 130 Type: "AddGroupVersion", 131 Group: groupName, 132 Value: value, 133 }) 134 } 135 func (f *recorderResourceManager) RemoveGroup(groupName string) { 136 f.lock.Lock() 137 defer f.lock.Unlock() 138 139 f.Actions = append(f.Actions, recorderResourceManagerAction{ 140 Type: "RemoveGroup", 141 Group: groupName, 142 }) 143 144 } 145 func (f *recorderResourceManager) RemoveGroupVersion(gv metav1.GroupVersion) { 146 f.lock.Lock() 147 defer f.lock.Unlock() 148 149 f.Actions = append(f.Actions, recorderResourceManagerAction{ 150 Type: "RemoveGroupVersion", 151 Group: gv.Group, 152 Version: gv.Version, 153 }) 154 155 } 156 func (f *recorderResourceManager) SetGroups(values []apidiscoveryv2.APIGroupDiscovery) { 157 f.lock.Lock() 158 defer f.lock.Unlock() 159 160 f.Actions = append(f.Actions, recorderResourceManagerAction{ 161 Type: "SetGroups", 162 Value: values, 163 }) 164 } 165 func (f *recorderResourceManager) WebService() *restful.WebService { 166 panic("unimplemented") 167 } 168 169 func (f *recorderResourceManager) ServeHTTP(http.ResponseWriter, *http.Request) { 170 panic("unimplemented") 171 } 172 173 func (f *recorderResourceManager) WithSource(source Source) ResourceManager { 174 panic("unimplemented") 175 }