Files
gvisor-tap-vsock/pkg/utils/filewatcher_test.go
Fata Nugraha e52ce48f63 Extract out filewatcher functionality
Signed-off-by: Fata Nugraha <fatanugraha@outlook.com>
2025-01-14 19:23:17 +08:00

68 lines
1.6 KiB
Go

package utils
import (
"os"
"path/filepath"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestFileWatcher(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("1"), 0o600)
fw, err := NewFileWatcher(path)
fw.writeGracePeriod = 50 * time.Millisecond // reduce the delay to make the test runs faster.
assert.NoError(t, err)
_ = fw.w.Add(path)
var numTriggered atomic.Int64
assertNumTriggered := func(expected int) {
time.Sleep(fw.writeGracePeriod + 50*time.Millisecond)
assert.Equal(t, int64(expected), numTriggered.Load())
}
_ = fw.Start(func() {
numTriggered.Add(1)
})
// CASE: can detect changes to the file.
if err := os.WriteFile(path, []byte("2"), 0o600); err != nil {
panic(err)
}
assertNumTriggered(1)
// CASE: can detect "swap"-based file modification.
tmpFile := filepath.Join(dir, "tmp.txt")
if err := os.WriteFile(tmpFile, []byte("lol"), 0o600); err != nil {
panic(err)
}
if err := os.Rename(tmpFile, path); err != nil {
panic(err)
}
assertNumTriggered(2)
// CASE: combine multiple partial writes into single event.
fd, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0o600)
if err != nil {
panic(err)
}
// we assume these writes happens in less than 50ms.
_, _ = fd.Write([]byte("a"))
_ = fd.Sync()
_, _ = fd.Write([]byte("b"))
fd.Close()
assertNumTriggered(3)
// CASE: closed file watcher should not call the callback after Stop() is called.
assert.NoError(t, fw.Stop())
if err := os.WriteFile(path, []byte("2"), 0o600); err != nil {
panic(err)
}
assertNumTriggered(3) // does not change.
}