(t *testing.T)
| 56 | } |
| 57 | |
| 58 | func TestServiceFailureWatcherClose(t *testing.T) { |
| 59 | s1 := serviceThatDoesntDoAnything() |
| 60 | s2 := serviceThatDoesntDoAnything() |
| 61 | m, err := NewManager(s1, s2) |
| 62 | require.NoError(t, err) |
| 63 | |
| 64 | s3, errorsS3 := errorReturningService() |
| 65 | s4, errorsS4 := errorReturningService() |
| 66 | |
| 67 | require.NoError(t, StartManagerAndAwaitHealthy(context.Background(), m)) |
| 68 | require.NoError(t, StartAndAwaitRunning(context.Background(), s3)) |
| 69 | require.NoError(t, StartAndAwaitRunning(context.Background(), s4)) |
| 70 | |
| 71 | // All goroutines created until now are unrelated to failure watcher. |
| 72 | defer goleak.VerifyNone(t, goleak.IgnoreCurrent(), goleak.Cleanup(func(_ int) { |
| 73 | require.NoError(t, StopManagerAndAwaitStopped(context.Background(), m)) |
| 74 | // These services are expected to errors. |
| 75 | require.Error(t, StopAndAwaitTerminated(context.Background(), s3)) |
| 76 | require.Error(t, StopAndAwaitTerminated(context.Background(), s4)) |
| 77 | |
| 78 | goleak.VerifyNone(t) |
| 79 | })) |
| 80 | |
| 81 | // Watch manager and both services |
| 82 | w := NewFailureWatcher() |
| 83 | w.WatchManager(m) |
| 84 | w.WatchService(s3) |
| 85 | w.WatchService(s4) |
| 86 | |
| 87 | ch := w.Chan() |
| 88 | |
| 89 | // Verify that we receive error from s3. |
| 90 | err = fmt.Errorf("service3 error") |
| 91 | errorsS3 <- err |
| 92 | |
| 93 | require.ErrorIs(t, <-ch, err) |
| 94 | |
| 95 | // After closing failure watcher, we don't receive any more errors. |
| 96 | w.Close() |
| 97 | require.Nil(t, <-ch) |
| 98 | |
| 99 | // Even sending error from service 4 doesn't make it to failure watcher. |
| 100 | errorsS4 <- fmt.Errorf("service4 error") |
| 101 | require.Nil(t, <-ch) |
| 102 | |
| 103 | // Since watcher is now closed, it cannot be used to watch services or managers. |
| 104 | require.Panics(t, func() { |
| 105 | w.WatchService(s3) |
| 106 | }) |
| 107 | require.Panics(t, func() { |
| 108 | w.WatchManager(m) |
| 109 | }) |
| 110 | |
| 111 | // Repeated call to Close doesn't panic. |
| 112 | w.Close() |
| 113 | } |
| 114 | |
| 115 | // Creates service which will return first error passed to the channel. |
nothing calls this directly
no test coverage detected