folderwatcher/folderwatcher_test.go
Christian Schmied 366152c483
All checks were successful
go/folderwatcher/pipeline/head This commit looks good
init
2024-09-26 12:34:36 +02:00

475 lines
11 KiB
Go

package folderwatcher
import (
"context"
"os"
"path/filepath"
"strconv"
"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 TestGlobbingN1(t *testing.T) {
tmpPath, err := os.MkdirTemp("", ".folderwatcher_test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpPath)
quitChan := make(chan struct{})
_ = os.MkdirAll(filepath.Join(tmpPath, "g0"), os.ModePerm)
_ = os.MkdirAll(filepath.Join(tmpPath, "g1"), os.ModePerm)
_ = os.MkdirAll(filepath.Join(tmpPath, "g2"), os.ModePerm)
filesIn := []string{"A", "B", "C"}
var filesOut []string
wg := sync.WaitGroup{}
conf := Config{
Folder: filepath.Join(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)
}
rel, err := filepath.Rel(tmpPath, filePath)
if err != nil {
return true, err
}
filesOut = append(filesOut, rel)
wg.Done()
return true, nil
}, func(s string, err error) {
})
for i, f := range filesIn {
wg.Add(1)
_ = os.WriteFile(filepath.Join(tmpPath, "g"+strconv.Itoa(i), 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 i, f := range filesIn {
if !Contains(filesOut, filepath.Join("g"+strconv.Itoa(i), f)) {
t.Errorf("File %s not found in %s", f, filesOut)
}
}
}
func TestGlobbingN2(t *testing.T) {
tmpPath, err := os.MkdirTemp("", ".folderwatcher_test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpPath)
quitChan := make(chan struct{})
_ = os.MkdirAll(filepath.Join(tmpPath, "g0", "s0"), os.ModePerm)
_ = os.MkdirAll(filepath.Join(tmpPath, "g0", "s2"), os.ModePerm)
_ = os.MkdirAll(filepath.Join(tmpPath, "g1", "s1"), os.ModePerm)
_ = os.MkdirAll(filepath.Join(tmpPath, "g1", "s3"), os.ModePerm)
_ = os.MkdirAll(filepath.Join(tmpPath, "gX"), os.ModePerm)
filesIn := []string{"A", "B", "C", "D"}
var filesOut []string
wg := sync.WaitGroup{}
conf := Config{
Folder: filepath.Join(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)
}
rel, err := filepath.Rel(tmpPath, filePath)
if err != nil {
return true, err
}
filesOut = append(filesOut, rel)
wg.Done()
return true, nil
}, func(s string, err error) {
})
for i, f := range filesIn {
wg.Add(1)
_ = os.WriteFile(filepath.Join(tmpPath, "g"+strconv.Itoa(i%2), "s"+strconv.Itoa(i), f), []byte{0}, os.ModePerm)
}
wg.Add(1)
_ = os.WriteFile(filepath.Join(tmpPath, "gX", "foo"), []byte{0}, os.ModePerm)
finishedChan := make(chan struct{})
go func() {
wg.Wait()
finishedChan <- struct{}{}
}()
ctx, ctxCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer ctxCancel()
select {
case <-finishedChan:
case <-ctx.Done():
wg.Done() // ctx Will Timeout, because gX/foo will always be remaining
// t.Error(ctx.Err())
}
quitChan <- struct{}{}
if len(filesOut) != len(filesIn) {
t.Errorf("filesOut length %d != %d", len(filesOut), len(filesIn))
}
for i, f := range filesIn {
if !Contains(filesOut, filepath.Join("g"+strconv.Itoa(i%2), "s"+strconv.Itoa(i), f)) {
t.Errorf("File %s not found in %s", f, filesOut)
}
}
if Contains(filesOut, filepath.Join("gX", "foo")) {
t.Errorf("File %s found in %s", filepath.Join("gX", "foo"), filesOut)
}
}
func Contains[T comparable](slice []T, item T) bool {
for _, v := range slice {
if v == item {
return true
}
}
return false
}