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  }