adding tests for Detect struct in collector. Adding ability to mock out exec.Command calls.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
package shell
|
||||
|
||||
func Create() Interface {
|
||||
return new(localShell)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Create mock using:
|
||||
// mockgen -source=collector/pkg/common/shell/interface.go -destination=collector/pkg/common/shell/mock/mock_shell.go
|
||||
type Interface interface {
|
||||
Command(logger *logrus.Entry, cmdName string, cmdArgs []string, workingDir string, environ []string) (string, error)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type localShell struct{}
|
||||
|
||||
func (s *localShell) Command(logger *logrus.Entry, cmdName string, cmdArgs []string, workingDir string, environ []string) (string, error) {
|
||||
logger.Infof("Executing command: %s %s", cmdName, strings.Join(cmdArgs, " "))
|
||||
|
||||
cmd := exec.Command(cmdName, cmdArgs...)
|
||||
var stdBuffer bytes.Buffer
|
||||
|
||||
logWriters := []io.Writer{
|
||||
&stdBuffer,
|
||||
}
|
||||
if logger.Logger.Level == logrus.DebugLevel {
|
||||
logWriters = append(logWriters, logger.Logger.Out)
|
||||
}
|
||||
|
||||
mw := io.MultiWriter(logWriters...)
|
||||
|
||||
cmd.Stdout = mw
|
||||
cmd.Stderr = mw
|
||||
|
||||
if environ != nil {
|
||||
cmd.Env = environ
|
||||
}
|
||||
if workingDir != "" && path.IsAbs(workingDir) {
|
||||
cmd.Dir = workingDir
|
||||
} else if workingDir != "" {
|
||||
return "", errors.New("Working Directory must be an absolute path")
|
||||
}
|
||||
|
||||
err := cmd.Run()
|
||||
return stdBuffer.String(), err
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLocalShellCommand(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
//setup
|
||||
testShell := localShell{}
|
||||
//test
|
||||
result, err := testShell.Command(logrus.WithField("exec", "test"), "echo", []string{"hello world"}, "", nil)
|
||||
|
||||
//assert
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "hello world\n", result)
|
||||
}
|
||||
|
||||
func TestLocalShellCommand_Date(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
//setup
|
||||
testShell := localShell{}
|
||||
|
||||
//test
|
||||
_, err := testShell.Command(logrus.WithField("exec", "test"), "date", []string{}, "", nil)
|
||||
|
||||
//assert
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
//
|
||||
//func TestExecCmd_Error(t *testing.T) {
|
||||
// t.Parallel()
|
||||
//
|
||||
// //setup
|
||||
// bc := collector.BaseCollector {}
|
||||
//
|
||||
// //test
|
||||
// _, err := bc.ExecCmd("smartctl", []string{"-a", "/dev/doesnotexist"}, "", nil)
|
||||
//
|
||||
// //assert
|
||||
// exitError, castOk := err.(*exec.ExitError);
|
||||
// require.True(t, castOk)
|
||||
// require.Equal(t, 1, exitError.ExitCode())
|
||||
//
|
||||
//}
|
||||
//
|
||||
|
||||
func TestLocalShellCommand_InvalidCommand(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
//setup
|
||||
testShell := localShell{}
|
||||
|
||||
//test
|
||||
_, err := testShell.Command(logrus.WithField("exec", "test"), "invalid_binary", []string{}, "", nil)
|
||||
|
||||
//assert
|
||||
_, castOk := err.(*exec.ExitError)
|
||||
require.False(t, castOk)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: collector/pkg/common/shell/interface.go
|
||||
|
||||
// Package mock_shell is a generated GoMock package.
|
||||
package mock_shell
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Command mocks base method.
|
||||
func (m *MockInterface) Command(logger *logrus.Entry, cmdName string, cmdArgs []string, workingDir string, environ []string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Command", logger, cmdName, cmdArgs, workingDir, environ)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Command indicates an expected call of Command.
|
||||
func (mr *MockInterfaceMockRecorder) Command(logger, cmdName, cmdArgs, workingDir, environ interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Command", reflect.TypeOf((*MockInterface)(nil).Command), logger, cmdName, cmdArgs, workingDir, environ)
|
||||
}
|
||||
Reference in New Issue
Block a user