Commit 8593c890 authored by protolambda's avatar protolambda

op-service: cliapp lifecycle test fix, prevent race nil-ptr on app state-access

parent a281abba
...@@ -48,12 +48,14 @@ var _ Lifecycle = (*fakeLifecycle)(nil) ...@@ -48,12 +48,14 @@ var _ Lifecycle = (*fakeLifecycle)(nil)
func TestLifecycleCmd(t *testing.T) { func TestLifecycleCmd(t *testing.T) {
appSetup := func(t *testing.T, shareApp **fakeLifecycle) (signalCh chan struct{}, initCh, startCh, stopCh, resultCh chan error) { appSetup := func(t *testing.T) (signalCh chan struct{}, initCh, startCh, stopCh, resultCh chan error, appCh chan *fakeLifecycle) {
signalCh = make(chan struct{}) signalCh = make(chan struct{})
initCh = make(chan error) initCh = make(chan error)
startCh = make(chan error) startCh = make(chan error)
stopCh = make(chan error) stopCh = make(chan error)
resultCh = make(chan error) resultCh = make(chan error)
// optional channel to retrieve the fakeLifecycle from, available some time after init, before start.
appCh = make(chan *fakeLifecycle, 1)
// mock an application that may fail at different stages of its lifecycle // mock an application that may fail at different stages of its lifecycle
mockAppFn := func(ctx *cli.Context, close context.CancelCauseFunc) (Lifecycle, error) { mockAppFn := func(ctx *cli.Context, close context.CancelCauseFunc) (Lifecycle, error) {
...@@ -72,9 +74,7 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -72,9 +74,7 @@ func TestLifecycleCmd(t *testing.T) {
stopped: false, stopped: false,
selfClose: close, selfClose: close,
} }
if shareApp != nil { appCh <- app
*shareApp = app
}
return app, nil return app, nil
} }
...@@ -115,19 +115,20 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -115,19 +115,20 @@ func TestLifecycleCmd(t *testing.T) {
close(startCh) close(startCh)
close(stopCh) close(stopCh)
close(resultCh) close(resultCh)
close(appCh)
}) })
return return
} }
t.Run("interrupt int", func(t *testing.T) { t.Run("interrupt int", func(t *testing.T) {
signalCh, _, _, _, resultCh := appSetup(t, nil) signalCh, _, _, _, resultCh, _ := appSetup(t)
signalCh <- struct{}{} signalCh <- struct{}{}
res := <-resultCh res := <-resultCh
require.ErrorIs(t, res, interruptErr) require.ErrorIs(t, res, interruptErr)
require.ErrorContains(t, res, "failed to setup") require.ErrorContains(t, res, "failed to setup")
}) })
t.Run("failed init", func(t *testing.T) { t.Run("failed init", func(t *testing.T) {
_, initCh, _, _, resultCh := appSetup(t, nil) _, initCh, _, _, resultCh, _ := appSetup(t)
v := errors.New("TEST INIT ERRROR") v := errors.New("TEST INIT ERRROR")
initCh <- v initCh <- v
res := <-resultCh res := <-resultCh
...@@ -135,9 +136,9 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -135,9 +136,9 @@ func TestLifecycleCmd(t *testing.T) {
require.ErrorContains(t, res, "failed to setup") require.ErrorContains(t, res, "failed to setup")
}) })
t.Run("interrupt start", func(t *testing.T) { t.Run("interrupt start", func(t *testing.T) {
var app *fakeLifecycle signalCh, initCh, _, _, resultCh, appCh := appSetup(t)
signalCh, initCh, _, _, resultCh := appSetup(t, &app)
initCh <- nil initCh <- nil
app := <-appCh
require.False(t, app.Stopped()) require.False(t, app.Stopped())
signalCh <- struct{}{} signalCh <- struct{}{}
res := <-resultCh res := <-resultCh
...@@ -146,9 +147,9 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -146,9 +147,9 @@ func TestLifecycleCmd(t *testing.T) {
require.True(t, app.Stopped()) require.True(t, app.Stopped())
}) })
t.Run("failed start", func(t *testing.T) { t.Run("failed start", func(t *testing.T) {
var app *fakeLifecycle _, initCh, startCh, _, resultCh, appCh := appSetup(t)
_, initCh, startCh, _, resultCh := appSetup(t, &app)
initCh <- nil initCh <- nil
app := <-appCh
require.False(t, app.Stopped()) require.False(t, app.Stopped())
v := errors.New("TEST START ERROR") v := errors.New("TEST START ERROR")
startCh <- v startCh <- v
...@@ -158,9 +159,9 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -158,9 +159,9 @@ func TestLifecycleCmd(t *testing.T) {
require.True(t, app.Stopped()) require.True(t, app.Stopped())
}) })
t.Run("graceful shutdown", func(t *testing.T) { t.Run("graceful shutdown", func(t *testing.T) {
var app *fakeLifecycle signalCh, initCh, startCh, stopCh, resultCh, appCh := appSetup(t)
signalCh, initCh, startCh, stopCh, resultCh := appSetup(t, &app)
initCh <- nil initCh <- nil
app := <-appCh
require.False(t, app.Stopped()) require.False(t, app.Stopped())
startCh <- nil startCh <- nil
signalCh <- struct{}{} // interrupt, but at an expected time signalCh <- struct{}{} // interrupt, but at an expected time
...@@ -169,9 +170,9 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -169,9 +170,9 @@ func TestLifecycleCmd(t *testing.T) {
require.True(t, app.Stopped()) require.True(t, app.Stopped())
}) })
t.Run("interrupted shutdown", func(t *testing.T) { t.Run("interrupted shutdown", func(t *testing.T) {
var app *fakeLifecycle signalCh, initCh, startCh, _, resultCh, appCh := appSetup(t)
signalCh, initCh, startCh, _, resultCh := appSetup(t, &app)
initCh <- nil initCh <- nil
app := <-appCh
require.False(t, app.Stopped()) require.False(t, app.Stopped())
startCh <- nil startCh <- nil
signalCh <- struct{}{} // start graceful shutdown signalCh <- struct{}{} // start graceful shutdown
...@@ -182,9 +183,9 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -182,9 +183,9 @@ func TestLifecycleCmd(t *testing.T) {
require.True(t, app.Stopped()) // still fully closes, interrupts only accelerate shutdown where possible. require.True(t, app.Stopped()) // still fully closes, interrupts only accelerate shutdown where possible.
}) })
t.Run("failed shutdown", func(t *testing.T) { t.Run("failed shutdown", func(t *testing.T) {
var app *fakeLifecycle signalCh, initCh, startCh, stopCh, resultCh, appCh := appSetup(t)
signalCh, initCh, startCh, stopCh, resultCh := appSetup(t, &app)
initCh <- nil initCh <- nil
app := <-appCh
require.False(t, app.Stopped()) require.False(t, app.Stopped())
startCh <- nil startCh <- nil
signalCh <- struct{}{} // start graceful shutdown signalCh <- struct{}{} // start graceful shutdown
...@@ -196,9 +197,9 @@ func TestLifecycleCmd(t *testing.T) { ...@@ -196,9 +197,9 @@ func TestLifecycleCmd(t *testing.T) {
require.True(t, app.Stopped()) require.True(t, app.Stopped())
}) })
t.Run("app self-close", func(t *testing.T) { t.Run("app self-close", func(t *testing.T) {
var app *fakeLifecycle _, initCh, startCh, stopCh, resultCh, appCh := appSetup(t)
_, initCh, startCh, stopCh, resultCh := appSetup(t, &app)
initCh <- nil initCh <- nil
app := <-appCh
require.False(t, app.Stopped()) require.False(t, app.Stopped())
startCh <- nil startCh <- nil
v := errors.New("TEST SELF CLOSE ERROR") v := errors.New("TEST SELF CLOSE ERROR")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment