knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/reconciler/testing/generate_name_reactor.go (about) 1 /* 2 Copyright 2019 The Knative 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 testing 18 19 import ( 20 "fmt" 21 "sync/atomic" 22 23 "k8s.io/apimachinery/pkg/api/meta" 24 "k8s.io/apimachinery/pkg/runtime" 25 clientgotesting "k8s.io/client-go/testing" 26 ) 27 28 // GenerateNameReactor will simulate the k8s API server 29 // and generate a name for resources who's metadata.generateName 30 // property is set. This happens only for CreateAction types 31 // 32 // This generator is deterministic (unliked k8s) and uses a global 33 // counter to help make test names predictable 34 type GenerateNameReactor struct { 35 count int64 36 } 37 38 // Handles contains all the logic to generate the name and mutates 39 // the create action object 40 // 41 // This is a hack as 'React' is passed a DeepCopy of the action hence 42 // this is the only opportunity to 'mutate' the action in the 43 // ReactionChain and have to continue executing additional reactors 44 // 45 // We should push changes upstream to client-go to help us with 46 // mocking 47 func (r *GenerateNameReactor) Handles(action clientgotesting.Action) bool { 48 create, ok := action.(clientgotesting.CreateAction) 49 if !ok { 50 return false 51 } 52 53 objMeta, err := meta.Accessor(create.GetObject()) 54 if err != nil { 55 return false 56 } 57 58 if objMeta.GetName() != "" { 59 return false 60 } 61 62 if objMeta.GetGenerateName() == "" { 63 return false 64 } 65 66 val := atomic.AddInt64(&r.count, 1) 67 68 objMeta.SetName(fmt.Sprintf("%s%05d", objMeta.GetGenerateName(), val)) 69 70 return false 71 } 72 73 // React is noop-function 74 func (r *GenerateNameReactor) React(action clientgotesting.Action) (handled bool, ret runtime.Object, err error) { 75 return false, nil, nil 76 } 77 78 var _ clientgotesting.Reactor = (*GenerateNameReactor)(nil) 79 80 // PrependGenerateNameReactor will instrument a client-go testing Fake 81 // with a reactor that simulates 'generateName' functionality 82 func PrependGenerateNameReactor(f *clientgotesting.Fake) { 83 f.ReactionChain = append([]clientgotesting.Reactor{&GenerateNameReactor{}}, f.ReactionChain...) 84 }