(t *testing.T)
| 99 | } |
| 100 | |
| 101 | func TestAllFunctionality(t *testing.T) { |
| 102 | errStartFailed := errors.New("start failed") |
| 103 | errRunFailed := errors.New("runFn failed") |
| 104 | errStopFailed := errors.New("stop failed") |
| 105 | |
| 106 | testCases := map[string]testCase{ |
| 107 | "normal flow": { |
| 108 | listenerLog: []string{"starting", "running", "stopping: Running", "terminated: Stopping"}, |
| 109 | }, |
| 110 | |
| 111 | "start returns error": { |
| 112 | startRetVal: errStartFailed, |
| 113 | awaitRunningError: []error{invalidServiceStateWithFailureError(Failed, Running, errStartFailed)}, |
| 114 | awaitTerminatedError: invalidServiceStateWithFailureError(Failed, Terminated, errStartFailed), // Failed in start |
| 115 | failureCase: errStartFailed, |
| 116 | listenerLog: []string{"starting", "failed: Starting: start failed"}, |
| 117 | }, |
| 118 | |
| 119 | "start is canceled via context and returns cancellation error": { |
| 120 | cancelAfterStartAsync: true, |
| 121 | startReturnContextErr: true, |
| 122 | awaitRunningError: []error{invalidServiceStateWithFailureError(Failed, Running, context.Canceled)}, |
| 123 | awaitTerminatedError: invalidServiceStateWithFailureError(Failed, Terminated, context.Canceled), |
| 124 | failureCase: context.Canceled, |
| 125 | listenerLog: []string{"starting", "failed: Starting: context canceled"}, |
| 126 | }, |
| 127 | |
| 128 | "start is canceled via context, doesn't return error. Run shouldn't runFn, since context is canceled now.": { |
| 129 | cancelAfterStartAsync: true, |
| 130 | startReturnContextErr: false, |
| 131 | // we can observe Stopping or Terminated |
| 132 | awaitRunningError: []error{invalidServiceStateError(Stopping, Running), invalidServiceStateError(Terminated, Running)}, |
| 133 | awaitTerminatedError: nil, // but still terminates correctly, since Start or RunningFn didn't return error |
| 134 | failureCase: nil, // start didn't return error, service stopped without calling run |
| 135 | listenerLog: []string{"starting", "stopping: Starting", "terminated: Stopping"}, |
| 136 | }, |
| 137 | |
| 138 | "start is canceled via StopAsync, but start doesn't return error": { |
| 139 | startReturnContextErr: false, // don't return error on cancellation, just stop early |
| 140 | stopAfterStartAsync: true, |
| 141 | // we can observe Stopping or Terminated |
| 142 | awaitRunningError: []error{invalidServiceStateError(Stopping, Running), invalidServiceStateError(Terminated, Running)}, |
| 143 | awaitTerminatedError: nil, // stopped while starting, but no error. Should be in Terminated state. |
| 144 | failureCase: nil, // start didn't return error, service stopped without calling run |
| 145 | listenerLog: []string{"starting", "stopping: Starting", "terminated: Stopping"}, |
| 146 | }, |
| 147 | |
| 148 | "runFn returns error": { |
| 149 | runRetVal: errRunFailed, |
| 150 | awaitTerminatedError: invalidServiceStateWithFailureError(Failed, Terminated, errRunFailed), // service will get into Failed state, since run failed |
| 151 | failureCase: errRunFailed, |
| 152 | listenerLog: []string{"starting", "running", "stopping: Running", "failed: Stopping: runFn failed"}, |
| 153 | }, |
| 154 | |
| 155 | "runFn returns error from context cancellation": { |
| 156 | runReturnContextErr: true, |
| 157 | cancelAfterAwaitRunning: true, |
| 158 | awaitTerminatedError: invalidServiceStateWithFailureError(Failed, Terminated, context.Canceled), // service will get into Failed state, since run failed |
nothing calls this directly
no test coverage detected