TestSupervisor_StopConcurrent exercises the s.stopping guard: several goroutines call Stop concurrently while the watcher is live in sess.Wait(). All calls must return without error and observe a fully-shut-down supervisor.
(t *testing.T)
| 800 | // sess.Wait(). All calls must return without error and observe a |
| 801 | // fully-shut-down supervisor. |
| 802 | func TestSupervisor_StopConcurrent(t *testing.T) { |
| 803 | t.Parallel() |
| 804 | |
| 805 | sess := newFakeSession() |
| 806 | c := newScriptedConnector(scriptStep{session: sess}) |
| 807 | s := lifecycle.New("test", c, lifecycle.Policy{}) |
| 808 | |
| 809 | assert.NilError(t, s.Start(t.Context())) |
| 810 | sess.waitParked(t) |
| 811 | |
| 812 | const n = 4 |
| 813 | errs := make(chan error, n) |
| 814 | var wg sync.WaitGroup |
| 815 | wg.Add(n) |
| 816 | for range n { |
| 817 | go func() { |
| 818 | defer wg.Done() |
| 819 | errs <- s.Stop(t.Context()) |
| 820 | }() |
| 821 | } |
| 822 | wg.Wait() |
| 823 | close(errs) |
| 824 | |
| 825 | for err := range errs { |
| 826 | assert.NilError(t, err) |
| 827 | } |
| 828 | assert.Check(t, is.Equal(s.State().State, lifecycle.StateStopped)) |
| 829 | assert.Check(t, sess.waitDone.Load(), "a Stop returned before watcher's Wait() completed") |
| 830 | } |
nothing calls this directly
no test coverage detected