github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/io/fakeopener/fakeopener.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 fakeopener 18 19 import ( 20 "bytes" 21 "context" 22 "os" 23 24 pkgio "sigs.k8s.io/prow/pkg/io" 25 ) 26 27 type FakeOpener struct { 28 pkgio.Opener 29 Buffer map[string]*bytes.Buffer 30 ReadError error 31 WriteError error 32 } 33 34 type nopReadWriteCloser struct { 35 *bytes.Buffer 36 } 37 38 func (nc *nopReadWriteCloser) Close() error { 39 return nil 40 } 41 42 func (fo *FakeOpener) Reader(ctx context.Context, path string) (pkgio.ReadCloser, error) { 43 if fo.ReadError != nil { 44 return nil, fo.ReadError 45 } 46 if fo.Buffer == nil { 47 fo.Buffer = make(map[string]*bytes.Buffer) 48 } 49 if _, ok := fo.Buffer[path]; !ok { 50 return nil, os.ErrNotExist 51 } 52 // The underlying Buffer contains a private `off(set)` field, which will 53 // move to the end of the buffer after one read, and there is no way to 54 // reset the `off(set)`. So create a new Buffer from the content, to make 55 // this Buffer readable repeatedly. 56 newBuf := bytes.NewBuffer(fo.Buffer[path].Bytes()) 57 return &nopReadWriteCloser{Buffer: newBuf}, nil 58 } 59 60 func (fo *FakeOpener) Writer(ctx context.Context, path string, opts ...pkgio.WriterOptions) (pkgio.WriteCloser, error) { 61 if fo.WriteError != nil { 62 return nil, fo.WriteError 63 } 64 if fo.Buffer == nil { 65 fo.Buffer = make(map[string]*bytes.Buffer) 66 } 67 68 overWrite := true 69 for _, o := range opts { 70 if o.PreconditionDoesNotExist != nil && *o.PreconditionDoesNotExist { 71 overWrite = false 72 break 73 } 74 } 75 if fo.Buffer[path] != nil { 76 if !overWrite { 77 return nil, os.ErrExist 78 } 79 fo.Buffer[path] = &bytes.Buffer{} 80 } 81 82 if _, ok := fo.Buffer[path]; !ok { 83 fo.Buffer[path] = &bytes.Buffer{} 84 } 85 86 return &nopReadWriteCloser{Buffer: fo.Buffer[path]}, nil 87 }