go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/_motor/providers/os/events/watcher_test.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package events 5 6 import ( 7 "io/ioutil" 8 "path/filepath" 9 "sync" 10 "testing" 11 "time" 12 13 "go.mondoo.com/cnquery/motor/providers" 14 "go.mondoo.com/cnquery/motor/providers/mock" 15 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 ) 19 20 type WatcherTester struct { 21 mock providers.Instance 22 watcher *Watcher 23 } 24 25 func SetupWatcherTest() *WatcherTester { 26 filepath, _ := filepath.Abs("testdata/watcher_test.toml") 27 trans, _ := mock.NewFromTomlFile(filepath) 28 return &WatcherTester{watcher: NewWatcher(trans), mock: trans} 29 } 30 31 func TeardownWatcherTest(wt *WatcherTester) { 32 wt.watcher.TearDown() 33 } 34 35 func TestCommandSubscribe(t *testing.T) { 36 var wg sync.WaitGroup 37 wt := SetupWatcherTest() 38 w := wt.watcher 39 40 var res *CommandObservable 41 wg.Add(1) 42 w.Subscribe("command", "hostname", func(co providers.Observable) { 43 switch x := co.(type) { 44 case *CommandObservable: 45 defer wg.Done() 46 res = x 47 default: 48 } 49 }) 50 wg.Wait() 51 52 stdout, err := ioutil.ReadAll(res.Result.Stdout) 53 assert.Nil(t, err, "could extract stdout") 54 assert.Equal(t, "mockland.local", string(stdout), "get the expected command output") 55 TeardownWatcherTest(wt) 56 } 57 58 func TestFileSubscribe(t *testing.T) { 59 var wg sync.WaitGroup 60 wt := SetupWatcherTest() 61 w := wt.watcher 62 63 var res *FileObservable 64 65 wg.Add(1) 66 err := w.Subscribe("file", "/tmp/test", func(fo providers.Observable) { 67 switch x := fo.(type) { 68 case *FileObservable: 69 defer wg.Done() 70 res = x 71 default: 72 } 73 }) 74 require.NoError(t, err) 75 wg.Wait() 76 content, err := ioutil.ReadAll(res.File) 77 assert.Nil(t, err, "file content was returned without any error") 78 assert.Equal(t, "test", string(content), "get the expected command output") 79 80 TeardownWatcherTest(wt) 81 } 82 83 func TestFileChangeEvents(t *testing.T) { 84 var waitInitialRead sync.WaitGroup 85 var waitFileUpdate sync.WaitGroup 86 var waitSecondRead sync.WaitGroup 87 88 wt := SetupWatcherTest() 89 w := wt.watcher 90 // wait 500ms 91 w.SleepDuration = time.Duration(2 * time.Millisecond) 92 93 res := []string{} 94 readCount := 0 95 waitInitialRead.Add(1) 96 waitFileUpdate.Add(1) 97 waitSecondRead.Add(1) 98 99 err := w.Subscribe("file", "/tmp/test", func(fo providers.Observable) { 100 switch x := fo.(type) { 101 case *FileObservable: 102 if readCount == 0 { 103 defer waitInitialRead.Done() 104 } else if readCount == 1 { 105 waitFileUpdate.Wait() 106 defer waitSecondRead.Done() 107 } else { 108 return 109 } 110 content, err := ioutil.ReadAll(x.File) 111 if err == nil { 112 res = append(res, string(content)) 113 } 114 readCount++ 115 default: 116 } 117 }) 118 require.NoError(t, err) 119 120 waitInitialRead.Wait() 121 122 // change file content 123 mt := wt.mock.(*mock.Provider) 124 mt.Fs.Files["/tmp/test"].Content = "newtest" 125 waitFileUpdate.Done() 126 127 waitSecondRead.Wait() 128 129 assert.Equal(t, []string{"test", "newtest"}, res, "detect file change") 130 131 TeardownWatcherTest(wt) 132 }