diff --git a/docs/source/developer_guide.rst b/docs/source/developer_guide.rst index 9a0c7a348..d055b4512 100644 --- a/docs/source/developer_guide.rst +++ b/docs/source/developer_guide.rst @@ -24,6 +24,17 @@ Additionally, all code must pass a suite of Go linters. There is a pre-commit ya See https://pre-commit.com/ and https://golangci-lint.run/ for more details on installing and using these tools. +We are using gomock to generate mocks for our unit tests. The mocks are living inside of a package under the real implementation, prefixed by mock_. An example is the package mock_workceptor under pkg/workceptor. + +In order to genenerate a mock for a particular file, you can run: + +.. code:: + mockgen -source=pkg/filename.go -destination=pkg/mock_pkg/mock_filename.go + +For example, to create/update mocks for Workceptor, we can run: + +.. code:: + mockgen -source=pkg/workceptor/workceptor.go -destination=pkg/workceptor/mock_workceptor/workceptor.go Source code ^^^^^^^^^^^ diff --git a/go.mod b/go.mod index 002c8da25..7fc5aae3f 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/ghjm/cmdline v0.1.2 github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/golang/mock v1.6.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/gorilla/websocket v1.5.0 github.com/jupp0r/go-priority-queue v0.0.0-20160601094913-ab1073853bde diff --git a/pkg/controlsvc/mock_controlsvc/interfaces.go b/pkg/controlsvc/mock_controlsvc/interfaces.go new file mode 100644 index 000000000..ceac127f5 --- /dev/null +++ b/pkg/controlsvc/mock_controlsvc/interfaces.go @@ -0,0 +1,200 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/controlsvc/interfaces.go + +// Package mock_controlsvc is a generated GoMock package. +package mock_controlsvc + +import ( + context "context" + controlsvc "github.com/ansible/receptor/pkg/controlsvc" + logger "github.com/ansible/receptor/pkg/logger" + netceptor "github.com/ansible/receptor/pkg/netceptor" + gomock "github.com/golang/mock/gomock" + io "io" + net "net" + reflect "reflect" +) + +// MockControlCommandType is a mock of ControlCommandType interface +type MockControlCommandType struct { + ctrl *gomock.Controller + recorder *MockControlCommandTypeMockRecorder +} + +// MockControlCommandTypeMockRecorder is the mock recorder for MockControlCommandType +type MockControlCommandTypeMockRecorder struct { + mock *MockControlCommandType +} + +// NewMockControlCommandType creates a new mock instance +func NewMockControlCommandType(ctrl *gomock.Controller) *MockControlCommandType { + mock := &MockControlCommandType{ctrl: ctrl} + mock.recorder = &MockControlCommandTypeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockControlCommandType) EXPECT() *MockControlCommandTypeMockRecorder { + return m.recorder +} + +// InitFromString mocks base method +func (m *MockControlCommandType) InitFromString(arg0 string) (controlsvc.ControlCommand, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InitFromString", arg0) + ret0, _ := ret[0].(controlsvc.ControlCommand) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// InitFromString indicates an expected call of InitFromString +func (mr *MockControlCommandTypeMockRecorder) InitFromString(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitFromString", reflect.TypeOf((*MockControlCommandType)(nil).InitFromString), arg0) +} + +// InitFromJSON mocks base method +func (m *MockControlCommandType) InitFromJSON(arg0 map[string]interface{}) (controlsvc.ControlCommand, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InitFromJSON", arg0) + ret0, _ := ret[0].(controlsvc.ControlCommand) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// InitFromJSON indicates an expected call of InitFromJSON +func (mr *MockControlCommandTypeMockRecorder) InitFromJSON(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitFromJSON", reflect.TypeOf((*MockControlCommandType)(nil).InitFromJSON), arg0) +} + +// MockControlCommand is a mock of ControlCommand interface +type MockControlCommand struct { + ctrl *gomock.Controller + recorder *MockControlCommandMockRecorder +} + +// MockControlCommandMockRecorder is the mock recorder for MockControlCommand +type MockControlCommandMockRecorder struct { + mock *MockControlCommand +} + +// NewMockControlCommand creates a new mock instance +func NewMockControlCommand(ctrl *gomock.Controller) *MockControlCommand { + mock := &MockControlCommand{ctrl: ctrl} + mock.recorder = &MockControlCommandMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockControlCommand) EXPECT() *MockControlCommandMockRecorder { + return m.recorder +} + +// ControlFunc mocks base method +func (m *MockControlCommand) ControlFunc(arg0 context.Context, arg1 *netceptor.Netceptor, arg2 controlsvc.ControlFuncOperations) (map[string]interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ControlFunc", arg0, arg1, arg2) + ret0, _ := ret[0].(map[string]interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ControlFunc indicates an expected call of ControlFunc +func (mr *MockControlCommandMockRecorder) ControlFunc(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ControlFunc", reflect.TypeOf((*MockControlCommand)(nil).ControlFunc), arg0, arg1, arg2) +} + +// MockControlFuncOperations is a mock of ControlFuncOperations interface +type MockControlFuncOperations struct { + ctrl *gomock.Controller + recorder *MockControlFuncOperationsMockRecorder +} + +// MockControlFuncOperationsMockRecorder is the mock recorder for MockControlFuncOperations +type MockControlFuncOperationsMockRecorder struct { + mock *MockControlFuncOperations +} + +// NewMockControlFuncOperations creates a new mock instance +func NewMockControlFuncOperations(ctrl *gomock.Controller) *MockControlFuncOperations { + mock := &MockControlFuncOperations{ctrl: ctrl} + mock.recorder = &MockControlFuncOperationsMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockControlFuncOperations) EXPECT() *MockControlFuncOperationsMockRecorder { + return m.recorder +} + +// BridgeConn mocks base method +func (m *MockControlFuncOperations) BridgeConn(message string, bc io.ReadWriteCloser, bcName string, logger *logger.ReceptorLogger) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BridgeConn", message, bc, bcName, logger) + ret0, _ := ret[0].(error) + return ret0 +} + +// BridgeConn indicates an expected call of BridgeConn +func (mr *MockControlFuncOperationsMockRecorder) BridgeConn(message, bc, bcName, logger interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BridgeConn", reflect.TypeOf((*MockControlFuncOperations)(nil).BridgeConn), message, bc, bcName, logger) +} + +// ReadFromConn mocks base method +func (m *MockControlFuncOperations) ReadFromConn(message string, out io.Writer) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadFromConn", message, out) + ret0, _ := ret[0].(error) + return ret0 +} + +// ReadFromConn indicates an expected call of ReadFromConn +func (mr *MockControlFuncOperationsMockRecorder) ReadFromConn(message, out interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFromConn", reflect.TypeOf((*MockControlFuncOperations)(nil).ReadFromConn), message, out) +} + +// WriteToConn mocks base method +func (m *MockControlFuncOperations) WriteToConn(message string, in chan []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WriteToConn", message, in) + ret0, _ := ret[0].(error) + return ret0 +} + +// WriteToConn indicates an expected call of WriteToConn +func (mr *MockControlFuncOperationsMockRecorder) WriteToConn(message, in interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteToConn", reflect.TypeOf((*MockControlFuncOperations)(nil).WriteToConn), message, in) +} + +// Close mocks base method +func (m *MockControlFuncOperations) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close +func (mr *MockControlFuncOperationsMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockControlFuncOperations)(nil).Close)) +} + +// RemoteAddr mocks base method +func (m *MockControlFuncOperations) RemoteAddr() net.Addr { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoteAddr") + ret0, _ := ret[0].(net.Addr) + return ret0 +} + +// RemoteAddr indicates an expected call of RemoteAddr +func (mr *MockControlFuncOperationsMockRecorder) RemoteAddr() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockControlFuncOperations)(nil).RemoteAddr)) +} diff --git a/pkg/framer/mock_framer/framer.go b/pkg/framer/mock_framer/framer.go new file mode 100644 index 000000000..84bc9ccb6 --- /dev/null +++ b/pkg/framer/mock_framer/framer.go @@ -0,0 +1,88 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/framer/framer.go + +// Package mock_framer is a generated GoMock package. +package mock_framer + +import ( + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockFramer is a mock of Framer interface +type MockFramer struct { + ctrl *gomock.Controller + recorder *MockFramerMockRecorder +} + +// MockFramerMockRecorder is the mock recorder for MockFramer +type MockFramerMockRecorder struct { + mock *MockFramer +} + +// NewMockFramer creates a new mock instance +func NewMockFramer(ctrl *gomock.Controller) *MockFramer { + mock := &MockFramer{ctrl: ctrl} + mock.recorder = &MockFramerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockFramer) EXPECT() *MockFramerMockRecorder { + return m.recorder +} + +// SendData mocks base method +func (m *MockFramer) SendData(data []byte) []byte { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendData", data) + ret0, _ := ret[0].([]byte) + return ret0 +} + +// SendData indicates an expected call of SendData +func (mr *MockFramerMockRecorder) SendData(data interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendData", reflect.TypeOf((*MockFramer)(nil).SendData), data) +} + +// RecvData mocks base method +func (m *MockFramer) RecvData(buf []byte) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RecvData", buf) +} + +// RecvData indicates an expected call of RecvData +func (mr *MockFramerMockRecorder) RecvData(buf interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvData", reflect.TypeOf((*MockFramer)(nil).RecvData), buf) +} + +// MessageReady mocks base method +func (m *MockFramer) MessageReady() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MessageReady") + ret0, _ := ret[0].(bool) + return ret0 +} + +// MessageReady indicates an expected call of MessageReady +func (mr *MockFramerMockRecorder) MessageReady() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MessageReady", reflect.TypeOf((*MockFramer)(nil).MessageReady)) +} + +// GetMessage mocks base method +func (m *MockFramer) GetMessage() ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMessage") + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMessage indicates an expected call of GetMessage +func (mr *MockFramerMockRecorder) GetMessage() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessage", reflect.TypeOf((*MockFramer)(nil).GetMessage)) +} diff --git a/pkg/netceptor/mock_netceptor/external_backend.go b/pkg/netceptor/mock_netceptor/external_backend.go new file mode 100644 index 000000000..1851523f0 --- /dev/null +++ b/pkg/netceptor/mock_netceptor/external_backend.go @@ -0,0 +1,92 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/netceptor/external_backend.go + +// Package mock_netceptor is a generated GoMock package. +package mock_netceptor + +import ( + context "context" + gomock "github.com/golang/mock/gomock" + reflect "reflect" + time "time" +) + +// MockMessageConn is a mock of MessageConn interface +type MockMessageConn struct { + ctrl *gomock.Controller + recorder *MockMessageConnMockRecorder +} + +// MockMessageConnMockRecorder is the mock recorder for MockMessageConn +type MockMessageConnMockRecorder struct { + mock *MockMessageConn +} + +// NewMockMessageConn creates a new mock instance +func NewMockMessageConn(ctrl *gomock.Controller) *MockMessageConn { + mock := &MockMessageConn{ctrl: ctrl} + mock.recorder = &MockMessageConnMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockMessageConn) EXPECT() *MockMessageConnMockRecorder { + return m.recorder +} + +// WriteMessage mocks base method +func (m *MockMessageConn) WriteMessage(ctx context.Context, data []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WriteMessage", ctx, data) + ret0, _ := ret[0].(error) + return ret0 +} + +// WriteMessage indicates an expected call of WriteMessage +func (mr *MockMessageConnMockRecorder) WriteMessage(ctx, data interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteMessage", reflect.TypeOf((*MockMessageConn)(nil).WriteMessage), ctx, data) +} + +// ReadMessage mocks base method +func (m *MockMessageConn) ReadMessage(ctx context.Context, timeout time.Duration) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadMessage", ctx, timeout) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReadMessage indicates an expected call of ReadMessage +func (mr *MockMessageConnMockRecorder) ReadMessage(ctx, timeout interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadMessage", reflect.TypeOf((*MockMessageConn)(nil).ReadMessage), ctx, timeout) +} + +// SetReadDeadline mocks base method +func (m *MockMessageConn) SetReadDeadline(t time.Time) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetReadDeadline", t) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetReadDeadline indicates an expected call of SetReadDeadline +func (mr *MockMessageConnMockRecorder) SetReadDeadline(t interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockMessageConn)(nil).SetReadDeadline), t) +} + +// Close mocks base method +func (m *MockMessageConn) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close +func (mr *MockMessageConnMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockMessageConn)(nil).Close)) +} diff --git a/pkg/netceptor/mock_netceptor/netceptor.go b/pkg/netceptor/mock_netceptor/netceptor.go new file mode 100644 index 000000000..00a06732c --- /dev/null +++ b/pkg/netceptor/mock_netceptor/netceptor.go @@ -0,0 +1,118 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/netceptor/netceptor.go + +// Package mock_netceptor is a generated GoMock package. +package mock_netceptor + +import ( + context "context" + netceptor "github.com/ansible/receptor/pkg/netceptor" + gomock "github.com/golang/mock/gomock" + reflect "reflect" + sync "sync" + time "time" +) + +// MockBackend is a mock of Backend interface +type MockBackend struct { + ctrl *gomock.Controller + recorder *MockBackendMockRecorder +} + +// MockBackendMockRecorder is the mock recorder for MockBackend +type MockBackendMockRecorder struct { + mock *MockBackend +} + +// NewMockBackend creates a new mock instance +func NewMockBackend(ctrl *gomock.Controller) *MockBackend { + mock := &MockBackend{ctrl: ctrl} + mock.recorder = &MockBackendMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockBackend) EXPECT() *MockBackendMockRecorder { + return m.recorder +} + +// Start mocks base method +func (m *MockBackend) Start(arg0 context.Context, arg1 *sync.WaitGroup) (chan netceptor.BackendSession, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Start", arg0, arg1) + ret0, _ := ret[0].(chan netceptor.BackendSession) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Start indicates an expected call of Start +func (mr *MockBackendMockRecorder) Start(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockBackend)(nil).Start), arg0, arg1) +} + +// MockBackendSession is a mock of BackendSession interface +type MockBackendSession struct { + ctrl *gomock.Controller + recorder *MockBackendSessionMockRecorder +} + +// MockBackendSessionMockRecorder is the mock recorder for MockBackendSession +type MockBackendSessionMockRecorder struct { + mock *MockBackendSession +} + +// NewMockBackendSession creates a new mock instance +func NewMockBackendSession(ctrl *gomock.Controller) *MockBackendSession { + mock := &MockBackendSession{ctrl: ctrl} + mock.recorder = &MockBackendSessionMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockBackendSession) EXPECT() *MockBackendSessionMockRecorder { + return m.recorder +} + +// Send mocks base method +func (m *MockBackendSession) Send(arg0 []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Send", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Send indicates an expected call of Send +func (mr *MockBackendSessionMockRecorder) Send(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockBackendSession)(nil).Send), arg0) +} + +// Recv mocks base method +func (m *MockBackendSession) Recv(arg0 time.Duration) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Recv", arg0) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Recv indicates an expected call of Recv +func (mr *MockBackendSessionMockRecorder) Recv(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockBackendSession)(nil).Recv), arg0) +} + +// Close mocks base method +func (m *MockBackendSession) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close +func (mr *MockBackendSessionMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockBackendSession)(nil).Close)) +} diff --git a/pkg/netceptor/netceptor.go b/pkg/netceptor/netceptor.go index 95a938bfb..fd0875d5f 100644 --- a/pkg/netceptor/netceptor.go +++ b/pkg/netceptor/netceptor.go @@ -446,6 +446,11 @@ func (s *Netceptor) MaxConnectionIdleTime() time.Duration { return s.maxConnectionIdleTime } +// GetLogger returns the logger of this Netceptor instance. +func (s *Netceptor) GetLogger() *logger.ReceptorLogger { + return s.Logger +} + // Sets the MaxConnectionIdleTime object on the Netceptor instance. func (s *Netceptor) SetMaxConnectionIdleTime(userDefinedMaxIdleConnectionTimeout string) error { // before we instantiate a new instance of Netceptor, let's verify that the user defined maxidleconnectiontimeout value is parseable diff --git a/pkg/workceptor/command.go b/pkg/workceptor/command.go index 7c548110c..b2c709195 100644 --- a/pkg/workceptor/command.go +++ b/pkg/workceptor/command.go @@ -42,10 +42,10 @@ func termThenKill(cmd *exec.Cmd, doneChan chan bool) { case <-doneChan: return case <-time.After(10 * time.Second): - MainInstance.nc.Logger.Warning("timed out waiting for pid %d to terminate with SIGINT", cmd.Process.Pid) + MainInstance.nc.GetLogger().Warning("timed out waiting for pid %d to terminate with SIGINT", cmd.Process.Pid) } if cmd.Process != nil { - MainInstance.nc.Logger.Info("sending SIGKILL to pid %d", cmd.Process.Pid) + MainInstance.nc.GetLogger().Info("sending SIGKILL to pid %d", cmd.Process.Pid) _ = cmd.Process.Kill() } } @@ -64,7 +64,7 @@ func commandRunner(command string, params string, unitdir string) error { statusFilename := path.Join(unitdir, "status") err := status.UpdateBasicStatus(statusFilename, WorkStatePending, "Not started yet", 0) if err != nil { - MainInstance.nc.Logger.Error("Error updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Error updating status file %s: %s", statusFilename, err) } var cmd *exec.Cmd if params == "" { @@ -105,16 +105,16 @@ loop: termThenKill(cmd, doneChan) err = status.UpdateBasicStatus(statusFilename, WorkStateFailed, "Killed", stdoutSize(unitdir)) if err != nil { - MainInstance.nc.Logger.Error("Error updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Error updating status file %s: %s", statusFilename, err) } os.Exit(-1) case <-time.After(250 * time.Millisecond): err = status.UpdateBasicStatus(statusFilename, WorkStateRunning, fmt.Sprintf("Running: PID %d", cmd.Process.Pid), stdoutSize(unitdir)) if err != nil { - MainInstance.nc.Logger.Error("Error updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Error updating status file %s: %s", statusFilename, err) writeStatusFailures++ if writeStatusFailures > 3 { - MainInstance.nc.Logger.Error("Exceeded retries for updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Exceeded retries for updating status file %s: %s", statusFilename, err) os.Exit(-1) } } else { @@ -125,7 +125,7 @@ loop: if err != nil { err = status.UpdateBasicStatus(statusFilename, WorkStateFailed, fmt.Sprintf("Error: %s", err), stdoutSize(unitdir)) if err != nil { - MainInstance.nc.Logger.Error("Error updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Error updating status file %s: %s", statusFilename, err) } return err @@ -133,12 +133,12 @@ loop: if cmd.ProcessState.Success() { err = status.UpdateBasicStatus(statusFilename, WorkStateSucceeded, cmd.ProcessState.String(), stdoutSize(unitdir)) if err != nil { - MainInstance.nc.Logger.Error("Error updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Error updating status file %s: %s", statusFilename, err) } } else { err = status.UpdateBasicStatus(statusFilename, WorkStateFailed, cmd.ProcessState.String(), stdoutSize(unitdir)) if err != nil { - MainInstance.nc.Logger.Error("Error updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Error updating status file %s: %s", statusFilename, err) } } os.Exit(cmd.ProcessState.ExitCode()) @@ -226,8 +226,8 @@ func (cw *commandUnit) runCommand(cmd *exec.Cmd) error { // Start launches a job with given parameters. func (cw *commandUnit) Start() error { - level := cw.w.nc.Logger.GetLogLevel() - levelName, _ := cw.w.nc.Logger.LogLevelToName(level) + level := cw.w.nc.GetLogger().GetLogLevel() + levelName, _ := cw.w.nc.GetLogger().LogLevelToName(level) cw.UpdateBasicStatus(WorkStatePending, "Launching command runner", 0) // TODO: This is another place where we rely on a pre-built binary for testing. @@ -368,9 +368,9 @@ func (cfg commandRunnerCfg) Run() error { statusFilename := path.Join(cfg.UnitDir, "status") err = (&StatusFileData{}).UpdateBasicStatus(statusFilename, WorkStateFailed, err.Error(), stdoutSize(cfg.UnitDir)) if err != nil { - MainInstance.nc.Logger.Error("Error updating status file %s: %s", statusFilename, err) + MainInstance.nc.GetLogger().Error("Error updating status file %s: %s", statusFilename, err) } - MainInstance.nc.Logger.Error("Command runner exited with error: %s\n", err) + MainInstance.nc.GetLogger().Error("Command runner exited with error: %s\n", err) os.Exit(-1) } os.Exit(0) diff --git a/pkg/workceptor/kubernetes.go b/pkg/workceptor/kubernetes.go index 04ad7d505..7c5340232 100644 --- a/pkg/workceptor/kubernetes.go +++ b/pkg/workceptor/kubernetes.go @@ -763,7 +763,7 @@ func (kw *kubeUnit) runWorkUsingLogger() { func isCompatibleK8S(kw *kubeUnit, versionStr string) bool { semver, err := version.ParseSemantic(versionStr) if err != nil { - kw.w.nc.Logger.Warning("could parse Kubernetes server version %s, will not use reconnect support", versionStr) + kw.w.nc.GetLogger().Warning("could parse Kubernetes server version %s, will not use reconnect support", versionStr) return false } @@ -787,11 +787,11 @@ func isCompatibleK8S(kw *kubeUnit, versionStr string) bool { } if semver.AtLeast(version.MustParseSemantic(compatibleVer)) { - kw.w.nc.Logger.Debug("Kubernetes version %s is at least %s, using reconnect support", semver, compatibleVer) + kw.w.nc.GetLogger().Debug("Kubernetes version %s is at least %s, using reconnect support", semver, compatibleVer) return true } - kw.w.nc.Logger.Debug("Kubernetes version %s not at least %s, not using reconnect support", semver, compatibleVer) + kw.w.nc.GetLogger().Debug("Kubernetes version %s not at least %s, not using reconnect support", semver, compatibleVer) return false } @@ -828,7 +828,7 @@ func shouldUseReconnect(kw *kubeUnit) bool { serverVerInfo, err := kw.clientset.ServerVersion() if err != nil { - kw.w.nc.Logger.Warning("could not detect Kubernetes server version, will not use reconnect support") + kw.w.nc.GetLogger().Warning("could not detect Kubernetes server version, will not use reconnect support") return false } @@ -898,7 +898,7 @@ func (kw *kubeUnit) runWorkUsingTCP() { if err != nil { errMsg := fmt.Sprintf("Error listening: %s", err) kw.UpdateBasicStatus(WorkStateFailed, errMsg, 0) - kw.w.nc.Logger.Error(errMsg) + kw.w.nc.GetLogger().Error(errMsg) return } @@ -922,7 +922,7 @@ func (kw *kubeUnit) runWorkUsingTCP() { if err != nil { errMsg := fmt.Sprintf("Error accepting: %s", err) kw.UpdateBasicStatus(WorkStateFailed, errMsg, 0) - kw.w.nc.Logger.Error(errMsg) + kw.w.nc.GetLogger().Error(errMsg) cancel() return @@ -935,7 +935,7 @@ func (kw *kubeUnit) runWorkUsingTCP() { if err != nil { errMsg := fmt.Sprintf("Error creating pod: %s", err) kw.UpdateBasicStatus(WorkStateFailed, errMsg, 0) - kw.w.nc.Logger.Error(errMsg) + kw.w.nc.GetLogger().Error(errMsg) cancel() return @@ -954,7 +954,7 @@ func (kw *kubeUnit) runWorkUsingTCP() { stdin, err = newStdinReader(kw.UnitDir()) if err != nil { errMsg := fmt.Sprintf("Error opening stdin file: %s", err) - kw.w.nc.Logger.Error(errMsg) + kw.w.nc.GetLogger().Error(errMsg) kw.UpdateBasicStatus(WorkStateFailed, errMsg, 0) cancel() @@ -965,7 +965,7 @@ func (kw *kubeUnit) runWorkUsingTCP() { stdout, err := newStdoutWriter(kw.UnitDir()) if err != nil { errMsg := fmt.Sprintf("Error opening stdout file: %s", err) - kw.w.nc.Logger.Error(errMsg) + kw.w.nc.GetLogger().Error(errMsg) kw.UpdateBasicStatus(WorkStateFailed, errMsg, 0) cancel() @@ -983,7 +983,7 @@ func (kw *kubeUnit) runWorkUsingTCP() { _ = conn.CloseWrite() if err != nil { errMsg := fmt.Sprintf("Error sending stdin to pod: %s", err) - kw.w.nc.Logger.Error(errMsg) + kw.w.nc.GetLogger().Error(errMsg) kw.UpdateBasicStatus(WorkStateFailed, errMsg, 0) cancel() @@ -1015,7 +1015,7 @@ func (kw *kubeUnit) runWorkUsingTCP() { } if err != nil { errMsg := fmt.Sprintf("Error reading stdout from pod: %s", err) - kw.w.nc.Logger.Error(errMsg) + kw.w.nc.GetLogger().Error(errMsg) kw.UpdateBasicStatus(WorkStateFailed, errMsg, 0) cancel() @@ -1231,7 +1231,7 @@ func (kw *kubeUnit) SetFromParams(params map[string]string) error { if podPendingTimeoutString != "" { podPendingTimeout, err := time.ParseDuration(podPendingTimeoutString) if err != nil { - kw.w.nc.Logger.Error("Failed to parse pod_pending_timeout -- valid examples include '1.5h', '30m', '30m10s'") + kw.w.nc.GetLogger().Error("Failed to parse pod_pending_timeout -- valid examples include '1.5h', '30m', '30m10s'") return err } @@ -1314,11 +1314,11 @@ func (kw *kubeUnit) Restart() error { if kw.deletePodOnRestart { err := kw.connectToKube() if err != nil { - kw.w.nc.Logger.Warning("Pod %s could not be deleted: %s", ked.PodName, err.Error()) + kw.w.nc.GetLogger().Warning("Pod %s could not be deleted: %s", ked.PodName, err.Error()) } else { err := kw.clientset.CoreV1().Pods(ked.KubeNamespace).Delete(context.Background(), ked.PodName, metav1.DeleteOptions{}) if err != nil { - kw.w.nc.Logger.Warning("Pod %s could not be deleted: %s", ked.PodName, err.Error()) + kw.w.nc.GetLogger().Warning("Pod %s could not be deleted: %s", ked.PodName, err.Error()) } } } @@ -1343,7 +1343,7 @@ func (kw *kubeUnit) Cancel() error { if kw.pod != nil { err := kw.clientset.CoreV1().Pods(kw.pod.Namespace).Delete(context.Background(), kw.pod.Name, metav1.DeleteOptions{}) if err != nil { - kw.w.nc.Logger.Error("Error deleting pod %s: %s", kw.pod.Name, err) + kw.w.nc.GetLogger().Error("Error deleting pod %s: %s", kw.pod.Name, err) } } if kw.cancel != nil { diff --git a/pkg/workceptor/mock_workceptor/interfaces.go b/pkg/workceptor/mock_workceptor/interfaces.go new file mode 100644 index 000000000..49120e499 --- /dev/null +++ b/pkg/workceptor/mock_workceptor/interfaces.go @@ -0,0 +1,319 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/workceptor/interfaces.go + +// Package mock_workceptor is a generated GoMock package. +package mock_workceptor + +import ( + workceptor "github.com/ansible/receptor/pkg/workceptor" + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockWorkUnit is a mock of WorkUnit interface +type MockWorkUnit struct { + ctrl *gomock.Controller + recorder *MockWorkUnitMockRecorder +} + +// MockWorkUnitMockRecorder is the mock recorder for MockWorkUnit +type MockWorkUnitMockRecorder struct { + mock *MockWorkUnit +} + +// NewMockWorkUnit creates a new mock instance +func NewMockWorkUnit(ctrl *gomock.Controller) *MockWorkUnit { + mock := &MockWorkUnit{ctrl: ctrl} + mock.recorder = &MockWorkUnitMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockWorkUnit) EXPECT() *MockWorkUnitMockRecorder { + return m.recorder +} + +// ID mocks base method +func (m *MockWorkUnit) ID() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ID") + ret0, _ := ret[0].(string) + return ret0 +} + +// ID indicates an expected call of ID +func (mr *MockWorkUnitMockRecorder) ID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockWorkUnit)(nil).ID)) +} + +// UnitDir mocks base method +func (m *MockWorkUnit) UnitDir() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UnitDir") + ret0, _ := ret[0].(string) + return ret0 +} + +// UnitDir indicates an expected call of UnitDir +func (mr *MockWorkUnitMockRecorder) UnitDir() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnitDir", reflect.TypeOf((*MockWorkUnit)(nil).UnitDir)) +} + +// StatusFileName mocks base method +func (m *MockWorkUnit) StatusFileName() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StatusFileName") + ret0, _ := ret[0].(string) + return ret0 +} + +// StatusFileName indicates an expected call of StatusFileName +func (mr *MockWorkUnitMockRecorder) StatusFileName() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StatusFileName", reflect.TypeOf((*MockWorkUnit)(nil).StatusFileName)) +} + +// StdoutFileName mocks base method +func (m *MockWorkUnit) StdoutFileName() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StdoutFileName") + ret0, _ := ret[0].(string) + return ret0 +} + +// StdoutFileName indicates an expected call of StdoutFileName +func (mr *MockWorkUnitMockRecorder) StdoutFileName() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StdoutFileName", reflect.TypeOf((*MockWorkUnit)(nil).StdoutFileName)) +} + +// Save mocks base method +func (m *MockWorkUnit) Save() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Save") + ret0, _ := ret[0].(error) + return ret0 +} + +// Save indicates an expected call of Save +func (mr *MockWorkUnitMockRecorder) Save() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockWorkUnit)(nil).Save)) +} + +// Load mocks base method +func (m *MockWorkUnit) Load() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Load") + ret0, _ := ret[0].(error) + return ret0 +} + +// Load indicates an expected call of Load +func (mr *MockWorkUnitMockRecorder) Load() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Load", reflect.TypeOf((*MockWorkUnit)(nil).Load)) +} + +// SetFromParams mocks base method +func (m *MockWorkUnit) SetFromParams(params map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetFromParams", params) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetFromParams indicates an expected call of SetFromParams +func (mr *MockWorkUnitMockRecorder) SetFromParams(params interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFromParams", reflect.TypeOf((*MockWorkUnit)(nil).SetFromParams), params) +} + +// UpdateBasicStatus mocks base method +func (m *MockWorkUnit) UpdateBasicStatus(state int, detail string, stdoutSize int64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UpdateBasicStatus", state, detail, stdoutSize) +} + +// UpdateBasicStatus indicates an expected call of UpdateBasicStatus +func (mr *MockWorkUnitMockRecorder) UpdateBasicStatus(state, detail, stdoutSize interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateBasicStatus", reflect.TypeOf((*MockWorkUnit)(nil).UpdateBasicStatus), state, detail, stdoutSize) +} + +// UpdateFullStatus mocks base method +func (m *MockWorkUnit) UpdateFullStatus(statusFunc func(*workceptor.StatusFileData)) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UpdateFullStatus", statusFunc) +} + +// UpdateFullStatus indicates an expected call of UpdateFullStatus +func (mr *MockWorkUnitMockRecorder) UpdateFullStatus(statusFunc interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFullStatus", reflect.TypeOf((*MockWorkUnit)(nil).UpdateFullStatus), statusFunc) +} + +// LastUpdateError mocks base method +func (m *MockWorkUnit) LastUpdateError() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LastUpdateError") + ret0, _ := ret[0].(error) + return ret0 +} + +// LastUpdateError indicates an expected call of LastUpdateError +func (mr *MockWorkUnitMockRecorder) LastUpdateError() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastUpdateError", reflect.TypeOf((*MockWorkUnit)(nil).LastUpdateError)) +} + +// Status mocks base method +func (m *MockWorkUnit) Status() *workceptor.StatusFileData { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Status") + ret0, _ := ret[0].(*workceptor.StatusFileData) + return ret0 +} + +// Status indicates an expected call of Status +func (mr *MockWorkUnitMockRecorder) Status() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockWorkUnit)(nil).Status)) +} + +// UnredactedStatus mocks base method +func (m *MockWorkUnit) UnredactedStatus() *workceptor.StatusFileData { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UnredactedStatus") + ret0, _ := ret[0].(*workceptor.StatusFileData) + return ret0 +} + +// UnredactedStatus indicates an expected call of UnredactedStatus +func (mr *MockWorkUnitMockRecorder) UnredactedStatus() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnredactedStatus", reflect.TypeOf((*MockWorkUnit)(nil).UnredactedStatus)) +} + +// Start mocks base method +func (m *MockWorkUnit) Start() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Start") + ret0, _ := ret[0].(error) + return ret0 +} + +// Start indicates an expected call of Start +func (mr *MockWorkUnitMockRecorder) Start() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockWorkUnit)(nil).Start)) +} + +// Restart mocks base method +func (m *MockWorkUnit) Restart() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Restart") + ret0, _ := ret[0].(error) + return ret0 +} + +// Restart indicates an expected call of Restart +func (mr *MockWorkUnitMockRecorder) Restart() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Restart", reflect.TypeOf((*MockWorkUnit)(nil).Restart)) +} + +// Cancel mocks base method +func (m *MockWorkUnit) Cancel() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Cancel") + ret0, _ := ret[0].(error) + return ret0 +} + +// Cancel indicates an expected call of Cancel +func (mr *MockWorkUnitMockRecorder) Cancel() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Cancel", reflect.TypeOf((*MockWorkUnit)(nil).Cancel)) +} + +// Release mocks base method +func (m *MockWorkUnit) Release(force bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Release", force) + ret0, _ := ret[0].(error) + return ret0 +} + +// Release indicates an expected call of Release +func (mr *MockWorkUnitMockRecorder) Release(force interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Release", reflect.TypeOf((*MockWorkUnit)(nil).Release), force) +} + +// MockWorkerConfig is a mock of WorkerConfig interface +type MockWorkerConfig struct { + ctrl *gomock.Controller + recorder *MockWorkerConfigMockRecorder +} + +// MockWorkerConfigMockRecorder is the mock recorder for MockWorkerConfig +type MockWorkerConfigMockRecorder struct { + mock *MockWorkerConfig +} + +// NewMockWorkerConfig creates a new mock instance +func NewMockWorkerConfig(ctrl *gomock.Controller) *MockWorkerConfig { + mock := &MockWorkerConfig{ctrl: ctrl} + mock.recorder = &MockWorkerConfigMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockWorkerConfig) EXPECT() *MockWorkerConfigMockRecorder { + return m.recorder +} + +// GetWorkType mocks base method +func (m *MockWorkerConfig) GetWorkType() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetWorkType") + ret0, _ := ret[0].(string) + return ret0 +} + +// GetWorkType indicates an expected call of GetWorkType +func (mr *MockWorkerConfigMockRecorder) GetWorkType() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkType", reflect.TypeOf((*MockWorkerConfig)(nil).GetWorkType)) +} + +// GetVerifySignature mocks base method +func (m *MockWorkerConfig) GetVerifySignature() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetVerifySignature") + ret0, _ := ret[0].(bool) + return ret0 +} + +// GetVerifySignature indicates an expected call of GetVerifySignature +func (mr *MockWorkerConfigMockRecorder) GetVerifySignature() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVerifySignature", reflect.TypeOf((*MockWorkerConfig)(nil).GetVerifySignature)) +} + +// NewWorker mocks base method +func (m *MockWorkerConfig) NewWorker(w *workceptor.Workceptor, unitID, workType string) workceptor.WorkUnit { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewWorker", w, unitID, workType) + ret0, _ := ret[0].(workceptor.WorkUnit) + return ret0 +} + +// NewWorker indicates an expected call of NewWorker +func (mr *MockWorkerConfigMockRecorder) NewWorker(w, unitID, workType interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewWorker", reflect.TypeOf((*MockWorkerConfig)(nil).NewWorker), w, unitID, workType) +} diff --git a/pkg/workceptor/mock_workceptor/workceptor.go b/pkg/workceptor/mock_workceptor/workceptor.go new file mode 100644 index 000000000..e86d0734e --- /dev/null +++ b/pkg/workceptor/mock_workceptor/workceptor.go @@ -0,0 +1,109 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/workceptor/workceptor.go + +// Package mock_workceptor is a generated GoMock package. +package mock_workceptor + +import ( + context "context" + tls "crypto/tls" + logger "github.com/ansible/receptor/pkg/logger" + netceptor "github.com/ansible/receptor/pkg/netceptor" + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockNetceptorForWorkceptor is a mock of NetceptorForWorkceptor interface +type MockNetceptorForWorkceptor struct { + ctrl *gomock.Controller + recorder *MockNetceptorForWorkceptorMockRecorder +} + +// MockNetceptorForWorkceptorMockRecorder is the mock recorder for MockNetceptorForWorkceptor +type MockNetceptorForWorkceptorMockRecorder struct { + mock *MockNetceptorForWorkceptor +} + +// NewMockNetceptorForWorkceptor creates a new mock instance +func NewMockNetceptorForWorkceptor(ctrl *gomock.Controller) *MockNetceptorForWorkceptor { + mock := &MockNetceptorForWorkceptor{ctrl: ctrl} + mock.recorder = &MockNetceptorForWorkceptorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockNetceptorForWorkceptor) EXPECT() *MockNetceptorForWorkceptorMockRecorder { + return m.recorder +} + +// NodeID mocks base method +func (m *MockNetceptorForWorkceptor) NodeID() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeID") + ret0, _ := ret[0].(string) + return ret0 +} + +// NodeID indicates an expected call of NodeID +func (mr *MockNetceptorForWorkceptorMockRecorder) NodeID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeID", reflect.TypeOf((*MockNetceptorForWorkceptor)(nil).NodeID)) +} + +// AddWorkCommand mocks base method +func (m *MockNetceptorForWorkceptor) AddWorkCommand(typeName string, verifySignature bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddWorkCommand", typeName, verifySignature) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddWorkCommand indicates an expected call of AddWorkCommand +func (mr *MockNetceptorForWorkceptorMockRecorder) AddWorkCommand(typeName, verifySignature interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWorkCommand", reflect.TypeOf((*MockNetceptorForWorkceptor)(nil).AddWorkCommand), typeName, verifySignature) +} + +// GetClientTLSConfig mocks base method +func (m *MockNetceptorForWorkceptor) GetClientTLSConfig(name, expectedHostName string, expectedHostNameType netceptor.ExpectedHostnameType) (*tls.Config, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetClientTLSConfig", name, expectedHostName, expectedHostNameType) + ret0, _ := ret[0].(*tls.Config) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetClientTLSConfig indicates an expected call of GetClientTLSConfig +func (mr *MockNetceptorForWorkceptorMockRecorder) GetClientTLSConfig(name, expectedHostName, expectedHostNameType interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClientTLSConfig", reflect.TypeOf((*MockNetceptorForWorkceptor)(nil).GetClientTLSConfig), name, expectedHostName, expectedHostNameType) +} + +// GetLogger mocks base method +func (m *MockNetceptorForWorkceptor) GetLogger() *logger.ReceptorLogger { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLogger") + ret0, _ := ret[0].(*logger.ReceptorLogger) + return ret0 +} + +// GetLogger indicates an expected call of GetLogger +func (mr *MockNetceptorForWorkceptorMockRecorder) GetLogger() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogger", reflect.TypeOf((*MockNetceptorForWorkceptor)(nil).GetLogger)) +} + +// DialContext mocks base method +func (m *MockNetceptorForWorkceptor) DialContext(ctx context.Context, node, service string, tlscfg *tls.Config) (*netceptor.Conn, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DialContext", ctx, node, service, tlscfg) + ret0, _ := ret[0].(*netceptor.Conn) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DialContext indicates an expected call of DialContext +func (mr *MockNetceptorForWorkceptorMockRecorder) DialContext(ctx, node, service, tlscfg interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DialContext", reflect.TypeOf((*MockNetceptorForWorkceptor)(nil).DialContext), ctx, node, service, tlscfg) +} diff --git a/pkg/workceptor/remote_work.go b/pkg/workceptor/remote_work.go index 190748e0d..89dd5158f 100644 --- a/pkg/workceptor/remote_work.go +++ b/pkg/workceptor/remote_work.go @@ -85,7 +85,7 @@ func (rw *remoteUnit) getConnection(ctx context.Context) (net.Conn, *bufio.Reade if err == nil { return conn, reader } - rw.w.nc.Logger.Debug("Connection to %s failed with error: %s", + rw.w.nc.GetLogger().Debug("Connection to %s failed with error: %s", rw.Status().ExtraData.(*remoteExtraData).RemoteNode, err) errStr := err.Error() if strings.Contains(errStr, "CRYPTO_ERROR") { @@ -269,7 +269,7 @@ func (rw *remoteUnit) monitorRemoteStatus(mw *utils.JobContext, forRelease bool) status := rw.Status() red, ok := status.ExtraData.(*remoteExtraData) if !ok { - rw.w.nc.Logger.Error("remote ExtraData missing") + rw.w.nc.GetLogger().Error("remote ExtraData missing") return } @@ -294,7 +294,7 @@ func (rw *remoteUnit) monitorRemoteStatus(mw *utils.JobContext, forRelease bool) } _, err := conn.Write([]byte(fmt.Sprintf("work status %s\n", remoteUnitID))) if err != nil { - rw.w.nc.Logger.Debug("Write error sending to %s: %s\n", remoteUnitID, err) + rw.w.nc.GetLogger().Debug("Write error sending to %s: %s\n", remoteUnitID, err) _ = conn.(interface{ CloseConnection() error }).CloseConnection() conn = nil @@ -302,7 +302,7 @@ func (rw *remoteUnit) monitorRemoteStatus(mw *utils.JobContext, forRelease bool) } status, err := utils.ReadStringContext(mw, reader, '\n') if err != nil { - rw.w.nc.Logger.Debug("Read error reading from %s: %s\n", remoteNode, err) + rw.w.nc.GetLogger().Debug("Read error reading from %s: %s\n", remoteNode, err) _ = conn.(interface{ CloseConnection() error }).CloseConnection() conn = nil @@ -311,7 +311,7 @@ func (rw *remoteUnit) monitorRemoteStatus(mw *utils.JobContext, forRelease bool) if status[:5] == "ERROR" { if strings.Contains(status, "unknown work unit") { if !forRelease { - rw.w.nc.Logger.Debug("Work unit %s on node %s is gone.\n", remoteUnitID, remoteNode) + rw.w.nc.GetLogger().Debug("Work unit %s on node %s is gone.\n", remoteUnitID, remoteNode) rw.UpdateFullStatus(func(status *StatusFileData) { status.State = WorkStateFailed status.Detail = "Remote work unit is gone" @@ -320,14 +320,14 @@ func (rw *remoteUnit) monitorRemoteStatus(mw *utils.JobContext, forRelease bool) return } - rw.w.nc.Logger.Error("Remote error: %s\n", strings.TrimRight(status[6:], "\n")) + rw.w.nc.GetLogger().Error("Remote error: %s\n", strings.TrimRight(status[6:], "\n")) return } si := StatusFileData{} err = json.Unmarshal([]byte(status), &si) if err != nil { - rw.w.nc.Logger.Error("Error unmarshalling JSON: %s\n", status) + rw.w.nc.GetLogger().Error("Error unmarshalling JSON: %s\n", status) return } @@ -335,7 +335,7 @@ func (rw *remoteUnit) monitorRemoteStatus(mw *utils.JobContext, forRelease bool) if rw.LastUpdateError() != nil { writeStatusFailures++ if writeStatusFailures > 3 { - rw.w.nc.Logger.Error("Exceeded retries for updating status file for work unit %s", rw.unitID) + rw.w.nc.GetLogger().Error("Exceeded retries for updating status file for work unit %s", rw.unitID) return } @@ -343,7 +343,7 @@ func (rw *remoteUnit) monitorRemoteStatus(mw *utils.JobContext, forRelease bool) writeStatusFailures = 0 } if err != nil { - rw.w.nc.Logger.Error("Error saving local status file: %s\n", err) + rw.w.nc.GetLogger().Error("Error saving local status file: %s\n", err) return } @@ -363,7 +363,7 @@ func (rw *remoteUnit) monitorRemoteStdout(mw *utils.JobContext) { status := rw.Status() red, ok := status.ExtraData.(*remoteExtraData) if !ok { - rw.w.nc.Logger.Error("remote ExtraData missing") + rw.w.nc.GetLogger().Error("remote ExtraData missing") return } @@ -374,7 +374,7 @@ func (rw *remoteUnit) monitorRemoteStdout(mw *utils.JobContext) { err = stdout.Close() } if err != nil { - rw.w.nc.Logger.Error("Could not open stdout file %s: %s\n", rw.stdoutFileName, err) + rw.w.nc.GetLogger().Error("Could not open stdout file %s: %s\n", rw.stdoutFileName, err) return } @@ -389,7 +389,7 @@ func (rw *remoteUnit) monitorRemoteStdout(mw *utils.JobContext) { } err := rw.Load() if err != nil { - rw.w.nc.Logger.Error("Could not read status file %s: %s\n", rw.statusFileName, err) + rw.w.nc.GetLogger().Error("Could not read status file %s: %s\n", rw.statusFileName, err) return } @@ -416,7 +416,7 @@ func (rw *remoteUnit) monitorRemoteStdout(mw *utils.JobContext) { if red.SignWork { signature, err := rw.w.createSignature(red.RemoteNode) if err != nil { - rw.w.nc.Logger.Error("could not create signature to get results") + rw.w.nc.GetLogger().Error("could not create signature to get results") return } @@ -424,31 +424,31 @@ func (rw *remoteUnit) monitorRemoteStdout(mw *utils.JobContext) { } wscBytes, err := json.Marshal(workSubmitCmd) if err != nil { - rw.w.nc.Logger.Error("error constructing work results command: %s", err) + rw.w.nc.GetLogger().Error("error constructing work results command: %s", err) return } wscBytes = append(wscBytes, '\n') _, err = conn.Write(wscBytes) if err != nil { - rw.w.nc.Logger.Warning("Write error sending to %s: %s\n", remoteNode, err) + rw.w.nc.GetLogger().Warning("Write error sending to %s: %s\n", remoteNode, err) continue } status, err := utils.ReadStringContext(mw, reader, '\n') if err != nil { - rw.w.nc.Logger.Warning("Read error reading from %s: %s\n", remoteNode, err) + rw.w.nc.GetLogger().Warning("Read error reading from %s: %s\n", remoteNode, err) continue } if !strings.Contains(status, "Streaming results") { - rw.w.nc.Logger.Warning("Remote node %s did not stream results\n", remoteNode) + rw.w.nc.GetLogger().Warning("Remote node %s did not stream results\n", remoteNode) continue } stdout, err := os.OpenFile(rw.stdoutFileName, os.O_CREATE+os.O_APPEND+os.O_WRONLY, 0o600) if err != nil { - rw.w.nc.Logger.Error("Could not open stdout file %s: %s\n", rw.stdoutFileName, err) + rw.w.nc.GetLogger().Error("Could not open stdout file %s: %s\n", rw.stdoutFileName, err) return } @@ -476,7 +476,7 @@ func (rw *remoteUnit) monitorRemoteStdout(mw *utils.JobContext) { } else { errmsg = err.Error() } - rw.w.nc.Logger.Warning("Could not copy to stdout file %s: %s\n", rw.stdoutFileName, errmsg) + rw.w.nc.GetLogger().Warning("Could not copy to stdout file %s: %s\n", rw.stdoutFileName, errmsg) continue } @@ -558,7 +558,7 @@ func (rw *remoteUnit) runAndMonitor(mw *utils.JobContext, forRelease bool, actio if forRelease { err := rw.BaseWorkUnit.Release(false) if err != nil { - rw.w.nc.Logger.Error("Error releasing unit %s: %s", rw.UnitDir(), err) + rw.w.nc.GetLogger().Error("Error releasing unit %s: %s", rw.UnitDir(), err) } } mw.WorkerDone() @@ -679,7 +679,7 @@ func (rw *remoteUnit) Release(force bool) error { } func newRemoteWorker(w *Workceptor, unitID, workType string) WorkUnit { - rw := &remoteUnit{logger: w.nc.Logger} + rw := &remoteUnit{logger: w.nc.GetLogger()} rw.BaseWorkUnit.Init(w, unitID, workType) red := &remoteExtraData{} red.RemoteParams = make(map[string]string) diff --git a/pkg/workceptor/workceptor.go b/pkg/workceptor/workceptor.go index a77fb6adf..0057f9a77 100644 --- a/pkg/workceptor/workceptor.go +++ b/pkg/workceptor/workceptor.go @@ -5,6 +5,7 @@ package workceptor import ( "context" + "crypto/tls" "fmt" "io" "os" @@ -16,17 +17,28 @@ import ( "github.com/ansible/receptor/pkg/certificates" "github.com/ansible/receptor/pkg/controlsvc" + "github.com/ansible/receptor/pkg/logger" "github.com/ansible/receptor/pkg/netceptor" "github.com/ansible/receptor/pkg/randstr" "github.com/ansible/receptor/pkg/utils" "github.com/golang-jwt/jwt/v4" ) +// NetceptorForWorkceptor is a interface to decouple workceptor from netceptor. +// it includes only the functions that workceptor uses. +type NetceptorForWorkceptor interface { + NodeID() string + AddWorkCommand(typeName string, verifySignature bool) error + GetClientTLSConfig(name string, expectedHostName string, expectedHostNameType netceptor.ExpectedHostnameType) (*tls.Config, error) // have a common pkg for types + GetLogger() *logger.ReceptorLogger + DialContext(ctx context.Context, node string, service string, tlscfg *tls.Config) (*netceptor.Conn, error) // create an interface for Conn +} + // Workceptor is the main object that handles unit-of-work management. type Workceptor struct { ctx context.Context Cancel context.CancelFunc - nc *netceptor.Netceptor + nc NetceptorForWorkceptor dataDir string workTypesLock *sync.RWMutex workTypes map[string]*workType @@ -44,7 +56,7 @@ type workType struct { } // New constructs a new Workceptor instance. -func New(ctx context.Context, nc *netceptor.Netceptor, dataDir string) (*Workceptor, error) { +func New(ctx context.Context, nc NetceptorForWorkceptor, dataDir string) (*Workceptor, error) { if dataDir == "" { dataDir = path.Join(os.TempDir(), "receptor") } @@ -271,12 +283,12 @@ func (w *Workceptor) AllocateRemoteUnit(remoteNode, remoteWorkType, tlsClient, t if ttl != "" { duration, err := time.ParseDuration(ttl) if err != nil { - w.nc.Logger.Error("Failed to parse provided ttl -- valid examples include '1.5h', '30m', '30m10s'") + w.nc.GetLogger().Error("Failed to parse provided ttl -- valid examples include '1.5h', '30m', '30m10s'") return nil, err } if signWork && duration > w.SigningExpiration { - w.nc.Logger.Warning("json web token expires before ttl") + w.nc.GetLogger().Warning("json web token expires before ttl") } expiration = time.Now().Add(duration) } else { @@ -301,7 +313,7 @@ func (w *Workceptor) scanForUnit(unitID string) { unitdir := path.Join(w.dataDir, unitID) fi, _ := os.Stat(unitdir) if fi == nil || !fi.IsDir() { - w.nc.Logger.Error("Error locating unit: %s", unitID) + w.nc.GetLogger().Error("Error locating unit: %s", unitID) return } @@ -323,18 +335,18 @@ func (w *Workceptor) scanForUnit(unitID string) { worker = newUnknownWorker(w, ident, sfd.WorkType) } if _, err := os.Stat(statusFilename); os.IsNotExist(err) { - w.nc.Logger.Error("Status file has disappeared for %s.", ident) + w.nc.GetLogger().Error("Status file has disappeared for %s.", ident) return } err := worker.Load() if err != nil { - w.nc.Logger.Warning("Failed to restart worker %s due to read error: %s", unitdir, err) + w.nc.GetLogger().Warning("Failed to restart worker %s due to read error: %s", unitdir, err) worker.UpdateBasicStatus(WorkStateFailed, fmt.Sprintf("Failed to restart: %s", err), stdoutSize(unitdir)) } err = worker.Restart() if err != nil && !IsPending(err) { - w.nc.Logger.Warning("Failed to restart worker %s: %s", unitdir, err) + w.nc.GetLogger().Warning("Failed to restart worker %s: %s", unitdir, err) worker.UpdateBasicStatus(WorkStateFailed, fmt.Sprintf("Failed to restart: %s", err), stdoutSize(unitdir)) } w.activeUnitsLock.Lock() @@ -471,7 +483,7 @@ func (w *Workceptor) GetResults(ctx context.Context, unitID string, startPos int defer func() { err = stdout.Close() if err != nil { - w.nc.Logger.Error("Error closing stdout %s", stdoutFilename) + w.nc.GetLogger().Error("Error closing stdout %s", stdoutFilename) } resultClose() cancel() @@ -484,7 +496,7 @@ func (w *Workceptor) GetResults(ctx context.Context, unitID string, startPos int case err == nil: case os.IsNotExist(err): if IsComplete(unit.Status().State) { - w.nc.Logger.Warning("Unit completed without producing any stdout\n") + w.nc.GetLogger().Warning("Unit completed without producing any stdout\n") return } @@ -494,7 +506,7 @@ func (w *Workceptor) GetResults(ctx context.Context, unitID string, startPos int continue default: - w.nc.Logger.Error("Error accessing stdout file: %s\n", err) + w.nc.GetLogger().Error("Error accessing stdout file: %s\n", err) return } @@ -514,7 +526,7 @@ func (w *Workceptor) GetResults(ctx context.Context, unitID string, startPos int if os.IsNotExist(err) { failures++ if failures > 3 { - w.nc.Logger.Error("Exceeded retries for reading stdout %s", stdoutFilename) + w.nc.GetLogger().Error("Exceeded retries for reading stdout %s", stdoutFilename) statChan <- struct{}{} return @@ -539,12 +551,12 @@ func (w *Workceptor) GetResults(ctx context.Context, unitID string, startPos int var newPos int64 newPos, err = stdout.Seek(filePos, 0) if err != nil { - w.nc.Logger.Warning("Seek error processing stdout: %s\n", err) + w.nc.GetLogger().Warning("Seek error processing stdout: %s\n", err) return } if newPos != filePos { - w.nc.Logger.Warning("Seek error processing stdout\n") + w.nc.GetLogger().Warning("Seek error processing stdout\n") return } @@ -567,12 +579,12 @@ func (w *Workceptor) GetResults(ctx context.Context, unitID string, startPos int if err == io.EOF { unitStatus := unit.Status() if IsComplete(unitStatus.State) && filePos >= unitStatus.StdoutSize { - w.nc.Logger.Debug("Stdout complete - closing channel for: %s \n", unitID) + w.nc.GetLogger().Debug("Stdout complete - closing channel for: %s \n", unitID) return } } else if err != nil { - w.nc.Logger.Error("Error reading stdout: %s\n", err) + w.nc.GetLogger().Error("Error reading stdout: %s\n", err) return } diff --git a/pkg/workceptor/workceptor_test.go b/pkg/workceptor/workceptor_test.go new file mode 100644 index 000000000..79a901e3e --- /dev/null +++ b/pkg/workceptor/workceptor_test.go @@ -0,0 +1,67 @@ +package workceptor_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/ansible/receptor/pkg/logger" + "github.com/ansible/receptor/pkg/workceptor" + "github.com/ansible/receptor/pkg/workceptor/mock_workceptor" + "github.com/golang/mock/gomock" +) + +func TestAllocateUnit(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockWorkUnit := mock_workceptor.NewMockWorkUnit(ctrl) + mockWorkUnit.EXPECT().SetFromParams(gomock.Any()).Return(nil).Times(1) + mockWorkUnit.EXPECT().Save().Return(nil).Times(1) + ctx := context.Background() + mockNetceptor := mock_workceptor.NewMockNetceptorForWorkceptor(ctrl) + + // attach logger to the mock netceptor and return any number of times + logger := logger.NewReceptorLogger("") + mockNetceptor.EXPECT().GetLogger().AnyTimes().Return(logger) + + workFunc := func(w *workceptor.Workceptor, unitID string, workType string) workceptor.WorkUnit { + return mockWorkUnit + } + + mockNetceptor.EXPECT().NodeID().Return("test") + w, err := workceptor.New(ctx, mockNetceptor, "/tmp") + if err != nil { + t.Errorf("Error while creating Workceptor: %v", err) + } + + mockNetceptor.EXPECT().AddWorkCommand(gomock.Any(), gomock.Any()).Return(nil) + w.RegisterWorker("testType", workFunc, false) + // Test a normal case + _, err = w.AllocateUnit("testType", map[string]string{"param": "value"}) + if err != nil { + t.Errorf("Expected no error, got: %v", err) + } + + // Test with a work type that doesn't exist + _, err = w.AllocateUnit("nonexistentType", map[string]string{"param": "value"}) + if err == nil || err.Error() != fmt.Errorf("unknown work type %s", "nonexistentType").Error() { + t.Errorf("Expected 'unknown work type %s', got: %v", "nonexistentType", err) + } + + // Test with a SetFromParams that returns an error + mockWorkUnit.EXPECT().SetFromParams(gomock.Any()).Return(errors.New("SetFromParams error")) + _, err = w.AllocateUnit("testType", map[string]string{"param": "value"}) + if err == nil || err.Error() != "SetFromParams error" { + t.Errorf("Expected 'SetFromParams error', got: %v", err) + } + + // Test with a Save that returns an error + mockWorkUnit.EXPECT().SetFromParams(gomock.Any()).Return(nil) + mockWorkUnit.EXPECT().Save().Return(errors.New("Save error")) + _, err = w.AllocateUnit("testType", map[string]string{"param": "value"}) + if err == nil || err.Error() != "Save error" { + t.Errorf("Expected 'Save error', got: %v", err) + } +} diff --git a/pkg/workceptor/workunitbase.go b/pkg/workceptor/workunitbase.go index 6d3c52aa3..62cb2ce59 100644 --- a/pkg/workceptor/workunitbase.go +++ b/pkg/workceptor/workunitbase.go @@ -95,25 +95,25 @@ func (bwu *BaseWorkUnit) Init(w *Workceptor, unitID string, workType string) { // Error logs message with unitID prepended. func (bwu *BaseWorkUnit) Error(format string, v ...interface{}) { format = fmt.Sprintf("[%s] %s", bwu.unitID, format) - bwu.w.nc.Logger.Error(format, v...) + bwu.w.nc.GetLogger().Error(format, v...) } // Warning logs message with unitID prepended. func (bwu *BaseWorkUnit) Warning(format string, v ...interface{}) { format = fmt.Sprintf("[%s] %s", bwu.unitID, format) - bwu.w.nc.Logger.Warning(format, v...) + bwu.w.nc.GetLogger().Warning(format, v...) } // Info logs message with unitID prepended. func (bwu *BaseWorkUnit) Info(format string, v ...interface{}) { format = fmt.Sprintf("[%s] %s", bwu.unitID, format) - bwu.w.nc.Logger.Info(format, v...) + bwu.w.nc.GetLogger().Info(format, v...) } // Debug logs message with unitID prepended. func (bwu *BaseWorkUnit) Debug(format string, v ...interface{}) { format = fmt.Sprintf("[%s] %s", bwu.unitID, format) - bwu.w.nc.Logger.Debug(format, v...) + bwu.w.nc.GetLogger().Debug(format, v...) } // SetFromParams sets the in-memory state from parameters. @@ -155,7 +155,7 @@ func (sfd *StatusFileData) lockStatusFile(filename string) (*lockedfile.File, er // unlockStatusFile releases the lock on the status file. func (sfd *StatusFileData) unlockStatusFile(filename string, lockFile *lockedfile.File) { if err := lockFile.Close(); err != nil { - MainInstance.nc.Logger.Error("Error closing %s.lock: %s", filename, err) + MainInstance.nc.GetLogger().Error("Error closing %s.lock: %s", filename, err) } } @@ -254,7 +254,7 @@ func (sfd *StatusFileData) UpdateFullStatus(filename string, statusFunc func(*St defer func() { err := file.Close() if err != nil { - MainInstance.nc.Logger.Error("Error closing %s: %s", filename, err) + MainInstance.nc.GetLogger().Error("Error closing %s: %s", filename, err) } }() size, err := file.Seek(0, 2) @@ -300,7 +300,7 @@ func (bwu *BaseWorkUnit) UpdateFullStatus(statusFunc func(*StatusFileData)) { bwu.lastUpdateError = err if err != nil { - bwu.w.nc.Logger.Error("Error updating status file %s: %s.", bwu.statusFileName, err) + bwu.w.nc.GetLogger().Error("Error updating status file %s: %s.", bwu.statusFileName, err) } } @@ -328,7 +328,7 @@ func (bwu *BaseWorkUnit) UpdateBasicStatus(state int, detail string, stdoutSize bwu.lastUpdateError = err if err != nil { - bwu.w.nc.Logger.Error("Error updating status file %s: %s.", bwu.statusFileName, err) + bwu.w.nc.GetLogger().Error("Error updating status file %s: %s.", bwu.statusFileName, err) } } @@ -376,7 +376,7 @@ loop: if event.Op&fsnotify.Write == fsnotify.Write { err = bwu.Load() if err != nil { - bwu.w.nc.Logger.Error("Error reading %s: %s", statusFile, err) + bwu.w.nc.GetLogger().Error("Error reading %s: %s", statusFile, err) } } case <-time.After(time.Second): @@ -386,7 +386,7 @@ loop: fi = newFi err = bwu.Load() if err != nil { - bwu.w.nc.Logger.Error("Error reading %s: %s", statusFile, err) + bwu.w.nc.GetLogger().Error("Error reading %s: %s", statusFile, err) } } } @@ -432,12 +432,12 @@ func (bwu *BaseWorkUnit) Release(force bool) error { attemptsLeft-- if attemptsLeft > 0 { - bwu.w.nc.Logger.Warning("Error removing directory for %s. Retrying %d more times.", bwu.unitID, attemptsLeft) + bwu.w.nc.GetLogger().Warning("Error removing directory for %s. Retrying %d more times.", bwu.unitID, attemptsLeft) time.Sleep(time.Second) continue } - bwu.w.nc.Logger.Error("Error removing directory for %s. No more retries left.", bwu.unitID) + bwu.w.nc.GetLogger().Error("Error removing directory for %s. No more retries left.", bwu.unitID) return err }