github.com/argoproj/argo-events@v1.9.1/eventsources/common/naivewatcher/watcher_test.go (about) 1 package naivewatcher 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "syscall" 8 "testing" 9 "time" 10 11 "github.com/argoproj/argo-events/eventsources/common/fsevent" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 type WatchableTestFS struct { 16 } 17 18 type TestFSID struct { 19 Device int32 20 Inode uint64 21 } 22 23 func (w *WatchableTestFS) Walk(root string, walkFn filepath.WalkFunc) error { 24 return filepath.Walk(root, walkFn) 25 } 26 27 func (w *WatchableTestFS) GetFileID(fi os.FileInfo) interface{} { 28 stat := fi.Sys().(*syscall.Stat_t) 29 return TestFSID{ 30 Device: int32(stat.Dev), 31 Inode: stat.Ino, 32 } 33 } 34 35 func TestWatcherAutoCheck(t *testing.T) { 36 watcher, err := NewWatcher(&WatchableTestFS{}) 37 if err != nil { 38 t.Fatal(err) 39 } 40 defer watcher.Close() 41 42 tmpdir, err := os.MkdirTemp("", "naive-watcher-") 43 if err != nil { 44 t.Fatal(err) 45 } 46 defer os.RemoveAll(tmpdir) 47 48 err = watcher.Add(tmpdir) 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 err = watcher.Start(50 * time.Millisecond) 54 if err != nil { 55 t.Fatal(err) 56 } 57 defer func() { 58 if err := watcher.Stop(); err != nil { 59 fmt.Printf("failed to stop the watcher. err: %+v\n", err) 60 } 61 }() 62 63 // Create a file 64 _, err = os.Create(filepath.Join(tmpdir, "foo")) 65 if err != nil { 66 t.Fatal(err) 67 } 68 time.Sleep(300 * time.Millisecond) 69 events := readEvents(t, watcher) 70 assert.Equal(t, []fsevent.Event{ 71 {Op: fsevent.Create, Name: filepath.Join(tmpdir, "foo")}, 72 }, events) 73 74 // Rename a file 75 err = os.Rename(filepath.Join(tmpdir, "foo"), filepath.Join(tmpdir, "bar")) 76 if err != nil { 77 t.Fatal(err) 78 } 79 time.Sleep(300 * time.Millisecond) 80 events = readEvents(t, watcher) 81 assert.Equal(t, []fsevent.Event{ 82 {Op: fsevent.Rename, Name: filepath.Join(tmpdir, "bar")}, 83 }, events) 84 85 // Write a file 86 err = os.WriteFile(filepath.Join(tmpdir, "bar"), []byte("wow"), 0666) 87 if err != nil { 88 t.Fatal(err) 89 } 90 time.Sleep(300 * time.Millisecond) 91 events = readEvents(t, watcher) 92 assert.Equal(t, []fsevent.Event{ 93 {Op: fsevent.Write, Name: filepath.Join(tmpdir, "bar")}, 94 }, events) 95 96 // Chmod a file 97 err = os.Chmod(filepath.Join(tmpdir, "bar"), 0777) 98 if err != nil { 99 t.Fatal(err) 100 } 101 time.Sleep(300 * time.Millisecond) 102 events = readEvents(t, watcher) 103 assert.Equal(t, []fsevent.Event{ 104 {Op: fsevent.Chmod, Name: filepath.Join(tmpdir, "bar")}, 105 }, events) 106 107 // Rename & Write & Chmod a file 108 err = os.Rename(filepath.Join(tmpdir, "bar"), filepath.Join(tmpdir, "foo")) 109 if err != nil { 110 t.Fatal(err) 111 } 112 err = os.WriteFile(filepath.Join(tmpdir, "foo"), []byte("wowwow"), 0666) 113 if err != nil { 114 t.Fatal(err) 115 } 116 err = os.Chmod(filepath.Join(tmpdir, "foo"), 0770) 117 if err != nil { 118 t.Fatal(err) 119 } 120 var actualOps fsevent.Op 121 time.Sleep(300 * time.Millisecond) 122 events = readEvents(t, watcher) 123 for _, event := range events { 124 if event.Name == filepath.Join(tmpdir, "foo") { 125 actualOps |= event.Op 126 } 127 } 128 assert.Equal(t, fsevent.Write|fsevent.Rename|fsevent.Chmod, actualOps) 129 130 // Remove a file 131 err = os.Remove(filepath.Join(tmpdir, "foo")) 132 if err != nil { 133 t.Fatal(err) 134 } 135 time.Sleep(300 * time.Millisecond) 136 events = readEvents(t, watcher) 137 assert.Equal(t, []fsevent.Event{ 138 {Op: fsevent.Remove, Name: filepath.Join(tmpdir, "foo")}, 139 }, events) 140 141 err = watcher.Stop() 142 if err != nil { 143 t.Fatal(err) 144 } 145 146 err = watcher.Remove(tmpdir) 147 if err != nil { 148 t.Fatal(err) 149 } 150 } 151 152 func TestWatcherManualCheck(t *testing.T) { 153 watcher, err := NewWatcher(&WatchableTestFS{}) 154 if err != nil { 155 t.Fatal(err) 156 } 157 defer watcher.Close() 158 159 tmpdir, err := os.MkdirTemp("", "naive-watcher-") 160 if err != nil { 161 t.Fatal(err) 162 } 163 defer os.RemoveAll(tmpdir) 164 165 err = watcher.Add(tmpdir) 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 events := checkAndReadEvents(t, watcher) 171 assert.Equal(t, []fsevent.Event{}, events) 172 173 // Create a file 174 _, err = os.Create(filepath.Join(tmpdir, "foo")) 175 if err != nil { 176 t.Fatal(err) 177 } 178 events = checkAndReadEvents(t, watcher) 179 assert.Equal(t, []fsevent.Event{ 180 {Op: fsevent.Create, Name: filepath.Join(tmpdir, "foo")}, 181 }, events) 182 183 // Rename a file 184 err = os.Rename(filepath.Join(tmpdir, "foo"), filepath.Join(tmpdir, "bar")) 185 if err != nil { 186 t.Fatal(err) 187 } 188 events = checkAndReadEvents(t, watcher) 189 assert.Equal(t, []fsevent.Event{ 190 {Op: fsevent.Rename, Name: filepath.Join(tmpdir, "bar")}, 191 }, events) 192 193 // Write a file 194 err = os.WriteFile(filepath.Join(tmpdir, "bar"), []byte("wow"), 0666) 195 if err != nil { 196 t.Fatal(err) 197 } 198 events = checkAndReadEvents(t, watcher) 199 assert.Equal(t, []fsevent.Event{ 200 {Op: fsevent.Write, Name: filepath.Join(tmpdir, "bar")}, 201 }, events) 202 203 // Chmod a file 204 err = os.Chmod(filepath.Join(tmpdir, "bar"), 0777) 205 if err != nil { 206 t.Fatal(err) 207 } 208 events = checkAndReadEvents(t, watcher) 209 assert.Equal(t, []fsevent.Event{ 210 {Op: fsevent.Chmod, Name: filepath.Join(tmpdir, "bar")}, 211 }, events) 212 213 // Rename & Write & Chmod a file 214 err = os.Rename(filepath.Join(tmpdir, "bar"), filepath.Join(tmpdir, "foo")) 215 if err != nil { 216 t.Fatal(err) 217 } 218 err = os.WriteFile(filepath.Join(tmpdir, "foo"), []byte("wowwow"), 0666) 219 if err != nil { 220 t.Fatal(err) 221 } 222 err = os.Chmod(filepath.Join(tmpdir, "foo"), 0770) 223 if err != nil { 224 t.Fatal(err) 225 } 226 events = checkAndReadEvents(t, watcher) 227 assert.Equal(t, []fsevent.Event{ 228 {Op: fsevent.Write | fsevent.Rename | fsevent.Chmod, Name: filepath.Join(tmpdir, "foo")}, 229 }, events) 230 231 // Remove a file 232 err = os.Remove(filepath.Join(tmpdir, "foo")) 233 if err != nil { 234 t.Fatal(err) 235 } 236 events = checkAndReadEvents(t, watcher) 237 assert.Equal(t, []fsevent.Event{ 238 {Op: fsevent.Remove, Name: filepath.Join(tmpdir, "foo")}, 239 }, events) 240 241 err = watcher.Remove(tmpdir) 242 if err != nil { 243 t.Fatal(err) 244 } 245 } 246 247 func checkAndReadEvents(t *testing.T, watcher *Watcher) []fsevent.Event { 248 err := watcher.Check() 249 if err != nil { 250 t.Fatal(err) 251 } 252 return readEvents(t, watcher) 253 } 254 255 func readEvents(t *testing.T, watcher *Watcher) []fsevent.Event { 256 events := []fsevent.Event{} 257 L: 258 for { 259 select { 260 case event := <-watcher.Events: 261 events = append(events, event) 262 default: 263 break L 264 } 265 } 266 return events 267 }