324 lines
6.9 KiB
Go
324 lines
6.9 KiB
Go
|
package folderwatcher
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"sync"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func TestNewFileHandling(t *testing.T) {
|
||
|
tmpPath, err := os.MkdirTemp("", ".folderwatcher_test")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer os.RemoveAll(tmpPath)
|
||
|
quitChan := make(chan struct{})
|
||
|
|
||
|
filesIn := []string{"A", "B", "C"}
|
||
|
for i, f := range filesIn { //remap filesIn to Full Path
|
||
|
filesIn[i] = filepath.Join(tmpPath, f)
|
||
|
if !filepath.IsAbs(filesIn[i]) {
|
||
|
t.Fatalf("file %s is not an absolute path", filesIn[i])
|
||
|
}
|
||
|
}
|
||
|
var filesOut []string
|
||
|
|
||
|
wg := sync.WaitGroup{}
|
||
|
|
||
|
conf := Config{
|
||
|
Folder: tmpPath,
|
||
|
}
|
||
|
watcher, err := NewFolderWatcher(conf, true, quitChan)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
go watcher.Watch(func(filePath string) (bool, error) {
|
||
|
if !filepath.IsAbs(filePath) {
|
||
|
t.Errorf("file %s is not an absolute path", filePath)
|
||
|
}
|
||
|
filesOut = append(filesOut, filePath)
|
||
|
wg.Done()
|
||
|
return true, nil
|
||
|
}, func(s string, err error) {
|
||
|
})
|
||
|
|
||
|
for _, f := range filesIn {
|
||
|
wg.Add(1)
|
||
|
_ = os.WriteFile(f, []byte{0}, os.ModePerm)
|
||
|
}
|
||
|
|
||
|
finishedChan := make(chan struct{})
|
||
|
go func() {
|
||
|
wg.Wait()
|
||
|
finishedChan <- struct{}{}
|
||
|
}()
|
||
|
|
||
|
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||
|
defer ctxCancel()
|
||
|
|
||
|
select {
|
||
|
case <-finishedChan:
|
||
|
case <-ctx.Done():
|
||
|
t.Error(ctx.Err())
|
||
|
}
|
||
|
quitChan <- struct{}{}
|
||
|
|
||
|
if len(filesOut) != len(filesIn) {
|
||
|
t.Errorf("filesOut length %d != %d", len(filesOut), len(filesIn))
|
||
|
}
|
||
|
for _, f := range filesIn {
|
||
|
if !Contains(filesOut, f) {
|
||
|
t.Errorf("File %s not found in %s", f, filesOut)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestOldFileHandling(t *testing.T) {
|
||
|
tmpPath, err := os.MkdirTemp("", ".folderwatcher_test")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer os.RemoveAll(tmpPath)
|
||
|
quitChan := make(chan struct{})
|
||
|
|
||
|
filesIn := []string{"A", "B", "C"}
|
||
|
for i, f := range filesIn { //remap filesIn to Full Path
|
||
|
filesIn[i] = filepath.Join(tmpPath, f)
|
||
|
if !filepath.IsAbs(filesIn[i]) {
|
||
|
t.Fatalf("file %s is not an absolute path", filesIn[i])
|
||
|
}
|
||
|
}
|
||
|
var filesOut []string
|
||
|
|
||
|
wg := sync.WaitGroup{}
|
||
|
|
||
|
conf := Config{
|
||
|
Folder: tmpPath,
|
||
|
}
|
||
|
|
||
|
for _, f := range filesIn {
|
||
|
wg.Add(1)
|
||
|
_ = os.WriteFile(f, []byte{0}, os.ModePerm)
|
||
|
}
|
||
|
|
||
|
watcher, err := NewFolderWatcher(conf, true, quitChan)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
go watcher.Watch(func(filePath string) (bool, error) {
|
||
|
if !filepath.IsAbs(filePath) {
|
||
|
t.Errorf("file %s is not an absolute path", filePath)
|
||
|
}
|
||
|
filesOut = append(filesOut, filePath)
|
||
|
wg.Done()
|
||
|
return true, nil
|
||
|
}, func(s string, err error) {
|
||
|
})
|
||
|
|
||
|
finishedChan := make(chan struct{})
|
||
|
go func() {
|
||
|
wg.Wait()
|
||
|
finishedChan <- struct{}{}
|
||
|
}()
|
||
|
|
||
|
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||
|
defer ctxCancel()
|
||
|
|
||
|
select {
|
||
|
case <-finishedChan:
|
||
|
case <-ctx.Done():
|
||
|
t.Error(ctx.Err())
|
||
|
}
|
||
|
quitChan <- struct{}{}
|
||
|
|
||
|
if len(filesOut) != len(filesIn) {
|
||
|
t.Errorf("filesOut length %d != %d", len(filesOut), len(filesIn))
|
||
|
}
|
||
|
for _, f := range filesIn {
|
||
|
if !Contains(filesOut, f) {
|
||
|
t.Errorf("File %s not found in %s", f, filesOut)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestOldAndNewFileHandling(t *testing.T) {
|
||
|
tmpPath, err := os.MkdirTemp("", ".folderwatcher_test")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer os.RemoveAll(tmpPath)
|
||
|
quitChan := make(chan struct{})
|
||
|
|
||
|
filesIn := []string{"A", "B", "C"}
|
||
|
for i, f := range filesIn { //remap filesIn to Full Path
|
||
|
filesIn[i] = filepath.Join(tmpPath, f)
|
||
|
if !filepath.IsAbs(filesIn[i]) {
|
||
|
t.Fatalf("file %s is not an absolute path", filesIn[i])
|
||
|
}
|
||
|
}
|
||
|
filesInRunning := []string{"D", "E", "F"}
|
||
|
for i, f := range filesInRunning { //remap filesIn to Full Path
|
||
|
filesInRunning[i] = filepath.Join(tmpPath, f)
|
||
|
if !filepath.IsAbs(filesInRunning[i]) {
|
||
|
t.Fatalf("file %s is not an absolute path", filesInRunning[i])
|
||
|
}
|
||
|
}
|
||
|
var filesOut []string
|
||
|
|
||
|
wg := sync.WaitGroup{}
|
||
|
|
||
|
conf := Config{
|
||
|
Folder: tmpPath,
|
||
|
}
|
||
|
|
||
|
for _, f := range filesIn {
|
||
|
wg.Add(1)
|
||
|
_ = os.WriteFile(f, []byte{0}, os.ModePerm)
|
||
|
}
|
||
|
|
||
|
watcher, err := NewFolderWatcher(conf, true, quitChan)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
go watcher.Watch(func(filePath string) (bool, error) {
|
||
|
if !filepath.IsAbs(filePath) {
|
||
|
t.Errorf("file %s is not an absolute path", filePath)
|
||
|
}
|
||
|
filesOut = append(filesOut, filePath)
|
||
|
wg.Done()
|
||
|
return true, nil
|
||
|
}, func(s string, err error) {
|
||
|
})
|
||
|
|
||
|
for _, f := range filesInRunning {
|
||
|
wg.Add(1)
|
||
|
filesIn = append(filesIn, f)
|
||
|
_ = os.WriteFile(f, []byte{0}, os.ModePerm)
|
||
|
}
|
||
|
|
||
|
finishedChan := make(chan struct{})
|
||
|
go func() {
|
||
|
wg.Wait()
|
||
|
finishedChan <- struct{}{}
|
||
|
}()
|
||
|
|
||
|
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||
|
defer ctxCancel()
|
||
|
|
||
|
select {
|
||
|
case <-finishedChan:
|
||
|
case <-ctx.Done():
|
||
|
t.Error(ctx.Err())
|
||
|
}
|
||
|
quitChan <- struct{}{}
|
||
|
|
||
|
if len(filesOut) != len(filesIn) {
|
||
|
t.Errorf("filesOut length %d != %d", len(filesOut), len(filesIn))
|
||
|
}
|
||
|
for _, f := range filesIn {
|
||
|
if !Contains(filesOut, f) {
|
||
|
t.Errorf("File %s not found in %s", f, filesOut)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestOldAndNewFileHandlingWithoutExisting(t *testing.T) {
|
||
|
tmpPath, err := os.MkdirTemp("", ".folderwatcher_test")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer os.RemoveAll(tmpPath)
|
||
|
quitChan := make(chan struct{})
|
||
|
|
||
|
filesIn := []string{"A", "B", "C"}
|
||
|
for i, f := range filesIn { //remap filesIn to Full Path
|
||
|
filesIn[i] = filepath.Join(tmpPath, f)
|
||
|
if !filepath.IsAbs(filesIn[i]) {
|
||
|
t.Fatalf("file %s is not an absolute path", filesIn[i])
|
||
|
}
|
||
|
}
|
||
|
filesInRunning := []string{"D", "E", "F"}
|
||
|
for i, f := range filesInRunning { //remap filesInRunning to Full Path
|
||
|
filesInRunning[i] = filepath.Join(tmpPath, f)
|
||
|
if !filepath.IsAbs(filesInRunning[i]) {
|
||
|
t.Fatalf("file %s is not an absolute path", filesInRunning[i])
|
||
|
}
|
||
|
}
|
||
|
var filesOut []string
|
||
|
|
||
|
wg := sync.WaitGroup{}
|
||
|
|
||
|
conf := Config{
|
||
|
Folder: tmpPath,
|
||
|
}
|
||
|
|
||
|
for _, f := range filesIn {
|
||
|
_ = os.WriteFile(f, []byte{0}, os.ModePerm)
|
||
|
}
|
||
|
|
||
|
watcher, err := NewFolderWatcher(conf, false, quitChan)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
go watcher.Watch(func(filePath string) (bool, error) {
|
||
|
if !filepath.IsAbs(filePath) {
|
||
|
t.Errorf("file %s is not an absolute path", filePath)
|
||
|
}
|
||
|
filesOut = append(filesOut, filePath)
|
||
|
wg.Done()
|
||
|
return true, nil
|
||
|
}, func(s string, err error) {
|
||
|
})
|
||
|
|
||
|
for _, f := range filesInRunning {
|
||
|
wg.Add(1)
|
||
|
_ = os.WriteFile(f, []byte{0}, os.ModePerm)
|
||
|
}
|
||
|
|
||
|
finishedChan := make(chan struct{})
|
||
|
go func() {
|
||
|
wg.Wait()
|
||
|
finishedChan <- struct{}{}
|
||
|
}()
|
||
|
|
||
|
ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||
|
defer ctxCancel()
|
||
|
|
||
|
select {
|
||
|
case <-finishedChan:
|
||
|
case <-ctx.Done():
|
||
|
t.Error(ctx.Err())
|
||
|
}
|
||
|
quitChan <- struct{}{}
|
||
|
|
||
|
if len(filesOut) != len(filesInRunning) {
|
||
|
t.Errorf("filesOut length %d != %d", len(filesOut), len(filesInRunning))
|
||
|
}
|
||
|
for _, f := range filesInRunning {
|
||
|
if !Contains(filesOut, f) {
|
||
|
t.Errorf("File %s not found in %s", f, filesOut)
|
||
|
}
|
||
|
}
|
||
|
for _, f := range filesIn {
|
||
|
if Contains(filesOut, f) {
|
||
|
t.Errorf("File %s found in %s", f, filesOut)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Contains[T comparable](slice []T, item T) bool {
|
||
|
for _, v := range slice {
|
||
|
if v == item {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
return false
|
||
|
}
|