Skip to content

Commit

Permalink
Merge pull request #95 from kubescape/fix-counters
Browse files Browse the repository at this point in the history
fix(counters): Fixed prioritizing "skipped" over "passed"
  • Loading branch information
yuleib authored Feb 23, 2023
2 parents 7c36c22 + 705e5b6 commit 565bf98
Show file tree
Hide file tree
Showing 9 changed files with 12,439 additions and 12 deletions.
2 changes: 1 addition & 1 deletion reporthandling/apis/statuses.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
StatusError ScanningStatus = "error" // Deprecated
)
const (
SubStatusConfigurationInfo StatusMsg = "Control missing configuration"
SubStatusConfigurationInfo StatusMsg = "Control configurations are empty"
SubStatusRequiresReviewInfo StatusMsg = "Control type is requires-review"
SubStatusManualReviewInfo StatusMsg = "Control type is manual-review"
)
Expand Down
13 changes: 7 additions & 6 deletions reporthandling/helpers/v1/listing.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,19 @@ func (all *AllLists) ToUniqueResources() {
all.failed = slices.UniqueStrings(all.failed)

const heuristicCapacity = 100 // alloc 100 slots to the stack. The rest would go to the heap - see https://github.com/golang/go/issues/58215

trimmed := append(make([]string, 0, heuristicCapacity), make([]string, 0, max(len(all.failed)+len(all.excluded)+len(all.passed)+len(all.skipped), heuristicCapacity)-heuristicCapacity)...)

// remove failed and excluded from passed list
// remove failed from excluded list
trimmed = append(trimmed, all.failed...)
all.passed = slices.TrimStableUnique(all.passed, trimmed)

// remove failed, excluded and passed from skipped list
trimmed = append(trimmed, all.passed...)
all.skipped = slices.TrimStableUnique(all.skipped, trimmed)

// remove failed, excluded, passed and skipped from other list
// remove failed and skipped from passed list
trimmed = append(trimmed, all.skipped...)
all.passed = slices.TrimStableUnique(all.passed, trimmed)

// remove failed, skipped and passed from "other" list
trimmed = append(trimmed, all.passed...)
all.other = slices.TrimStableUnique(all.other, trimmed)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ func (frameworkSummary *FrameworkSummary) initResourcesSummary(controlInfoMap ma
for k, control := range frameworkSummary.Controls {
if statusInfo, ok := controlInfoMap[control.ControlID]; ok && statusInfo.InnerStatus != apis.StatusUnknown {
control.SetStatus(&statusInfo)
control.SetSubStatus(apis.SubStatusIntegration)
} else if control.GetStatus().Status() == apis.StatusUnknown {
control.CalculateStatus()
}
Expand Down
8 changes: 4 additions & 4 deletions reporthandling/results/v1/reportsummary/summarydetails.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ func (summaryDetails *SummaryDetails) InitResourcesSummary(controlInfoMap map[st
for k, control := range summaryDetails.Controls {
if statusInfo, ok := controlInfoMap[control.ControlID]; ok && statusInfo.InnerStatus != apis.StatusUnknown {
control.SetStatus(&statusInfo)
control.SetSubStatus(apis.SubStatusIntegration)
} else if control.GetStatus().Status() == apis.StatusUnknown {
control.CalculateStatus()
}
Expand Down Expand Up @@ -161,9 +160,10 @@ func (summaryDetails *SummaryDetails) AppendResourceResult(resourceResult *resou
}

// update frameworks counters
for _, framework := range summaryDetails.Frameworks {
updateControlsSummaryCounters(resourceResult, framework.Controls, &helpersv1.Filters{FrameworkNames: []string{framework.Name}})
framework.CalculateStatus()
for i := range summaryDetails.Frameworks {
updateControlsSummaryCounters(resourceResult, summaryDetails.Frameworks[i].Controls, &helpersv1.Filters{FrameworkNames: []string{summaryDetails.Frameworks[i].GetName()}})
summaryDetails.Frameworks[i].StatusCounters.Set(summaryDetails.Frameworks[i].ListResourcesIDs())
summaryDetails.Frameworks[i].CalculateStatus()
}
}

Expand Down
205 changes: 205 additions & 0 deletions reporthandling/results/v1/reportsummary/summarydetails_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package reportsummary

import (
_ "embed"
"encoding/json"
"fmt"
"testing"

"github.com/kubescape/opa-utils/reporthandling/apis"
Expand Down Expand Up @@ -326,3 +329,205 @@ func TestSummaryDetails_GetControlsSeverityCounters(t *testing.T) {
})
}
}

//go:embed testdata/summaryDetails.json
var summaryDetailsBytes []byte

//go:embed testdata/allResourcesResults.json
var allResourcesResultsBytes []byte

func setUpSummaryDetails() (*SummaryDetails, error) {
summaryDetails := &SummaryDetails{}
if err := json.Unmarshal(summaryDetailsBytes, summaryDetails); err != nil {
return nil, fmt.Errorf("failed to unmarshal summaryDetailsBytes: %v", err)
}

allResourcesResults := map[string]resourcesresults.Result{}
if err := json.Unmarshal(allResourcesResultsBytes, &allResourcesResults); err != nil {
return nil, fmt.Errorf("failed to unmarshal allResourcesResults: %v", err)
}

for i := range allResourcesResults {
t := allResourcesResults[i]
summaryDetails.AppendResourceResult(&t)
}

summaryDetails.InitResourcesSummary(nil)

return summaryDetails, nil
}
func TestSummaryDetails_Counters(t *testing.T) {

summaryDetails, err := setUpSummaryDetails()
if err != nil {
t.Fatalf("failed to unmarshal allResourcesResults: %v", err)
}

// testing counters
assert.Equal(t, 93, summaryDetails.StatusCounters.All())
assert.Equal(t, 4, summaryDetails.StatusCounters.Passed())
assert.Equal(t, 9, summaryDetails.StatusCounters.Failed())
assert.Equal(t, 80, summaryDetails.StatusCounters.Skipped())

assert.Equal(t, 93, summaryDetails.NumberOfResources().All())
assert.Equal(t, 4, summaryDetails.NumberOfResources().Passed())
assert.Equal(t, 9, summaryDetails.NumberOfResources().Failed())
assert.Equal(t, 80, summaryDetails.NumberOfResources().Skipped())

assert.Equal(t, 0, summaryDetails.GetControlsSeverityCounters().NumberOfCriticalSeverity())
assert.Equal(t, 3, summaryDetails.GetControlsSeverityCounters().NumberOfHighSeverity())
assert.Equal(t, 1, summaryDetails.GetControlsSeverityCounters().NumberOfMediumSeverity())
assert.Equal(t, 0, summaryDetails.GetControlsSeverityCounters().NumberOfLowSeverity())

assert.Equal(t, 0, summaryDetails.GetResourcesSeverityCounters().NumberOfCriticalSeverity())
assert.Equal(t, 20, summaryDetails.GetResourcesSeverityCounters().NumberOfHighSeverity())
assert.Equal(t, 8, summaryDetails.GetResourcesSeverityCounters().NumberOfMediumSeverity())
assert.Equal(t, 0, summaryDetails.GetResourcesSeverityCounters().NumberOfLowSeverity())

assert.Equal(t, 27, summaryDetails.NumberOfControls().All())
assert.Equal(t, 22, summaryDetails.NumberOfControls().Passed())
assert.Equal(t, 4, summaryDetails.NumberOfControls().Failed())
assert.Equal(t, 1, summaryDetails.NumberOfControls().Skipped())
}

func TestSummaryDetails_UniqueControls(t *testing.T) {

summaryDetails, err := setUpSummaryDetails()
if err != nil {
t.Fatalf("failed to unmarshal allResourcesResults: %v", err)
}
m := map[string]interface{}{}
for _, c := range summaryDetails.ListControls() {
m[c.GetID()] = nil
}

assert.Equal(t, len(summaryDetails.ListControls()), len(m))

}

func TestSummaryDetails_UniqueFrameworks(t *testing.T) {

summaryDetails, err := setUpSummaryDetails()
if err != nil {
t.Fatalf("failed to unmarshal allResourcesResults: %v", err)
}
m := map[string]interface{}{}
for _, c := range summaryDetails.ListFrameworks() {
m[c.GetName()] = nil
}

assert.Equal(t, len(summaryDetails.ListFrameworks()), len(m))

}

func TestSummaryDetails_UniqueResources(t *testing.T) {

summaryDetails, err := setUpSummaryDetails()
if err != nil {
t.Fatalf("failed to unmarshal allResourcesResults: %v", err)
}

m := map[string]interface{}{}
r := summaryDetails.ListResourcesIDs().All()
for r.HasNext() {
m[r.Next()] = nil
}

assert.Equal(t, summaryDetails.ListResourcesIDs().All().Len(), len(m))

}

//go:embed testdata/initSummaryDetails.json
var initSummaryDetailsBytes []byte

//go:embed testdata/resourcesResult.json
var resourcesResultBytes []byte

func TestSummaryDetails_AppendResourceResult(t *testing.T) {

summaryDetails := &SummaryDetails{}
if err := json.Unmarshal(initSummaryDetailsBytes, summaryDetails); err != nil {
t.Fatalf("failed to unmarshal initSummaryDetailsBytes: %v", err)
}

resourcesResult := &resourcesresults.Result{}
if err := json.Unmarshal(resourcesResultBytes, resourcesResult); err != nil {
t.Fatalf("failed to unmarshal resourcesResultBytes: %v", err)
}
summaryDetails.AppendResourceResult(resourcesResult)

// Test framework status
fw := summaryDetails.Frameworks[0]

assert.Equal(t, 1, fw.StatusCounters.All())
assert.Equal(t, 0, fw.StatusCounters.Passed())
assert.Equal(t, 0, fw.StatusCounters.Failed())
assert.Equal(t, 1, fw.StatusCounters.Skipped())

assert.Truef(t, fw.GetStatus().IsSkipped(), "framework status is \"%s\"", fw.GetStatus().Status())
}

func TestUpdateControlsSummaryCounters(t *testing.T) {

tests := []struct {
want apis.IStatus
controlID string
name string
}{
{
name: "Skipped control",
controlID: "C-0012",
want: &apis.StatusInfo{
InnerStatus: apis.StatusSkipped,
SubStatus: apis.SubStatusConfiguration,
InnerInfo: "Control configurations are empty",
},
},
{
name: "Passed control",
controlID: "C-0057",
want: &apis.StatusInfo{
InnerStatus: apis.StatusPassed,
SubStatus: "",
InnerInfo: "",
},
},
}

summaryDetails := &SummaryDetails{}
if err := json.Unmarshal(initSummaryDetailsBytes, summaryDetails); err != nil {
t.Fatalf("failed to unmarshal initSummaryDetailsBytes: %v", err)
}

resourcesResult := &resourcesresults.Result{}
if err := json.Unmarshal(resourcesResultBytes, resourcesResult); err != nil {
t.Fatalf("failed to unmarshal resourcesResultBytes: %v", err)
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
summaryDetails := &SummaryDetails{}
if err := json.Unmarshal(initSummaryDetailsBytes, summaryDetails); err != nil {
t.Fatalf("failed to unmarshal initSummaryDetailsBytes: %v", err)
}

resourcesResult := &resourcesresults.Result{}
if err := json.Unmarshal(resourcesResultBytes, resourcesResult); err != nil {
t.Fatalf("failed to unmarshal resourcesResultBytes: %v", err)
}

updateControlsSummaryCounters(resourcesResult, summaryDetails.Controls, nil)

if summaryDetails.Controls.GetControl(EControlCriteriaID, tt.controlID).GetStatus().Status() != tt.want.Status() {
t.Errorf("Status() = %v, want %v", summaryDetails.Controls.GetControl(EControlCriteriaID, tt.controlID).GetStatus().Status(), tt.want.Status())
}
if summaryDetails.Controls.GetControl(EControlCriteriaID, tt.controlID).GetStatus().GetSubStatus() != tt.want.GetSubStatus() {
t.Errorf("GetSubStatus() = %v, want %v", summaryDetails.Controls.GetControl(EControlCriteriaID, tt.controlID).GetStatus().GetSubStatus(), tt.want.GetSubStatus())
}
if summaryDetails.Controls.GetControl(EControlCriteriaID, tt.controlID).GetStatus().Info() != tt.want.Info() {
t.Errorf("Info() = %v, want %v", summaryDetails.Controls.GetControl(EControlCriteriaID, tt.controlID).GetStatus().Info(), tt.want.Info())
}
})
}

}
Loading

0 comments on commit 565bf98

Please sign in to comment.