summaryrefslogtreecommitdiff
path: root/plugins/reload/tests
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/reload/tests')
-rw-r--r--plugins/reload/tests/configs/.rr-reload.yaml8
-rw-r--r--plugins/reload/tests/reload_plugin_test.go259
-rw-r--r--plugins/reload/tests/watcher_test.go698
3 files changed, 262 insertions, 703 deletions
diff --git a/plugins/reload/tests/configs/.rr-reload.yaml b/plugins/reload/tests/configs/.rr-reload.yaml
index e1149cd2..52511aa1 100644
--- a/plugins/reload/tests/configs/.rr-reload.yaml
+++ b/plugins/reload/tests/configs/.rr-reload.yaml
@@ -1,5 +1,5 @@
server:
- command: php ../../../tests/http/client.php echo pipes
+ command: php ../../../tests/psr-worker-bench.php
user: ''
group: ''
env:
@@ -8,7 +8,7 @@ server:
relayTimeout: 20s
http:
debug: true
- address: '127.0.0.1:15395'
+ address: '127.0.0.1:22388'
maxRequestSize: 1024
middleware:
- ''
@@ -33,9 +33,9 @@ http:
reload:
interval: 1s
patterns:
- - .go
+ - .txt
services:
http:
dirs:
- - ''
+ - './unit_tests'
recursive: true
diff --git a/plugins/reload/tests/reload_plugin_test.go b/plugins/reload/tests/reload_plugin_test.go
index 3d50030f..c49609f1 100644
--- a/plugins/reload/tests/reload_plugin_test.go
+++ b/plugins/reload/tests/reload_plugin_test.go
@@ -1,14 +1,23 @@
package tests
import (
+ "io"
+ "io/ioutil"
+ "math/rand"
+ "net/http"
"os"
"os/signal"
+ "path/filepath"
+ "strconv"
"sync"
"syscall"
"testing"
"time"
+ "github.com/golang/mock/gomock"
"github.com/spiral/endure"
+ "github.com/spiral/errors"
+ "github.com/spiral/roadrunner/v2/mocks"
"github.com/spiral/roadrunner/v2/plugins/config"
httpPlugin "github.com/spiral/roadrunner/v2/plugins/http"
"github.com/spiral/roadrunner/v2/plugins/logger"
@@ -18,6 +27,9 @@ import (
"github.com/stretchr/testify/assert"
)
+const testDir string = "unit_tests"
+const hugeNumberOfFiles uint = 5000
+
func TestReloadInit(t *testing.T) {
cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.DebugLevel))
assert.NoError(t, err)
@@ -27,9 +39,21 @@ func TestReloadInit(t *testing.T) {
Prefix: "rr",
}
+ err = os.Mkdir(testDir, 0755)
+ assert.NoError(t, err)
+ defer func() {
+ assert.NoError(t, freeResources(testDir))
+ }()
+
+ controller := gomock.NewController(t)
+ mockLogger := mocks.NewMockLogger(controller)
+
+ mockLogger.EXPECT().Debug("file was created", "path", gomock.Any(), "name", "file.txt", "size", gomock.Any()).Times(2)
+ mockLogger.EXPECT().Info("Resetting http plugin").Times(1)
+
err = cont.RegisterAll(
cfg,
- &logger.ZapLogger{},
+ mockLogger,
&server.Plugin{},
&httpPlugin.Plugin{},
&reload.Plugin{},
@@ -80,5 +104,238 @@ func TestReloadInit(t *testing.T) {
}
}()
+ t.Run("ReloadTestInit", reloadTestInit)
+
+ wg.Wait()
+}
+
+func reloadTestInit(t *testing.T) {
+ err := ioutil.WriteFile(filepath.Join(testDir, "file.txt"), //nolint:gosec
+ []byte{}, 0755)
+ assert.NoError(t, err)
+}
+
+func TestReloadHugeNumberOfFiles(t *testing.T) {
+ cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.DebugLevel))
+ assert.NoError(t, err)
+
+ cfg := &config.Viper{
+ Path: "configs/.rr-reload.yaml",
+ Prefix: "rr",
+ }
+
+ // try to remove, skip error
+ assert.NoError(t, freeResources(testDir))
+ err = os.Mkdir(testDir, 0755)
+ assert.NoError(t, err)
+
+ defer func() {
+ assert.NoError(t, freeResources(testDir))
+ }()
+
+ // controller := gomock.NewController(t)
+ // mockLogger := mocks.NewMockLogger(controller)
+ //
+ // mockLogger.EXPECT().Debug("file was created", "path", gomock.Any(), "name", "file.txt", "size", gomock.Any()).Times(2)
+ // mockLogger.EXPECT().Info("Resetting http plugin").Times(1)
+
+ err = cont.RegisterAll(
+ cfg,
+ // mockLogger,
+ &logger.ZapLogger{},
+ &server.Plugin{},
+ &httpPlugin.Plugin{},
+ &reload.Plugin{},
+ &resetter.Plugin{},
+ )
+ assert.NoError(t, err)
+
+ err = cont.Init()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ ch, err := cont.Serve()
+ assert.NoError(t, err)
+
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
+
+ wg := &sync.WaitGroup{}
+ wg.Add(1)
+
+ tt := time.NewTimer(time.Second * 160)
+
+ go func() {
+ defer wg.Done()
+ for {
+ select {
+ case e := <-ch:
+ assert.Fail(t, "error", e.Error.Error())
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ case <-sig:
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ return
+ case <-tt.C:
+ // timeout
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ return
+ }
+ }
+ }()
+
+ t.Run("ReloadTestHugeNumberOfFiles", reloadHugeNumberOfFiles)
+ ttt := time.Now()
+ t.Run("ReloadRandomlyChangeFile", randomlyChangeFile)
+ if time.Since(ttt).Seconds() > 140 {
+ t.Fatal("spend too much time on reloading")
+ }
+ t.Run("ReloadHTTPLiveAfterReset", reloadHTTPLiveAfterReset)
+
wg.Wait()
}
+
+func reloadHTTPLiveAfterReset(t *testing.T) {
+ req, err := http.NewRequest("GET", "http://localhost:22388", nil)
+ assert.NoError(t, err)
+
+ r, err := http.DefaultClient.Do(req)
+ assert.NoError(t, err)
+
+ b, err := ioutil.ReadAll(r.Body)
+ assert.NoError(t, err)
+
+ assert.Equal(t, 200, r.StatusCode)
+ assert.Equal(t, "hello world", string(b))
+
+ err = r.Body.Close()
+ assert.NoError(t, err)
+}
+
+func randomlyChangeFile(t *testing.T) {
+ // we know, that directory contains 5000 files (0-4999)
+ // let's try to randomly change it
+ for i := 0; i < 100; i++ {
+ // rand sleep
+ rSleep := rand.Int63n(1000) // nolint:gosec
+ time.Sleep(time.Millisecond * time.Duration(rSleep))
+ rNum := rand.Int63n(int64(hugeNumberOfFiles)) // nolint:gosec
+ err := ioutil.WriteFile(filepath.Join(testDir, "file_"+strconv.Itoa(int(rNum))+".txt"), []byte("Hello, Gophers!"), 0755) // nolint:gosec
+ assert.NoError(t, err)
+ }
+}
+
+func reloadHugeNumberOfFiles(t *testing.T) {
+ for i := uint(0); i < hugeNumberOfFiles; i++ {
+ assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".txt"))
+ }
+}
+
+func freeResources(path string) error {
+ return os.RemoveAll(path)
+}
+
+func makeFile(filename string) error {
+ return ioutil.WriteFile(filepath.Join(testDir, filename), []byte{}, 0755) //nolint:gosec
+}
+
+func copyDir(src string, dst string) error {
+ src = filepath.Clean(src)
+ dst = filepath.Clean(dst)
+
+ si, err := os.Stat(src)
+ if err != nil {
+ return err
+ }
+ if !si.IsDir() {
+ return errors.E(errors.Str("source is not a directory"))
+ }
+
+ _, err = os.Stat(dst)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+ if err == nil {
+ return errors.E(errors.Str("destination already exists"))
+ }
+
+ err = os.MkdirAll(dst, si.Mode())
+ if err != nil {
+ return err
+ }
+
+ entries, err := ioutil.ReadDir(src)
+ if err != nil {
+ return err
+ }
+
+ for _, entry := range entries {
+ srcPath := filepath.Join(src, entry.Name())
+ dstPath := filepath.Join(dst, entry.Name())
+
+ if entry.IsDir() {
+ err = copyDir(srcPath, dstPath)
+ if err != nil {
+ return err
+ }
+ } else {
+ // Skip symlinks.
+ if entry.Mode()&os.ModeSymlink != 0 {
+ continue
+ }
+
+ err = copyFile(srcPath, dstPath)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func copyFile(src, dst string) error {
+ in, err := os.Open(src)
+ if err != nil {
+ return errors.E(err)
+ }
+ defer func() {
+ _ = in.Close()
+ }()
+
+ out, err := os.Create(dst)
+ if err != nil {
+ return errors.E(err)
+ }
+ defer func() {
+ _ = out.Close()
+ }()
+
+ _, err = io.Copy(out, in)
+ if err != nil {
+ return errors.E(err)
+ }
+
+ err = out.Sync()
+ if err != nil {
+ return errors.E(err)
+ }
+
+ si, err := os.Stat(src)
+ if err != nil {
+ return errors.E(err)
+ }
+ err = os.Chmod(dst, si.Mode())
+ if err != nil {
+ return errors.E(err)
+ }
+ return nil
+}
diff --git a/plugins/reload/tests/watcher_test.go b/plugins/reload/tests/watcher_test.go
deleted file mode 100644
index f1e0d737..00000000
--- a/plugins/reload/tests/watcher_test.go
+++ /dev/null
@@ -1,698 +0,0 @@
-package tests
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "runtime"
- "strings"
- "testing"
- "time"
-
- "github.com/spiral/errors"
- logPlugin "github.com/spiral/roadrunner/v2/plugins/logger"
- "github.com/spiral/roadrunner/v2/plugins/reload"
- "go.uber.org/zap"
-)
-
-var testServiceName = "test"
-
-// scenario
-// Create walker instance, init with default config, check that Watcher found all files from config
-func Test_Correct_Watcher_Init(t *testing.T) {
- tempDir, err := ioutil.TempDir(".", "")
- defer func() {
- err = freeResources(tempDir)
- if err != nil {
- t.Fatal(err)
- }
- }()
- if err != nil {
- t.Fatal(err)
- }
- err = ioutil.WriteFile(filepath.Join(tempDir, "file.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- wc := reload.WatcherConfig{
- ServiceName: testServiceName,
- Recursive: false,
- Directories: []string{tempDir},
- FilterHooks: nil,
- Files: make(map[string]os.FileInfo),
- Ignored: nil,
- FilePatterns: nil,
- }
-
- logger, _ := zap.NewDevelopment()
- lg := logPlugin.NewZapAdapter(logger)
-
- w, err := reload.NewWatcher([]reload.WatcherConfig{wc}, lg)
- if err != nil {
- t.Fatal(err)
- }
-
- if len(w.GetAllFiles(testServiceName)) != 2 {
- t.Fatal("incorrect directories len")
- }
-}
-
-// scenario
-// create 3 files, create walker instance
-// Start poll events
-// change file and see, if event had come to handler
-func Test_Get_FileEvent(t *testing.T) {
- tempDir, err := ioutil.TempDir(".", "")
- c := make(chan struct{})
- defer func(name string) {
- err = freeResources(name)
- if err != nil {
- c <- struct{}{}
- t.Fatal(err)
- }
- c <- struct{}{}
- }(tempDir)
-
- if err != nil {
- t.Fatal(err)
- }
- err = ioutil.WriteFile(filepath.Join(tempDir, "file1.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file2.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file3.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- wc := reload.WatcherConfig{
- ServiceName: testServiceName,
- Recursive: false,
- Directories: []string{tempDir},
- FilterHooks: nil,
- Files: make(map[string]os.FileInfo),
- Ignored: nil,
- FilePatterns: []string{"aaa", "txt"},
- }
-
- logger, _ := zap.NewDevelopment()
- lg := logPlugin.NewZapAdapter(logger)
-
- w, err := reload.NewWatcher([]reload.WatcherConfig{wc}, lg)
- if err != nil {
- t.Fatal(err)
- }
-
- // should be 3 files and directory
- if len(w.GetAllFiles(testServiceName)) != 4 {
- t.Fatal("incorrect directories len")
- }
-
- go limitTime(time.Second*10, t.Name(), c)
-
- go func() {
- go func() {
- time.Sleep(time.Second)
- err2 := ioutil.WriteFile(filepath.Join(tempDir, "file2.txt"), //nolint:gosec
- []byte{1, 1, 1}, 0755)
- if err2 != nil {
- panic(err2)
- }
- runtime.Goexit()
- }()
-
- go func() {
- for e := range w.Event {
- if e.Path != "file2.txt" {
- panic("didn't handle event when write file2")
- }
- w.Stop()
- }
- }()
- }()
-
- err = w.StartPolling(time.Second)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-// scenario
-// create 3 files with different extensions, create walker instance
-// Start poll events
-// change file with txt extension, and see, if event had not come to handler because it was filtered
-func Test_FileExtensionFilter(t *testing.T) {
- tempDir, err := ioutil.TempDir(".", "")
- c := make(chan struct{})
- defer func(name string) {
- err = freeResources(name)
- if err != nil {
- c <- struct{}{}
- t.Fatal(err)
- }
- c <- struct{}{}
- }(tempDir)
-
- if err != nil {
- t.Fatal(err)
- }
- err = ioutil.WriteFile(filepath.Join(tempDir, "file1.aaa"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file2.bbb"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file3.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
- wc := reload.WatcherConfig{
- ServiceName: testServiceName,
- Recursive: false,
- Directories: []string{tempDir},
- FilterHooks: func(filename string, patterns []string) error {
- for i := 0; i < len(patterns); i++ {
- if strings.Contains(filename, patterns[i]) {
- return nil
- }
- }
- return errors.E(errors.Skip)
- },
- Files: make(map[string]os.FileInfo),
- Ignored: nil,
- FilePatterns: []string{"aaa", "bbb"},
- }
-
- logger, _ := zap.NewDevelopment()
- lg := logPlugin.NewZapAdapter(logger)
-
- w, err := reload.NewWatcher([]reload.WatcherConfig{wc}, lg)
- if err != nil {
- t.Fatal(err)
- }
-
- dirLen := len(w.GetAllFiles(testServiceName))
- // should be 2 files (one filtered) and directory
- if dirLen != 3 {
- t.Fatalf("incorrect directories len, len is: %d", dirLen)
- }
-
- go limitTime(time.Second*5, t.Name(), c)
-
- go func() {
- go func() {
- err2 := ioutil.WriteFile(filepath.Join(tempDir, "file3.txt"), //nolint:gosec
- []byte{1, 1, 1}, 0755)
- if err2 != nil {
- panic(err2)
- }
-
- runtime.Goexit()
- }()
-
- go func() {
- for e := range w.Event {
- fmt.Println(e.Info.Name())
- panic("handled event from filtered file")
- }
- }()
- w.Stop()
- runtime.Goexit()
- }()
-
- err = w.StartPolling(time.Second)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-// nested
-// scenario
-// create dir and nested dir
-// make files with aaa, bbb and txt extensions, filter txt
-// change not filtered file, handle event
-func Test_Recursive_Support(t *testing.T) {
- tempDir, err := ioutil.TempDir(".", "")
- defer func() {
- err = freeResources(tempDir)
- if err != nil {
- t.Fatal(err)
- }
- }()
-
- nestedDir, err := ioutil.TempDir(tempDir, "nested")
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file1.aaa"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file2.bbb"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(nestedDir, "file3.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
- err = ioutil.WriteFile(filepath.Join(nestedDir, "file4.aaa"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- wc := reload.WatcherConfig{
- ServiceName: testServiceName,
- Recursive: true,
- Directories: []string{tempDir},
- FilterHooks: func(filename string, patterns []string) error {
- for i := 0; i < len(patterns); i++ {
- if strings.Contains(filename, patterns[i]) {
- return nil
- }
- }
- return errors.E(errors.Skip)
- },
- Files: make(map[string]os.FileInfo),
- Ignored: nil,
- FilePatterns: []string{"aaa", "bbb"},
- }
-
- logger, _ := zap.NewDevelopment()
- lg := logPlugin.NewZapAdapter(logger)
-
- w, err := reload.NewWatcher([]reload.WatcherConfig{wc}, lg)
- if err != nil {
- t.Fatal(err)
- }
-
- dirLen := len(w.GetAllFiles(testServiceName))
- // should be 3 files (2 from root dir, and 1 from nested), filtered txt
- if dirLen != 3 {
- t.Fatalf("incorrect directories len, len is: %d", dirLen)
- }
-
- go func() {
- // time sleep is used here because StartPolling is blocking operation
- time.Sleep(time.Second * 5)
- // change file in nested directory
- err = ioutil.WriteFile(filepath.Join(nestedDir, "file4.aaa"), //nolint:gosec
- []byte{1, 1, 1}, 0755)
- if err != nil {
- panic(err)
- }
- go func() {
- for e := range w.Event {
- if e.Info.Name() != "file4.aaa" {
- panic("wrong handled event from watcher in nested dir")
- }
- w.Stop()
- }
- }()
- }()
-
- err = w.StartPolling(time.Second)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func Test_Wrong_Dir(t *testing.T) {
- // no such file or directory
- wrongDir := "askdjfhaksdlfksdf"
-
- wc := reload.WatcherConfig{
- ServiceName: testServiceName,
- Recursive: true,
- Directories: []string{wrongDir},
- FilterHooks: func(filename string, patterns []string) error {
- for i := 0; i < len(patterns); i++ {
- if strings.Contains(filename, patterns[i]) {
- return nil
- }
- }
- return errors.E(errors.Skip)
- },
- Files: make(map[string]os.FileInfo),
- Ignored: nil,
- FilePatterns: []string{"aaa", "bbb"},
- }
-
- logger, _ := zap.NewDevelopment()
- lg := logPlugin.NewZapAdapter(logger)
-
- _, err := reload.NewWatcher([]reload.WatcherConfig{wc}, lg)
- if err == nil {
- t.Fatal(err)
- }
-}
-
-func Test_Filter_Directory(t *testing.T) {
- tempDir, err := ioutil.TempDir(".", "")
- c := make(chan struct{})
- defer func(name string) {
- err = freeResources(name)
- if err != nil {
- c <- struct{}{}
- t.Fatal(err)
- }
- c <- struct{}{}
- }(tempDir)
-
- go limitTime(time.Second*10, t.Name(), c)
-
- nestedDir, err := ioutil.TempDir(tempDir, "nested")
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file1.aaa"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file2.bbb"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(nestedDir, "file3.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
- err = ioutil.WriteFile(filepath.Join(nestedDir, "file4.aaa"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- ignored, err := reload.ConvertIgnored([]string{nestedDir})
- if err != nil {
- t.Fatal(err)
- }
- wc := reload.WatcherConfig{
- ServiceName: testServiceName,
- Recursive: true,
- Directories: []string{tempDir},
- FilterHooks: func(filename string, patterns []string) error {
- for i := 0; i < len(patterns); i++ {
- if strings.Contains(filename, patterns[i]) {
- return nil
- }
- }
- return errors.E(errors.Skip)
- },
- Files: make(map[string]os.FileInfo),
- Ignored: ignored,
- FilePatterns: []string{"aaa", "bbb", "txt"},
- }
-
- logger, _ := zap.NewDevelopment()
- lg := logPlugin.NewZapAdapter(logger)
-
- w, err := reload.NewWatcher([]reload.WatcherConfig{wc}, lg)
- if err != nil {
- t.Fatal(err)
- }
-
- dirLen := len(w.GetAllFiles(testServiceName))
- // should be 2 files (2 from root dir), filtered other
- if dirLen != 2 {
- t.Fatalf("incorrect directories len, len is: %d", dirLen)
- }
-
- go func() {
- go func() {
- err2 := ioutil.WriteFile(filepath.Join(nestedDir, "file4.aaa"), //nolint:gosec
- []byte{1, 1, 1}, 0755)
- if err2 != nil {
- panic(err2)
- }
- }()
-
- go func() {
- for e := range w.Event {
- fmt.Println("file: " + e.Info.Name())
- panic("handled event from watcher in nested dir")
- }
- }()
-
- // time sleep is used here because StartPolling is blocking operation
- time.Sleep(time.Second * 5)
- w.Stop()
- }()
-
- err = w.StartPolling(time.Second)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-// copy files from nested dir to not ignored
-// should fire an event
-func Test_Copy_Directory(t *testing.T) {
- tempDir, err := ioutil.TempDir(".", "")
- c := make(chan struct{})
- defer func() {
- err = freeResources(tempDir)
- if err != nil {
- c <- struct{}{}
- t.Fatal(err)
- }
- c <- struct{}{}
- }()
-
- nestedDir, err := ioutil.TempDir(tempDir, "nested")
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file1.aaa"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(tempDir, "file2.bbb"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- err = ioutil.WriteFile(filepath.Join(nestedDir, "file3.txt"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
- err = ioutil.WriteFile(filepath.Join(nestedDir, "file4.aaa"), //nolint:gosec
- []byte{}, 0755)
- if err != nil {
- t.Fatal(err)
- }
-
- ignored, err := reload.ConvertIgnored([]string{nestedDir})
- if err != nil {
- t.Fatal(err)
- }
-
- wc := reload.WatcherConfig{
- ServiceName: testServiceName,
- Recursive: true,
- Directories: []string{tempDir},
- FilterHooks: func(filename string, patterns []string) error {
- for i := 0; i < len(patterns); i++ {
- if strings.Contains(filename, patterns[i]) {
- return nil
- }
- }
- return errors.E(errors.Skip)
- },
- Files: make(map[string]os.FileInfo),
- Ignored: ignored,
- FilePatterns: []string{"aaa", "bbb", "txt"},
- }
-
- logger, _ := zap.NewDevelopment()
- lg := logPlugin.NewZapAdapter(logger)
-
- w, err := reload.NewWatcher([]reload.WatcherConfig{wc}, lg)
- if err != nil {
- t.Fatal(err)
- }
-
- dirLen := len(w.GetAllFiles(testServiceName))
- // should be 2 files (2 from root dir), filtered other
- if dirLen != 2 {
- t.Fatalf("incorrect directories len, len is: %d", dirLen)
- }
-
- go limitTime(time.Second*10, t.Name(), c)
-
- go func() {
- go func() {
- err2 := copyDir(nestedDir, filepath.Join(tempDir, "copyTo"))
- if err2 != nil {
- panic(err2)
- }
-
- // exit from current goroutine
- runtime.Goexit()
- }()
-
- go func() {
- for range w.Event {
- // here should be event, otherwise we won't stop
- w.Stop()
- }
- }()
- }()
-
- err = w.StartPolling(time.Second)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func limitTime(d time.Duration, name string, free chan struct{}) {
- go func() {
- ticket := time.NewTicker(d)
- for {
- select {
- case <-ticket.C:
- ticket.Stop()
- panic("timeout exceed, test: " + name)
- case <-free:
- ticket.Stop()
- return
- }
- }
- }()
-}
-
-func copyFile(src, dst string) error {
- in, err := os.Open(src)
- if err != nil {
- return err
- }
- defer func() {
- _ = in.Close()
- }()
-
- out, err := os.Create(dst)
- if err != nil {
- return err
- }
- defer func() {
- if e := out.Close(); e != nil {
- err = e
- }
- }()
-
- _, err = io.Copy(out, in)
- if err != nil {
- return err
- }
-
- err = out.Sync()
- if err != nil {
- return err
- }
-
- si, err := os.Stat(src)
- if err != nil {
- return err
- }
- err = os.Chmod(dst, si.Mode())
- if err != nil {
- return err
- }
- return nil
-}
-
-func copyDir(src string, dst string) error {
- src = filepath.Clean(src)
- dst = filepath.Clean(dst)
-
- si, err := os.Stat(src)
- if err != nil {
- return err
- }
- if !si.IsDir() {
- return fmt.Errorf("source is not a directory")
- }
-
- _, err = os.Stat(dst)
- if err != nil && !os.IsNotExist(err) {
- return err
- }
- if err == nil {
- return fmt.Errorf("destination already exists")
- }
-
- err = os.MkdirAll(dst, si.Mode())
- if err != nil {
- return err
- }
-
- entries, err := ioutil.ReadDir(src)
- if err != nil {
- return err
- }
-
- for _, entry := range entries {
- srcPath := filepath.Join(src, entry.Name())
- dstPath := filepath.Join(dst, entry.Name())
-
- if entry.IsDir() {
- err = copyDir(srcPath, dstPath)
- if err != nil {
- return err
- }
- } else {
- // Skip symlinks.
- if entry.Mode()&os.ModeSymlink != 0 {
- continue
- }
-
- err = copyFile(srcPath, dstPath)
- if err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-func freeResources(path string) error {
- return os.RemoveAll(path)
-}