summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2022-03-06 17:58:58 +0700
committerShulhan <ms@kilabit.info>2022-03-06 23:10:57 +0700
commit456bbd1166fd87984d98fbc6029b5ce9798e451b (patch)
treee60b8c1ae3ad6f5820d5f48d765a04403597cd6f
parent4dfd8ca2c40f6c904dac5789754020ef28887a7c (diff)
downloadpakakeh.go-456bbd1166fd87984d98fbc6029b5ce9798e451b.tar.xz
lib/memfs: move the test for NewWatcher and DirWatcher as example
With this we do one thing (write testing) and output two things (testing the code and give an example for code).
-rw-r--r--lib/memfs/dirwatcher_example_test.go168
-rw-r--r--lib/memfs/dirwatcher_test.go199
-rw-r--r--lib/memfs/watcher_example_test.go82
-rw-r--r--lib/memfs/watcher_test.go91
4 files changed, 253 insertions, 287 deletions
diff --git a/lib/memfs/dirwatcher_example_test.go b/lib/memfs/dirwatcher_example_test.go
new file mode 100644
index 00000000..a8468d80
--- /dev/null
+++ b/lib/memfs/dirwatcher_example_test.go
@@ -0,0 +1,168 @@
+// Copyright 2022, Shulhan <ms@kilabit.info>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package memfs
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+ "time"
+)
+
+func ExampleDirWatcher() {
+ var (
+ ns NodeState
+ rootDir string
+ err error
+ )
+
+ rootDir, err = ioutil.TempDir("", "libmemfs")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // In this example, we watch sub directory "assets" and its contents,
+ // include only file with .adoc extension and ignoring files with
+ // .html extension.
+ dw := &DirWatcher{
+ Options: Options{
+ Root: rootDir,
+ Includes: []string{
+ `assets/.*`,
+ `.*\.adoc$`,
+ },
+ Excludes: []string{
+ `.*\.html$`,
+ },
+ },
+ Delay: 150 * time.Millisecond,
+ }
+
+ err = dw.Start()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("Deleting the root directory:\n")
+ err = os.Remove(rootDir)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s\n", ns.State, ns.Node.Path)
+
+ // Create the root directory back with sub directory
+ // This will trigger two FileStateCreated events, one for "/" and one
+ // for "/assets".
+ dirAssets := filepath.Join(rootDir, "assets")
+ fmt.Printf("Re-create root directory with sub-directory:\n")
+ err = os.MkdirAll(dirAssets, 0770)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s\n", ns.State, ns.Node.Path)
+ ns = <-dw.C
+ fmt.Printf("-- %s %s\n", ns.State, ns.Node.Path)
+
+ // Modify the permission on root directory
+ fmt.Printf("Chmod on root directory:\n")
+ err = os.Chmod(rootDir, 0700)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s %s\n", ns.State, ns.Node.Path, ns.Node.Mode())
+
+ newFile := filepath.Join(rootDir, "new.adoc")
+ fmt.Println("Create new file on root directory: /new.adoc")
+ err = ioutil.WriteFile(newFile, nil, 0600)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s %s\n", ns.State, ns.Node.Path, ns.Node.Mode())
+
+ fmt.Println("Remove file on root directory: /new.adoc")
+ err = os.Remove(newFile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s %s\n", ns.State, ns.Node.Path, ns.Node.Mode())
+
+ // Create sub-directory.
+ subDir := filepath.Join(rootDir, "subdir")
+ fmt.Println("Create new sub-directory: /subdir")
+ err = os.Mkdir(subDir, 0770)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s %s\n", ns.State, ns.Node.Path, ns.Node.Mode())
+
+ // Add new file in sub directory.
+ newFile = filepath.Join(subDir, "new.adoc")
+ fmt.Println("Create new file in sub directory: /subdir/new.adoc")
+ err = ioutil.WriteFile(newFile, nil, 0600)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s %s\n", ns.State, ns.Node.Path, ns.Node.Mode())
+
+ fmt.Println("Remove file in sub directory: /subdir/new.adoc")
+ err = os.Remove(newFile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s %s\n", ns.State, ns.Node.Path, ns.Node.Mode())
+
+ // Creating file that is excluded should not trigger event.
+ newFile = filepath.Join(subDir, "new.html")
+ fmt.Println("Create excluded file in sub directory: /subdir/new.html")
+ err = ioutil.WriteFile(newFile, nil, 0600)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Create file without extension in directory "assets" should trigger
+ // event.
+ newFile = filepath.Join(dirAssets, "new")
+ fmt.Println("Create new file under assets: /assets/new")
+ err = ioutil.WriteFile(newFile, nil, 0600)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-dw.C
+ fmt.Printf("-- %s %s %s\n", ns.State, ns.Node.Path, ns.Node.Mode())
+
+ dw.Stop()
+
+ //Output:
+ //Deleting the root directory:
+ //-- FileStateDeleted /
+ //Re-create root directory with sub-directory:
+ //-- FileStateCreated /
+ //-- FileStateCreated /assets
+ //Chmod on root directory:
+ //-- FileStateUpdateMode / drwx------
+ //Create new file on root directory: /new.adoc
+ //-- FileStateCreated /new.adoc -rw-------
+ //Remove file on root directory: /new.adoc
+ //-- FileStateDeleted /new.adoc -rw-------
+ //Create new sub-directory: /subdir
+ //-- FileStateCreated /subdir drwxr-x---
+ //Create new file in sub directory: /subdir/new.adoc
+ //-- FileStateCreated /subdir/new.adoc -rw-------
+ //Remove file in sub directory: /subdir/new.adoc
+ //-- FileStateDeleted /subdir/new.adoc -rw-------
+ //Create excluded file in sub directory: /subdir/new.html
+ //Create new file under assets: /assets/new
+ //-- FileStateCreated /assets/new -rw-------
+}
diff --git a/lib/memfs/dirwatcher_test.go b/lib/memfs/dirwatcher_test.go
index 4bf1cd48..a62f6001 100644
--- a/lib/memfs/dirwatcher_test.go
+++ b/lib/memfs/dirwatcher_test.go
@@ -5,8 +5,6 @@
package memfs
import (
- "fmt"
- "io/ioutil"
"os"
"path/filepath"
"testing"
@@ -15,200 +13,6 @@ import (
"github.com/shuLhan/share/lib/test"
)
-func TestDirWatcher(t *testing.T) {
- var (
- err error
- gotNS NodeState
- dir string
- x int
- )
-
- dir = t.TempDir()
- if err != nil {
- t.Fatal(err)
- }
-
- fmt.Printf(">>> Watching directory %q for changes ...\n", dir)
-
- exps := []struct {
- path string
- state FileState
- }{{
- state: FileStateDeleted,
- path: "/",
- }, {
- state: FileStateCreated,
- path: "/",
- }, {
- state: FileStateCreated,
- path: "/assets",
- }, {
- state: FileStateUpdateMode,
- path: "/",
- }, {
- state: FileStateCreated,
- path: "/new.adoc",
- }, {
- state: FileStateDeleted,
- path: "/new.adoc",
- }, {
- state: FileStateCreated,
- path: "/sub",
- }, {
- state: FileStateCreated,
- path: "/sub/new.adoc",
- }, {
- state: FileStateDeleted,
- path: "/sub/new.adoc",
- }, {
- state: FileStateCreated,
- path: "/assets/new",
- }, {
- state: FileStateDeleted,
- path: "/assets/new",
- }}
-
- dw := &DirWatcher{
- Options: Options{
- Root: dir,
- Includes: []string{
- `assets/.*`,
- `.*\.adoc$`,
- },
- Excludes: []string{
- `.*\.html$`,
- },
- },
- Delay: 150 * time.Millisecond,
- }
-
- err = dw.Start()
- if err != nil {
- t.Fatal(err)
- }
-
- // Delete the directory being watched.
- t.Logf("Deleting root directory %q ...\n", dir)
- err = os.Remove(dir)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Create the watched directory back with sub directory
- // This will trigger two FileStateCreated events, one for "/" and one
- // for "/assets".
- dirAssets := filepath.Join(dir, "assets")
- t.Logf("Re-create root directory %q ...\n", dirAssets)
- err = os.MkdirAll(dirAssets, 0770)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Modify the permission on root directory
- t.Logf("Modify root directory %q ...\n", dir)
- err = os.Chmod(dir, 0700)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Add new file to watched directory.
- newFile := filepath.Join(dir, "new.adoc")
- t.Logf("Create new file on root directory: %q ...\n", newFile)
- err = ioutil.WriteFile(newFile, nil, 0600)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Remove file.
- t.Logf("Remove file on root directory: %q ...\n", newFile)
- err = os.Remove(newFile)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Create sub-directory.
- subDir := filepath.Join(dir, "sub")
- t.Logf("Create new sub-directory: %q ...\n", subDir)
- err = os.Mkdir(subDir, 0770)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Add new file in sub directory.
- newFile = filepath.Join(subDir, "new.adoc")
- t.Logf("Create new file in sub directory: %q ...\n", newFile)
- err = ioutil.WriteFile(newFile, nil, 0600)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Remove file in sub directory.
- t.Logf("Remove file in sub directory: %q ...\n", newFile)
- err = os.Remove(newFile)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- // Create exclude file, should not trigger event.
- newFile = filepath.Join(subDir, "new.html")
- t.Logf("Create excluded file in sub directory: %q ...\n", newFile)
- err = ioutil.WriteFile(newFile, nil, 0600)
- if err != nil {
- t.Fatal(err)
- }
-
- // Create file without extension in white list directory "assets",
- // should trigger event.
- newFile = filepath.Join(dirAssets, "new")
- t.Logf("Create new file on assets: %q ...\n", newFile)
- err = ioutil.WriteFile(newFile, nil, 0600)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-dw.C
- test.Assert(t, "path", exps[x].path, gotNS.Node.Path)
- test.Assert(t, "state", exps[x].state, gotNS.State)
- x++
-
- dw.Stop()
-}
-
//
// Test renaming sub-directory being watched.
//
@@ -270,6 +74,9 @@ func TestDirWatcher_renameDirectory(t *testing.T) {
<-dw.C
<-dw.C
+ // Wait for all watcher finished.
+ time.Sleep(400 * time.Millisecond)
+
var expDirs = []string{
"/newsubdir",
}
diff --git a/lib/memfs/watcher_example_test.go b/lib/memfs/watcher_example_test.go
new file mode 100644
index 00000000..9ef7d8e2
--- /dev/null
+++ b/lib/memfs/watcher_example_test.go
@@ -0,0 +1,82 @@
+// Copyright 2022, Shulhan <ms@kilabit.info>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package memfs
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "time"
+)
+
+func ExampleNewWatcher() {
+ var (
+ content = "Content of file"
+
+ f *os.File
+ watcher *Watcher
+ ns NodeState
+ err error
+ )
+
+ // Create a file to be watched.
+ f, err = ioutil.TempFile("", "watcher")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ watcher, err = NewWatcher(f.Name(), 150*time.Millisecond)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Update file mode.
+ err = f.Chmod(0700)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ ns = <-watcher.C
+ fmt.Printf("State: %s\n", ns.State)
+ fmt.Printf("File mode: %s\n", ns.Node.Mode())
+ fmt.Printf("File size: %d\n", ns.Node.Size())
+
+ // Update content of file.
+ _, err = f.WriteString(content)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-watcher.C
+ fmt.Printf("State: %s\n", ns.State)
+ fmt.Printf("File mode: %s\n", ns.Node.Mode())
+ fmt.Printf("File size: %d\n", ns.Node.Size())
+
+ err = f.Close()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Remove the file.
+ err = os.Remove(f.Name())
+ if err != nil {
+ log.Fatal(err)
+ }
+ ns = <-watcher.C
+ fmt.Printf("State: %s\n", ns.State)
+ fmt.Printf("File mode: %s\n", ns.Node.Mode())
+ fmt.Printf("File size: %d\n", ns.Node.Size())
+
+ //Output:
+ //State: FileStateUpdateMode
+ //File mode: -rwx------
+ //File size: 0
+ //State: FileStateUpdateContent
+ //File mode: -rwx------
+ //File size: 15
+ //State: FileStateDeleted
+ //File mode: -rwx------
+ //File size: 15
+}
diff --git a/lib/memfs/watcher_test.go b/lib/memfs/watcher_test.go
deleted file mode 100644
index 30693b7f..00000000
--- a/lib/memfs/watcher_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package memfs
-
-import (
- "io/ioutil"
- "os"
- "testing"
- "time"
-
- "github.com/shuLhan/share/lib/test"
-)
-
-type caseWatcher struct {
- state FileState
- mode os.FileMode
- size int64
-}
-
-func TestWatcher(t *testing.T) {
- var (
- content = "Write changes"
-
- f *os.File
- watcher *Watcher
- gotNS NodeState
- err error
- x int
- )
-
- f, err = ioutil.TempFile("", "watcher")
- if err != nil {
- t.Fatal(err)
- }
-
- exps := []caseWatcher{{
- state: FileStateUpdateMode,
- mode: 0700,
- }, {
- state: FileStateUpdateContent,
- mode: 0700,
- size: int64(len(content)),
- }, {
- state: FileStateDeleted,
- mode: 0700,
- size: int64(len(content)),
- }}
-
- watcher, err = NewWatcher(f.Name(), 150*time.Millisecond)
- if err != nil {
- t.Fatal(err)
- }
-
- // Update file mode
- err = f.Chmod(0700)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-watcher.C
- test.Assert(t, "state", exps[x].state, gotNS.State)
- test.Assert(t, "file mode", exps[x].mode, gotNS.Node.Mode())
- test.Assert(t, "file size", exps[x].size, gotNS.Node.Size())
- x++
-
- _, err = f.WriteString(content)
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-watcher.C
- test.Assert(t, "state", exps[x].state, gotNS.State)
- test.Assert(t, "file mode", exps[x].mode, gotNS.Node.Mode())
- test.Assert(t, "file size", exps[x].size, gotNS.Node.Size())
- x++
-
- err = f.Close()
- if err != nil {
- t.Fatal(err)
- }
-
- err = os.Remove(f.Name())
- if err != nil {
- t.Fatal(err)
- }
- gotNS = <-watcher.C
- test.Assert(t, "state", exps[x].state, gotNS.State)
- test.Assert(t, "file mode", exps[x].mode, gotNS.Node.Mode())
- test.Assert(t, "file size", exps[x].size, gotNS.Node.Size())
- x++
-}