adding tests for Detect struct in collector. Adding ability to mock out exec.Command calls.

This commit is contained in:
Jason Kulatunga
2022-05-06 20:07:23 -07:00
parent 2214febbd1
commit 21d07a0712
15 changed files with 314 additions and 16 deletions
+5
View File
@@ -0,0 +1,5 @@
package shell
func Create() Interface {
return new(localShell)
}
+11
View File
@@ -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)
}
+45
View File
@@ -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)
}