add tests for main pspy methods

This commit is contained in:
Dominic Breuker
2018-03-15 09:22:22 +01:00
parent 6739870f4d
commit 9b43b8fe9d
2 changed files with 131 additions and 119 deletions

View File

@@ -33,7 +33,7 @@ func Start(cfg *config.Config, b *Bindings, sigCh chan os.Signal) chan struct{}
b.Logger.Infof("Config: %+v\n", cfg) b.Logger.Infof("Config: %+v\n", cfg)
initFSW(b.FSW, cfg.RDirs, cfg.Dirs, b.Logger) initFSW(b.FSW, cfg.RDirs, cfg.Dirs, b.Logger)
triggerCh, fsEventCh := startFSW(b.FSW, b.Logger) triggerCh, fsEventCh := startFSW(b.FSW, b.Logger, 1*time.Second)
psEventCh := startPSS(b.PSS, b.Logger, triggerCh) psEventCh := startPSS(b.PSS, b.Logger, triggerCh)
@@ -77,13 +77,13 @@ func initFSW(fsw FSWatcher, rdirs, dirs []string, logger Logger) {
} }
} }
func startFSW(fsw FSWatcher, logger Logger) (triggerCh chan struct{}, fsEventCh chan string) { func startFSW(fsw FSWatcher, logger Logger, drainFor time.Duration) (triggerCh chan struct{}, fsEventCh chan string) {
triggerCh, fsEventCh, errCh := fsw.Run() triggerCh, fsEventCh, errCh := fsw.Run()
go logErrors(errCh, logger) go logErrors(errCh, logger)
// ignore all file system events created on startup // ignore all file system events created on startup
logger.Infof("Draining file system events due to startup...") logger.Infof("Draining file system events due to startup...")
drainEventsFor(triggerCh, fsEventCh, 1*time.Second) drainEventsFor(triggerCh, fsEventCh, drainFor)
logger.Infof("done") logger.Infof("done")
return triggerCh, fsEventCh return triggerCh, fsEventCh
} }
@@ -106,7 +106,7 @@ func triggerEvery(d time.Duration, triggerCh chan struct{}) {
func logErrors(errCh chan error, logger Logger) { func logErrors(errCh chan error, logger Logger) {
for { for {
err := <-errCh err := <-errCh
logger.Errorf("ERROR: %v\n", err) logger.Errorf("ERROR: %v", err)
} }
} }

View File

@@ -1,140 +1,152 @@
package pspy package pspy
// import ( import (
// "fmt" "errors"
// "os" "fmt"
// "syscall" "testing"
// "testing" "time"
// "time" )
// "github.com/dominicbreuker/pspy/internal/config" func TestInitFSW(t *testing.T) {
// ) l := newMockLogger()
fsw := newMockFSWatcher()
rdirs := make([]string, 0)
dirs := make([]string, 0)
go func() {
fsw.initErrCh <- errors.New("error1")
fsw.initErrCh <- errors.New("error2")
close(fsw.initDoneCh)
}()
// func TestStart(t *testing.T) { initFSW(fsw, rdirs, dirs, l)
// cfg := config.Config{
// RDirs: []string{"rdir"},
// Dirs: []string{"dir"},
// LogFS: true,
// LogPS: true,
// }
// mockLogger := newMockLogger()
// mockIW := newMockFSWatcher()
// mockPS := newMockProcfsScanner(nil)
// sigCh := make(chan os.Signal)
// exit, err := Init(cfg, mockLogger, mockIW, mockPS, sigCh) expectMessage(t, l.Error, "initializing fs watcher: error1")
// if err != nil { expectMessage(t, l.Error, "initializing fs watcher: error2")
// t.Fatalf("Unexpcted error: %v", err) expectClosed(t, fsw.initDoneCh)
// } }
// mockIW.fsEventCh <- "some fs event"
// expectMsg(t, mockLogger.Event, "FS: some fs event\n")
// mockPS.psEventCh <- "some ps event" // very flaky test... refactor code!
// expectMsg(t, mockLogger.Event, "CMD: some ps event\n") func TestStartFSW(t *testing.T) {
l := newMockLogger()
fsw := newMockFSWatcher()
drainFor := 100 * time.Millisecond
// sigCh <- syscall.SIGINT go func() {
// expectExit(t, exit) fsw.runTriggerCh <- struct{}{} // trigger sent while draining
// } fsw.runEventCh <- "event sent while draining"
fsw.runErrCh <- errors.New("error sent while draining")
<-time.After(drainFor) // ensure draining is over
fsw.runTriggerCh <- struct{}{}
fsw.runEventCh <- "event sent after draining"
fsw.runErrCh <- errors.New("error sent after draining")
}()
// func expectMsg(t *testing.T, ch chan string, msg string) { // sends no events and triggers from the drain phase
// select { triggerCh, fsEventCh := startFSW(fsw, l, drainFor)
// case received := <-ch: expectMessage(t, l.Info, "Draining file system events due to startup...")
// if received != msg { expectMessage(t, l.Error, "ERROR: error sent while draining")
// t.Fatalf("Wanted to receive %s but got %s", msg, received) expectMessage(t, l.Info, "done")
// } expectTrigger(t, triggerCh)
// case <-time.After(500 * time.Millisecond): expectMessage(t, fsEventCh, "event sent after draining")
// t.Fatalf("Did not receive message in time. Wanted: %s", msg) }
// }
// }
// func expectExit(t *testing.T, ch chan struct{}) { // #### Helpers ####
// select {
// case <-ch:
// return
// case <-time.After(500 * time.Millisecond):
// t.Fatalf("Did not receive exit signal in time")
// }
// }
// // ##### Mocks ##### var timeout = 100 * time.Millisecond
var errTimeout = errors.New("timeout")
// // Logger func expectMessage(t *testing.T, ch chan string, expected string) {
select {
case actual := <-ch:
if actual != expected {
t.Fatalf("Wrong message: got '%s' but wanted %s", actual, expected)
}
case <-time.After(timeout):
t.Fatalf("Did not get message in time: %s", expected)
}
}
// type mockLogger struct { func expectTrigger(t *testing.T, ch chan struct{}) {
// Info chan string select {
// Error chan string case <-ch:
// Event chan string return
// } case <-time.After(timeout):
t.Fatalf("Did not get trigger in time")
}
}
// func newMockLogger() *mockLogger { func expectClosed(t *testing.T, ch chan struct{}) {
// return &mockLogger{ select {
// Info: make(chan string, 10), case _, ok := <-ch:
// Error: make(chan string, 10), if ok {
// Event: make(chan string, 10), t.Fatalf("Channel not closed: got ok=%t", ok)
// } }
// } case <-time.After(timeout):
t.Fatalf("Channel not closed: timeout!")
}
}
// func (l *mockLogger) Infof(format string, v ...interface{}) { // ##### Mocks #####
// l.Info <- fmt.Sprintf(format, v...)
// }
// func (l *mockLogger) Errorf(format string, v ...interface{}) { // Logger
// l.Error <- fmt.Sprintf(format, v...)
// }
// func (l *mockLogger) Eventf(format string, v ...interface{}) { type mockLogger struct {
// l.Event <- fmt.Sprintf(format, v...) Info chan string
// } Error chan string
Event chan string
}
// // InotfiyWatcher func newMockLogger() *mockLogger {
return &mockLogger{
Info: make(chan string, 10),
Error: make(chan string, 10),
Event: make(chan string, 10),
}
}
// type mockFSWatcher struct { func (l *mockLogger) Infof(format string, v ...interface{}) {
// initErrCh chan error l.Info <- fmt.Sprintf(format, v...)
// initDoneCh chan struct{} }
// runTriggerCh chan struct{}
// runEventCh chan struct{}
// runErrorCh chan struct{}
// closed bool
// }
// func newMockFSWatcher() *mockFSWatcher { func (l *mockLogger) Errorf(format string, v ...interface{}) {
// return &mockFSWatcher{} l.Error <- fmt.Sprintf(format, v...)
// } }
// func (fs *mockFSWatcher) Init(rdirs, dirs []string) (chan error, chan struct{}) { func (l *mockLogger) Eventf(color int, format string, v ...interface{}) {
// fs.initErrCh = make(chan error) m := fmt.Sprintf(format, v...)
// fs.initDoneCh = make(chan struct{}) l.Event <- fmt.Sprintf("%d %s", color, m)
// return fs.initErrCh, fs.initDoneCh }
// }
// func (fs *mockFSWatcher) Run() (chan struct{}, chan string, chan error) { // FSWatcher
// fs.runTriggerCh, fs.runEventCh, fs.runErrorCh = make(chan struct{}), make(chan string), make(chan error)
// return fs.runTriggerCh, fs.runEventCh, fs.runErrorCh
// }
// func (i mockFSWatcher) Close() { type mockFSWatcher struct {
// i.closed = true rdirs []string
// } dirs []string
initErrCh chan error
initDoneCh chan struct{}
runTriggerCh chan struct{}
runEventCh chan string
runErrCh chan error
}
// // ProcfsScanner func newMockFSWatcher() *mockFSWatcher {
return &mockFSWatcher{
rdirs: make([]string, 0),
dirs: make([]string, 0),
initErrCh: make(chan error),
initDoneCh: make(chan struct{}),
runTriggerCh: make(chan struct{}),
runEventCh: make(chan string),
runErrCh: make(chan error),
}
}
// type mockProcfsScanner struct { func (fsw *mockFSWatcher) Init(rdirs, dirs []string) (chan error, chan struct{}) {
// triggerCh chan struct{} fsw.rdirs = rdirs
// interval time.Duration fsw.dirs = dirs
// psEventCh chan string return fsw.initErrCh, fsw.initDoneCh
// setupErr error }
// }
// func newMockProcfsScanner(setupErr error) *mockProcfsScanner { func (fsw *mockFSWatcher) Run() (chan struct{}, chan string, chan error) {
// return &mockProcfsScanner{ return fsw.runTriggerCh, fsw.runEventCh, fsw.runErrCh
// psEventCh: make(chan string), }
// setupErr: setupErr,
// }
// }
// func (p *mockProcfsScanner) Setup(triggerCh chan struct{}, interval time.Duration) (chan string, error) {
// if p.setupErr != nil {
// return nil, p.setupErr
// }
// return p.psEventCh, nil
// }