Merge branch 'kubescape:master' into core_cautils_datastructuremethods_tests

This commit is contained in:
Cbrom
2023-11-22 22:13:58 +03:00
committed by GitHub
17 changed files with 1325 additions and 10 deletions
+1
View File
@@ -20,6 +20,7 @@ concurrency:
jobs:
pr-scanner:
if: github.repository_owner == 'kubescape'
permissions:
actions: read
checks: read
+53
View File
@@ -0,0 +1,53 @@
package cautils
import (
"testing"
)
// Returns a valid URL when given a valid control ID.
func TestGetControlLink_ValidControlID(t *testing.T) {
controlID := "cis-1.1.3"
expectedURL := "https://hub.armosec.io/docs/cis-1-1-3"
result := GetControlLink(controlID)
if result != expectedURL {
t.Errorf("Expected URL: %s, but got: %s", expectedURL, result)
}
}
// Replaces dots with hyphens in the control ID to generate the correct documentation link.
func TestGetControlLink_DotsInControlID(t *testing.T) {
controlID := "cis.1.1.3"
expectedURL := "https://hub.armosec.io/docs/cis-1-1-3"
result := GetControlLink(controlID)
if result != expectedURL {
t.Errorf("Expected URL: %s, but got: %s", expectedURL, result)
}
}
// Returns a lowercase URL.
func TestGetControlLink_LowercaseURL(t *testing.T) {
controlID := "CIS-1.1.3"
expectedURL := "https://hub.armosec.io/docs/cis-1-1-3"
result := GetControlLink(controlID)
if result != expectedURL {
t.Errorf("Expected URL: %s, but got: %s", expectedURL, result)
}
}
// Returns URL to armosec docs when given an empty control ID.
func TestGetControlLink_EmptyControlID(t *testing.T) {
controlID := ""
expectedURL := "https://hub.armosec.io/docs/"
result := GetControlLink(controlID)
if result != expectedURL {
t.Errorf("Expected URL: %s, but got: %s", expectedURL, result)
}
}
+422
View File
@@ -1,9 +1,12 @@
package cautils
import (
"io"
"os"
"testing"
"github.com/kubescape/go-logger"
"github.com/stretchr/testify/assert"
)
func TestStartSpinner(t *testing.T) {
@@ -30,3 +33,422 @@ func TestStartSpinner(t *testing.T) {
})
}
}
func TestFailureDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
FailureDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestWarningDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
WarningDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestFailureTextDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
FailureTextDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestInfoDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
InfoDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestInfoTextDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
InfoTextDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestSimpleDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
SimpleDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestSuccessDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
SuccessDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestDescriptionDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
DescriptionDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestBoldDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
BoldDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestLineDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "Test",
},
{
text: "",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
LineDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestSectionHeadingDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test Section",
want: "\nTest Section\n────────────\n\n",
},
{
text: "",
want: "\n\n\n\n",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
SectionHeadingDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
func TestStarDisplay(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "Test",
want: "* Test",
},
{
text: "",
want: "* ",
},
}
for _, tt := range tests {
t.Run(tt.text, func(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
StarDisplay(os.Stdout, tt.text)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
assert.Equal(t, tt.want, string(got))
})
}
}
// Returns a new instance of ProgressHandler with the given title.
func TestNewProgressHandler_(t *testing.T) {
tests := []struct {
title string
}{
{
title: "Test title",
},
{
title: "",
},
}
for _, tt := range tests {
t.Run(tt.title, func(t *testing.T) {
progressHandler := NewProgressHandler(tt.title)
assert.NotNil(t, progressHandler)
assert.Equal(t, tt.title, progressHandler.title)
})
}
}
+107
View File
@@ -105,3 +105,110 @@ func getRelativePath(p string) string {
pp := strings.SplitAfter(p, "api=")
return pp[1]
}
// Converts a YAML object to a JSON object
func TestConvertYamlToJson(t *testing.T) {
tests := []struct {
yamlObj map[interface{}]interface{}
jsonObj map[string]interface{}
}{
{
yamlObj: map[interface{}]interface{}{
"name": "John",
"age": 30,
"city": "New York",
},
jsonObj: map[string]interface{}{
"name": "John",
"age": 30,
"city": "New York",
},
},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
assert.Equal(t, tt.jsonObj, convertYamlToJson(tt.yamlObj))
})
}
}
func TestIsYaml(t *testing.T) {
tests := []struct {
path string
want bool
}{
{
path: "temp.yaml",
want: true,
},
{
path: "temp.json",
want: false,
},
{
path: "random.txt",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.path, func(t *testing.T) {
assert.Equal(t, tt.want, IsYaml(tt.path))
})
}
}
func TestIsJson(t *testing.T) {
tests := []struct {
path string
want bool
}{
{
path: "temp.yaml",
want: false,
},
{
path: "temp.json",
want: true,
},
{
path: "random.txt",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.path, func(t *testing.T) {
assert.Equal(t, tt.want, IsJson(tt.path))
})
}
}
func TestGetFileFormat(t *testing.T) {
tests := []struct {
path string
want FileFormat
}{
{
path: "temp.yaml",
want: YAML_FILE_FORMAT,
},
{
path: "temp.json",
want: JSON_FILE_FORMAT,
},
{
path: "random.txt",
want: "random.txt",
},
}
for _, tt := range tests {
t.Run(tt.path, func(t *testing.T) {
assert.Equal(t, tt.want, GetFileFormat(tt.path))
})
}
}
@@ -1,12 +1,15 @@
package getter
import (
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
"testing"
beClient "github.com/kubescape/backend/pkg/client/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -96,3 +99,45 @@ func TestHttpMethods(t *testing.T) {
require.EqualValues(t, "body-delete", resp)
})
}
// Returns an empty string and nil error when given a nil response or nil response body.
func TestHttpRespToString_NilResponse(t *testing.T) {
resp := &http.Response{}
result, err := httpRespToString(resp)
assert.Equal(t, "", result)
assert.Nil(t, err)
}
func TestHttpRespToString_ValidResponse(t *testing.T) {
resp := &http.Response{
Body: ioutil.NopCloser(strings.NewReader("test response")),
Status: "200 OK",
StatusCode: 200,
}
result, err := httpRespToString(resp)
assert.Equal(t, "test response", result)
assert.Nil(t, err)
}
// Returns an error with status and reason when unable to read response body.
func TestHttpRespToString_ReadError(t *testing.T) {
resp := &http.Response{
Body: ioutil.NopCloser(strings.NewReader("test response")),
}
resp.Body.Close()
result, err := httpRespToString(resp)
assert.EqualError(t, err, "http-error: '', reason: 'test response'")
assert.Equal(t, "test response", result)
}
// Returns an error with status and reason when unable to read response body.
func TestHttpRespToString_ErrorCodeLessThan200(t *testing.T) {
resp := &http.Response{
Body: ioutil.NopCloser(strings.NewReader("test response")),
StatusCode: 100,
}
resp.Body.Close()
result, err := httpRespToString(resp)
assert.EqualError(t, err, "http-error: '', reason: 'test response'")
assert.Equal(t, "test response", result)
}
+43
View File
@@ -0,0 +1,43 @@
package getter
import (
"testing"
"github.com/stretchr/testify/assert"
)
// should return true if the string is present in the slice
func TestContains(t *testing.T) {
tests := []struct {
str []string
key string
want bool
}{
{
str: []string{"apple", "banana", "orange"},
key: "banana",
want: true,
},
{
str: []string{"apple", "banana", "orange"},
key: "mango",
want: false,
},
{
str: []string{"", "banana", "banana"},
key: "banana",
want: true,
},
{
str: []string{"", "", ""},
key: "grape",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.key, func(t *testing.T) {
assert.Equal(t, tt.want, contains(tt.str, tt.key))
})
}
}
+23
View File
@@ -0,0 +1,23 @@
package core
import (
"testing"
"github.com/stretchr/testify/assert"
)
// The function should return a non-nil pointer.
func TestNewKubescape_ReturnsNonNilPointer(t *testing.T) {
k := NewKubescape()
assert.NotNil(t, k)
}
// The function should not panic.
func TestNewKubescape_DoesNotPanic(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("Function panicked: %v", r)
}
}()
NewKubescape()
}
+255
View File
@@ -0,0 +1,255 @@
package core
import (
"context"
"encoding/json"
"io"
"os"
"sort"
"testing"
"github.com/stretchr/testify/assert"
)
// Function receives a non-empty list of policies
func TestNonEmptyListOfPolicies(t *testing.T) {
policies := []string{"policy1", "policy2", "policy3"}
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
jsonListFormat(context.Background(), "", policies)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
// got := buf.String()
want := `[
"policy1",
"policy2",
"policy3"
]
`
assert.Equal(t, want, string(got))
}
// Function returns a valid JSON string
func TestValidJsonString(t *testing.T) {
policies := []string{"policy1", "policy2", "policy3"}
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
jsonListFormat(context.Background(), "", policies)
w.Close()
out, _ := io.ReadAll(r)
os.Stdout = rescueStdout
var result []string
err := json.Unmarshal(out, &result)
assert.NoError(t, err)
}
// Function receives an empty list of policies
func TestEmptyListOfPolicies(t *testing.T) {
policies := []string{}
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
jsonListFormat(context.Background(), "", policies)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
want := "[]\n"
assert.Equal(t, want, string(got))
}
// Function receives a nil list of policies
func TestNilListOfPolicies(t *testing.T) {
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
jsonListFormat(context.Background(), "", nil)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
want := "null\n"
assert.Equal(t, want, string(got))
}
// Returns a 2D slice with one row for each policy in the input slice.
func TestGeneratePolicyRows_NonEmptyPolicyList(t *testing.T) {
// Arrange
policies := []string{"policy1", "policy2", "policy3"}
// Act
result := generatePolicyRows(policies)
// Assert
assert.Equal(t, [][]string{{"policy1"}, {"policy2"}, {"policy3"}}, result)
}
// Returns an empty 2D slice for an empty list of policies.
func TestGeneratePolicyRows_EmptyPolicyList(t *testing.T) {
// Arrange
policies := []string{}
// Act
got := generatePolicyRows(policies)
// Assert
assert.Empty(t, got)
}
// The function returns a list of rows, each containing a formatted string with control ID, control name, docs, and frameworks.
func TestShortFormatControlRows_ReturnsListOfRowsWithFormattedString(t *testing.T) {
controlRows := [][]string{
{"ID1", "Control 1", "Docs 1", "Framework 1"},
{"ID2", "Control 2", "Docs 2", "Framework 2"},
}
want := [][]string{
{"Control ID : ID1\nControl Name : Control 1\nDocs : Docs 1\nFrameworks : Framework 1"},
{"Control ID : ID2\nControl Name : Control 2\nDocs : Docs 2\nFrameworks : Framework 2"},
}
got := shortFormatControlRows(controlRows)
assert.Equal(t, want, got)
}
// The function formats the control rows correctly, replacing newlines in the frameworks column with line breaks.
func TestShortFormatControlRows_FormatsControlRowsCorrectly(t *testing.T) {
controlRows := [][]string{
{"ID1", "Control 1", "Docs 1", "Framework\n1"},
{"ID2", "Control 2", "Docs 2", "Framework\n2"},
}
want := [][]string{
{"Control ID : ID1\nControl Name : Control 1\nDocs : Docs 1\nFrameworks : Framework 1"},
{"Control ID : ID2\nControl Name : Control 2\nDocs : Docs 2\nFrameworks : Framework 2"},
}
result := shortFormatControlRows(controlRows)
assert.Equal(t, want, result)
}
// The function handles a control row with an empty control ID.
func TestShortFormatControlRows_HandlesControlRowWithEmptyControlID(t *testing.T) {
controlRows := [][]string{
{"", "Control 1", "Docs 1", "Framework 1"},
}
want := [][]string{
{"Control ID : \nControl Name : Control 1\nDocs : Docs 1\nFrameworks : Framework 1"},
}
got := shortFormatControlRows(controlRows)
assert.Equal(t, want, got)
}
// The function handles a control row with an empty control name.
func TestShortFormatControlRows_HandlesControlRowWithEmptyControlName(t *testing.T) {
controlRows := [][]string{
{"ID1", "", "Docs 1", "Framework 1"},
}
want := [][]string{
{"Control ID : ID1\nControl Name : \nDocs : Docs 1\nFrameworks : Framework 1"},
}
got := shortFormatControlRows(controlRows)
assert.Equal(t, want, got)
}
// Generates rows for each policy with ID, control, documentation, and framework
func TestGenerateControlRowsWithAllFields(t *testing.T) {
policies := []string{
"1|Control 1|Framework 1",
"2|Control 2|Framework 2",
"3|Control 3|Framework 3",
}
want := [][]string{
{"1", "Control 1", "https://hub.armosec.io/docs/1", "Framework\n1"},
{"2", "Control 2", "https://hub.armosec.io/docs/2", "Framework\n2"},
{"3", "Control 3", "https://hub.armosec.io/docs/3", "Framework\n3"},
}
got := generateControlRows(policies)
assert.Equal(t, want, got)
}
// The function generates a table with the correct headers and rows based on the input policies.
func TestGenerateTableWithCorrectHeadersAndRows(t *testing.T) {
// Arrange
ctx := context.Background()
policies := []string{
"1|Control 1|Framework 1",
"2|Control 2|Framework 2",
"3|Control 3|Framework 3",
}
// Redirect stdout to a buffer
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
prettyPrintControls(ctx, policies)
w.Close()
got, _ := io.ReadAll(r)
os.Stdout = rescueStdout
// got := buf.String()
want := `┌────────────┬──────────────┬───────────────────────────────┬────────────┐
│ Control ID │ Control name │ Docs │ Frameworks │
├────────────┼──────────────┼───────────────────────────────┼────────────┤
│ 1 │ Control 1 │ https://hub.armosec.io/docs/1 │ Framework │
│ │ │ │ 1 │
├────────────┼──────────────┼───────────────────────────────┼────────────┤
│ 2 │ Control 2 │ https://hub.armosec.io/docs/2 │ Framework │
│ │ │ │ 2 │
├────────────┼──────────────┼───────────────────────────────┼────────────┤
│ 3 │ Control 3 │ https://hub.armosec.io/docs/3 │ Framework │
│ │ │ │ 3 │
└────────────┴──────────────┴───────────────────────────────┴────────────┘
`
assert.Equal(t, want, string(got))
}
// Returns a non-empty list of supported actions when 'ListSupportActions' is called.
func TestListSupportActionsNotEmpty(t *testing.T) {
actions := ListSupportActions()
assert.NotEmpty(t, actions)
}
func TestListSupportActionsReturnsSupportedActions(t *testing.T) {
got := ListSupportActions()
want := []string{"controls", "exceptions", "frameworks"}
sort.Strings(got)
assert.Equal(t, want, got)
}
+15
View File
@@ -0,0 +1,15 @@
package core
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
)
// sets os.Stdout and os.Stderr to nil
func TestSetsOsStdoutAndStderrToNil(t *testing.T) {
disableCopaLogger()
assert.Nil(t, os.Stdout)
assert.Nil(t, os.Stderr)
}
+46
View File
@@ -0,0 +1,46 @@
package core
import (
"testing"
"github.com/kubescape/kubescape/v3/core/cautils"
"github.com/stretchr/testify/assert"
)
func TestIsPrioritizationScanType(t *testing.T) {
tests := []struct {
name cautils.ScanTypes
want bool
}{
{
name: cautils.ScanTypeCluster,
want: true,
},
{
name: cautils.ScanTypeRepo,
want: true,
},
{
name: cautils.ScanTypeImage,
want: false,
},
{
name: cautils.ScanTypeWorkload,
want: false,
},
{
name: cautils.ScanTypeFramework,
want: false,
},
{
name: cautils.ScanTypeControl,
want: false,
},
}
for _, tt := range tests {
t.Run(string(tt.name), func(t *testing.T) {
assert.Equal(t, tt.want, isPrioritizationScanType(tt.name))
})
}
}
@@ -0,0 +1,57 @@
package gotree
func EmptyTreeMock() Tree {
tree := New("")
return tree
}
func RootTreeMock() Tree {
tree := New("root")
return tree
}
func SimpleTreeMock() Tree {
tree := New("root")
tree.Add("child1")
tree.Add("child2")
return tree
}
func SimpleTreeWithLinesMock() Tree {
tree := New("root")
tree.Add("child1")
tree.Add("child2")
tree.Add("child3\nLine2\nLine3")
tree.Add("child4")
return tree
}
func SubTreeMock1() Tree {
tree := New("root")
tree.Add("child1").Add("child1.1")
return tree
}
func SubTreeMock2() Tree {
tree := New("root")
tree.Add("child1").Add("child1.1")
tree.Add("child2")
tree.Add("child3").Add("child3.1")
return tree
}
func SubTreeWithLinesMock() Tree {
tree := New("root")
tree.Add("child1").Add("child1.1\nLine2\nLine3")
tree.Add("child2")
tree.Add("child3").Add("child3.1\nLine2\nLine3")
return tree
}
@@ -0,0 +1,171 @@
package gotree
import (
"testing"
"github.com/stretchr/testify/assert"
)
var (
p = &printer{}
)
func TestTreePrint(t *testing.T) {
tests := []struct {
name string
tree Tree
want string
}{
{
name: "EmptyTreeMock",
tree: EmptyTreeMock(),
want: "\n",
},
{
name: "RootTreeMock",
tree: RootTreeMock(),
want: "root\n",
},
{
name: "SimpleTreeMock",
tree: SimpleTreeMock(),
want: "root\n" +
"├── child1\n" +
"└── child2\n",
},
{
name: "SimpleTreeWithLinesMock",
tree: SimpleTreeWithLinesMock(),
want: "root\n" +
"├── child1\n" +
"├── child2\n" +
"├── child3\n" +
"│ Line2\n" +
"│ Line3\n" +
"└── child4\n",
},
{
name: "SubTreeMock1",
tree: SubTreeMock1(),
want: "root\n" +
"└── child1\n" +
" └── child1.1\n",
},
{
name: "SubTreeMock2",
tree: SubTreeMock2(),
want: "root\n" +
"├── child1\n" +
"│ └── child1.1\n" +
"├── child2\n" +
"└── child3\n" +
" └── child3.1\n",
},
{
name: "SubTreeWithLinesMock",
tree: SubTreeWithLinesMock(),
want: "root\n" +
"├── child1\n" +
"│ └── child1.1\n" +
"│ Line2\n" +
"│ Line3\n" +
"├── child2\n" +
"└── child3\n" +
" └── child3.1\n" +
" Line2\n" +
" Line3\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, tt.tree.Print())
})
}
}
func TestPrintText_LastTree(t *testing.T) {
inputText := "Root\n├── Child1\n└── Child2"
expectedOutput := "└── Root\n ├── Child1\n └── Child2\n"
result := p.printText(inputText, []bool{}, true)
assert.Equal(t, expectedOutput, result)
}
func TestPrintText_NotLastTree(t *testing.T) {
inputText := "Root\n├── Child1\n└── Child2"
expectedOutput := "├── Root\n│ ├── Child1\n│ └── Child2\n"
result := p.printText(inputText, []bool{}, false)
assert.Equal(t, expectedOutput, result)
}
func Test_printer_printItems(t *testing.T) {
tests := []struct {
name string
tree Tree
want string
}{
{
name: "EmptyTreeMock",
tree: EmptyTreeMock(),
want: "",
},
{
name: "RootTreeMock",
tree: RootTreeMock(),
want: "",
},
{
name: "SimpleTreeMock",
tree: SimpleTreeMock(),
want: "├── child1\n" +
"└── child2\n",
},
{
name: "SimpleTreeWithLinesMock",
tree: SimpleTreeWithLinesMock(),
want: "├── child1\n" +
"├── child2\n" +
"├── child3\n" +
"│ Line2\n" +
"│ Line3\n" +
"└── child4\n",
},
{
name: "SubTreeMock1",
tree: SubTreeMock1(),
want: "└── child1\n" +
" └── child1.1\n",
},
{
name: "SubTreeMock2",
tree: SubTreeMock2(),
want: "├── child1\n" +
"│ └── child1.1\n" +
"├── child2\n" +
"└── child3\n" +
" └── child3.1\n",
},
{
name: "SubTreeWithLinesMock",
tree: SubTreeWithLinesMock(),
want: "├── child1\n" +
"│ └── child1.1\n" +
"│ Line2\n" +
"│ Line3\n" +
"├── child2\n" +
"└── child3\n" +
" └── child3.1\n" +
" Line2\n" +
" Line3\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, p.printItems(tt.tree.Items(), []bool{}))
})
}
}
+59
View File
@@ -1 +1,60 @@
package score
import (
"testing"
cautils "github.com/kubescape/kubescape/v3/core/cautils"
"github.com/stretchr/testify/assert"
)
func TestNewScoreWrapper(t *testing.T) {
opaSessionObj := cautils.NewOPASessionObjMock()
scoreWrapper := NewScoreWrapper(opaSessionObj)
assert.NotNil(t, scoreWrapper)
assert.NotNil(t, scoreWrapper.scoreUtil)
assert.Equal(t, opaSessionObj, scoreWrapper.opaSessionObj)
}
func TestNewScoreWrapperWithNilAllResources(t *testing.T) {
opaSessionObj := &cautils.OPASessionObj{
AllResources: nil,
}
scoreWrapper := NewScoreWrapper(opaSessionObj)
assert.NotNil(t, scoreWrapper)
assert.NotNil(t, scoreWrapper.scoreUtil)
assert.NotNil(t, scoreWrapper.opaSessionObj)
assert.Nil(t, scoreWrapper.opaSessionObj.AllResources)
assert.Empty(t, scoreWrapper.opaSessionObj.AllResources)
}
func TestCalculateReturnsNilErrorWhenReportVersionIsEPostureReportV2(t *testing.T) {
opaSessionObj := cautils.NewOPASessionObjMock()
scoreWrapper := NewScoreWrapper(opaSessionObj)
err := scoreWrapper.Calculate(EPostureReportV2)
assert.Nil(t, err)
}
func TestCalculateReturnsErrorWhenReportVersionIsEPostureReportV1(t *testing.T) {
opaSessionObj := &cautils.OPASessionObj{}
scoreWrapper := NewScoreWrapper(opaSessionObj)
err := scoreWrapper.Calculate(EPostureReportV1)
assert.Error(t, err)
assert.Equal(t, "unsupported score calculator", err.Error())
}
func TestCalculateReturnsErrorWhenReportVersionIsNotSupported(t *testing.T) {
opaSessionObj := &cautils.OPASessionObj{}
scoreWrapper := NewScoreWrapper(opaSessionObj)
err := scoreWrapper.Calculate("v3")
assert.Error(t, err)
assert.Equal(t, "unsupported score calculator", err.Error())
}
+4 -4
View File
@@ -389,7 +389,7 @@ require (
go.mongodb.org/mongo-driver v1.11.3 // indirect
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect
go.opentelemetry.io/contrib/instrumentation/runtime v0.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.41.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.41.0 // indirect
@@ -404,8 +404,8 @@ require (
go.step.sm/crypto v0.32.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/net v0.15.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
@@ -419,7 +419,7 @@ require (
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect
google.golang.org/grpc v1.58.1 // indirect
google.golang.org/grpc v1.58.3 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
+4 -4
View File
@@ -1984,8 +1984,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -2111,8 +2111,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+2 -2
View File
@@ -37,7 +37,7 @@ require (
golang.org/x/oauth2 v0.12.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.58.1 // indirect
google.golang.org/grpc v1.58.3 // indirect
)
require (
@@ -399,7 +399,7 @@ require (
go.mongodb.org/mongo-driver v1.11.4 // indirect
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect
go.opentelemetry.io/contrib/instrumentation/runtime v0.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.41.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.41.0 // indirect
+18
View File
@@ -1,11 +1,29 @@
package main
import (
"os"
"os/signal"
"syscall"
logger "github.com/kubescape/go-logger"
"github.com/kubescape/kubescape/v3/cmd"
)
func main() {
// Capture interrupt signal
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM)
// Handle interrupt signal
go func() {
<-signalChan
// Perform cleanup or graceful shutdown here
logger.L().StopError("Received interrupt signal, exiting...")
// Exit the program with proper exit code for SIGINT
os.Exit(130)
}()
if err := cmd.Execute(); err != nil {
logger.L().Fatal(err.Error())
}