Skip to content

Commit

Permalink
Merge pull request kubescape#1504 from cbrom/core_pkg_containerscan_t…
Browse files Browse the repository at this point in the history
…ests

Enhancement of Test Coverage and Code Improvements in Container Scan Package
  • Loading branch information
matthyx authored Nov 24, 2023
2 parents 84d4ff7 + f3670ca commit 029b4c2
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 78 deletions.
248 changes: 231 additions & 17 deletions core/pkg/containerscan/containerscan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package containerscan
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"testing"

"github.com/francoispqt/gojay"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestDecodeScanWIthDangearousArtifacts(t *testing.T) {
Expand Down Expand Up @@ -61,30 +62,243 @@ func TestUnmarshalScanReport1(t *testing.T) {

func TestGetByPkgNameSuccess(t *testing.T) {
ds := GenerateContainerScanReportMock()
a := ds.Layers[0].GetFilesByPackage("coreutils")
if a != nil {
a := ds.Layers[0].GetPackagesNames()
require.Equal(t, 1, len(a))
assert.Equal(t, []string{"coreutils"}, a)

fmt.Printf("%+v\n", *a)
}

func TestScanResultReportValidate(t *testing.T) {
tests := []struct {
name string
in ScanResultReport
expected bool
}{
{
name: "empty report should return false",
in: ScanResultReport{},
expected: false,
},
{
name: "report with empty CustomerGUID should return false",
in: ScanResultReport{
CustomerGUID: "",
ImgHash: "aaa",
ImgTag: "bbb",
Timestamp: 1,
},
expected: false,
},
{
name: "report with empty ImgHash and ImgTag should return false",
in: ScanResultReport{
CustomerGUID: "aaa",
ImgHash: "",
ImgTag: "",
Timestamp: 1,
},
expected: false,
},
{
name: "report with empty ImageHash and non-empty ImgTag should return true",
in: ScanResultReport{
CustomerGUID: "aaa",
ImgHash: "",
ImgTag: "bbb",
Timestamp: 1,
},
expected: true,
},
{
name: "report with non-empty ImageHash and empty ImgTag should return true",
in: ScanResultReport{
CustomerGUID: "aaa",
ImgHash: "bbb",
ImgTag: "",
Timestamp: 1,
},
expected: true,
},
{
name: "report with non-empty ImageHash and non-empty ImgTag should return true",
in: ScanResultReport{
CustomerGUID: "aaa",
ImgHash: "bbb",
ImgTag: "ccc",
Timestamp: 1,
},
expected: true,
},
{
name: "report with Timestamp <= 0 should return false",
in: ScanResultReport{
CustomerGUID: "aaa",
ImgHash: "bbb",
ImgTag: "ccc",
Timestamp: 0,
},
expected: false,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := test.in.Validate()
assert.Equal(t, test.expected, res)
})
}
}

func TestGetByPkgNameMissing(t *testing.T) {
ds := GenerateContainerScanReportMock()
a := ds.Layers[0].GetFilesByPackage("s")
if a != nil && len(*a) > 0 {
t.Errorf("expected - no such package should be in that layer %v\n\n; found - %v", ds, a)
func TestScanElasticContainerScanSummaryResultValidate(t *testing.T) {
tests := []struct {
name string
in ElasticContainerScanSummaryResult
expected bool
}{
{
name: "empty summary should return false",
in: ElasticContainerScanSummaryResult{},
expected: false,
},
{
name: "summary with empty CustomerGUID should return false",
in: ElasticContainerScanSummaryResult{
CustomerGUID: "",
ContainerScanID: "aaa",
ImgHash: "bbb",
ImgTag: "ccc",
Timestamp: 1,
},
expected: false,
},
{
name: "summary with empty ContainerScanID should return false",
in: ElasticContainerScanSummaryResult{
CustomerGUID: "aaa",
ContainerScanID: "",
ImgHash: "bbb",
ImgTag: "ccc",
Timestamp: 1,
},
expected: false,
},
{
name: "summary with empty ImgHash and ImgTag should return false",
in: ElasticContainerScanSummaryResult{
CustomerGUID: "aaa",
ContainerScanID: "bbb",
ImgHash: "",
ImgTag: "",
Timestamp: 1,
},
expected: false,
},
{
name: "summary with empty ImageHash and non-empty ImgTag should return true",
in: ElasticContainerScanSummaryResult{
CustomerGUID: "aaa",
ContainerScanID: "bbb",
ImgHash: "",
ImgTag: "ccc",
Timestamp: 1,
},
expected: true,
},
{
name: "summary with non-empty ImageHash and empty ImgTag should return true",
in: ElasticContainerScanSummaryResult{
CustomerGUID: "aaa",
ContainerScanID: "bbb",
ImgHash: "ccc",
ImgTag: "",
Timestamp: 1,
},
expected: true,
},
{
name: "summary with non-empty ImageHash and non-empty ImgTag should return true",
in: ElasticContainerScanSummaryResult{
CustomerGUID: "aaa",
ContainerScanID: "bbb",
ImgHash: "ccc",
ImgTag: "ddd",
Timestamp: 1,
},
expected: true,
},
{
name: "summary with Timestamp < 0 should return false",
in: ElasticContainerScanSummaryResult{
CustomerGUID: "aaa",
ContainerScanID: "bbb",
ImgHash: "ccc",
ImgTag: "ddd",
Timestamp: -1,
},
expected: false,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := test.in.Validate()
assert.Equal(t, test.expected, res)
})
}
}

func TestCalculateFixed(t *testing.T) {
res := CalculateFixed([]FixedIn{{
Name: "",
ImgTag: "",
Version: "",
}})
if 0 != res {
t.Errorf("wrong fix status: %v", res)
tests := []struct {
name string
in []FixedIn
expected int
}{
{
name: "empty list should return 0",
in: []FixedIn{},
expected: 0,
},
{
name: "None Version value should return 0",
in: []FixedIn{
{Version: "None"},
{Version: "None"},
{Version: "None"},
},
expected: 0,
},
{
name: "empty Version value should return 0",
in: []FixedIn{
{Version: ""},
{Version: ""},
{Version: ""},
},
expected: 0,
},
{
name: "non empty or non None Version value should return 1",
in: []FixedIn{
{Version: "1.23"},
{Version: ""},
{Version: ""},
},
expected: 1,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := CalculateFixed(test.in)
assert.Equal(t, test.expected, res)
})
}
}

func TestReturnsHashValueForValidInputValues(t *testing.T) {
report := ScanResultReport{}
expectedHash := "7416232187745851261"
actualHash := report.AsFNVHash()
if actualHash != expectedHash {
t.Errorf("Expected hash value %s, but got %s", expectedHash, actualHash)
}
}
24 changes: 24 additions & 0 deletions core/pkg/containerscan/datastructures.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,30 @@ var KnownSeverities = map[string]bool{
CriticalSeverity: true,
}

// CalculateFixed calculates the number of fixes in a given list of FixedIn objects.
//
// Example Usage:
//
// fixes := []FixedIn{
// {Version: "None"},
// {Version: "1.2.3"},
// {Version: ""},
// }
//
// result := CalculateFixed(fixes)
// fmt.Println(result) // Output: 1
//
// Inputs:
// - Fixes: a slice of FixedIn objects representing the fixes for a vulnerability.
//
// Flow:
// 1. Iterate over each FixedIn object in the Fixes slice.
// 2. Check if the Version field of the current FixedIn object is not equal to "None" and not empty.
// 3. If the condition is true for any FixedIn object, return 1.
// 4. If the loop completes without returning, return 0.
//
// Outputs:
// - An integer representing the number of fixes found in the Fixes slice.
func CalculateFixed(Fixes []FixedIn) int {
for _, fix := range Fixes {
if fix.Version != "None" && fix.Version != "" {
Expand Down
14 changes: 4 additions & 10 deletions core/pkg/containerscan/datastructuresmethods.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,7 @@ import (
"github.com/armosec/armoapi-go/identifiers"
)

func (layer *ScanResultLayer) GetFilesByPackage(pkgname string) (files *PkgFiles) {
for _, pkg := range layer.Packages {
if pkg.PackageName == pkgname {
return &pkg.Files
}
}

return &PkgFiles{}
}

// GetPackagesNames retrieves the names of all the packages stored in the Packages field of the ScanResultLayer object and returns them as a slice of strings.
func (layer *ScanResultLayer) GetPackagesNames() []string {
pkgsNames := []string{}
for _, pkg := range layer.Packages {
Expand All @@ -24,6 +15,7 @@ func (layer *ScanResultLayer) GetPackagesNames() []string {
return pkgsNames
}

// GetDesignatorsNContext retrieves the designators and context information from the ScanResultReport object and returns them as a pair of objects.
func (scanresult *ScanResultReport) GetDesignatorsNContext() (*identifiers.PortalDesignator, []identifiers.ArmoContext) {
designatorsObj := identifiers.AttributesDesignatorsFromWLID(scanresult.WLID)
designatorsObj.Attributes["containerName"] = scanresult.ContainerName
Expand All @@ -32,6 +24,7 @@ func (scanresult *ScanResultReport) GetDesignatorsNContext() (*identifiers.Porta
return designatorsObj, contextObj
}

// Validate checks if the scan result report is valid.
func (scanresult *ScanResultReport) Validate() bool {
if scanresult.CustomerGUID == "" || (scanresult.ImgHash == "" && scanresult.ImgTag == "") || scanresult.Timestamp <= 0 {
return false
Expand All @@ -42,6 +35,7 @@ func (scanresult *ScanResultReport) Validate() bool {
return true
}

// IsRCE checks if a vulnerability description contains any keywords related to remote code execution (RCE) or arbitrary code injection.
func (v *Vulnerability) IsRCE() bool {
desc := strings.ToLower(v.Description)

Expand Down
Loading

0 comments on commit 029b4c2

Please sign in to comment.