Skip to content

Commit a04d1aa

Browse files
committed
fix score calculation for framework with all controls in status irrelevant
Signed-off-by: Amir Malka <[email protected]>
1 parent be60387 commit a04d1aa

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

score/score.go

+23
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,20 @@ func (su *ScoreUtil) ControlScore(ctrlReport *reporthandling.ControlReport, _ /*
246246

247247
}
248248

249+
// allControlsInFrameworkIrrelevant returns true if all controls in a framework were irrelevant (0 resources were checked across all controls).
250+
func (su *ScoreUtil) allControlsInFrameworkIrrelevant(ctrls *reportsummary.ControlSummaries) bool {
251+
for ctrlID := range *ctrls {
252+
ctrl := (*ctrls)[ctrlID]
253+
if ctrl.ListResourcesIDs(nil).Len() != 0 {
254+
return false
255+
}
256+
if ctrl.GetSubStatus() != apis.SubStatusIrrelevant {
257+
return false
258+
}
259+
}
260+
return true
261+
}
262+
249263
// CalculatePostureReportV2 calculates controls by framework score.
250264
func (su *ScoreUtil) CalculatePostureReportV2(report *v2.PostureReport) error {
251265
for i := range report.SummaryDetails.Frameworks {
@@ -254,6 +268,15 @@ func (su *ScoreUtil) CalculatePostureReportV2(report *v2.PostureReport) error {
254268
fwUnormalizedScore, wcsFwork := su.ControlsSummariesScore(&report.SummaryDetails.Frameworks[i].Controls, report.SummaryDetails.Frameworks[i].GetName())
255269

256270
if wcsFwork == 0 { // NOTE(fred): since this is a float32, perhaps we should use a tolerance here
271+
272+
// if all controls in framework are irrelevant, set framework score to 100
273+
// except for empty frameworks (first check)
274+
if len(report.SummaryDetails.Frameworks[i].Controls) > 0 && su.allControlsInFrameworkIrrelevant(&report.SummaryDetails.Frameworks[i].Controls) {
275+
report.SummaryDetails.Frameworks[i].Score = 100
276+
su.debugf("all controls in frameware are irrelevant - framework %s score %v", report.SummaryDetails.Frameworks[i].GetName(), report.SummaryDetails.Frameworks[i].GetScore())
277+
continue
278+
}
279+
257280
report.SummaryDetails.Frameworks[i].Score = 0
258281

259282
return fmt.Errorf(

score/score_test.go

+39-3
Original file line numberDiff line numberDiff line change
@@ -360,11 +360,12 @@ func TestCalculatePostureReportV2(t *testing.T) {
360360
const (
361361
expectedForFramework1 = float32(62.577965)
362362
expectedForFramework2 = float32(46.42857)
363+
expectedForFramework3 = float32(100)
363364
expectedSummary = float32(51.280453)
364365
)
365366

366367
t.Run("assert control scores", func(t *testing.T) {
367-
require.Len(t, report.SummaryDetails.Controls, 4)
368+
require.Len(t, report.SummaryDetails.Controls, 5)
368369
for _, control := range report.SummaryDetails.Controls {
369370
var expectedForControl float64
370371

@@ -377,6 +378,8 @@ func TestCalculatePostureReportV2(t *testing.T) {
377378
expectedForControl = 66.666664
378379
case "control-4":
379380
expectedForControl = 0 // passed
381+
case "control-5":
382+
expectedForControl = 0 // passed
380383
}
381384

382385
assert.InDeltaf(t, expectedForControl, control.Score, 1e-6,
@@ -392,6 +395,9 @@ func TestCalculatePostureReportV2(t *testing.T) {
392395
assert.InDeltaf(t, expectedForFramework2, report.SummaryDetails.Frameworks[1].Score, 1e-6,
393396
"unexpected summarized score for framework[1]",
394397
)
398+
assert.InDeltaf(t, expectedForFramework3, report.SummaryDetails.Frameworks[2].Score, 1e-6,
399+
"unexpected summarized score for framework[2]",
400+
)
395401
})
396402

397403
t.Run("assert final score", func(t *testing.T) {
@@ -594,6 +600,25 @@ func mockPostureReportV2(t testing.TB) (map[string]workloadinterface.IMetadata,
594600
},
595601
},
596602
},
603+
{
604+
// expected score: 100%
605+
Name: "mock-fw-summary-3",
606+
Controls: reportsummary.ControlSummaries{
607+
// 0 failed resources
608+
// All resources passed (control is irrelevant)
609+
// expected control score: 100%
610+
"summary-1": reportsummary.ControlSummary{
611+
Name: "mock-control-5",
612+
ControlID: "control-5",
613+
ResourceIDs: helpers.AllLists{},
614+
ScoreFactor: 7.00,
615+
StatusInfo: apis.StatusInfo{
616+
InnerStatus: apis.StatusPassed,
617+
SubStatus: apis.SubStatusIrrelevant,
618+
},
619+
},
620+
},
621+
},
597622
},
598623
},
599624
Results: []resourcesresults.Result{},
@@ -957,13 +982,15 @@ func TestSetPostureReportComplianceScores(t *testing.T) {
957982
const (
958983
expectedScoreFramework1 = float32(62.577965)
959984
expectedScoreFramework2 = float32(46.42857)
985+
expectedScoreFramework3 = float32(100)
960986
expectedComplianceScoreFramework1 = float32(66.66667)
961987
expectedComplianceScoreFramework2 = float32(75)
962-
expectedSummary = float32(70.833336)
988+
expectedComplianceScoreFramework3 = float32(100)
989+
expectedSummary = float32(76.66667)
963990
)
964991

965992
t.Run("assert control scores", func(t *testing.T) {
966-
require.Len(t, report.SummaryDetails.Controls, 4)
993+
require.Len(t, report.SummaryDetails.Controls, 5)
967994
for _, control := range report.SummaryDetails.Controls {
968995
var expectedComplianceScore float64
969996
var expectedScore float64
@@ -981,6 +1008,9 @@ func TestSetPostureReportComplianceScores(t *testing.T) {
9811008
case "control-4":
9821009
expectedComplianceScore = 100 // passed
9831010
expectedScore = 0
1011+
case "control-5":
1012+
expectedComplianceScore = 100 // passed
1013+
expectedScore = 0
9841014
}
9851015

9861016
assert.InDeltaf(t, expectedComplianceScore, *control.ComplianceScore, 1e-6,
@@ -1000,6 +1030,9 @@ func TestSetPostureReportComplianceScores(t *testing.T) {
10001030
assert.InDeltaf(t, expectedScoreFramework2, report.SummaryDetails.Frameworks[1].Score, 1e-6,
10011031
"unexpected summarized score for framework[1]",
10021032
)
1033+
assert.InDeltaf(t, expectedScoreFramework3, report.SummaryDetails.Frameworks[2].Score, 1e-6,
1034+
"unexpected summarized score for framework[2]",
1035+
)
10031036
})
10041037

10051038
t.Run("assert framework compliance scores", func(t *testing.T) {
@@ -1009,6 +1042,9 @@ func TestSetPostureReportComplianceScores(t *testing.T) {
10091042
assert.InDeltaf(t, expectedComplianceScoreFramework2, report.SummaryDetails.Frameworks[1].ComplianceScore, 1e-6,
10101043
"unexpected summarized compliance score for framework[1]",
10111044
)
1045+
assert.InDeltaf(t, expectedComplianceScoreFramework3, report.SummaryDetails.Frameworks[2].ComplianceScore, 1e-6,
1046+
"unexpected summarized compliance score for framework[2]",
1047+
)
10121048
})
10131049

10141050
t.Run("assert final score", func(t *testing.T) {

0 commit comments

Comments
 (0)