Skip to content

Commit

Permalink
workflow: execute unit tests on Windows (#717)
Browse files Browse the repository at this point in the history
Previously some unit tests was implemented to execute and validate
scenarios only for Linux based machines. This commit fix these tests to
execute on Windows.

Note that the goal of this commit is only to fix these tests and make
them work on Windows, we still need to make some improvements on some
of these tests to have a better assertiveness.

This commit also change the configuration of Test workflow to add
windows-latest as a new runner.

Signed-off-by: Matheus Alcantara <matheus.alcantara@zup.com.br>
  • Loading branch information
matheusalcantarazup authored Oct 27, 2021
1 parent 1888d99 commit 9a85401
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 45 deletions.
11 changes: 9 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ on: [ "pull_request" ]
permissions: read-all
jobs:
test:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version:
- 1.17
os:
- ubuntu-latest
- windows-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- uses: actions/checkout@v2
Expand All @@ -26,6 +33,6 @@ jobs:
fetch-depth: 0
- uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: ${{ matrix.go-version }}
- name: test
run: make test
5 changes: 4 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"
"path"
"path/filepath"
"strings"
"testing"

"github.com/ZupIT/horusec-devkit/pkg/enums/vulnerability"
Expand Down Expand Up @@ -451,7 +452,7 @@ func TestConfig_Bytes(t *testing.T) {
"cert_path": "cert-path",
"repository_name": "my-project",
"print_output_type": "sonarqube",
"json_output_file_path": "/tmp/output-sonarqube.json",
"json_output_file_path": "` + filepath.Join(os.TempDir(), "output-sonarqube.json") + `",
"project_path": "./horusec-manager",
"custom_rules_path": "test",
"container_bind_project_path": "./my-path",
Expand Down Expand Up @@ -591,6 +592,8 @@ func TestConfig_Bytes(t *testing.T) {
},
"version": "{{VERSION_NOT_FOUND}}"
}`
// Add scape slashes when running on Windows.
expectedOutput = strings.ReplaceAll(expectedOutput, `\`, `\\`)
assert.Equal(t, expectedOutput, string(cfg.Bytes()))
})
t.Run("Should have the predefined schema", func(t *testing.T) {
Expand Down
12 changes: 9 additions & 3 deletions internal/services/docker/docker_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ import (

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/errdefs"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"

errorsenum "github.com/ZupIT/horusec/internal/enums/errors"

cliConfig "github.com/ZupIT/horusec/config"
dockerEntities "github.com/ZupIT/horusec/internal/entities/docker"
"github.com/ZupIT/horusec/internal/services/docker/client"
Expand Down Expand Up @@ -61,24 +64,26 @@ const (
)

func TestDockerAPI_CreateLanguageAnalysisContainer(t *testing.T) {
t.Run("Should return return error when ImagePath is empty", func(t *testing.T) {
t.Run("Should return error when DefaultImage is empty", func(t *testing.T) {
api := New(client.NewDockerClient(), &cliConfig.Config{}, uuid.New())
_, err := api.CreateLanguageAnalysisContainer(&dockerEntities.AnalysisData{
DefaultImage: "",
CMD: "cmd",
})

assert.Error(t, err)
assert.ErrorIs(t, err, errorsenum.ErrImageTagCmdRequired)
})

t.Run("Should return return error when cmd is empty", func(t *testing.T) {
t.Run("Should return error when cmd is empty", func(t *testing.T) {
api := New(client.NewDockerClient(), &cliConfig.Config{}, uuid.New())
_, err := api.CreateLanguageAnalysisContainer(&dockerEntities.AnalysisData{
DefaultImage: "image",
CMD: "",
})

assert.Error(t, err)
assert.ErrorIs(t, err, errorsenum.ErrImageTagCmdRequired)
})

t.Run("Should return error when pull image aleatory", func(t *testing.T) {
Expand All @@ -88,6 +93,7 @@ func TestDockerAPI_CreateLanguageAnalysisContainer(t *testing.T) {
CMD: "command",
})

assert.True(t, errdefs.IsInvalidParameter(err), "Expected error ErrInvalidParameter")
assert.Error(t, err)
})

Expand All @@ -99,7 +105,7 @@ func TestDockerAPI_CreateLanguageAnalysisContainer(t *testing.T) {
})

assert.Error(t, err)
assert.Contains(t, err.Error(), "Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist:")
assert.True(t, errdefs.IsInvalidParameter(err), "Expected error ErrInvalidParameter")
})

t.Run("Should return error when list image to check if exist", func(t *testing.T) {
Expand Down
37 changes: 17 additions & 20 deletions internal/services/formatters/csharp/scs/formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ package scs
import (
"errors"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

analysisEntities "github.com/ZupIT/horusec-devkit/pkg/entities/analysis"

Expand All @@ -31,26 +33,26 @@ import (
"github.com/ZupIT/horusec/internal/services/formatters/csharp/scs/enums"
)

func createSlnFile() error {
path, _ := os.Getwd()
func createSlnFile(t *testing.T) {
wd, _ := os.Getwd()

if err := os.MkdirAll(path+"/.horusec/00000000-0000-0000-0000-000000000000", 0755); err != nil {
return err
}
dir := filepath.Join(wd, ".horusec", "00000000-0000-0000-0000-000000000000")
err := os.MkdirAll(dir, 0755)
require.Nil(t, err, "Expected nil error to create sln directory: %v", err)

_, err := os.Create(path + "/.horusec/00000000-0000-0000-0000-000000000000/test.sln")
return err
}
f, err := os.Create(filepath.Join(dir, "test.sln"))
require.Nil(t, err, "Expected nil error to create sln file: %v", err)

func removeSlnFile() error {
path, _ := os.Getwd()
t.Cleanup(func() {
assert.NoError(t, f.Close(), "Expected nil error to close sln file")
assert.NoError(t, os.RemoveAll(dir), "Expected nil error to remove sln directory")
})

return os.RemoveAll(path + "/.horusec")
}

func TestParseOutput(t *testing.T) {
t.Run("should return 4 vulnerabilities with no errors", func(t *testing.T) {
assert.NoError(t, createSlnFile())
createSlnFile(t)

dockerAPIControllerMock := &docker.Mock{}
dockerAPIControllerMock.On("SetAnalysisID")
Expand Down Expand Up @@ -104,11 +106,10 @@ func TestParseOutput(t *testing.T) {
formatter.StartAnalysis("")
assert.Len(t, analysis.AnalysisVulnerabilities, 4)

assert.NoError(t, removeSlnFile())
})

t.Run("should return error when unmarshalling output", func(t *testing.T) {
assert.NoError(t, createSlnFile())
createSlnFile(t)

analysis := &analysisEntities.Analysis{}
dockerAPIControllerMock := &docker.Mock{}
Expand All @@ -126,11 +127,10 @@ func TestParseOutput(t *testing.T) {
formatter.StartAnalysis("")
assert.NotEmpty(t, analysis.Errors)

assert.NoError(t, removeSlnFile())
})

t.Run("should return build error", func(t *testing.T) {
assert.NoError(t, createSlnFile())
createSlnFile(t)

analysis := &analysisEntities.Analysis{}
dockerAPIControllerMock := &docker.Mock{}
Expand All @@ -148,7 +148,6 @@ func TestParseOutput(t *testing.T) {
formatter.StartAnalysis("")
assert.NotEmpty(t, analysis.Errors)

assert.NoError(t, removeSlnFile())
})

t.Run("should return error not found solution file", func(t *testing.T) {
Expand All @@ -168,7 +167,7 @@ func TestParseOutput(t *testing.T) {
})

t.Run("should return error executing container", func(t *testing.T) {
assert.NoError(t, createSlnFile())
createSlnFile(t)

analysis := &analysisEntities.Analysis{}
dockerAPIControllerMock := &docker.Mock{}
Expand All @@ -184,8 +183,6 @@ func TestParseOutput(t *testing.T) {

formatter.StartAnalysis("")
assert.NotEmpty(t, analysis.Errors)

assert.NoError(t, removeSlnFile())
})

t.Run("should not execute tool because it's ignored", func(t *testing.T) {
Expand Down
14 changes: 9 additions & 5 deletions internal/services/formatters/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package formatters
import (
"errors"
"fmt"
"path/filepath"
"strconv"
"testing"

Expand Down Expand Up @@ -166,15 +167,18 @@ func TestGetCommitAuthor(t *testing.T) {

func TestGetConfigProjectPath(t *testing.T) {
t.Run("should success get project path", func(t *testing.T) {
cliConfig := &config.Config{}
cliConfig.ProjectPath = "test"
cliConfig := &config.Config{
StartOptions: config.StartOptions{
ProjectPath: "test",
},
}

monitorController := NewFormatterService(&analysis.Analysis{}, &docker.Mock{}, cliConfig)
svc := NewFormatterService(&analysis.Analysis{}, &docker.Mock{}, cliConfig)

result := monitorController.GetConfigProjectPath()
result := svc.GetConfigProjectPath()

assert.NotEmpty(t, result)
assert.Equal(t, "test/.horusec/00000000-0000-0000-0000-000000000000", result)
assert.Equal(t, filepath.Join("test", ".horusec", "00000000-0000-0000-0000-000000000000"), result)
})
}

Expand Down
4 changes: 3 additions & 1 deletion internal/services/git/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ func TestGetCommitAuthor(t *testing.T) {
require.Nil(t, err, "Expected nil error to create temp file: %v", err)

t.Cleanup(func() {
require.Nil(t, os.Remove(tmp.Name()), "Expected nil error to delete temp file: %v", err)
assert.NoError(t, tmp.Close(), "Expected nil error to close temp file")
err := os.Remove(tmp.Name())
require.Nil(t, err, "Expected nil error to delete temp file: %v", err)
})

author := service.CommitAuthor("1-2", tmp.Name())
Expand Down
38 changes: 25 additions & 13 deletions internal/usecases/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
package cli

import (
"errors"
"os"
"testing"

"github.com/ZupIT/horusec/internal/enums/outputtype"
validation "github.com/go-ozzo/ozzo-validation/v4"

"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -129,23 +132,32 @@ func TestValidateConfigs(t *testing.T) {
assert.NoError(t, err)
})
t.Run("Should return error because not exists path in workdir", func(t *testing.T) {
cfg := &config.Config{}
cfg.WorkDir = &workdir.WorkDir{
Go: []string{"NOT EXISTS PATH"},
CSharp: []string{},
Ruby: []string{},
Python: []string{},
Java: []string{},
Kotlin: []string{},
JavaScript: []string{},
Leaks: []string{},
HCL: []string{},
cfg := &config.Config{
StartOptions: config.StartOptions{
WorkDir: &workdir.WorkDir{
Go: []string{"NOT EXISTS PATH"},
CSharp: []string{},
Ruby: []string{},
Python: []string{},
Java: []string{},
Kotlin: []string{},
JavaScript: []string{},
Leaks: []string{},
HCL: []string{},
},
},
}

err := useCases.ValidateConfig(cfg)
assert.Error(t, err)
assert.Contains(t, err.Error(), "work_dir: stat ")
assert.Contains(t, err.Error(), "internal/usecases/cli/NOT EXISTS PATH: no such file or directory.")

var vErrors validation.Errors
assert.True(t, errors.As(err, &vErrors), "Expected that error should be validiation.Errors")

workDirErr, exists := vErrors["work_dir"]
assert.True(t, exists, "Expected error from work dir config")

assert.ErrorIs(t, workDirErr, os.ErrNotExist)
})
t.Run("Should return error because cert path is not valid", func(t *testing.T) {
cfg := config.New()
Expand Down

0 comments on commit 9a85401

Please sign in to comment.