162 lines
3.1 KiB
Go
162 lines
3.1 KiB
Go
// Copyright 2022 PingCAP, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package watcher
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestWatcher(t *testing.T) {
|
|
var (
|
|
oldFilePath, newFilePath string
|
|
oldFileName = "mysql-bin.000001"
|
|
newFileName = "mysql-bin.000002"
|
|
wg sync.WaitGroup
|
|
)
|
|
|
|
// create dir
|
|
dir := t.TempDir()
|
|
|
|
// join the path
|
|
oldFilePath = filepath.Join(dir, oldFileName)
|
|
newFilePath = filepath.Join(dir, newFileName)
|
|
|
|
// create watcher
|
|
w := NewWatcher()
|
|
|
|
// watch directory
|
|
err := w.Add(dir)
|
|
require.NoError(t, err)
|
|
|
|
// start watcher
|
|
err = w.Start(10 * time.Millisecond)
|
|
require.NoError(t, err)
|
|
defer w.Close()
|
|
|
|
// create file
|
|
f, err := os.Create(oldFilePath)
|
|
require.NoError(t, err)
|
|
f.Close()
|
|
|
|
// watch for create
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
assertEvent(w, oldFilePath, Create, t)
|
|
}()
|
|
wg.Wait()
|
|
|
|
// watch for write
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
assertEvent(w, oldFilePath, Modify, t)
|
|
}()
|
|
|
|
f, err = os.OpenFile(oldFilePath, os.O_WRONLY, 0766)
|
|
require.NoError(t, err)
|
|
f.Write([]byte("meaningless content"))
|
|
f.Close()
|
|
wg.Wait()
|
|
|
|
// watch for chmod
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
assertEvent(w, oldFilePath, Chmod, t)
|
|
}()
|
|
|
|
err = os.Chmod(oldFilePath, 0777)
|
|
require.NoError(t, err)
|
|
wg.Wait()
|
|
|
|
// watch for rename
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
assertEvent(w, oldFilePath, Rename, t)
|
|
}()
|
|
|
|
err = os.Rename(oldFilePath, newFilePath)
|
|
require.NoError(t, err)
|
|
wg.Wait()
|
|
|
|
// watch for remove
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
assertEvent(w, newFilePath, Remove, t)
|
|
}()
|
|
|
|
err = os.Remove(newFilePath)
|
|
require.NoError(t, err)
|
|
wg.Wait()
|
|
|
|
// watch for create again
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
assertEvent(w, oldFilePath, Create, t)
|
|
}()
|
|
|
|
// create file again
|
|
f, err = os.Create(oldFilePath)
|
|
require.NoError(t, err)
|
|
f.Close()
|
|
wg.Wait()
|
|
|
|
// create another dir
|
|
dir2 := t.TempDir()
|
|
oldFilePath2 := filepath.Join(dir2, oldFileName)
|
|
|
|
// add another directory for watching
|
|
err = w.Add(dir2)
|
|
require.NoError(t, err)
|
|
|
|
// watch for move (rename to another directory)
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
assertEvent(w, oldFilePath, Move, t)
|
|
}()
|
|
|
|
err = os.Rename(oldFilePath, oldFilePath2)
|
|
require.NoError(t, err)
|
|
wg.Wait()
|
|
}
|
|
|
|
func assertEvent(w *Watcher, path string, op Op, t *testing.T) {
|
|
for {
|
|
select {
|
|
case ev := <-w.Events:
|
|
if ev.IsDirEvent() {
|
|
continue // skip event for directory
|
|
}
|
|
require.True(t, ev.HasOps(op))
|
|
require.Equal(t, path, ev.Path)
|
|
return
|
|
case err2 := <-w.Errors:
|
|
t.Fatal(err2)
|
|
return
|
|
}
|
|
}
|
|
}
|