github.com/wtsi-hgi/go-softpack-builder@v1.8.1/internal/coremock/core.go (about) 1 /******************************************************************************* 2 * Copyright (c) 2024 Genome Research Ltd. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included 13 * in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 ******************************************************************************/ 23 24 package coremock 25 26 import ( 27 "errors" 28 "io" 29 "mime/multipart" 30 "net/http" 31 "net/url" 32 "path/filepath" 33 "sync" 34 ) 35 36 // MockCore can be used to bring up a simplified core-like service that you can 37 // upload and get files from. 38 type MockCore struct { 39 mu sync.RWMutex 40 Err error 41 Files map[string]string 42 } 43 44 // NewMockCore returns a new MockCore with an empty set of Files. 45 func NewMockCore() *MockCore { 46 return &MockCore{ 47 Files: make(map[string]string), 48 } 49 } 50 51 func (m *MockCore) setFile(filename, contents string) { 52 m.mu.Lock() 53 defer m.mu.Unlock() 54 55 m.Files[filename] = contents 56 } 57 58 // GetFile thread-safe returns previously uploaded file contents by filename. 59 func (m *MockCore) GetFile(filename string) (string, bool) { 60 m.mu.RLock() 61 defer m.mu.RUnlock() 62 63 contents, ok := m.Files[filename] 64 65 return contents, ok 66 } 67 68 // ServeHTTP is to implement http.Handler so you can httptest.NewServer(m). 69 func (m *MockCore) ServeHTTP(w http.ResponseWriter, r *http.Request) { 70 if m.Err != nil { 71 http.Error(w, m.Err.Error(), http.StatusInternalServerError) 72 73 return 74 } 75 76 mr, err := r.MultipartReader() 77 if err != nil { 78 return 79 } 80 81 envPath, err := url.QueryUnescape(r.URL.RawQuery) 82 if err != nil { 83 return 84 } 85 86 m.readFileFromQuery(mr, envPath) 87 } 88 89 func (m *MockCore) readFileFromQuery(mr *multipart.Reader, envPath string) { 90 for { 91 p, err := mr.NextPart() 92 if errors.Is(err, io.EOF) { 93 break 94 } else if err != nil { 95 return 96 } 97 98 name := p.FileName() 99 100 buf, err := io.ReadAll(p) 101 if err != nil { 102 return 103 } 104 105 m.setFile(filepath.Join(envPath, name), string(buf)) 106 } 107 }