github.com/verrazzano/verrazzano@v1.7.0/platform-operator/internal/monitor/monitor_test.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package monitor 5 6 import ( 7 "fmt" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 ctrlerrors "github.com/verrazzano/verrazzano/pkg/controller/errors" 13 ) 14 15 var fakeCompName = "fake-component-name" 16 17 func TestMonitorTypeIsRunning(t *testing.T) { 18 a := assert.New(t) 19 20 m := &BackgroundProcessMonitorType{ComponentName: fakeCompName} 21 blocker := make(chan int) 22 finished := make(chan int) 23 operation := func() error { 24 defer func() { finished <- 0 }() 25 <-blocker 26 return nil 27 } 28 29 a.False(m.IsRunning()) 30 31 m.Run(operation) 32 a.True(m.IsRunning()) 33 34 // send to the channel to unblock operation 35 blocker <- 0 36 37 // block until the operation says it's finished 38 <-finished 39 40 // even after the operation is finished, the monitor should still be "running" unless reset 41 a.True(m.IsRunning()) 42 } 43 44 func TestMonitorTypeCheckResultWhileRunning(t *testing.T) { 45 a := assert.New(t) 46 47 m := &BackgroundProcessMonitorType{ComponentName: fakeCompName} 48 blocker := make(chan int) 49 operation := func() error { 50 <-blocker 51 return nil 52 } 53 54 m.Run(operation) 55 res, err := m.CheckResult() 56 a.Equal(false, res) 57 a.Equal(ctrlerrors.RetryableError{Source: fakeCompName}, err) 58 blocker <- 0 59 } 60 61 func TestMonitorTypeCheckResult(t *testing.T) { 62 a := assert.New(t) 63 64 errMsg := "an error from the background operation" 65 tests := []struct { 66 success bool 67 expectedResult bool 68 expectedError error 69 }{ 70 { 71 success: true, 72 expectedResult: true, 73 }, 74 { 75 success: false, 76 expectedResult: false, 77 }, 78 } 79 80 for _, tt := range tests { 81 m := &BackgroundProcessMonitorType{ComponentName: fakeCompName} 82 operation := func() error { 83 if tt.success { 84 return nil 85 } 86 return fmt.Errorf(errMsg) 87 } 88 89 // Run the background goroutine 90 m.Run(operation) 91 92 // CheckResult returns an error if the operation has not yet completed, so keep checking until complete 93 if res, ok := waitForResult(t, m); ok { 94 a.Equal(tt.expectedResult, res) 95 } else { 96 a.Fail("Expected a result from CheckResult but never received one") 97 } 98 } 99 } 100 101 // waitForResult waits for the background process result to be available. Returns the value of 102 // the result and true if a result was received, or false if we timed out waiting. 103 func waitForResult(t *testing.T, monitor *BackgroundProcessMonitorType) (bool, bool) { 104 var res, gotResult bool 105 for i := 0; i < 100; i++ { 106 var err error 107 // CheckResult returns an error if the operation is still running 108 res, err = monitor.CheckResult() 109 if err != nil { 110 t.Log("Waiting for result...") 111 time.Sleep(100 * time.Millisecond) 112 continue 113 } 114 gotResult = true 115 break 116 } 117 return res, gotResult 118 } 119 120 func TestMonitorTypeReset(t *testing.T) { 121 a := assert.New(t) 122 123 m := &BackgroundProcessMonitorType{ComponentName: fakeCompName} 124 operation := func() error { 125 return nil 126 } 127 128 // Run the background goroutine 129 m.Run(operation) 130 131 // Wait for the operation result to be available 132 if res, ok := waitForResult(t, m); ok { 133 a.True(res) 134 } else { 135 a.Fail("Expected a result from CheckResult but never received one") 136 } 137 138 a.True(m.IsRunning()) 139 140 m.Reset() 141 res, _ := m.CheckResult() 142 a.False(res) 143 a.False(m.IsRunning()) 144 } 145 146 func TestMonitorTypeIsCompleted(t *testing.T) { 147 a := assert.New(t) 148 149 m := &BackgroundProcessMonitorType{ComponentName: fakeCompName} 150 blocker := make(chan int) 151 finished := make(chan int) 152 operation := func() error { 153 defer func() { finished <- 0 }() 154 <-blocker 155 return nil 156 } 157 158 m.Run(operation) 159 a.True(m.IsRunning()) 160 m.SetCompleted() 161 a.True(m.IsCompleted()) 162 a.False(m.IsRunning()) 163 164 // send to the channel to unblock operation 165 blocker <- 0 166 167 // block until the operation says it's finished 168 <-finished 169 }