|
|
|
@ -16,166 +16,6 @@ import (
|
|
|
|
|
"golang.org/x/sys/windows/svc"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestOSServiceClient(t *testing.T) {
|
|
|
|
|
type args struct {
|
|
|
|
|
returnsOpenSCManagerError error
|
|
|
|
|
returnsOpenServiceError error
|
|
|
|
|
returnsServiceQueryError error
|
|
|
|
|
returnsServiceCloseError error
|
|
|
|
|
returnsSCMgrDisconnectError error
|
|
|
|
|
returnsServiceState svc.State
|
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
args args
|
|
|
|
|
maybeHealthy *bool
|
|
|
|
|
}{
|
|
|
|
|
// healthy
|
|
|
|
|
{"should pass for healthy service", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Running,
|
|
|
|
|
}, boolPointer(true)},
|
|
|
|
|
{"should pass for healthy service even when there's an error closing the service handle", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: errors.New("error while closing the service handle"),
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Running,
|
|
|
|
|
}, boolPointer(true)},
|
|
|
|
|
{"should pass for healthy service even when there's an error disconnecting from SCManager", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: errors.New("error while disconnecting from service manager"),
|
|
|
|
|
returnsServiceState: svc.Running,
|
|
|
|
|
}, boolPointer(true)},
|
|
|
|
|
|
|
|
|
|
// warning
|
|
|
|
|
{"should be in warning state for any state that's not Running, Paused or Stopped", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.StartPending,
|
|
|
|
|
}, nil},
|
|
|
|
|
{"should be in warning state when we cannot connect to the service manager", args{
|
|
|
|
|
returnsOpenSCManagerError: errors.New("cannot connect to service manager"),
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Running,
|
|
|
|
|
}, nil},
|
|
|
|
|
{"should be in warning state when we cannot open the service", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: errors.New("service testService does not exist"),
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Running,
|
|
|
|
|
}, nil},
|
|
|
|
|
{"should be in warning state when we cannot query the service state", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: errors.New("cannot query testService state"),
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Running,
|
|
|
|
|
}, nil},
|
|
|
|
|
{"should be in warning state for for any state that's not Running, Paused or Stopped when there's an error closing the service handle", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: errors.New("error while closing the service handle"),
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.StartPending,
|
|
|
|
|
}, nil},
|
|
|
|
|
{"should be in warning state for for any state that's not Running, Paused or Stopped when there's an error disconnecting from SCManager", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: errors.New("error while disconnecting from service manager"),
|
|
|
|
|
returnsServiceState: svc.StartPending,
|
|
|
|
|
}, nil},
|
|
|
|
|
|
|
|
|
|
// critical
|
|
|
|
|
{"should fail for paused service", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Paused,
|
|
|
|
|
}, boolPointer(false)},
|
|
|
|
|
{"should fail for stopped service", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Stopped,
|
|
|
|
|
}, boolPointer(false)},
|
|
|
|
|
{"should fail for stopped service even when there's an error closing the service handle", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: errors.New("error while closing the service handle"),
|
|
|
|
|
returnsSCMgrDisconnectError: nil,
|
|
|
|
|
returnsServiceState: svc.Stopped,
|
|
|
|
|
}, boolPointer(false)},
|
|
|
|
|
{"should fail for stopped service even when there's an error disconnecting from SCManager", args{
|
|
|
|
|
returnsOpenSCManagerError: nil,
|
|
|
|
|
returnsOpenServiceError: nil,
|
|
|
|
|
returnsServiceQueryError: nil,
|
|
|
|
|
returnsServiceCloseError: nil,
|
|
|
|
|
returnsSCMgrDisconnectError: errors.New("error while disconnecting from service manager"),
|
|
|
|
|
returnsServiceState: svc.Stopped,
|
|
|
|
|
}, boolPointer(false)},
|
|
|
|
|
}
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
old := win
|
|
|
|
|
defer func() { win = old }()
|
|
|
|
|
win = fakeWindowsOS{
|
|
|
|
|
returnsOpenSCManagerError: tt.args.returnsOpenSCManagerError,
|
|
|
|
|
returnsOpenServiceError: tt.args.returnsOpenServiceError,
|
|
|
|
|
returnsServiceQueryError: tt.args.returnsServiceQueryError,
|
|
|
|
|
returnsServiceCloseError: tt.args.returnsServiceCloseError,
|
|
|
|
|
returnsSCMgrDisconnectError: tt.args.returnsSCMgrDisconnectError,
|
|
|
|
|
returnsServiceState: tt.args.returnsServiceState,
|
|
|
|
|
}
|
|
|
|
|
probe, err := NewOSServiceClient()
|
|
|
|
|
if (tt.args.returnsOpenSCManagerError != nil && err == nil) || (tt.args.returnsOpenSCManagerError == nil && err != nil) {
|
|
|
|
|
t.Errorf("FAIL: %s. Expected error on OpenSCManager %v , but err == %v", tt.name, tt.args.returnsOpenSCManagerError, err)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
actualError := probe.Check("testService")
|
|
|
|
|
actuallyHealthy := actualError == nil
|
|
|
|
|
actualErrorIsCritical := errors.Is(actualError, ErrOSServiceStatusCritical)
|
|
|
|
|
actualWarning := !actuallyHealthy && !actualErrorIsCritical
|
|
|
|
|
expectedHealthy := tt.maybeHealthy != nil && *tt.maybeHealthy
|
|
|
|
|
expectedWarning := tt.maybeHealthy == nil
|
|
|
|
|
if expectedHealthy && !actuallyHealthy {
|
|
|
|
|
t.Errorf("FAIL: %s. Expected healthy %t, but err == %v", tt.name, boolVal(tt.maybeHealthy), actualError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if expectedWarning && !actualWarning {
|
|
|
|
|
t.Errorf("FAIL: %s. Expected non critical error, but err == %v", tt.name, actualError)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestCheck_OSService(t *testing.T) {
|
|
|
|
|
type args struct {
|
|
|
|
|
returnsOpenSCManagerError error
|
|
|
|
|