@@ -11,6 +11,7 @@ import (
1111 "github.com/golang/mock/gomock"
1212 "github.com/stretchr/testify/assert"
1313 "github.com/stretchr/testify/require"
14+ "golang.org/x/sys/windows/svc"
1415)
1516
1617var errTestFailure = errors .New ("test failure" )
@@ -146,3 +147,110 @@ func TestExecuteCommandTimeout(t *testing.T) {
146147 _ , err := client .ExecuteCommand (context .Background (), "ping" , "-t" , "localhost" )
147148 require .Error (t , err )
148149}
150+
151+ type mockManagedService struct {
152+ queryFuncs []func () (svc.Status , error )
153+ controlFunc func (svc.Cmd ) (svc.Status , error )
154+ }
155+
156+ func (m * mockManagedService ) Query () (svc.Status , error ) {
157+ queryFunc := m .queryFuncs [0 ]
158+ m .queryFuncs = m .queryFuncs [1 :]
159+ return queryFunc ()
160+ }
161+
162+ func (m * mockManagedService ) Control (cmd svc.Cmd ) (svc.Status , error ) {
163+ return m .controlFunc (cmd )
164+ }
165+
166+ func TestTryStopServiceFn (t * testing.T ) {
167+ tests := []struct {
168+ name string
169+ queryFuncs []func () (svc.Status , error )
170+ controlFunc func (svc.Cmd ) (svc.Status , error )
171+ expectError bool
172+ }{
173+ {
174+ name : "Service already stopped" ,
175+ queryFuncs : []func () (svc.Status , error ){
176+ func () (svc.Status , error ) {
177+ return svc.Status {State : svc .Stopped }, nil
178+ },
179+ },
180+ controlFunc : nil ,
181+ expectError : false ,
182+ },
183+ {
184+ name : "Service running and stops successfully" ,
185+ queryFuncs : []func () (svc.Status , error ){
186+ func () (svc.Status , error ) {
187+ return svc.Status {State : svc .Running }, nil
188+ },
189+ func () (svc.Status , error ) {
190+ return svc.Status {State : svc .Stopped }, nil
191+ },
192+ },
193+ controlFunc : func (svc.Cmd ) (svc.Status , error ) {
194+ return svc.Status {State : svc .Stopped }, nil
195+ },
196+ expectError : false ,
197+ },
198+ {
199+ name : "Service running and stops after multiple attempts" ,
200+ queryFuncs : []func () (svc.Status , error ){
201+ func () (svc.Status , error ) {
202+ return svc.Status {State : svc .Running }, nil
203+ },
204+ func () (svc.Status , error ) {
205+ return svc.Status {State : svc .Running }, nil
206+ },
207+ func () (svc.Status , error ) {
208+ return svc.Status {State : svc .Running }, nil
209+ },
210+ func () (svc.Status , error ) {
211+ return svc.Status {State : svc .Stopped }, nil
212+ },
213+ },
214+ controlFunc : func (svc.Cmd ) (svc.Status , error ) {
215+ return svc.Status {State : svc .Stopped }, nil
216+ },
217+ expectError : false ,
218+ },
219+ {
220+ name : "Service running and fails to stop" ,
221+ queryFuncs : []func () (svc.Status , error ){
222+ func () (svc.Status , error ) {
223+ return svc.Status {State : svc .Running }, nil
224+ },
225+ },
226+ controlFunc : func (svc.Cmd ) (svc.Status , error ) {
227+ return svc.Status {State : svc .Running }, errors .New ("failed to stop service" ) //nolint:err113 // test error
228+ },
229+ expectError : true ,
230+ },
231+ {
232+ name : "Service query fails" ,
233+ queryFuncs : []func () (svc.Status , error ){
234+ func () (svc.Status , error ) {
235+ return svc.Status {}, errors .New ("failed to query service status" ) //nolint:err113 // test error
236+ },
237+ },
238+ controlFunc : nil ,
239+ expectError : true ,
240+ },
241+ }
242+ for _ , tt := range tests {
243+ t .Run (tt .name , func (t * testing.T ) {
244+ service := & mockManagedService {
245+ queryFuncs : tt .queryFuncs ,
246+ controlFunc : tt .controlFunc ,
247+ }
248+ err := tryStopServiceFn (context .Background (), service )()
249+ if tt .expectError {
250+ assert .Error (t , err )
251+ return
252+ }
253+ assert .NoError (t , err )
254+ })
255+ }
256+ }
0 commit comments