From f9eedd99fd0217bcf85c090026369a9c9ffe1df2 Mon Sep 17 00:00:00 2001 From: iancardosozup <86669442+iancardosozup@users.noreply.github.com> Date: Fri, 17 Dec 2021 13:00:34 -0300 Subject: [PATCH] requirements:bugfix - now returns error instead of panicking when fail (#856) Signed-off-by: Ian Cardoso --- cmd/app/start/start.go | 19 ++-- cmd/app/start/start_test.go | 99 +++++++++++++------ .../controllers/requirements/docker/docker.go | 41 ++++---- internal/controllers/requirements/git/git.go | 37 +++---- .../controllers/requirements/requirements.go | 29 ++---- .../requirements/requirements_test.go | 12 +-- internal/utils/testutil/requirements_mock.go | 11 ++- 7 files changed, 137 insertions(+), 111 deletions(-) diff --git a/cmd/app/start/start.go b/cmd/app/start/start.go index d5e2c76cd..8cbe9bd25 100644 --- a/cmd/app/start/start.go +++ b/cmd/app/start/start.go @@ -49,8 +49,8 @@ type Prompt interface { // Requirements is the interface that validate Horusec dynamic // requirements to execute analysis type Requirements interface { - ValidateDocker() - ValidateGit() + ValidateDocker() error + ValidateGit() error } type Start struct { @@ -319,20 +319,27 @@ func (s *Start) validateConfig() error { return err } - s.validateRequirements() + if err := s.validateRequirements(); err != nil { + return err + } logger.LogDebugWithLevel(messages.MsgDebugShowConfigs + string(s.configs.Bytes())) return nil } -func (s *Start) validateRequirements() { +func (s *Start) validateRequirements() error { if s.configs.EnableGitHistoryAnalysis { - s.requirements.ValidateGit() + if err := s.requirements.ValidateGit(); err != nil { + return err + } } if !s.configs.DisableDocker { - s.requirements.ValidateDocker() + if err := s.requirements.ValidateDocker(); err != nil { + return err + } } + return nil } func (s *Start) isRunPromptQuestion(cmd *cobra.Command) bool { diff --git a/cmd/app/start/start_test.go b/cmd/app/start/start_test.go index 396672f05..9bf5e39a3 100644 --- a/cmd/app/start/start_test.go +++ b/cmd/app/start/start_test.go @@ -59,7 +59,7 @@ func TestNewStartCommand(t *testing.T) { analyzerMock := testutil.NewAnalyzerMock() promptMock.On("Ask").Return("Y", nil) analyzerMock.On("Analyze").Return(0, nil) - requirementsMock.On("ValidateDocker") + requirementsMock.On("ValidateDocker").Return(nil) start := &Start{ configs: cfg, prompt: promptMock, @@ -103,7 +103,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) analyzer.On("Analyze").Return(0, nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { prompt.AssertCalled(t, "Ask") @@ -118,7 +118,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) analyzer.On("Analyze").Return(0, nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -135,7 +135,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { err: true, onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(10, nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -169,8 +169,8 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) analyzer.On("Analyze").Return(0, nil) - requirements.On("ValidateDocker") - requirements.On("ValidateGit") + requirements.On("ValidateDocker").Return(nil) + requirements.On("ValidateGit").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.True(t, cfg.ReturnErrorIfFoundVulnerability) @@ -182,6 +182,45 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { requirements.AssertCalled(t, "ValidateGit") }, }, + { + name: "Should execute command exec with error when validate if git is installed(--enable-git-history)", + args: []string{testutil.StartFlagEnableGitHistory, testutil.StartFlagReturnError}, + err: true, + onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { + prompt.On("Ask").Return("Y", nil) + analyzer.On("Analyze").Return(0, nil) + requirements.On("ValidateGit").Return(errors.New("some error")) + }, + assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { + assert.True(t, cfg.ReturnErrorIfFoundVulnerability) + assert.True(t, cfg.EnableGitHistoryAnalysis) + + prompt.AssertCalled(t, "Ask") + analyzer.AssertNotCalled(t, "Analyze") + requirements.AssertNotCalled(t, "ValidateDocker") + requirements.AssertCalled(t, "ValidateGit") + }, + }, + { + name: "Should execute command exec with error when validate if docker is installed", + args: []string{testutil.StartFlagEnableGitHistory, testutil.StartFlagReturnError}, + err: true, + onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { + prompt.On("Ask").Return("Y", nil) + analyzer.On("Analyze").Return(0, nil) + requirements.On("ValidateDocker").Return(errors.New("some error")) + requirements.On("ValidateGit").Return(nil) + }, + assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { + assert.True(t, cfg.ReturnErrorIfFoundVulnerability) + assert.True(t, cfg.EnableGitHistoryAnalysis) + + prompt.AssertCalled(t, "Ask") + analyzer.AssertNotCalled(t, "Analyze") + requirements.AssertCalled(t, "ValidateDocker") + requirements.AssertCalled(t, "ValidateGit") + }, + }, { name: "Should execute command exec without error and not ask because is different project path(-p, -e)", args: []string{testutil.StartFlagReturnError, testutil.StartFlagProjectPath, os.TempDir()}, @@ -189,7 +228,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) analyzer.On("Analyze").Return(0, nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.True(t, cfg.ReturnErrorIfFoundVulnerability) @@ -223,7 +262,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) analyzer.On("Analyze").Return(10, nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, filepath.Clean(os.TempDir()), cfg.ProjectPath) @@ -242,7 +281,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) analyzer.On("Analyze").Return(0, nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, filepath.Clean(os.TempDir()), cfg.ProjectPath) @@ -260,7 +299,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { err: false, onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) analyzer.On("Analyze").Return(0, nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { @@ -280,7 +319,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -299,7 +338,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -317,7 +356,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { err: false, onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) analyzer.On("Analyze").Return(0, nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { @@ -336,7 +375,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { t.Run("Should execute command exec without error sending to web application (-u,-a)", func(t *testing.T) { @@ -356,7 +395,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, "*vsaf&&", cfg.HorusecAPIUri) @@ -374,7 +413,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -392,7 +431,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -410,7 +449,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -428,7 +467,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -446,7 +485,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, testutil.RootPath, cfg.ProjectPath) @@ -464,7 +503,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.NotEqual(t, "potato", cfg.TimeoutInSecondsAnalysis) @@ -481,7 +520,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.True(t, cfg.DisableDocker) @@ -498,7 +537,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.Equal(t, int64(123), cfg.TimeoutInSecondsRequest) @@ -515,7 +554,7 @@ func TestStartCommand_ExecuteUnitTests(t *testing.T) { onFn: func(prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock) { analyzer.On("Analyze").Return(0, nil) prompt.On("Ask").Return("Y", nil) - requirements.On("ValidateDocker") + requirements.On("ValidateDocker").Return(nil) }, assertFn: func(t *testing.T, prompt *testutil.PromptMock, requirements *testutil.RequirementsMock, analyzer *testutil.AnalyzerMock, cfg *config.Config) { assert.NotEqual(t, "potato", cfg.TimeoutInSecondsRequest) @@ -557,7 +596,7 @@ func TestStartCommand_ExecuteIntegrationTest(t *testing.T) { cfg.WorkDir = &workdir.WorkDir{} requirementsMock := testutil.NewRequirementsMock() - requirementsMock.On("ValidateDocker") + requirementsMock.On("ValidateDocker").Return(nil) cmd := &Start{ configs: cfg, @@ -616,7 +655,7 @@ func TestStartCommand_ExecuteIntegrationTest(t *testing.T) { cfg.WorkDir = &workdir.WorkDir{} requirementsMock := testutil.NewRequirementsMock() - requirementsMock.On("ValidateDocker") + requirementsMock.On("ValidateDocker").Return(nil) cmd := &Start{ configs: cfg, @@ -662,7 +701,7 @@ func TestStartCommand_ExecuteIntegrationTest(t *testing.T) { cfg.WorkDir = &workdir.WorkDir{} requirementsMock := testutil.NewRequirementsMock() - requirementsMock.On("ValidateDocker") + requirementsMock.On("ValidateDocker").Return(nil) cmd := &Start{ configs: cfg, @@ -707,7 +746,7 @@ func TestStartCommand_ExecuteIntegrationTest(t *testing.T) { cfg.WorkDir = &workdir.WorkDir{} requirementsMock := testutil.NewRequirementsMock() - requirementsMock.On("ValidateDocker") + requirementsMock.On("ValidateDocker").Return(nil) cmd := &Start{ configs: cfg, @@ -767,7 +806,7 @@ func TestStartCommand_ExecuteIntegrationTest(t *testing.T) { cfg.WorkDir = &workdir.WorkDir{} requirementsMock := testutil.NewRequirementsMock() - requirementsMock.On("ValidateDocker") + requirementsMock.On("ValidateDocker").Return(nil) cmd := &Start{ configs: cfg, @@ -821,7 +860,7 @@ func TestStartCommand_ExecuteIntegrationTest(t *testing.T) { cfg.WorkDir = &workdir.WorkDir{} requirementMock := testutil.NewRequirementsMock() - requirementMock.On("ValidateDocker") + requirementMock.On("ValidateDocker").Return(nil) cmd := &Start{ configs: cfg, diff --git a/internal/controllers/requirements/docker/docker.go b/internal/controllers/requirements/docker/docker.go index a65070d06..c8f6d4e94 100644 --- a/internal/controllers/requirements/docker/docker.go +++ b/internal/controllers/requirements/docker/docker.go @@ -39,41 +39,36 @@ var ( ErrDockerNotInstalled = errors.New("docker not found. Please check and try again") ) -type RequirementDocker struct{} - -func NewRequirementDocker() *RequirementDocker { - return &RequirementDocker{} -} - -func (r *RequirementDocker) ValidateDocker() error { - response, err := r.validateIfDockerIsInstalled() +func Validate() error { + response, err := validateIfDockerIsInstalled() if err != nil { return err } - return r.validateIfDockerIsSupported(response) + return validateIfDockerIsSupported(response) } -func (r *RequirementDocker) validateIfDockerIsInstalled() (string, error) { - response, err := r.execDockerVersion() +func validateIfDockerIsInstalled() (string, error) { + response, err := execDockerVersion() if err != nil { logger.LogInfo(messages.MsgInfoHowToInstallDocker) return "", err } - if !r.checkIfContainsDockerVersion(response) { + + if !checkIfContainsDockerVersion(response) { return "", ErrDockerNotInstalled } - return response, r.checkIfDockerIsRunning() + return response, checkIfDockerIsRunning() } -func (r *RequirementDocker) validateIfDockerIsSupported(version string) error { - err := r.validateIfDockerIsRunningInMinVersion(version) +func validateIfDockerIsSupported(version string) error { + err := validateIfDockerIsRunningInMinVersion(version) if err != nil { return err } return nil } -func (r *RequirementDocker) execDockerVersion() (string, error) { +func execDockerVersion() (string, error) { responseBytes, err := exec.Command("docker", "-v").CombinedOutput() if err != nil { logger.LogErrorWithLevel( @@ -83,7 +78,7 @@ func (r *RequirementDocker) execDockerVersion() (string, error) { return strings.ToLower(string(responseBytes)), nil } -func (r *RequirementDocker) checkIfDockerIsRunning() error { +func checkIfDockerIsRunning() error { responseBytes, err := exec.Command("docker", "ps").CombinedOutput() if err != nil { logger.LogErrorWithLevel( @@ -92,8 +87,8 @@ func (r *RequirementDocker) checkIfDockerIsRunning() error { return err } -func (r *RequirementDocker) validateIfDockerIsRunningInMinVersion(response string) error { - version, subversion, err := r.extractDockerVersionFromString(response) +func validateIfDockerIsRunningInMinVersion(response string) error { + version, subversion, err := extractDockerVersionFromString(response) if err != nil { logger.LogErrorWithLevel(messages.MsgErrorWhenDockerIsLowerVersion, ErrMinVersion) return err @@ -108,19 +103,19 @@ func (r *RequirementDocker) validateIfDockerIsRunningInMinVersion(response strin return nil } -func (r *RequirementDocker) extractDockerVersionFromString(response string) (int, int, error) { +func extractDockerVersionFromString(response string) (int, int, error) { responseSpited := strings.Split(strings.ToLower(response), "docker version ") if len(responseSpited) < 1 || len(responseSpited) > 1 && len(responseSpited[1]) < 8 { return 0, 0, ErrDockerNotInstalled } - return r.getVersionAndSubVersion(responseSpited[1]) + return getVersionAndSubVersion(responseSpited[1]) } -func (r *RequirementDocker) checkIfContainsDockerVersion(response string) bool { +func checkIfContainsDockerVersion(response string) bool { return strings.Contains(strings.ToLower(response), "docker version ") } -func (r *RequirementDocker) getVersionAndSubVersion(fullVersion string) (int, int, error) { +func getVersionAndSubVersion(fullVersion string) (int, int, error) { version, err := strconv.Atoi(fullVersion[0:2]) if err != nil { return 0, 0, ErrDockerNotInstalled diff --git a/internal/controllers/requirements/git/git.go b/internal/controllers/requirements/git/git.go index 4cc6aa2bf..b8fa60e86 100644 --- a/internal/controllers/requirements/git/git.go +++ b/internal/controllers/requirements/git/git.go @@ -42,33 +42,28 @@ var ( ErrGitLowerVersion = errors.New("git version is lower of 2.01. Please check and try again") ) -type RequirementGit struct{} - -func NewRequirementGit() *RequirementGit { - return &RequirementGit{} -} - -func (r *RequirementGit) ValidateGit() error { - response, err := r.validateIfGitIsInstalled() +func Validate() error { + response, err := validateIfGitIsInstalled() if err != nil { return err } - return r.validateIfGitIsSupported(response) + return validateIfGitIsSupported(response) } -func (r *RequirementGit) validateIfGitIsInstalled() (string, error) { - response, err := r.execGitVersion() +func validateIfGitIsInstalled() (string, error) { + response, err := execGitVersion() if err != nil { return "", err } - if !r.checkIfContainsGitVersion(response) { + + if !checkIfContainsGitVersion(response) { return "", ErrGitNotInstalled } return response, nil } -func (r *RequirementGit) validateIfGitIsSupported(version string) error { - err := r.validateIfGitIsRunningInMinVersion(version) +func validateIfGitIsSupported(version string) error { + err := validateIfGitIsRunningInMinVersion(version) if err != nil { logger.LogInfo(messages.MsgInfoHowToInstallGit) return err @@ -76,7 +71,7 @@ func (r *RequirementGit) validateIfGitIsSupported(version string) error { return nil } -func (r *RequirementGit) execGitVersion() (string, error) { +func execGitVersion() (string, error) { responseBytes, err := exec.Command("git", "--version").CombinedOutput() if err != nil { logger.LogErrorWithLevel(messages.MsgErrorWhenCheckRequirementsGit, err) @@ -85,8 +80,8 @@ func (r *RequirementGit) execGitVersion() (string, error) { return strings.ToLower(string(responseBytes)), nil } -func (r *RequirementGit) validateIfGitIsRunningInMinVersion(response string) error { - version, subversion, err := r.extractGitVersionFromString(response) +func validateIfGitIsRunningInMinVersion(response string) error { + version, subversion, err := extractGitVersionFromString(response) if err != nil { return err } @@ -100,19 +95,19 @@ func (r *RequirementGit) validateIfGitIsRunningInMinVersion(response string) err return nil } -func (r *RequirementGit) extractGitVersionFromString(response string) (int, int, error) { +func extractGitVersionFromString(response string) (int, int, error) { responseSpited := strings.Split(strings.ToLower(response), "git version ") if len(responseSpited) < 1 || len(responseSpited) > 1 && len(responseSpited[1]) < 3 { return 0, 0, ErrGitNotInstalled } - return r.getVersionAndSubVersion(responseSpited[1]) + return getVersionAndSubVersion(responseSpited[1]) } -func (r *RequirementGit) checkIfContainsGitVersion(response string) bool { +func checkIfContainsGitVersion(response string) bool { return strings.Contains(strings.ToLower(response), "git version ") } -func (r *RequirementGit) getVersionAndSubVersion(fullVersion string) (int, int, error) { +func getVersionAndSubVersion(fullVersion string) (int, int, error) { version, err := strconv.Atoi(fullVersion[0:1]) if err != nil { return 0, 0, ErrGitNotInstalled diff --git a/internal/controllers/requirements/requirements.go b/internal/controllers/requirements/requirements.go index ae39ec013..b4cfcf6d3 100644 --- a/internal/controllers/requirements/requirements.go +++ b/internal/controllers/requirements/requirements.go @@ -15,39 +15,28 @@ package requirements import ( - "errors" - - "github.com/ZupIT/horusec-devkit/pkg/utils/logger" - "github.com/ZupIT/horusec/internal/controllers/requirements/docker" "github.com/ZupIT/horusec/internal/controllers/requirements/git" - "github.com/ZupIT/horusec/internal/helpers/messages" ) -var ErrRequirements = errors.New("check the requirements for run and try again") +type ValidationFn func() error type Requirements struct { - gitRequirements *git.RequirementGit - dockerRequirements *docker.RequirementDocker + gitValidationFn ValidationFn + dockerValidationFn ValidationFn } func NewRequirements() *Requirements { return &Requirements{ - gitRequirements: git.NewRequirementGit(), - dockerRequirements: docker.NewRequirementDocker(), + gitValidationFn: git.Validate, + dockerValidationFn: docker.Validate, } } -func (r *Requirements) ValidateDocker() { - err := r.dockerRequirements.ValidateDocker() - if err != nil { - logger.LogPanicWithLevel(messages.MsgPanicDockerRequirementsToRunHorusec, ErrRequirements) - } +func (r *Requirements) ValidateDocker() error { + return r.dockerValidationFn() } -func (r *Requirements) ValidateGit() { - err := r.gitRequirements.ValidateGit() - if err != nil { - logger.LogPanicWithLevel(messages.MsgPanicGitRequirementsToRunHorusec, ErrRequirements) - } +func (r *Requirements) ValidateGit() error { + return r.gitValidationFn() } diff --git a/internal/controllers/requirements/requirements_test.go b/internal/controllers/requirements/requirements_test.go index 2fbe142a5..b7b1fdce5 100644 --- a/internal/controllers/requirements/requirements_test.go +++ b/internal/controllers/requirements/requirements_test.go @@ -20,14 +20,12 @@ import ( "github.com/stretchr/testify/assert" ) -func TestValidateRequirements(t *testing.T) { +func TestValidateAllRequirements(t *testing.T) { t.Run("should return no error when everything it is ok", func(t *testing.T) { controller := NewRequirements() - assert.NotPanics(t, func() { - controller.ValidateDocker() - }) - assert.NotPanics(t, func() { - controller.ValidateGit() - }) + err := controller.ValidateGit() + assert.NoError(t, err) + err = controller.ValidateDocker() + assert.NoError(t, err) }) } diff --git a/internal/utils/testutil/requirements_mock.go b/internal/utils/testutil/requirements_mock.go index acdc4c003..707a2b186 100644 --- a/internal/utils/testutil/requirements_mock.go +++ b/internal/utils/testutil/requirements_mock.go @@ -15,6 +15,7 @@ package testutil import ( + mockutils "github.com/ZupIT/horusec-devkit/pkg/utils/mock" "github.com/stretchr/testify/mock" ) @@ -26,10 +27,12 @@ func NewRequirementsMock() *RequirementsMock { return new(RequirementsMock) } -func (m *RequirementsMock) ValidateDocker() { - _ = m.MethodCalled("ValidateDocker") +func (m *RequirementsMock) ValidateDocker() error { + args := m.MethodCalled("ValidateDocker") + return mockutils.ReturnNilOrError(args, 0) } -func (m *RequirementsMock) ValidateGit() { - _ = m.MethodCalled("ValidateGit") +func (m *RequirementsMock) ValidateGit() error { + args := m.MethodCalled("ValidateGit") + return mockutils.ReturnNilOrError(args, 0) }