github.com/Jeffail/benthos/v3@v3.65.0/internal/config/reader_test.go (about) 1 package config 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 "time" 8 9 "github.com/Jeffail/benthos/v3/lib/log" 10 "github.com/Jeffail/benthos/v3/lib/manager" 11 "github.com/Jeffail/benthos/v3/lib/metrics" 12 "github.com/Jeffail/benthos/v3/lib/stream" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func newDummyReader(confFilePath string) *Reader { 18 rdr := NewReader(confFilePath, nil) 19 rdr.changeDelayPeriod = 1 * time.Millisecond 20 rdr.changeFlushPeriod = 1 * time.Millisecond 21 return rdr 22 } 23 24 func TestReaderFileWatching(t *testing.T) { 25 dummyConfig := []byte(` 26 input: 27 kafka: {} 28 output: 29 aws_s3: {} 30 `) 31 32 confDir := t.TempDir() 33 34 // Create an empty config file in the config folder 35 confFilePath := filepath.Join(confDir, "main.yaml") 36 require.NoError(t, os.WriteFile(confFilePath, []byte{}, 0o644)) 37 38 rdr := newDummyReader(confFilePath) 39 40 changeChan := make(chan struct{}) 41 var updatedConf stream.Config 42 require.NoError(t, rdr.SubscribeConfigChanges(func(conf stream.Config) bool { 43 updatedConf = conf 44 close(changeChan) 45 return true 46 })) 47 48 // Watch for configuration changes 49 testMgr, err := manager.NewV2(manager.NewResourceConfig(), nil, log.Noop(), metrics.Noop()) 50 require.NoError(t, err) 51 require.NoError(t, rdr.BeginFileWatching(testMgr, true)) 52 53 // Overwrite original config 54 require.NoError(t, os.WriteFile(confFilePath, dummyConfig, 0o644)) 55 56 // Wait for the config watcher to reload the config 57 select { 58 case <-changeChan: 59 case <-time.After(100 * time.Millisecond): 60 require.FailNow(t, "Expected a config change to be triggered") 61 } 62 63 assert.Equal(t, "kafka", updatedConf.Input.Type) 64 assert.Equal(t, "aws_s3", updatedConf.Output.Type) 65 } 66 67 func TestReaderFileWatchingSymlinkReplace(t *testing.T) { 68 dummyConfig := []byte(` 69 input: 70 kafka: {} 71 output: 72 aws_s3: {} 73 `) 74 75 rootDir := t.TempDir() 76 77 // Create a config folder 78 confDir := filepath.Join(rootDir, "config") 79 require.NoError(t, os.Mkdir(confDir, 0o755)) 80 81 // Create a symlink to the config folder 82 confDirSymlink := filepath.Join(rootDir, "symlink") 83 require.NoError(t, os.Symlink(confDir, confDirSymlink)) 84 85 // Create an empty config file in the config folder through the symlink 86 confFilePath := filepath.Join(confDirSymlink, "main.yaml") 87 require.NoError(t, os.WriteFile(confFilePath, []byte{}, 0o644)) 88 89 rdr := newDummyReader(confFilePath) 90 91 changeChan := make(chan struct{}) 92 var updatedConf stream.Config 93 require.NoError(t, rdr.SubscribeConfigChanges(func(conf stream.Config) bool { 94 updatedConf = conf 95 close(changeChan) 96 return true 97 })) 98 99 // Watch for configuration changes 100 testMgr, err := manager.NewV2(manager.NewResourceConfig(), nil, log.Noop(), metrics.Noop()) 101 require.NoError(t, err) 102 require.NoError(t, rdr.BeginFileWatching(testMgr, true)) 103 104 // Create a new config folder and place in it a new copy of the config file 105 newConfDir := filepath.Join(rootDir, "config_new") 106 require.NoError(t, os.Mkdir(newConfDir, 0o755)) 107 require.NoError(t, os.WriteFile(filepath.Join(newConfDir, "main.yaml"), dummyConfig, 0o644)) 108 109 // Create a symlink to the new config folder 110 newConfDirSymlink := filepath.Join(rootDir, "symlink_new") 111 require.NoError(t, os.Symlink(newConfDir, newConfDirSymlink)) 112 113 // Overwrite the original symlink with the new symlink 114 require.NoError(t, os.Rename(newConfDirSymlink, confDirSymlink)) 115 116 // Remove the original config folder to trigger a config refresh 117 require.NoError(t, os.RemoveAll(confDir)) 118 119 // Wait for the config watcher to reload the config 120 select { 121 case <-changeChan: 122 case <-time.After(100 * time.Millisecond): 123 require.FailNow(t, "Expected a config change to be triggered") 124 } 125 126 assert.Equal(t, "kafka", updatedConf.Input.Type) 127 assert.Equal(t, "aws_s3", updatedConf.Output.Type) 128 }