From 78b78b99b6a43dec93b5e7bdd197b16df5719703 Mon Sep 17 00:00:00 2001 From: Marc Carmier Date: Fri, 3 Sep 2021 22:40:04 +0200 Subject: [PATCH] Add CLI option -mocks-directory to automatically load mocks from files in a folder at startup --- main.go | 1 + server/admin_server.go | 9 ++++++ server/config/config.go | 1 + server/services/mocks.go | 61 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/main.go b/main.go index d66eb4b..366207d 100644 --- a/main.go +++ b/main.go @@ -31,6 +31,7 @@ func parseConfig() (c config.Config) { flag.StringVar(&c.StaticFiles, "static-files", ".", "The location of the static files to serve (index.html, etc.)") flag.IntVar(&c.HistoryMaxRetention, "history-retention", 0, "The maximum number of calls to keep in the history by sessions (0 = infinity)") flag.StringVar(&c.PersistenceDirectory, "persistence-directory", "", "If defined, the directory where the sessions will be synchronized") + flag.StringVar(&c.MocksDirectory, "mocks-directory", "", "If defined, the directory use to load the mocks at server start") flag.Parse() return } diff --git a/server/admin_server.go b/server/admin_server.go index aefafb3..11b3726 100644 --- a/server/admin_server.go +++ b/server/admin_server.go @@ -35,6 +35,15 @@ func Serve(config config.Config) { adminServerEngine.Use(recoverMiddleware(), loggerMiddleware(), middleware.Gzip()) mockServerEngine, mockServices := NewMockServer(config) + + // Autoload mocks at start + if config.MocksDirectory != "" { + log.WithField("port", config.ConfigListenPort).Infof("Loading mocks from %s", config.MocksDirectory) + if err := mockServices.Load(config.MocksDirectory); err != nil { + log.WithField("port", config.ConfigListenPort).Fatal(err) + } + } + graphServices := services.NewGraph() handler := handlers.NewAdmin(mockServices, graphServices) diff --git a/server/config/config.go b/server/config/config.go index 845bb5e..03f185d 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -8,6 +8,7 @@ type Config struct { StaticFiles string HistoryMaxRetention int PersistenceDirectory string + MocksDirectory string Build Build } diff --git a/server/services/mocks.go b/server/services/mocks.go index ef4e473..842639d 100644 --- a/server/services/mocks.go +++ b/server/services/mocks.go @@ -1,7 +1,10 @@ package services import ( + "encoding/json" "fmt" + "io/ioutil" + "path/filepath" "regexp" "strings" "sync" @@ -9,6 +12,7 @@ import ( "github.com/Thiht/smocker/server/types" "github.com/teris-io/shortid" + "gopkg.in/yaml.v3" ) var ( @@ -32,6 +36,7 @@ type Mocks interface { GetSessions() types.Sessions SetSessions(sessions types.Sessions) Reset(force bool) + Load(path string) error } type mocks struct { @@ -315,3 +320,59 @@ func (s *mocks) Reset(force bool) { go s.persistence.StoreSessions(s.sessions.Clone()) } + +func (s *mocks) Load(path string) error { + mockslist := make(map[string][]types.Mock) + + files, err := ioutil.ReadDir(path) + if err != nil { + return fmt.Errorf("unable to find mocks files: %w ", err) + } + + for _, file := range files { + ext := filepath.Ext(file.Name()) + + if ext != ".yml" && ext != ".yaml" && ext != ".json" { + continue + } + + content, err := ioutil.ReadFile(filepath.Join(path, file.Name())) + if err != nil { + return fmt.Errorf("unable to read mock file %s: %w ", file.Name(), err) + } + + var Ms []types.Mock + + switch ext { + case ".yml", ".yaml": + err = yaml.Unmarshal(content, &Ms) + case ".json": + err = json.Unmarshal(content, &Ms) + } + + if err != nil { + return fmt.Errorf("unable to parse mock file %s: %w ", file.Name(), err) + } + + for _, mock := range Ms { + if err = mock.Validate(); err != nil { + return fmt.Errorf("unvalid mock file %s: %w ", file.Name(), err) + } + } + + mockslist[file.Name()] = Ms + } + + sessionID := s.GetLastSession().ID + + for fileName, mocks := range mockslist { + for _, mock := range mocks { + m := mock + if _, err = s.AddMock(sessionID, &m); err != nil { + return fmt.Errorf("unable to add mock file %s: %w ", fileName, err) + } + } + } + + return nil +}