github.com/Jeffail/benthos/v3@v3.65.0/internal/shutdown/signaller_test.go (about) 1 package shutdown 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func assertOpen(t *testing.T, c <-chan struct{}) { 12 t.Helper() 13 select { 14 case <-c: 15 t.Error("expected channel to be open") 16 default: 17 } 18 } 19 20 func assertClosed(t *testing.T, c <-chan struct{}) { 21 t.Helper() 22 select { 23 case <-c: 24 case <-time.After(time.Millisecond * 100): 25 t.Error("expected channel to be closed") 26 } 27 } 28 29 func TestSignallerNotClosed(t *testing.T) { 30 s := NewSignaller() 31 32 assertOpen(t, s.CloseAtLeisureChan()) 33 assert.False(t, s.ShouldCloseAtLeisure()) 34 35 assertOpen(t, s.CloseNowChan()) 36 assert.False(t, s.ShouldCloseNow()) 37 38 assertOpen(t, s.HasClosedChan()) 39 assert.False(t, s.HasClosed()) 40 41 s.ShutdownComplete() 42 43 assertOpen(t, s.CloseAtLeisureChan()) 44 assert.False(t, s.ShouldCloseAtLeisure()) 45 46 assertOpen(t, s.CloseNowChan()) 47 assert.False(t, s.ShouldCloseNow()) 48 49 assertClosed(t, s.HasClosedChan()) 50 assert.True(t, s.HasClosed()) 51 } 52 53 func TestSignallerAtLeisure(t *testing.T) { 54 s := NewSignaller() 55 s.CloseAtLeisure() 56 57 assertClosed(t, s.CloseAtLeisureChan()) 58 assert.True(t, s.ShouldCloseAtLeisure()) 59 60 assertOpen(t, s.CloseNowChan()) 61 assert.False(t, s.ShouldCloseNow()) 62 63 assertOpen(t, s.HasClosedChan()) 64 assert.False(t, s.HasClosed()) 65 66 s.ShutdownComplete() 67 68 assertClosed(t, s.CloseAtLeisureChan()) 69 assert.True(t, s.ShouldCloseAtLeisure()) 70 71 assertOpen(t, s.CloseNowChan()) 72 assert.False(t, s.ShouldCloseNow()) 73 74 assertClosed(t, s.HasClosedChan()) 75 assert.True(t, s.HasClosed()) 76 } 77 78 func TestSignallerNow(t *testing.T) { 79 s := NewSignaller() 80 s.CloseNow() 81 82 assertClosed(t, s.CloseAtLeisureChan()) 83 assert.True(t, s.ShouldCloseAtLeisure()) 84 85 assertClosed(t, s.CloseNowChan()) 86 assert.True(t, s.ShouldCloseNow()) 87 88 assertOpen(t, s.HasClosedChan()) 89 assert.False(t, s.HasClosed()) 90 91 s.ShutdownComplete() 92 93 assertClosed(t, s.CloseAtLeisureChan()) 94 assert.True(t, s.ShouldCloseAtLeisure()) 95 96 assertClosed(t, s.CloseNowChan()) 97 assert.True(t, s.ShouldCloseNow()) 98 99 assertClosed(t, s.HasClosedChan()) 100 assert.True(t, s.HasClosed()) 101 } 102 103 func TestSignallerAtLeisureCtx(t *testing.T) { 104 s := NewSignaller() 105 106 // Cancelled from original context 107 inCtx, inDone := context.WithCancel(context.Background()) 108 ctx, done := s.CloseAtLeisureCtx(inCtx) 109 assertOpen(t, ctx.Done()) 110 inDone() 111 assertClosed(t, ctx.Done()) 112 done() 113 114 // Cancelled from returned cancel func 115 inCtx, inDone = context.WithCancel(context.Background()) 116 ctx, done = s.CloseAtLeisureCtx(inCtx) 117 assertOpen(t, ctx.Done()) 118 done() 119 assertClosed(t, ctx.Done()) 120 inDone() 121 122 // Cancelled from at leisure signal 123 inCtx, inDone = context.WithCancel(context.Background()) 124 ctx, done = s.CloseAtLeisureCtx(inCtx) 125 assertOpen(t, ctx.Done()) 126 s.CloseAtLeisure() 127 assertClosed(t, ctx.Done()) 128 done() 129 inDone() 130 131 // Cancelled from at immediate signal 132 inCtx, inDone = context.WithCancel(context.Background()) 133 s = NewSignaller() 134 ctx, done = s.CloseAtLeisureCtx(inCtx) 135 assertOpen(t, ctx.Done()) 136 s.CloseNow() 137 assertClosed(t, ctx.Done()) 138 done() 139 inDone() 140 } 141 142 func TestSignallerNowCtx(t *testing.T) { 143 s := NewSignaller() 144 145 // Cancelled from original context 146 inCtx, inDone := context.WithCancel(context.Background()) 147 ctx, done := s.CloseNowCtx(inCtx) 148 assertOpen(t, ctx.Done()) 149 inDone() 150 assertClosed(t, ctx.Done()) 151 done() 152 153 // Cancelled from returned cancel func 154 inCtx, inDone = context.WithCancel(context.Background()) 155 ctx, done = s.CloseNowCtx(inCtx) 156 assertOpen(t, ctx.Done()) 157 done() 158 assertClosed(t, ctx.Done()) 159 inDone() 160 161 // Not cancelled from at leisure signal 162 inCtx, inDone = context.WithCancel(context.Background()) 163 ctx, done = s.CloseNowCtx(inCtx) 164 assertOpen(t, ctx.Done()) 165 s.CloseAtLeisure() 166 assertOpen(t, ctx.Done()) 167 done() 168 assertClosed(t, ctx.Done()) 169 inDone() 170 171 // Cancelled from at immediate signal 172 inCtx, inDone = context.WithCancel(context.Background()) 173 ctx, done = s.CloseNowCtx(inCtx) 174 assertOpen(t, ctx.Done()) 175 s.CloseNow() 176 assertClosed(t, ctx.Done()) 177 done() 178 inDone() 179 } 180 181 func TestSignallerHasClosedCtx(t *testing.T) { 182 s := NewSignaller() 183 184 // Cancelled from original context 185 inCtx, inDone := context.WithCancel(context.Background()) 186 ctx, done := s.HasClosedCtx(inCtx) 187 assertOpen(t, ctx.Done()) 188 inDone() 189 assertClosed(t, ctx.Done()) 190 done() 191 192 // Cancelled from returned cancel func 193 inCtx, inDone = context.WithCancel(context.Background()) 194 ctx, done = s.HasClosedCtx(inCtx) 195 assertOpen(t, ctx.Done()) 196 done() 197 assertClosed(t, ctx.Done()) 198 inDone() 199 200 // Cancelled from at leisure signal 201 inCtx, inDone = context.WithCancel(context.Background()) 202 ctx, done = s.HasClosedCtx(inCtx) 203 assertOpen(t, ctx.Done()) 204 s.ShutdownComplete() 205 assertClosed(t, ctx.Done()) 206 done() 207 inDone() 208 }