watch-spring/internal/watcher_test.go

171 lines
3.3 KiB
Go
Executable File

package internal
import (
"context"
"errors"
"testing"
"time"
"github.com/fsnotify/fsnotify"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
)
var logger *logrus.Logger
type testErrorNotifier struct {
*fsnotify.Watcher
}
func (n *testErrorNotifier) NewWatcher() (*fsnotify.Watcher, error) {
return nil, errIntentional
}
var (
errNotifier = &testErrorNotifier{}
okNotifier = &Notifier{}
)
var (
mockDeploy ExecFunc
mockErrorDeploy ExecFunc
errIntentional = errors.New("intentional error")
binaryPath = ""
scriptPath = ""
executionMaxTimeout = time.Second * 2
events = []fsnotify.Event{
{
Name: "test event",
Op: fsnotify.Create,
},
{
Name: "Write",
Op: fsnotify.Write,
},
}
)
func TestMain(m *testing.M) {
logger = logrus.New()
logger.SetLevel(logrus.DebugLevel)
mockDeploy = func(executableFilePath string, args ...string) error {
return nil
}
mockErrorDeploy = func(executableFilePath string, args ...string) error {
return errIntentional
}
}
func sendTestEvents(w *Watcher) {
for _, event := range events {
w.fswatcher.Events <- event
}
}
func newWatcher() (*Watcher, error) {
return NewWatcher(logger, okNotifier, mockDeploy)
}
func newWatcherWithDeployError() (*Watcher, error) {
return NewWatcher(logger, okNotifier, mockErrorDeploy)
}
func newWatcherWithCtorError() (*Watcher, error) {
return NewWatcher(logger, errNotifier, mockDeploy)
}
func Test_NewNotifier(t *testing.T) {
require.NotNil(t, NewNotifier())
}
func Test_NewWatcher(t *testing.T) {
w, err := newWatcher()
require.NoError(t, err)
require.NotNil(t, w)
}
func Test_ErrorNewWatcher(t *testing.T) {
w, err := newWatcherWithCtorError()
require.NoError(t, err)
require.NotNil(t, w)
}
func Test_Close(t *testing.T) {
w, err := newWatcher()
require.NoError(t, err)
require.NotNil(t, w)
require.NoError(t, w.Close())
}
func Test_Monitor(t *testing.T) {
w, err := newWatcher()
require.NoError(t, err)
require.NoError(t, w.Monitor("testdata/file-to-watch.txt"))
}
func Test_ListenSuccess(t *testing.T) {
w, err := newWatcher()
require.NoError(t, err)
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, err := newWatcherWithDeployError()
require.NoError(t, err)
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, err := newWatcher()
require.NoError(t, err)
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)
errChan := make(chan error)
go w.Listen(ctx, errChan, scriptPath)
go func(cancel context.CancelFunc) {
time.Sleep(executionMaxTimeout)
cancel()
}(cancel)
sendTestEvents(w)
return ctx, errChan
}