diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go index 50299bc..77e03a9 100644 --- a/internal/watcher/watcher.go +++ b/internal/watcher/watcher.go @@ -13,6 +13,11 @@ type watcher struct { deploy pkgwatcher.DeployFunc } +var ( + errEventsClosedChan = errors.New("events is closed") + errErrorsClosedChan = errors.New("errors is closed") +) + func NewWatcher(deploy pkgwatcher.DeployFunc) *watcher { wt, err := fsnotify.NewWatcher() if err != nil { @@ -36,8 +41,8 @@ func (w *watcher) Listen(binaryPath, scriptPath string, outputErr chan<- error) select { case event, ok := <-events: if !ok { - log.Printf("!ok <-events \n") - outputErr <- errors.New("!ok <-events") + log.Println(errEventsClosedChan) + outputErr <- errEventsClosedChan return } if !event.Has(fsnotify.Write) { @@ -47,14 +52,17 @@ func (w *watcher) Listen(binaryPath, scriptPath string, outputErr chan<- error) if err := w.deploy(binaryPath, scriptPath); err != nil { log.Printf("deploy: %s\n", err) + outputErr <- err continue } case err, ok := <-errChan: if !ok { - log.Printf("!ok <-errors\n") + log.Println(errErrorsClosedChan) + outputErr <- errErrorsClosedChan return } log.Printf("<-errors: %s\n", err) + outputErr <- err } } }(w.fswatcher.Events, w.fswatcher.Errors, outputErr) diff --git a/internal/watcher/watcher_test.go b/internal/watcher/watcher_test.go new file mode 100644 index 0000000..084b0b3 --- /dev/null +++ b/internal/watcher/watcher_test.go @@ -0,0 +1,136 @@ +package watcher + +import ( + "context" + "errors" + "testing" + "time" + + "gitea.urkob.com/urko/git-webhook-ci/cfg" + pkgwatcher "gitea.urkob.com/urko/git-webhook-ci/pkg/watcher" + "github.com/fsnotify/fsnotify" + "github.com/stretchr/testify/require" +) + +var ( + mockDeploy pkgwatcher.DeployFunc + mockErrorDeploy pkgwatcher.DeployFunc + errIntentional = errors.New("intentional error") + binaryPath = "" + scriptPath = "" + executionMaxTimeout = time.Second * 2 + config *cfg.Config + events = []fsnotify.Event{ + { + Name: "test event", + Op: fsnotify.Create, + }, + { + Name: "Write", + Op: fsnotify.Write, + }, + } +) + +func init() { + mockDeploy = func(binaryPath, scriptPath string) error { + return nil + } + + mockErrorDeploy = func(binaryPath, scriptPath string) error { + return errIntentional + } + + config = cfg.NewConfig(false) +} + +func sendTestEvents(w *watcher) { + for _, event := range events { + w.fswatcher.Events <- event + } +} + +func getNewWatcher() *watcher { + return NewWatcher(mockDeploy) +} + +func getNewWatcherWithError() *watcher { + return NewWatcher(mockErrorDeploy) +} + +func Test_NewWatcher(t *testing.T) { + w := getNewWatcher() + require.NotNil(t, w) +} + +func Test_Close(t *testing.T) { + w := getNewWatcher() + err := w.Close() + require.NoError(t, err) +} + +func Test_Monitor(t *testing.T) { + w := getNewWatcher() + err := w.Monitor(config.TestFileToWatchPath) + require.NoError(t, err) +} + +func Test_ListenSuccess(t *testing.T) { + w := getNewWatcher() + ctx, errors := listenWithSendEvents(w) + + for { + select { + case <-ctx.Done(): + return + case err := <-errors: + require.NoError(t, err) + return + } + } +} + +func Test_ListenError(t *testing.T) { + w := getNewWatcherWithError() + ctx, errors := listenWithSendEvents(w) + + for { + select { + case <-ctx.Done(): + return + case err := <-errors: + require.Error(t, err) + require.EqualError(t, err, errIntentional.Error()) + return + } + } +} + +func Test_ListenErrorChanClose(t *testing.T) { + w := getNewWatcher() + ctx, errors := listenWithSendEvents(w) + close(w.fswatcher.Events) + for { + select { + case <-ctx.Done(): + return + case err := <-errors: + require.Error(t, err) + require.EqualError(t, err, errEventsClosedChan.Error()) + return + } + } +} + +func listenWithSendEvents(w *watcher) (context.Context, chan error) { + ctx, cancel := context.WithTimeout(context.Background(), executionMaxTimeout) + errors := make(chan error) + w.Listen(binaryPath, scriptPath, errors) + go func(cancel context.CancelFunc) { + time.Sleep(executionMaxTimeout) + cancel() + }(cancel) + + sendTestEvents(w) + return ctx, errors +}