mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
Enhancements and tests for configurationprinter
Wrote new tests for `categorytable` and `frameworkscan` Refactored the `shortFormatRow` function for: - Imporved readability - Consistency - Improve code modularity - Encapsulation: The formatted string construction is encapsulated within the function, maintaining code modularity and separation of concerns. Added the `MockISeverityCounters` mock struct to test the `renderSeverityCountersSummary` function. Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
This commit is contained in:
+147
@@ -1,6 +1,8 @@
|
||||
package configurationprinter
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@@ -187,3 +189,148 @@ func TestGenerateCategoryStatusRow(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCategoryTableWriter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
headers []string
|
||||
columnAligments []int
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "Test1",
|
||||
headers: []string{"Control name", "Resources", "View details"},
|
||||
columnAligments: []int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_CENTER, tablewriter.ALIGN_LEFT},
|
||||
want: "┌──────────────┬───────────┬──────────────┐\n│ Control name │ Resources │ View details │\n├──────────────┼───────────┼──────────────┤\n└──────────────┴───────────┴──────────────┘\n",
|
||||
},
|
||||
{
|
||||
name: "Test2",
|
||||
headers: []string{"", "Control name", "Docs"},
|
||||
columnAligments: []int{tablewriter.ALIGN_CENTER, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_CENTER},
|
||||
want: "┌──┬──────────────┬──────┐\n│ │ Control name │ Docs │\n├──┼──────────────┼──────┤\n└──┴──────────────┴──────┘\n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a temporary file to capture output
|
||||
f, err := os.CreateTemp("", "print")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
tableWriter := getCategoryTableWriter(f, tt.headers, tt.columnAligments)
|
||||
|
||||
// Redirect stderr to the temporary file
|
||||
oldStderr := os.Stderr
|
||||
defer func() {
|
||||
os.Stderr = oldStderr
|
||||
}()
|
||||
os.Stderr = f
|
||||
|
||||
tableWriter.Render()
|
||||
|
||||
// Read the contents of the temporary file
|
||||
f.Seek(0, 0)
|
||||
got, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
assert.NotNil(t, tableWriter)
|
||||
assert.Equal(t, tt.want, string(got))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderSingleCategory(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
categoryName string
|
||||
rows [][]string
|
||||
infoToPrintInfo []utils.InfoStars
|
||||
headers []string
|
||||
columnAligments []int
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "Test1",
|
||||
categoryName: "Resources",
|
||||
rows: [][]string{
|
||||
{"Regular", "regular line", "1"},
|
||||
{"Thick", "particularly thick line", "2"},
|
||||
{"Double", "double line", "3"},
|
||||
},
|
||||
infoToPrintInfo: []utils.InfoStars{
|
||||
utils.InfoStars{
|
||||
Stars: "1",
|
||||
Info: "Low severity",
|
||||
},
|
||||
utils.InfoStars{
|
||||
Stars: "5",
|
||||
Info: "Critical severity",
|
||||
},
|
||||
},
|
||||
headers: []string{"Control name", "Resources", "View details"},
|
||||
columnAligments: []int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_CENTER, tablewriter.ALIGN_LEFT},
|
||||
want: "Resources\n┌──────────────┬─────────────────────────┬──────────────┐\n│ Control name │ Resources │ View details │\n├──────────────┼─────────────────────────┼──────────────┤\n│ Regular │ regular line │ 1 │\n│ Thick │ particularly thick line │ 2 │\n│ Double │ double line │ 3 │\n└──────────────┴─────────────────────────┴──────────────┘\n1 Low severity\n5 Critical severity\n\n",
|
||||
},
|
||||
{
|
||||
name: "Test2",
|
||||
categoryName: "Control name",
|
||||
rows: [][]string{
|
||||
{"Regular", "regular line", "1"},
|
||||
{"Thick", "particularly thick line", "2"},
|
||||
{"Double", "double line", "3"},
|
||||
},
|
||||
infoToPrintInfo: []utils.InfoStars{
|
||||
utils.InfoStars{
|
||||
Stars: "1",
|
||||
Info: "Low severity",
|
||||
},
|
||||
utils.InfoStars{
|
||||
Stars: "5",
|
||||
Info: "Critical severity",
|
||||
},
|
||||
utils.InfoStars{
|
||||
Stars: "4",
|
||||
Info: "High severity",
|
||||
},
|
||||
},
|
||||
headers: []string{"Control name", "Resources", "View details"},
|
||||
columnAligments: []int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_CENTER, tablewriter.ALIGN_LEFT},
|
||||
want: "Control name\n┌──────────────┬─────────────────────────┬──────────────┐\n│ Control name │ Resources │ View details │\n├──────────────┼─────────────────────────┼──────────────┤\n│ Regular │ regular line │ 1 │\n│ Thick │ particularly thick line │ 2 │\n│ Double │ double line │ 3 │\n└──────────────┴─────────────────────────┴──────────────┘\n1 Low severity\n5 Critical severity\n4 High severity\n\n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a temporary file to capture output
|
||||
f, err := os.CreateTemp("", "print")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
tableWriter := getCategoryTableWriter(f, tt.headers, tt.columnAligments)
|
||||
|
||||
// Redirect stderr to the temporary file
|
||||
oldStderr := os.Stderr
|
||||
defer func() {
|
||||
os.Stderr = oldStderr
|
||||
}()
|
||||
os.Stderr = f
|
||||
|
||||
renderSingleCategory(f, tt.categoryName, tableWriter, tt.rows, tt.infoToPrintInfo)
|
||||
|
||||
// Read the contents of the temporary file
|
||||
f.Seek(0, 0)
|
||||
got, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
assert.NotNil(t, tableWriter)
|
||||
assert.Equal(t, tt.want, string(got))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+15
-1
@@ -111,7 +111,21 @@ func (fp *FrameworkPrinter) PrintSummaryTable(writer io.Writer, summaryDetails *
|
||||
func shortFormatRow(dataRows [][]string) [][]string {
|
||||
rows := [][]string{}
|
||||
for _, dataRow := range dataRows {
|
||||
rows = append(rows, []string{fmt.Sprintf("Severity"+strings.Repeat(" ", 11)+": %+v\nControl Name"+strings.Repeat(" ", 7)+": %+v\nFailed Resources"+strings.Repeat(" ", 3)+": %+v\nAll Resources"+strings.Repeat(" ", 6)+": %+v\n%% Compliance-Score"+strings.Repeat(" ", 1)+": %+v", dataRow[summaryColumnSeverity], dataRow[summaryColumnName], dataRow[summaryColumnCounterFailed], dataRow[summaryColumnCounterAll], dataRow[summaryColumnComplianceScore])})
|
||||
// Define the row content using a formatted string
|
||||
rowContent := fmt.Sprintf("Severity%s: %+v\nControl Name%s: %+v\nFailed Resources%s: %+v\nAll Resources%s: %+v\n%% Compliance-Score%s: %+v",
|
||||
strings.Repeat(" ", 11),
|
||||
dataRow[summaryColumnSeverity],
|
||||
strings.Repeat(" ", 7),
|
||||
dataRow[summaryColumnName],
|
||||
strings.Repeat(" ", 3),
|
||||
dataRow[summaryColumnCounterFailed],
|
||||
strings.Repeat(" ", 6),
|
||||
dataRow[summaryColumnCounterAll],
|
||||
strings.Repeat(" ", 1),
|
||||
dataRow[summaryColumnComplianceScore])
|
||||
|
||||
// Append the formatted row content to the rows slice
|
||||
rows = append(rows, []string{rowContent})
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
package configurationprinter
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/kubescape/opa-utils/reporthandling/results/v1/reportsummary"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type MockISeverityCounters struct {
|
||||
CriticalCount int
|
||||
HighCount int
|
||||
MediumCount int
|
||||
LowCount int
|
||||
}
|
||||
|
||||
func (m *MockISeverityCounters) NumberOfCriticalSeverity() int {
|
||||
return m.CriticalCount
|
||||
}
|
||||
|
||||
func (m *MockISeverityCounters) NumberOfHighSeverity() int {
|
||||
return m.HighCount
|
||||
}
|
||||
|
||||
func (m *MockISeverityCounters) NumberOfMediumSeverity() int {
|
||||
return m.MediumCount
|
||||
}
|
||||
|
||||
func (m *MockISeverityCounters) NumberOfLowSeverity() int {
|
||||
return m.LowCount
|
||||
}
|
||||
|
||||
func (m *MockISeverityCounters) Increase(severity string, amount int) {
|
||||
}
|
||||
|
||||
func TestNewFrameworkPrinter(t *testing.T) {
|
||||
// Test case 1: Verifying default verbose mode
|
||||
frameworkPrinter := NewFrameworkPrinter(false)
|
||||
assert.NotNil(t, frameworkPrinter)
|
||||
assert.Equal(t, false, frameworkPrinter.verboseMode)
|
||||
|
||||
// Test case 2: Setting verbose mode to true
|
||||
frameworkPrinter = NewFrameworkPrinter(true)
|
||||
assert.NotNil(t, frameworkPrinter)
|
||||
assert.Equal(t, true, frameworkPrinter.verboseMode)
|
||||
}
|
||||
|
||||
func TestGetVerboseMode(t *testing.T) {
|
||||
// Test case 1: Verifying false verbose mode
|
||||
frameworkPrinter := NewFrameworkPrinter(false)
|
||||
assert.Equal(t, false, frameworkPrinter.getVerboseMode())
|
||||
|
||||
// Test case 2: Setting verbose mode to true
|
||||
frameworkPrinter = NewFrameworkPrinter(true)
|
||||
assert.Equal(t, true, frameworkPrinter.getVerboseMode())
|
||||
}
|
||||
|
||||
func TestShortRowFormat(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
rows [][]string
|
||||
expectedRows [][]string
|
||||
}{
|
||||
{
|
||||
name: "Test Empty rows",
|
||||
rows: [][]string{},
|
||||
expectedRows: [][]string{},
|
||||
},
|
||||
{
|
||||
name: "Test Non empty row",
|
||||
rows: [][]string{
|
||||
{"Medium", "Control 1", "2", "20", "0.8"},
|
||||
},
|
||||
expectedRows: [][]string{[]string{"Severity : Medium\nControl Name : Control 1\nFailed Resources : 2\nAll Resources : 20\n% Compliance-Score : 0.8"}},
|
||||
},
|
||||
{
|
||||
name: "Test Non empty rows",
|
||||
rows: [][]string{
|
||||
{"Medium", "Control 1", "2", "20", "0.8"},
|
||||
{"Low", "Control 2", "0", "30", "1.0"},
|
||||
},
|
||||
expectedRows: [][]string{[]string{"Severity : Medium\nControl Name : Control 1\nFailed Resources : 2\nAll Resources : 20\n% Compliance-Score : 0.8"}, []string{"Severity : Low\nControl Name : Control 2\nFailed Resources : 0\nAll Resources : 30\n% Compliance-Score : 1.0"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expectedRows, shortFormatRow(tt.rows))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderSeverityCountersSummary(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
counters MockISeverityCounters
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
name: "All empty",
|
||||
counters: MockISeverityCounters{},
|
||||
expected: [][]string{[]string{"Critical", "0"}, []string{"High", "0"}, []string{"Medium", "0"}, []string{"Low", "0"}},
|
||||
},
|
||||
{
|
||||
name: "All different",
|
||||
counters: MockISeverityCounters{
|
||||
CriticalCount: 7,
|
||||
HighCount: 17,
|
||||
MediumCount: 27,
|
||||
LowCount: 37,
|
||||
},
|
||||
expected: [][]string{[]string{"Critical", "7"}, []string{"High", "17"}, []string{"Medium", "27"}, []string{"Low", "37"}},
|
||||
},
|
||||
{
|
||||
name: "All equal",
|
||||
counters: MockISeverityCounters{
|
||||
CriticalCount: 7,
|
||||
HighCount: 7,
|
||||
MediumCount: 7,
|
||||
LowCount: 7,
|
||||
},
|
||||
expected: [][]string{[]string{"Critical", "7"}, []string{"High", "7"}, []string{"Medium", "7"}, []string{"Low", "7"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, renderSeverityCountersSummary(&tt.counters))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintSummaryTable(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
summaryDetails *reportsummary.SummaryDetails
|
||||
sortedControlIDs [][]string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "All empty",
|
||||
summaryDetails: &reportsummary.SummaryDetails{
|
||||
Frameworks: []reportsummary.FrameworkSummary{
|
||||
{
|
||||
Name: "CIS Kubernetes Benchmark",
|
||||
},
|
||||
{
|
||||
Name: "nsa",
|
||||
},
|
||||
{
|
||||
Name: "mitre",
|
||||
},
|
||||
},
|
||||
},
|
||||
sortedControlIDs: [][]string{},
|
||||
want: "\nKubescape did not scan any resources. Make sure you are scanning valid manifests (Deployments, Pods, etc.)\n",
|
||||
},
|
||||
}
|
||||
|
||||
fp := NewFrameworkPrinter(false)
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a temporary file to capture output
|
||||
f, err := os.CreateTemp("", "print")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Redirect stderr to the temporary file
|
||||
oldStderr := os.Stderr
|
||||
defer func() {
|
||||
os.Stderr = oldStderr
|
||||
}()
|
||||
os.Stderr = f
|
||||
|
||||
fp.PrintSummaryTable(f, tt.summaryDetails, tt.sortedControlIDs)
|
||||
|
||||
// Read the contents of the temporary file
|
||||
f.Seek(0, 0)
|
||||
got, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.want, string(got))
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user