diff --git a/annotated_test.go b/annotated_test.go index 7eefddde4..b7d521715 100644 --- a/annotated_test.go +++ b/annotated_test.go @@ -1500,6 +1500,8 @@ func assertApp( require.NoError(t, app.Stop(ctx)) assert.True(t, *stopped) } + + defer app.Stop(ctx) } func TestHookAnnotations(t *testing.T) { diff --git a/app_test.go b/app_test.go index df3bf8bcd..9f705834e 100644 --- a/app_test.go +++ b/app_test.go @@ -918,43 +918,6 @@ func TestTimeoutOptions(t *testing.T) { assert.True(t, stopped, "app wasn't stopped") } -func TestRecoverFromPanicsOption(t *testing.T) { - t.Parallel() - - t.Run("CannotGiveToModule", func(t *testing.T) { - t.Parallel() - mod := Module("MyModule", RecoverFromPanics()) - err := New(mod).Err() - require.Error(t, err) - require.Contains(t, err.Error(), - "fx.RecoverFromPanics Option should be passed to top-level App, "+ - "not to fx.Module") - }) - - run := func(withOption bool) { - opts := []Option{ - Provide(func() int { - panic("terrible sorrow") - }), - Invoke(func(a int) {}), - } - if withOption { - opts = append(opts, RecoverFromPanics()) - app := New(opts...) - err := app.Err() - require.Error(t, err) - assert.Contains(t, err.Error(), - `panic: "terrible sorrow" in func: "go.uber.org/fx_test".TestRecoverFromPanicsOption.`) - } else { - assert.Panics(t, func() { New(opts...) }, - "expected panic without RecoverFromPanics() option") - } - } - - t.Run("WithoutOption", func(t *testing.T) { run(false) }) - t.Run("WithOption", func(t *testing.T) { run(true) }) -} - func TestAppRunTimeout(t *testing.T) { t.Parallel() @@ -1461,6 +1424,7 @@ func TestAppStart(t *testing.T) { } app.Stop(ctx) assert.NoError(t, app.Start(ctx)) + app.Stop(ctx) }) } diff --git a/internal/leaky_test/leaky_test.go b/internal/leaky_test/leaky_test.go new file mode 100644 index 000000000..3307494f0 --- /dev/null +++ b/internal/leaky_test/leaky_test.go @@ -0,0 +1,69 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// leaky_test contains tests that are explicitly leaking goroutines because they +// trigger a panic on purpose. +// To prevent these from making it difficult for us to use goleak for tests in +// fx_test, we contain these here. +package leaky_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/fx" +) + +func TestRecoverFromPanicsOption(t *testing.T) { + t.Parallel() + + t.Run("CannotGiveToModule", func(t *testing.T) { + t.Parallel() + mod := fx.Module("MyModule", fx.RecoverFromPanics()) + err := fx.New(mod).Err() + require.Error(t, err) + require.Contains(t, err.Error(), + "fx.RecoverFromPanics Option should be passed to top-level App, "+ + "not to fx.Module") + }) + run := func(withOption bool) { + opts := []fx.Option{ + fx.Provide(func() int { + panic("terrible sorrow") + }), + fx.Invoke(func(a int) {}), + } + if withOption { + opts = append(opts, fx.RecoverFromPanics()) + app := fx.New(opts...) + err := app.Err() + require.Error(t, err) + assert.Contains(t, err.Error(), + `panic: "terrible sorrow" in func: "go.uber.org/fx/internal/leaky_test_test".TestRecoverFromPanicsOption.`) + } else { + assert.Panics(t, func() { fx.New(opts...) }, + "expected panic without RecoverFromPanics() option") + } + } + + t.Run("WithoutOption", func(t *testing.T) { run(false) }) + t.Run("WithOption", func(t *testing.T) { run(true) }) +} diff --git a/signal.go b/signal.go index 79dcfeb41..1593c5de2 100644 --- a/signal.go +++ b/signal.go @@ -87,8 +87,6 @@ func (recv *signalReceivers) relayer(ctx context.Context) { select { case <-recv.shutdown: return - case <-ctx.Done(): - return case signal := <-recv.signals: recv.Broadcast(ShutdownSignal{ Signal: signal,